diff mbox

Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference

Message ID 20161024142951.GO7282@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Oct. 24, 2016, 2:29 p.m. UTC
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  <jakub@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.


	Jakub

Comments

Jason Merrill Oct. 24, 2016, 6:34 p.m. UTC | #1
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
Jakub Jelinek Oct. 24, 2016, 7:09 p.m. UTC | #2
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
Jason Merrill Oct. 31, 2016, 1:56 p.m. UTC | #3
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
diff mbox

Patch

--- 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 ();
+}