From a73d2258a7f0bd52aa9a4df764109c9df7f02e26 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 9 Oct 2011 18:33:28 +0000 Subject: [PATCH] gdb/ 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 | 9 ++++ gdb/dwarf2read.c | 75 +++++++++++++++++++++++++--- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.cp/anon-struct.exp | 3 ++ 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 16f654b4074..b366c65f1f0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2011-10-09 Jan Kratochvil + + 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 * python/lib/gdb/printing.py (register_pretty_printer): New argument diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index fc6a4d50d20..55abb93b963 100644 --- 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; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index fcdc3767117..0ec3cf95cc7 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-10-09 Jan Kratochvil + + Fix printed anonymous struct name. + * gdb.cp/anon-struct.exp (print type of X::t2): New test. + 2011-10-09 Joseph Myers * gdb.base/solib-symbol.exp: Do not include directories in diff --git a/gdb/testsuite/gdb.cp/anon-struct.exp b/gdb/testsuite/gdb.cp/anon-struct.exp index 0afb99ae196..ed518643026 100644 --- 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"