diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index c4bcc1e7d909..aea25c8dad02 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -722,6 +722,15 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { CXXRecordDecl *PrevDecl = 0; ClassTemplateDecl *PrevClassTemplate = 0; + if (!isFriend && Pattern->getPreviousDeclaration()) { + DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); + if (Found.first != Found.second) { + PrevClassTemplate = dyn_cast<ClassTemplateDecl>(*Found.first); + if (PrevClassTemplate) + PrevDecl = PrevClassTemplate->getTemplatedDecl(); + } + } + // If this isn't a friend, then it's a member template, in which // case we just want to build the instantiation in the // specialization. If it is a friend, we want to build it in @@ -836,7 +845,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { // friend target decl? } else { Inst->setAccess(D->getAccess()); - Inst->setInstantiatedFromMemberTemplate(D); + if (!PrevClassTemplate) + Inst->setInstantiatedFromMemberTemplate(D); } // Trigger creation of the type for the instantiation. diff --git a/clang/test/SemaTemplate/class-template-decl.cpp b/clang/test/SemaTemplate/class-template-decl.cpp index 1be1bc070a81..e7722123f9c2 100644 --- a/clang/test/SemaTemplate/class-template-decl.cpp +++ b/clang/test/SemaTemplate/class-template-decl.cpp @@ -56,3 +56,21 @@ namespace M { } template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}} + +namespace PR8001 { + template<typename T1> + struct Foo { + template<typename T2> class Bar; + typedef Bar<T1> Baz; + + template<typename T2> + struct Bar { + Bar() {} + }; + }; + + void pr8001() { + Foo<int>::Baz x; + Foo<int>::Bar<int> y(x); + } +}