diff options
| author | Nikola Smiljanic <popizdeh@gmail.com> | 2014-06-06 02:58:59 +0000 |
|---|---|---|
| committer | Nikola Smiljanic <popizdeh@gmail.com> | 2014-06-06 02:58:59 +0000 |
| commit | 69fdc9ff89813e679b578e3953131515ddfcac32 (patch) | |
| tree | b621e3dac15e3c158f93c9718d67271a0fa39c11 /clang/lib/Parse/ParseTemplate.cpp | |
| parent | df540cbf92d11cc43d269e033e79cff9ea61a7cb (diff) | |
| download | bcm5719-llvm-69fdc9ff89813e679b578e3953131515ddfcac32.tar.gz bcm5719-llvm-69fdc9ff89813e679b578e3953131515ddfcac32.zip | |
PR11306 - Variadic template fix-it suggestion. Recover from misplaced or redundant ellipsis in parameter pack.
llvm-svn: 210304
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
| -rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index a4a7abc1f6c..4d0ec8f834d 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -498,6 +498,11 @@ Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { 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(unsigned Depth, unsigned Position) { 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(unsigned Depth, unsigned Position) { 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(unsigned Depth, unsigned Position) { 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(unsigned Depth, unsigned Position) { 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 |

