Hide the specializations folding sets of ClassTemplateDecl as an implementation detail (InsertPos
leaks though) and add methods to its interface for adding/finding specializations.

Simplifies its users a bit and we no longer need to replace specializations in the folding set with
their redeclarations. We just return the most recent redeclarations.

As a bonus, it fixes http://llvm.org/PR7670.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108832 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 9e1d79d..a75c1c0 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -171,6 +171,28 @@
   Decl::Destroy(C);
 }
 
+ClassTemplateSpecializationDecl *
+ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
+                                      unsigned NumArgs, void *&InsertPos) {
+  llvm::FoldingSetNodeID ID;
+  ClassTemplateSpecializationDecl::Profile(ID, Args, NumArgs, getASTContext());
+  ClassTemplateSpecializationDecl *D
+      = getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+  return D ? D->getMostRecentDeclaration() : 0;
+}
+
+ClassTemplatePartialSpecializationDecl *
+ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
+                                             unsigned NumArgs,
+                                             void *&InsertPos) {
+  llvm::FoldingSetNodeID ID;
+  ClassTemplatePartialSpecializationDecl::Profile(ID, Args, NumArgs,
+                                                  getASTContext());
+  ClassTemplatePartialSpecializationDecl *D
+      = getPartialSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+  return D ? D->getMostRecentDeclaration() : 0;
+}
+
 void ClassTemplateDecl::getPartialSpecializations(
           llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
   llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
@@ -181,7 +203,7 @@
        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
        P != PEnd; ++P) {
     assert(!PS[P->getSequenceNumber()]);
-    PS[P->getSequenceNumber()] = &*P;
+    PS[P->getSequenceNumber()] = P->getMostRecentDeclaration();
   }
 }
 
@@ -194,7 +216,22 @@
                           PEnd = getPartialSpecializations().end();
        P != PEnd; ++P) {
     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
-      return &*P;
+      return P->getMostRecentDeclaration();
+  }
+
+  return 0;
+}
+
+ClassTemplatePartialSpecializationDecl *
+ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
+                                    ClassTemplatePartialSpecializationDecl *D) {
+  Decl *DCanon = D->getCanonicalDecl();
+  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+            P = getPartialSpecializations().begin(),
+         PEnd = getPartialSpecializations().end();
+       P != PEnd; ++P) {
+    if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
+      return P->getMostRecentDeclaration();
   }
 
   return 0;