Consider this test case: class C { public: C() {} ~C() {} }; typedef struct { C m; } t; typedef t s; s v; The DW_TAG_typedef DIE describing the typedef t has children DIEs. The children DIEs are actually the DIEs representing the members of the anonymous structure named by T. What is happening is, since gen_typedef_die equates the anonymous struct named by the typedef t with the DIE of the naming typedef, get_context_die called with the type tree of the anonymous typedef yields the DIE of the typedef.
Created attachment 23149 [details] Candidate patch I am bootstrapping this patch at the moment.
Patch posted to http://gcc.gnu.org/ml/gcc-patches/2011-01/msg02118.html
g++ (GCC) 4.6.0 20110203 (experimental) with the Comment 2 patch template <typename T> class F { typedef struct { int i; } C; C a; }; F<int> f; -> <1><2d>: Abbrev Number: 2 (DW_TAG_class_type) <2e> DW_AT_name : (indirect string, offset: 0x37): F<int> <2><39>: Abbrev Number: 3 (DW_TAG_structure_type) <3a> DW_AT_name : C and DW_TAG_typedef gets completely lost in such case.
This is because G++ generates struct F<int>::C. The instantiated F<int>::C a typedef. No anonymous struct is generated inside F<int>. What is generated is really the same as for: template<typename T> class F { struct C {int i}; C a; }; F<int> f; I guess we could try hard to trick the dwarf emitter into describing debug information for a typedef and an anonymous code that is actually not generated (instantiated), but would that be really worth it?
(In reply to comment #4) > This is because G++ generates struct F<int>::C. The instantiated > F<int>::C a typedef. No anonymous struct is generated inside F<int>. > What is generated is really the same as for: > > template<typename T> > class F > { > struct C {int i}; > C a; > }; > F<int> f; > > I guess we could try hard to trick the dwarf emitter into describing > debug information for a typedef and an anonymous code that is actually > not generated (instantiated), but would that be really worth it? See also PR47939. Yes, debug info consumers expect typedefs to be available if they are used in source.
> See also PR47939. Yes, debug info consumers expect typedefs to be available > if they are used in source. I'll try again a little bit :-) I think for templates the situation is a little bit different from non-templates cases like PR47939. Generally speaking we emit close to no debug info for template *definitions*. We emit debug info for template instantiations. As the instantiation doesn't contain the typedef (because [dcl.typedef/8] says that the typedef actually names the anonymous struct, so it is valid that the lookup of C yields a struct named C) I find it acceptable to emit the debug info that is emitted now. Now a possible way to go would be to change the output of the instantiation; i.e make G++ generate the typedef and the anonymous type. Just like what is done in the non-template case. If this is agreed upon by the C++ maintainers then I guess it could be a separate patch that would go in after the one I am proposing at http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00781.html
Author: dodji Date: Wed Mar 16 21:04:58 2011 New Revision: 171073 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171073 Log: 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. Added: trunk/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C Modified: trunk/gcc/ChangeLog trunk/gcc/dwarf2out.c trunk/gcc/testsuite/ChangeLog
Author: dodji Date: Wed Mar 16 21:11:17 2011 New Revision: 171074 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171074 Log: 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. Added: branches/gcc-4_6-branch/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C Modified: branches/gcc-4_6-branch/gcc/ChangeLog branches/gcc-4_6-branch/gcc/dwarf2out.c branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
The initial issue has been fixed in trunk (4.7) and 4.6 so far. There are two tangent issues that remain, though. One is the template related case raised by Jan in comment #3, and the other one is that constructors of the anonymous struct are named t. They should also be anonymous and have DW_AT_linkage_name set to t. This is from a comment Jason made at http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00926.html. So I am keeping this bug open to track these. I will maybe open separate bugs for these issues at some point.
I have reverted the patch from 4.6 for now because I have apparently committed a bit too quickly.
Author: dodji Date: Thu Mar 17 16:41:05 2011 New Revision: 171105 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171105 Log: 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. Added: branches/gcc-4_6-branch/gcc/testsuite/g++.dg/debug/dwarf2/typedef6.C Modified: branches/gcc-4_6-branch/gcc/ChangeLog branches/gcc-4_6-branch/gcc/dwarf2out.c branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
GCC 4.6.0 is being released, adjusting target milestone.
Unassigning myself as the initial bug is fixed in 4.6.
Comment 3 has been filed as new PR debug/48603.
The same thing can happen for unions in c++11. Consider the following: struct some_struct { some_struct() = default; some_struct(int v) {} }; typedef union { int x; some_struct y; } a_union_t; a_union_t z; This creates a DW_TAG_typedef with children. I propose to extend the candidate patch to unions: --- gcc/dwarf2out.c 2011-09-15 12:16:36.000000000 +0200 +++ gcc/dwarf2out.c 2011-10-10 13:56:09.000000000 +0200 @@ -8106,7 +8106,7 @@ strip_naming_typedef (tree type, dw_die_ref type_die) { if (type - && TREE_CODE (type) == RECORD_TYPE + && ( TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE ) && type_die && type_die->die_tag == DW_TAG_typedef && is_naming_typedef_decl (TYPE_NAME (type)))
(In reply to comment #15) > The same thing can happen for unions in c++11. I am being hit by this bug in c++11, though I am not able to follow the whole discussion. Can I get a concise summary on what kind of construct triggers the problem so that I can work it around in my code? Stucts with default ctors within unions? Thanks! (Compiling gcc snapshot from 28/2/2012 now to see if it is still an issue).