diff options
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 75 |
1 files changed, 68 insertions, 7 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index fc6a4d5..55abb93 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; |