llvm_unreachable("Late templated function without associated lexed tokens");
}
-\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
+
+/// \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);\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
+ 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 =\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
+ 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.