This is the mail archive of the gdb-cvs@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]

[binutils-gdb] PR c++/17976, symtab/17821


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=96553a0cffb30d2ac6068eb71bed38ea7432073b

commit 96553a0cffb30d2ac6068eb71bed38ea7432073b
Author: Doug Evans <dje@google.com>
Date:   Sat Feb 21 21:58:31 2015 -0800

    PR c++/17976, symtab/17821
    
    This patch addresses two issues.
    
    The basic problem is that "(anonymous namespace)" doesn't get entered
    into the symbol table because when dwarf2read.c:new_symbol_full is called
    the DIE has no name (dwarf2_name returns NULL).
    
    PR 17976: ptype '(anonymous namespace)' should work like any namespace
    
    PR 17821: perf issue looking up (anonymous namespace)
    
    bash$ gdb monster-program
    (gdb) mt set per on
    (gdb) mt set symbol-cache-size 0
    (gdb) break (anonymous namespace)::foo
    
    Before:
    
    Command execution time: 3.266289 (cpu), 6.169030 (wall)
    Space used: 811429888 (+12910592 for this command)
    
    After:
    
    Command execution time: 1.264076 (cpu), 4.057408 (wall)
    Space used: 798781440 (+0 for this command)
    
    gdb/ChangeLog:
    
    	PR c++/17976, symtab/17821
    	* cp-namespace.c (cp_search_static_and_baseclasses): New parameter
    	is_in_anonymous.  All callers updated.
    	(find_symbol_in_baseclass): Ditto.
    	(cp_lookup_nested_symbol_1): Ditto.  Don't search all static blocks
    	for symbols in an anonymous namespace.
    	* dwarf2read.c (namespace_name): Don't call dwarf2_name, fetch
    	DW_AT_name directly.
    	(dwarf2_name): Convert missing namespace name to
    	CP_ANONYMOUS_NAMESPACE_STR.
    
    gdeb/testsuite/ChangeLog:
    
    	* gdb.cp/anon-ns.exp: Add test for ptype '(anonymous namespace)'.

Diff:
---
 gdb/ChangeLog                    | 13 ++++++++++++
 gdb/cp-namespace.c               | 43 ++++++++++++++++++++++++++--------------
 gdb/dwarf2read.c                 | 16 +++++++++++++--
 gdb/testsuite/ChangeLog          |  4 ++++
 gdb/testsuite/gdb.cp/anon-ns.exp |  4 ++++
 5 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b7a72d9..faccd5f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2015-02-21  Doug Evans  <dje@google.com>
+
+	PR c++/17976, symtab/17821
+	* cp-namespace.c (cp_search_static_and_baseclasses): New parameter
+	is_in_anonymous.  All callers updated.
+	(find_symbol_in_baseclass): Ditto.
+	(cp_lookup_nested_symbol_1): Ditto.  Don't search all static blocks
+	for symbols in an anonymous namespace.
+	* dwarf2read.c (namespace_name): Don't call dwarf2_name, fetch
+	DW_AT_name directly.
+	(dwarf2_name): Convert missing namespace name to
+	CP_ANONYMOUS_NAMESPACE_STR.
+
 2015-02-20  Pedro Alves  <palves@redhat.com>
 
 	* linux-nat.c (linux_handle_extended_wait): Call
diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c
index 2cc2ea9..e278189 100644
--- a/gdb/cp-namespace.c
+++ b/gdb/cp-namespace.c
@@ -37,7 +37,7 @@ static struct symbol *
 			     const char *nested_name,
 			     const char *concatenated_name,
 			     const struct block *block,
-			     int basic_lookup);
+			     int basic_lookup, int is_in_anonymous);
 
 static struct type *cp_lookup_transparent_type_loop (const char *name,
 						     const char *scope,
@@ -327,7 +327,8 @@ static struct symbol *
 cp_search_static_and_baseclasses (const char *name,
 				  const struct block *block,
 				  const domain_enum domain,
-				  unsigned int prefix_len)
+				  unsigned int prefix_len,
+				  int is_in_anonymous)
 {
   struct symbol *sym;
   char *klass, *nested;
@@ -366,7 +367,8 @@ cp_search_static_and_baseclasses (const char *name,
   /* Look for a symbol named NESTED in this class.
      The caller is assumed to have already have done a basic lookup of NAME.
      So we pass zero for BASIC_LOOKUP to cp_lookup_nested_symbol_1 here.  */
-  sym = cp_lookup_nested_symbol_1 (klass_type, nested, name, block, 0);
+  sym = cp_lookup_nested_symbol_1 (klass_type, nested, name, block, 0,
+				   is_in_anonymous);
 
   do_cleanups (cleanup);
   return sym;
@@ -416,7 +418,8 @@ cp_lookup_symbol_in_namespace (const char *namespace, const char *name,
     return sym;
 
   if (search)
-    sym = cp_search_static_and_baseclasses (name, block, domain, prefix_len);
+    sym = cp_search_static_and_baseclasses (name, block, domain, prefix_len,
+					    is_in_anonymous);
 
   return sym;
 }
@@ -900,7 +903,7 @@ cp_find_type_baseclass_by_name (struct type *parent_type, const char *name)
 
 static struct symbol *
 find_symbol_in_baseclass (struct type *parent_type, const char *name,
-			   const struct block *block)
+			  const struct block *block, int is_in_anonymous)
 {
   int i;
   struct symbol *sym;
@@ -925,7 +928,7 @@ find_symbol_in_baseclass (struct type *parent_type, const char *name,
       xsnprintf (concatenated_name, len, "%s::%s", base_name, name);
 
       sym = cp_lookup_nested_symbol_1 (base_type, name, concatenated_name,
-				       block, 1);
+				       block, 1, is_in_anonymous);
       if (sym != NULL)
 	break;
     }
@@ -942,16 +945,17 @@ find_symbol_in_baseclass (struct type *parent_type, const char *name,
    passed as an argument so that callers can control how space for it is
    allocated.
    If BASIC_LOOKUP is non-zero then perform a basic lookup of
-   CONCATENATED_NAME.  See cp_basic_lookup_symbol for details.  */
+   CONCATENATED_NAME.  See cp_basic_lookup_symbol for details.
+   If IS_IN_ANONYMOUS is non-zero then CONCATENATED_NAME is in an anonymous
+   namespace.  */
 
 static struct symbol *
 cp_lookup_nested_symbol_1 (struct type *container_type,
 			   const char *nested_name,
 			   const char *concatenated_name,
 			   const struct block *block,
-			   int basic_lookup)
+			   int basic_lookup, int is_in_anonymous)
 {
-  int is_in_anonymous = cp_is_in_anonymous (concatenated_name);
   struct symbol *sym;
 
   /* NOTE: carlton/2003-11-10: We don't treat C++ class members
@@ -981,16 +985,22 @@ cp_lookup_nested_symbol_1 (struct type *container_type,
 
   /* Nope.  We now have to search all static blocks in all objfiles,
      even if block != NULL, because there's no guarantees as to which
-     symtab the symbol we want is in.  */
-  sym = lookup_static_symbol (concatenated_name, VAR_DOMAIN);
-  if (sym != NULL)
-    return sym;
+     symtab the symbol we want is in.  Except for symbols defined in
+     anonymous namespaces should be treated as local to a single file,
+     which we just searched.  */
+  if (!is_in_anonymous)
+    {
+      sym = lookup_static_symbol (concatenated_name, VAR_DOMAIN);
+      if (sym != NULL)
+	return sym;
+    }
 
   /* If this is a class with baseclasses, search them next.  */
   CHECK_TYPEDEF (container_type);
   if (TYPE_N_BASECLASSES (container_type) > 0)
     {
-      sym = find_symbol_in_baseclass (container_type, nested_name, block);
+      sym = find_symbol_in_baseclass (container_type, nested_name, block,
+				      is_in_anonymous);
       if (sym != NULL)
 	return sym;
     }
@@ -1038,14 +1048,17 @@ cp_lookup_nested_symbol (struct type *parent_type,
 	const char *parent_name = type_name_no_tag_or_error (saved_parent_type);
 	struct symbol *sym;
 	char *concatenated_name;
+	int is_in_anonymous;
 
 	size = strlen (parent_name) + 2 + strlen (nested_name) + 1;
 	concatenated_name = alloca (size);
 	xsnprintf (concatenated_name, size, "%s::%s",
 		   parent_name, nested_name);
+	is_in_anonymous = cp_is_in_anonymous (concatenated_name);
 
 	sym = cp_lookup_nested_symbol_1 (parent_type, nested_name,
-					 concatenated_name, block, 1);
+					 concatenated_name, block, 1,
+					 is_in_anonymous);
 
 	if (symbol_lookup_debug)
 	  {
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index a764389..ac78165 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -14109,7 +14109,12 @@ namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
        current_die != NULL;
        current_die = dwarf2_extension (die, &cu))
     {
-      name = dwarf2_name (current_die, cu);
+      /* We don't use dwarf2_name here so that we can detect the absence
+	 of a name -> anonymous namespace.  */
+      struct attribute *attr = dwarf2_attr (die, DW_AT_name, cu);
+
+      if (attr != NULL)
+	name = DW_STRING (attr);
       if (name != NULL)
 	break;
     }
@@ -19253,7 +19258,8 @@ dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
   return name;
 }
 
-/* Get name of a die, return NULL if not found.  */
+/* Get name of a die, return NULL if not found.
+   Anonymous namespaces are converted to their magic string.  */
 
 static const char *
 dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
@@ -19262,6 +19268,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 
   attr = dwarf2_attr (die, DW_AT_name, cu);
   if ((!attr || !DW_STRING (attr))
+      && die->tag != DW_TAG_namespace
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
@@ -19280,6 +19287,11 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 	 to canonicalize them.  */
       return DW_STRING (attr);
 
+    case DW_TAG_namespace:
+      if (attr != NULL && DW_STRING (attr) != NULL)
+	return DW_STRING (attr);
+      return CP_ANONYMOUS_NAMESPACE_STR;
+
     case DW_TAG_subprogram:
       /* Java constructors will all be named "<init>", so return
 	 the class name when we see this special case.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index dbcc4f6..bc3bdd9 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2015-02-21  Doug Evans  <dje@google.com>
+
+	* gdb.cp/anon-ns.exp: Add test for ptype '(anonymous namespace)'.
+
 2015-02-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	PR corefiles/17808
diff --git a/gdb/testsuite/gdb.cp/anon-ns.exp b/gdb/testsuite/gdb.cp/anon-ns.exp
index ab9da14..d817435 100644
--- a/gdb/testsuite/gdb.cp/anon-ns.exp
+++ b/gdb/testsuite/gdb.cp/anon-ns.exp
@@ -64,5 +64,9 @@ foreach test $methods {
     }
 }
 
+# PR c++/17976
+gdb_test "ptype '(anonymous namespace)'" \
+    "type = namespace \\\(anonymous namespace\\\)"
+
 gdb_exit
 return 0


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