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 1/2] Perform a namespace lookup at every block level



cp_lookup_symbol_namespace did two things look in the current namespace
as well as examine applicable imports. I realized that we didnt need to
examine imports at each scope level. We can simply look at the import
destination.

This patch separates the two kinds of lookups (imports and scopes) and
performs the import lookup at every block level.


Same as above, but I fixed a couple of issues with the previous patch. The first issue is that even while we iterate over blocks the original scope should be used. Secondly, the call to lookup_symbol_name space in valops.c must also perform a per block search. The final issue is recursive search which is discussed in part 2 of this patch.

----

2009-08-11 Sami Wagiaalla <swagiaal@redhat.com>

	* dwarf2read.c (read_lexical_block_scope): Create blocks for scopes
      	which contain using directives even if they contain no declarations.
       	* symtab.c (lookup_symbol_aux): Pass lowest level
       	block to la_lookup_symbol_nonlocal.
       	* cp-namespace.c (cp_lookup_symbol_nonlocal): call
       	cp_lookup_symbol_namespace.
       	(cp_lookup_symbol_namespace): Perform an import lookup at every block
       	level.
       	(cp_lookup_symbol_imports): New function.
       	(cp_lookup_symbol_in_namespace): New function.

2009-08-11 Sami Wagiaalla <swagiaal@redhat.com>

       	* gdb.cp/namespace-using.exp: Add test for printing of namespaces
       	imported into file scope.
       	Marked test as xfail.
       	* gdb.cp/namespace-using.cc (marker5): New function.

diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index d2d8f2e..a0ccd7f 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -42,6 +42,18 @@ static struct symbol *lookup_namespace_scope (const char *name,
 					      const char *scope,
 					      int scope_len);

+static struct symbol *cp_lookup_symbol_imports (const char *scope,
+                                                const char *name,
+                                                const char *linkage_name,
+                                                const struct block *block,
+                                                const domain_enum domain);
+
+static struct symbol *cp_lookup_symbol_in_namespace (const char *namespace,
+                                                     const char *name,
+                                                     const char *linkage_name,
+                                                     const struct block *block,
+                                                     const domain_enum domain);
+
 static struct symbol *lookup_symbol_file (const char *name,
 					  const char *linkage_name,
 					  const struct block *block,
@@ -265,8 +277,41 @@ cp_lookup_symbol_nonlocal (const char *name,
 			   const struct block *block,
 			   const domain_enum domain)
 {
-  return lookup_namespace_scope (name, linkage_name, block, domain,
-				 block_scope (block), 0);
+  struct symbol *sym;
+  const char *scope = block_scope (block);
+
+  sym = lookup_namespace_scope (name, linkage_name, block, domain, scope, 0);
+  if ( sym != NULL)
+    return sym;
+
+  return cp_lookup_symbol_namespace(scope, name, linkage_name, block, domain);
+}
+
+/* Searches for NAME in the current namespace, and by applying relevant import
+   statements belonging to BLOCK and its parents. SCOPE is the namespace scope
+   of the context in which the search is being evaluated.  */
+
+struct symbol*
+cp_lookup_symbol_namespace (const char *scope,
+                            const char *name,
+                            const char *linkage_name,
+                            const struct block *block,
+                            const domain_enum domain)
+{
+  struct symbol *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);
+
+      if (sym)
+        return sym;
+
+      block = BLOCK_SUPERBLOCK(block);
+    }
+
+  return NULL;
 }

 /* Lookup NAME at namespace scope (or, in C terms, in static and
@@ -320,25 +365,59 @@ lookup_namespace_scope (const char *name,
   namespace = alloca (scope_len + 1);
   strncpy (namespace, scope, scope_len);
   namespace[scope_len] = '\0';
-  return cp_lookup_symbol_namespace (namespace, name, linkage_name,
+  return cp_lookup_symbol_in_namespace (namespace, name, linkage_name,
 				     block, domain);
 }

-/* Look up NAME in the C++ namespace NAMESPACE, applying the using
-   directives that are active in BLOCK.  Other arguments are as in
+/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
    cp_lookup_symbol_nonlocal.  */

-struct symbol *
-cp_lookup_symbol_namespace (const char *namespace,
-			    const char *name,
-			    const char *linkage_name,
-			    const struct block *block,
-			    const domain_enum domain)
+static struct symbol *
+cp_lookup_symbol_in_namespace (const char *namespace,
+			       const char *name,
+			       const char *linkage_name,
+			       const struct block *block,
+			       const domain_enum domain)
+{
+
+  if (namespace[0] == '\0')
+    {
+      return lookup_symbol_file (name, linkage_name, block,
+				 domain, 0);
+    }
+  else
+    {
+      char *concatenated_name
+	= alloca (strlen (namespace) + 2 + strlen (name) + 1);
+      strcpy (concatenated_name, namespace);
+      strcat (concatenated_name, "::");
+      strcat (concatenated_name, name);
+      return lookup_symbol_file (concatenated_name, linkage_name,
+				block, domain,
+				cp_is_anonymous (namespace));
+    }
+}
+
+/* Search for NAME by applying all import statements belonging
+   to BLOCK which are applicable in SCOPE.  */
+
+static 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 struct using_direct *current;
   struct symbol *sym;

-  /* First, go through the using directives.  If any of them add new
+  /* 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;
+
+  /* Go through the using directives.  If any of them add new
      names to the namespace we're searching in, see if we can find a
      match by applying them.  */

@@ -346,9 +425,12 @@ cp_lookup_symbol_namespace (const char *namespace,
        current != NULL;
        current = current->next)
     {
-      if (strcmp (namespace, current->import_dest) == 0)
+
+      /* If the import destination is the current scope or one of its ancestors then
+         it is applicable.  */
+      if (strncmp (scope, current->import_dest, strlen(current->import_dest)) == 0)
 	{
-	  sym = cp_lookup_symbol_namespace (current->import_src,
+	  sym = cp_lookup_symbol_in_namespace (current->import_src,
 					    name,
 					    linkage_name,
 					    block,
@@ -358,27 +440,7 @@ cp_lookup_symbol_namespace (const char *namespace,
 	}
     }

-  /* We didn't find anything by applying any of the using directives
-     that are still applicable; so let's see if we've got a match
-     using the current namespace.  */
-
-  if (namespace[0] == '\0')
-    {
-      return lookup_symbol_file (name, linkage_name, block,
-				 domain, 0);
-    }
-  else
-    {
-      char *concatenated_name
-	= alloca (strlen (namespace) + 2 + strlen (name) + 1);
-      strcpy (concatenated_name, namespace);
-      strcat (concatenated_name, "::");
-      strcat (concatenated_name, name);
-      sym = lookup_symbol_file (concatenated_name, linkage_name,
-				block, domain,
-				cp_is_anonymous (namespace));
-      return sym;
-    }
+  return NULL;
 }

 /* Look up NAME in BLOCK's static block and in global blocks.  If
@@ -461,7 +523,7 @@ cp_lookup_nested_type (struct type *parent_type,
 	   lookup_symbol_namespace works when looking them up.  */

 	const char *parent_name = TYPE_TAG_NAME (parent_type);
-	struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
+	struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name,
 							 nested_name,
 							 NULL,
 							 block,
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 445bab8..f18d804 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3922,7 +3922,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
   new = pop_context ();

-  if (local_symbols != NULL)
+  if (local_symbols != NULL || using_directives != NULL)
     {
       struct block *block
         = finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
diff --git a/gdb/symtab.c b/gdb/symtab.c
index c88156a..cebbb4b 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1304,13 +1304,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
       && block != NULL)
     {
       struct symbol *sym = NULL;
+      const struct block *function_block = block;
       /* 'this' is only defined in the function's block, so find the
 	 enclosing function block.  */
-      for (; block && !BLOCK_FUNCTION (block);
-	   block = BLOCK_SUPERBLOCK (block));
+      for (; function_block && !BLOCK_FUNCTION (function_block);
+      function_block = BLOCK_SUPERBLOCK (function_block));

-      if (block && !dict_empty (BLOCK_DICT (block)))
-	sym = lookup_block_symbol (block, langdef->la_name_of_this,
+      if (function_block && !dict_empty (BLOCK_DICT (function_block)))
+	sym = lookup_block_symbol (function_block, langdef->la_name_of_this,
 				   NULL, VAR_DOMAIN);
       if (sym)
 	{
@@ -1334,11 +1335,14 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 	      return NULL;
 	    }
 	}
-    }

-  /* Now do whatever is appropriate for LANGUAGE to look
-     up static and global variables.  */
+      /* C++ language specific lookup requires the lowest block level.  */
+      if (language != language_cplus)
+        block = function_block;
+
+    }

+  /* Now do whatever is appropriate for LANGUAGE specific lookup.  */
   sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain);
   if (sym != NULL)
     return sym;
diff --git a/gdb/testsuite/gdb.cp/namespace-using.cc b/gdb/testsuite/gdb.cp/namespace-using.cc
index 4786fd5..091b4cc 100644
--- a/gdb/testsuite/gdb.cp/namespace-using.cc
+++ b/gdb/testsuite/gdb.cp/namespace-using.cc
@@ -1,3 +1,16 @@
+namespace C
+{
+  int cc = 3;
+}
+
+using namespace C;
+int marker5()
+{
+  cc;
+  return 0;
+}
+
+
 namespace A
 {
   int _a = 1;
@@ -6,7 +19,7 @@ namespace A

 int marker4(){
 	using A::x;
-	return 0;
+  return marker5();
 }

 int marker3(){
diff --git a/gdb/testsuite/gdb.cp/namespace-using.exp b/gdb/testsuite/gdb.cp/namespace-using.exp
index f24973f..bd1016b 100644
--- a/gdb/testsuite/gdb.cp/namespace-using.exp
+++ b/gdb/testsuite/gdb.cp/namespace-using.exp
@@ -28,6 +28,11 @@ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb
     return -1
 }

+if [get_compiler_info ${binfile}] {
+    return -1;
+}
+
+
 # Get things started.

 gdb_exit
@@ -73,7 +78,13 @@ gdb_test "print B::a" "= 1"
 gdb_breakpoint "marker3"
 gdb_continue_to_breakpoint "marker3"

-gdb_test "print _a" "No symbol \"_a\" in current context." "Print a without import"
+# gcc-4-3 puts import statements for aliases in
+# the global scope instead of the corresponding
+# function scope. These wrong import statements throw
+# this test off. This is fixed in gcc-4-4.
+if [test_compiler_info gcc-4-3-*] then { setup_xfail *-*-* }
+
+gdb_test "print _a" "No symbol \"_a\" in current context." "Print _a without import"

 ############################################
 # Test printing of individually imported elements
@@ -85,3 +96,14 @@ if ![runto marker4] then {
 }

 gdb_test "print x" "= 2"
+
+############################################
+# test printing of namespace imported into
+# file scope.
+
+if ![runto marker5] then {
+    perror "couldn't run to marker5"
+    continue
+}
+
+gdb_test "print cc" "= 3"


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