diff options
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 208 |
1 files changed, 106 insertions, 102 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index d4a0502859..84b967e213 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -1157,109 +1157,113 @@ void Parser::LateTemplateParser(const FunctionDecl *FD) { llvm_unreachable("Late templated function without associated lexed tokens"); } - -/// \brief Late parse a C++ function template in Microsoft mode. -void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) { - if(!LMT.D) - return; - - // If this is a member template, introduce the template parameter scope. - ParseScope TemplateScope(this, Scope::TemplateParamScope); - - // Get the FunctionDecl. - FunctionDecl *FD = 0; - if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LMT.D)) - FD = FunTmpl->getTemplatedDecl(); - else - FD = cast<FunctionDecl>(LMT.D); - - // Reinject the template parameters. - SmallVector<ParseScope*, 4> TemplateParamScopeStack; - DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD); - if (Declarator && Declarator->getNumTemplateParameterLists() != 0) { - Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator); - Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D); - } else { - Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D); - - // Get the list of DeclContext to reenter. - SmallVector<DeclContext*, 4> DeclContextToReenter; - DeclContext *DD = FD->getLexicalParent(); - while (DD && DD->isRecord()) { - DeclContextToReenter.push_back(DD); - DD = DD->getLexicalParent(); - } - - // Reenter template scopes from outmost to innermost. - SmallVector<DeclContext*, 4>::reverse_iterator II = - DeclContextToReenter.rbegin(); - for (; II != DeclContextToReenter.rend(); ++II) { - if (ClassTemplatePartialSpecializationDecl* MD = - dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) { - TemplateParamScopeStack.push_back(new ParseScope(this, - Scope::TemplateParamScope)); - Actions.ActOnReenterTemplateScope(getCurScope(), MD); - } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) { - TemplateParamScopeStack.push_back(new ParseScope(this, - Scope::TemplateParamScope, - MD->getDescribedClassTemplate() != 0 )); - Actions.ActOnReenterTemplateScope(getCurScope(), - MD->getDescribedClassTemplate()); - } - } - } - assert(!LMT.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); - - // Consume the previously pushed token. - ConsumeAnyToken(); - assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) - && "Inline method not starting with '{', ':' or 'try'"); - - // Parse the method body. Function body parsing code is similar enough - // to be re-used for method bodies as well. - ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope); - - // Recreate the DeclContext. - Sema::ContextRAII SavedContext(Actions, Actions.getContainingDC(FD)); - - if (FunctionTemplateDecl *FunctionTemplate - = dyn_cast_or_null<FunctionTemplateDecl>(LMT.D)) - Actions.ActOnStartOfFunctionDef(getCurScope(), - FunctionTemplate->getTemplatedDecl()); - if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(LMT.D)) - Actions.ActOnStartOfFunctionDef(getCurScope(), Function); - - - if (Tok.is(tok::kw_try)) { - ParseFunctionTryBlock(LMT.D, FnScope); - } else { - if (Tok.is(tok::colon)) - ParseConstructorInitializer(LMT.D); - else - Actions.ActOnDefaultCtorInitializers(LMT.D); - - if (Tok.is(tok::l_brace)) { - ParseFunctionStatementBody(LMT.D, FnScope); - Actions.MarkAsLateParsedTemplate(FD, false); - } else - Actions.ActOnFinishFunctionBody(LMT.D, 0); - } - - // Exit scopes. +
+/// \brief Late parse a C++ function template in Microsoft mode.
+void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
+ if(!LMT.D)
+ return;
+
+ // Get the FunctionDecl.
+ FunctionDecl *FD = 0;
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LMT.D))
+ FD = FunTmpl->getTemplatedDecl();
+ else
+ FD = cast<FunctionDecl>(LMT.D);
+
+ // To restore the context after late parsing. + Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext);
+
+ SmallVector<ParseScope*, 4> TemplateParamScopeStack;
+ DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD);
+ if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
+ TemplateParamScopeStack.push_back(new ParseScope(this, Scope::TemplateParamScope));
+ Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
+ Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+ } else {
+ // Get the list of DeclContext to reenter.
+ SmallVector<DeclContext*, 4> DeclContextToReenter;
+ DeclContext *DD = FD->getLexicalParent();
+ while (DD && !DD->isTranslationUnit()) {
+ DeclContextToReenter.push_back(DD);
+ DD = DD->getLexicalParent();
+ }
+
+ // Reenter template scopes from outmost to innermost.
+ SmallVector<DeclContext*, 4>::reverse_iterator II =
+ DeclContextToReenter.rbegin();
+ for (; II != DeclContextToReenter.rend(); ++II) {
+ if (ClassTemplatePartialSpecializationDecl* MD =
+ dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {
+ TemplateParamScopeStack.push_back(new ParseScope(this,
+ Scope::TemplateParamScope));
+ Actions.ActOnReenterTemplateScope(getCurScope(), MD);
+ } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
+ TemplateParamScopeStack.push_back(new ParseScope(this,
+ Scope::TemplateParamScope,
+ MD->getDescribedClassTemplate() != 0 ));
+ Actions.ActOnReenterTemplateScope(getCurScope(),
+ MD->getDescribedClassTemplate());
+ }
+ TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
+ Actions.PushDeclContext(Actions.getCurScope(), *II);
+ }
+ TemplateParamScopeStack.push_back(new ParseScope(this,
+ Scope::TemplateParamScope));
+ Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+ }
+
+ assert(!LMT.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);
+
+ // Consume the previously pushed token.
+ ConsumeAnyToken();
+ assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
+ && "Inline method not starting with '{', ':' or 'try'");
+
+ // Parse the method body. Function body parsing code is similar enough
+ // to be re-used for method bodies as well.
+ ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
+
+ // Recreate the containing function DeclContext.
+ Sema::ContextRAII FunctionSavedContext(Actions, Actions.getContainingDC(FD));
+
+ if (FunctionTemplateDecl *FunctionTemplate
+ = dyn_cast_or_null<FunctionTemplateDecl>(LMT.D))
+ Actions.ActOnStartOfFunctionDef(getCurScope(),
+ FunctionTemplate->getTemplatedDecl());
+ if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(LMT.D))
+ Actions.ActOnStartOfFunctionDef(getCurScope(), Function);
+
+
+ if (Tok.is(tok::kw_try)) {
+ ParseFunctionTryBlock(LMT.D, FnScope);
+ } else {
+ if (Tok.is(tok::colon))
+ ParseConstructorInitializer(LMT.D);
+ else
+ Actions.ActOnDefaultCtorInitializers(LMT.D);
+
+ if (Tok.is(tok::l_brace)) {
+ ParseFunctionStatementBody(LMT.D, FnScope);
+ Actions.MarkAsLateParsedTemplate(FD, false);
+ } else
+ Actions.ActOnFinishFunctionBody(LMT.D, 0);
+ }
+
+ // Exit scopes.
FnScope.Exit(); - SmallVector<ParseScope*, 4>::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()); + SmallVector<ParseScope*, 4>::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. |