diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp index 84b7df7295f6..076edb93fa11 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp @@ -120,7 +120,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), TemplateParams, LAngleLoc, RAngleLoc)) { // Skip until the semi-colon or a }. - SkipUntil(tok::r_brace, true, true); + SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); if (Tok.is(tok::semi)) ConsumeToken(); return 0; @@ -216,7 +216,7 @@ Parser::ParseSingleDeclarationAfterTemplate( // Error parsing the declarator? if (!DeclaratorInfo.hasName()) { // If so, skip until the semi-colon or a }. - SkipUntil(tok::r_brace, true, true); + SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); if (Tok.is(tok::semi)) ConsumeToken(); return 0; @@ -236,6 +236,35 @@ Parser::ParseSingleDeclarationAfterTemplate( << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); DS.ClearStorageClassSpecs(); } + + if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) { + if (DeclaratorInfo.getName().getKind() != UnqualifiedId::IK_TemplateId) { + // If the declarator-id is not a template-id, issue a diagnostic and + // recover by ignoring the 'template' keyword. + Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0; + return ParseFunctionDefinition(DeclaratorInfo, ParsedTemplateInfo(), + &LateParsedAttrs); + } else { + SourceLocation LAngleLoc + = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); + Diag(DeclaratorInfo.getIdentifierLoc(), + diag::err_explicit_instantiation_with_definition) + << SourceRange(TemplateInfo.TemplateLoc) + << FixItHint::CreateInsertion(LAngleLoc, "<>"); + + // Recover as if it were an explicit specialization. + TemplateParameterLists FakedParamLists; + FakedParamLists.push_back(Actions.ActOnTemplateParameterList( + 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0, + LAngleLoc)); + + return ParseFunctionDefinition( + DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists, + /*isSpecialization=*/true, + /*LastParamListWasEmpty=*/true), + &LateParsedAttrs); + } + } return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo, &LateParsedAttrs); } @@ -247,7 +276,7 @@ Parser::ParseSingleDeclarationAfterTemplate( if (Tok.is(tok::comma)) { Diag(Tok, diag::err_multiple_template_declarators) << (int)TemplateInfo.Kind; - SkipUntil(tok::semi, true, false); + SkipUntil(tok::semi); return ThisDecl; } @@ -320,7 +349,8 @@ Parser::ParseTemplateParameterList(unsigned Depth, } else { // If we failed to parse a template parameter, skip until we find // a comma or closing brace. - SkipUntil(tok::comma, tok::greater, tok::greatergreater, true, true); + SkipUntil(tok::comma, tok::greater, tok::greatergreater, + StopAtSemi | StopBeforeMatch); } // Did we find a comma or the end of the template parameter list? @@ -334,7 +364,8 @@ Parser::ParseTemplateParameterList(unsigned Depth, // try to get out of the expression. This error is currently // subsumed by whatever goes on in ParseTemplateParameter. Diag(Tok.getLocation(), diag::err_expected_comma_greater); - SkipUntil(tok::comma, tok::greater, tok::greatergreater, true, true); + SkipUntil(tok::comma, tok::greater, tok::greatergreater, + StopAtSemi | StopBeforeMatch); return false; } } @@ -582,7 +613,8 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { if (DefaultArg.isInvalid()) { Diag(Tok.getLocation(), diag::err_default_template_template_parameter_not_template); - SkipUntil(tok::comma, tok::greater, tok::greatergreater, true, true); + SkipUntil(tok::comma, tok::greater, tok::greatergreater, + StopAtSemi | StopBeforeMatch); } } @@ -632,7 +664,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { DefaultArg = ParseAssignmentExpression(); if (DefaultArg.isInvalid()) - SkipUntil(tok::comma, tok::greater, true, true); + SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); } // Create the parameter. @@ -650,6 +682,8 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { /// \param RAngleLoc the location of the consumed '>'. /// /// \param ConsumeLastToken if true, the '>' is not consumed. +/// +/// \returns true, if current token does not start with '>', false otherwise. bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, bool ConsumeLastToken) { // What will be left once we've consumed the '>'. @@ -794,8 +828,10 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template, if (Invalid) { // Try to find the closing '>'. - SkipUntil(tok::greater, true, !ConsumeLastToken); - + if (ConsumeLastToken) + SkipUntil(tok::greater, StopAtSemi); + else + SkipUntil(tok::greater, StopAtSemi | StopBeforeMatch); return true; } } @@ -1160,7 +1196,7 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { } if (Arg.isInvalid()) { - SkipUntil(tok::comma, tok::greater, true, true); + SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch); return true; } @@ -1212,30 +1248,19 @@ SourceRange Parser::ParsedTemplateInfo::getSourceRange() const { return R; } -void Parser::LateTemplateParserCallback(void *P, const FunctionDecl *FD) { - ((Parser*)P)->LateTemplateParser(FD); -} - - -void Parser::LateTemplateParser(const FunctionDecl *FD) { - LateParsedTemplatedFunction *LPT = LateParsedTemplateMap[FD]; - if (LPT) { - ParseLateTemplatedFuncDef(*LPT); - return; - } - - llvm_unreachable("Late templated function without associated lexed tokens"); +void Parser::LateTemplateParserCallback(void *P, LateParsedTemplate &LPT) { + ((Parser *)P)->ParseLateTemplatedFuncDef(LPT); } /// \brief Late parse a C++ function template in Microsoft mode. -void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) { - if(!LMT.D) +void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { + if (!LPT.D) return; // Get the FunctionDecl. - FunctionTemplateDecl *FunTmplD = dyn_cast<FunctionTemplateDecl>(LMT.D); + FunctionTemplateDecl *FunTmplD = dyn_cast<FunctionTemplateDecl>(LPT.D); FunctionDecl *FunD = - FunTmplD ? FunTmplD->getTemplatedDecl() : cast<FunctionDecl>(LMT.D); + FunTmplD ? FunTmplD->getTemplatedDecl() : cast<FunctionDecl>(LPT.D); // Track template parameter depth. TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth); @@ -1253,7 +1278,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) { } // Reenter template scopes from outermost to innermost. - SmallVector<DeclContext*, 4>::reverse_iterator II = + SmallVectorImpl<DeclContext *>::reverse_iterator II = DeclContextsToReenter.rbegin(); for (; II != DeclContextsToReenter.rend(); ++II) { if (ClassTemplatePartialSpecializationDecl *MD = @@ -1263,12 +1288,14 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) { Actions.ActOnReenterTemplateScope(getCurScope(), MD); ++CurTemplateDepthTracker; } else if (CXXRecordDecl *MD = dyn_cast_or_null<CXXRecordDecl>(*II)) { - bool ManageScope = MD->getDescribedClassTemplate() != 0; + bool IsClassTemplate = MD->getDescribedClassTemplate() != 0; TemplateParamScopeStack.push_back( - new ParseScope(this, Scope::TemplateParamScope, ManageScope)); + new ParseScope(this, Scope::TemplateParamScope, + /*ManageScope*/IsClassTemplate)); Actions.ActOnReenterTemplateScope(getCurScope(), MD->getDescribedClassTemplate()); - ++CurTemplateDepthTracker; + if (IsClassTemplate) + ++CurTemplateDepthTracker; } TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope)); Actions.PushDeclContext(Actions.getCurScope(), *II); @@ -1281,15 +1308,15 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) { Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator); ++CurTemplateDepthTracker; } - Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D); + Actions.ActOnReenterTemplateScope(getCurScope(), LPT.D); ++CurTemplateDepthTracker; - assert(!LMT.Toks.empty() && "Empty body!"); + assert(!LPT.Toks.empty() && "Empty body!"); // Append the current token at the end of the new token stream so that it // doesn't get lost. - LMT.Toks.push_back(Tok); - PP.EnterTokenStream(LMT.Toks.data(), LMT.Toks.size(), true, false); + LPT.Toks.push_back(Tok); + PP.EnterTokenStream(LPT.Toks.data(), LPT.Toks.size(), true, false); // Consume the previously pushed token. ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); @@ -1306,34 +1333,30 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) { Actions.ActOnStartOfFunctionDef(getCurScope(), FunD); if (Tok.is(tok::kw_try)) { - ParseFunctionTryBlock(LMT.D, FnScope); + ParseFunctionTryBlock(LPT.D, FnScope); } else { if (Tok.is(tok::colon)) - ParseConstructorInitializer(LMT.D); + ParseConstructorInitializer(LPT.D); else - Actions.ActOnDefaultCtorInitializers(LMT.D); + Actions.ActOnDefaultCtorInitializers(LPT.D); if (Tok.is(tok::l_brace)) { assert((!FunTmplD || FunTmplD->getTemplateParameters()->getDepth() < TemplateParameterDepth) && "TemplateParameterDepth should be greater than the depth of " "current template being instantiated!"); - ParseFunctionStatementBody(LMT.D, FnScope); - Actions.MarkAsLateParsedTemplate(FunD, false); + ParseFunctionStatementBody(LPT.D, FnScope); + Actions.UnmarkAsLateParsedTemplate(FunD); } else - Actions.ActOnFinishFunctionBody(LMT.D, 0); + Actions.ActOnFinishFunctionBody(LPT.D, 0); } // Exit scopes. FnScope.Exit(); - SmallVector<ParseScope*, 4>::reverse_iterator I = + SmallVectorImpl<ParseScope *>::reverse_iterator I = TemplateParamScopeStack.rbegin(); for (; I != TemplateParamScopeStack.rend(); ++I) delete *I; - - DeclGroupPtrTy grp = Actions.ConvertDeclToDeclGroup(LMT.D); - if (grp) - Actions.getASTConsumer().HandleTopLevelDecl(grp.get()); } /// \brief Lex a delayed template function for late parsing. |