forked from OSchip/llvm-project
Properly account for redeclarations when explicitly instantiating class templates.
What happens here is that we actually turn the first declaration into a definition, regardless of whether it was actually originally a definition, and furthermore we do this all after we've instantiated all the declarations. This exposes a bug in my DefinitionData patch where it was only setting the DefinitionData for previous declarations, not future declarations. Fortunately, there's an iterator for that. llvm-svn: 99657
This commit is contained in:
parent
2f072e95e6
commit
93cc732ffc
|
@ -1413,10 +1413,8 @@ void TagDecl::startDefinition() {
|
|||
CXXRecordDecl *D = cast<CXXRecordDecl>(this);
|
||||
struct CXXRecordDecl::DefinitionData *Data =
|
||||
new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
|
||||
do {
|
||||
D->DefinitionData = Data;
|
||||
D = cast_or_null<CXXRecordDecl>(D->getPreviousDeclaration());
|
||||
} while (D);
|
||||
for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
|
||||
cast<CXXRecordDecl>(*I)->DefinitionData = Data;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,3 +50,33 @@ namespace test1 {
|
|||
Registry<int>::node node(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Redeclarations during explicit instantiations.
|
||||
namespace test2 {
|
||||
template <typename T> class A {
|
||||
class Foo;
|
||||
class Foo {
|
||||
int foo();
|
||||
};
|
||||
};
|
||||
template class A<int>;
|
||||
|
||||
template <typename T> class B {
|
||||
class Foo;
|
||||
class Foo {
|
||||
typedef int X;
|
||||
};
|
||||
typename Foo::X x;
|
||||
class Foo;
|
||||
};
|
||||
template class B<int>;
|
||||
|
||||
template <typename T> class C {
|
||||
class Foo;
|
||||
class Foo;
|
||||
};
|
||||
template <typename T> class C<T>::Foo {
|
||||
int x;
|
||||
};
|
||||
template class C<int>;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue