]> granicus.if.org Git - clang/commitdiff
Fix C++ PCH issue.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 13 Sep 2010 11:45:48 +0000 (11:45 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 13 Sep 2010 11:45:48 +0000 (11:45 +0000)
The canonical FunctionTemplateDecl contains the specializations but we cannot use getCanonicalDecl on Template because it may still be initializing.
Write and read it from PCH.
Fixes http://llvm.org/PR8134

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

lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/PCH/cxx-templates.h

index 77cd426b6e9be82e58162ec92c0ef608b0886c3a..e5a87b0c109ef0c536946b09a7745d8687dc7640 100644 (file)
@@ -294,6 +294,10 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
     FD->TemplateOrSpecialization = FTInfo;
 
     if (FD->isCanonicalDecl()) { // if canonical add to template's set.
+      // The template that contains the specializations set. It's not safe to
+      // use getCanonicalDecl on Template since it may still be initializing.
+      FunctionTemplateDecl *CanonTemplate
+        = cast<FunctionTemplateDecl>(Reader.GetDecl(Record[Idx++]));
       // Get the InsertPos by FindNodeOrInsertPos() instead of calling
       // InsertNode(FTInfo) directly to avoid the getASTContext() call in
       // FunctionTemplateSpecializationInfo's Profile().
@@ -303,9 +307,9 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
       FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(),
                                                   TemplArgs.size(), C);
       void *InsertPos = 0;
-      Template->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      CanonTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
       assert(InsertPos && "Another specialization already inserted!");
-      Template->getSpecializations().InsertNode(FTInfo, InsertPos);
+      CanonTemplate->getSpecializations().InsertNode(FTInfo, InsertPos);
     }
     break;
   }
@@ -1041,7 +1045,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
 
     // Read the function specialization declarations.
     // FunctionTemplateDecl's FunctionTemplateSpecializationInfos are filled
-    // through the specialized FunctionDecl's setFunctionTemplateSpecialization.
+    // when reading the specialized FunctionDecl.
     unsigned NumSpecs = Record[Idx++];
     while (NumSpecs--)
       Reader.GetDecl(Record[Idx++]);
index 3f990e7a5657b86f1605f0e7d54c1237a5b05a1b..76974667a8928277e5dc6a7766a91525a1630cc9 100644 (file)
@@ -257,6 +257,12 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
     }
     
     Writer.AddSourceLocation(FTSInfo->getPointOfInstantiation(), Record);
+
+    if (D->isCanonicalDecl()) {
+      // Write the template that contains the specializations set. We will
+      // add a FunctionTemplateSpecializationInfo to it when reading.
+      Writer.AddDeclRef(FTSInfo->getTemplate()->getCanonicalDecl(), Record);
+    }
     break;
   }
   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
index e5c06a9e12aa0a5cdcd2fcbab70cdf9f5f11549b..e1f285b19dcb69e3862a9957d113cfba8e977b59 100644 (file)
@@ -145,3 +145,8 @@ struct TS5 {
   template <typename T>
   TS5(T y) : s(y) {}
 };
+
+// PR 8134
+template<class T> void f_PR8134(T);
+template<class T> void f_PR8134(T);
+void g_PR8134() { f_PR8134(0); f_PR8134('x'); }