Hi! This is another addition in DWARF5. The patch emits these attributes only for DW_TAG_subprogram for non-static ref-qualified member functions. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
We really should emit it also for DW_TAG_subroutine_type for PMF types, the problem is that for FUNCTION_TYPE/METHOD_TYPE, dwarf2out.c uses type_main_variant and get_qualified_type, neither of them understand ref-qualifies. I think we'd need to change get_qualified_type to use some lang-hook which for C++ would also check the ref qualifiers, and then for these two avoid type_main_variant and instead use get_qualified_type to get the non-const/volatile/restrict etc. qualified one (and only then we can use the decl_dwarf_attribute langhook to ask the FE whether the attribute should be emitted). Does that make sense, or do you have another approach? Is it ok to use decl_dwarf_attribute langhook for that, or do we need type_dwarf_attribute? 2016-10-24 Jakub Jelinek <ja...@redhat.com> * dwarf2out.c (gen_subprogram_die): Add DW_AT_reference or DW_AT_rvalue_reference attributes. * cp-objcp-common.c (cp_decl_dwarf_attribute): Handle DW_AT_reference and DW_AT_rvalue_reference. * g++.dg/debug/dwarf2/ref-2.C: New test. --- gcc/dwarf2out.c.jj 2016-10-22 18:57:43.000000000 +0200 +++ gcc/dwarf2out.c 2016-10-24 11:11:44.848161758 +0200 @@ -20662,6 +20662,21 @@ gen_subprogram_die (tree decl, dw_die_re if (defaulted != -1) add_AT_unsigned (subr_die, DW_AT_defaulted, defaulted); } + + /* If this is a C++11 non-static member function with & ref-qualifier + then generate a DW_AT_reference attribute. */ + if ((dwarf_version >= 5 || !dwarf_strict) + && lang_hooks.decls.decl_dwarf_attribute (decl, + DW_AT_reference) == 1) + add_AT_flag (subr_die, DW_AT_reference, 1); + + /* If this is a C++11 non-static member function with && + ref-qualifier then generate a DW_AT_reference attribute. */ + if ((dwarf_version >= 5 || !dwarf_strict) + && lang_hooks.decls.decl_dwarf_attribute (decl, + DW_AT_rvalue_reference) + == 1) + add_AT_flag (subr_die, DW_AT_rvalue_reference, 1); } } /* Tag abstract instances with DW_AT_inline. */ --- gcc/cp/cp-objcp-common.c.jj 2016-10-22 18:57:43.000000000 +0200 +++ gcc/cp/cp-objcp-common.c 2016-10-24 11:01:19.140065571 +0200 @@ -173,6 +173,32 @@ cp_decl_dwarf_attribute (const_tree decl return 1; break; + case DW_AT_reference: + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)) + && !FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) + return 1; + if ((TREE_CODE (decl) == FUNCTION_TYPE + || TREE_CODE (decl) == METHOD_TYPE) + && FUNCTION_REF_QUALIFIED (decl) + && !FUNCTION_RVALUE_QUALIFIED (decl)) + return 1; + break; + + case DW_AT_rvalue_reference: + if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl) + && FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)) + && FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) + return 1; + if ((TREE_CODE (decl) == FUNCTION_TYPE + || TREE_CODE (decl) == METHOD_TYPE) + && FUNCTION_REF_QUALIFIED (decl) + && FUNCTION_RVALUE_QUALIFIED (decl)) + return 1; + break; + default: break; } --- gcc/testsuite/g++.dg/debug/dwarf2/ref-2.C.jj 2016-10-24 11:43:32.054070334 +0200 +++ gcc/testsuite/g++.dg/debug/dwarf2/ref-2.C 2016-10-24 11:51:48.173803454 +0200 @@ -0,0 +1,20 @@ +// { dg-do compile { target c++11 } } +// { dg-options "-g -gno-strict-dwarf -dA" } +// { dg-final { scan-assembler-times " DW_AT_reference" 1 } } +// { dg-final { scan-assembler-times " DW_AT_rvalue_reference" 1 } } + +struct S +{ + void foo (); + void bar () &; + void baz () &&; +}; + +void +test () +{ + S s; + s.foo (); + s.bar (); + S ().baz (); +} Jakub