r220331 - [modules] When building an injected-class-name type, we may have to insert it

Richard Smith richard-llvm at metafoo.co.uk
Tue Oct 21 14:15:18 PDT 2014


Author: rsmith
Date: Tue Oct 21 16:15:18 2014
New Revision: 220331

URL: http://llvm.org/viewvc/llvm-project?rev=220331&view=rev
Log:
[modules] When building an injected-class-name type, we may have to insert it
into multiple merged classes' TypeForDecl slots.

Modified:
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
    cfe/trunk/test/Modules/Inputs/cxx-templates-b.h
    cfe/trunk/test/Modules/Inputs/cxx-templates-c.h
    cfe/trunk/test/Modules/Inputs/cxx-templates-d.h
    cfe/trunk/test/Modules/cxx-templates.cpp

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=220331&r1=220330&r2=220331&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Oct 21 16:15:18 2014
@@ -5493,13 +5493,18 @@ QualType ASTReader::readTypeRecord(unsig
     QualType TST = readType(*Loc.F, Record, Idx); // probably derivable
     // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
     // for AST reading, too much interdependencies.
-    const Type *T;
-    if (const Type *Existing = D->getTypeForDecl())
-      T = Existing;
-    else if (auto *Prev = D->getPreviousDecl())
-      T = Prev->getTypeForDecl();
-    else
+    const Type *T = nullptr;
+    for (auto *DI = D; DI; DI = DI->getPreviousDecl()) {
+      if (const Type *Existing = DI->getTypeForDecl()) {
+        T = Existing;
+        break;
+      }
+    }
+    if (!T) {
       T = new (Context, TypeAlignment) InjectedClassNameType(D, TST);
+      for (auto *DI = D; DI; DI = DI->getPreviousDecl())
+        DI->setTypeForDecl(T);
+    }
     return QualType(T, 0);
   }
 

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-a.h?rev=220331&r1=220330&r2=220331&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-a.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-a.h Tue Oct 21 16:15:18 2014
@@ -99,3 +99,8 @@ struct MergeAnonUnionMember {
 inline MergeAnonUnionMember<> maum_a() { return {}; }
 
 template<typename T> struct DontWalkPreviousDeclAfterMerging { struct Inner { typedef T type; }; };
+
+namespace TestInjectedClassName {
+  template<typename T> struct X { X(); };
+  typedef X<char[1]> A;
+}

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-b.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-b.h?rev=220331&r1=220330&r2=220331&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-b.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-b.h Tue Oct 21 16:15:18 2014
@@ -24,6 +24,11 @@ template<typename T> template<typename U
 constexpr int Outer<T>::Inner<U>::g() { return 2; }
 static_assert(Outer<int>::Inner<int>::g() == 2, "");
 
+namespace TestInjectedClassName {
+  template<typename T> struct X { X(); };
+  typedef X<char[2]> B;
+}
+
 @import cxx_templates_b_impl;
 
 template<typename T, typename> struct Identity { typedef T type; };

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-c.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-c.h?rev=220331&r1=220330&r2=220331&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-c.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-c.h Tue Oct 21 16:15:18 2014
@@ -21,3 +21,8 @@ inline MergeAnonUnionMember<> maum_c() {
 
 template<typename T> struct DontWalkPreviousDeclAfterMerging { struct Inner { typedef T type; }; };
 typedef DontWalkPreviousDeclAfterMerging<char>::Inner dwpdam_typedef;
+
+namespace TestInjectedClassName {
+  template<typename T> struct X { X(); };
+  typedef X<char[3]> C;
+}

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-d.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-d.h?rev=220331&r1=220330&r2=220331&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-d.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-d.h Tue Oct 21 16:15:18 2014
@@ -1,3 +1,9 @@
 @import cxx_templates_common;
 
 inline int InstantiateWithAnonymousDeclsD(WithAnonymousDecls<char> x) { return (x.k ? x.a : x.b) + (x.k ? x.s.c : x.s.d) + x.e; }
+
+namespace TestInjectedClassName {
+  template<typename T> struct X { X(); };
+  typedef X<int> D;
+  inline D UseD() { return D(); }
+}

Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=220331&r1=220330&r2=220331&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Tue Oct 21 16:15:18 2014
@@ -122,6 +122,10 @@ void g() {
   (void)&WithImplicitSpecialMembers<int>::n;
 
   MergeClassTemplateSpecializations_string s;
+
+  extern TestInjectedClassName::A *use_a;
+  extern TestInjectedClassName::C *use_c;
+  TestInjectedClassName::UseD();
 }
 
 static_assert(Outer<int>::Inner<int>::f() == 1, "");





More information about the cfe-commits mailing list