]> granicus.if.org Git - clang/commitdiff
[PCH] Write out the ClassTemplateDecl::Common::InjectedClassNameType type
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 6 Nov 2012 00:35:02 +0000 (00:35 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Tue, 6 Nov 2012 00:35:02 +0000 (00:35 +0000)
reference instead of relying on computing it.

In general, if storage is no issue, it is preferable to deserialize info from
the PCH instead of trying to recompute it after the PCH was loaded.

The incentive to change this now was due to r155303 changing how friend template
classes in dependent contexts are handled; such classes can now be chained to
a previous template class but the computed InjectedClassNameType may be different
due to the extra template parameters from the dependent context.

The new handling requires more investigation but, in the meantime, writing out
InjectedClassNameType fixes PCH issue in rdar://12627738.

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

lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/PCH/friend-template.cpp [new file with mode: 0644]

index 17509c852789698fcdfc10a3a9c48f6a45754d9a..c42944df6344310d17f3455369e55100f10390f9 100644 (file)
@@ -1353,10 +1353,10 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
     for (unsigned I = 0; I != Size; ++I)
       SpecIDs.push_back(ReadDeclID(Record, Idx));
 
+    ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
     if (SpecIDs[0]) {
       typedef serialization::DeclID DeclID;
       
-      ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
       // FIXME: Append specializations!
       CommonPtr->LazySpecializations
         = new (Reader.getContext()) DeclID [SpecIDs.size()];
@@ -1364,7 +1364,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
              SpecIDs.size() * sizeof(DeclID));
     }
     
-    // InjectedClassNameType is computed.
+    CommonPtr->InjectedClassNameType = Reader.readType(F, Record, Idx);
   }
 }
 
index e84afba549501b99e1751aabb3189f486d781a6c..74865657637cd77da19286277825cdec54e1ebe0 100644 (file)
@@ -1084,7 +1084,7 @@ void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
       Writer.AddDeclRef(&*I, Record); 
     }
 
-    // InjectedClassNameType is computed, no need to write it.
+    Writer.AddTypeRef(D->getCommonPtr()->InjectedClassNameType, Record);
   }
   Code = serialization::DECL_CLASS_TEMPLATE;
 }
diff --git a/test/PCH/friend-template.cpp b/test/PCH/friend-template.cpp
new file mode 100644 (file)
index 0000000..989819b
--- /dev/null
@@ -0,0 +1,46 @@
+// Test this without pch.
+// RUN: %clang_cc1 -include %s -fsyntax-only -verify %s
+
+// Test with pch.
+// RUN: %clang_cc1 -emit-pch -o %t %s
+// RUN: %clang_cc1 -include-pch %t -fsyntax-only -verify %s 
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+// rdar://12627738
+namespace rdar12627738 {
+
+class RecyclerTag {
+    template <typename T> friend class Recycler;
+};
+
+}
+
+#else
+
+namespace rdar12627738 {
+
+template<typename TTag>
+class CRN {
+    template <typename T> friend class Recycler;
+};
+
+
+template<typename T>
+class Recycler {
+public:
+    Recycler ();
+};
+
+
+template<typename T>
+Recycler<T>::Recycler ()
+{
+}
+
+}
+
+#endif