Improve code generation for function template specializations:
  - Track implicit instantiations vs. the not-yet-supported explicit
  specializations
  - Give implicit instantiations of function templates (and member
  functions of class templates) linkonce_odr linkage.
  - Improve name mangling for function template specializations,
  including the template arguments of the instantiation and the return
  type of the function.

Note that our name-mangling is improved, but not correct: we still
don't mangle substitutions, although the manglings we produce can be
demangled.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74466 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index e25fe90..fa4d93c 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -584,7 +584,7 @@
   if (FunctionTemplateSpecializationInfo *Info 
         = TemplateOrSpecialization
             .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
-    return Info->Template;
+    return Info->Template.getPointer();
   }
   return 0;
 }
@@ -610,7 +610,8 @@
     Info = new (Context) FunctionTemplateSpecializationInfo;
   
   Info->Function = this;
-  Info->Template = Template;
+  Info->Template.setPointer(Template);
+  Info->Template.setInt(0); // Implicit instantiation, unless told otherwise
   Info->TemplateArguments = TemplateArgs;
   TemplateOrSpecialization = Info;
   
@@ -619,6 +620,26 @@
   Template->getSpecializations().InsertNode(Info, InsertPos);
 }
 
+bool FunctionDecl::isExplicitSpecialization() const {
+  // FIXME: check this property for explicit specializations of member
+  // functions of class templates.
+  FunctionTemplateSpecializationInfo *Info 
+    = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+  if (!Info)
+    return false;
+  
+  return Info->isExplicitSpecialization();
+}
+
+void FunctionDecl::setExplicitSpecialization(bool ES) {
+  // FIXME: set this property for explicit specializations of member functions
+  // of class templates.
+  FunctionTemplateSpecializationInfo *Info 
+    = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+  if (Info)
+    Info->setExplicitSpecialization(ES);
+}
+
 //===----------------------------------------------------------------------===//
 // TagDecl Implementation
 //===----------------------------------------------------------------------===//