Message ID | 20170222165750.GZ1849@tucnak |
---|---|
State | New |
Headers | show |
OK. On Wed, Feb 22, 2017 at 8:57 AM, Jakub Jelinek <jakub@redhat.com> wrote: > On Tue, Feb 21, 2017 at 12:37:32PM -0800, Jason Merrill wrote: >> On Sat, Feb 18, 2017 at 12:17 AM, Jakub Jelinek <jakub@redhat.com> wrote: >> > On Fri, Feb 17, 2017 at 09:37:09PM -0500, Jason Merrill wrote: >> >> On Fri, Feb 17, 2017 at 1:52 PM, Jakub Jelinek <jakub@redhat.com> wrote: >> >> > - && die->die_tag != DW_TAG_member) >> >> > + && die->die_tag != DW_TAG_member >> >> > + && (die->die_tag != DW_TAG_variable || !class_scope_p (die->die_parent))) >> >> >> >> How about we only check class_scope_p (die->die_parent), and don't >> >> consider the TAG at all? DW_TAG_member should only appear at class >> >> scope. >> > >> > That wouldn't work, because that would avoid adding linkage attributes to >> > methods. I could use: >> > && (die->die_tag == DW_TAG_subprogram || !class_scope_p (die->die_parent)) >> > (not 100% sure if some other tag than those can make it here) >> > or >> > && ((die->die_tag != DW_TAG_member || die->die_tag != DW_TAG_variable) >> > || !class_scope_p (die->die_parent)) >> > or just use >> > && (!VAR_P (decl) || !class_scope_p (die->die_parent)) >> > or similar. >> > >> >> > - if (old_die->die_tag == DW_TAG_member) >> >> > + if (old_die->die_tag == DW_TAG_member >> >> > + || (dwarf_version >= 5 && class_scope_p (old_die->die_parent))) >> >> >> >> Likewise here. >> > >> > This spot probably can be changed as you wrote, it is in gen_variable_die, >> > so methods shouldn't appear there. >> >> Hmm, let's think about the behavior we want here. I don't see any >> reason not to put AT_linkage_name on a member DW_TAG_variable; I think >> the old behavior avoided putting it on DW_TAG_member just because it >> isn't defined for DW_TAG_member. So it's not clear to me that we need >> any changes in add_linkage_name or its call site. > > Ah, ok. But then we need to make sure gen_variable_die doesn't set > no_linkage_name for -gdwarf-5, because otherwise on the attached testcase > we don't emit linkage_name on b, c, d anywhere (we used to emit that > before). > > Starting bootstrap/regtest now, does this look ok if that passes? > > 2017-02-22 Jakub Jelinek <jakub@redhat.com> > > * dwarf2out.c (gen_variable_die): For -gdwarf-5, use DW_TAG_variable > instead of DW_TAG_member for static data member declarations and don't > set no_linkage_name for static inline data members. > (gen_member_die): For -gdwarf-5 don't change DW_TAG_variable > to DW_TAG_member. > > * g++.dg/debug/dwarf2/inline-var-2.C: New test. > > --- gcc/dwarf2out.c.jj 2017-02-18 17:11:18.759821871 +0100 > +++ gcc/dwarf2out.c 2017-02-22 17:48:27.378223877 +0100 > @@ -22669,7 +22669,8 @@ gen_variable_die (tree decl, tree origin > && lang_hooks.decls.decl_dwarf_attribute (decl, DW_AT_inline) != -1) > { > declaration = true; > - no_linkage_name = true; > + if (dwarf_version < 5) > + no_linkage_name = true; > } > > ultimate_origin = decl_ultimate_origin (decl_or_origin); > @@ -22820,9 +22821,10 @@ gen_variable_die (tree decl, tree origin > } > > /* 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)) > + to have DW_TAG_member tag in DWARF{3,4} and we emit it for compatibility > + also in DWARF2; the specification should still be DW_TAG_variable > + referencing the DW_TAG_member DIE. */ > + if (declaration && class_scope_p (context_die) && dwarf_version < 5) > var_die = new_die (DW_TAG_member, context_die, decl); > else > var_die = new_die (DW_TAG_variable, context_die, decl); > @@ -24091,7 +24093,8 @@ gen_member_die (tree type, dw_die_ref co > && get_AT (child, DW_AT_specification) == NULL) > { > reparent_child (child, context_die); > - child->die_tag = DW_TAG_member; > + if (dwarf_version < 5) > + child->die_tag = DW_TAG_member; > } > else > splice_child_die (context_die, child); > @@ -24113,7 +24116,7 @@ gen_member_die (tree type, dw_die_ref co > } > > /* For C++ inline static data members emit immediately a DW_TAG_variable > - DIE that will refer to that DW_TAG_member through > + DIE that will refer to that DW_TAG_member/DW_TAG_variable through > DW_AT_specification. */ > if (TREE_STATIC (member) > && (lang_hooks.decls.decl_dwarf_attribute (member, DW_AT_inline) > --- gcc/testsuite/g++.dg/debug/dwarf2/inline-var-2.C.jj 2017-02-22 17:54:28.019597440 +0100 > +++ gcc/testsuite/g++.dg/debug/dwarf2/inline-var-2.C 2017-02-22 17:54:10.000000000 +0100 > @@ -0,0 +1,35 @@ > +// { dg-do compile } > +// { dg-options "-O -std=c++1z -gdwarf-5 -dA -gno-strict-dwarf" } > +// { dg-require-weak "" } > +// { dg-final { scan-assembler-not "DW_TAG_member" { xfail *-*-aix* } } } > + > +inline int a; > +struct S > +{ > + static inline double b = 4.0; > + static constexpr int c = 2; > + static constexpr inline char d = 3; > + static const int j = 7; > + static int k; > + static double l; > +} s; > +const int S::j; > +int S::k = 8; > +template <int N> > +inline int e = N; > +int &f = e<2>; > +template <int N> > +struct T > +{ > + static inline double g = 4.0; > + static constexpr int h = 2; > + static inline constexpr char i = 3; > + static const int m = 8; > + static int n; > + static double o; > +}; > +T<5> t; > +template <> > +const int T<5>::m; > +template <> > +int T<5>::n = 9; > > > Jakub
--- gcc/dwarf2out.c.jj 2017-02-18 17:11:18.759821871 +0100 +++ gcc/dwarf2out.c 2017-02-22 17:48:27.378223877 +0100 @@ -22669,7 +22669,8 @@ gen_variable_die (tree decl, tree origin && lang_hooks.decls.decl_dwarf_attribute (decl, DW_AT_inline) != -1) { declaration = true; - no_linkage_name = true; + if (dwarf_version < 5) + no_linkage_name = true; } ultimate_origin = decl_ultimate_origin (decl_or_origin); @@ -22820,9 +22821,10 @@ gen_variable_die (tree decl, tree origin } /* 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)) + to have DW_TAG_member tag in DWARF{3,4} and we emit it for compatibility + also in DWARF2; the specification should still be DW_TAG_variable + referencing the DW_TAG_member DIE. */ + if (declaration && class_scope_p (context_die) && dwarf_version < 5) var_die = new_die (DW_TAG_member, context_die, decl); else var_die = new_die (DW_TAG_variable, context_die, decl); @@ -24091,7 +24093,8 @@ gen_member_die (tree type, dw_die_ref co && get_AT (child, DW_AT_specification) == NULL) { reparent_child (child, context_die); - child->die_tag = DW_TAG_member; + if (dwarf_version < 5) + child->die_tag = DW_TAG_member; } else splice_child_die (context_die, child); @@ -24113,7 +24116,7 @@ gen_member_die (tree type, dw_die_ref co } /* For C++ inline static data members emit immediately a DW_TAG_variable - DIE that will refer to that DW_TAG_member through + DIE that will refer to that DW_TAG_member/DW_TAG_variable through DW_AT_specification. */ if (TREE_STATIC (member) && (lang_hooks.decls.decl_dwarf_attribute (member, DW_AT_inline) --- gcc/testsuite/g++.dg/debug/dwarf2/inline-var-2.C.jj 2017-02-22 17:54:28.019597440 +0100 +++ gcc/testsuite/g++.dg/debug/dwarf2/inline-var-2.C 2017-02-22 17:54:10.000000000 +0100 @@ -0,0 +1,35 @@ +// { dg-do compile } +// { dg-options "-O -std=c++1z -gdwarf-5 -dA -gno-strict-dwarf" } +// { dg-require-weak "" } +// { dg-final { scan-assembler-not "DW_TAG_member" { xfail *-*-aix* } } } + +inline int a; +struct S +{ + static inline double b = 4.0; + static constexpr int c = 2; + static constexpr inline char d = 3; + static const int j = 7; + static int k; + static double l; +} s; +const int S::j; +int S::k = 8; +template <int N> +inline int e = N; +int &f = e<2>; +template <int N> +struct T +{ + static inline double g = 4.0; + static constexpr int h = 2; + static inline constexpr char i = 3; + static const int m = 8; + static int n; + static double o; +}; +T<5> t; +template <> +const int T<5>::m; +template <> +int T<5>::n = 9;