Keep track of function template specializations, to eliminate
redundant, implicit instantiations of function templates and provide a
place where we can hang function template specializations.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74454 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 725b066..e25fe90 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -372,11 +372,6 @@
 
   C.Deallocate(ParamInfo);
 
-  if (FunctionTemplateSpecializationInfo *Info 
-        = TemplateOrSpecialization
-            .dyn_cast<FunctionTemplateSpecializationInfo*>())
-    C.Deallocate(Info);
-  
   Decl::Destroy(C);
 }
 
@@ -564,6 +559,18 @@
   return false;
 }
 
+void 
+FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
+  PreviousDeclaration = PrevDecl;
+  
+  if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
+    FunctionTemplateDecl *PrevFunTmpl 
+      = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
+    assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
+    FunTmpl->setPreviousDeclaration(PrevFunTmpl);
+  }
+}
+
 /// getOverloadedOperator - Which C++ overloaded operator this
 /// function represents, if any.
 OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
@@ -595,15 +602,21 @@
 void 
 FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context,
                                                 FunctionTemplateDecl *Template,
-                                     const TemplateArgumentList *TemplateArgs) {
+                                     const TemplateArgumentList *TemplateArgs,
+                                                void *InsertPos) {
   FunctionTemplateSpecializationInfo *Info 
     = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
   if (!Info)
     Info = new (Context) FunctionTemplateSpecializationInfo;
   
+  Info->Function = this;
   Info->Template = Template;
   Info->TemplateArguments = TemplateArgs;
   TemplateOrSpecialization = Info;
+  
+  // Insert this function template specialization into the set of known
+  // function template specialiations.
+  Template->getSpecializations().InsertNode(Info, InsertPos);
 }
 
 //===----------------------------------------------------------------------===//