From: Matthias Kretz <m.kretz@gsi.de>
To: <gcc-patches@gcc.gnu.org>
Subject: [PATCH] c++: Output less irrelevant info for function template decl [PR100716]
Date: Tue, 25 May 2021 21:16:10 +0200 [thread overview]
Message-ID: <3000132.OxmWWEHjG1@excalibur> (raw)
[-- 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 }
+}
next reply other threads:[~2021-05-25 19:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-25 19:16 Matthias Kretz [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3000132.OxmWWEHjG1@excalibur \
--to=m.kretz@gsi.de \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).