Don't lose track of previous-declarations when instantiating a class template.

Fixes PR8001.

llvm-svn: 118454
This commit is contained in:
Nick Lewycky 2010-11-08 23:29:42 +00:00
parent c7baee31ad
commit 6147891648
2 changed files with 29 additions and 1 deletions

View File

@ -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.

View File

@ -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);
}
}