OSDN Git Service

gdb/
authorjkratoch <jkratoch>
Sun, 9 Oct 2011 18:33:27 +0000 (18:33 +0000)
committerjkratoch <jkratoch>
Sun, 9 Oct 2011 18:33:27 +0000 (18:33 +0000)
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/
Fix printed anonymous struct name.
* gdb.cp/anon-struct.exp (print type of X::t2): New test.

gdb/ChangeLog
gdb/dwarf2read.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/anon-struct.exp

index 16f654b..b366c65 100644 (file)
@@ -1,3 +1,12 @@
+2011-10-09  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.
+
 2011-10-07  Doug Evans  <dje@google.com>
 
        * python/lib/gdb/printing.py (register_pretty_printer): New argument
index fc6a4d5..55abb93 100644 (file)
@@ -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;
index fcdc376..0ec3cf9 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-09  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+       Fix printed anonymous struct name.
+       * gdb.cp/anon-struct.exp (print type of X::t2): New test.
+
 2011-10-09  Joseph Myers  <joseph@codesourcery.com>
 
        * gdb.base/solib-symbol.exp: Do not include directories in
index 0afb99a..ed51864 100644 (file)
@@ -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"