forked from OSchip/llvm-project
parent
6f1e2c6d19
commit
9b7efd5bb6
|
@ -1162,113 +1162,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;
|
||||
|
||||
// Get the FunctionDecl.
|
||||
FunctionDecl *FD = 0;
|
||||
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LMT.D))
|
||||
FD = FunTmpl->getTemplatedDecl();
|
||||
else
|
||||
FD = cast<FunctionDecl>(LMT.D);
|
||||
|
||||
|
||||
/// \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.
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue