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,15 +1255,23 @@ new ParseScope(this, Scope::TemplateParamScope)); Actions.ActOnReenterTemplateScope(getCurScope(), MD); ++CurTemplateDepthTracker; - } else if (CXXRecordDecl *MD = dyn_cast_or_null(*II)) { - bool IsClassTemplate = MD->getDescribedClassTemplate() != 0; + } else if (CXXRecordDecl *RD = dyn_cast_or_null(*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); @@ -1271,12 +1279,9 @@ TemplateParamScopeStack.push_back( new ParseScope(this, Scope::TemplateParamScope)); - DeclaratorDecl *Declarator = dyn_cast(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 auto invalidTrailingRetType() -> Bogus {} // expected-error {{unknown type name 'Bogus'}} + +namespace PR19613 { + +struct HeapTypeConfig { + static void from_bitset(); +}; + +template +struct TypeImpl { + struct BitsetType; + + static void Any() { + BitsetType::New(); + } +}; + +template +struct TypeImpl::BitsetType { + static void New() { + Config::from_bitset(); + } +}; + +static void f() { + TypeImpl::Any(); +} + +template struct S { + template struct T; +}; +template template struct S::T { + template struct U; + template struct U { + template static int f() { + return sizeof(A) + sizeof(B) + sizeof(C) + sizeof(E); + } + }; +}; + +static void g() { + S::T::U::f(); +} + +}