summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-30 04:39:27 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-30 04:39:27 +0000
commit1e13c5a8fb9c9fbf24e90a86cc1e745fce0eac22 (patch)
tree147fa9a1d9cc212242c0e5ece21e1238e66b73a0
parent526f504f0653de13b89a474c338cbd688ce01972 (diff)
downloadbcm5719-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.h1
-rw-r--r--clang/lib/AST/Decl.cpp9
-rw-r--r--clang/test/SemaTemplate/injected-class-name.cpp12
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;
+ };
+}
OpenPOWER on IntegriCloud