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.
+\r
+/// \brief Late parse a C++ function template in Microsoft mode.\r
+void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {\r
+ if(!LMT.D)\r
+ return;\r
+\r
+ // Get the FunctionDecl.\r
+ FunctionDecl *FD = 0;\r
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LMT.D))\r
+ FD = FunTmpl->getTemplatedDecl();\r
+ else\r
+ FD = cast<FunctionDecl>(LMT.D);\r
+ \r
+ // To restore the context after late parsing.
+ Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext);\r
+\r
+ SmallVector<ParseScope*, 4> TemplateParamScopeStack;\r
+ DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD);\r
+ if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {\r
+ TemplateParamScopeStack.push_back(new ParseScope(this, Scope::TemplateParamScope));\r
+ Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);\r
+ Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);\r
+ } else {\r
+ // Get the list of DeclContext to reenter.\r
+ SmallVector<DeclContext*, 4> DeclContextToReenter;\r
+ DeclContext *DD = FD->getLexicalParent();\r
+ while (DD && !DD->isTranslationUnit()) {\r
+ DeclContextToReenter.push_back(DD);\r
+ DD = DD->getLexicalParent();\r
+ }\r
+\r
+ // Reenter template scopes from outmost to innermost.\r
+ SmallVector<DeclContext*, 4>::reverse_iterator II =\r
+ DeclContextToReenter.rbegin();\r
+ for (; II != DeclContextToReenter.rend(); ++II) {\r
+ if (ClassTemplatePartialSpecializationDecl* MD =\r
+ dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {\r
+ TemplateParamScopeStack.push_back(new ParseScope(this,\r
+ Scope::TemplateParamScope));\r
+ Actions.ActOnReenterTemplateScope(getCurScope(), MD);\r
+ } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {\r
+ TemplateParamScopeStack.push_back(new ParseScope(this,\r
+ Scope::TemplateParamScope,\r
+ MD->getDescribedClassTemplate() != 0 ));\r
+ Actions.ActOnReenterTemplateScope(getCurScope(),\r
+ MD->getDescribedClassTemplate());\r
+ }\r
+ TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));\r
+ Actions.PushDeclContext(Actions.getCurScope(), *II);\r
+ }\r
+ TemplateParamScopeStack.push_back(new ParseScope(this,\r
+ Scope::TemplateParamScope));\r
+ Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);\r
+ }\r
+\r
+ assert(!LMT.Toks.empty() && "Empty body!");\r
+\r
+ // Append the current token at the end of the new token stream so that it\r
+ // doesn't get lost.\r
+ LMT.Toks.push_back(Tok);\r
+ PP.EnterTokenStream(LMT.Toks.data(), LMT.Toks.size(), true, false);\r
+\r
+ // Consume the previously pushed token.\r
+ ConsumeAnyToken();\r
+ assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))\r
+ && "Inline method not starting with '{', ':' or 'try'");\r
+\r
+ // Parse the method body. Function body parsing code is similar enough\r
+ // to be re-used for method bodies as well.\r
+ ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);\r
+\r
+ // Recreate the containing function DeclContext.\r
+ Sema::ContextRAII FunctionSavedContext(Actions, Actions.getContainingDC(FD));\r
+\r
+ if (FunctionTemplateDecl *FunctionTemplate\r
+ = dyn_cast_or_null<FunctionTemplateDecl>(LMT.D))\r
+ Actions.ActOnStartOfFunctionDef(getCurScope(),\r
+ FunctionTemplate->getTemplatedDecl());\r
+ if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(LMT.D))\r
+ Actions.ActOnStartOfFunctionDef(getCurScope(), Function);\r
+ \r
+\r
+ if (Tok.is(tok::kw_try)) {\r
+ ParseFunctionTryBlock(LMT.D, FnScope);\r
+ } else {\r
+ if (Tok.is(tok::colon))\r
+ ParseConstructorInitializer(LMT.D);\r
+ else\r
+ Actions.ActOnDefaultCtorInitializers(LMT.D);\r
+\r
+ if (Tok.is(tok::l_brace)) {\r
+ ParseFunctionStatementBody(LMT.D, FnScope);\r
+ Actions.MarkAsLateParsedTemplate(FD, false);\r
+ } else\r
+ Actions.ActOnFinishFunctionBody(LMT.D, 0);\r
+ }\r
+\r
+ // Exit scopes.\r
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 =\r
+ TemplateParamScopeStack.rbegin();\r
+ for (; I != TemplateParamScopeStack.rend(); ++I)\r
+ delete *I;\r
+\r
+ DeclGroupPtrTy grp = Actions.ConvertDeclToDeclGroup(LMT.D);\r
+ if (grp)\r
+ Actions.getASTConsumer().HandleTopLevelDecl(grp.get());\r
}
/// \brief Lex a delayed template function for late parsing.