On Mon, Jun 16, 2014 at 8:51 AM, Richard Smith <[email protected]> wrote: > Author: rsmith > Date: Mon Jun 16 10:51:22 2014 > New Revision: 211031 > > URL: http://llvm.org/viewvc/llvm-project?rev=211031&view=rev > Log: > [C++1z] Implement N4051: 'typename' is permitted instead of 'class' when > declaring a template template parameter.
Hooray! \o/ > > Modified: > cfe/trunk/include/clang/Basic/DiagnosticGroups.td > cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td > cfe/trunk/lib/Parse/ParseTemplate.cpp > cfe/trunk/test/FixIt/fixit.cpp > cfe/trunk/test/Parser/cxx-template-decl.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=211031&r1=211030&r2=211031&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Jun 16 10:51:22 2014 > @@ -121,6 +121,9 @@ def FormatZeroLength : DiagGroup<"format > def CXXPre1yCompat : DiagGroup<"c++98-c++11-compat">; > def CXXPre1yCompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic", > [CXXPre1yCompat]>; > +def CXXPre1zCompat : DiagGroup<"c++98-c++11-c++14-compat">; > +def CXXPre1zCompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic", > + [CXXPre1zCompat]>; > > def CXX98CompatBindToTemporaryCopy : > DiagGroup<"c++98-compat-bind-to-temporary-copy">; > @@ -133,11 +136,13 @@ def CXX98Compat : DiagGroup<"c++98-compa > [CXX98CompatBindToTemporaryCopy, > CXX98CompatLocalTypeTemplateArgs, > CXX98CompatUnnamedTypeTemplateArgs, > - CXXPre1yCompat]>; > + CXXPre1yCompat, > + CXXPre1zCompat]>; > // Warnings for C++11 features which are Extensions in C++98 mode. > def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", > [CXX98Compat, > - CXXPre1yCompatPedantic]>; > + CXXPre1yCompatPedantic, > + CXXPre1zCompatPedantic]>; > > def CXX11Narrowing : DiagGroup<"c++11-narrowing">; > > @@ -157,10 +162,16 @@ def CXX11Compat : DiagGroup<"c++11-compa > [CXX11Narrowing, > CXX11CompatReservedUserDefinedLiteral, > CXX11CompatDeprecatedWritableStr, > - CXXPre1yCompat]>; > + CXXPre1yCompat, > + CXXPre1zCompat]>; > def : DiagGroup<"c++0x-compat", [CXX11Compat]>; > def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic", > - [CXXPre1yCompatPedantic]>; > + [CXXPre1yCompatPedantic, > + CXXPre1zCompatPedantic]>; > + > +def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre1zCompat]>; > +def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic", > + [CXXPre1zCompatPedantic]>; > > def : DiagGroup<"effc++">; > def DivZero : DiagGroup<"division-by-zero">; > @@ -620,6 +631,10 @@ def CXX11 : DiagGroup<"c++11-extensions" > // earlier C++ versions. > def CXX1y : DiagGroup<"c++1y-extensions">; > > +// A warning group for warnings about using C++1z features as extensions in > +// earlier C++ versions. > +def CXX1z : DiagGroup<"c++1z-extensions">; > + > def : DiagGroup<"c++0x-extensions", [CXX11]>; > def DelegatingCtorCycles : > DiagGroup<"delegating-ctor-cycles">; > > Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=211031&r1=211030&r2=211031&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Mon Jun 16 10:51:22 > 2014 > @@ -566,6 +566,13 @@ 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 ext_template_template_param_typename : ExtWarn< > + "template template parameter using 'typename' is a C++1z extension">, > + InGroup<CXX1z>; > +def warn_cxx1y_compat_template_template_param_typename : Warning< > + "template template parameter using 'typename' is " > + "incompatible with C++ standards before C++1z">, > + InGroup<CXXPre1zCompat>, DefaultIgnore; > def err_template_spec_syntax_non_template : Error< > "identifier followed by '<' indicates a class template specialization but " > "%0 %select{does not refer to a template|refers to a function template|" > > Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=211031&r1=211030&r2=211031&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseTemplate.cpp (original) > +++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Jun 16 10:51:22 2014 > @@ -519,10 +519,13 @@ Decl *Parser::ParseTypeParameter(unsigne > /// template parameters. > /// > /// type-parameter: [C++ temp.param] > -/// 'template' '<' template-parameter-list '>' 'class' > +/// 'template' '<' template-parameter-list '>' type-parameter-key > /// ...[opt] identifier[opt] > -/// 'template' '<' template-parameter-list '>' 'class' > identifier[opt] > -/// = id-expression > +/// 'template' '<' template-parameter-list '>' type-parameter-key > +/// identifier[opt] = id-expression > +/// type-parameter-key: > +/// 'class' > +/// 'typename' [C++1z] > Decl * > Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { > assert(Tok.is(tok::kw_template) && "Expected 'template' keyword"); > @@ -539,20 +542,29 @@ Parser::ParseTemplateTemplateParameter(u > } > } > > + // Provide an ExtWarn if the C++1z feature of using 'typename' here is > used. > // Generate a meaningful error if the user forgot to put class before the > // identifier, comma, or greater. Provide a fixit if the identifier, comma, > - // or greater appear immediately or after 'typename' or 'struct'. In the > - // latter case, replace the keyword with 'class'. > + // or greater appear immediately or after 'struct'. In the latter case, > + // replace the keyword with 'class'. > if (!TryConsumeToken(tok::kw_class)) { > bool Replace = Tok.is(tok::kw_typename) || Tok.is(tok::kw_struct); > - const Token& Next = Replace ? NextToken() : Tok; > - if (Next.is(tok::identifier) || Next.is(tok::comma) || > - Next.is(tok::greater) || Next.is(tok::greatergreater) || > - Next.is(tok::ellipsis)) > + const Token &Next = Tok.is(tok::kw_struct) ? NextToken() : Tok; > + if (Tok.is(tok::kw_typename)) { > + Diag(Tok.getLocation(), > + getLangOpts().CPlusPlus1z > + ? diag::warn_cxx1y_compat_template_template_param_typename > + : diag::ext_template_template_param_typename) > + << (!getLangOpts().CPlusPlus1z > + ? FixItHint::CreateReplacement(Tok.getLocation(), "class") > + : FixItHint()); > + } else if (Next.is(tok::identifier) || Next.is(tok::comma) || > + Next.is(tok::greater) || Next.is(tok::greatergreater) || > + Next.is(tok::ellipsis)) { > Diag(Tok.getLocation(), diag::err_class_on_template_template_param) > << (Replace ? FixItHint::CreateReplacement(Tok.getLocation(), > "class") > : FixItHint::CreateInsertion(Tok.getLocation(), "class > ")); > - else > + } else > Diag(Tok.getLocation(), diag::err_class_on_template_template_param); > > if (Replace) > > Modified: cfe/trunk/test/FixIt/fixit.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=211031&r1=211030&r2=211031&view=diff > ============================================================================== > --- cfe/trunk/test/FixIt/fixit.cpp (original) > +++ cfe/trunk/test/FixIt/fixit.cpp Mon Jun 16 10:51:22 2014 > @@ -204,7 +204,7 @@ template<class T> typedef Mystery<T>::ty > } > > template<template<typename> Foo, // expected-error {{template template > parameter requires 'class' after the parameter list}} > - template<typename> typename Bar, // expected-error {{template > template parameter requires 'class' after the parameter list}} > + template<typename> typename Bar, // expected-warning {{template > template parameter using 'typename' is a C++1z extension}} > template<typename> struct Baz> // expected-error {{template > template parameter requires 'class' after the parameter list}} > void func(); > > > Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=211031&r1=211030&r2=211031&view=diff > ============================================================================== > --- cfe/trunk/test/Parser/cxx-template-decl.cpp (original) > +++ cfe/trunk/test/Parser/cxx-template-decl.cpp Mon Jun 16 10:51:22 2014 > @@ -1,5 +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 > > > > @@ -24,6 +25,11 @@ template <template X> struct Err1; // ex > 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> typename Foo> struct Cxx1z; > +#if __cplusplus <= 201402L > +// expected-warning@-2 {{extension}} > +#endif > + > // Template function declarations > template <typename T> void foo(); > template <typename T, typename U> void foo(); > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
