diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-04-29 08:53:40 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-04-29 08:53:40 +0000 |
commit | fed844d8676db8daece6144340284b09f901323d (patch) | |
tree | 64280f39079a76c86f8e99c619ef279bc0a32ef3 /lib/Parse/ParseTemplate.cpp | |
parent | 97aea95f46f27ff0927faa72baa7fe2b0bce1d2d (diff) |
Properly reenter multiple contexts when parsing a late-parsed function template
within a dependent context. Patch by Will Wilson (+clang-format)!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180702 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 66 |
1 files changed, 32 insertions, 34 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index f14666922b..f25beff92b 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -1259,43 +1259,41 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) { 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); + // Get the list of DeclContexts to reenter. + SmallVector<DeclContext*, 4> DeclContextsToReenter; + DeclContext *DD = FD->getLexicalParent(); + while (DD && !DD->isTranslationUnit()) { + DeclContextsToReenter.push_back(DD); + DD = DD->getLexicalParent(); + } + + // Reenter template scopes from outermost to innermost. + SmallVector<DeclContext*, 4>::reverse_iterator II = + DeclContextsToReenter.rbegin(); + for (; II != DeclContextsToReenter.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)) { + bool ManageScope = MD->getDescribedClassTemplate() != 0; + TemplateParamScopeStack.push_back( + new ParseScope(this, Scope::TemplateParamScope, ManageScope)); + Actions.ActOnReenterTemplateScope(getCurScope(), + MD->getDescribedClassTemplate()); } - TemplateParamScopeStack.push_back(new ParseScope(this, - Scope::TemplateParamScope)); - Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D); + TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope)); + Actions.PushDeclContext(Actions.getCurScope(), *II); } + TemplateParamScopeStack.push_back( + new ParseScope(this, Scope::TemplateParamScope)); + + DeclaratorDecl *Declarator = dyn_cast<DeclaratorDecl>(FD); + if (Declarator && Declarator->getNumTemplateParameterLists() != 0) + Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator); + Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D); assert(!LMT.Toks.empty() && "Empty body!"); |