Hide FunctionTemplateDecl's specializations folding set as implementation detail and introduce
FunctionTemplateDecl::findSpecialization.

Redeclarations of specializations will not cause the previous decl to be removed from the set,
the set will keep the canonical decl. findSpecialization will return the most recent redeclaration.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108834 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 149938f..e695310 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1400,14 +1400,15 @@
   if (InsertPos)
     Template->getSpecializations().InsertNode(Info, InsertPos);
   else {
-    // Try to insert the new node. If there is an existing node, remove it 
-    // first.
+    // Try to insert the new node. If there is an existing node, leave it, the
+    // set will contain the canonical decls while
+    // FunctionTemplateDecl::findSpecialization will return
+    // the most recent redeclarations.
     FunctionTemplateSpecializationInfo *Existing
       = Template->getSpecializations().GetOrInsertNode(Info);
-    if (Existing) {
-      Template->getSpecializations().RemoveNode(Existing);
-      Template->getSpecializations().GetOrInsertNode(Info);
-    }
+    (void)Existing;
+    assert((!Existing || Existing->Function->isCanonicalDecl()) &&
+           "Set is supposed to only contain canonical decls");
   }
 }
 
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index a75c1c0..f308d71 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -119,6 +119,16 @@
   Decl::Destroy(C);
 }
 
+FunctionDecl *
+FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
+                                         unsigned NumArgs, void *&InsertPos) {
+  llvm::FoldingSetNodeID ID;
+  FunctionTemplateSpecializationInfo::Profile(ID,Args,NumArgs, getASTContext());
+  FunctionTemplateSpecializationInfo *Info
+      = getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+  return Info ? Info->Function->getMostRecentDeclaration() : 0;
+}
+
 FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() {
   FunctionTemplateDecl *FunTmpl = this;
   while (FunTmpl->getPreviousDeclaration())