public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [patch] Add support for imported declaration and correct search order
@ 2010-02-25 20:17 Sami Wagiaalla
  2010-02-25 21:50 ` Tom Tromey
  2010-02-25 22:42 ` Jan Kratochvil
  0 siblings, 2 replies; 16+ messages in thread
From: Sami Wagiaalla @ 2010-02-25 20:17 UTC (permalink / raw)
  To: GDB Patches

[-- Attachment #1: Type: text/plain, Size: 16909 bytes --]

This patch adds support for printing of variables which have been 
imported in this manner:

namespace A
   {
     int x;
   }

int main(){
   using A::x
}

2010-02-25  Sami Wagiaalla  <swagiaal@redhat.com>

	PR c++/7936:
	* cp-support.h: Added char *declaration element to using_direct
	data struct.
	(cp_add_using): Added char *declaration argument.
	(cp_add_using_directive): Ditto.
	(cp_lookup_symbol_imports): made extern.
	* cp-namespace.c: Updated with the above changes.
	* dwarf2read.c (read_import_statement): Ditto.
	(read_namespace): Ditto.
	(read_import_statement): Support import declarations.
	* cp-namespace.c (cp_lookup_symbol_imports): Check for imported
	declarations.
	Added support for 'declaration_only' search.
	(cp_lookup_symbol_namespace): Attempt to search for the name as
	is before consideration of imports.
	* symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
	search at every block level search.
	Now takes language argument.
	(lookup_symbol_aux): Updated.

2010-02-25  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/shadow.exp: Removed kfail; test has been fix.
	* gdb.cp/nsusing.exp: Ditto.


diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 5e894d4..85082ce 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -117,7 +117,7 @@ cp_scan_for_anonymous_namespaces (const struct 
symbol *symbol)
  		 anonymous namespace.  So add symbols in it to the
  		 namespace given by the previous component if there is
  		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL);
+	      cp_add_using_directive (dest, src, NULL, NULL);
  	    }
  	  /* The "+ 2" is for the "::".  */
  	  previous_component = next_component + 2;
@@ -132,7 +132,10 @@ cp_scan_for_anonymous_namespaces (const struct 
symbol *symbol)
     has already been added, don't add it twice.  */

  void
-cp_add_using_directive (const char *dest, const char *src, const char 
*alias)
+cp_add_using_directive (const char *dest,
+                        const char *src,
+                        const char *alias,
+                        const char *declaration)
  {
    struct using_direct *current;
    struct using_direct *new;
@@ -146,8 +149,8 @@ cp_add_using_directive (const char *dest, const char 
*src, const char *alias)
  	return;
      }

-  using_directives = cp_add_using (dest, src, alias, using_directives);
-
+  using_directives = cp_add_using (dest, src, alias, declaration,
+                                   using_directives);
  }

  /* Record the namespace that the function defined by SYMBOL was
@@ -209,18 +212,22 @@ struct using_direct *
  cp_add_using (const char *dest,
                const char *src,
                const char *alias,
+              const char *declaration,
  	      struct using_direct *next)
  {
    struct using_direct *retval;

    retval = xmalloc (sizeof (struct using_direct));
+  memset (retval, 0, sizeof (struct using_direct));
+
    retval->import_src = savestring (src, strlen(src));
    retval->import_dest = savestring (dest, strlen(dest));

    if (alias != NULL)
      retval->alias = savestring (alias, strlen (alias));
-  else
-    retval->alias = NULL;
+
+  if (declaration != NULL)
+    retval->declaration = savestring (declaration, strlen (declaration));

    retval->next = next;
    retval->searched = 0;
@@ -249,11 +256,10 @@ cp_lookup_symbol_nonlocal (const char *name,
    if (sym != NULL)
      return sym;

-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, 
domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, 
domain);
  }

-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
     cp_lookup_symbol_nonlocal.  */

  static struct symbol *
@@ -304,26 +310,28 @@ reset_directive_searched (void *data)
       }

     If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of 
namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import 
of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the 
import of Y
     is considered.  */

-static struct symbol *
+struct symbol *
  cp_lookup_symbol_imports (const char *scope,
                            const char *name,
                            const char *linkage_name,
                            const struct block *block,
                            const domain_enum domain,
+			  const int declaration_only,
                            const int search_parents)
  {
    struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
    int len;
    int directive_match;
    struct cleanup *searched_cleanup;

    /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
    if (sym != NULL)
      return sym;

@@ -352,6 +360,31 @@ cp_lookup_symbol_imports (const char *scope,
  	current->searched = 1;
  	searched_cleanup = make_cleanup (reset_directive_searched, current);

+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
  	if (current->alias != NULL && strcmp (name, current->alias) == 0)
  	  /* If the import is creating an alias and the alias matches the
  	     sought name.  Pass current->import_src as the NAME to direct the
@@ -372,6 +405,7 @@ cp_lookup_symbol_imports (const char *scope,
  	                                    linkage_name,
  	                                    block,
  	                                    domain,
+	                                    0,
  	                                    0);
  	  }
  	current->searched = 0;
@@ -394,16 +428,21 @@ cp_lookup_symbol_namespace (const char *scope,
                              const char *name,
                              const char *linkage_name,
                              const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
  {
    struct symbol *sym;

+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if ( sym != NULL)
+    return sym;
+
    /* Search for name in namespaces imported to this and parent blocks.  */
    while (block != NULL)
      {
        sym = cp_lookup_symbol_imports (scope, name, linkage_name, 
block, domain,
-                                      search_parents);
+                                      0, 1);

        if (sym)
  	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index a6a9af1..8e7abc6 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
     Eg:
         namespace C = A::B;
     ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
  */

  struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
    char *import_dest;

    char *alias;
+  char *declaration;

    struct using_direct *next;

@@ -90,11 +96,13 @@ extern int cp_is_anonymous (const char *namespace);

  extern void cp_add_using_directive (const char *dest,
                                      const char *src,
-                                    const char *alias);
+                                    const char *alias,
+                                    const char *declaration);

  extern struct using_direct *cp_add_using (const char *dest,
                                            const char *src,
                                            const char *alias,
+                                          const char *declaration,
  					  struct using_direct *next);

  extern void cp_initialize_namespace (void);
@@ -119,8 +127,15 @@ extern struct symbol *cp_lookup_symbol_namespace 
(const char *namespace,
  						  const char *name,
  						  const char *linkage_name,
  						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);

  extern struct type *cp_lookup_nested_type (struct type *parent_type,
  					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index a05c946..04cdd34 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,10 @@ read_import_statement (struct die_info *die, 
struct dwarf2_cu *cu)
    struct dwarf2_cu *imported_cu;
    const char *imported_name;
    const char *imported_name_prefix;
-  char *import_alias;
-
-  const char *import_prefix;
    char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
+  const char *import_prefix;

    import_attr = dwarf2_attr (die, DW_AT_import, cu);
    if (import_attr == NULL)
@@ -3448,23 +3448,32 @@ read_import_statement (struct die_info *die, 
struct dwarf2_cu *cu)
       to the name of the imported die.  */
    imported_name_prefix = determine_prefix (imported_die, imported_cu);

-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
      {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = (char *) imported_name_prefix;
      }
    else
      {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      if (strlen (imported_name_prefix) > 0)
+        {
+          canonical_name = alloca (strlen (imported_name_prefix)
+                                   + 2 + strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name_prefix);
+          strcat (canonical_name, "::");
+          strcat (canonical_name, imported_name);
+        }
+      else
+        {
+          canonical_name = alloca (strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name);
+        }
      }

    using_directives = cp_add_using (import_prefix,
                                     canonical_name,
                                     import_alias,
+                                   imported_declaration,
                                     using_directives);
  }

@@ -5624,7 +5633,7 @@ read_namespace (struct die_info *die, struct 
dwarf2_cu *cu)
        if (is_anonymous)
  	{
  	  const char *previous_prefix = determine_prefix (die, cu);
-	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL);
+	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL, NULL);
  	}
      }

diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
  	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
  						     name, NULL,
  						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
  	      if (function == NULL)
  		error (_("No symbol \"%s\" in namespace \"%s\"."),
  		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..45e09df 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
  struct symbol *lookup_symbol_aux_local (const char *name,
  					const char *linkage_name,
  					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);

  static
  struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char 
*linkage_name,
    /* Search specified block and its superiors.  Don't search
       STATIC_BLOCK or GLOBAL_BLOCK.  */

-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, 
language);
    if (sym != NULL)
      return sym;

    /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */

    langdef = language_def (language);
-
    if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
        && block != NULL)
      {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char 
*linkage_name,
  static struct symbol *
  lookup_symbol_aux_local (const char *name, const char *linkage_name,
  			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
  {
    struct symbol *sym;
    const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);

    /* Check if either no block is specified or it's a global block.  */

@@ -1446,6 +1448,13 @@ lookup_symbol_aux_local (const char *name, const 
char *linkage_name,
        if (sym != NULL)
  	return sym;

+      if (language == language_cplus )
+        {
+          sym = cp_lookup_symbol_imports (scope, name, linkage_name, 
block, domain, 1, 1);
+          if (sym != NULL)
+            return sym;
+        }
+
        if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
  	break;
        block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp 
b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
      perror "couldn't run to breakpoint marker4"
      continue
  }
-setup_kfail "gdb/7936" "*-*-*"
+
  gdb_test "print dx" "= 4"

  ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                  using namespace A;
                  y++; // marker4

-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
                }
            }
        }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp 
b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
  gdb_breakpoint [gdb_get_line_number "marker5"]
  gdb_continue_to_breakpoint "marker5"

-setup_kfail "gdb/7936" "*-*-*"
  gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,

    sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
  				    get_selected_block (0),
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);

    if (sym == NULL)
      return NULL;

[-- Attachment #2: declaration.patch --]
[-- Type: text/plain, Size: 15627 bytes --]

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 5e894d4..85082ce 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -117,7 +117,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL);
+	      cp_add_using_directive (dest, src, NULL, NULL);
 	    }
 	  /* The "+ 2" is for the "::".  */
 	  previous_component = next_component + 2;
@@ -132,7 +132,10 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
    has already been added, don't add it twice.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src, const char *alias)
+cp_add_using_directive (const char *dest,
+                        const char *src,
+                        const char *alias,
+                        const char *declaration)
 {
   struct using_direct *current;
   struct using_direct *new;
@@ -146,8 +149,8 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias)
 	return;
     }
 
-  using_directives = cp_add_using (dest, src, alias, using_directives);
-
+  using_directives = cp_add_using (dest, src, alias, declaration,
+                                   using_directives);
 }
 
 /* Record the namespace that the function defined by SYMBOL was
@@ -209,18 +212,22 @@ struct using_direct *
 cp_add_using (const char *dest,
               const char *src,
               const char *alias,
+              const char *declaration,
 	      struct using_direct *next)
 {
   struct using_direct *retval;
 
   retval = xmalloc (sizeof (struct using_direct));
+  memset (retval, 0, sizeof (struct using_direct));
+
   retval->import_src = savestring (src, strlen(src));
   retval->import_dest = savestring (dest, strlen(dest));
 
   if (alias != NULL)
     retval->alias = savestring (alias, strlen (alias));
-  else
-    retval->alias = NULL;
+
+  if (declaration != NULL)
+    retval->declaration = savestring (declaration, strlen (declaration));
 
   retval->next = next;
   retval->searched = 0;
@@ -249,11 +256,10 @@ cp_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
@@ -304,26 +310,28 @@ reset_directive_searched (void *data)
      }
 
    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the import of Y
    is considered.  */
 
-static struct symbol *
+struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
                           const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
+			  const int declaration_only,
                           const int search_parents)
 {
   struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
   int len;
   int directive_match;
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
   if (sym != NULL)
     return sym;
 
@@ -352,6 +360,31 @@ cp_lookup_symbol_imports (const char *scope,
 	current->searched = 1;
 	searched_cleanup = make_cleanup (reset_directive_searched, current);
 
+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
 	if (current->alias != NULL && strcmp (name, current->alias) == 0)
 	  /* If the import is creating an alias and the alias matches the
 	     sought name.  Pass current->import_src as the NAME to direct the
@@ -372,6 +405,7 @@ cp_lookup_symbol_imports (const char *scope,
 	                                    linkage_name,
 	                                    block,
 	                                    domain,
+	                                    0,
 	                                    0);
 	  }
 	current->searched = 0;
@@ -394,16 +428,21 @@ cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const char *linkage_name,
                             const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
 {
   struct symbol *sym;
 
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if ( sym != NULL)
+    return sym;
+
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
       sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
-                                      search_parents);
+                                      0, 1);
 
       if (sym)
 	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index a6a9af1..8e7abc6 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
    Eg:
        namespace C = A::B;
    ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
 */
 
 struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
   char *import_dest;
 
   char *alias;
+  char *declaration;
 
   struct using_direct *next;
 
@@ -90,11 +96,13 @@ extern int cp_is_anonymous (const char *namespace);
 
 extern void cp_add_using_directive (const char *dest,
                                     const char *src,
-                                    const char *alias);
+                                    const char *alias,
+                                    const char *declaration);
 
 extern struct using_direct *cp_add_using (const char *dest,
                                           const char *src,
                                           const char *alias,
+                                          const char *declaration,
 					  struct using_direct *next);
 
 extern void cp_initialize_namespace (void);
@@ -119,8 +127,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
 						  const char *linkage_name,
 						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index a05c946..04cdd34 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,10 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_cu *imported_cu;
   const char *imported_name;
   const char *imported_name_prefix;
-  char *import_alias;
-
-  const char *import_prefix;
   char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
+  const char *import_prefix;
 
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
@@ -3448,23 +3448,32 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, imported_cu);
 
-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
     {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = (char *) imported_name_prefix;
     }
   else
     {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      if (strlen (imported_name_prefix) > 0)
+        {
+          canonical_name = alloca (strlen (imported_name_prefix)
+                                   + 2 + strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name_prefix);
+          strcat (canonical_name, "::");
+          strcat (canonical_name, imported_name);
+        }
+      else
+        {
+          canonical_name = alloca (strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name);
+        }
     }
 
   using_directives = cp_add_using (import_prefix,
                                    canonical_name,
                                    import_alias,
+                                   imported_declaration,
                                    using_directives);
 }
 
@@ -5624,7 +5633,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
       if (is_anonymous)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
-	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL);
+	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL, NULL);
 	}
     }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
 						     name, NULL,
 						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
 	      if (function == NULL)
 		error (_("No symbol \"%s\" in namespace \"%s\"."), 
 		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..45e09df 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
 struct symbol *lookup_symbol_aux_local (const char *name,
 					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language);
   if (sym != NULL)
     return sym;
 
   /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */
 
   langdef = language_def (language);
-
   if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
       && block != NULL)
     {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
 			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);
 
   /* Check if either no block is specified or it's a global block.  */
 
@@ -1446,6 +1448,13 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
       if (sym != NULL)
 	return sym;
 
+      if (language == language_cplus )
+        {
+          sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain, 1, 1);
+          if (sym != NULL)
+            return sym;
+        }
+
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
 	break;
       block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
-setup_kfail "gdb/7936" "*-*-*"
+
 gdb_test "print dx" "= 4"
 
 ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                 using namespace A;
                 y++; // marker4
 
-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
               }
           }
       }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
-setup_kfail "gdb/7936" "*-*-*"
 gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,
 
   sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
 				    get_selected_block (0), 
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);
 
   if (sym == NULL)
     return NULL;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search order
  2010-02-25 20:17 [patch] Add support for imported declaration and correct search order Sami Wagiaalla
@ 2010-02-25 21:50 ` Tom Tromey
  2010-02-25 22:42 ` Jan Kratochvil
  1 sibling, 0 replies; 16+ messages in thread
From: Tom Tromey @ 2010-02-25 21:50 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: GDB Patches

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

Sami> +  if (declaration != NULL)
Sami> +    retval->declaration = savestring (declaration, strlen (declaration));

... time to work on that memory leak bug :-)

Sami> +   and Y will be considered.  If SEARCH_PARENTS is false only the
Sami> import of Y
Sami>     is considered.  */

Thanks for adding that space :)

Sami> -static struct symbol *
Sami> +struct symbol *
Sami>  cp_lookup_symbol_imports (const char *scope,
Sami>                            const char *name,
Sami>                            const char *linkage_name,
Sami>                            const struct block *block,
Sami>                            const domain_enum domain,
Sami> +			  const int declaration_only,
Sami>                            const int search_parents)

The header comment should describe the new parameter.

Sami> +  if ( sym != NULL)

Extra space.

Sami> +      canonical_name = (char *) imported_name_prefix;

This cast is avoidable by introducing a new temporary for the alloca
result.  So, please change that.

Sami> +      if (language == language_cplus )

Extra space.

Sami> +        {
Sami> +          sym = cp_lookup_symbol_imports (scope, name, linkage_name,
Sami> block, domain, 1, 1);

This looks like it wraps.

I'm a little wary of changing lookup_symbol_aux_local to have
c++-specific code in it.  I suppose it isn't *too* bad in that we can
replace it with a language method if we really need to.

Tom

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search  order
  2010-02-25 20:17 [patch] Add support for imported declaration and correct search order Sami Wagiaalla
  2010-02-25 21:50 ` Tom Tromey
@ 2010-02-25 22:42 ` Jan Kratochvil
  2010-02-26 20:11   ` Tom Tromey
  1 sibling, 1 reply; 16+ messages in thread
From: Jan Kratochvil @ 2010-02-25 22:42 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: GDB Patches

On Thu, 25 Feb 2010 21:14:15 +0100, Sami Wagiaalla wrote:
>    retval->import_src = savestring (src, strlen(src));
>    retval->import_dest = savestring (dest, strlen(dest));
...
> +    retval->declaration = savestring (declaration, strlen (declaration));

(sure really only a nitpick)

These savestring calls can be simplified to:
# +    retval->declaration = xstrdup (declaration);

as was cleaned up by:
	[obv] Replace savestring by xstrdup where possible
	http://sourceware.org/ml/gdb-patches/2009-05/msg00516.html

but new `savestring (X, strlen (X))' calls apparently crept in since that time.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search  order
  2010-02-25 22:42 ` Jan Kratochvil
@ 2010-02-26 20:11   ` Tom Tromey
  2010-03-03 21:46     ` Sami Wagiaalla
  0 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2010-02-26 20:11 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Sami Wagiaalla, GDB Patches

>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:

>> +    retval->declaration = savestring (declaration, strlen (declaration));

Jan> (sure really only a nitpick)

That is what 70% of my reviews consist of :-)

Jan> These savestring calls can be simplified to:
Jan> # +    retval->declaration = xstrdup (declaration);
Jan> as was cleaned up by:
Jan> 	[obv] Replace savestring by xstrdup where possible
Jan> 	http://sourceware.org/ml/gdb-patches/2009-05/msg00516.html
Jan> but new `savestring (X, strlen (X))' calls apparently crept in
Jan> since that time.

Yes, thanks -- I forgot about this.  In this case I think these have to
be replaced with obstack allocations anyhow, since currently they are
all leaked.

According to the appended semantic patch, the uses of savestring in this
function are the only "bad" ones.

Tom

@@
expression e;
@@

- savestring (e, strlen (e))
+ xstrdup (e)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search   order
  2010-02-26 20:11   ` Tom Tromey
@ 2010-03-03 21:46     ` Sami Wagiaalla
  2010-03-03 22:00       ` Tom Tromey
  0 siblings, 1 reply; 16+ messages in thread
From: Sami Wagiaalla @ 2010-03-03 21:46 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 16936 bytes --]

Rebased on memory leak fix patch and incorporated requested Fixes.
Thanks for the reviews.

    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        PR c++/7936:
        * cp-support.h: Added char *declaration element to using_direct
        data struct.
        (cp_add_using): Added char *declaration argument.
        (cp_add_using_directive): Ditto.
        (cp_lookup_symbol_imports): made extern.
        * cp-namespace.c: Updated with the above changes.
        * dwarf2read.c (read_import_statement): Ditto.
        (read_namespace): Ditto.
        (read_import_statement): Support import declarations.
        * cp-namespace.c (cp_lookup_symbol_imports): Check for imported
        declarations.
        Added support for 'declaration_only' search.
        (cp_lookup_symbol_namespace): Attempt to search for the name as
        is before consideration of imports.
        * symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
        search at every block level search.
        Now takes language argument.
        (lookup_symbol_aux): Updated.
    
    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        * gdb.cp/shadow.exp: Removed kfail; test has been fix.
        * gdb.cp/nsusing.exp: Ditto.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 173924b..dd7227f 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -118,7 +118,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol,
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL, obstack);
+	      cp_add_using_directive (dest, src, NULL, NULL, obstack);
 	    }
 	  /* The "+ 2" is for the "::".  */
 	  previous_component = next_component + 2;
@@ -135,12 +135,17 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol,
    Create a new struct using direct which imports the namespace SRC into the
    scope DEST.  ALIAS is the name of the imported namespace in the current
    scope.  If ALIAS is NULL then the namespace is known by its original name.
+   DECLARATION is the name if the imported varable if this is a declaration
+   import (Eg. using A::x), otherwise it is NULL.
    Set its next member in the linked list to NEXT; allocate all memory
    using xmalloc.  It copies the strings, so NAME can be a temporary
    string.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src, const char *alias,
+cp_add_using_directive (const char *dest,
+			const char *src,
+			const char *alias,
+			const char *declaration,
                         struct obstack *obstack)
 {
   struct using_direct *current;
@@ -165,6 +170,9 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
   if (alias != NULL)
     new->alias = obsavestring (alias, strlen (alias), obstack);
 
+  if (declaration != NULL)
+    new->declaration = savestring (declaration, strlen (declaration));
+
   new->next = using_directives;
   using_directives = new;
 }
@@ -238,11 +246,10 @@ cp_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
@@ -280,7 +287,15 @@ reset_directive_searched (void *data)
 }
 
 /* Search for NAME by applying all import statements belonging
-   to BLOCK which are applicable in SCOPE.
+   to BLOCK which are applicable in SCOPE.  If DECLARATION_ONLY the search
+   is restricted to using declarations.
+   Example:
+
+     namespace A{
+       int x;
+     }
+     using A::x;
+
    If SEARCH_PARENTS the search will include imports which are applicable in
    parents of SCOPE.
    Example:
@@ -293,26 +308,28 @@ reset_directive_searched (void *data)
      }
 
    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the import of Y
    is considered.  */
 
-static struct symbol *
+struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
                           const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
+			  const int declaration_only,
                           const int search_parents)
 {
   struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
   int len;
   int directive_match;
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
   if (sym != NULL)
     return sym;
 
@@ -341,6 +358,31 @@ cp_lookup_symbol_imports (const char *scope,
 	current->searched = 1;
 	searched_cleanup = make_cleanup (reset_directive_searched, current);
 
+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
 	if (current->alias != NULL && strcmp (name, current->alias) == 0)
 	  /* If the import is creating an alias and the alias matches the
 	     sought name.  Pass current->import_src as the NAME to direct the
@@ -361,6 +403,7 @@ cp_lookup_symbol_imports (const char *scope,
 	                                    linkage_name,
 	                                    block,
 	                                    domain,
+	                                    0,
 	                                    0);
 	  }
 	current->searched = 0;
@@ -383,16 +426,21 @@ cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const char *linkage_name,
                             const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
 {
   struct symbol *sym;
 
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if (sym != NULL)
+    return sym;
+
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
       sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
-                                      search_parents);
+                                      0, 1);
 
       if (sym)
 	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 23ed686..ac8ee21 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
    Eg:
        namespace C = A::B;
    ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
 */
 
 struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
   char *import_dest;
 
   char *alias;
+  char *declaration;
 
   struct using_direct *next;
 
@@ -91,6 +97,7 @@ extern int cp_is_anonymous (const char *namespace);
 extern void cp_add_using_directive (const char *dest,
                                     const char *src,
                                     const char *alias,
+				    const char *declaration,
                                     struct obstack *obstack);
 
 extern void cp_initialize_namespace (void);
@@ -116,8 +123,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
 						  const char *linkage_name,
 						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index c7c96c9..86f3922 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,10 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_cu *imported_cu;
   const char *imported_name;
   const char *imported_name_prefix;
-  char *import_alias;
-
-  const char *import_prefix;
   char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
+  const char *import_prefix;
 
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
@@ -3448,23 +3448,32 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, imported_cu);
 
-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
     {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = (char *) imported_name_prefix;
     }
   else
     {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      if (strlen (imported_name_prefix) > 0)
+        {
+          canonical_name = alloca (strlen (imported_name_prefix)
+                                   + 2 + strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name_prefix);
+          strcat (canonical_name, "::");
+          strcat (canonical_name, imported_name);
+        }
+      else
+        {
+          canonical_name = alloca (strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name);
+        }
     }
 
   cp_add_using_directive (import_prefix,
                           canonical_name,
                           import_alias,
+                          imported_declaration,
                           &cu->objfile->objfile_obstack);
 }
 
@@ -5625,7 +5634,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
 	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
-	                          &objfile->objfile_obstack);
+	                          NULL, &objfile->objfile_obstack);
 	}
     }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
 						     name, NULL,
 						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
 	      if (function == NULL)
 		error (_("No symbol \"%s\" in namespace \"%s\"."), 
 		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..1a8d5ad 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
 struct symbol *lookup_symbol_aux_local (const char *name,
 					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language);
   if (sym != NULL)
     return sym;
 
   /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */
 
   langdef = language_def (language);
-
   if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
       && block != NULL)
     {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
 			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);
 
   /* Check if either no block is specified or it's a global block.  */
 
@@ -1446,6 +1448,19 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
       if (sym != NULL)
 	return sym;
 
+      if (language == language_cplus)
+        {
+          sym = cp_lookup_symbol_imports (scope,
+                                          name,
+                                          linkage_name,
+                                          block,
+                                          domain,
+                                          1,
+                                          1);
+          if (sym != NULL)
+            return sym;
+        }
+
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
 	break;
       block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
-setup_kfail "gdb/7936" "*-*-*"
+
 gdb_test "print dx" "= 4"
 
 ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                 using namespace A;
                 y++; // marker4
 
-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
               }
           }
       }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
-setup_kfail "gdb/7936" "*-*-*"
 gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,
 
   sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
 				    get_selected_block (0), 
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);
 
   if (sym == NULL)
     return NULL;

[-- Attachment #2: declaration.patch --]
[-- Type: text/plain, Size: 16845 bytes --]


    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        PR c++/7936:
        * cp-support.h: Added char *declaration element to using_direct
        data struct.
        (cp_add_using): Added char *declaration argument.
        (cp_add_using_directive): Ditto.
        (cp_lookup_symbol_imports): made extern.
        * cp-namespace.c: Updated with the above changes.
        * dwarf2read.c (read_import_statement): Ditto.
        (read_namespace): Ditto.
        (read_import_statement): Support import declarations.
        * cp-namespace.c (cp_lookup_symbol_imports): Check for imported
        declarations.
        Added support for 'declaration_only' search.
        (cp_lookup_symbol_namespace): Attempt to search for the name as
        is before consideration of imports.
        * symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
        search at every block level search.
        Now takes language argument.
        (lookup_symbol_aux): Updated.
    
    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        * gdb.cp/shadow.exp: Removed kfail; test has been fix.
        * gdb.cp/nsusing.exp: Ditto.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 173924b..dd7227f 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -118,7 +118,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol,
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL, obstack);
+	      cp_add_using_directive (dest, src, NULL, NULL, obstack);
 	    }
 	  /* The "+ 2" is for the "::".  */
 	  previous_component = next_component + 2;
@@ -135,12 +135,17 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol,
    Create a new struct using direct which imports the namespace SRC into the
    scope DEST.  ALIAS is the name of the imported namespace in the current
    scope.  If ALIAS is NULL then the namespace is known by its original name.
+   DECLARATION is the name if the imported varable if this is a declaration
+   import (Eg. using A::x), otherwise it is NULL.
    Set its next member in the linked list to NEXT; allocate all memory
    using xmalloc.  It copies the strings, so NAME can be a temporary
    string.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src, const char *alias,
+cp_add_using_directive (const char *dest,
+			const char *src,
+			const char *alias,
+			const char *declaration,
                         struct obstack *obstack)
 {
   struct using_direct *current;
@@ -165,6 +170,9 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
   if (alias != NULL)
     new->alias = obsavestring (alias, strlen (alias), obstack);
 
+  if (declaration != NULL)
+    new->declaration = savestring (declaration, strlen (declaration));
+
   new->next = using_directives;
   using_directives = new;
 }
@@ -238,11 +246,10 @@ cp_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
@@ -280,7 +287,15 @@ reset_directive_searched (void *data)
 }
 
 /* Search for NAME by applying all import statements belonging
-   to BLOCK which are applicable in SCOPE.
+   to BLOCK which are applicable in SCOPE.  If DECLARATION_ONLY the search
+   is restricted to using declarations.
+   Example:
+
+     namespace A{
+       int x;
+     }
+     using A::x;
+
    If SEARCH_PARENTS the search will include imports which are applicable in
    parents of SCOPE.
    Example:
@@ -293,26 +308,28 @@ reset_directive_searched (void *data)
      }
 
    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the import of Y
    is considered.  */
 
-static struct symbol *
+struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
                           const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
+			  const int declaration_only,
                           const int search_parents)
 {
   struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
   int len;
   int directive_match;
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
   if (sym != NULL)
     return sym;
 
@@ -341,6 +358,31 @@ cp_lookup_symbol_imports (const char *scope,
 	current->searched = 1;
 	searched_cleanup = make_cleanup (reset_directive_searched, current);
 
+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
 	if (current->alias != NULL && strcmp (name, current->alias) == 0)
 	  /* If the import is creating an alias and the alias matches the
 	     sought name.  Pass current->import_src as the NAME to direct the
@@ -361,6 +403,7 @@ cp_lookup_symbol_imports (const char *scope,
 	                                    linkage_name,
 	                                    block,
 	                                    domain,
+	                                    0,
 	                                    0);
 	  }
 	current->searched = 0;
@@ -383,16 +426,21 @@ cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const char *linkage_name,
                             const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
 {
   struct symbol *sym;
 
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if (sym != NULL)
+    return sym;
+
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
       sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
-                                      search_parents);
+                                      0, 1);
 
       if (sym)
 	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 23ed686..ac8ee21 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
    Eg:
        namespace C = A::B;
    ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
 */
 
 struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
   char *import_dest;
 
   char *alias;
+  char *declaration;
 
   struct using_direct *next;
 
@@ -91,6 +97,7 @@ extern int cp_is_anonymous (const char *namespace);
 extern void cp_add_using_directive (const char *dest,
                                     const char *src,
                                     const char *alias,
+				    const char *declaration,
                                     struct obstack *obstack);
 
 extern void cp_initialize_namespace (void);
@@ -116,8 +123,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
 						  const char *linkage_name,
 						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index c7c96c9..86f3922 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,10 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_cu *imported_cu;
   const char *imported_name;
   const char *imported_name_prefix;
-  char *import_alias;
-
-  const char *import_prefix;
   char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
+  const char *import_prefix;
 
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
@@ -3448,23 +3448,32 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, imported_cu);
 
-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
     {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = (char *) imported_name_prefix;
     }
   else
     {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      if (strlen (imported_name_prefix) > 0)
+        {
+          canonical_name = alloca (strlen (imported_name_prefix)
+                                   + 2 + strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name_prefix);
+          strcat (canonical_name, "::");
+          strcat (canonical_name, imported_name);
+        }
+      else
+        {
+          canonical_name = alloca (strlen (imported_name) + 1);
+          strcpy (canonical_name, imported_name);
+        }
     }
 
   cp_add_using_directive (import_prefix,
                           canonical_name,
                           import_alias,
+                          imported_declaration,
                           &cu->objfile->objfile_obstack);
 }
 
@@ -5625,7 +5634,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
 	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
-	                          &objfile->objfile_obstack);
+	                          NULL, &objfile->objfile_obstack);
 	}
     }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
 						     name, NULL,
 						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
 	      if (function == NULL)
 		error (_("No symbol \"%s\" in namespace \"%s\"."), 
 		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..1a8d5ad 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
 struct symbol *lookup_symbol_aux_local (const char *name,
 					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language);
   if (sym != NULL)
     return sym;
 
   /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */
 
   langdef = language_def (language);
-
   if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
       && block != NULL)
     {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
 			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);
 
   /* Check if either no block is specified or it's a global block.  */
 
@@ -1446,6 +1448,19 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
       if (sym != NULL)
 	return sym;
 
+      if (language == language_cplus)
+        {
+          sym = cp_lookup_symbol_imports (scope,
+                                          name,
+                                          linkage_name,
+                                          block,
+                                          domain,
+                                          1,
+                                          1);
+          if (sym != NULL)
+            return sym;
+        }
+
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
 	break;
       block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
-setup_kfail "gdb/7936" "*-*-*"
+
 gdb_test "print dx" "= 4"
 
 ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                 using namespace A;
                 y++; // marker4
 
-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
               }
           }
       }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
-setup_kfail "gdb/7936" "*-*-*"
 gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,
 
   sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
 				    get_selected_block (0), 
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);
 
   if (sym == NULL)
     return NULL;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search   order
  2010-03-03 21:46     ` Sami Wagiaalla
@ 2010-03-03 22:00       ` Tom Tromey
  2010-03-08 16:39         ` Sami Wagiaalla
  0 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2010-03-03 22:00 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: gdb-patches

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

Sami>    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
Sami>         PR c++/7936:

Getting close...

Sami> +cp_add_using_directive (const char *dest,
Sami> +			const char *src,
Sami> +			const char *alias,
Sami> +			const char *declaration,
Sami>                         struct obstack *obstack)
[...]
Sami> +  if (declaration != NULL)
Sami> +    new->declaration = savestring (declaration, strlen (declaration));

obsavestring

Does the duplicate exclusion logic here need to be updated to account
for the new field?

Sami> @@ -3448,23 +3448,32 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
Sami> +      canonical_name = (char *) imported_name_prefix;

I don't think you should need to cast away const in this function.
There is some other way to make it work, like having a non-const
temporary hold the result of alloca.

Sami> +      else
Sami> +        {
Sami> +          canonical_name = alloca (strlen (imported_name) + 1);
Sami> +          strcpy (canonical_name, imported_name);
Sami> +        }

I think this is a pointless copy, just do canonical_name = imported_name.

thanks,
Tom

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search    order
  2010-03-03 22:00       ` Tom Tromey
@ 2010-03-08 16:39         ` Sami Wagiaalla
  2010-03-08 18:58           ` Tom Tromey
  0 siblings, 1 reply; 16+ messages in thread
From: Sami Wagiaalla @ 2010-03-08 16:39 UTC (permalink / raw)
  To: tromey; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 17298 bytes --]

Corrected patch:

    2010-03-08  Sami Wagiaalla  <swagiaal@redhat.com>
    
        PR c++/7936:
        * cp-support.h: Added char *declaration element to using_direct
        data struct.
        (cp_add_using): Added char *declaration argument.
        (cp_add_using_directive): Ditto.
        (cp_lookup_symbol_imports): made extern.
        * cp-namespace.c: Updated with the above changes.
        * dwarf2read.c (read_import_statement): Ditto.
        (read_namespace): Ditto.
        (read_import_statement): Support import declarations.
        * cp-namespace.c (cp_lookup_symbol_imports): Check for imported
        declarations.
        Added support for 'declaration_only' search.
        (cp_lookup_symbol_namespace): Attempt to search for the name as
        is before consideration of imports.
        * symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
        search at every block level search.
        Now takes language argument.
        (lookup_symbol_aux): Updated.
    
    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        * gdb.cp/shadow.exp: Removed kfail; test has been fix.
        * gdb.cp/nsusing.exp: Ditto.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 3880141..71e4cf5 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -117,7 +117,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL,
+	      cp_add_using_directive (dest, src, NULL, NULL,
 	                              &SYMBOL_SYMTAB (symbol)->objfile->objfile_obstack);
 	    }
 	  /* The "+ 2" is for the "::".  */
@@ -135,11 +135,15 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
    Create a new struct using_direct which imports the namespace SRC into the
    scope DEST.  ALIAS is the name of the imported namespace in the current
    scope.  If ALIAS is NULL then the namespace is known by its original name.
-   The arguments are copied into newly allocated memory so they can be 
-   temporaries.  */
+   DECLARATION is the name if the imported varable if this is a declaration
+   import (Eg. using A::x), otherwise it is NULL. The arguments are copied
+   into newly allocated memory so they can be temporaries.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src, const char *alias,
+cp_add_using_directive (const char *dest,
+			const char *src,
+			const char *alias,
+			const char *declaration,
                         struct obstack *obstack)
 {
   struct using_direct *current;
@@ -152,7 +156,9 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
       if (strcmp (current->import_src, src) == 0
           && strcmp (current->import_dest, dest) == 0
           && ((!alias && !current->alias)
-              || strcmp (current->alias, alias) == 0))
+              || strcmp (current->alias, alias) == 0)
+          && ((!declaration && !current->declaration)
+              || strcmp (current->declaration, declaration) == 0))
 	return;
     }
 
@@ -164,6 +170,10 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
   if (alias != NULL)
     new->alias = obsavestring (alias, strlen (alias), obstack);
 
+  if (declaration != NULL)
+    new->declaration = obsavestring (declaration, strlen (declaration),
+                                     obstack);
+
   new->next = using_directives;
   using_directives = new;
 }
@@ -237,11 +247,10 @@ cp_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
@@ -279,7 +288,15 @@ reset_directive_searched (void *data)
 }
 
 /* Search for NAME by applying all import statements belonging
-   to BLOCK which are applicable in SCOPE.
+   to BLOCK which are applicable in SCOPE.  If DECLARATION_ONLY the search
+   is restricted to using declarations.
+   Example:
+
+     namespace A{
+       int x;
+     }
+     using A::x;
+
    If SEARCH_PARENTS the search will include imports which are applicable in
    parents of SCOPE.
    Example:
@@ -292,26 +309,28 @@ reset_directive_searched (void *data)
      }
 
    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the import of Y
    is considered.  */
 
-static struct symbol *
+struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
                           const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
+			  const int declaration_only,
                           const int search_parents)
 {
   struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
   int len;
   int directive_match;
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
   if (sym != NULL)
     return sym;
 
@@ -340,6 +359,31 @@ cp_lookup_symbol_imports (const char *scope,
 	current->searched = 1;
 	searched_cleanup = make_cleanup (reset_directive_searched, current);
 
+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
 	if (current->alias != NULL && strcmp (name, current->alias) == 0)
 	  /* If the import is creating an alias and the alias matches the
 	     sought name.  Pass current->import_src as the NAME to direct the
@@ -360,6 +404,7 @@ cp_lookup_symbol_imports (const char *scope,
 	                                    linkage_name,
 	                                    block,
 	                                    domain,
+	                                    0,
 	                                    0);
 	  }
 	current->searched = 0;
@@ -382,16 +427,21 @@ cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const char *linkage_name,
                             const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
 {
   struct symbol *sym;
 
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if (sym != NULL)
+    return sym;
+
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
       sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
-                                      search_parents);
+                                      0, 1);
 
       if (sym)
 	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 3921a5f..3fc93a4 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
    Eg:
        namespace C = A::B;
    ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
 */
 
 struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
   char *import_dest;
 
   char *alias;
+  char *declaration;
 
   struct using_direct *next;
 
@@ -91,6 +97,7 @@ extern int cp_is_anonymous (const char *namespace);
 extern void cp_add_using_directive (const char *dest,
                                     const char *src,
                                     const char *alias,
+				    const char *declaration,
                                     struct obstack *obstack);
 
 extern void cp_initialize_namespace (void);
@@ -115,8 +122,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
 						  const char *linkage_name,
 						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 447424e..ac04c68 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,12 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_cu *imported_cu;
   const char *imported_name;
   const char *imported_name_prefix;
-  char *import_alias;
-
+  const char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
   const char *import_prefix;
-  char *canonical_name;
+
+  char *temp;
 
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
@@ -3448,23 +3450,27 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, imported_cu);
 
-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
     {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = imported_name_prefix;
     }
-  else
+  else if (strlen (imported_name_prefix) > 0)
     {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      temp = alloca (strlen (imported_name_prefix)
+                     + 2 + strlen (imported_name) + 1);
+      strcpy (temp, imported_name_prefix);
+      strcat (temp, "::");
+      strcat (temp, imported_name);
+      canonical_name = temp;
     }
+  else
+    canonical_name = imported_name;
 
   cp_add_using_directive (import_prefix,
                           canonical_name,
                           import_alias,
+                          imported_declaration,
                           &cu->objfile->objfile_obstack);
 }
 
@@ -5625,7 +5631,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
 	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
-	                          &objfile->objfile_obstack);
+	                          NULL, &objfile->objfile_obstack);
 	}
     }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
 						     name, NULL,
 						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
 	      if (function == NULL)
 		error (_("No symbol \"%s\" in namespace \"%s\"."), 
 		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..1a8d5ad 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
 struct symbol *lookup_symbol_aux_local (const char *name,
 					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language);
   if (sym != NULL)
     return sym;
 
   /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */
 
   langdef = language_def (language);
-
   if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
       && block != NULL)
     {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
 			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);
 
   /* Check if either no block is specified or it's a global block.  */
 
@@ -1446,6 +1448,19 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
       if (sym != NULL)
 	return sym;
 
+      if (language == language_cplus)
+        {
+          sym = cp_lookup_symbol_imports (scope,
+                                          name,
+                                          linkage_name,
+                                          block,
+                                          domain,
+                                          1,
+                                          1);
+          if (sym != NULL)
+            return sym;
+        }
+
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
 	break;
       block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
-setup_kfail "gdb/7936" "*-*-*"
+
 gdb_test "print dx" "= 4"
 
 ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                 using namespace A;
                 y++; // marker4
 
-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
               }
           }
       }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
-setup_kfail "gdb/7936" "*-*-*"
 gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,
 
   sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
 				    get_selected_block (0), 
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);
 
   if (sym == NULL)
     return NULL;

[-- Attachment #2: declaration.patch --]
[-- Type: text/plain, Size: 17281 bytes --]


    2010-03-08  Sami Wagiaalla  <swagiaal@redhat.com>
    
        PR c++/7936:
        * cp-support.h: Added char *declaration element to using_direct
        data struct.
        (cp_add_using): Added char *declaration argument.
        (cp_add_using_directive): Ditto.
        (cp_lookup_symbol_imports): made extern.
        * cp-namespace.c: Updated with the above changes.
        * dwarf2read.c (read_import_statement): Ditto.
        (read_namespace): Ditto.
        (read_import_statement): Support import declarations.
        * cp-namespace.c (cp_lookup_symbol_imports): Check for imported
        declarations.
        Added support for 'declaration_only' search.
        (cp_lookup_symbol_namespace): Attempt to search for the name as
        is before consideration of imports.
        * symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
        search at every block level search.
        Now takes language argument.
        (lookup_symbol_aux): Updated.
    
    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        * gdb.cp/shadow.exp: Removed kfail; test has been fix.
        * gdb.cp/nsusing.exp: Ditto.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 3880141..71e4cf5 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -117,7 +117,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL,
+	      cp_add_using_directive (dest, src, NULL, NULL,
 	                              &SYMBOL_SYMTAB (symbol)->objfile->objfile_obstack);
 	    }
 	  /* The "+ 2" is for the "::".  */
@@ -135,11 +135,15 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
    Create a new struct using_direct which imports the namespace SRC into the
    scope DEST.  ALIAS is the name of the imported namespace in the current
    scope.  If ALIAS is NULL then the namespace is known by its original name.
-   The arguments are copied into newly allocated memory so they can be 
-   temporaries.  */
+   DECLARATION is the name if the imported varable if this is a declaration
+   import (Eg. using A::x), otherwise it is NULL. The arguments are copied
+   into newly allocated memory so they can be temporaries.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src, const char *alias,
+cp_add_using_directive (const char *dest,
+			const char *src,
+			const char *alias,
+			const char *declaration,
                         struct obstack *obstack)
 {
   struct using_direct *current;
@@ -152,7 +156,9 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
       if (strcmp (current->import_src, src) == 0
           && strcmp (current->import_dest, dest) == 0
           && ((!alias && !current->alias)
-              || strcmp (current->alias, alias) == 0))
+              || strcmp (current->alias, alias) == 0)
+          && ((!declaration && !current->declaration)
+              || strcmp (current->declaration, declaration) == 0))
 	return;
     }
 
@@ -164,6 +170,10 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
   if (alias != NULL)
     new->alias = obsavestring (alias, strlen (alias), obstack);
 
+  if (declaration != NULL)
+    new->declaration = obsavestring (declaration, strlen (declaration),
+                                     obstack);
+
   new->next = using_directives;
   using_directives = new;
 }
@@ -237,11 +247,10 @@ cp_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
@@ -279,7 +288,15 @@ reset_directive_searched (void *data)
 }
 
 /* Search for NAME by applying all import statements belonging
-   to BLOCK which are applicable in SCOPE.
+   to BLOCK which are applicable in SCOPE.  If DECLARATION_ONLY the search
+   is restricted to using declarations.
+   Example:
+
+     namespace A{
+       int x;
+     }
+     using A::x;
+
    If SEARCH_PARENTS the search will include imports which are applicable in
    parents of SCOPE.
    Example:
@@ -292,26 +309,28 @@ reset_directive_searched (void *data)
      }
 
    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the import of Y
    is considered.  */
 
-static struct symbol *
+struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
                           const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
+			  const int declaration_only,
                           const int search_parents)
 {
   struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
   int len;
   int directive_match;
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
   if (sym != NULL)
     return sym;
 
@@ -340,6 +359,31 @@ cp_lookup_symbol_imports (const char *scope,
 	current->searched = 1;
 	searched_cleanup = make_cleanup (reset_directive_searched, current);
 
+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
 	if (current->alias != NULL && strcmp (name, current->alias) == 0)
 	  /* If the import is creating an alias and the alias matches the
 	     sought name.  Pass current->import_src as the NAME to direct the
@@ -360,6 +404,7 @@ cp_lookup_symbol_imports (const char *scope,
 	                                    linkage_name,
 	                                    block,
 	                                    domain,
+	                                    0,
 	                                    0);
 	  }
 	current->searched = 0;
@@ -382,16 +427,21 @@ cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const char *linkage_name,
                             const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
 {
   struct symbol *sym;
 
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if (sym != NULL)
+    return sym;
+
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
       sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
-                                      search_parents);
+                                      0, 1);
 
       if (sym)
 	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 3921a5f..3fc93a4 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
    Eg:
        namespace C = A::B;
    ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
 */
 
 struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
   char *import_dest;
 
   char *alias;
+  char *declaration;
 
   struct using_direct *next;
 
@@ -91,6 +97,7 @@ extern int cp_is_anonymous (const char *namespace);
 extern void cp_add_using_directive (const char *dest,
                                     const char *src,
                                     const char *alias,
+				    const char *declaration,
                                     struct obstack *obstack);
 
 extern void cp_initialize_namespace (void);
@@ -115,8 +122,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
 						  const char *linkage_name,
 						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 447424e..ac04c68 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,12 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_cu *imported_cu;
   const char *imported_name;
   const char *imported_name_prefix;
-  char *import_alias;
-
+  const char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
   const char *import_prefix;
-  char *canonical_name;
+
+  char *temp;
 
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
@@ -3448,23 +3450,27 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, imported_cu);
 
-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
     {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = imported_name_prefix;
     }
-  else
+  else if (strlen (imported_name_prefix) > 0)
     {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      temp = alloca (strlen (imported_name_prefix)
+                     + 2 + strlen (imported_name) + 1);
+      strcpy (temp, imported_name_prefix);
+      strcat (temp, "::");
+      strcat (temp, imported_name);
+      canonical_name = temp;
     }
+  else
+    canonical_name = imported_name;
 
   cp_add_using_directive (import_prefix,
                           canonical_name,
                           import_alias,
+                          imported_declaration,
                           &cu->objfile->objfile_obstack);
 }
 
@@ -5625,7 +5631,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
 	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
-	                          &objfile->objfile_obstack);
+	                          NULL, &objfile->objfile_obstack);
 	}
     }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
 						     name, NULL,
 						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
 	      if (function == NULL)
 		error (_("No symbol \"%s\" in namespace \"%s\"."), 
 		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..1a8d5ad 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
 struct symbol *lookup_symbol_aux_local (const char *name,
 					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language);
   if (sym != NULL)
     return sym;
 
   /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */
 
   langdef = language_def (language);
-
   if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
       && block != NULL)
     {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
 			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);
 
   /* Check if either no block is specified or it's a global block.  */
 
@@ -1446,6 +1448,19 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
       if (sym != NULL)
 	return sym;
 
+      if (language == language_cplus)
+        {
+          sym = cp_lookup_symbol_imports (scope,
+                                          name,
+                                          linkage_name,
+                                          block,
+                                          domain,
+                                          1,
+                                          1);
+          if (sym != NULL)
+            return sym;
+        }
+
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
 	break;
       block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
-setup_kfail "gdb/7936" "*-*-*"
+
 gdb_test "print dx" "= 4"
 
 ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                 using namespace A;
                 y++; // marker4
 
-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
               }
           }
       }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
-setup_kfail "gdb/7936" "*-*-*"
 gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,
 
   sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
 				    get_selected_block (0), 
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);
 
   if (sym == NULL)
     return NULL;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search order
  2010-03-08 16:39         ` Sami Wagiaalla
@ 2010-03-08 18:58           ` Tom Tromey
  2010-03-09 18:21             ` Sami Wagiaalla
  0 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2010-03-08 18:58 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: gdb-patches

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

Sami> +          && ((!declaration && !current->declaration)
Sami> +              || strcmp (current->declaration, declaration) == 0))

I think this check is wrong in the same way as the alias check in the
previous patch.

Tom

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search  order
  2010-03-08 18:58           ` Tom Tromey
@ 2010-03-09 18:21             ` Sami Wagiaalla
  2010-03-09 18:27               ` Tom Tromey
  2010-03-23 20:31               ` Ulrich Weigand
  0 siblings, 2 replies; 16+ messages in thread
From: Sami Wagiaalla @ 2010-03-09 18:21 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 17723 bytes --]

On 03/08/2010 01:58 PM, Tom Tromey wrote:
>>>>>> "Sami" == Sami Wagiaalla<swagiaal@redhat.com>  writes:
> 
> Sami>  +&&  ((!declaration&&  !current->declaration)
> Sami>  +              || strcmp (current->declaration, declaration) == 0))
> 
> I think this check is wrong in the same way as the alias check in the
> previous patch.
> 

Corrected and rebased:


    2010-03-09  Sami Wagiaalla  <swagiaal@redhat.com>
    
        PR c++/7936:
        * cp-support.h: Added char *declaration element to using_direct
        data struct.
        (cp_add_using): Added char *declaration argument.
        (cp_add_using_directive): Ditto.
        (cp_lookup_symbol_imports): made extern.
        * cp-namespace.c: Updated with the above changes.
        * dwarf2read.c (read_import_statement): Ditto.
        (read_namespace): Ditto.
        (read_import_statement): Support import declarations.
        * cp-namespace.c (cp_lookup_symbol_imports): Check for imported
        declarations.
        Added support for 'declaration_only' search.
        (cp_lookup_symbol_namespace): Attempt to search for the name as
        is before consideration of imports.
        * symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
        search at every block level search.
        Now takes language argument.
        (lookup_symbol_aux): Updated.
    
    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        * gdb.cp/shadow.exp: Removed kfail; test has been fix.
        * gdb.cp/nsusing.exp: Ditto.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 7593475..bf7f254 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -117,7 +117,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL,
+	      cp_add_using_directive (dest, src, NULL, NULL,
 	                              &SYMBOL_SYMTAB (symbol)->objfile->objfile_obstack);
 	    }
 	  /* The "+ 2" is for the "::".  */
@@ -135,11 +135,15 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
    Create a new struct using_direct which imports the namespace SRC into the
    scope DEST.  ALIAS is the name of the imported namespace in the current
    scope.  If ALIAS is NULL then the namespace is known by its original name.
-   The arguments are copied into newly allocated memory so they can be 
-   temporaries.  */
+   DECLARATION is the name if the imported varable if this is a declaration
+   import (Eg. using A::x), otherwise it is NULL. The arguments are copied
+   into newly allocated memory so they can be temporaries.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src, const char *alias,
+cp_add_using_directive (const char *dest,
+			const char *src,
+			const char *alias,
+			const char *declaration,
                         struct obstack *obstack)
 {
   struct using_direct *current;
@@ -153,7 +157,10 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
           && strcmp (current->import_dest, dest) == 0
           && ((alias == NULL && current->alias == NULL)
               || (alias != NULL && current->alias != NULL
-        	  && strcmp (alias, current->alias) == 0)))
+        	  && strcmp (alias, current->alias) == 0))
+	  && ((declaration == NULL && current->declaration == NULL)
+	      || (declaration != NULL && current->declaration != NULL
+		  && strcmp (declaration, current->declaration) == 0)))
 	return;
     }
 
@@ -165,6 +172,10 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
   if (alias != NULL)
     new->alias = obsavestring (alias, strlen (alias), obstack);
 
+  if (declaration != NULL)
+    new->declaration = obsavestring (declaration, strlen (declaration),
+                                     obstack);
+
   new->next = using_directives;
   using_directives = new;
 }
@@ -238,11 +249,10 @@ cp_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
@@ -280,7 +290,15 @@ reset_directive_searched (void *data)
 }
 
 /* Search for NAME by applying all import statements belonging
-   to BLOCK which are applicable in SCOPE.
+   to BLOCK which are applicable in SCOPE.  If DECLARATION_ONLY the search
+   is restricted to using declarations.
+   Example:
+
+     namespace A{
+       int x;
+     }
+     using A::x;
+
    If SEARCH_PARENTS the search will include imports which are applicable in
    parents of SCOPE.
    Example:
@@ -293,26 +311,28 @@ reset_directive_searched (void *data)
      }
 
    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the import of Y
    is considered.  */
 
-static struct symbol *
+struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
                           const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
+			  const int declaration_only,
                           const int search_parents)
 {
   struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
   int len;
   int directive_match;
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
   if (sym != NULL)
     return sym;
 
@@ -341,6 +361,31 @@ cp_lookup_symbol_imports (const char *scope,
 	current->searched = 1;
 	searched_cleanup = make_cleanup (reset_directive_searched, current);
 
+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
 	if (current->alias != NULL && strcmp (name, current->alias) == 0)
 	  /* If the import is creating an alias and the alias matches the
 	     sought name.  Pass current->import_src as the NAME to direct the
@@ -361,6 +406,7 @@ cp_lookup_symbol_imports (const char *scope,
 	                                    linkage_name,
 	                                    block,
 	                                    domain,
+	                                    0,
 	                                    0);
 	  }
 	current->searched = 0;
@@ -383,16 +429,21 @@ cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const char *linkage_name,
                             const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
 {
   struct symbol *sym;
 
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if (sym != NULL)
+    return sym;
+
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
       sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
-                                      search_parents);
+                                      0, 1);
 
       if (sym)
 	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 3921a5f..3fc93a4 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
    Eg:
        namespace C = A::B;
    ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
 */
 
 struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
   char *import_dest;
 
   char *alias;
+  char *declaration;
 
   struct using_direct *next;
 
@@ -91,6 +97,7 @@ extern int cp_is_anonymous (const char *namespace);
 extern void cp_add_using_directive (const char *dest,
                                     const char *src,
                                     const char *alias,
+				    const char *declaration,
                                     struct obstack *obstack);
 
 extern void cp_initialize_namespace (void);
@@ -115,8 +122,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
 						  const char *linkage_name,
 						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 447424e..ac04c68 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,12 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_cu *imported_cu;
   const char *imported_name;
   const char *imported_name_prefix;
-  char *import_alias;
-
+  const char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
   const char *import_prefix;
-  char *canonical_name;
+
+  char *temp;
 
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
@@ -3448,23 +3450,27 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, imported_cu);
 
-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
     {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = imported_name_prefix;
     }
-  else
+  else if (strlen (imported_name_prefix) > 0)
     {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      temp = alloca (strlen (imported_name_prefix)
+                     + 2 + strlen (imported_name) + 1);
+      strcpy (temp, imported_name_prefix);
+      strcat (temp, "::");
+      strcat (temp, imported_name);
+      canonical_name = temp;
     }
+  else
+    canonical_name = imported_name;
 
   cp_add_using_directive (import_prefix,
                           canonical_name,
                           import_alias,
+                          imported_declaration,
                           &cu->objfile->objfile_obstack);
 }
 
@@ -5625,7 +5631,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
 	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
-	                          &objfile->objfile_obstack);
+	                          NULL, &objfile->objfile_obstack);
 	}
     }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
 						     name, NULL,
 						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
 	      if (function == NULL)
 		error (_("No symbol \"%s\" in namespace \"%s\"."), 
 		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..1a8d5ad 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
 struct symbol *lookup_symbol_aux_local (const char *name,
 					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language);
   if (sym != NULL)
     return sym;
 
   /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */
 
   langdef = language_def (language);
-
   if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
       && block != NULL)
     {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
 			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);
 
   /* Check if either no block is specified or it's a global block.  */
 
@@ -1446,6 +1448,19 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
       if (sym != NULL)
 	return sym;
 
+      if (language == language_cplus)
+        {
+          sym = cp_lookup_symbol_imports (scope,
+                                          name,
+                                          linkage_name,
+                                          block,
+                                          domain,
+                                          1,
+                                          1);
+          if (sym != NULL)
+            return sym;
+        }
+
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
 	break;
       block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
-setup_kfail "gdb/7936" "*-*-*"
+
 gdb_test "print dx" "= 4"
 
 ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                 using namespace A;
                 y++; // marker4
 
-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
               }
           }
       }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
-setup_kfail "gdb/7936" "*-*-*"
 gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,
 
   sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
 				    get_selected_block (0), 
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);
 
   if (sym == NULL)
     return NULL;

[-- Attachment #2: declaration.patch --]
[-- Type: text/plain, Size: 17363 bytes --]


    2010-03-09  Sami Wagiaalla  <swagiaal@redhat.com>
    
        PR c++/7936:
        * cp-support.h: Added char *declaration element to using_direct
        data struct.
        (cp_add_using): Added char *declaration argument.
        (cp_add_using_directive): Ditto.
        (cp_lookup_symbol_imports): made extern.
        * cp-namespace.c: Updated with the above changes.
        * dwarf2read.c (read_import_statement): Ditto.
        (read_namespace): Ditto.
        (read_import_statement): Support import declarations.
        * cp-namespace.c (cp_lookup_symbol_imports): Check for imported
        declarations.
        Added support for 'declaration_only' search.
        (cp_lookup_symbol_namespace): Attempt to search for the name as
        is before consideration of imports.
        * symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
        search at every block level search.
        Now takes language argument.
        (lookup_symbol_aux): Updated.
    
    2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
    
        * gdb.cp/shadow.exp: Removed kfail; test has been fix.
        * gdb.cp/nsusing.exp: Ditto.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 7593475..bf7f254 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -117,7 +117,7 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 		 anonymous namespace.  So add symbols in it to the
 		 namespace given by the previous component if there is
 		 one, or to the global namespace if there isn't.  */
-	      cp_add_using_directive (dest, src, NULL,
+	      cp_add_using_directive (dest, src, NULL, NULL,
 	                              &SYMBOL_SYMTAB (symbol)->objfile->objfile_obstack);
 	    }
 	  /* The "+ 2" is for the "::".  */
@@ -135,11 +135,15 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
    Create a new struct using_direct which imports the namespace SRC into the
    scope DEST.  ALIAS is the name of the imported namespace in the current
    scope.  If ALIAS is NULL then the namespace is known by its original name.
-   The arguments are copied into newly allocated memory so they can be 
-   temporaries.  */
+   DECLARATION is the name if the imported varable if this is a declaration
+   import (Eg. using A::x), otherwise it is NULL. The arguments are copied
+   into newly allocated memory so they can be temporaries.  */
 
 void
-cp_add_using_directive (const char *dest, const char *src, const char *alias,
+cp_add_using_directive (const char *dest,
+			const char *src,
+			const char *alias,
+			const char *declaration,
                         struct obstack *obstack)
 {
   struct using_direct *current;
@@ -153,7 +157,10 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
           && strcmp (current->import_dest, dest) == 0
           && ((alias == NULL && current->alias == NULL)
               || (alias != NULL && current->alias != NULL
-        	  && strcmp (alias, current->alias) == 0)))
+        	  && strcmp (alias, current->alias) == 0))
+	  && ((declaration == NULL && current->declaration == NULL)
+	      || (declaration != NULL && current->declaration != NULL
+		  && strcmp (declaration, current->declaration) == 0)))
 	return;
     }
 
@@ -165,6 +172,10 @@ cp_add_using_directive (const char *dest, const char *src, const char *alias,
   if (alias != NULL)
     new->alias = obsavestring (alias, strlen (alias), obstack);
 
+  if (declaration != NULL)
+    new->declaration = obsavestring (declaration, strlen (declaration),
+                                     obstack);
+
   new->next = using_directives;
   using_directives = new;
 }
@@ -238,11 +249,10 @@ cp_lookup_symbol_nonlocal (const char *name,
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain);
 }
 
-/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
@@ -280,7 +290,15 @@ reset_directive_searched (void *data)
 }
 
 /* Search for NAME by applying all import statements belonging
-   to BLOCK which are applicable in SCOPE.
+   to BLOCK which are applicable in SCOPE.  If DECLARATION_ONLY the search
+   is restricted to using declarations.
+   Example:
+
+     namespace A{
+       int x;
+     }
+     using A::x;
+
    If SEARCH_PARENTS the search will include imports which are applicable in
    parents of SCOPE.
    Example:
@@ -293,26 +311,28 @@ reset_directive_searched (void *data)
      }
 
    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of namespaces X
-   and Y will be considered. If SEARCH_PARENTS is false only the import of Y
+   and Y will be considered.  If SEARCH_PARENTS is false only the import of Y
    is considered.  */
 
-static struct symbol *
+struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
                           const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
+			  const int declaration_only,
                           const int search_parents)
 {
   struct using_direct *current;
-  struct symbol *sym;
+  struct symbol *sym = NULL;
   int len;
   int directive_match;
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  if (!declaration_only)
+    sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                         domain);
   if (sym != NULL)
     return sym;
 
@@ -341,6 +361,31 @@ cp_lookup_symbol_imports (const char *scope,
 	current->searched = 1;
 	searched_cleanup = make_cleanup (reset_directive_searched, current);
 
+	/* If there is an import of a single declaration, compare the imported
+	   declaration with the sought out name.  If there is a match pass
+	   current->import_src as NAMESPACE to direct the search towards the
+	   imported namespace.  */
+	if (current->declaration && strcmp (name, current->declaration) == 0)
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
+	                                       name,
+	                                       linkage_name,
+	                                       block,
+	                                       domain);
+
+	/* If this is a DECLARATION_ONLY search or a symbol was found or
+	   this import statement was an import declaration, the search
+	   of this import is complete.  */
+        if (declaration_only || sym != NULL || current->declaration)
+          {
+            current->searched = 0;
+            discard_cleanups (searched_cleanup);
+
+            if (sym != NULL)
+              return sym;
+
+            continue;
+          }
+
 	if (current->alias != NULL && strcmp (name, current->alias) == 0)
 	  /* If the import is creating an alias and the alias matches the
 	     sought name.  Pass current->import_src as the NAME to direct the
@@ -361,6 +406,7 @@ cp_lookup_symbol_imports (const char *scope,
 	                                    linkage_name,
 	                                    block,
 	                                    domain,
+	                                    0,
 	                                    0);
 	  }
 	current->searched = 0;
@@ -383,16 +429,21 @@ cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const char *linkage_name,
                             const struct block *block,
-                            const domain_enum domain,
-                            const int search_parents)
+                            const domain_enum domain)
 {
   struct symbol *sym;
 
+  /* First, try to find the symbol in the given namespace.  */
+  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
+                                       domain);
+  if (sym != NULL)
+    return sym;
+
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
       sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
-                                      search_parents);
+                                      0, 1);
 
       if (sym)
 	return sym;
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 3921a5f..3fc93a4 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -44,6 +44,11 @@ struct demangle_component;
    Eg:
        namespace C = A::B;
    ALIAS = "C"
+   DECLARATION is the name of the imported declaration, if this import
+   statement represents one.
+   Eg:
+       using A::x;
+   Where x is variable in namespace A.  DECLARATION is set to x.
 */
 
 struct using_direct
@@ -52,6 +57,7 @@ struct using_direct
   char *import_dest;
 
   char *alias;
+  char *declaration;
 
   struct using_direct *next;
 
@@ -91,6 +97,7 @@ extern int cp_is_anonymous (const char *namespace);
 extern void cp_add_using_directive (const char *dest,
                                     const char *src,
                                     const char *alias,
+				    const char *declaration,
                                     struct obstack *obstack);
 
 extern void cp_initialize_namespace (void);
@@ -115,8 +122,15 @@ extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
 						  const char *linkage_name,
 						  const struct block *block,
-						  const domain_enum domain,
-						  const int search_parents);
+						  const domain_enum domain);
+
+extern struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain,
+                                                const int declaration_only,
+                                                const int search_parents);
 
 extern struct type *cp_lookup_nested_type (struct type *parent_type,
 					   const char *nested_name,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 447424e..ac04c68 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3385,10 +3385,12 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
   struct dwarf2_cu *imported_cu;
   const char *imported_name;
   const char *imported_name_prefix;
-  char *import_alias;
-
+  const char *canonical_name;
+  const char *import_alias;
+  const char *imported_declaration = NULL;
   const char *import_prefix;
-  char *canonical_name;
+
+  char *temp;
 
   import_attr = dwarf2_attr (die, DW_AT_import, cu);
   if (import_attr == NULL)
@@ -3448,23 +3450,27 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
      to the name of the imported die.  */
   imported_name_prefix = determine_prefix (imported_die, imported_cu);
 
-  if (strlen (imported_name_prefix) > 0)
+  if (imported_die->tag != DW_TAG_namespace)
     {
-      canonical_name = alloca (strlen (imported_name_prefix)
-                               + 2 + strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name_prefix);
-      strcat (canonical_name, "::");
-      strcat (canonical_name, imported_name);
+      imported_declaration = imported_name;
+      canonical_name = imported_name_prefix;
     }
-  else
+  else if (strlen (imported_name_prefix) > 0)
     {
-      canonical_name = alloca (strlen (imported_name) + 1);
-      strcpy (canonical_name, imported_name);
+      temp = alloca (strlen (imported_name_prefix)
+                     + 2 + strlen (imported_name) + 1);
+      strcpy (temp, imported_name_prefix);
+      strcat (temp, "::");
+      strcat (temp, imported_name);
+      canonical_name = temp;
     }
+  else
+    canonical_name = imported_name;
 
   cp_add_using_directive (import_prefix,
                           canonical_name,
                           import_alias,
+                          imported_declaration,
                           &cu->objfile->objfile_obstack);
 }
 
@@ -5625,7 +5631,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
 	{
 	  const char *previous_prefix = determine_prefix (die, cu);
 	  cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
-	                          &objfile->objfile_obstack);
+	                          NULL, &objfile->objfile_obstack);
 	}
     }
 
diff --git a/gdb/eval.c b/gdb/eval.c
index e2ceea7..f48b392 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1435,7 +1435,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	      function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
 						     name, NULL,
 						     get_selected_block (0),
-						     VAR_DOMAIN, 1);
+						     VAR_DOMAIN);
 	      if (function == NULL)
 		error (_("No symbol \"%s\" in namespace \"%s\"."), 
 		       name, TYPE_TAG_NAME (type));
diff --git a/gdb/symtab.c b/gdb/symtab.c
index af4e501..1a8d5ad 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -95,7 +95,8 @@ static
 struct symbol *lookup_symbol_aux_local (const char *name,
 					const char *linkage_name,
 					const struct block *block,
-					const domain_enum domain);
+					const domain_enum domain,
+					enum language language);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
@@ -1354,15 +1355,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, linkage_name, block, domain, language);
   if (sym != NULL)
     return sym;
 
   /* If requested to do so by the caller and if appropriate for LANGUAGE,
-     check to see if NAME is a field of `this'. */
+     check to see if NAME is a field of `this'.  */
 
   langdef = language_def (language);
-
   if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
       && block != NULL)
     {
@@ -1430,10 +1430,12 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 static struct symbol *
 lookup_symbol_aux_local (const char *name, const char *linkage_name,
 			 const struct block *block,
-			 const domain_enum domain)
+			 const domain_enum domain,
+			 enum language language)
 {
   struct symbol *sym;
   const struct block *static_block = block_static_block (block);
+  const char *scope = block_scope (block);
 
   /* Check if either no block is specified or it's a global block.  */
 
@@ -1446,6 +1448,19 @@ lookup_symbol_aux_local (const char *name, const char *linkage_name,
       if (sym != NULL)
 	return sym;
 
+      if (language == language_cplus)
+        {
+          sym = cp_lookup_symbol_imports (scope,
+                                          name,
+                                          linkage_name,
+                                          block,
+                                          domain,
+                                          1,
+                                          1);
+          if (sym != NULL)
+            return sym;
+        }
+
       if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
 	break;
       block = BLOCK_SUPERBLOCK (block);
diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index 72a616e..b060ee2 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -154,7 +154,7 @@ if ![runto marker4] then {
     perror "couldn't run to breakpoint marker4"
     continue
 }
-setup_kfail "gdb/7936" "*-*-*"
+
 gdb_test "print dx" "= 4"
 
 ############################################
diff --git a/gdb/testsuite/gdb.cp/shadow.cc b/gdb/testsuite/gdb.cp/shadow.cc
index 1651510..0520b2a 100644
--- a/gdb/testsuite/gdb.cp/shadow.cc
+++ b/gdb/testsuite/gdb.cp/shadow.cc
@@ -29,8 +29,10 @@ public:
                 using namespace A;
                 y++; // marker4
 
-                using A::x;
-                y++; // marker5
+                {
+                  using A::x;
+                  y++; // marker5
+                }
               }
           }
       }
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 1e5e80b..40c35a4 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -85,5 +85,4 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
-setup_kfail "gdb/7936" "*-*-*"
 gdb_test "print x" "= 11" "Print imported namespace x"
diff --git a/gdb/valops.c b/gdb/valops.c
index b94c411..b5e47d3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -3119,7 +3119,7 @@ value_maybe_namespace_elt (const struct type *curtype,
 
   sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
 				    get_selected_block (0), 
-				    VAR_DOMAIN, 1);
+				    VAR_DOMAIN);
 
   if (sym == NULL)
     return NULL;

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search order
  2010-03-09 18:21             ` Sami Wagiaalla
@ 2010-03-09 18:27               ` Tom Tromey
  2010-03-23 20:31               ` Ulrich Weigand
  1 sibling, 0 replies; 16+ messages in thread
From: Tom Tromey @ 2010-03-09 18:27 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: gdb-patches

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

Sami>    2010-03-09  Sami Wagiaalla  <swagiaal@redhat.com>
Sami>         PR c++/7936:
Sami>        * cp-support.h: Added char *declaration element to using_direct
Sami>        data struct.
Sami>        (cp_add_using): Added char *declaration argument.
Sami>        (cp_add_using_directive): Ditto.
Sami>        (cp_lookup_symbol_imports): made extern.
Sami>        * cp-namespace.c: Updated with the above changes.
Sami>        * dwarf2read.c (read_import_statement): Ditto.
Sami>        (read_namespace): Ditto.
Sami>        (read_import_statement): Support import declarations.
Sami>        * cp-namespace.c (cp_lookup_symbol_imports): Check for imported
Sami>        declarations.
Sami>        Added support for 'declaration_only' search.
Sami>        (cp_lookup_symbol_namespace): Attempt to search for the name as
Sami>        is before consideration of imports.
Sami>        * symtab.c (lookup_symbol_aux_local): Added a 'declaration_only'
Sami>        search at every block level search.
Sami>        Now takes language argument.
Sami>        (lookup_symbol_aux): Updated.
Sami>     2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
Sami>         * gdb.cp/shadow.exp: Removed kfail; test has been fix.
Sami>        * gdb.cp/nsusing.exp: Ditto.

This is ok, thanks.

Tom

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search  order
  2010-03-09 18:21             ` Sami Wagiaalla
  2010-03-09 18:27               ` Tom Tromey
@ 2010-03-23 20:31               ` Ulrich Weigand
  2010-03-23 20:51                 ` Sami Wagiaalla
  1 sibling, 1 reply; 16+ messages in thread
From: Ulrich Weigand @ 2010-03-23 20:31 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: Tom Tromey, gdb-patches

Sami Wagiaalla wrote:

>     2010-03-03  Sami Wagiaalla  <swagiaal@redhat.com>
>     
>         * gdb.cp/shadow.exp: Removed kfail; test has been fix.

This test is now failing for me:

print x
$5 = 55
(gdb) FAIL: gdb.cp/shadow.exp: Print imported namespace x

(Same value as with GDB 7.1, except the test was KFAILed there ...)

Any suggestions where to look?

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search   order
  2010-03-23 20:31               ` Ulrich Weigand
@ 2010-03-23 20:51                 ` Sami Wagiaalla
  2010-03-23 21:35                   ` Ulrich Weigand
  0 siblings, 1 reply; 16+ messages in thread
From: Sami Wagiaalla @ 2010-03-23 20:51 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Tom Tromey, gdb-patches

On 03/23/2010 04:31 PM, Ulrich Weigand wrote:
> Sami Wagiaalla wrote:
>
>>      2010-03-03  Sami Wagiaalla<swagiaal@redhat.com>
>>
>>          * gdb.cp/shadow.exp: Removed kfail; test has been fix.
>
> This test is now failing for me:
>
> print x
> $5 = 55
> (gdb) FAIL: gdb.cp/shadow.exp: Print imported namespace x
>
> (Same value as with GDB 7.1, except the test was KFAILed there ...)
>

I can try to reproduce it. Which compiler are you using ?

> Any suggestions where to look?
>

In lookup_symbol_aux_local the call to cp_lookup_symbol_imports is 
failing so the local variable in the outer block is being found. IIRC 
the import statement was not nested correctly with older compilers so 
that would be my first guess.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search   order
  2010-03-23 20:51                 ` Sami Wagiaalla
@ 2010-03-23 21:35                   ` Ulrich Weigand
  2010-03-29 14:48                     ` Sami Wagiaalla
  0 siblings, 1 reply; 16+ messages in thread
From: Ulrich Weigand @ 2010-03-23 21:35 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: Tom Tromey, gdb-patches

Sami Wagiaalla wrote:

> On 03/23/2010 04:31 PM, Ulrich Weigand wrote:
> > This test is now failing for me:
> >
> > print x
> > $5 = 55
> > (gdb) FAIL: gdb.cp/shadow.exp: Print imported namespace x
> >
> > (Same value as with GDB 7.1, except the test was KFAILed there ...)
> >
> 
> I can try to reproduce it. Which compiler are you using ?

GCC 4.1 (the RHEL 5.4 system compiler).

> > Any suggestions where to look?
> >
> 
> In lookup_symbol_aux_local the call to cp_lookup_symbol_imports is 
> failing so the local variable in the outer block is being found. IIRC 
> the import statement was not nested correctly with older compilers so 
> that would be my first guess.

That might well be the case.  Here's the debug info I'm seeing:

The section .debug_info contains:

  Compilation Unit @ offset 0x0:
   Length:        479
   Version:       2
   Abbrev Offset: 0
   Pointer Size:  8
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
     DW_AT_stmt_list   : 0	
     DW_AT_producer    : GNU C++ 4.1.2 20080704 (Red Hat 4.1.2-46)	
     DW_AT_language    : 4	(C++)
     DW_AT_name        : /home/uweigand/fsf/gdb-head/gdb/testsuite/gdb.cp/shadow.cc	
 <1><76>: Abbrev Number: 2 (DW_TAG_class_type)
     DW_AT_sibling     : <bd>	
     DW_AT_name        : B	
     DW_AT_byte_size   : 4	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 10	
 <2><80>: Abbrev Number: 3 (DW_TAG_member)
     DW_AT_name        : x	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 12	
     DW_AT_type        : <bd>	
     DW_AT_data_member_location: 2 byte block: 23 0 	(DW_OP_plus_uconst: 0)
 <2><8c>: Abbrev Number: 4 (DW_TAG_subprogram)
     DW_AT_external    : 1	
     DW_AT_name        : func	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 15	
     DW_AT_MIPS_linkage_name: _ZN1B4funcEv	
     DW_AT_type        : <bd>	
     DW_AT_declaration : 1	
 <3><a7>: Abbrev Number: 5 (DW_TAG_formal_parameter)
     DW_AT_type        : <c4>	
     DW_AT_artificial  : 1	
 <3><ad>: Abbrev Number: 6 (DW_TAG_imported_module)
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 29	
     DW_AT_import      : <ca>	
 <3><b4>: Abbrev Number: 7 (DW_TAG_imported_declaration)
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 33	
     DW_AT_import      : <d3>	
 <1><bd>: Abbrev Number: 8 (DW_TAG_base_type)
     DW_AT_name        : int	
     DW_AT_byte_size   : 4	
     DW_AT_encoding    : 5	(signed)
 <1><c4>: Abbrev Number: 9 (DW_TAG_pointer_type)
     DW_AT_byte_size   : 8	
     DW_AT_type        : <76>	
 <1><ca>: Abbrev Number: 10 (DW_TAG_namespace)
     DW_AT_sibling     : <f2>	
     DW_AT_name        : A	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 2	
 <2><d3>: Abbrev Number: 11 (DW_TAG_variable)
     DW_AT_name        : x	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 3	
     DW_AT_MIPS_linkage_name: (indirect string, offset: 0x0): _ZN1A1xE	
     DW_AT_type        : <bd>	
     DW_AT_external    : 1	
     DW_AT_declaration : 1	
 <2><e2>: Abbrev Number: 11 (DW_TAG_variable)
     DW_AT_name        : x	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 3	
     DW_AT_MIPS_linkage_name: (indirect string, offset: 0x0): _ZN1A1xE	
     DW_AT_type        : <bd>	
     DW_AT_external    : 1	
     DW_AT_declaration : 1	
 <1><f2>: Abbrev Number: 12 (DW_TAG_subprogram)
     DW_AT_sibling     : <15a>	
     DW_AT_specification: <8c>	
     DW_AT_low_pc      : 0x10000620	
     DW_AT_high_pc     : 0x100006f0	
     DW_AT_frame_base  : 0	(location list)
 <2><10f>: Abbrev Number: 13 (DW_TAG_formal_parameter)
     DW_AT_name        : this	
     DW_AT_type        : <15a>	
     DW_AT_artificial  : 1	
     DW_AT_location    : 2 byte block: 91 30 	(DW_OP_fbreg: 48)
 <2><11d>: Abbrev Number: 14 (DW_TAG_lexical_block)
     DW_AT_low_pc      : 0x10000658	
     DW_AT_high_pc     : 0x100006d8	
 <3><12e>: Abbrev Number: 15 (DW_TAG_variable)
     DW_AT_name        : x	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 21	
     DW_AT_type        : <bd>	
     DW_AT_location    : 2 byte block: 91 64 	(DW_OP_fbreg: -28)
 <3><13a>: Abbrev Number: 14 (DW_TAG_lexical_block)
     DW_AT_low_pc      : 0x1000067c	
     DW_AT_high_pc     : 0x100006d8	
 <4><14b>: Abbrev Number: 15 (DW_TAG_variable)
     DW_AT_name        : x	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 25	
     DW_AT_type        : <bd>	
     DW_AT_location    : 2 byte block: 91 60 	(DW_OP_fbreg: -32)
 <1><15a>: Abbrev Number: 16 (DW_TAG_const_type)
     DW_AT_type        : <c4>	
 <1><15f>: Abbrev Number: 17 (DW_TAG_subprogram)
     DW_AT_sibling     : <194>	
     DW_AT_external    : 1	
     DW_AT_name        : main	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 43	
     DW_AT_type        : <bd>	
     DW_AT_low_pc      : 0x100005d4	
     DW_AT_high_pc     : 0x10000620	
     DW_AT_frame_base  : 0x4d	(location list)
 <2><184>: Abbrev Number: 15 (DW_TAG_variable)
     DW_AT_name        : theB	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 45	
     DW_AT_type        : <76>	
     DW_AT_location    : 2 byte block: 91 60 	(DW_OP_fbreg: -32)
 <1><194>: Abbrev Number: 10 (DW_TAG_namespace)
     DW_AT_sibling     : <1b5>	
     DW_AT_name        : ::	
     DW_AT_decl_file   : 2	
     DW_AT_decl_line   : 0	
 <2><19e>: Abbrev Number: 18 (DW_TAG_variable)
     DW_AT_name        : x	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 6	
     DW_AT_type        : <bd>	
     DW_AT_external    : 1	
     DW_AT_declaration : 1	
 <2><1a9>: Abbrev Number: 18 (DW_TAG_variable)
     DW_AT_name        : y	
     DW_AT_decl_file   : 1	
     DW_AT_decl_line   : 7	
     DW_AT_type        : <bd>	
     DW_AT_external    : 1	
     DW_AT_declaration : 1	
 <1><1b5>: Abbrev Number: 19 (DW_TAG_variable)
     DW_AT_specification: <19e>	
     DW_AT_location    : 9 byte block: 3 0 0 0 0 10 1 b 4 	(DW_OP_addr: 10010b04)
 <1><1c4>: Abbrev Number: 19 (DW_TAG_variable)
     DW_AT_specification: <1a9>	
     DW_AT_location    : 9 byte block: 3 0 0 0 0 10 1 c 7c 	(DW_OP_addr: 10010c7c)
 <1><1d3>: Abbrev Number: 19 (DW_TAG_variable)
     DW_AT_specification: <e2>	
     DW_AT_location    : 9 byte block: 3 0 0 0 0 10 1 b 0 	(DW_OP_addr: 10010b00)


Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search    order
  2010-03-23 21:35                   ` Ulrich Weigand
@ 2010-03-29 14:48                     ` Sami Wagiaalla
  2010-03-29 17:27                       ` Tom Tromey
  0 siblings, 1 reply; 16+ messages in thread
From: Sami Wagiaalla @ 2010-03-29 14:48 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1707 bytes --]

I forgot to cc list in my previous message to the thread so Ulrich's 
reply was only to me. In summary I concluded that this was a compiler 
issue and Ulrich agreed that marking the test as known failure with 
gcc's earlier than gcc 44 would be appropriate.

Here is a ptach:

2010-03-29  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/nsusing.exp: Marked imported declaration test as xfail with
	gcc < 4.4.
	* gdb.cp/shadow.exp: Ditto.


diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index b060ee2..090cbd4 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -206,5 +206,7 @@ if ![runto_main] then {
 gdb_breakpoint [gdb_get_line_number "marker10 stop"]
 gdb_continue_to_breakpoint "marker10 stop"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }
 # Assert that M::x is printed and not N::x
 gdb_test "print x" "= 911" "print x (from M::x)"
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 40c35a4..b5b8aad 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -31,6 +31,10 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
     return -1
 }
 
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
 # Get things started.
 
 gdb_exit
@@ -85,4 +89,7 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }
+
 gdb_test "print x" "= 11" "Print imported namespace x"

[-- Attachment #2: xfail.patch --]
[-- Type: text/plain, Size: 1430 bytes --]

2010-03-29  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/nsusing.exp: Marked imported declaration test as xfail with
	gcc < 4.4.
	* gdb.cp/shadow.exp: Ditto.


diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index b060ee2..090cbd4 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -206,5 +206,7 @@ if ![runto_main] then {
 gdb_breakpoint [gdb_get_line_number "marker10 stop"]
 gdb_continue_to_breakpoint "marker10 stop"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }
 # Assert that M::x is printed and not N::x
 gdb_test "print x" "= 911" "print x (from M::x)"
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 40c35a4..b5b8aad 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -31,6 +31,10 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
     return -1
 }
 
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
 # Get things started.
 
 gdb_exit
@@ -85,4 +89,7 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }
+
 gdb_test "print x" "= 11" "Print imported namespace x"

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search     order
  2010-03-29 17:27                       ` Tom Tromey
@ 2010-03-29 17:23                         ` Sami Wagiaalla
  0 siblings, 0 replies; 16+ messages in thread
From: Sami Wagiaalla @ 2010-03-29 17:23 UTC (permalink / raw)
  To: tromey; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1952 bytes --]

On 03/29/2010 12:33 PM, Tom Tromey wrote:
>>>>>> "Sami" == Sami Wagiaalla<swagiaal@redhat.com>  writes:
> 
> Sami>  +if { [test_compiler_info {gcc-[0-3]-*}] ||
> Sami>  +     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }
> 
> Split the second line here after the "{" and then again before the "}".
> 
> Sami>  +if { [test_compiler_info {gcc-[0-3]-*}] ||
> Sami>  +     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }
> 
> Here too.
> 
> Ok with this change.
> 

Will commit this:

2010-03-29  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/nsusing.exp: Marked imported declaration test as xfail with
	gcc < 4.4.
	* gdb.cp/shadow.exp: Ditto.

diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index b060ee2..718b4b8 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -206,5 +206,10 @@ if ![runto_main] then {
 gdb_breakpoint [gdb_get_line_number "marker10 stop"]
 gdb_continue_to_breakpoint "marker10 stop"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} {
+    setup_xfail *-*-* 
+}
+
 # Assert that M::x is printed and not N::x
 gdb_test "print x" "= 911" "print x (from M::x)"
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 40c35a4..945cf99 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -31,6 +31,10 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
     return -1
 }
 
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
 # Get things started.
 
 gdb_exit
@@ -85,4 +89,9 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} {
+    setup_xfail *-*-*
+}
+
 gdb_test "print x" "= 11" "Print imported namespace x"

[-- Attachment #2: xfail.patch --]
[-- Type: text/plain, Size: 1445 bytes --]

2010-03-29  Sami Wagiaalla  <swagiaal@redhat.com>

	* gdb.cp/nsusing.exp: Marked imported declaration test as xfail with
	gcc < 4.4.
	* gdb.cp/shadow.exp: Ditto.

diff --git a/gdb/testsuite/gdb.cp/nsusing.exp b/gdb/testsuite/gdb.cp/nsusing.exp
index b060ee2..718b4b8 100644
--- a/gdb/testsuite/gdb.cp/nsusing.exp
+++ b/gdb/testsuite/gdb.cp/nsusing.exp
@@ -206,5 +206,10 @@ if ![runto_main] then {
 gdb_breakpoint [gdb_get_line_number "marker10 stop"]
 gdb_continue_to_breakpoint "marker10 stop"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} {
+    setup_xfail *-*-* 
+}
+
 # Assert that M::x is printed and not N::x
 gdb_test "print x" "= 911" "print x (from M::x)"
diff --git a/gdb/testsuite/gdb.cp/shadow.exp b/gdb/testsuite/gdb.cp/shadow.exp
index 40c35a4..945cf99 100644
--- a/gdb/testsuite/gdb.cp/shadow.exp
+++ b/gdb/testsuite/gdb.cp/shadow.exp
@@ -31,6 +31,10 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
     return -1
 }
 
+if [get_compiler_info ${binfile}] {
+    return -1
+}
+
 # Get things started.
 
 gdb_exit
@@ -85,4 +89,9 @@ gdb_test "print x" "= 55" "Print local x not namespace x"
 gdb_breakpoint [gdb_get_line_number "marker5"]
 gdb_continue_to_breakpoint "marker5"
 
+if { [test_compiler_info {gcc-[0-3]-*}] ||
+     [test_compiler_info {gcc-4-[0-3]-*}]} {
+    setup_xfail *-*-*
+}
+
 gdb_test "print x" "= 11" "Print imported namespace x"

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [patch] Add support for imported declaration and correct search    order
  2010-03-29 14:48                     ` Sami Wagiaalla
@ 2010-03-29 17:27                       ` Tom Tromey
  2010-03-29 17:23                         ` Sami Wagiaalla
  0 siblings, 1 reply; 16+ messages in thread
From: Tom Tromey @ 2010-03-29 17:27 UTC (permalink / raw)
  To: Sami Wagiaalla; +Cc: gdb-patches

>>>>> "Sami" == Sami Wagiaalla <swagiaal@redhat.com> writes:

Sami> +if { [test_compiler_info {gcc-[0-3]-*}] ||
Sami> +     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }

Split the second line here after the "{" and then again before the "}".

Sami> +if { [test_compiler_info {gcc-[0-3]-*}] ||
Sami> +     [test_compiler_info {gcc-4-[0-3]-*}]} { setup_xfail *-*-* }

Here too.

Ok with this change.

Tom

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2010-03-29 17:27 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-25 20:17 [patch] Add support for imported declaration and correct search order Sami Wagiaalla
2010-02-25 21:50 ` Tom Tromey
2010-02-25 22:42 ` Jan Kratochvil
2010-02-26 20:11   ` Tom Tromey
2010-03-03 21:46     ` Sami Wagiaalla
2010-03-03 22:00       ` Tom Tromey
2010-03-08 16:39         ` Sami Wagiaalla
2010-03-08 18:58           ` Tom Tromey
2010-03-09 18:21             ` Sami Wagiaalla
2010-03-09 18:27               ` Tom Tromey
2010-03-23 20:31               ` Ulrich Weigand
2010-03-23 20:51                 ` Sami Wagiaalla
2010-03-23 21:35                   ` Ulrich Weigand
2010-03-29 14:48                     ` Sami Wagiaalla
2010-03-29 17:27                       ` Tom Tromey
2010-03-29 17:23                         ` Sami Wagiaalla

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).