Update the message for template-template param keyword for C++17
authorErich Keane <erich.keane@intel.com>
Mon, 27 Sep 2021 20:16:03 +0000 (13:16 -0700)
committerErich Keane <erich.keane@intel.com>
Tue, 28 Sep 2021 13:02:29 +0000 (06:02 -0700)
C++17 permits using 'typename' or 'class' for a template template
parameter, but the error message in the parser only refers to 'class'.
This patch, in C++17 or newer modes, adds "or 'template'" to the
diagnostic.

clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseTemplate.cpp
clang/test/Parser/cxx-template-decl.cpp
clang/test/Parser/cxx2a-concept-declaration.cpp

index 834f29f..fb84496 100644 (file)
@@ -742,8 +742,9 @@ def err_unknown_template_name : Error<
   "unknown template name %0">;
 def err_expected_comma_greater : Error<
   "expected ',' or '>' in template-parameter-list">;
-def err_class_on_template_template_param : Error<
-  "template template parameter requires 'class' after the parameter list">;
+def err_class_on_template_template_param
+    : Error<"template template parameter requires 'class'%select{| or "
+            "'typename'}0 after the parameter list">;
 def ext_template_template_param_typename : ExtWarn<
   "template template parameter using 'typename' is a C++17 extension">,
   InGroup<CXX17>;
index 0fbde73..45af61a 100644 (file)
@@ -906,10 +906,13 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
     } else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,
                             tok::greatergreater, tok::ellipsis)) {
       Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
-        << (Replace ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
-                    : FixItHint::CreateInsertion(Tok.getLocation(), "class "));
+          << getLangOpts().CPlusPlus17
+          << (Replace
+                  ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
+                  : FixItHint::CreateInsertion(Tok.getLocation(), "class "));
     } else
-      Diag(Tok.getLocation(), diag::err_class_on_template_template_param);
+      Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
+          << getLangOpts().CPlusPlus17;
 
     if (Replace)
       ConsumeToken();
index 7455b1d..26f6ce2 100644 (file)
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
-// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++1z %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp14 %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cpp17 -std=gnu++1z %s
 
 
 
@@ -19,11 +19,14 @@ template <int +> struct x1; // expected-error {{expected ',' or '>' in template-
 template <int +, T> struct x2; // expected-error {{expected ',' or '>' in template-parameter-list}} \
                                 expected-error {{expected unqualified-id}}
 template<template<int+>> struct x3; // expected-error {{expected ',' or '>' in template-parameter-list}} \
-                                         expected-error {{template template parameter requires 'class' after the parameter list}}
+                                         cpp14-error {{template template parameter requires 'class' after the parameter list}} \
+                                         cpp17-error {{template template parameter requires 'class' or 'typename' after the parameter list}}
 template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \
 // expected-error{{extraneous}}
-template <template <typename> > struct Err2;       // expected-error {{template template parameter requires 'class' after the parameter list}}
-template <template <typename> Foo> struct Err3;    // expected-error {{template template parameter requires 'class' after the parameter list}}
+template <template <typename> > struct Err2;       // cpp14-error {{template template parameter requires 'class' after the parameter list}}
+// cpp17-error@-1{{template template parameter requires 'class' or 'typename' after the parameter list}}
+template <template <typename> Foo> struct Err3;    // cpp14-error {{template template parameter requires 'class' after the parameter list}}
+// cpp17-error@-1{{template template parameter requires 'class' or 'typename' after the parameter list}}
 
 template <template <typename> typename Foo> struct Cxx1z;
 #if __cplusplus <= 201402L
index a7c69c2..25c4412 100644 (file)
@@ -11,7 +11,7 @@ template<concept T> concept D1 = true;
 
 template<template<typename> concept T> concept D2 = true;
 // expected-error@-1{{expected identifier}}
-// expected-error@-2{{template template parameter requires 'class' after the parameter list}}
+// expected-error@-2{{template template parameter requires 'class' or 'typename' after the parameter list}}
 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
 struct S1 {