http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46101
--- Comment #2 from Dodji Seketeli <dodji at gcc dot gnu.org> 2010-11-14 14:15:06 UTC --- I am currently testing the patch below: >From d16601c89e153c54ef017cca5db854898d9c6502 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli <do...@redhat.com> Date: Sun, 14 Nov 2010 12:55:34 +0100 Subject: [PATCH 1/2] Fix PR debug/46101 gcc/ * dwarf2out.c (lookup_type_die_strip_naming_typedef): New function. (gen_generic_params_dies, scope_die_for, gen_type_die_for_member): Replace uses of lookup_type_die with use of lookup_type_die_strip_naming_typedef. gcc/testsuite/ * g++.dg/debug/dwarf2/typedef5.C: New test --- gcc/dwarf2out.c | 28 +++++++++++++++++++++++-- gcc/testsuite/g++.dg/debug/dwarf2/typedef5.C | 10 +++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/typedef5.C diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 9bb569b..1094a9f 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -6160,6 +6160,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 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 *); static int decl_die_table_eq (const void *, const void *); @@ -7920,6 +7921,27 @@ lookup_type_die (tree type) return TYPE_SYMTAB_DIE (type); } +/* 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 + equate the anonymous struct named by the typedef with the DIE of + the naming typedef. So by default, lookup_type_die on an anonymous + struct yields the DIE of the naming typedef. + + [1]: Read the comment of is_naming_typedef_decl to learn about what + a naming typedef is. */ + +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; +} + /* Equate a DIE to a given type specifier. */ static inline void @@ -12883,7 +12905,7 @@ gen_generic_params_dies (tree t) return; if (TYPE_P (t)) - die = lookup_type_die (t); + die = lookup_type_die_strip_naming_typedef (t); else if (DECL_P (t)) die = lookup_decl_die (t); @@ -17763,7 +17785,7 @@ scope_die_for (tree t, dw_die_ref context_die) scope_die = comp_unit_die (); } else - scope_die = lookup_type_die (containing_scope); + scope_die = lookup_type_die_strip_naming_typedef (containing_scope); } else scope_die = context_die; @@ -18590,7 +18612,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die) gcc_assert (!decl_ultimate_origin (member)); push_decl_scope (type); - type_die = lookup_type_die (type); + type_die = lookup_type_die_strip_naming_typedef (type); if (TREE_CODE (member) == FUNCTION_DECL) gen_subprogram_die (member, type_die); else if (TREE_CODE (member) == FIELD_DECL) diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/typedef5.C b/gcc/testsuite/g++.dg/debug/dwarf2/typedef5.C new file mode 100644 index 0000000..d9d058c --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/typedef5.C @@ -0,0 +1,10 @@ +// Origin: PR debug/46101 +// { dg-options "-g -feliminate-dwarf2-dups" } +// { dg-do compile } + +typedef struct +{ + virtual void f () { } +} A; + +A a;