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] Fix printed anonymous struct name


Hi,

dwarf2read considers dwarf2_name to return the base name and determine_prefix
to return the namespaces/classes, togeter forming the fully qualified name.

But in the case of anonymous structs the DW_AT_linkage_name hint contains
fully qualified name which was whole returned by dwarf2_name causing various
confusion.

Split the anonymous structs DW_AT_linkage_name hint properly to the
namespaces/classes and base name part which fixes the testcase and also some
futher issue .debug_types I am going to post for GCC.

In fact modifying die_needs_namespace also seems to work making the code more
simple but I do not find such solution correct.

No regressions on {x86_64,x86_64-m32,i686}-fedora16pre-linux-gnu and with
-gdwarf-4 with -fdebug-types-section and with -fno-debug-types-section.

(The very first hunk change is in fact unrelated, I haven't tried to exploit
it, it looks just as an inconcistency typo to me.)


ptype X::t2
type = struct X::X::t2 {
    X::C2 m;
}
(gdb) FAIL: gdb.cp/anon-struct.exp: print type of X::t2
->
ptype X::t2
type = struct X::t2 {
    X::C2 m;
}
(gdb) PASS: gdb.cp/anon-struct.exp: print type of X::t2


Thanks,
Jan


gdb/
2011-09-28  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix printed anonymous struct name.
	* dwarf2read.c (fixup_partial_die): Handle for anonymous structs also
	DW_TAG_interface_type.  Strip for anonymous structs any prefixes.
	(anonymous_struct_prefix): New function.
	(determine_prefix): New variables retval.  Call anonymous_struct_prefix.
	(dwarf2_name): Strip for anonymous structs any prefixes.

gdb/testsuite/
2011-09-28  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Fix printed anonymous struct name.
	* gdb.cp/anon-struct.exp (print type of X::t2): New test.

--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -9801,9 +9801,10 @@ fixup_partial_die (struct partial_die_info *part_die,
   /* GCC might emit a nameless struct or union that has a linkage
      name.  See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510.  */
   if (part_die->name == NULL
-      && (part_die->tag == DW_TAG_structure_type
-	  || part_die->tag == DW_TAG_union_type
-	  || part_die->tag == DW_TAG_class_type)
+      && (part_die->tag == DW_TAG_class_type
+	  || part_die->tag == DW_TAG_interface_type
+	  || part_die->tag == DW_TAG_structure_type
+	  || part_die->tag == DW_TAG_union_type)
       && part_die->linkage_name != NULL)
     {
       char *demangled;
@@ -9811,7 +9812,17 @@ fixup_partial_die (struct partial_die_info *part_die,
       demangled = cplus_demangle (part_die->linkage_name, DMGL_TYPES);
       if (demangled)
 	{
-	  part_die->name = obsavestring (demangled, strlen (demangled),
+	  const char *base;
+
+	  /* Strip any leading namespaces/classes, keep only the base name.
+	     DW_AT_name for named DIEs does not contain the prefixes.  */
+	  base = strrchr (demangled, ':');
+	  if (base && base > demangled && base[-1] == ':')
+	    base++;
+	  else
+	    base = demangled;
+
+	  part_die->name = obsavestring (base, strlen (base),
 					 &cu->objfile->objfile_obstack);
 	  xfree (demangled);
 	}
@@ -12160,6 +12171,42 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
   return NULL;
 }
 
+/* GCC might emit a nameless typedef that has a linkage name.  Determine the
+   prefix part in such case.  See
+   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510.  */
+
+static char *
+anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct attribute *attr;
+  char *base;
+
+  if (die->tag != DW_TAG_class_type && die->tag != DW_TAG_interface_type
+      && die->tag != DW_TAG_structure_type && die->tag != DW_TAG_union_type)
+    return NULL;
+
+  attr = dwarf2_attr (die, DW_AT_name, cu);
+  if (attr != NULL && DW_STRING (attr) != NULL)
+    return NULL;
+
+  attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+  if (attr == NULL)
+    attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+  if (attr == NULL || DW_STRING (attr) == NULL)
+    return NULL;
+
+  /* dwarf2_name had to be already called.  */
+  gdb_assert (DW_STRING_IS_CANONICAL (attr));
+
+  /* Strip the base name, keep any leading namespaces/classes.  */
+  base = strrchr (DW_STRING (attr), ':');
+  if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
+    return "";
+
+  return obsavestring (DW_STRING (attr), &base[-1] - DW_STRING (attr),
+		       &cu->objfile->objfile_obstack);
+}
+
 /* Return the name of the namespace/class that DIE is defined within,
    or "" if we can't tell.  The caller should not xfree the result.
 
@@ -12181,11 +12228,16 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *parent, *spec_die;
   struct dwarf2_cu *spec_cu;
   struct type *parent_type;
+  char *retval;
 
   if (cu->language != language_cplus && cu->language != language_java
       && cu->language != language_fortran)
     return "";
 
+  retval = anonymous_struct_prefix (die, cu);
+  if (retval)
+    return retval;
+
   /* We have to be careful in the presence of DW_AT_specification.
      For example, with GCC 3.4, given the code
 
@@ -12477,12 +12529,21 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
 
 	  if (demangled)
 	    {
+	      char *base;
+
 	      /* FIXME: we already did this for the partial symbol... */
-	      DW_STRING (attr)
-		= obsavestring (demangled, strlen (demangled),
-				&cu->objfile->objfile_obstack);
+	      DW_STRING (attr) = obsavestring (demangled, strlen (demangled),
+					       &cu->objfile->objfile_obstack);
 	      DW_STRING_IS_CANONICAL (attr) = 1;
 	      xfree (demangled);
+
+	      /* Strip any leading namespaces/classes, keep only the base name.
+		 DW_AT_name for named DIEs does not contain the prefixes.  */
+	      base = strrchr (DW_STRING (attr), ':');
+	      if (base && base > DW_STRING (attr) && base[-1] == ':')
+		return &base[1];
+	      else
+		return DW_STRING (attr);
 	    }
 	}
       break;
--- a/gdb/testsuite/gdb.cp/anon-struct.exp
+++ b/gdb/testsuite/gdb.cp/anon-struct.exp
@@ -24,6 +24,9 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] }
 gdb_test "ptype t::t" "type = void \\(t \\* const\\)" \
     "print type of t::t"
 
+gdb_test "ptype X::t2" "type = struct X::t2 {\[\r\n \]*X::C2 m;\[\r\n \]*}" \
+    "print type of X::t2"
+
 gdb_test "ptype X::t2::t2" "type = void \\(X::t2 \\* const\\)" \
     "print type of X::t2::t2"
 


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