From 37574f55cd637340f651330f5cfda69742880d36 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Mon, 8 Nov 2010 23:29:42 +0000 Subject: [PATCH] Don't lose track of previous-declarations when instantiating a class template. Fixes PR8001. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118454 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiateDecl.cpp | 12 +++++++++++- test/SemaTemplate/class-template-decl.cpp | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index c4bcc1e7d9..aea25c8dad 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/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(*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/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp index 1be1bc070a..e7722123f9 100644 --- a/test/SemaTemplate/class-template-decl.cpp +++ b/test/SemaTemplate/class-template-decl.cpp @@ -56,3 +56,21 @@ namespace M { } template class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}} + +namespace PR8001 { + template + struct Foo { + template class Bar; + typedef Bar Baz; + + template + struct Bar { + Bar() {} + }; + }; + + void pr8001() { + Foo::Baz x; + Foo::Bar y(x); + } +} -- 2.50.1