Use the ASTMutationListener to track added template specializations in a chained PCH.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117533 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index 5ed607a..5ded805 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -22,7 +22,8 @@
 
 enum DeclUpdateKind {
   UPD_CXX_SET_DEFINITIONDATA,
-  UPD_CXX_ADDED_IMPLICIT_MEMBER
+  UPD_CXX_ADDED_IMPLICIT_MEMBER,
+  UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION
 };
 
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index c0aff9a..f09873a 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -2069,13 +2069,6 @@
             std::make_pair(&F, Record[I+1]);
       break;
     }
-
-    case ADDITIONAL_TEMPLATE_SPECIALIZATIONS: {
-      AdditionalTemplateSpecializations &ATS =
-          AdditionalTemplateSpecializationsPending[Record[0]];
-      ATS.insert(ATS.end(), Record.begin()+1, Record.end());
-      break;
-    }
     }
     First = false;
   }
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index b815878..ea995af 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1553,20 +1553,6 @@
       }
     }
   }
-
-  // If this is a template, read additional specializations that may be in a
-  // different part of the chain.
-  if (isa<RedeclarableTemplateDecl>(D)) {
-    AdditionalTemplateSpecializationsMap::iterator F =
-        AdditionalTemplateSpecializationsPending.find(ID);
-    if (F != AdditionalTemplateSpecializationsPending.end()) {
-      for (AdditionalTemplateSpecializations::iterator I = F->second.begin(),
-                                                       E = F->second.end();
-           I != E; ++I)
-        GetDecl(*I);
-      AdditionalTemplateSpecializationsPending.erase(F);
-    }
-  }
   assert(Idx == Record.size());
 
   // The declaration may have been modified by files later in the chain.
@@ -1617,6 +1603,10 @@
     case UPD_CXX_ADDED_IMPLICIT_MEMBER:
       cast<CXXRecordDecl>(D)->addedMember(Reader.GetDecl(Record[Idx++]));
       break;
+
+    case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
+      // It will be added to the template's specializations set when loaded.
+      Reader.GetDecl(Record[Idx++]);
     }
   }
 }
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 340f0cc..3589b9b 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2181,21 +2181,6 @@
   Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable.str());
 }
 
-/// \brief Write ADDITIONAL_TEMPLATE_SPECIALIZATIONS blocks for all templates
-/// that have new specializations in the current AST file.
-void ASTWriter::WriteAdditionalTemplateSpecializations() {
-  RecordData Record;
-  for (AdditionalTemplateSpecializationsMap::iterator
-           I = AdditionalTemplateSpecializations.begin(),
-           E = AdditionalTemplateSpecializations.end();
-       I != E; ++I) {
-    Record.clear();
-    Record.push_back(I->first);
-    Record.insert(Record.end(), I->second.begin(), I->second.end());
-    Stream.EmitRecord(ADDITIONAL_TEMPLATE_SPECIALIZATIONS, Record);
-  }
-}
-
 //===----------------------------------------------------------------------===//
 // General Serialization Routines
 //===----------------------------------------------------------------------===//
@@ -2697,10 +2682,6 @@
          I != E; ++I)
     WriteDeclContextVisibleUpdate(*I);
 
-  // Write the updates to C++ template specialization lists.
-  if (!AdditionalTemplateSpecializations.empty())
-    WriteAdditionalTemplateSpecializations();
-
   WriteDeclUpdatesBlocks();
 
   Record.clear();
@@ -3340,3 +3321,13 @@
   Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER);
   AddDeclRef(D, Record);
 }
+
+void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
+                                     const ClassTemplateSpecializationDecl *D) {
+  if (!(D->getPCHLevel() == 0 && TD->getPCHLevel() > 0))
+    return; // Not a source specialization added to a template from PCH.
+
+  UpdateRecord &Record = DeclUpdates[TD];
+  Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION);
+  AddDeclRef(D, Record);
+}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 46f62b7..5b403cf 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -905,10 +905,6 @@
     InstFromD = cast<ClassTemplatePartialSpecializationDecl>(InstFromD)->
                     getSpecializedTemplate();
   }
-  // Is this a specialization of an already-serialized template?
-  if (InstFromD->getCanonicalDecl()->getPCHLevel() != 0)
-    Writer.AddAdditionalTemplateSpecialization(Writer.getDeclID(InstFromD),
-                                               Writer.getDeclID(D));
 
   // Explicit info.
   Writer.AddTypeSourceInfo(D->getTypeAsWritten(), Record);