aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDodji Seketeli <dodji@redhat.com>2011-03-16 21:04:58 +0000
committerDodji Seketeli <dodji@gcc.gnu.org>2011-03-16 22:04:58 +0100
commit7b5cb7d63412fe8599cf9dada904e574d39809f9 (patch)
treedff3437743f8faab4d8acbc419ea5f338f98473b
parent532c679ea9bdf337fa0c09cbc9b0737b4a4b1aa9 (diff)
downloadgcc-7b5cb7d63412fe8599cf9dada904e574d39809f9.zip
gcc-7b5cb7d63412fe8599cf9dada904e574d39809f9.tar.gz
gcc-7b5cb7d63412fe8599cf9dada904e574d39809f9.tar.bz2
re PR debug/47510 (DW_TAG_typedef can have children when designating a naming typedef)
PR debug/47510 gcc/ PR debug/47510 * dwarf2out.c (strip_naming_typedef): Factorize out of ... (lookup_type_die_strip_naming_typedef): ... here. (get_context_die): Use it. (gen_typedef_die): Add a DW_AT_{,MIPS_}linkage_name attribute to the anonymous struct named by the naming typedef. gcc/testsuite/ PR debug/47510 * g++.dg/debug/dwarf2/typedef6.C: New test. From-SVN: r171073
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/dwarf2out.c36
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C30
4 files changed, 74 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 10a1548..8ab1bd0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2011-03-16 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/47510
+ * dwarf2out.c (strip_naming_typedef): Factorize out of ...
+ (lookup_type_die_strip_naming_typedef): ... here.
+ (get_context_die): Use it.
+ (gen_typedef_die): Add a DW_AT_{,MIPS_}linkage_name attribute to
+ the anonymous struct named by the naming typedef.
+
2011-03-16 H.J. Lu <hongjiu.lu@intel.com>
PR target/48154
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 733c849..b28025f 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -6341,6 +6341,7 @@ static void remove_child_TAG (dw_die_ref, enum dwarf_tag);
static void add_child_die (dw_die_ref, dw_die_ref);
static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
static dw_die_ref lookup_type_die (tree);
+static dw_die_ref strip_naming_typedef (tree, dw_die_ref);
static dw_die_ref lookup_type_die_strip_naming_typedef (tree);
static void equate_type_number_to_die (tree, dw_die_ref);
static hashval_t decl_die_table_hash (const void *);
@@ -8129,6 +8130,22 @@ lookup_type_die (tree type)
return TYPE_SYMTAB_DIE (type);
}
+/* Given a TYPE_DIE representing the type TYPE, if TYPE is an
+ anonymous type named by the typedef TYPE_DIE, return the DIE of the
+ anonymous type instead the one of the naming typedef. */
+
+static inline dw_die_ref
+strip_naming_typedef (tree type, dw_die_ref type_die)
+{
+ if (type
+ && TREE_CODE (type) == RECORD_TYPE
+ && type_die
+ && type_die->die_tag == DW_TAG_typedef
+ && is_naming_typedef_decl (TYPE_NAME (type)))
+ type_die = get_AT_ref (type_die, DW_AT_type);
+ return type_die;
+}
+
/* Like lookup_type_die, but if type is an anonymous type named by a
typedef[1], return the DIE of the anonymous type instead the one of
the naming typedef. This is because in gen_typedef_die, we did
@@ -8143,11 +8160,7 @@ static inline dw_die_ref
lookup_type_die_strip_naming_typedef (tree type)
{
dw_die_ref die = lookup_type_die (type);
- if (TREE_CODE (type) == RECORD_TYPE
- && die->die_tag == DW_TAG_typedef
- && is_naming_typedef_decl (TYPE_NAME (type)))
- die = get_AT_ref (die, DW_AT_type);
- return die;
+ return strip_naming_typedef (type, die);
}
/* Equate a DIE to a given type specifier. */
@@ -20443,6 +20456,14 @@ gen_typedef_die (tree decl, dw_die_ref context_die)
anonymous struct DIE. */
if (!TREE_ASM_WRITTEN (type))
gen_tagged_type_die (type, context_die, DINFO_USAGE_DIR_USE);
+
+ /* This is a GNU Extension. We are adding a
+ DW_AT_linkage_name attribute to the DIE of the
+ anonymous struct TYPE. The value of that attribute
+ is the name of the typedef decl naming the anonymous
+ struct. This greatly eases the work of consumers of
+ this debug info. */
+ add_linkage_attr (lookup_type_die (type), decl);
}
}
@@ -20923,7 +20944,10 @@ get_context_die (tree context)
{
/* Find die that represents this context. */
if (TYPE_P (context))
- return force_type_die (TYPE_MAIN_VARIANT (context));
+ {
+ context = TYPE_MAIN_VARIANT (context);
+ return strip_naming_typedef (context, force_type_die (context));
+ }
else
return force_decl_die (context);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5685b45..fd64f48 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-03-16 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/47510
+ * ++.dg/debug/dwarf2/typedef6.C: New test.
+
2011-03-16 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/elision2.C: New.
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C b/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C
new file mode 100644
index 0000000..8896446
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C
@@ -0,0 +1,30 @@
+// Origin PR debug/
+// { dg-options "-g -dA" }
+
+class C {
+public:
+ C() {}
+ ~C() {}
+};
+typedef struct {
+ C m;
+} t;
+typedef t s;
+s v;
+
+/*
+ We want to check that we have a DIE describing the typedef t like this:
+
+ .uleb128 0xc # (DIE (0xb8) DW_TAG_typedef)
+ .ascii "t\0" # DW_AT_name
+ .byte 0x1 # DW_AT_decl_file (../../prtests/test.cc)
+ .byte 0xb # DW_AT_decl_line
+ .long 0x78 # DW_AT_type
+
+ e.g, it should not haven any child DIE -- the bug here was that this
+ DIE had children DIEs. So we check that the last line is immediately
+ followed by a line containing the pattern "(DIE (", instead of a
+ line containing a DW_AT_sibling attribute.
+ */
+
+// { dg-final { scan-assembler-times "\[^\n\r\]*\\(DIE \[^\n\r\]* DW_TAG_typedef\\)\[\n\r\]{1,2}\[^\n\r\].*\"t\\\\0\"\[^\n\r\]*DW_AT_name\[\n\r\]{1,2}\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type\[\n\r\]{1,2}\[^\n\r\]*\\(DIE" 1 } }