This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Add support for imported declaration and correct search order


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: declaration.patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]