When we start the definition of a class template, set the

InjectedClassNameType's Decl to point at the definition. It's a little
messy, but we do the same thing with classes and their record types,
since much of Clang expects that the TagDecl* one gets out of a type
is the definition. Fixes several Boost.Proto failures.

llvm-svn: 102691
This commit is contained in:
Douglas Gregor 2010-04-30 04:39:27 +00:00
parent 526f504f06
commit 1e13c5a8fb
3 changed files with 22 additions and 0 deletions

View File

@ -2566,6 +2566,7 @@ class InjectedClassNameType : public Type {
QualType InjectedType;
friend class ASTContext; // ASTContext creates these.
friend class TagDecl; // TagDecl mutilates the Decl
InjectedClassNameType(CXXRecordDecl *D, QualType TST)
: Type(InjectedClassName, QualType(), true),
Decl(D), InjectedType(TST) {

View File

@ -1479,6 +1479,10 @@ void TagDecl::startDefinition() {
if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
TagT->decl.setPointer(this);
TagT->decl.setInt(1);
} else if (InjectedClassNameType *Injected
= const_cast<InjectedClassNameType *>(
TypeForDecl->getAs<InjectedClassNameType>())) {
Injected->Decl = cast<CXXRecordDecl>(this);
}
if (isa<CXXRecordDecl>(this)) {
@ -1500,6 +1504,11 @@ void TagDecl::completeDefinition() {
assert(TagT->decl.getPointer() == this &&
"Attempt to redefine a tag definition?");
TagT->decl.setInt(0);
} else if (InjectedClassNameType *Injected
= const_cast<InjectedClassNameType *>(
TypeForDecl->getAs<InjectedClassNameType>())) {
assert(Injected->Decl == this &&
"Attempt to redefine a class template definition?");
}
}

View File

@ -48,3 +48,15 @@ namespace pr6326 {
};
template class A<int>;
}
namespace ForwardDecls {
template<typename T>
struct X;
template<typename T>
struct X {
typedef T foo;
typedef X<T> xt;
typename xt::foo *t;
};
}