From b19337fbe474a0086d0154421d4b2cedfa8d92a2 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 20 Feb 2013 20:19:27 +0000 Subject: [PATCH] PR15311: Finish implementation of the suggested resolution of core issue 1488, which allows grouping parens in an abstract-pack-declarator. This was already mostly implemented, but missed some cases. Add an ExtWarn for use of this extension until CWG ratifies it. llvm-svn: 175660 --- clang/include/clang/Basic/DiagnosticParseKinds.td | 3 +++ clang/lib/Parse/ParseDecl.cpp | 7 +++++++ clang/test/FixIt/fixit-cxx0x.cpp | 2 +- clang/test/Parser/cxx0x-ambig.cpp | 5 ++++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index a3ad84e..c75241e 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -470,6 +470,9 @@ def err_parser_impl_limit_overflow : Error< def err_misplaced_ellipsis_in_declaration : Error< "'...' must %select{immediately precede declared identifier|" "be innermost component of anonymous pack declaration}0">; +def ext_abstract_pack_declarator_parens : ExtWarn< + "ISO C++11 requires a parenthesized pack declaration to have a name">, + InGroup>; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 8bfdffc..a2045327 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4439,6 +4439,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { !((D.getContext() == Declarator::PrototypeContext || D.getContext() == Declarator::BlockLiteralContext) && NextToken().is(tok::r_paren) && + !D.hasGroupingParens() && !Actions.containsUnexpandedParameterPacks(D))) { SourceLocation EllipsisLoc = ConsumeToken(); if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) { @@ -4521,6 +4522,12 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // This could be something simple like "int" (in which case the declarator // portion is empty), if an abstract-declarator is allowed. D.SetIdentifier(0, Tok.getLocation()); + + // The grammar for abstract-pack-declarator does not allow grouping parens. + // FIXME: Revisit this once core issue 1488 is resolved. + if (D.hasEllipsis() && D.hasGroupingParens()) + Diag(PP.getLocForEndOfToken(D.getEllipsisLoc()), + diag::ext_abstract_pack_declarator_parens); } else { if (Tok.getKind() == tok::annot_pragma_parser_crash) LLVM_BUILTIN_TRAP; diff --git a/clang/test/FixIt/fixit-cxx0x.cpp b/clang/test/FixIt/fixit-cxx0x.cpp index 3884c64..1f6275f 100644 --- a/clang/test/FixIt/fixit-cxx0x.cpp +++ b/clang/test/FixIt/fixit-cxx0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -std=c++11 %s +// RUN: %clang_cc1 -verify -std=c++11 -Wno-anonymous-pack-parens %s // RUN: cp %s %t // RUN: not %clang_cc1 -x c++ -std=c++11 -fixit %t // RUN: %clang_cc1 -Wall -pedantic -x c++ -std=c++11 %t diff --git a/clang/test/Parser/cxx0x-ambig.cpp b/clang/test/Parser/cxx0x-ambig.cpp index 96e2006..ac9c75e 100644 --- a/clang/test/Parser/cxx0x-ambig.cpp +++ b/clang/test/Parser/cxx0x-ambig.cpp @@ -110,7 +110,7 @@ namespace ellipsis { void f(S(...args[sizeof(T)])); // expected-note {{here}} void f(S(...args)[sizeof(T)]); // expected-error {{redeclared}} expected-note {{here}} void f(S ...args[sizeof(T)]); // expected-error {{redeclared}} - void g(S(...[sizeof(T)])); // expected-note {{here}} + void g(S(...[sizeof(T)])); // expected-note {{here}} expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} void g(S(...)[sizeof(T)]); // expected-error {{function cannot return array type}} void g(S ...[sizeof(T)]); // expected-error {{redeclared}} void h(T(...)); // function type, expected-error {{unexpanded parameter pack}} @@ -125,5 +125,8 @@ namespace ellipsis { void j(T(T...)); // expected-error {{unexpanded parameter pack}} void k(int(...)(T)); // expected-error {{cannot return function type}} void k(int ...(T)); + void l(int(&...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} + void l(int(*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} + void l(int(S::*...)(T)); // expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} }; } -- 2.7.4