r211031 - [C++1z] Implement N4051: 'typename' is permitted instead of 'class' when declaring a template template parameter.
David Blaikie
dblaikie at gmail.com
Mon Jun 16 10:26:39 PDT 2014
On Mon, Jun 16, 2014 at 8:51 AM, Richard Smith
<richard-llvm at metafoo.co.uk> 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 at -2 {{extension}}
> +#endif
> +
> // Template function declarations
> template <typename T> void foo();
> template <typename T, typename U> void foo();
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list