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