Revert "Use function overloading instead of template specialization for diagnosis of bad template argument deductions."

This reverts commit a730f548325756d050d4caaa28fcbffdae8dfe95.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186729 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 7ebcd88..04aaf18 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -548,13 +548,13 @@
 }
 
 namespace {
-  // Structure used by DeductionFailureInfo to store
+  // Structure used by OverloadCandidate::DeductionFailureInfo to store
   // template argument information.
   struct DFIArguments {
     TemplateArgument FirstArg;
     TemplateArgument SecondArg;
   };
-  // Structure used by DeductionFailureInfo to store
+  // Structure used by OverloadCandidate::DeductionFailureInfo to store
   // template parameter and template argument information.
   struct DFIParamWithArguments : DFIArguments {
     TemplateParameter Param;
@@ -563,10 +563,11 @@
 
 /// \brief Convert from Sema's representation of template deduction information
 /// to the form used in overload-candidate information.
-DeductionFailureInfo MakeDeductionFailureInfo(ASTContext &Context,
-                                              Sema::TemplateDeductionResult TDK,
-                                              TemplateDeductionInfo &Info) {
-  DeductionFailureInfo Result;
+OverloadCandidate::DeductionFailureInfo
+static MakeDeductionFailureInfo(ASTContext &Context,
+                                Sema::TemplateDeductionResult TDK,
+                                TemplateDeductionInfo &Info) {
+  OverloadCandidate::DeductionFailureInfo Result;
   Result.Result = static_cast<unsigned>(TDK);
   Result.HasDiagnostic = false;
   Result.Data = 0;
@@ -624,7 +625,7 @@
   return Result;
 }
 
-void DeductionFailureInfo::Destroy() {
+void OverloadCandidate::DeductionFailureInfo::Destroy() {
   switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
   case Sema::TDK_Success:
   case Sema::TDK_Invalid:
@@ -658,13 +659,15 @@
   }
 }
 
-PartialDiagnosticAt *DeductionFailureInfo::getSFINAEDiagnostic() {
+PartialDiagnosticAt *
+OverloadCandidate::DeductionFailureInfo::getSFINAEDiagnostic() {
   if (HasDiagnostic)
     return static_cast<PartialDiagnosticAt*>(static_cast<void*>(Diagnostic));
   return 0;
 }
 
-TemplateParameter DeductionFailureInfo::getTemplateParameter() {
+TemplateParameter
+OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
   switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
   case Sema::TDK_Success:
   case Sema::TDK_Invalid:
@@ -692,7 +695,8 @@
   return TemplateParameter();
 }
 
-TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() {
+TemplateArgumentList *
+OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
   switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
   case Sema::TDK_Success:
   case Sema::TDK_Invalid:
@@ -718,7 +722,7 @@
   return 0;
 }
 
-const TemplateArgument *DeductionFailureInfo::getFirstArg() {
+const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
   switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
   case Sema::TDK_Success:
   case Sema::TDK_Invalid:
@@ -744,7 +748,8 @@
   return 0;
 }
 
-const TemplateArgument *DeductionFailureInfo::getSecondArg() {
+const TemplateArgument *
+OverloadCandidate::DeductionFailureInfo::getSecondArg() {
   switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
   case Sema::TDK_Success:
   case Sema::TDK_Invalid:
@@ -770,7 +775,8 @@
   return 0;
 }
 
-Expr *DeductionFailureInfo::getExpr() {
+Expr *
+OverloadCandidate::DeductionFailureInfo::getExpr() {
   if (static_cast<Sema::TemplateDeductionResult>(Result) ==
         Sema::TDK_FailedOverloadResolution)
     return static_cast<Expr*>(Data);
@@ -8122,7 +8128,7 @@
   return isTemplate ? oc_function_template : oc_function;
 }
 
-void MaybeEmitInheritedConstructorNote(Sema &S, Decl *Fn) {
+void MaybeEmitInheritedConstructorNote(Sema &S, FunctionDecl *Fn) {
   const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn);
   if (!Ctor) return;
 
@@ -8408,52 +8414,30 @@
   MaybeEmitInheritedConstructorNote(S, Fn);
 }
 
-/// Additional arity mismatch diagnosis specific to a function overload
-/// candidates. This is not covered by the more general DiagnoseArityMismatch()
-/// over a candidate in any candidate set.
-bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand,
-                        unsigned NumArgs) {
+void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand,
+                           unsigned NumFormalArgs) {
+  // TODO: treat calls to a missing default constructor as a special case
+
   FunctionDecl *Fn = Cand->Function;
+  const FunctionProtoType *FnTy = Fn->getType()->getAs<FunctionProtoType>();
+
   unsigned MinParams = Fn->getMinRequiredArguments();
 
   // With invalid overloaded operators, it's possible that we think we
-  // have an arity mismatch when in fact it looks like we have the
+  // have an arity mismatch when it fact it looks like we have the
   // right number of arguments, because only overloaded operators have
   // the weird behavior of overloading member and non-member functions.
   // Just don't report anything.
   if (Fn->isInvalidDecl() && 
       Fn->getDeclName().getNameKind() == DeclarationName::CXXOperatorName)
-    return true;
-
-  if (NumArgs < MinParams) {
-    assert((Cand->FailureKind == ovl_fail_too_few_arguments) ||
-           (Cand->FailureKind == ovl_fail_bad_deduction &&
-            Cand->DeductionFailure.Result == Sema::TDK_TooFewArguments));
-  } else {
-    assert((Cand->FailureKind == ovl_fail_too_many_arguments) ||
-           (Cand->FailureKind == ovl_fail_bad_deduction &&
-            Cand->DeductionFailure.Result == Sema::TDK_TooManyArguments));
-  }
-
-  return false;
-}
-
-/// General arity mismatch diagnosis over a candidate in a candidate set.
-void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) {
-  assert(isa<FunctionDecl>(D) &&
-      "The templated declaration should at least be a function"
-      " when diagnosing bad template argument deduction due to too many"
-      " or too few arguments");
-  
-  FunctionDecl *Fn = cast<FunctionDecl>(D);
-  
-  // TODO: treat calls to a missing default constructor as a special case
-  const FunctionProtoType *FnTy = Fn->getType()->getAs<FunctionProtoType>();
-  unsigned MinParams = Fn->getMinRequiredArguments();
+    return;
 
   // at least / at most / exactly
   unsigned mode, modeCount;
   if (NumFormalArgs < MinParams) {
+    assert((Cand->FailureKind == ovl_fail_too_few_arguments) ||
+           (Cand->FailureKind == ovl_fail_bad_deduction &&
+            Cand->DeductionFailure.Result == Sema::TDK_TooFewArguments));
     if (MinParams != FnTy->getNumArgs() ||
         FnTy->isVariadic() || FnTy->isTemplateVariadic())
       mode = 0; // "at least"
@@ -8461,6 +8445,9 @@
       mode = 2; // "exactly"
     modeCount = MinParams;
   } else {
+    assert((Cand->FailureKind == ovl_fail_too_many_arguments) ||
+           (Cand->FailureKind == ovl_fail_bad_deduction &&
+            Cand->DeductionFailure.Result == Sema::TDK_TooManyArguments));
     if (MinParams != FnTy->getNumArgs())
       mode = 1; // "at most"
     else
@@ -8482,42 +8469,25 @@
   MaybeEmitInheritedConstructorNote(S, Fn);
 }
 
-/// Arity mismatch diagnosis specific to a function overload candidate.
-void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand,
-                           unsigned NumFormalArgs) {
-  if (!CheckArityMismatch(S, Cand, NumFormalArgs))
-    DiagnoseArityMismatch(S, Cand->Function, NumFormalArgs);
-}
-
-TemplateDecl *getDescribedTemplate(Decl *Templated) {
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Templated))
-    return FD->getDescribedFunctionTemplate();
-  else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Templated))
-    return RD->getDescribedClassTemplate();
-
-  llvm_unreachable("Unsupported: Getting the described template declaration"
-                   " for bad deduction diagnosis");
-}
-
 /// Diagnose a failed template-argument deduction.
-void DiagnoseBadDeduction(Sema &S, Decl *Templated,
-                          DeductionFailureInfo &DeductionFailure,
+void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
                           unsigned NumArgs) {
-  TemplateParameter Param = DeductionFailure.getTemplateParameter();
+  FunctionDecl *Fn = Cand->Function; // pattern
+
+  TemplateParameter Param = Cand->DeductionFailure.getTemplateParameter();
   NamedDecl *ParamD;
   (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
   (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
   (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
-  switch (DeductionFailure.Result) {
+  switch (Cand->DeductionFailure.Result) {
   case Sema::TDK_Success:
     llvm_unreachable("TDK_success while diagnosing bad deduction");
 
   case Sema::TDK_Incomplete: {
     assert(ParamD && "no parameter found for incomplete deduction result");
-    S.Diag(Templated->getLocation(),
-           diag::note_ovl_candidate_incomplete_deduction)
-        << ParamD->getDeclName();
-    MaybeEmitInheritedConstructorNote(S, Templated);
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_incomplete_deduction)
+      << ParamD->getDeclName();
+    MaybeEmitInheritedConstructorNote(S, Fn);
     return;
   }
 
@@ -8525,7 +8495,7 @@
     assert(ParamD && "no parameter found for bad qualifiers deduction result");
     TemplateTypeParmDecl *TParam = cast<TemplateTypeParmDecl>(ParamD);
 
-    QualType Param = DeductionFailure.getFirstArg()->getAsType();
+    QualType Param = Cand->DeductionFailure.getFirstArg()->getAsType();
 
     // Param will have been canonicalized, but it should just be a
     // qualified version of ParamD, so move the qualifiers to that.
@@ -8538,11 +8508,11 @@
     // about that.  It also doesn't matter as much, because it won't
     // have any template parameters in it (because deduction isn't
     // done on dependent types).
-    QualType Arg = DeductionFailure.getSecondArg()->getAsType();
+    QualType Arg = Cand->DeductionFailure.getSecondArg()->getAsType();
 
-    S.Diag(Templated->getLocation(), diag::note_ovl_candidate_underqualified)
-        << ParamD->getDeclName() << Arg << NonCanonParam;
-    MaybeEmitInheritedConstructorNote(S, Templated);
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_underqualified)
+      << ParamD->getDeclName() << Arg << NonCanonParam;
+    MaybeEmitInheritedConstructorNote(S, Fn);
     return;
   }
 
@@ -8557,20 +8527,20 @@
       which = 2;
     }
 
-    S.Diag(Templated->getLocation(),
-           diag::note_ovl_candidate_inconsistent_deduction)
-        << which << ParamD->getDeclName() << *DeductionFailure.getFirstArg()
-        << *DeductionFailure.getSecondArg();
-    MaybeEmitInheritedConstructorNote(S, Templated);
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_inconsistent_deduction)
+      << which << ParamD->getDeclName()
+      << *Cand->DeductionFailure.getFirstArg()
+      << *Cand->DeductionFailure.getSecondArg();
+    MaybeEmitInheritedConstructorNote(S, Fn);
     return;
   }
 
   case Sema::TDK_InvalidExplicitArguments:
     assert(ParamD && "no parameter found for invalid explicit arguments");
     if (ParamD->getDeclName())
-      S.Diag(Templated->getLocation(),
+      S.Diag(Fn->getLocation(),
              diag::note_ovl_candidate_explicit_arg_mismatch_named)
-          << ParamD->getDeclName();
+        << ParamD->getDeclName();
     else {
       int index = 0;
       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
@@ -8580,36 +8550,35 @@
         index = NTTP->getIndex();
       else
         index = cast<TemplateTemplateParmDecl>(ParamD)->getIndex();
-      S.Diag(Templated->getLocation(),
+      S.Diag(Fn->getLocation(),
              diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
-          << (index + 1);
+        << (index + 1);
     }
-    MaybeEmitInheritedConstructorNote(S, Templated);
+    MaybeEmitInheritedConstructorNote(S, Fn);
     return;
 
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
-    DiagnoseArityMismatch(S, Templated, NumArgs);
+    DiagnoseArityMismatch(S, Cand, NumArgs);
     return;
 
   case Sema::TDK_InstantiationDepth:
-    S.Diag(Templated->getLocation(),
-           diag::note_ovl_candidate_instantiation_depth);
-    MaybeEmitInheritedConstructorNote(S, Templated);
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_instantiation_depth);
+    MaybeEmitInheritedConstructorNote(S, Fn);
     return;
 
   case Sema::TDK_SubstitutionFailure: {
     // Format the template argument list into the argument string.
     SmallString<128> TemplateArgString;
     if (TemplateArgumentList *Args =
-            DeductionFailure.getTemplateArgumentList()) {
+          Cand->DeductionFailure.getTemplateArgumentList()) {
       TemplateArgString = " ";
       TemplateArgString += S.getTemplateArgumentBindingsText(
-          getDescribedTemplate(Templated)->getTemplateParameters(), *Args);
+          Fn->getDescribedFunctionTemplate()->getTemplateParameters(), *Args);
     }
 
     // If this candidate was disabled by enable_if, say so.
-    PartialDiagnosticAt *PDiag = DeductionFailure.getSFINAEDiagnostic();
+    PartialDiagnosticAt *PDiag = Cand->DeductionFailure.getSFINAEDiagnostic();
     if (PDiag && PDiag->second.getDiagID() ==
           diag::err_typename_nested_not_found_enable_if) {
       // FIXME: Use the source range of the condition, and the fully-qualified
@@ -8630,25 +8599,25 @@
       PDiag->second.EmitToString(S.getDiagnostics(), SFINAEArgString);
     }
 
-    S.Diag(Templated->getLocation(),
-           diag::note_ovl_candidate_substitution_failure)
-        << TemplateArgString << SFINAEArgString << R;
-    MaybeEmitInheritedConstructorNote(S, Templated);
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_substitution_failure)
+      << TemplateArgString << SFINAEArgString << R;
+    MaybeEmitInheritedConstructorNote(S, Fn);
     return;
   }
 
   case Sema::TDK_FailedOverloadResolution: {
-    OverloadExpr::FindResult R = OverloadExpr::find(DeductionFailure.getExpr());
-    S.Diag(Templated->getLocation(),
+    OverloadExpr::FindResult R =
+        OverloadExpr::find(Cand->DeductionFailure.getExpr());
+    S.Diag(Fn->getLocation(),
            diag::note_ovl_candidate_failed_overload_resolution)
-        << R.Expression->getName();
+      << R.Expression->getName();
     return;
   }
 
   case Sema::TDK_NonDeducedMismatch: {
     // FIXME: Provide a source location to indicate what we couldn't match.
-    TemplateArgument FirstTA = *DeductionFailure.getFirstArg();
-    TemplateArgument SecondTA = *DeductionFailure.getSecondArg();
+    TemplateArgument FirstTA = *Cand->DeductionFailure.getFirstArg();
+    TemplateArgument SecondTA = *Cand->DeductionFailure.getSecondArg();
     if (FirstTA.getKind() == TemplateArgument::Template &&
         SecondTA.getKind() == TemplateArgument::Template) {
       TemplateName FirstTN = FirstTA.getAsTemplate();
@@ -8663,38 +8632,26 @@
           // 2) The diagnostic printer only attempts to find a better
           //    name for types, not decls.
           // Ideally, this should folded into the diagnostic printer.
-          S.Diag(Templated->getLocation(),
+          S.Diag(Fn->getLocation(),
                  diag::note_ovl_candidate_non_deduced_mismatch_qualified)
               << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl();
           return;
         }
       }
     }
-    S.Diag(Templated->getLocation(),
-           diag::note_ovl_candidate_non_deduced_mismatch)
-        << FirstTA << SecondTA;
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch)
+      << FirstTA << SecondTA;
     return;
   }
   // TODO: diagnose these individually, then kill off
   // note_ovl_candidate_bad_deduction, which is uselessly vague.
   case Sema::TDK_MiscellaneousDeductionFailure:
-    S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_deduction);
-    MaybeEmitInheritedConstructorNote(S, Templated);
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction);
+    MaybeEmitInheritedConstructorNote(S, Fn);
     return;
   }
 }
 
-/// Diagnose a failed template-argument deduction, for function calls.
-void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, unsigned NumArgs) {
-  unsigned TDK = Cand->DeductionFailure.Result;
-  if (TDK == Sema::TDK_TooFewArguments || TDK == Sema::TDK_TooManyArguments) {
-    if (CheckArityMismatch(S, Cand, NumArgs))
-      return;
-  }
-  DiagnoseBadDeduction(S, Cand->Function, // pattern
-                       Cand->DeductionFailure, NumArgs);
-}
-
 /// CUDA: diagnose an invalid call across targets.
 void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {
   FunctionDecl *Caller = cast<FunctionDecl>(S.CurContext);
@@ -8842,7 +8799,7 @@
   }
 }
 
-static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) {
+SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) {
   if (Cand->Function)
     return Cand->Function->getLocation();
   if (Cand->IsSurrogate)
@@ -8850,7 +8807,8 @@
   return SourceLocation();
 }
 
-static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) {
+static unsigned
+RankDeductionFailure(const OverloadCandidate::DeductionFailureInfo &DFI) {
   switch ((Sema::TemplateDeductionResult)DFI.Result) {
   case Sema::TDK_Success:
     llvm_unreachable("TDK_success while diagnosing bad deduction");
@@ -9143,108 +9101,6 @@
     S.Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I);
 }
 
-static SourceLocation
-GetLocationForCandidate(const TemplateSpecCandidate *Cand) {
-  return Cand->Specialization ? Cand->Specialization->getLocation()
-                              : SourceLocation();
-}
-
-struct CompareTemplateSpecCandidatesForDisplay {
-  Sema &S;
-  CompareTemplateSpecCandidatesForDisplay(Sema &S) : S(S) {}
-
-  bool operator()(const TemplateSpecCandidate *L,
-                  const TemplateSpecCandidate *R) {
-    // Fast-path this check.
-    if (L == R)
-      return false;
-
-    // Assuming that both candidates are not matches...
-
-    // Sort by the ranking of deduction failures.
-    if (L->DeductionFailure.Result != R->DeductionFailure.Result)
-      return RankDeductionFailure(L->DeductionFailure) <
-             RankDeductionFailure(R->DeductionFailure);
-
-    // Sort everything else by location.
-    SourceLocation LLoc = GetLocationForCandidate(L);
-    SourceLocation RLoc = GetLocationForCandidate(R);
-
-    // Put candidates without locations (e.g. builtins) at the end.
-    if (LLoc.isInvalid())
-      return false;
-    if (RLoc.isInvalid())
-      return true;
-
-    return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc);
-  }
-};
-
-/// Diagnose a template argument deduction failure.
-/// We are treating these failures as overload failures due to bad
-/// deductions.
-void TemplateSpecCandidate::NoteDeductionFailure(Sema &S) {
-  DiagnoseBadDeduction(S, Specialization, // pattern
-                       DeductionFailure, /*NumArgs=*/0);
-}
-
-void TemplateSpecCandidateSet::destroyCandidates() {
-  for (iterator i = begin(), e = end(); i != e; ++i) {
-    i->DeductionFailure.Destroy();
-  }
-}
-
-void TemplateSpecCandidateSet::clear() {
-  destroyCandidates();
-  Candidates.clear();
-}
-
-/// NoteCandidates - When no template specialization match is found, prints
-/// diagnostic messages containing the non-matching specializations that form
-/// the candidate set.
-/// This is analoguous to OverloadCandidateSet::NoteCandidates() with
-/// OCD == OCD_AllCandidates and Cand->Viable == false.
-void TemplateSpecCandidateSet::NoteCandidates(Sema &S, SourceLocation Loc) {
-  // Sort the candidates by position (assuming no candidate is a match).
-  // Sorting directly would be prohibitive, so we make a set of pointers
-  // and sort those.
-  SmallVector<TemplateSpecCandidate *, 32> Cands;
-  Cands.reserve(size());
-  for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) {
-    if (Cand->Specialization)
-      Cands.push_back(Cand);
-    // Otherwise, this is a non matching builtin candidate.  We do not,
-    // in general, want to list every possible builtin candidate.
-  }
-
-  std::sort(Cands.begin(), Cands.end(),
-            CompareTemplateSpecCandidatesForDisplay(S));
-
-  // FIXME: Perhaps rename OverloadsShown and getShowOverloads()
-  // for generalization purposes (?).
-  const OverloadsShown ShowOverloads = S.Diags.getShowOverloads();
-
-  SmallVectorImpl<TemplateSpecCandidate *>::iterator I, E;
-  unsigned CandsShown = 0;
-  for (I = Cands.begin(), E = Cands.end(); I != E; ++I) {
-    TemplateSpecCandidate *Cand = *I;
-
-    // Set an arbitrary limit on the number of candidates we'll spam
-    // the user with.  FIXME: This limit should depend on details of the
-    // candidate list.
-    if (CandsShown >= 4 && ShowOverloads == Ovl_Best)
-      break;
-    ++CandsShown;
-
-    assert(Cand->Specialization &&
-           "Non-matching built-in candidates are not added to Cands.");
-    Cand->NoteDeductionFailure(S);
-  }
-
-  if (I != E)
-    S.Diag(Loc, diag::note_ovl_too_many_candidates) << int(E - I);
-}
-
 // [PossiblyAFunctionType]  -->   [Return]
 // NonFunctionType --> NonFunctionType
 // R (A) --> R(A)
@@ -9287,19 +9143,18 @@
   OverloadExpr *OvlExpr;
   TemplateArgumentListInfo OvlExplicitTemplateArgs;
   SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
-  TemplateSpecCandidateSet FailedCandidates;
 
 public:
-  AddressOfFunctionResolver(Sema &S, Expr *SourceExpr,
-                            const QualType &TargetType, bool Complain)
-      : S(S), SourceExpr(SourceExpr), TargetType(TargetType),
-        Complain(Complain), Context(S.getASTContext()),
-        TargetTypeIsNonStaticMemberFunction(
-            !!TargetType->getAs<MemberPointerType>()),
-        FoundNonTemplateFunction(false),
-        OvlExprInfo(OverloadExpr::find(SourceExpr)),
-        OvlExpr(OvlExprInfo.Expression),
-        FailedCandidates(OvlExpr->getNameLoc()) {
+  AddressOfFunctionResolver(Sema &S, Expr* SourceExpr, 
+                            const QualType& TargetType, bool Complain)
+    : S(S), SourceExpr(SourceExpr), TargetType(TargetType), 
+      Complain(Complain), Context(S.getASTContext()), 
+      TargetTypeIsNonStaticMemberFunction(
+                                    !!TargetType->getAs<MemberPointerType>()),
+      FoundNonTemplateFunction(false),
+      OvlExprInfo(OverloadExpr::find(SourceExpr)),
+      OvlExpr(OvlExprInfo.Expression)
+  {
     ExtractUnqualifiedFunctionTypeFromTargetType();
     
     if (!TargetFunctionType->isFunctionType()) {        
@@ -9377,16 +9232,13 @@
     //   function template specialization, which is added to the set of
     //   overloaded functions considered.
     FunctionDecl *Specialization = 0;
-    TemplateDeductionInfo Info(FailedCandidates.getLocation());
+    TemplateDeductionInfo Info(OvlExpr->getNameLoc());
     if (Sema::TemplateDeductionResult Result
           = S.DeduceTemplateArguments(FunctionTemplate, 
                                       &OvlExplicitTemplateArgs,
                                       TargetFunctionType, Specialization, 
                                       Info, /*InOverloadResolution=*/true)) {
-      // Make a note of the failed deduction for diagnostics.
-      FailedCandidates.addCandidate()
-          .set(FunctionTemplate->getTemplatedDecl(),
-               MakeDeductionFailureInfo(Context, Result, Info));
+      // FIXME: make a note of the failed deduction for diagnostics.
       (void)Result;
       return false;
     } 
@@ -9491,15 +9343,15 @@
     for (unsigned I = 0, E = Matches.size(); I != E; ++I)
       MatchesCopy.addDecl(Matches[I].second, Matches[I].first.getAccess());
 
-    // TODO: It looks like FailedCandidates does not serve much purpose
-    // here, since the no_viable diagnostic has index 0.
-    UnresolvedSetIterator Result = S.getMostSpecialized(
-        MatchesCopy.begin(), MatchesCopy.end(), FailedCandidates, TPOC_Other, 0,
-        SourceExpr->getLocStart(), S.PDiag(),
-        S.PDiag(diag::err_addr_ovl_ambiguous) << Matches[0]
-                                                     .second->getDeclName(),
-        S.PDiag(diag::note_ovl_candidate) << (unsigned)oc_function_template,
-        Complain, TargetFunctionType);
+    UnresolvedSetIterator Result =
+      S.getMostSpecialized(MatchesCopy.begin(), MatchesCopy.end(),
+                           TPOC_Other, 0, SourceExpr->getLocStart(),
+                           S.PDiag(),
+                           S.PDiag(diag::err_addr_ovl_ambiguous)
+                             << Matches[0].second->getDeclName(),
+                           S.PDiag(diag::note_ovl_candidate)
+                             << (unsigned) oc_function_template,
+                           Complain, TargetFunctionType);
 
     if (Result != MatchesCopy.end()) {
       // Make it the first and only element
@@ -9528,7 +9380,6 @@
     S.Diag(OvlExpr->getLocStart(), diag::err_addr_ovl_no_viable)
         << OvlExpr->getName() << TargetFunctionType
         << OvlExpr->getSourceRange();
-    FailedCandidates.NoteCandidates(S, OvlExpr->getLocStart());
     S.NoteAllOverloadCandidates(OvlExpr, TargetFunctionType);
   } 
   
@@ -9645,7 +9496,6 @@
 
   TemplateArgumentListInfo ExplicitTemplateArgs;
   ovl->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs);
-  TemplateSpecCandidateSet FailedCandidates(ovl->getNameLoc());
 
   // Look through all of the overloaded functions, searching for one
   // whose type matches exactly.
@@ -9668,16 +9518,12 @@
     //   function template specialization, which is added to the set of
     //   overloaded functions considered.
     FunctionDecl *Specialization = 0;
-    TemplateDeductionInfo Info(FailedCandidates.getLocation());
+    TemplateDeductionInfo Info(ovl->getNameLoc());
     if (TemplateDeductionResult Result
           = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs,
                                     Specialization, Info,
                                     /*InOverloadResolution=*/true)) {
-      // Make a note of the failed deduction for diagnostics.
-      // TODO: Actually use the failed-deduction info?
-      FailedCandidates.addCandidate()
-          .set(FunctionTemplate->getTemplatedDecl(),
-               MakeDeductionFailureInfo(Context, Result, Info));
+      // FIXME: make a note of the failed deduction for diagnostics.
       (void)Result;
       continue;
     }
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 7939c48..6f1ab19 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -5925,13 +5925,13 @@
 ///
 /// \param Previous the set of declarations that may be specialized by
 /// this function specialization.
-bool Sema::CheckFunctionTemplateSpecialization(
-    FunctionDecl *FD, TemplateArgumentListInfo *ExplicitTemplateArgs,
-    LookupResult &Previous) {
+bool
+Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
+                                 TemplateArgumentListInfo *ExplicitTemplateArgs,
+                                          LookupResult &Previous) {
   // The set of function template specializations that could match this
   // explicit function template specialization.
   UnresolvedSet<8> Candidates;
-  TemplateSpecCandidateSet FailedCandidates(FD->getLocation());
 
   DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
   for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
@@ -5969,16 +5969,13 @@
       // Perform template argument deduction to determine whether we may be
       // specializing this template.
       // FIXME: It is somewhat wasteful to build
-      TemplateDeductionInfo Info(FailedCandidates.getLocation());
+      TemplateDeductionInfo Info(FD->getLocation());
       FunctionDecl *Specialization = 0;
       if (TemplateDeductionResult TDK
             = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs, FT,
                                       Specialization, Info)) {
-        // Template argument deduction failed; record why it failed, so
+        // FIXME: Template argument deduction failed; record why it failed, so
         // that we can provide nifty diagnostics.
-        FailedCandidates.addCandidate()
-            .set(FunTmpl->getTemplatedDecl(),
-                 MakeDeductionFailureInfo(Context, TDK, Info));
         (void)TDK;
         continue;
       }
@@ -5989,14 +5986,14 @@
   }
 
   // Find the most specialized function template.
-  UnresolvedSetIterator Result = getMostSpecialized(
-      Candidates.begin(), Candidates.end(), FailedCandidates, TPOC_Other, 0,
-      FD->getLocation(),
-      PDiag(diag::err_function_template_spec_no_match) << FD->getDeclName(),
-      PDiag(diag::err_function_template_spec_ambiguous)
-          << FD->getDeclName() << (ExplicitTemplateArgs != 0),
-      PDiag(diag::note_function_template_spec_matched));
-
+  UnresolvedSetIterator Result
+    = getMostSpecialized(Candidates.begin(), Candidates.end(),
+                         TPOC_Other, 0, FD->getLocation(),
+                  PDiag(diag::err_function_template_spec_no_match)
+                    << FD->getDeclName(),
+                  PDiag(diag::err_function_template_spec_ambiguous)
+                    << FD->getDeclName() << (ExplicitTemplateArgs != 0),
+                  PDiag(diag::note_function_template_spec_matched));
   if (Result == Candidates.end())
     return true;
 
@@ -6815,7 +6812,6 @@
   //  instantiated from the member definition associated with its class
   //  template.
   UnresolvedSet<8> Matches;
-  TemplateSpecCandidateSet FailedCandidates(D.getIdentifierLoc());
   for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
        P != PEnd; ++P) {
     NamedDecl *Prev = *P;
@@ -6835,16 +6831,13 @@
     if (!FunTmpl)
       continue;
 
-    TemplateDeductionInfo Info(FailedCandidates.getLocation());
+    TemplateDeductionInfo Info(D.getIdentifierLoc());
     FunctionDecl *Specialization = 0;
     if (TemplateDeductionResult TDK
           = DeduceTemplateArguments(FunTmpl,
                                (HasExplicitTemplateArgs ? &TemplateArgs : 0),
                                     R, Specialization, Info)) {
-      // Keep track of almost-matches.
-      FailedCandidates.addCandidate()
-          .set(FunTmpl->getTemplatedDecl(),
-               MakeDeductionFailureInfo(Context, TDK, Info));
+      // FIXME: Keep track of almost-matches?
       (void)TDK;
       continue;
     }
@@ -6853,12 +6846,12 @@
   }
 
   // Find the most specialized function template specialization.
-  UnresolvedSetIterator Result = getMostSpecialized(
-      Matches.begin(), Matches.end(), FailedCandidates, TPOC_Other, 0,
-      D.getIdentifierLoc(),
-      PDiag(diag::err_explicit_instantiation_not_known) << Name,
-      PDiag(diag::err_explicit_instantiation_ambiguous) << Name,
-      PDiag(diag::note_explicit_instantiation_candidate));
+  UnresolvedSetIterator Result
+    = getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, 0,
+                         D.getIdentifierLoc(),
+                     PDiag(diag::err_explicit_instantiation_not_known) << Name,
+                     PDiag(diag::err_explicit_instantiation_ambiguous) << Name,
+                         PDiag(diag::note_explicit_instantiation_candidate));
 
   if (Result == Matches.end())
     return true;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 8d6aaa0..29ee6df 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -4148,18 +4148,23 @@
 ///
 /// \returns the most specialized function template specialization, if
 /// found. Otherwise, returns SpecEnd.
-UnresolvedSetIterator Sema::getMostSpecialized(
-    UnresolvedSetIterator SpecBegin, UnresolvedSetIterator SpecEnd,
-    TemplateSpecCandidateSet &FailedCandidates,
-    TemplatePartialOrderingContext TPOC, unsigned NumCallArguments,
-    SourceLocation Loc, const PartialDiagnostic &NoneDiag,
-    const PartialDiagnostic &AmbigDiag, const PartialDiagnostic &CandidateDiag,
-    bool Complain, QualType TargetType) {
+///
+/// \todo FIXME: Consider passing in the "also-ran" candidates that failed
+/// template argument deduction.
+UnresolvedSetIterator
+Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin,
+                         UnresolvedSetIterator SpecEnd,
+                         TemplatePartialOrderingContext TPOC,
+                         unsigned NumCallArguments,
+                         SourceLocation Loc,
+                         const PartialDiagnostic &NoneDiag,
+                         const PartialDiagnostic &AmbigDiag,
+                         const PartialDiagnostic &CandidateDiag,
+                         bool Complain,
+                         QualType TargetType) {
   if (SpecBegin == SpecEnd) {
-    if (Complain) {
+    if (Complain)
       Diag(Loc, NoneDiag);
-      FailedCandidates.NoteCandidates(*this, Loc);
-    }
     return SpecEnd;
   }
 
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 7632bba..3904daa 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2252,18 +2252,15 @@
   SmallVector<MatchResult, 4> Matched;
   SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
   Template->getPartialSpecializations(PartialSpecs);
-  TemplateSpecCandidateSet FailedCandidates(PointOfInstantiation);
   for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
     ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
-    TemplateDeductionInfo Info(FailedCandidates.getLocation());
+    TemplateDeductionInfo Info(PointOfInstantiation);
     if (TemplateDeductionResult Result
           = DeduceTemplateArguments(Partial,
                                     ClassTemplateSpec->getTemplateArgs(),
                                     Info)) {
-      // Store the failed-deduction information for use in diagnostics, later.
-      // TODO: Actually use the failed-deduction info?
-      FailedCandidates.addCandidate()
-          .set(Partial, MakeDeductionFailureInfo(Context, Result, Info));
+      // FIXME: Store the failed-deduction information for use in
+      // diagnostics, later.
       (void)Result;
     } else {
       Matched.push_back(PartialSpecMatchResult());