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 <ja...@redhat.com> * 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.000000000 +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.000000000 +0200 +++ gcc/cp/cp-objcp-common.c 2016-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.C 2016-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 <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; +}; +T<5> t; Jakub