Re: [PATCH] Emit DW_AT_inline for C++17 inline variables (take 2)
On Wed, 2016-11-02 at 00:08 +0100, Mark Wielaard wrote: > That seemed to have been the last usage of origin_die in gen_variable_die. > So removing that caused: > > /home/mark/src/gcc/gcc/dwarf2out.c: In function ‘void gen_variable_die(tree, > tree, dw_die_ref)’: > /home/mark/src/gcc/gcc/dwarf2out.c:22454:14: error: variable ‘origin_die’ set > but not used [-Werror=unused-but-set-variable] >dw_die_ref origin_die = NULL; > ^~ > cc1plus: all warnings being treated as errors > make[3]: *** [dwarf2out.o] Error 1 > > The following seems to work around that and makes things build again for me: Which is precisely what Jakub checked in 5 minutes before I sent that email. Sorry for the noise. Everything builds again. Thanks, Mark
Re: [PATCH] Emit DW_AT_inline for C++17 inline variables (take 2)
On Tue, Nov 01, 2016 at 01:20:23PM -0400, Jason Merrill wrote: > On Tue, Nov 1, 2016@12:10 PM, Jakub Jelinekwrote: > > + && !get_AT (var_die, DW_AT_inline) > > + && (origin_die == NULL || get_AT (origin_die, DW_AT_inline) == > > NULL) > > Can we drop this repetition (here and for DW_AT_const_expr)? get_AT > should look through DW_AT_abstract_origin, and we should have added > that earlier in gen_variable_die. > > OK with that change. That seemed to have been the last usage of origin_die in gen_variable_die. So removing that caused: /home/mark/src/gcc/gcc/dwarf2out.c: In function ‘void gen_variable_die(tree, tree, dw_die_ref)’: /home/mark/src/gcc/gcc/dwarf2out.c:22454:14: error: variable ‘origin_die’ set but not used [-Werror=unused-but-set-variable] dw_die_ref origin_die = NULL; ^~ cc1plus: all warnings being treated as errors make[3]: *** [dwarf2out.o] Error 1 The following seems to work around that and makes things build again for me: diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 5ff6f97..24b85c1 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -22451,7 +22451,6 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) tree ultimate_origin; dw_die_ref var_die; dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL; - dw_die_ref origin_die = NULL; bool declaration = (DECL_EXTERNAL (decl_or_origin) || class_or_namespace_scope_p (context_die)); bool specialization_p = false; @@ -22627,7 +22626,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) var_die = new_die (DW_TAG_variable, context_die, decl); if (origin != NULL) -origin_die = add_abstract_origin_attribute (var_die, origin); +add_abstract_origin_attribute (var_die, origin); /* Loop unrolling can create multiple blocks that refer to the same static variable, so we must test for the DW_AT_declaration flag. Cheers, Mark
Re: [PATCH] Emit DW_AT_inline for C++17 inline variables (take 2)
On Tue, Nov 1, 2016 at 12:10 PM, Jakub Jelinekwrote: > + && !get_AT (var_die, DW_AT_inline) > + && (origin_die == NULL || get_AT (origin_die, DW_AT_inline) == NULL) Can we drop this repetition (here and for DW_AT_const_expr)? get_AT should look through DW_AT_abstract_origin, and we should have added that earlier in gen_variable_die. OK with that change. Jason
[PATCH] Emit DW_AT_inline for C++17 inline variables (take 2)
On Mon, Oct 31, 2016 at 10:38:40AM -0400, Jason Merrill wrote: > > The current DWARF 5 wording is: > > "If the variable entry represents the defining declaration for a C++ static > > data > > member of a structure, class or union, the entry has a DW_AT_specification > > attribute, whose value is a reference to the debugging information entry > > representing the declaration of this data member. The referenced entry has > > the tag DW_TAG_member and will be a child of some class, structure or > > union type entry." on page 98 in DWARF5_Public_Review.pdf. > > Yes, this changed in DWARF 3; DWARF 2 didn't specify the tag. I think > this was a mistake. > > > Incidentally, I've filed today a DWARF issue that Appendix A doesn't list > > for DW_TAG_member lots of attributes that are allowed for DW_TAG_variable > > and are useful for static data members. > > Using DW_TAG_variable would address that, too. After some IRC discussions, following updated patch ensures that even for inline static data members we emit DW_TAG_member in class with DW_AT_declaration and DW_TAG_variable outside of the class with DW_AT_specification pointing to the DW_TAG_member DIE. DW_AT_location and DW_AT_linkage_name appear on the DW_TAG_variable DIE, DW_AT_const_value/DW_AT_const_expr/DW_AT_inline etc. on DW_TAG_member (except for DW_AT_inline like for non-inline static data members). Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-11-01 Jakub Jelinek* dwarf2out.c (add_name_and_src_coords_attributes): Add NO_LINKAGE_NAME argument, don't call add_linkage_name if it is true. (gen_variable_die): For C++ inline static data members, consider the initial call when old_die is NULL to be declaration and call add_name_and_src_coords_attributes in that case with true as NO_LINKAGE_NAME. Add DW_AT_inline attribute if needed. (gen_member_die): For C++ inline static data members, emit a definition DIE right away in DW_TAG_compile_unit context. cp/ * cp-objcp-common.c (cp_decl_dwarf_attribute): Handle DW_AT_inline. testsuite/ * g++.dg/debug/dwarf2/inline-var-1.C: New test. --- gcc/dwarf2out.c.jj 2016-10-31 22:46:16.932801519 +0100 +++ gcc/dwarf2out.c 2016-11-01 11:51:57.839403234 +0100 @@ -3503,7 +3503,7 @@ static void add_prototyped_attribute (dw static dw_die_ref add_abstract_origin_attribute (dw_die_ref, tree); static void add_pure_or_virtual_attribute (dw_die_ref, tree); static void add_src_coords_attributes (dw_die_ref, tree); -static void add_name_and_src_coords_attributes (dw_die_ref, tree); +static void add_name_and_src_coords_attributes (dw_die_ref, tree, bool = false); static void add_discr_value (dw_die_ref, dw_discr_value *); static void add_discr_list (dw_die_ref, dw_discr_list_ref); static inline dw_discr_list_ref AT_discr_list (dw_attr_node *); @@ -19820,7 +19820,8 @@ add_linkage_name (dw_die_ref die, tree d given decl, but only if it actually has a name. */ static void -add_name_and_src_coords_attributes (dw_die_ref die, tree decl) +add_name_and_src_coords_attributes (dw_die_ref die, tree decl, + bool no_linkage_name) { tree decl_name; @@ -19833,7 +19834,8 @@ add_name_and_src_coords_attributes (dw_d if (! DECL_ARTIFICIAL (decl)) add_src_coords_attributes (die, decl); - add_linkage_name (die, decl); + if (!no_linkage_name) + add_linkage_name (die, decl); } #ifdef VMS_DEBUGGING_INFO @@ -22215,6 +22217,22 @@ gen_variable_die (tree decl, tree origin bool declaration = (DECL_EXTERNAL (decl_or_origin) || class_or_namespace_scope_p (context_die)); bool specialization_p = false; + bool no_linkage_name = false; + + /* While C++ inline static data members have definitions inside of the + class, force the first DIE to be a declaration, then let gen_member_die + reparent it to the class context and call gen_variable_die again + to create the outside of the class DIE for the definition. */ + if (!declaration + && old_die == NULL + && decl + && DECL_CONTEXT (decl) + && TYPE_P (DECL_CONTEXT (decl)) + && lang_hooks.decls.decl_dwarf_attribute (decl, DW_AT_inline) != -1) +{ + declaration = true; + no_linkage_name = true; +} ultimate_origin = decl_ultimate_origin (decl_or_origin); if (decl || ultimate_origin) @@ -22402,7 +22420,7 @@ gen_variable_die (tree decl, tree origin } } else -add_name_and_src_coords_attributes (var_die, decl); +add_name_and_src_coords_attributes (var_die, decl, no_linkage_name); if ((origin == NULL && !specialization_p) || (origin != NULL @@ -22465,6 +22483,17 @@ gen_variable_die (tree decl, tree origin && (origin_die == NULL || get_AT (origin_die, DW_AT_const_expr) == NULL) && !specialization_p) add_AT_flag (var_die, DW_AT_const_expr, 1); + + if
Re: [PATCH] Emit DW_AT_inline for C++17 inline variables
On Mon, Oct 31, 2016 at 10:25 AM, Jakub Jelinekwrote: > On Mon, Oct 31, 2016 at 09:52:28AM -0400, Jason Merrill wrote: >> On 10/14/2016 01:33 PM, Jakub Jelinek wrote: >> >This also uses the infrastructure of the langhook patch I've sent earlier. >> >It emits (if not strict dwarf) DW_AT_inline on explicit or implicit inline >> >variables, and also tweaks dwarf2out so that for inline static data members >> >we consider in-class declarations as definitions (emit DW_AT_linkage_name >> >and no DW_AT_declaration) for them. >> >> Hmm, so there's no DW_TAG_variable for the inline static data member? That >> seems problematic to me. The DWARF 3 convention that static data members >> use DW_TAG_member seems rather misguided, since in fact they are variables. >> Why did that change? > > I had to bisect it, apparently it has been changed by myself in > r145770, rationale in thread starting at > https://gcc.gnu.org/ml/gcc-patches/2009-04/msg00039.html > > The current DWARF 5 wording is: > "If the variable entry represents the defining declaration for a C++ static > data > member of a structure, class or union, the entry has a DW_AT_specification > attribute, whose value is a reference to the debugging information entry > representing the declaration of this data member. The referenced entry has > the tag DW_TAG_member and will be a child of some class, structure or > union type entry." on page 98 in DWARF5_Public_Review.pdf. Yes, this changed in DWARF 3; DWARF 2 didn't specify the tag. I think this was a mistake. > Incidentally, I've filed today a DWARF issue that Appendix A doesn't list > for DW_TAG_member lots of attributes that are allowed for DW_TAG_variable > and are useful for static data members. Using DW_TAG_variable would address that, too. Jason
Re: [PATCH] Emit DW_AT_inline for C++17 inline variables
On Mon, Oct 31, 2016 at 09:52:28AM -0400, Jason Merrill wrote: > On 10/14/2016 01:33 PM, Jakub Jelinek wrote: > >This also uses the infrastructure of the langhook patch I've sent earlier. > >It emits (if not strict dwarf) DW_AT_inline on explicit or implicit inline > >variables, and also tweaks dwarf2out so that for inline static data members > >we consider in-class declarations as definitions (emit DW_AT_linkage_name > >and no DW_AT_declaration) for them. > > Hmm, so there's no DW_TAG_variable for the inline static data member? That > seems problematic to me. The DWARF 3 convention that static data members > use DW_TAG_member seems rather misguided, since in fact they are variables. > Why did that change? I had to bisect it, apparently it has been changed by myself in r145770, rationale in thread starting at https://gcc.gnu.org/ml/gcc-patches/2009-04/msg00039.html The current DWARF 5 wording is: "If the variable entry represents the defining declaration for a C++ static data member of a structure, class or union, the entry has a DW_AT_specification attribute, whose value is a reference to the debugging information entry representing the declaration of this data member. The referenced entry has the tag DW_TAG_member and will be a child of some class, structure or union type entry." on page 98 in DWARF5_Public_Review.pdf. And page 117 has in 5.7.6: "A data member (as opposed to a member function) is represented by a debugging information entry with the tag DW_TAG_member." So, using DW_TAG_variable as DW_TAG_{structure,class}_type children for the non-inline static data members would violate these two. C++17 is outside of the scope of DWARF5 I guess, so the question is to find out what do we want for those and agree on that with consumers and other producers. Incidentally, I've filed today a DWARF issue that Appendix A doesn't list for DW_TAG_member lots of attributes that are allowed for DW_TAG_variable and are useful for static data members. Some of them we want anyway, at least unless we agree on the non-inline static data members no longer be DW_TAG_member in the structure/class type and change the standard. In particular DW_AT_const_value and DW_AT_const_expr are desirable even for the static data members in C++98..14 (or non-inline ones in C++17). The rest, like DW_AT_linkage_name, DW_AT_location, etc. are generally more useful mainly for the inline ones. Jakub
Re: [PATCH] Emit DW_AT_inline for C++17 inline variables
On 10/14/2016 01:33 PM, Jakub Jelinek wrote: This also uses the infrastructure of the langhook patch I've sent earlier. It emits (if not strict dwarf) DW_AT_inline on explicit or implicit inline variables, and also tweaks dwarf2out so that for inline static data members we consider in-class declarations as definitions (emit DW_AT_linkage_name and no DW_AT_declaration) for them. Hmm, so there's no DW_TAG_variable for the inline static data member? That seems problematic to me. The DWARF 3 convention that static data members use DW_TAG_member seems rather misguided, since in fact they are variables. Why did that change? Jason
[PATCH] Emit DW_AT_inline for C++17 inline variables
Hi! This also uses the infrastructure of the langhook patch I've sent earlier. It emits (if not strict dwarf) DW_AT_inline on explicit or implicit inline variables, and also tweaks dwarf2out so that for inline static data members we consider in-class declarations as definitions (emit DW_AT_linkage_name and no DW_AT_declaration) for them. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-10-14 Jakub Jelinek* dwarf2out.c (add_linkage_name): Add linkage attribute even for DW_TAG_member if it is inline static data member. (gen_variable_die): Consider inline static data member's DW_TAG_member to be definition rather than declaration. Add DW_AT_inline attribute if needed. cp/ * cp-objcp-common.c (cp_decl_dwarf_attribute): Handle DW_AT_inline. testsuite/ * g++.dg/debug/dwarf2/inline-var-1.C: New test. --- gcc/dwarf2out.c.jj 2016-10-14 15:22:57.0 +0200 +++ gcc/dwarf2out.c 2016-10-14 16:39:12.226917016 +0200 @@ -18896,7 +18896,10 @@ add_linkage_name (dw_die_ref die, tree d && VAR_OR_FUNCTION_DECL_P (decl) && TREE_PUBLIC (decl) && !(VAR_P (decl) && DECL_REGISTER (decl)) - && die->die_tag != DW_TAG_member) + && (die->die_tag != DW_TAG_member + || (VAR_P (decl) + && (lang_hooks.decls.decl_dwarf_attribute (decl, DW_AT_inline) + != -1 add_linkage_name_raw (die, decl); } @@ -21382,6 +21385,20 @@ gen_variable_die (tree decl, tree origin return; } + /* For static data members, the declaration (or definition for inline + variables) in the class is supposed to have DW_TAG_member tag; + the specification if any should still be DW_TAG_variable referencing + the DW_TAG_member DIE. */ + enum dwarf_tag tag = DW_TAG_variable; + if (declaration && class_scope_p (context_die)) +{ + tag = DW_TAG_member; + /* Inline static data members are defined inside of the class. */ + if (lang_hooks.decls.decl_dwarf_attribute (decl_or_origin, DW_AT_inline) + != -1) + declaration = false; +} + if (old_die) { if (declaration) @@ -21414,14 +21431,7 @@ gen_variable_die (tree decl, tree origin goto gen_variable_die_location; } } - - /* For static data members, the declaration in the class is supposed - to have DW_TAG_member tag; the specification should still be - DW_TAG_variable referencing the DW_TAG_member DIE. */ - if (declaration && class_scope_p (context_die)) -var_die = new_die (DW_TAG_member, context_die, decl); - else -var_die = new_die (DW_TAG_variable, context_die, decl); + var_die = new_die (tag, context_die, decl); if (origin != NULL) origin_die = add_abstract_origin_attribute (var_die, origin); @@ -21521,6 +21531,17 @@ gen_variable_die (tree decl, tree origin && (origin_die == NULL || get_AT (origin_die, DW_AT_const_expr) == NULL) && !specialization_p) add_AT_flag (var_die, DW_AT_const_expr, 1); + + if (!dwarf_strict) +{ + int inl = lang_hooks.decls.decl_dwarf_attribute (decl_or_origin, + DW_AT_inline); + if (inl != -1 + && !get_AT (var_die, DW_AT_inline) + && (origin_die == NULL || get_AT (origin_die, DW_AT_inline) == NULL) + && !specialization_p) + add_AT_unsigned (var_die, DW_AT_inline, inl); +} } /* Generate a DIE to represent a named constant. */ --- gcc/cp/cp-objcp-common.c.jj 2016-10-14 15:01:27.0 +0200 +++ gcc/cp/cp-objcp-common.c2016-10-14 15:46:14.650303379 +0200 @@ -173,6 +173,16 @@ cp_decl_dwarf_attribute (const_tree decl return 1; break; +case DW_AT_inline: + if (VAR_P (decl) && DECL_INLINE_VAR_P (decl)) + { + if (DECL_VAR_DECLARED_INLINE_P (decl)) + return DW_INL_declared_inlined; + else + return DW_INL_inlined; + } + break; + default: break; } --- gcc/testsuite/g++.dg/debug/dwarf2/inline-var-1.C.jj 2016-10-14 16:55:30.345512927 +0200 +++ gcc/testsuite/g++.dg/debug/dwarf2/inline-var-1.C2016-10-14 16:56:45.704558635 +0200 @@ -0,0 +1,26 @@ +// { dg-do compile } +// { dg-options "-O -std=c++1z -g -dA -gno-strict-dwarf" } +// { dg-require-weak "" } +// { dg-final { scan-assembler-times "0x3\[^\n\r]* DW_AT_inline" 6 } } +// { dg-final { scan-assembler-times "0x1\[^\n\r]* DW_AT_inline" 2 } } +// { dg-final { scan-assembler-not " DW_AT_declaration" } } +// { dg-final { scan-assembler-times " DW_AT_\[^\n\r]*linkage_name" 7 } } + +inline int a; +struct S +{ + static inline double b = 4.0; + static constexpr int c = 2; + static constexpr inline char d = 3; +} s; +template +inline int e = N; +int = e<2>; +template +struct T +{ + static inline double g = 4.0; + static constexpr int h = 2; + static inline constexpr char i = 3; +}; +T<5> t; Jakub