r180702 - Properly reenter multiple contexts when parsing a late-parsed function template
Richard Smith
richard-llvm at metafoo.co.uk
Mon Apr 29 01:53:40 PDT 2013
Author: rsmith
Date: Mon Apr 29 03:53:40 2013
New Revision: 180702
URL: http://llvm.org/viewvc/llvm-project?rev=180702&view=rev
Log:
Properly reenter multiple contexts when parsing a late-parsed function template
within a dependent context. Patch by Will Wilson (+clang-format)!
Modified:
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=180702&r1=180701&r2=180702&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Apr 29 03:53:40 2013
@@ -1259,43 +1259,41 @@ void Parser::ParseLateTemplatedFuncDef(L
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!");
Modified: cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp?rev=180702&r1=180701&r2=180702&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp Mon Apr 29 03:53:40 2013
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
class A {
More information about the cfe-commits
mailing list