New patch addressing Richard's feedback.
http://reviews.llvm.org/D3555
Files:
include/clang/Sema/Sema.h
lib/Parse/ParseTemplate.cpp
lib/Sema/SemaDeclCXX.cpp
test/Parser/DelayedTemplateParsing.cpp
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -4886,6 +4886,7 @@
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
void ActOnReenterTemplateScope(Scope *S, Decl *Template);
void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D);
+ void ActOnReenterRecordTemplateScope(Scope *S, CXXRecordDecl *RD);
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -1255,28 +1255,33 @@
new ParseScope(this, Scope::TemplateParamScope));
Actions.ActOnReenterTemplateScope(getCurScope(), MD);
++CurTemplateDepthTracker;
- } else if (CXXRecordDecl *MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
- bool IsClassTemplate = MD->getDescribedClassTemplate() != 0;
+ } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
+ if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate()) {
+ TemplateParamScopeStack.push_back(new ParseScope(this,
+ Scope::TemplateParamScope, /*EnteredScope*/true));
+ Actions.ActOnReenterTemplateScope(getCurScope(), CTD);
+ ++CurTemplateDepthTracker;
+ }
+
+ bool HasTemplateParams = RD->getNumTemplateParameterLists() > 0;
+
TemplateParamScopeStack.push_back(
- new ParseScope(this, Scope::TemplateParamScope,
- /*ManageScope*/IsClassTemplate));
- Actions.ActOnReenterTemplateScope(getCurScope(),
- MD->getDescribedClassTemplate());
- if (IsClassTemplate)
+ new ParseScope(this, Scope::TemplateParamScope,
+ /*EnteredScope*/HasTemplateParams));
+ if (HasTemplateParams) {
+ Actions.ActOnReenterRecordTemplateScope(getCurScope(), RD);
++CurTemplateDepthTracker;
+ }
}
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>(FunD);
- const unsigned DeclaratorNumTemplateParameterLists =
- (Declarator ? Declarator->getNumTemplateParameterLists() : 0);
- if (Declarator && DeclaratorNumTemplateParameterLists != 0) {
- Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
- CurTemplateDepthTracker.addDepth(DeclaratorNumTemplateParameterLists);
+ if (unsigned NumLists = FunD->getNumTemplateParameterLists()) {
+ Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), FunD);
+ CurTemplateDepthTracker.addDepth(NumLists);
}
Actions.ActOnReenterTemplateScope(getCurScope(), LPT.D);
++CurTemplateDepthTracker;
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -5984,9 +5984,9 @@
if (!D)
return;
- int NumParamList = D->getNumTemplateParameterLists();
- for (int i = 0; i < NumParamList; i++) {
- TemplateParameterList* Params = D->getTemplateParameterList(i);
+ unsigned NumParamList = D->getNumTemplateParameterLists();
+ for (unsigned i = 0; i < NumParamList; i++) {
+ TemplateParameterList *Params = D->getTemplateParameterList(i);
for (TemplateParameterList::iterator Param = Params->begin(),
ParamEnd = Params->end();
Param != ParamEnd; ++Param) {
@@ -5999,6 +5999,22 @@
}
}
+void Sema::ActOnReenterRecordTemplateScope(Scope *S, CXXRecordDecl *RD) {
+ if (!RD)
+ return;
+
+ unsigned NumParamLists = RD->getNumTemplateParameterLists();
+ for (unsigned i = 0; i < NumParamLists; ++i) {
+ TemplateParameterList *Params = RD->getTemplateParameterList(i);
+ for (NamedDecl *Param : *Params) {
+ if (Param->getDeclName()) {
+ S->AddDecl(Param);
+ IdResolver.AddDecl(Param);
+ }
+ }
+ }
+}
+
void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
if (!D)
return;
Index: test/Parser/DelayedTemplateParsing.cpp
===================================================================
--- test/Parser/DelayedTemplateParsing.cpp
+++ test/Parser/DelayedTemplateParsing.cpp
@@ -123,3 +123,47 @@
template <typename T>
auto invalidTrailingRetType() -> Bogus {} // expected-error {{unknown type name 'Bogus'}}
+
+namespace PR19613 {
+
+struct HeapTypeConfig {
+ static void from_bitset();
+};
+
+template <class Config>
+struct TypeImpl {
+ struct BitsetType;
+
+ static void Any() {
+ BitsetType::New();
+ }
+};
+
+template<class Config>
+struct TypeImpl<Config>::BitsetType {
+ static void New() {
+ Config::from_bitset();
+ }
+};
+
+static void f() {
+ TypeImpl<HeapTypeConfig>::Any();
+}
+
+template<typename A> struct S {
+ template<typename B> struct T;
+};
+template<typename A> template<typename B> struct S<A>::T {
+ template<typename C, typename D> struct U;
+ template<typename C> struct U<C, C> {
+ template<typename E> static int f() {
+ return sizeof(A) + sizeof(B) + sizeof(C) + sizeof(E);
+ }
+ };
+};
+
+static void g() {
+ S<int>::T<int>::U<int,int>::f<int>();
+}
+
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits