diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 43 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 7 |
3 files changed, 47 insertions, 21 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 53851929a0c..65ec44c5775 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4661,19 +4661,6 @@ void Parser::ParseDeclaratorInternal(Declarator &D, } } -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(Declarator &D) { // 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(Declarator &D) { // An ellipsis cannot be placed outside parentheses. if (EllipsisLoc.isValid()) - diagnoseMisplacedEllipsis(*this, D, EllipsisLoc); + DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D); return; } 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 diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 92197e43e27..d893c881103 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -544,7 +544,7 @@ static void maybeDiagnoseTemplateParameterShadow(Sema &SemaRef, Scope *S, /// 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, bool Typename, bool Ellipsis, 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, bool Typename, bool Ellipsis, // 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(); } |