On Fri, Oct 14, 2016 at 07:31:16PM +0200, Jakub Jelinek wrote: > This relies on the previous langhook patch (which greatly simplifies it). > > I'm only handling variables for now, DW_AT_const_expr is just weird on > functions/methods, it is supposed to appear only on > DW_TAG_inlined_subroutine? > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
This doesn't apply any longer, because Richard removed the origin_die variable this and following patch need. Here is an updated version that also reverts part of that change, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-10-20 Jakub Jelinek <ja...@redhat.com> * dwarf2out.c (gen_variable_die): Emit DW_AT_const_expr attribute if needed. Re-add origin_die variable and its initialization. cp/ * cp-objcp-common.c (cp_decl_dwarf_attribute): Handle DW_AT_const_expr. testsuite/ * g++.dg/debug/dwarf2/constexpr-var-1.C: New test. --- gcc/dwarf2out.c.jj 2016-10-14 14:37:15.000000000 +0200 +++ gcc/dwarf2out.c 2016-10-14 15:22:57.878078634 +0200 @@ -22247,6 +22247,7 @@ gen_variable_die (tree decl, tree origin 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; @@ -22413,7 +22414,7 @@ gen_variable_die (tree decl, tree origin var_die = new_die (tag, context_die, decl); if (origin != NULL) - add_abstract_origin_attribute (var_die, origin); + origin_die = 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. @@ -21513,6 +21513,14 @@ gen_variable_die (tree decl, tree origin } else tree_add_const_value_attribute_for_decl (var_die, decl_or_origin); + + if ((dwarf_version >= 4 || !dwarf_strict) + && lang_hooks.decls.decl_dwarf_attribute (decl_or_origin, + DW_AT_const_expr) == 1 + && !get_AT (var_die, DW_AT_const_expr) + && (origin_die == NULL || get_AT (origin_die, DW_AT_const_expr) == NULL) + && !specialization_p) + add_AT_flag (var_die, DW_AT_const_expr, 1); } /* Generate a DIE to represent a named constant. */ --- gcc/cp/cp-objcp-common.c.jj 2016-10-14 14:27:56.000000000 +0200 +++ gcc/cp/cp-objcp-common.c 2016-10-14 15:01:27.770495885 +0200 @@ -168,6 +168,11 @@ cp_decl_dwarf_attribute (const_tree decl } break; + case DW_AT_const_expr: + if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl)) + return 1; + break; + default: break; } --- gcc/testsuite/g++.dg/debug/dwarf2/constexpr-var-1.C.jj 2016-10-14 15:32:23.323882991 +0200 +++ gcc/testsuite/g++.dg/debug/dwarf2/constexpr-var-1.C 2016-10-14 15:31:56.000000000 +0200 @@ -0,0 +1,9 @@ +// { dg-do compile } +// { dg-options "-O -std=c++11 -g -dA -gno-strict-dwarf" } +// { dg-final { scan-assembler-times " DW_AT_const_expr" 2 } } + +constexpr int a = 5; +struct S +{ + static constexpr int b = 6; +} s; Jakub