Message ID | 20161024142951.GO7282@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On Mon, Oct 24, 2016 at 10:29 AM, Jakub Jelinek <jakub@redhat.com> wrote: > 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? OK. > 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? Can we pull out the ref-qualifier before we clobber the qualifiers on the type? > Is it ok to use decl_dwarf_attribute langhook for that, or > do we need type_dwarf_attribute? I think it's fine to use the same langhook, but we probably want to rename it. Jason
On Mon, Oct 24, 2016 at 02:34:04PM -0400, Jason Merrill wrote: > On Mon, Oct 24, 2016 at 10:29 AM, Jakub Jelinek <jakub@redhat.com> wrote: > > 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? > > OK. Thanks, committed. > > 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? > > Can we pull out the ref-qualifier before we clobber the qualifiers on the type? We could handle it like "reverse" flag, basically replace bool reverse with int that would hold bitmask of the flags, but I really don't understand how the reverse flag works right now, I don't see how it can work reliably when we use and rely on equate_type_number_to_die/lookup_type_die mechanism where we store just a single DIE for each type. We either equate it to a type with DW_AT_endianity present, or not, and then the rest of the lookups will be just random. I'm afraid to make it work reliably we'd need to somehow store both the "reverse" and "!reverse" DIEs for each type DIE, and similarly for the & and && flags. Or by changing get_qualified_die (in particular check_base_type) to use a langhook, we could at least for DW_AT_{reference,rvalue_reference} just use equate_type_number_to_die/lookup_type_die reliably (DW_AT_endianity issue remains). Jakub
On 10/24/2016 03:09 PM, Jakub Jelinek wrote: > On Mon, Oct 24, 2016 at 02:34:04PM -0400, Jason Merrill wrote: >> On Mon, Oct 24, 2016 at 10:29 AM, Jakub Jelinek <jakub@redhat.com> wrote: >>> 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? >> >> OK. > > Thanks, committed. > >>> 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? >> >> Can we pull out the ref-qualifier before we clobber the qualifiers on the type? > > We could handle it like "reverse" flag, basically replace bool reverse with > int that would hold bitmask of the flags, but I really don't understand how > the reverse flag works right now, I don't see how it can work reliably when > we use and rely on equate_type_number_to_die/lookup_type_die mechanism where > we store just a single DIE for each type. We either equate it to a type > with DW_AT_endianity present, or not, and then the rest of the lookups will > be just random. I'm afraid to make it work reliably we'd need to somehow > store both the "reverse" and "!reverse" DIEs for each type DIE, and > similarly for the & and && flags. > > Or by changing get_qualified_die (in particular check_base_type) to use a > langhook, we could at least for DW_AT_{reference,rvalue_reference} just use > equate_type_number_to_die/lookup_type_die reliably (DW_AT_endianity issue > remains). Yeah, I think that adding a langhook is the right way to go. The generic code clobbering C++ qualifiers is a frequent headache. Jason
--- 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 (); +}