r210304 - PR11306 - Variadic template fix-it suggestion. Recover from misplaced or redundant ellipsis in parameter pack.
Nikola Smiljanic
popizdeh at gmail.com
Thu Jun 5 19:59:00 PDT 2014
Author: nikola
Date: Thu Jun 5 21:58:59 2014
New Revision: 210304
URL: http://llvm.org/viewvc/llvm-project?rev=210304&view=rev
Log:
PR11306 - Variadic template fix-it suggestion. Recover from misplaced or redundant ellipsis in parameter pack.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/FixIt/fixit-cxx0x.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=210304&r1=210303&r2=210304&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Jun 5 21:58:59 2014
@@ -2371,6 +2371,12 @@ private:
Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
+ void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+ SourceLocation CorrectLoc,
+ bool AlreadyHasEllipsis,
+ bool IdentifierHasName);
+ void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+ Declarator &D);
// C++ 14.3: Template arguments [temp.arg]
typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=210304&r1=210303&r2=210304&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 5 21:58:59 2014
@@ -5174,7 +5174,7 @@ public:
void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl);
- Decl *ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+ Decl *ActOnTypeParameter(Scope *S, bool Typename,
SourceLocation EllipsisLoc,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=210304&r1=210303&r2=210304&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Jun 5 21:58:59 2014
@@ -4661,19 +4661,6 @@ void Parser::ParseDeclaratorInternal(Dec
}
}
-static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
- SourceLocation EllipsisLoc) {
- if (EllipsisLoc.isValid()) {
- FixItHint Insertion;
- if (!D.getEllipsisLoc().isValid()) {
- Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
- D.setEllipsisLoc(EllipsisLoc);
- }
- P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
- << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
- }
-}
-
/// ParseDirectDeclarator
/// direct-declarator: [C99 6.7.5]
/// [C99] identifier
@@ -4753,7 +4740,8 @@ void Parser::ParseDirectDeclarator(Decla
// The ellipsis was put in the wrong place. Recover, and explain to
// the user what they should have done.
ParseDeclarator(D);
- diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
+ if (EllipsisLoc.isValid())
+ DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
return;
} else
D.setEllipsisLoc(EllipsisLoc);
@@ -5004,7 +4992,7 @@ void Parser::ParseParenDeclarator(Declar
// An ellipsis cannot be placed outside parentheses.
if (EllipsisLoc.isValid())
- diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
+ DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
return;
}
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=210304&r1=210303&r2=210304&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Thu Jun 5 21:58:59 2014
@@ -498,6 +498,11 @@ Decl *Parser::ParseTypeParameter(unsigne
return nullptr;
}
+ // Recover from misplaced ellipsis.
+ bool AlreadyHasEllipsis = EllipsisLoc.isValid();
+ if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+ DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
+
// Grab a default argument (if available).
// Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
// we introduce the type parameter into the local scope.
@@ -507,9 +512,9 @@ Decl *Parser::ParseTypeParameter(unsigne
DefaultArg = ParseTypeName(/*Range=*/nullptr,
Declarator::TemplateTypeArgContext).get();
- return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, Ellipsis,
- EllipsisLoc, KeyLoc, ParamName, NameLoc,
- Depth, Position, EqualLoc, DefaultArg);
+ return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, EllipsisLoc,
+ KeyLoc, ParamName, NameLoc, Depth, Position,
+ EqualLoc, DefaultArg);
}
/// ParseTemplateTemplateParameter - Handle the parsing of template
@@ -579,6 +584,11 @@ Parser::ParseTemplateTemplateParameter(u
return nullptr;
}
+ // Recover from misplaced ellipsis.
+ bool AlreadyHasEllipsis = EllipsisLoc.isValid();
+ if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+ DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
+
TemplateParameterList *ParamList =
Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
TemplateLoc, LAngleLoc,
@@ -629,6 +639,11 @@ Parser::ParseNonTypeTemplateParameter(un
return nullptr;
}
+ // Recover from misplaced ellipsis.
+ SourceLocation EllipsisLoc;
+ if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+ DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
+
// If there is a default value, parse it.
// Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
// we introduce the template parameter into the local scope.
@@ -654,6 +669,28 @@ Parser::ParseNonTypeTemplateParameter(un
DefaultArg.get());
}
+void Parser::DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+ SourceLocation CorrectLoc,
+ bool AlreadyHasEllipsis,
+ bool IdentifierHasName) {
+ FixItHint Insertion;
+ if (!AlreadyHasEllipsis)
+ Insertion = FixItHint::CreateInsertion(CorrectLoc, "...");
+ Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
+ << FixItHint::CreateRemoval(EllipsisLoc) << Insertion
+ << !IdentifierHasName;
+}
+
+void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+ Declarator &D) {
+ assert(EllipsisLoc.isValid());
+ bool AlreadyHasEllipsis = D.getEllipsisLoc().isValid();
+ if (!AlreadyHasEllipsis)
+ D.setEllipsisLoc(EllipsisLoc);
+ DiagnoseMisplacedEllipsis(EllipsisLoc, D.getIdentifierLoc(),
+ AlreadyHasEllipsis, D.hasName());
+}
+
/// \brief Parses a '>' at the end of a template list.
///
/// If this function encounters '>>', '>>>', '>=', or '>>=', it tries
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=210304&r1=210303&r2=210304&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Jun 5 21:58:59 2014
@@ -544,7 +544,7 @@ static void maybeDiagnoseTemplateParamet
/// ParamNameLoc is the location of the parameter name (if any).
/// If the type parameter has a default argument, it will be added
/// later via ActOnTypeParameterDefault.
-Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
SourceLocation EllipsisLoc,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
@@ -560,10 +560,11 @@ Decl *Sema::ActOnTypeParameter(Scope *S,
if (!ParamName)
Loc = KeyLoc;
+ bool IsParameterPack = EllipsisLoc.isValid();
TemplateTypeParmDecl *Param
= TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
KeyLoc, Loc, Depth, Position, ParamName,
- Typename, Ellipsis);
+ Typename, IsParameterPack);
Param->setAccess(AS_public);
if (Invalid)
Param->setInvalidDecl();
@@ -579,7 +580,7 @@ Decl *Sema::ActOnTypeParameter(Scope *S,
// C++0x [temp.param]p9:
// A default template-argument may be specified for any kind of
// template-parameter that is not a template parameter pack.
- if (DefaultArg && Ellipsis) {
+ if (DefaultArg && IsParameterPack) {
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
DefaultArg = ParsedType();
}
Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=210304&r1=210303&r2=210304&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Thu Jun 5 21:58:59 2014
@@ -138,3 +138,23 @@ int RegisterVariable() {
register int n; // expected-warning {{'register' storage class specifier is deprecated}}
return n;
}
+
+namespace MisplacedParameterPack {
+ template <typename Args...> // expected-error {{'...' must immediately precede declared identifier}}
+ void misplacedEllipsisInTypeParameter(Args...);
+
+ template <typename... Args...> // expected-error {{'...' must immediately precede declared identifier}}
+ void redundantEllipsisInTypeParameter(Args...);
+
+ template <template <typename> class Args...> // expected-error {{'...' must immediately precede declared identifier}}
+ void misplacedEllipsisInTemplateTypeParameter(Args<int>...);
+
+ template <template <typename> class... Args...> // expected-error {{'...' must immediately precede declared identifier}}
+ void redundantEllipsisInTemplateTypeParameter(Args<int>...);
+
+ template <int N...> // expected-error {{'...' must immediately precede declared identifier}}
+ void misplacedEllipsisInNonTypeTemplateParameter();
+
+ template <int... N...> // expected-error {{'...' must immediately precede declared identifier}}
+ void redundantEllipsisInNonTypeTemplateParameter();
+}
More information about the cfe-commits
mailing list