diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-30 04:39:27 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-30 04:39:27 +0000 |
commit | 1e13c5a8fb9c9fbf24e90a86cc1e745fce0eac22 (patch) | |
tree | 147fa9a1d9cc212242c0e5ece21e1238e66b73a0 | |
parent | 526f504f0653de13b89a474c338cbd688ce01972 (diff) | |
download | bcm5719-llvm-1e13c5a8fb9c9fbf24e90a86cc1e745fce0eac22.tar.gz bcm5719-llvm-1e13c5a8fb9c9fbf24e90a86cc1e745fce0eac22.zip |
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
-rw-r--r-- | clang/include/clang/AST/Type.h | 1 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaTemplate/injected-class-name.cpp | 12 |
3 files changed, 22 insertions, 0 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 7eb332bd95a..030c74c6408 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -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) { diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index fc805451cba..ffe49671d8a 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -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?"); } } diff --git a/clang/test/SemaTemplate/injected-class-name.cpp b/clang/test/SemaTemplate/injected-class-name.cpp index 586be189b0a..4c21d2585d3 100644 --- a/clang/test/SemaTemplate/injected-class-name.cpp +++ b/clang/test/SemaTemplate/injected-class-name.cpp @@ -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; + }; +} |