This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] Fix printed anonymous struct name
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 29 Sep 2011 01:23:45 +0200
- Subject: [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"