When explicit template arguments are provided for a function call,
substitute those template arguments into the function parameter types
prior to template argument deduction. There's still a bit of work to
do to make this work properly when only some of the template arguments
are specified.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74576 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index f7deb1f..03ac2d9 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2166,8 +2166,9 @@
       AddOverloadCandidate(FD, Args, NumArgs, CandidateSet, 
                            SuppressUserConversions);
     else
-      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*F), Args, 
-                                   NumArgs, CandidateSet, 
+      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*F),
+                                   /*FIXME: explicit args */false, 0, 0,
+                                   Args, NumArgs, CandidateSet, 
                                    SuppressUserConversions);
   }
 }
@@ -2273,6 +2274,9 @@
 /// template specialization.
 void 
 Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+                                   bool HasExplicitTemplateArgs,
+                                 const TemplateArgument *ExplicitTemplateArgs,
+                                   unsigned NumExplicitTemplateArgs,
                                    Expr **Args, unsigned NumArgs,
                                    OverloadCandidateSet& CandidateSet,
                                    bool SuppressUserConversions,
@@ -2289,8 +2293,9 @@
   TemplateDeductionInfo Info(Context);
   FunctionDecl *Specialization = 0;
   if (TemplateDeductionResult Result
-        = DeduceTemplateArguments(FunctionTemplate, Args, NumArgs, 
-                                  Specialization, Info)) {
+        = DeduceTemplateArguments(FunctionTemplate, HasExplicitTemplateArgs,
+                                  ExplicitTemplateArgs, NumExplicitTemplateArgs,
+                                  Args, NumArgs, Specialization, Info)) {
     // FIXME: Record what happened with template argument deduction, so
     // that we can give the user a beautiful diagnostic.
     (void)Result;
@@ -3438,8 +3443,9 @@
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func))
       AddOverloadCandidate(FD, Args, NumArgs, CandidateSet);
     else
-      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func), Args, 
-                                   NumArgs, CandidateSet);
+      AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),  
+                                   /*FIXME: explicit args */false, 0, 0,
+                                   Args, NumArgs, CandidateSet);
   }
 }
 
@@ -3758,6 +3764,9 @@
 /// arguments and Fn, and returns NULL.
 FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
                                             DeclarationName UnqualifiedName,
+                                            bool HasExplicitTemplateArgs,
+                                 const TemplateArgument *ExplicitTemplateArgs,
+                                            unsigned NumExplicitTemplateArgs,
                                             SourceLocation LParenLoc,
                                             Expr **Args, unsigned NumArgs,
                                             SourceLocation *CommaLocs, 
@@ -3790,11 +3799,17 @@
          Func != FuncEnd; ++Func) {
       DeclContext *Ctx = 0;
       if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Func)) {
+        if (HasExplicitTemplateArgs)
+          continue;
+        
         AddOverloadCandidate(FunDecl, Args, NumArgs, CandidateSet);
         Ctx = FunDecl->getDeclContext();
       } else {
         FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*Func);
-        AddTemplateOverloadCandidate(FunTmpl, Args, NumArgs, CandidateSet);
+        AddTemplateOverloadCandidate(FunTmpl, HasExplicitTemplateArgs,
+                                     ExplicitTemplateArgs,
+                                     NumExplicitTemplateArgs,
+                                     Args, NumArgs, CandidateSet);
         Ctx = FunTmpl->getDeclContext();
       }
 
@@ -3803,6 +3818,7 @@
         ArgumentDependentLookup = false;
     }
   } else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) {
+    assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
     AddOverloadCandidate(Func, Args, NumArgs, CandidateSet);
 
     if (Func->getDeclContext()->isRecord() ||
@@ -3810,7 +3826,10 @@
       ArgumentDependentLookup = false;
   } else if (FunctionTemplateDecl *FuncTemplate 
                = dyn_cast_or_null<FunctionTemplateDecl>(Callee)) {
-    AddTemplateOverloadCandidate(FuncTemplate, Args, NumArgs, CandidateSet);
+    AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
+                                 ExplicitTemplateArgs,
+                                 NumExplicitTemplateArgs, 
+                                 Args, NumArgs, CandidateSet);
 
     if (FuncTemplate->getDeclContext()->isRecord())
       ArgumentDependentLookup = false;
@@ -3819,6 +3838,7 @@
   if (Callee)
     UnqualifiedName = Callee->getDeclName();
 
+  // FIXME: Pass explicit template arguments through for ADL
   if (ArgumentDependentLookup)
     AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
                                          CandidateSet);