From: Dodji Seketeli Date: Wed, 16 Mar 2011 21:04:58 +0000 (+0000) Subject: re PR debug/47510 (DW_TAG_typedef can have children when designating a naming typedef) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7b5cb7d63412fe8599cf9dada904e574d39809f9;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10a154899b4..8ab1bd0a3f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-03-16 Dodji Seketeli + + 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 PR target/48154 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 733c849396d..b28025fcdf7 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 5685b45576c..fd64f48e49b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-03-16 Dodji Seketeli + + PR debug/47510 + * ++.dg/debug/dwarf2/typedef6.C: New test. + 2011-03-16 Jason Merrill * 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 00000000000..8896446a7ed --- /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 } }