]> granicus.if.org Git - clang/commitdiff
When we start the definition of a class template, set the
authorDouglas Gregor <dgregor@apple.com>
Fri, 30 Apr 2010 04:39:27 +0000 (04:39 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 30 Apr 2010 04:39:27 +0000 (04:39 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102691 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Type.h
lib/AST/Decl.cpp
test/SemaTemplate/injected-class-name.cpp

index 7eb332bd95ae17d3e5a6b0611f6ccb2775a9ea4c..030c74c64089ab708ad846e897043f7c96a12c99 100644 (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) {
index fc805451cba0e15ba6efbbe017053d617d7e2780..ffe49671d8a3629cbb255245ad64ed53ac173169 100644 (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?");
   }
 }
 
index 586be189b0ab62b1b6485b9fbb0626fd63390878..4c21d2585d32a0b3c943875eaa8fb21c15c66bcd 100644 (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;
+  };
+}