public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference
@ 2016-10-24 14:29 Jakub Jelinek
  2016-10-24 18:34 ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2016-10-24 14:29 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

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.

--- 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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference
  2016-10-24 14:29 [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference Jakub Jelinek
@ 2016-10-24 18:34 ` Jason Merrill
  2016-10-24 19:09   ` Jakub Jelinek
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2016-10-24 18:34 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches List

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference
  2016-10-24 18:34 ` Jason Merrill
@ 2016-10-24 19:09   ` Jakub Jelinek
  2016-10-31 13:56     ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2016-10-24 19:09 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference
  2016-10-24 19:09   ` Jakub Jelinek
@ 2016-10-31 13:56     ` Jason Merrill
  2016-11-01 13:56       ` Jakub Jelinek
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2016-10-31 13:56 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches List

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference
  2016-10-31 13:56     ` Jason Merrill
@ 2016-11-01 13:56       ` Jakub Jelinek
  2016-11-01 18:05         ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Jelinek @ 2016-11-01 13:56 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Mon, Oct 31, 2016 at 09:56:28AM -0400, Jason Merrill wrote:
> >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.

I've tried to implement that, but am getting some TYPE_CANONICAL differences
because of that, and am really lost what the problem is and how to fix it.
Furthermore, I bet the exception specification also should be considered in
that langhook.

The testcase I've been trying is:

struct S
{
  void foo1 ();
  void bar1 () &;
  void baz1 () &&;
  void foo2 () const;
  void bar2 () const &;
  void baz2 () const &&;
  void foo3 () const;
  void bar3 () const &;
  void baz3 () const &&;
};

void
test ()
{
  S s;
  auto o1 = &S::foo1;
  auto r1 = &S::bar1;
  auto z1 = &S::baz1;
  auto o2 = &S::foo2;
  auto r2 = &S::bar2;
  auto z2 = &S::baz2;
  auto o3 = &S::foo3;
  auto r3 = &S::bar3;
  auto z3 = &S::baz3;
  void (S::*o4) () const;
  o4 = &S::foo3;
  void (S::*r4) () const &;
  r4 = &S::bar3;
  void (S::*z4) () const &&;
  z4 = &S::baz3;
  (s.*o1) ();
  (s.*r1) ();
  (S ().*z1) ();
  (s.*o2) ();
  (s.*r2) ();
  (S ().*z2) ();
  (s.*o3) ();
  (s.*r3) ();
  (S ().*z3) ();
  (s.*o4) ();
  (s.*r4) ();
  (S ().*z4) ();
}

--- gcc/hooks.h.jj	2016-10-31 13:28:06.000000000 +0100
+++ gcc/hooks.h	2016-11-01 12:55:33.662494341 +0100
@@ -59,6 +59,7 @@ extern bool hook_bool_rtx_mode_int_int_i
 							int, int, int *, bool);
 extern bool hook_bool_tree_tree_false (tree, tree);
 extern bool hook_bool_tree_tree_true (tree, tree);
+extern bool hook_bool_const_tree_const_tree_true (const_tree, const_tree);
 extern bool hook_bool_tree_bool_false (tree, bool);
 extern bool hook_bool_wint_wint_uint_bool_true (const widest_int &,
 						const widest_int &,
--- gcc/cp/cp-objcp-common.h.jj	2016-10-31 13:28:11.000000000 +0100
+++ gcc/cp/cp-objcp-common.h	2016-11-01 12:56:44.446605921 +0100
@@ -27,6 +27,8 @@ extern tree objcp_tsubst_copy_and_build
 					 tree, bool);
 
 extern int cp_decl_dwarf_attribute (const_tree, int);
+extern int cp_type_dwarf_attribute (const_tree, int);
+extern bool cp_check_base_type (const_tree, const_tree);
 extern void cp_common_init_ts (void);
 
 /* Lang hooks that are shared between C++ and ObjC++ are defined here.  Hooks
@@ -131,6 +133,10 @@ extern void cp_common_init_ts (void);
 #define LANG_HOOKS_GIMPLIFY_EXPR cp_gimplify_expr
 #undef LANG_HOOKS_DECL_DWARF_ATTRIBUTE
 #define LANG_HOOKS_DECL_DWARF_ATTRIBUTE cp_decl_dwarf_attribute
+#undef LANG_HOOKS_TYPE_DWARF_ATTRIBUTE
+#define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE cp_type_dwarf_attribute
+#undef LANG_HOOKS_CHECK_BASE_TYPE
+#define LANG_HOOKS_CHECK_BASE_TYPE cp_check_base_type
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
 #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
--- gcc/cp/cp-objcp-common.c.jj	2016-11-01 14:39:29.308309164 +0100
+++ gcc/cp/cp-objcp-common.c	2016-11-01 14:22:40.135992547 +0100
@@ -179,11 +179,6 @@ cp_decl_dwarf_attribute (const_tree 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:
@@ -192,11 +187,6 @@ cp_decl_dwarf_attribute (const_tree 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_inline:
@@ -216,6 +206,57 @@ cp_decl_dwarf_attribute (const_tree decl
   return -1;
 }
 
+/* Return -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute
+   value otherwise.  */
+int
+cp_type_dwarf_attribute (const_tree type, int attr)
+{
+  if (type == NULL_TREE)
+    return -1;
+
+  switch (attr)
+    {
+    case DW_AT_reference:
+      if ((TREE_CODE (type) == FUNCTION_TYPE
+	   || TREE_CODE (type) == METHOD_TYPE)
+	  && FUNCTION_REF_QUALIFIED (type)
+	  && !FUNCTION_RVALUE_QUALIFIED (type))
+	return 1;
+      break;
+
+    case DW_AT_rvalue_reference:
+      if ((TREE_CODE (type) == FUNCTION_TYPE
+	   || TREE_CODE (type) == METHOD_TYPE)
+	  && FUNCTION_REF_QUALIFIED (type)
+	  && FUNCTION_RVALUE_QUALIFIED (type))
+	return 1;
+      break;
+
+    default:
+      break;
+    }
+
+  return -1;
+}
+
+/* Perform any FE specific additional testing whether
+   CAND and BASE are the same type for except for get_qualified_type
+   purposes.  */
+
+bool
+cp_check_base_type (const_tree cand, const_tree base)
+{
+  if (TREE_CODE (cand) == FUNCTION_TYPE
+      || TREE_CODE (cand) == METHOD_TYPE)
+    {
+      gcc_assert (TREE_CODE (base) == FUNCTION_TYPE
+		  || TREE_CODE (base) == METHOD_TYPE);
+      if (type_memfn_rqual (cand) != type_memfn_rqual (base))
+	return false;
+    }
+  return true;
+}
+
 /* Stubs to keep c-opts.c happy.  */
 void
 push_file_scope (void)
--- gcc/hooks.c.jj	2016-10-31 13:28:06.000000000 +0100
+++ gcc/hooks.c	2016-11-01 12:55:58.479182864 +0100
@@ -293,6 +293,12 @@ hook_bool_tree_tree_true (tree, tree)
 }
 
 bool
+hook_bool_const_tree_const_tree_true (const_tree, const_tree)
+{
+  return true;
+}
+
+bool
 hook_bool_tree_bool_false (tree, bool)
 {
   return false;
--- gcc/dwarf2out.c.jj	2016-11-01 12:27:57.000000000 +0100
+++ gcc/dwarf2out.c	2016-11-01 14:12:07.533930429 +0100
@@ -12569,8 +12569,19 @@ modified_type_die (tree type, int cv_qua
 	 copy was created to help us keep track of typedef names) and
 	 that copy might have a different TYPE_UID from the original
 	 ..._TYPE node.  */
-      if (TREE_CODE (type) != VECTOR_TYPE
-	  && TREE_CODE (type) != ARRAY_TYPE)
+      if (TREE_CODE (type) == FUNCTION_TYPE
+	  || TREE_CODE (type) == METHOD_TYPE)
+	{
+	  /* For function/method types, can't use type_main_variant here,
+	     because that can have different ref-qualifiers for C++,
+	     but try to canonicalize.  */
+	  for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+	    if (check_qualified_type (t, type, TYPE_QUALS (type)))
+	      type = t;
+	  return lookup_type_die (type);
+	}
+      else if (TREE_CODE (type) != VECTOR_TYPE
+	       && TREE_CODE (type) != ARRAY_TYPE)
 	return lookup_type_die (type_main_variant (type));
       else
 	/* Vectors have the debugging information in the type,
@@ -24054,6 +24065,13 @@ gen_subroutine_type_die (tree type, dw_d
 
   if (get_AT (subr_die, DW_AT_name))
     add_pubtype (type, subr_die);
+  if ((dwarf_version >= 5 || !dwarf_strict)
+      && lang_hooks.types.type_dwarf_attribute (type, DW_AT_reference) != -1)
+    add_AT_flag (subr_die, DW_AT_reference, 1);
+  if ((dwarf_version >= 5 || !dwarf_strict)
+      && lang_hooks.types.type_dwarf_attribute (type,
+						DW_AT_rvalue_reference) != -1)
+    add_AT_flag (subr_die, DW_AT_rvalue_reference, 1);
 }
 
 /* Generate a DIE for a type definition.  */
@@ -24279,9 +24297,20 @@ gen_type_die_with_usage (tree type, dw_d
      of this type (i.e. without any const or volatile qualifiers) so
      get the main variant (i.e. the unqualified version) of this type
      now.  (Vectors and arrays are special because the debugging info is in the
-     cloned type itself).  */
-  if (TREE_CODE (type) != VECTOR_TYPE
-      && TREE_CODE (type) != ARRAY_TYPE)
+     cloned type itself.  Similarly function/method types can contain extra
+     ref-qualification).  */
+  if (TREE_CODE (type) == FUNCTION_TYPE
+      || TREE_CODE (type) == METHOD_TYPE)
+    {
+      /* For function/method types, can't use type_main_variant here,
+	 because that can have different ref-qualifiers for C++,
+	 but try to canonicalize.  */
+      for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+	if (check_qualified_type (t, type, TYPE_QUALS (type)))
+	  type = t;
+    }
+  else if (TREE_CODE (type) != VECTOR_TYPE
+	   && TREE_CODE (type) != ARRAY_TYPE)
     type = type_main_variant (type);
 
   /* If this is an array type with hidden descriptor, handle it first.  */
@@ -24353,14 +24382,14 @@ gen_type_die_with_usage (tree type, dw_d
     case FUNCTION_TYPE:
       /* Force out return type (in case it wasn't forced out already).  */
       gen_type_die_with_usage (TREE_TYPE (type), context_die,
-					DINFO_USAGE_DIR_USE);
+			       DINFO_USAGE_DIR_USE);
       gen_subroutine_type_die (type, context_die);
       break;
 
     case METHOD_TYPE:
       /* Force out return type (in case it wasn't forced out already).  */
       gen_type_die_with_usage (TREE_TYPE (type), context_die,
-					DINFO_USAGE_DIR_USE);
+			       DINFO_USAGE_DIR_USE);
       gen_subroutine_type_die (type, context_die);
       break;
 
--- gcc/langhooks-def.h.jj	2016-10-31 13:28:13.000000000 +0100
+++ gcc/langhooks-def.h	2016-11-01 13:29:15.299138536 +0100
@@ -84,6 +84,7 @@ extern bool lhd_omp_mappable_type (tree)
 extern const char *lhd_get_substring_location (const substring_loc &,
 					       location_t *out_loc);
 extern int lhd_decl_dwarf_attribute (const_tree, int);
+extern int lhd_type_dwarf_attribute (const_tree, int);
 
 #define LANG_HOOKS_NAME			"GNU unknown"
 #define LANG_HOOKS_IDENTIFIER_SIZE	sizeof (struct lang_identifier)
@@ -186,6 +187,8 @@ extern tree lhd_make_node (enum tree_cod
 #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE lhd_enum_underlying_base_type
 #define LANG_HOOKS_GET_DEBUG_TYPE	NULL
 #define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO NULL
+#define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE	lhd_type_dwarf_attribute
+#define LANG_HOOKS_CHECK_BASE_TYPE	hook_bool_const_tree_const_tree_true
 
 #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
   LANG_HOOKS_MAKE_TYPE, \
@@ -208,7 +211,9 @@ extern tree lhd_make_node (enum tree_cod
   LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \
   LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE, \
   LANG_HOOKS_GET_DEBUG_TYPE, \
-  LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO \
+  LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO, \
+  LANG_HOOKS_TYPE_DWARF_ATTRIBUTE, \
+  LANG_HOOKS_CHECK_BASE_TYPE \
 }
 
 /* Declaration hooks.  */
--- gcc/langhooks.h.jj	2016-10-31 16:42:21.349663774 +0100
+++ gcc/langhooks.h	2016-11-01 12:49:31.618038408 +0100
@@ -162,6 +162,14 @@ struct lang_hooks_for_types
      for the debugger about scale factor, etc.  */
   bool (*get_fixed_point_type_info) (const_tree,
 				     struct fixed_point_type_info *);
+
+  /* Returns -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute
+     value otherwise.  */
+  int (*type_dwarf_attribute) (const_tree, int);
+
+  /* Return TRUE iff unqualified CAND and BASE types are equivalent for
+     check_qualified_type purposes.  */
+  bool (*check_base_type) (const_tree, const_tree);
 };
 
 /* Language hooks related to decls and the symbol table.  */
--- gcc/tree.c.jj	2016-10-31 16:42:21.348663787 +0100
+++ gcc/tree.c	2016-11-01 12:49:31.622038358 +0100
@@ -6507,6 +6507,7 @@ check_base_type (const_tree cand, const_
 	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
 	  /* Check alignment.  */
 	  && TYPE_ALIGN (cand) == TYPE_ALIGN (base)
+	  && lang_hooks.types.check_base_type (cand, base)
 	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
 				   TYPE_ATTRIBUTES (base)));
 }
--- gcc/langhooks.c.jj	2016-10-31 13:28:11.000000000 +0100
+++ gcc/langhooks.c	2016-11-01 12:53:22.330142711 +0100
@@ -702,6 +702,15 @@ lhd_decl_dwarf_attribute (const_tree, in
   return -1;
 }
 
+/* Default implementation of LANG_HOOKS_TYPE_DWARF_ATTRIBUTE.  Don't add
+   any attributes.  */
+
+int
+lhd_type_dwarf_attribute (const_tree, int)
+{
+  return -1;
+}
+
 /* Returns true if the current lang_hooks represents the GNU C frontend.  */
 
 bool


	Jakub

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference
  2016-11-01 13:56       ` Jakub Jelinek
@ 2016-11-01 18:05         ` Jason Merrill
  2016-11-01 18:44           ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2016-11-01 18:05 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches List

On Tue, Nov 1, 2016 at 9:56 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Mon, Oct 31, 2016 at 09:56:28AM -0400, Jason Merrill wrote:
>> >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.
>
> I've tried to implement that, but am getting some TYPE_CANONICAL differences
> because of that, and am really lost what the problem is and how to fix it.
> Furthermore, I bet the exception specification also should be considered in
> that langhook.

Yes.  I'll take a look.

Jason

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference
  2016-11-01 18:05         ` Jason Merrill
@ 2016-11-01 18:44           ` Jason Merrill
  0 siblings, 0 replies; 7+ messages in thread
From: Jason Merrill @ 2016-11-01 18:44 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 994 bytes --]

On Tue, Nov 1, 2016 at 2:04 PM, Jason Merrill <jason@redhat.com> wrote:
> On Tue, Nov 1, 2016 at 9:56 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> On Mon, Oct 31, 2016 at 09:56:28AM -0400, Jason Merrill wrote:
>>> >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.
>>
>> I've tried to implement that, but am getting some TYPE_CANONICAL differences
>> because of that, and am really lost what the problem is and how to fix it.
>> Furthermore, I bet the exception specification also should be considered in
>> that langhook.
>
> Yes.  I'll take a look.

This patch on top of yours passes regtest and seems to DTRT with your
testcase on brief inspection.

[-- Attachment #2: check-lang-type.diff --]
[-- Type: text/plain, Size: 8266 bytes --]

commit d11a8a96689cc81c71fc48b16653aff2227b6fff
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 1 14:13:00 2016 -0400

    fix

diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 986821d..0ef7e1e 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -135,8 +135,6 @@ extern void cp_common_init_ts (void);
 #define LANG_HOOKS_DECL_DWARF_ATTRIBUTE cp_decl_dwarf_attribute
 #undef LANG_HOOKS_TYPE_DWARF_ATTRIBUTE
 #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE cp_type_dwarf_attribute
-#undef LANG_HOOKS_CHECK_BASE_TYPE
-#define LANG_HOOKS_CHECK_BASE_TYPE cp_check_base_type
 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
 #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ac15d67..4dc6e22 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1980,7 +1980,8 @@ static bool
 cp_check_qualified_type (const_tree cand, const_tree base, int type_quals,
 			 cp_ref_qualifier rqual, tree raises)
 {
-  return (check_qualified_type (cand, base, type_quals)
+  return (TYPE_QUALS (cand) == type_quals
+	  && check_base_type (cand, base)
 	  && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (cand),
 				ce_exact)
 	  && type_memfn_rqual (cand) == rqual);
@@ -4080,9 +4081,7 @@ cp_build_type_attribute_variant (tree type, tree attributes)
 }
 
 /* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
-   Called only after doing all language independent checks.  Only
-   to check TYPE_RAISES_EXCEPTIONS for FUNCTION_TYPE, the rest is already
-   compared in type_hash_eq.  */
+   Called only after doing all language independent checks.  */
 
 bool
 cxx_type_hash_eq (const_tree typea, const_tree typeb)
@@ -4090,6 +4089,8 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb)
   gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE
 	      || TREE_CODE (typea) == METHOD_TYPE);
 
+  if (type_memfn_rqual (typea) != type_memfn_rqual (typeb))
+    return false;
   return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea),
 			    TYPE_RAISES_EXCEPTIONS (typeb), ce_exact);
 }
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c823fdb..21b5380 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -12336,12 +12336,14 @@ modified_type_die (tree type, int cv_quals, bool reverse,
       if (TREE_CODE (type) == FUNCTION_TYPE
 	  || TREE_CODE (type) == METHOD_TYPE)
 	{
-	  /* For function/method types, can't use type_main_variant here,
+	  /* For function/method types, can't just use type_main_variant here,
 	     because that can have different ref-qualifiers for C++,
 	     but try to canonicalize.  */
-	  for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-	    if (check_qualified_type (t, type, TYPE_QUALS (type)))
-	      type = t;
+	  tree main = TYPE_MAIN_VARIANT (type);
+	  for (tree t = main; t; t = TYPE_NEXT_VARIANT (t))
+	    if (check_base_type (t, main)
+		&& check_lang_type (t, type))
+	      return lookup_type_die (t);
 	  return lookup_type_die (type);
 	}
       else if (TREE_CODE (type) != VECTOR_TYPE
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 24f6c99..3995786 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -293,12 +293,6 @@ hook_bool_tree_tree_true (tree, tree)
 }
 
 bool
-hook_bool_const_tree_const_tree_true (const_tree, const_tree)
-{
-  return true;
-}
-
-bool
 hook_bool_tree_bool_false (tree, bool)
 {
   return false;
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 7965603..a1d6776 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -59,7 +59,6 @@ extern bool hook_bool_rtx_mode_int_int_intp_bool_false (rtx, machine_mode,
 							int, int, int *, bool);
 extern bool hook_bool_tree_tree_false (tree, tree);
 extern bool hook_bool_tree_tree_true (tree, tree);
-extern bool hook_bool_const_tree_const_tree_true (const_tree, const_tree);
 extern bool hook_bool_tree_bool_false (tree, bool);
 extern bool hook_bool_wint_wint_uint_bool_true (const widest_int &,
 						const widest_int &,
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index bb7b97a..5c330f0 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -188,7 +188,6 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_GET_DEBUG_TYPE	NULL
 #define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO NULL
 #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE	lhd_type_dwarf_attribute
-#define LANG_HOOKS_CHECK_BASE_TYPE	hook_bool_const_tree_const_tree_true
 
 #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
   LANG_HOOKS_MAKE_TYPE, \
@@ -212,8 +211,7 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE, \
   LANG_HOOKS_GET_DEBUG_TYPE, \
   LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO, \
-  LANG_HOOKS_TYPE_DWARF_ATTRIBUTE, \
-  LANG_HOOKS_CHECK_BASE_TYPE \
+  LANG_HOOKS_TYPE_DWARF_ATTRIBUTE \
 }
 
 /* Declaration hooks.  */
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index c8bbd24..150227c 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -120,7 +120,7 @@ struct lang_hooks_for_types
   /* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
      Called only after doing all language independent checks.
      At present, this function is only called when both TYPE1 and TYPE2 are
-     FUNCTION_TYPEs.  */
+     FUNCTION_TYPE or METHOD_TYPE.  */
   bool (*type_hash_eq) (const_tree, const_tree);
 
   /* Return TRUE if TYPE uses a hidden descriptor and fills in information
@@ -166,10 +166,6 @@ struct lang_hooks_for_types
   /* Returns -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute
      value otherwise.  */
   int (*type_dwarf_attribute) (const_tree, int);
-
-  /* Return TRUE iff unqualified CAND and BASE types are equivalent for
-     check_qualified_type purposes.  */
-  bool (*check_base_type) (const_tree, const_tree);
 };
 
 /* Language hooks related to decls and the symbol table.  */
diff --git a/gcc/tree.c b/gcc/tree.c
index 825376c..434aff1 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6497,6 +6497,21 @@ set_type_quals (tree type, int type_quals)
   TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
 }
 
+/* Returns true iff CAND and BASE have equivalent language-specific
+   qualifiers.  */
+
+bool
+check_lang_type (const_tree cand, const_tree base)
+{
+  if (lang_hooks.types.type_hash_eq == NULL)
+    return true;
+  /* type_hash_eq currently only applies to these types.  */
+  if (TREE_CODE (cand) != FUNCTION_TYPE
+      && TREE_CODE (cand) != METHOD_TYPE)
+    return true;
+  return lang_hooks.types.type_hash_eq (cand, base);
+}
+
 /* Returns true iff unqualified CAND and BASE are equivalent.  */
 
 bool
@@ -6507,7 +6522,6 @@ check_base_type (const_tree cand, const_tree base)
 	  && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base)
 	  /* Check alignment.  */
 	  && TYPE_ALIGN (cand) == TYPE_ALIGN (base)
-	  && lang_hooks.types.check_base_type (cand, base)
 	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
 				   TYPE_ATTRIBUTES (base)));
 }
@@ -6518,7 +6532,8 @@ bool
 check_qualified_type (const_tree cand, const_tree base, int type_quals)
 {
   return (TYPE_QUALS (cand) == type_quals
-	  && check_base_type (cand, base));
+	  && check_base_type (cand, base)
+	  && check_lang_type (cand, base));
 }
 
 /* Returns true iff CAND is equivalent to BASE with ALIGN.  */
@@ -6533,7 +6548,8 @@ check_aligned_type (const_tree cand, const_tree base, unsigned int align)
 	  /* Check alignment.  */
 	  && TYPE_ALIGN (cand) == align
 	  && attribute_list_equal (TYPE_ATTRIBUTES (cand),
-				   TYPE_ATTRIBUTES (base)));
+				   TYPE_ATTRIBUTES (base))
+	  && check_lang_type (cand, base));
 }
 
 /* This function checks to see if TYPE matches the size one of the built-in 
diff --git a/gcc/tree.h b/gcc/tree.h
index c494f23..fb4f033 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4210,6 +4210,11 @@ extern tree merge_dllimport_decl_attributes (tree, tree);
 /* Handle a "dllimport" or "dllexport" attribute.  */
 extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);
 
+/* Returns true iff CAND and BASE have equivalent language-specific
+   qualifiers.  */
+
+extern bool check_lang_type (const_tree cand, const_tree base);
+
 /* Returns true iff unqualified CAND and BASE are equivalent.  */
 
 extern bool check_base_type (const_tree cand, const_tree base);

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-11-01 18:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-24 14:29 [PATCH] Emit DWARF5 DW_AT_reference and DW_AT_rvalue_reference Jakub Jelinek
2016-10-24 18:34 ` Jason Merrill
2016-10-24 19:09   ` Jakub Jelinek
2016-10-31 13:56     ` Jason Merrill
2016-11-01 13:56       ` Jakub Jelinek
2016-11-01 18:05         ` Jason Merrill
2016-11-01 18:44           ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).