aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-11-06 00:35:02 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-11-06 00:35:02 +0000
commit4f11234702bbf453c921328576043998f01fbe0a (patch)
tree77948aed3c3bf09b6028b1959a8323a6ef2ecf88
parentc7be10245e78bf38694b26f289880edefb9f16e9 (diff)
[PCH] Write out the ClassTemplateDecl::Common::InjectedClassNameType type
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
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp4
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp2
-rw-r--r--test/PCH/friend-template.cpp46
3 files changed, 49 insertions, 3 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 17509c8527..c42944df63 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -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);
}
}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index e84afba549..7486565763 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -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
index 0000000000..989819b64f
--- /dev/null
+++ b/test/PCH/friend-template.cpp
@@ -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