When searching for the instantiation of a locally-scoped tag

declaration, also look for an instantiation of its previous
declarations. Fixes PR8801.

llvm-svn: 122361
This commit is contained in:
Douglas Gregor 2010-12-21 21:22:51 +00:00
parent 87c47499c6
commit e9fc8dc84c
2 changed files with 28 additions and 5 deletions

View File

@ -1735,11 +1735,21 @@ Decl *LocalInstantiationScope::getInstantiationOf(const Decl *D) {
for (LocalInstantiationScope *Current = this; Current;
Current = Current->Outer) {
// Check if we found something within this scope.
llvm::DenseMap<const Decl *, Decl *>::iterator Found
= Current->LocalDecls.find(D);
if (Found != Current->LocalDecls.end())
return Found->second;
const Decl *CheckD = D;
do {
llvm::DenseMap<const Decl *, Decl *>::iterator Found
= Current->LocalDecls.find(CheckD);
if (Found != Current->LocalDecls.end())
return Found->second;
// If this is a tag declaration, it's possible that we need to look for
// a previous declaration.
if (const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
CheckD = Tag->getPreviousDeclaration();
else
CheckD = 0;
} while (CheckD);
// If we aren't combined with our outer scope, we're done.
if (!Current->CombineWithOuterScope)
break;

View File

@ -50,3 +50,16 @@ namespace local_class_with_virtual_functions {
struct S { };
void test() { f<S>(); }
}
namespace PR8801 {
template<typename T>
void foo() {
class X;
int (X::*pmf)(T) = 0;
class X : public T { };
}
struct Y { };
template void foo<Y>();
}