public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: Output less irrelevant info for function template decl [PR100716]
@ 2021-05-25 19:16 Matthias Kretz
  2021-05-26 21:29 ` Matthias Kretz
  0 siblings, 1 reply; 5+ messages in thread
From: Matthias Kretz @ 2021-05-25 19:16 UTC (permalink / raw)
  To: gcc-patches

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


From: Matthias Kretz <kretz@kde.org>

Ensure dump_template_decl for function templates never prints template 
parameters after the function name (it did with -fno-pretty-templates) and 
skip output of irrelevant & confusing "[with T = T]" in dump_substitution.

gcc/cp/ChangeLog:

	PR c++/100716
	* error.c (dump_template_bindings): Include code to print
	"[with" and ']', conditional on whether anything is printed at
	all. This is tied to whether a semicolon is needed to separate
	multiple template parameters. If the template argument repeats
	the template parameter (T = T), then skip the parameter.
	(dump_substitution): Moved code to print "[with" and ']' to
	dump_template_bindings.
	(dump_function_decl): Partial revert of PR50828, which masked
	TFF_TEMPLATE_NAME for all of dump_function_decl. Now
	TFF_TEMPLATE_NAME is masked for the scope of the function and
	only carries through to dump_function_name.
	(dump_function_name): Avoid calling dump_template_parms if
	TFF_TEMPLATE_NAME is set.

gcc/testsuite/ChangeLog:

	PR c++/100716
	* g++.dg/diagnostic/pr100716.C: New test.
	* g++.dg/diagnostic/pr100716-1.C: Same test with
	-fno-pretty-templates.
---
 gcc/cp/error.c                               | 59 +++++++++++++++-----
 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C | 54 ++++++++++++++++++
 gcc/testsuite/g++.dg/diagnostic/pr100716.C   | 54 ++++++++++++++++++
 3 files changed, 152 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716.C


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 std::experimental::simd              https://github.com/VcDevel/std-simd
──────────────────────────────────────────────────────────────────────────

[-- Attachment #2: 0001-c-Output-less-irrelevant-info-for-function-template-.patch --]
[-- Type: text/x-patch, Size: 8135 bytes --]

diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 010fbce41a7..bc0b68f07e0 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -381,7 +381,32 @@ static void
 dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
                         vec<tree, va_gc> *typenames)
 {
-  bool need_semicolon = false;
+  struct prepost_semicolon
+  {
+    cxx_pretty_printer *pp;
+    bool need_semicolon = false;
+
+    void operator()()
+    {
+      if (need_semicolon)
+	pp_separate_with_semicolon (pp);
+      else
+	{
+	  pp_cxx_whitespace (pp);
+	  pp_cxx_left_bracket (pp);
+	  pp->translate_string ("with");
+	  pp_cxx_whitespace (pp);
+	  need_semicolon = true;
+	}
+    }
+
+    ~prepost_semicolon()
+    {
+      if (need_semicolon)
+	pp_cxx_right_bracket (pp);
+    }
+  } semicolon_or_introducer = {pp};
+
   int i;
   tree t;
 
@@ -405,10 +430,19 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 	  if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
 	    arg = TREE_VEC_ELT (lvl_args, arg_idx);
 
-	  if (need_semicolon)
-	    pp_separate_with_semicolon (pp);
-	  dump_template_parameter (pp, TREE_VEC_ELT (p, i),
-                                   TFF_PLAIN_IDENTIFIER);
+	  tree parm_i = TREE_VEC_ELT (p, i);
+	  /* Skip this parameter if it just noise such as "T = T".  */
+	  if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM
+		&& TREE_CODE (parm_i) == TREE_LIST
+		&& TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL
+		&& TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i)))
+		     == TEMPLATE_TYPE_PARM
+		&& DECL_NAME (TREE_VALUE (parm_i))
+		     == DECL_NAME (TREE_CHAIN (arg)))
+	    continue;
+
+	  semicolon_or_introducer();
+	  dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER);
 	  pp_cxx_whitespace (pp);
 	  pp_equal (pp);
 	  pp_cxx_whitespace (pp);
@@ -424,7 +458,6 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 	    pp_string (pp, M_("<missing>"));
 
 	  ++arg_idx;
-	  need_semicolon = true;
 	}
 
       parms = TREE_CHAIN (parms);
@@ -446,8 +479,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 
   FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
     {
-      if (need_semicolon)
-	pp_separate_with_semicolon (pp);
+      semicolon_or_introducer();
       dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
       pp_cxx_whitespace (pp);
       pp_equal (pp);
@@ -1652,12 +1684,7 @@ dump_substitution (cxx_pretty_printer *pp,
       && !(flags & TFF_NO_TEMPLATE_BINDINGS))
     {
       vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
-      pp_cxx_whitespace (pp);
-      pp_cxx_left_bracket (pp);
-      pp->translate_string ("with");
-      pp_cxx_whitespace (pp);
       dump_template_bindings (pp, template_parms, template_args, typenames);
-      pp_cxx_right_bracket (pp);
     }
 }
 
@@ -1698,7 +1725,8 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   bool constexpr_p;
   tree ret = NULL_TREE;
 
-  flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
+  int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME;
+  flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME;
   if (TREE_CODE (t) == TEMPLATE_DECL)
     t = DECL_TEMPLATE_RESULT (t);
 
@@ -1782,7 +1810,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   else
     dump_scope (pp, CP_DECL_CONTEXT (t), flags);
 
-  dump_function_name (pp, t, flags);
+  dump_function_name (pp, t, dump_function_name_flags);
 
   if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
     {
@@ -2006,6 +2034,7 @@ dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
   dump_module_suffix (pp, t);
 
   if (DECL_TEMPLATE_INFO (t)
+      && !(flags & TFF_TEMPLATE_NAME)
       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
       && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
 	  || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
new file mode 100644
index 00000000000..93490da6a83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
@@ -0,0 +1,54 @@
+// { dg-options "-fno-pretty-templates" }
+
+template<typename T>
+  struct A
+  {
+    template<typename U>
+      void f() {} // { dg-line Af }
+
+    template<typename U>
+      void g(U) {} // { dg-line Ag }
+  };
+
+template<typename T>
+  struct B
+  {
+    template<typename U>
+      void f(U) {} // { dg-line Bf }
+
+    template<typename U>
+      void g(U, T) {} // { dg-line Bg }
+  };
+
+struct C
+{
+  template<typename U>
+    void f(U) {} // { dg-line Cf }
+
+  template<typename U>
+    void g() {} // { dg-line Cg }
+};
+
+int main()
+{
+  A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<int>::f\\(\\)'" "" { target *-*-* } Af }
+
+  A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<int>::g\\(U\\)'" "" { target *-*-* } Ag }
+
+  B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<int>::f\\(U\\)'" "" { target *-*-* } Bf }
+
+  B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<int>::g\\(U, int\\)'" "" { target *-*-* } Bg }
+
+  B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<float>::g\\(U, float\\)'" "" { target *-*-* } Bg }
+
+  C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf }
+
+  C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg }
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716.C b/gcc/testsuite/g++.dg/diagnostic/pr100716.C
new file mode 100644
index 00000000000..4a1f0a4e10a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr100716.C
@@ -0,0 +1,54 @@
+// { dg-options "-fpretty-templates" }
+
+template<typename T>
+  struct A
+  {
+    template<typename U>
+      void f() {} // { dg-line Af }
+
+    template<typename U>
+      void g(U) {} // { dg-line Ag }
+  };
+
+template<typename T>
+  struct B
+  {
+    template<typename U>
+      void f(U) {} // { dg-line Bf }
+
+    template<typename U>
+      void g(U, T) {} // { dg-line Bg }
+  };
+
+struct C
+{
+  template<typename U>
+    void f(U) {} // { dg-line Cf }
+
+  template<typename U>
+    void g() {} // { dg-line Cg }
+};
+
+int main()
+{
+  A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<T>::f\\(\\) \\\[with T = int\\\]'" "" { target *-*-* } Af }
+
+  A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<T>::g\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Ag }
+
+  B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::f\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Bf }
+
+  B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = int\\\]'" "" { target *-*-* } Bg }
+
+  B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = float\\\]'" "" { target *-*-* } Bg }
+
+  C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf }
+
+  C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg }
+}

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

* Re: [PATCH] c++: Output less irrelevant info for function template decl [PR100716]
  2021-05-25 19:16 [PATCH] c++: Output less irrelevant info for function template decl [PR100716] Matthias Kretz
@ 2021-05-26 21:29 ` Matthias Kretz
  2021-05-27 15:07   ` Jason Merrill
  0 siblings, 1 reply; 5+ messages in thread
From: Matthias Kretz @ 2021-05-26 21:29 UTC (permalink / raw)
  To: gcc-patches

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

New revision which can also be compiled with GCC 4.8.

From: Matthias Kretz <kretz@kde.org>

Ensure dump_template_decl for function templates never prints template
parameters after the function name (it did with -fno-pretty-templates)
and skip output of irrelevant & confusing "[with T = T]" in
dump_substitution.

gcc/cp/ChangeLog:

	PR c++/100716
	* error.c (dump_template_bindings): Include code to print
	"[with" and ']', conditional on whether anything is printed at
	all. This is tied to whether a semicolon is needed to separate
	multiple template parameters. If the template argument repeats
	the template parameter (T = T), then skip the parameter.
	(dump_substitution): Moved code to print "[with" and ']' to
	dump_template_bindings.
	(dump_function_decl): Partial revert of PR50828, which masked
	TFF_TEMPLATE_NAME for all of dump_function_decl. Now
	TFF_TEMPLATE_NAME is masked for the scope of the function and
	only carries through to dump_function_name.
	(dump_function_name): Avoid calling dump_template_parms if
	TFF_TEMPLATE_NAME is set.

gcc/testsuite/ChangeLog:

	PR c++/100716
	* g++.dg/diagnostic/pr100716.C: New test.
	* g++.dg/diagnostic/pr100716-1.C: Same test with
	-fno-pretty-templates.
---
 gcc/cp/error.c                               | 59 +++++++++++++++-----
 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C | 54 ++++++++++++++++++
 gcc/testsuite/g++.dg/diagnostic/pr100716.C   | 54 ++++++++++++++++++
 3 files changed, 152 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716.C


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 std::experimental::simd              https://github.com/VcDevel/std-simd
──────────────────────────────────────────────────────────────────────────

[-- Attachment #2: 0003-c-Output-less-irrelevant-info-for-function-template-.patch --]
[-- Type: text/x-patch, Size: 8134 bytes --]

diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index ad69df6ef7f..b0836d83888 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -371,7 +371,32 @@ static void
 dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
                         vec<tree, va_gc> *typenames)
 {
-  bool need_semicolon = false;
+  struct prepost_semicolon
+  {
+    cxx_pretty_printer *pp;
+    bool need_semicolon;
+
+    void operator()()
+    {
+      if (need_semicolon)
+	pp_separate_with_semicolon (pp);
+      else
+	{
+	  pp_cxx_whitespace (pp);
+	  pp_cxx_left_bracket (pp);
+	  pp->translate_string ("with");
+	  pp_cxx_whitespace (pp);
+	  need_semicolon = true;
+	}
+    }
+
+    ~prepost_semicolon()
+    {
+      if (need_semicolon)
+	pp_cxx_right_bracket (pp);
+    }
+  } semicolon_or_introducer = {pp, false};
+
   int i;
   tree t;
 
@@ -395,10 +420,19 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 	  if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
 	    arg = TREE_VEC_ELT (lvl_args, arg_idx);
 
-	  if (need_semicolon)
-	    pp_separate_with_semicolon (pp);
-	  dump_template_parameter (pp, TREE_VEC_ELT (p, i),
-                                   TFF_PLAIN_IDENTIFIER);
+	  tree parm_i = TREE_VEC_ELT (p, i);
+	  /* Skip this parameter if it just noise such as "T = T".  */
+	  if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM
+		&& TREE_CODE (parm_i) == TREE_LIST
+		&& TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL
+		&& TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i)))
+		     == TEMPLATE_TYPE_PARM
+		&& DECL_NAME (TREE_VALUE (parm_i))
+		     == DECL_NAME (TREE_CHAIN (arg)))
+	    continue;
+
+	  semicolon_or_introducer();
+	  dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER);
 	  pp_cxx_whitespace (pp);
 	  pp_equal (pp);
 	  pp_cxx_whitespace (pp);
@@ -414,7 +448,6 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 	    pp_string (pp, M_("<missing>"));
 
 	  ++arg_idx;
-	  need_semicolon = true;
 	}
 
       parms = TREE_CHAIN (parms);
@@ -436,8 +469,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 
   FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
     {
-      if (need_semicolon)
-	pp_separate_with_semicolon (pp);
+      semicolon_or_introducer();
       dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
       pp_cxx_whitespace (pp);
       pp_equal (pp);
@@ -1599,12 +1631,7 @@ dump_substitution (cxx_pretty_printer *pp,
       && !(flags & TFF_NO_TEMPLATE_BINDINGS))
     {
       vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
-      pp_cxx_whitespace (pp);
-      pp_cxx_left_bracket (pp);
-      pp->translate_string ("with");
-      pp_cxx_whitespace (pp);
       dump_template_bindings (pp, template_parms, template_args, typenames);
-      pp_cxx_right_bracket (pp);
     }
 }
 
@@ -1645,7 +1672,8 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   bool constexpr_p;
   tree ret = NULL_TREE;
 
-  flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
+  int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME;
+  flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME;
   if (TREE_CODE (t) == TEMPLATE_DECL)
     t = DECL_TEMPLATE_RESULT (t);
 
@@ -1723,7 +1751,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   else
     dump_scope (pp, CP_DECL_CONTEXT (t), flags);
 
-  dump_function_name (pp, t, flags);
+  dump_function_name (pp, t, dump_function_name_flags);
 
   if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
     {
@@ -1937,6 +1965,7 @@ dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
   dump_module_suffix (pp, t);
 
   if (DECL_TEMPLATE_INFO (t)
+      && !(flags & TFF_TEMPLATE_NAME)
       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
       && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
 	  || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
new file mode 100644
index 00000000000..93490da6a83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
@@ -0,0 +1,54 @@
+// { dg-options "-fno-pretty-templates" }
+
+template<typename T>
+  struct A
+  {
+    template<typename U>
+      void f() {} // { dg-line Af }
+
+    template<typename U>
+      void g(U) {} // { dg-line Ag }
+  };
+
+template<typename T>
+  struct B
+  {
+    template<typename U>
+      void f(U) {} // { dg-line Bf }
+
+    template<typename U>
+      void g(U, T) {} // { dg-line Bg }
+  };
+
+struct C
+{
+  template<typename U>
+    void f(U) {} // { dg-line Cf }
+
+  template<typename U>
+    void g() {} // { dg-line Cg }
+};
+
+int main()
+{
+  A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<int>::f\\(\\)'" "" { target *-*-* } Af }
+
+  A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<int>::g\\(U\\)'" "" { target *-*-* } Ag }
+
+  B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<int>::f\\(U\\)'" "" { target *-*-* } Bf }
+
+  B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<int>::g\\(U, int\\)'" "" { target *-*-* } Bg }
+
+  B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<float>::g\\(U, float\\)'" "" { target *-*-* } Bg }
+
+  C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf }
+
+  C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg }
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716.C b/gcc/testsuite/g++.dg/diagnostic/pr100716.C
new file mode 100644
index 00000000000..4a1f0a4e10a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr100716.C
@@ -0,0 +1,54 @@
+// { dg-options "-fpretty-templates" }
+
+template<typename T>
+  struct A
+  {
+    template<typename U>
+      void f() {} // { dg-line Af }
+
+    template<typename U>
+      void g(U) {} // { dg-line Ag }
+  };
+
+template<typename T>
+  struct B
+  {
+    template<typename U>
+      void f(U) {} // { dg-line Bf }
+
+    template<typename U>
+      void g(U, T) {} // { dg-line Bg }
+  };
+
+struct C
+{
+  template<typename U>
+    void f(U) {} // { dg-line Cf }
+
+  template<typename U>
+    void g() {} // { dg-line Cg }
+};
+
+int main()
+{
+  A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<T>::f\\(\\) \\\[with T = int\\\]'" "" { target *-*-* } Af }
+
+  A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<T>::g\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Ag }
+
+  B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::f\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Bf }
+
+  B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = int\\\]'" "" { target *-*-* } Bg }
+
+  B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = float\\\]'" "" { target *-*-* } Bg }
+
+  C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf }
+
+  C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg }
+}

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

* Re: [PATCH] c++: Output less irrelevant info for function template decl [PR100716]
  2021-05-26 21:29 ` Matthias Kretz
@ 2021-05-27 15:07   ` Jason Merrill
  2021-05-27 15:25     ` Matthias Kretz
  0 siblings, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2021-05-27 15:07 UTC (permalink / raw)
  To: Matthias Kretz, gcc-patches

On 5/26/21 5:29 PM, Matthias Kretz wrote:
> New revision which can also be compiled with GCC 4.8.
> 
> From: Matthias Kretz <kretz@kde.org>
> 
> Ensure dump_template_decl for function templates never prints template
> parameters after the function name (it did with -fno-pretty-templates)
> and skip output of irrelevant & confusing "[with T = T]" in
> dump_substitution.
> 
> gcc/cp/ChangeLog:
> 
> 	PR c++/100716
> 	* error.c (dump_template_bindings): Include code to print
> 	"[with" and ']', conditional on whether anything is printed at
> 	all. This is tied to whether a semicolon is needed to separate
> 	multiple template parameters. If the template argument repeats
> 	the template parameter (T = T), then skip the parameter.

This description should really be in a comment in the code, rather than 
the ChangeLog.  OK either way.

> 	(dump_substitution): Moved code to print "[with" and ']' to
> 	dump_template_bindings.
> 	(dump_function_decl): Partial revert of PR50828, which masked
> 	TFF_TEMPLATE_NAME for all of dump_function_decl. Now
> 	TFF_TEMPLATE_NAME is masked for the scope of the function and
> 	only carries through to dump_function_name.
> 	(dump_function_name): Avoid calling dump_template_parms if
> 	TFF_TEMPLATE_NAME is set.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/100716
> 	* g++.dg/diagnostic/pr100716.C: New test.
> 	* g++.dg/diagnostic/pr100716-1.C: Same test with
> 	-fno-pretty-templates.
> ---
>   gcc/cp/error.c                               | 59 +++++++++++++++-----
>   gcc/testsuite/g++.dg/diagnostic/pr100716-1.C | 54 ++++++++++++++++++
>   gcc/testsuite/g++.dg/diagnostic/pr100716.C   | 54 ++++++++++++++++++
>   3 files changed, 152 insertions(+), 15 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716.C
> 
> 
> --
> ──────────────────────────────────────────────────────────────────────────
>   Dr. Matthias Kretz                           https://mattkretz.github.io
>   GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
>   std::experimental::simd              https://github.com/VcDevel/std-simd
> ──────────────────────────────────────────────────────────────────────────
> 


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

* Re: [PATCH] c++: Output less irrelevant info for function template decl [PR100716]
  2021-05-27 15:07   ` Jason Merrill
@ 2021-05-27 15:25     ` Matthias Kretz
  2021-05-27 21:17       ` Jason Merrill
  0 siblings, 1 reply; 5+ messages in thread
From: Matthias Kretz @ 2021-05-27 15:25 UTC (permalink / raw)
  To: gcc-patches, Jason Merrill

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

On Thursday, 27 May 2021 17:07:40 CEST Jason Merrill wrote:
> On 5/26/21 5:29 PM, Matthias Kretz wrote:
> > New revision which can also be compiled with GCC 4.8.
> > 
> > From: Matthias Kretz <kretz@kde.org>
> > 
> > Ensure dump_template_decl for function templates never prints template
> > parameters after the function name (it did with -fno-pretty-templates)
> > and skip output of irrelevant & confusing "[with T = T]" in
> > dump_substitution.
> > 
> > gcc/cp/ChangeLog:
> > 	PR c++/100716
> > 	* error.c (dump_template_bindings): Include code to print
> > 	"[with" and ']', conditional on whether anything is printed at
> > 	all. This is tied to whether a semicolon is needed to separate
> > 	multiple template parameters. If the template argument repeats
> > 	the template parameter (T = T), then skip the parameter.
> 
> This description should really be in a comment in the code, rather than
> the ChangeLog.  OK either way.

Added comments in the code. New patch below.


From: Matthias Kretz <kretz@kde.org>

Ensure dump_template_decl for function templates never prints template
parameters after the function name (it did with -fno-pretty-templates)
and skip output of irrelevant & confusing "[with T = T]" in
dump_substitution.

gcc/cp/ChangeLog:

	PR c++/100716
	* error.c (dump_template_bindings): Include code to print
	"[with" and ']', conditional on whether anything is printed at
	all. This is tied to whether a semicolon is needed to separate
	multiple template parameters. If the template argument repeats
	the template parameter (T = T), then skip the parameter.
	(dump_substitution): Moved code to print "[with" and ']' to
	dump_template_bindings.
	(dump_function_decl): Partial revert of PR50828, which masked
	TFF_TEMPLATE_NAME for all of dump_function_decl. Now
	TFF_TEMPLATE_NAME is masked for the scope of the function and
	only carries through to dump_function_name.
	(dump_function_name): Avoid calling dump_template_parms if
	TFF_TEMPLATE_NAME is set.

gcc/testsuite/ChangeLog:

	PR c++/100716
	* g++.dg/diagnostic/pr100716.C: New test.
	* g++.dg/diagnostic/pr100716-1.C: Same test with
	-fno-pretty-templates.
---
 gcc/cp/error.c                               | 63 +++++++++++++++-----
 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C | 54 +++++++++++++++++
 gcc/testsuite/g++.dg/diagnostic/pr100716.C   | 54 +++++++++++++++++
 3 files changed, 156 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716.C


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
 std::experimental::simd              https://github.com/VcDevel/std-simd
──────────────────────────────────────────────────────────────────────────

[-- Attachment #2: 0001-c-Output-less-irrelevant-info-for-function-template-.patch --]
[-- Type: text/x-patch, Size: 8354 bytes --]

diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index a2f19d1a5c1..ade9b17e663 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -371,7 +371,35 @@ static void
 dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
                         vec<tree, va_gc> *typenames)
 {
-  bool need_semicolon = false;
+  /* Print "[with" and ']', conditional on whether anything is printed at all.
+     This is tied to whether a semicolon is needed to separate multiple template
+     parameters.  */
+  struct prepost_semicolon
+  {
+    cxx_pretty_printer *pp;
+    bool need_semicolon;
+
+    void operator()()
+    {
+      if (need_semicolon)
+	pp_separate_with_semicolon (pp);
+      else
+	{
+	  pp_cxx_whitespace (pp);
+	  pp_cxx_left_bracket (pp);
+	  pp->translate_string ("with");
+	  pp_cxx_whitespace (pp);
+	  need_semicolon = true;
+	}
+    }
+
+    ~prepost_semicolon()
+    {
+      if (need_semicolon)
+	pp_cxx_right_bracket (pp);
+    }
+  } semicolon_or_introducer = {pp, false};
+
   int i;
   tree t;
 
@@ -395,10 +423,20 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 	  if (lvl_args && NUM_TMPL_ARGS (lvl_args) > arg_idx)
 	    arg = TREE_VEC_ELT (lvl_args, arg_idx);
 
-	  if (need_semicolon)
-	    pp_separate_with_semicolon (pp);
-	  dump_template_parameter (pp, TREE_VEC_ELT (p, i),
-                                   TFF_PLAIN_IDENTIFIER);
+	  tree parm_i = TREE_VEC_ELT (p, i);
+	  /* If the template argument repeats the template parameter (T = T),
+	     skip the parameter.*/
+	  if (arg && TREE_CODE (arg) == TEMPLATE_TYPE_PARM
+		&& TREE_CODE (parm_i) == TREE_LIST
+		&& TREE_CODE (TREE_VALUE (parm_i)) == TYPE_DECL
+		&& TREE_CODE (TREE_TYPE (TREE_VALUE (parm_i)))
+		     == TEMPLATE_TYPE_PARM
+		&& DECL_NAME (TREE_VALUE (parm_i))
+		     == DECL_NAME (TREE_CHAIN (arg)))
+	    continue;
+
+	  semicolon_or_introducer();
+	  dump_template_parameter (pp, parm_i, TFF_PLAIN_IDENTIFIER);
 	  pp_cxx_whitespace (pp);
 	  pp_equal (pp);
 	  pp_cxx_whitespace (pp);
@@ -414,7 +452,6 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 	    pp_string (pp, M_("<missing>"));
 
 	  ++arg_idx;
-	  need_semicolon = true;
 	}
 
       parms = TREE_CHAIN (parms);
@@ -436,8 +473,7 @@ dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
 
   FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
     {
-      if (need_semicolon)
-	pp_separate_with_semicolon (pp);
+      semicolon_or_introducer();
       dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
       pp_cxx_whitespace (pp);
       pp_equal (pp);
@@ -1599,12 +1635,7 @@ dump_substitution (cxx_pretty_printer *pp,
       && !(flags & TFF_NO_TEMPLATE_BINDINGS))
     {
       vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
-      pp_cxx_whitespace (pp);
-      pp_cxx_left_bracket (pp);
-      pp->translate_string ("with");
-      pp_cxx_whitespace (pp);
       dump_template_bindings (pp, template_parms, template_args, typenames);
-      pp_cxx_right_bracket (pp);
     }
 }
 
@@ -1645,7 +1676,8 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   bool constexpr_p;
   tree ret = NULL_TREE;
 
-  flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
+  int dump_function_name_flags = flags & ~TFF_UNQUALIFIED_NAME;
+  flags = dump_function_name_flags & ~TFF_TEMPLATE_NAME;
   if (TREE_CODE (t) == TEMPLATE_DECL)
     t = DECL_TEMPLATE_RESULT (t);
 
@@ -1723,7 +1755,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
   else
     dump_scope (pp, CP_DECL_CONTEXT (t), flags);
 
-  dump_function_name (pp, t, flags);
+  dump_function_name (pp, t, dump_function_name_flags);
 
   if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
     {
@@ -1937,6 +1969,7 @@ dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
   dump_module_suffix (pp, t);
 
   if (DECL_TEMPLATE_INFO (t)
+      && !(flags & TFF_TEMPLATE_NAME)
       && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
       && (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
 	  || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
new file mode 100644
index 00000000000..93490da6a83
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
@@ -0,0 +1,54 @@
+// { dg-options "-fno-pretty-templates" }
+
+template<typename T>
+  struct A
+  {
+    template<typename U>
+      void f() {} // { dg-line Af }
+
+    template<typename U>
+      void g(U) {} // { dg-line Ag }
+  };
+
+template<typename T>
+  struct B
+  {
+    template<typename U>
+      void f(U) {} // { dg-line Bf }
+
+    template<typename U>
+      void g(U, T) {} // { dg-line Bg }
+  };
+
+struct C
+{
+  template<typename U>
+    void f(U) {} // { dg-line Cf }
+
+  template<typename U>
+    void g() {} // { dg-line Cg }
+};
+
+int main()
+{
+  A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<int>::f\\(\\)'" "" { target *-*-* } Af }
+
+  A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<int>::g\\(U\\)'" "" { target *-*-* } Ag }
+
+  B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<int>::f\\(U\\)'" "" { target *-*-* } Bf }
+
+  B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<int>::g\\(U, int\\)'" "" { target *-*-* } Bg }
+
+  B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<float>::g\\(U, float\\)'" "" { target *-*-* } Bg }
+
+  C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf }
+
+  C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg }
+}
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr100716.C b/gcc/testsuite/g++.dg/diagnostic/pr100716.C
new file mode 100644
index 00000000000..4a1f0a4e10a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr100716.C
@@ -0,0 +1,54 @@
+// { dg-options "-fpretty-templates" }
+
+template<typename T>
+  struct A
+  {
+    template<typename U>
+      void f() {} // { dg-line Af }
+
+    template<typename U>
+      void g(U) {} // { dg-line Ag }
+  };
+
+template<typename T>
+  struct B
+  {
+    template<typename U>
+      void f(U) {} // { dg-line Bf }
+
+    template<typename U>
+      void g(U, T) {} // { dg-line Bg }
+  };
+
+struct C
+{
+  template<typename U>
+    void f(U) {} // { dg-line Cf }
+
+  template<typename U>
+    void g() {} // { dg-line Cg }
+};
+
+int main()
+{
+  A<int>().f(0); // { dg-error "no matching function for call to 'A<int>::f\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<T>::f\\(\\) \\\[with T = int\\\]'" "" { target *-*-* } Af }
+
+  A<int>().g(); // { dg-error "no matching function for call to 'A<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void A<T>::g\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Ag }
+
+  B<int>().f(); // { dg-error "no matching function for call to 'B<int>::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::f\\(U\\) \\\[with T = int\\\]'" "" { target *-*-* } Bf }
+
+  B<int>().g(); // { dg-error "no matching function for call to 'B<int>::g\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = int\\\]'" "" { target *-*-* } Bg }
+
+  B<float>().g(0); // { dg-error "no matching function for call to 'B<float>::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void B<T>::g\\(U, T\\) \\\[with T = float\\\]'" "" { target *-*-* } Bg }
+
+  C().f(); // { dg-error "no matching function for call to 'C::f\\(\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::f\\(U\\)'" "" { target *-*-* } Cf }
+
+  C().g(0); // { dg-error "no matching function for call to 'C::g\\(int\\)'" }
+  // { dg-message "candidate: 'template<class U> void C::g\\(\\)'" "" { target *-*-* } Cg }
+}

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

* Re: [PATCH] c++: Output less irrelevant info for function template decl [PR100716]
  2021-05-27 15:25     ` Matthias Kretz
@ 2021-05-27 21:17       ` Jason Merrill
  0 siblings, 0 replies; 5+ messages in thread
From: Jason Merrill @ 2021-05-27 21:17 UTC (permalink / raw)
  To: Matthias Kretz, gcc-patches

On 5/27/21 11:25 AM, Matthias Kretz wrote:
> On Thursday, 27 May 2021 17:07:40 CEST Jason Merrill wrote:
>> On 5/26/21 5:29 PM, Matthias Kretz wrote:
>>> New revision which can also be compiled with GCC 4.8.
>>>
>>> From: Matthias Kretz <kretz@kde.org>
>>>
>>> Ensure dump_template_decl for function templates never prints template
>>> parameters after the function name (it did with -fno-pretty-templates)
>>> and skip output of irrelevant & confusing "[with T = T]" in
>>> dump_substitution.
>>>
>>> gcc/cp/ChangeLog:
>>> 	PR c++/100716
>>> 	* error.c (dump_template_bindings): Include code to print
>>> 	"[with" and ']', conditional on whether anything is printed at
>>> 	all. This is tied to whether a semicolon is needed to separate
>>> 	multiple template parameters. If the template argument repeats
>>> 	the template parameter (T = T), then skip the parameter.
>>
>> This description should really be in a comment in the code, rather than
>> the ChangeLog.  OK either way.
> 
> Added comments in the code. New patch below.

Applied with missing spaces before () added.

> From: Matthias Kretz <kretz@kde.org>
> 
> Ensure dump_template_decl for function templates never prints template
> parameters after the function name (it did with -fno-pretty-templates)
> and skip output of irrelevant & confusing "[with T = T]" in
> dump_substitution.
> 
> gcc/cp/ChangeLog:
> 
> 	PR c++/100716
> 	* error.c (dump_template_bindings): Include code to print
> 	"[with" and ']', conditional on whether anything is printed at
> 	all. This is tied to whether a semicolon is needed to separate
> 	multiple template parameters. If the template argument repeats
> 	the template parameter (T = T), then skip the parameter.
> 	(dump_substitution): Moved code to print "[with" and ']' to
> 	dump_template_bindings.
> 	(dump_function_decl): Partial revert of PR50828, which masked
> 	TFF_TEMPLATE_NAME for all of dump_function_decl. Now
> 	TFF_TEMPLATE_NAME is masked for the scope of the function and
> 	only carries through to dump_function_name.
> 	(dump_function_name): Avoid calling dump_template_parms if
> 	TFF_TEMPLATE_NAME is set.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/100716
> 	* g++.dg/diagnostic/pr100716.C: New test.
> 	* g++.dg/diagnostic/pr100716-1.C: Same test with
> 	-fno-pretty-templates.
> ---
>   gcc/cp/error.c                               | 63 +++++++++++++++-----
>   gcc/testsuite/g++.dg/diagnostic/pr100716-1.C | 54 +++++++++++++++++
>   gcc/testsuite/g++.dg/diagnostic/pr100716.C   | 54 +++++++++++++++++
>   3 files changed, 156 insertions(+), 15 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
>   create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716.C
> 
> 
> --
> ──────────────────────────────────────────────────────────────────────────
>   Dr. Matthias Kretz                           https://mattkretz.github.io
>   GSI Helmholtz Centre for Heavy Ion Research               https://gsi.de
>   std::experimental::simd              https://github.com/VcDevel/std-simd
> ──────────────────────────────────────────────────────────────────────────
> 


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

end of thread, other threads:[~2021-05-27 21:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-25 19:16 [PATCH] c++: Output less irrelevant info for function template decl [PR100716] Matthias Kretz
2021-05-26 21:29 ` Matthias Kretz
2021-05-27 15:07   ` Jason Merrill
2021-05-27 15:25     ` Matthias Kretz
2021-05-27 21:17       ` 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).