https://github.com/cor3ntin created 
https://github.com/llvm/llvm-project/pull/135993

Reverts llvm/llvm-project#133426

This is failing on some bots 
https://lab.llvm.org/buildbot/#/builders/163/builds/17265

>From 2586e26ebaaf967c441651a736b740bc2113ecc1 Mon Sep 17 00:00:00 2001
From: cor3ntin <corentinja...@gmail.com>
Date: Wed, 16 Apr 2025 19:39:15 +0200
Subject: [PATCH] =?UTF-8?q?Revert=20"[Clang][RFC]=20Bypass=20TAD=20during?=
 =?UTF-8?q?=20overload=20resolution=20if=20a=20perfect=20match=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit facc57fc25d0f05f5834fed421662dbad3ec5b50.
---
 clang/docs/ReleaseNotes.rst                   |   6 -
 clang/include/clang/Sema/Overload.h           | 224 +-------
 clang/lib/Sema/SemaCodeComplete.cpp           |   6 +-
 clang/lib/Sema/SemaInit.cpp                   |  15 +-
 clang/lib/Sema/SemaOverload.cpp               | 522 ++++--------------
 clang/lib/Sema/SemaTemplateDeduction.cpp      |   4 +-
 .../constrant-satisfaction-conversions.cpp    |   8 +-
 clang/test/SemaCUDA/function-overload.cu      |   3 +
 .../SemaCXX/implicit-member-functions.cpp     |  21 +-
 ...overload-resolution-deferred-templates.cpp | 185 -------
 .../instantiate-function-params.cpp           |   7 +-
 .../Templight/templight-empty-entries-fix.cpp | 126 +++--
 12 files changed, 217 insertions(+), 910 deletions(-)
 delete mode 100644 
clang/test/SemaCXX/overload-resolution-deferred-templates.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index acbc9c5a6fac9..0891fd058bb57 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -96,12 +96,6 @@ C++ Language Changes
       asm((std::string_view("nop")) ::: (std::string_view("memory")));
     }
 
-- Clang now implements the changes to overload resolution proposed by section 
1 and 2 of
-  `P3606 <https://wg21.link/P3606R0>`_. If a non-template candidate exists in 
an overload set that is
-  a perfect match (all conversion sequences are identity conversions) template 
candiates are not instantiated.
-  Diagnostics that would have resulted from the instantiation of these 
template candidates are no longer
-  produced. This aligns Clang closer to the behavior of GCC, and fixes 
(#GH62096), (#GH74581), and (#GH74581).
-
 C++2c Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index 813811af06e89..6e08762dcc6d7 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -407,24 +407,6 @@ class Sema;
              Third == ICK_Identity;
     }
 
-    /// A conversion sequence is perfect if it is an identity conversion and
-    /// the type of the source is the same as the type of the target.
-    bool isPerfect(const ASTContext &C) const {
-      if (!isIdentityConversion())
-        return false;
-      // If we are not performing a reference binding, we can skip comparing
-      // the types, which has a noticeable performance impact.
-      if (!ReferenceBinding) {
-        assert(First || C.hasSameUnqualifiedType(getFromType(), getToType(2)));
-        return true;
-      }
-      if (!C.hasSameType(getFromType(), getToType(2)))
-        return false;
-      if (BindsToRvalue && IsLvalueReference)
-        return false;
-      return true;
-    }
-
     ImplicitConversionRank getRank() const;
     NarrowingKind
     getNarrowingKind(ASTContext &Context, const Expr *Converted,
@@ -761,12 +743,6 @@ class Sema;
       Standard.setAllToTypes(T);
     }
 
-    /// A conversion sequence is perfect if it is an identity conversion and
-    /// the type of the source is the same as the type of the target.
-    bool isPerfect(const ASTContext &C) const {
-      return isStandard() && Standard.isPerfect(C);
-    }
-
     // True iff this is a conversion sequence from an initializer list to an
     // array or std::initializer.
     bool hasInitializerListContainerType() const {
@@ -1003,20 +979,6 @@ class Sema;
       return false;
     }
 
-    // An overload is a perfect match if the conversion
-    // sequences for each argument are perfect.
-    bool isPerfectMatch(const ASTContext &Ctx) const {
-      if (!Viable)
-        return false;
-      for (const auto &C : Conversions) {
-        if (!C.isInitialized() || !C.isPerfect(Ctx))
-          return false;
-      }
-      if (isa_and_nonnull<CXXConversionDecl>(Function))
-        return FinalConversion.isPerfect(Ctx);
-      return true;
-    }
-
     bool TryToFixBadConversion(unsigned Idx, Sema &S) {
       bool CanFix = Fix.tryToFixConversion(
                       Conversions[Idx].Bad.FromExpr,
@@ -1053,65 +1015,6 @@ class Sema;
           RewriteKind(CRK_None) {}
   };
 
-  struct DeferredTemplateOverloadCandidate {
-
-    // intrusive linked list support for allocateDeferredCandidate
-    DeferredTemplateOverloadCandidate *Next = nullptr;
-
-    enum Kind { Function, Method, Conversion };
-
-    LLVM_PREFERRED_TYPE(Kind)
-    unsigned Kind : 2;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned AllowObjCConversionOnExplicit : 1;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned AllowResultConversion : 1;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned AllowExplicit : 1;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned SuppressUserConversions : 1;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned PartialOverloading : 1;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned AggregateCandidateDeduction : 1;
-  };
-
-  struct DeferredFunctionTemplateOverloadCandidate
-      : public DeferredTemplateOverloadCandidate {
-    FunctionTemplateDecl *FunctionTemplate;
-    DeclAccessPair FoundDecl;
-    ArrayRef<Expr *> Args;
-    CallExpr::ADLCallKind IsADLCandidate;
-    OverloadCandidateParamOrder PO;
-  };
-  static_assert(std::is_trivially_destructible_v<
-                DeferredFunctionTemplateOverloadCandidate>);
-
-  struct DeferredMethodTemplateOverloadCandidate
-      : public DeferredTemplateOverloadCandidate {
-    FunctionTemplateDecl *FunctionTemplate;
-    DeclAccessPair FoundDecl;
-    ArrayRef<Expr *> Args;
-    CXXRecordDecl *ActingContext;
-    Expr::Classification ObjectClassification;
-    QualType ObjectType;
-    OverloadCandidateParamOrder PO;
-  };
-  static_assert(std::is_trivially_destructible_v<
-                DeferredMethodTemplateOverloadCandidate>);
-
-  struct DeferredConversionTemplateOverloadCandidate
-      : public DeferredTemplateOverloadCandidate {
-    FunctionTemplateDecl *FunctionTemplate;
-    DeclAccessPair FoundDecl;
-    CXXRecordDecl *ActingContext;
-    Expr *From;
-    QualType ToType;
-  };
-
-  static_assert(std::is_trivially_destructible_v<
-                DeferredConversionTemplateOverloadCandidate>);
-
   /// OverloadCandidateSet - A set of overload candidates, used in C++
   /// overload resolution (C++ 13.3).
   class OverloadCandidateSet {
@@ -1140,11 +1043,6 @@ class Sema;
       /// C++ [over.match.call.general]
       /// Resolve a call through the address of an overload set.
       CSK_AddressOfOverloadSet,
-
-      /// When doing overload resolution during code completion,
-      /// we want to show all viable candidates, including otherwise
-      /// deferred template candidates.
-      CSK_CodeCompletion,
     };
 
     /// Information about operator rewrites to consider when adding operator
@@ -1219,15 +1117,7 @@ class Sema;
     SmallVector<OverloadCandidate, 16> Candidates;
     llvm::SmallPtrSet<uintptr_t, 16> Functions;
 
-    DeferredTemplateOverloadCandidate *FirstDeferredCandidate = nullptr;
-    unsigned DeferredCandidatesCount : 8 * sizeof(unsigned) - 2;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned HasDeferredTemplateConstructors : 1;
-    LLVM_PREFERRED_TYPE(bool)
-    unsigned ResolutionByPerfectCandidateIsDisabled : 1;
-
-    // Allocator for ConversionSequenceLists and deferred candidate args.
-    // We store the first few of these
+    // Allocator for ConversionSequenceLists. We store the first few of these
     // inline to avoid allocation for small sets.
     llvm::BumpPtrAllocator SlabAllocator;
 
@@ -1235,11 +1125,8 @@ class Sema;
     CandidateSetKind Kind;
     OperatorRewriteInfo RewriteInfo;
 
-    /// Small storage size for ImplicitConversionSequences
-    /// and the persisted arguments of deferred candidates.
     constexpr static unsigned NumInlineBytes =
-        32 * sizeof(ImplicitConversionSequence);
-
+        24 * sizeof(ImplicitConversionSequence);
     unsigned NumInlineBytesUsed = 0;
     alignas(void *) char InlineSpace[NumInlineBytes];
 
@@ -1250,13 +1137,15 @@ class Sema;
     /// from the slab allocator.
     /// FIXME: It would probably be nice to have a SmallBumpPtrAllocator
     /// instead.
+    /// FIXME: Now that this only allocates ImplicitConversionSequences, do we
+    /// want to un-generalize this?
     template <typename T>
     T *slabAllocate(unsigned N) {
       // It's simpler if this doesn't need to consider alignment.
       static_assert(alignof(T) == alignof(void *),
                     "Only works for pointer-aligned types.");
-      static_assert(std::is_trivially_destructible_v<T> ||
-                        (std::is_same_v<ImplicitConversionSequence, T>),
+      static_assert(std::is_trivial<T>::value ||
+                        std::is_same<ImplicitConversionSequence, T>::value,
                     "Add destruction logic to OverloadCandidateSet::clear().");
 
       unsigned NBytes = sizeof(T) * N;
@@ -1270,34 +1159,12 @@ class Sema;
       return reinterpret_cast<T *>(FreeSpaceStart);
     }
 
-    // Because the size of OverloadCandidateSet has a noticeable impact on
-    // performance, we store each deferred template candidate in the slab
-    // allocator such that deferred candidates are ultimately a singly-linked
-    // intrusive linked list. This ends up being much more efficient than a
-    // SmallVector that is empty in the common case.
-    template <typename T> T *allocateDeferredCandidate() {
-      T *C = slabAllocate<T>(1);
-      if (!FirstDeferredCandidate)
-        FirstDeferredCandidate = C;
-      else {
-        auto *F = FirstDeferredCandidate;
-        while (F->Next)
-          F = F->Next;
-        F->Next = C;
-      }
-      DeferredCandidatesCount++;
-      return C;
-    }
-
     void destroyCandidates();
 
   public:
     OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK,
                          OperatorRewriteInfo RewriteInfo = {})
-        : FirstDeferredCandidate(nullptr), DeferredCandidatesCount(0),
-          HasDeferredTemplateConstructors(false),
-          ResolutionByPerfectCandidateIsDisabled(false), Loc(Loc), Kind(CSK),
-          RewriteInfo(RewriteInfo) {}
+        : Loc(Loc), Kind(CSK), RewriteInfo(RewriteInfo) {}
     OverloadCandidateSet(const OverloadCandidateSet &) = delete;
     OverloadCandidateSet &operator=(const OverloadCandidateSet &) = delete;
     ~OverloadCandidateSet() { destroyCandidates(); }
@@ -1309,9 +1176,6 @@ class Sema;
     /// Whether diagnostics should be deferred.
     bool shouldDeferDiags(Sema &S, ArrayRef<Expr *> Args, SourceLocation 
OpLoc);
 
-    // Whether the resolution of template candidates should be deferred
-    bool shouldDeferTemplateArgumentDeduction(const LangOptions &Opts) const;
-
     /// Determine when this overload candidate will be new to the
     /// overload set.
     bool isNewCandidate(Decl *F, OverloadCandidateParamOrder PO =
@@ -1335,10 +1199,8 @@ class Sema;
     iterator begin() { return Candidates.begin(); }
     iterator end() { return Candidates.end(); }
 
-    size_t size() const { return Candidates.size() + DeferredCandidatesCount; }
-    bool empty() const {
-      return Candidates.empty() && DeferredCandidatesCount == 0;
-    }
+    size_t size() const { return Candidates.size(); }
+    bool empty() const { return Candidates.empty(); }
 
     /// Allocate storage for conversion sequences for NumConversions
     /// conversions.
@@ -1354,24 +1216,6 @@ class Sema;
       return ConversionSequenceList(Conversions, NumConversions);
     }
 
-    /// Provide storage for any Expr* arg that must be preserved
-    /// until deferred template candidates are deduced.
-    /// Typically this should be used for reversed operator arguments
-    /// and any time the argument array is transformed while adding
-    /// a template candidate.
-    llvm::MutableArrayRef<Expr *> getPersistentArgsArray(unsigned N) {
-      Expr **Exprs = slabAllocate<Expr *>(N);
-      return llvm::MutableArrayRef<Expr *>(Exprs, N);
-    }
-
-    template <typename... T>
-    llvm::MutableArrayRef<Expr *> getPersistentArgsArray(T *...Exprs) {
-      llvm::MutableArrayRef<Expr *> Arr =
-          getPersistentArgsArray(sizeof...(Exprs));
-      llvm::copy(std::initializer_list<Expr *>{Exprs...}, Arr.data());
-      return Arr;
-    }
-
     /// Add a new candidate with NumConversions conversion sequence slots
     /// to the overload set.
     OverloadCandidate &addCandidate(unsigned NumConversions = 0,
@@ -1387,32 +1231,6 @@ class Sema;
       return C;
     }
 
-    void AddDeferredTemplateCandidate(
-        FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-        ArrayRef<Expr *> Args, bool SuppressUserConversions,
-        bool PartialOverloading, bool AllowExplicit,
-        CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
-        bool AggregateCandidateDeduction);
-
-    void AddDeferredMethodTemplateCandidate(
-        FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl,
-        CXXRecordDecl *ActingContext, QualType ObjectType,
-        Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
-        bool SuppressUserConversions, bool PartialOverloading,
-        OverloadCandidateParamOrder PO);
-
-    void AddDeferredConversionTemplateCandidate(
-        FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-        CXXRecordDecl *ActingContext, Expr *From, QualType ToType,
-        bool AllowObjCConversionOnExplicit, bool AllowExplicit,
-        bool AllowResultConversion);
-
-    void InjectNonDeducedTemplateCandidates(Sema &S);
-
-    void DisableResolutionByPerfectCandidate() {
-      ResolutionByPerfectCandidateIsDisabled = true;
-    }
-
     /// Find the best viable function on this overload set, if it exists.
     OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc,
                                          OverloadCandidateSet::iterator& Best);
@@ -1445,15 +1263,6 @@ class Sema;
       DestAS = AS;
     }
 
-  private:
-    OverloadingResult ResultForBestCandidate(const iterator &Best);
-    void CudaExcludeWrongSideCandidates(
-        Sema &S, SmallVectorImpl<OverloadCandidate *> &Candidates);
-    OverloadingResult
-    BestViableFunctionImpl(Sema &S, SourceLocation Loc,
-                           OverloadCandidateSet::iterator &Best);
-    void PerfectViableFunction(Sema &S, SourceLocation Loc,
-                               OverloadCandidateSet::iterator &Best);
   };
 
   bool isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1,
@@ -1502,21 +1311,6 @@ class Sema;
   // parameter.
   bool shouldEnforceArgLimit(bool PartialOverloading, FunctionDecl *Function);
 
-  inline bool OverloadCandidateSet::shouldDeferTemplateArgumentDeduction(
-      const LangOptions &Opts) const {
-    return
-        // For user defined conversion we need to check against different
-        // combination of CV qualifiers and look at any explicit specifier, so
-        // always deduce template candidates.
-        Kind != CSK_InitByUserDefinedConversion
-        // When doing code completion, we want to see all the
-        // viable candidates.
-        && Kind != CSK_CodeCompletion
-        // CUDA may prefer template candidates even when a non-candidate
-        // is a perfect match
-        && !Opts.CUDA;
-  }
-
 } // namespace clang
 
 #endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 45405d4709e14..f6ec4cb0f069e 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6354,8 +6354,7 @@ SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, 
ArrayRef<Expr *> Args,
   Expr *NakedFn = Fn->IgnoreParenCasts();
   // Build an overload candidate set based on the functions we find.
   SourceLocation Loc = Fn->getExprLoc();
-  OverloadCandidateSet CandidateSet(Loc,
-                                    OverloadCandidateSet::CSK_CodeCompletion);
+  OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
 
   if (auto ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn)) {
     SemaRef.AddOverloadedCallCandidates(ULE, ArgsWithoutDependentTypes,
@@ -6558,8 +6557,7 @@ QualType 
SemaCodeCompletion::ProduceConstructorSignatureHelp(
   // FIXME: Provide support for variadic template constructors.
 
   if (CRD) {
-    OverloadCandidateSet CandidateSet(Loc,
-                                      
OverloadCandidateSet::CSK_CodeCompletion);
+    OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
     for (NamedDecl *C : SemaRef.LookupConstructors(CRD)) {
       if (auto *FD = dyn_cast<FunctionDecl>(C)) {
         // FIXME: we can't yet provide correct signature help for initializer
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 82489847b589b..a1e4bb4321d53 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -10029,19 +10029,12 @@ QualType 
Sema::DeduceTemplateSpecializationFromInitializer(
     //   When [...] the constructor [...] is a candidate by
     //    - [over.match.copy] (in all cases)
     if (TD) {
-
-      // As template candidates are not deduced immediately,
-      // persist the array in the overload set.
-      MutableArrayRef<Expr *> TmpInits =
-          Candidates.getPersistentArgsArray(Inits.size());
-
-      for (auto [I, E] : llvm::enumerate(Inits)) {
+      SmallVector<Expr *, 8> TmpInits;
+      for (Expr *E : Inits)
         if (auto *DI = dyn_cast<DesignatedInitExpr>(E))
-          TmpInits[I] = DI->getInit();
+          TmpInits.push_back(DI->getInit());
         else
-          TmpInits[I] = E;
-      }
-
+          TmpInits.push_back(E);
       AddTemplateOverloadCandidate(
           TD, FoundDecl, /*ExplicitArgs=*/nullptr, TmpInits, Candidates,
           /*SuppressUserConversions=*/false,
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index deef01c946feb..55634aa75ae25 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1123,10 +1123,6 @@ void OverloadCandidateSet::clear(CandidateSetKind CSK) {
   Candidates.clear();
   Functions.clear();
   Kind = CSK;
-  FirstDeferredCandidate = nullptr;
-  DeferredCandidatesCount = 0;
-  HasDeferredTemplateConstructors = false;
-  ResolutionByPerfectCandidateIsDisabled = false;
 }
 
 namespace {
@@ -7799,14 +7795,15 @@ void Sema::AddMethodCandidate(
   }
 }
 
-static void AddMethodTemplateCandidateImmediately(
-    Sema &S, OverloadCandidateSet &CandidateSet,
+void Sema::AddMethodTemplateCandidate(
     FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl,
     CXXRecordDecl *ActingContext,
     TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType,
     Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
-    bool SuppressUserConversions, bool PartialOverloading,
-    OverloadCandidateParamOrder PO) {
+    OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
+    bool PartialOverloading, OverloadCandidateParamOrder PO) {
+  if (!CandidateSet.isNewCandidate(MethodTmpl, PO))
+    return;
 
   // C++ [over.match.funcs]p7:
   //   In each case where a candidate is a function template, candidate
@@ -7820,12 +7817,12 @@ static void AddMethodTemplateCandidateImmediately(
   TemplateDeductionInfo Info(CandidateSet.getLocation());
   FunctionDecl *Specialization = nullptr;
   ConversionSequenceList Conversions;
-  if (TemplateDeductionResult Result = S.DeduceTemplateArguments(
+  if (TemplateDeductionResult Result = DeduceTemplateArguments(
           MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info,
           PartialOverloading, /*AggregateDeductionCandidate=*/false,
           /*PartialOrdering=*/false, ObjectType, ObjectClassification,
           [&](ArrayRef<QualType> ParamTypes) {
-            return S.CheckNonDependentConversions(
+            return CheckNonDependentConversions(
                 MethodTmpl, ParamTypes, Args, CandidateSet, Conversions,
                 SuppressUserConversions, ActingContext, ObjectType,
                 ObjectClassification, PO);
@@ -7847,8 +7844,8 @@ static void AddMethodTemplateCandidateImmediately(
       Candidate.FailureKind = ovl_fail_bad_conversion;
     else {
       Candidate.FailureKind = ovl_fail_bad_deduction;
-      Candidate.DeductionFailure =
-          MakeDeductionFailureInfo(S.Context, Result, Info);
+      Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+                                                            Info);
     }
     return;
   }
@@ -7858,34 +7855,10 @@ static void AddMethodTemplateCandidateImmediately(
   assert(Specialization && "Missing member function template specialization?");
   assert(isa<CXXMethodDecl>(Specialization) &&
          "Specialization is not a member function?");
-  S.AddMethodCandidate(
-      cast<CXXMethodDecl>(Specialization), FoundDecl, ActingContext, 
ObjectType,
-      ObjectClassification, Args, CandidateSet, SuppressUserConversions,
-      PartialOverloading, Conversions, PO, Info.hasStrictPackMatch());
-}
-
-void Sema::AddMethodTemplateCandidate(
-    FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl,
-    CXXRecordDecl *ActingContext,
-    TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType,
-    Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
-    OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
-    bool PartialOverloading, OverloadCandidateParamOrder PO) {
-  if (!CandidateSet.isNewCandidate(MethodTmpl, PO))
-    return;
-
-  if (ExplicitTemplateArgs ||
-      !CandidateSet.shouldDeferTemplateArgumentDeduction(getLangOpts())) {
-    AddMethodTemplateCandidateImmediately(
-        *this, CandidateSet, MethodTmpl, FoundDecl, ActingContext,
-        ExplicitTemplateArgs, ObjectType, ObjectClassification, Args,
-        SuppressUserConversions, PartialOverloading, PO);
-    return;
-  }
-
-  CandidateSet.AddDeferredMethodTemplateCandidate(
-      MethodTmpl, FoundDecl, ActingContext, ObjectType, ObjectClassification,
-      Args, SuppressUserConversions, PartialOverloading, PO);
+  AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl,
+                     ActingContext, ObjectType, ObjectClassification, Args,
+                     CandidateSet, SuppressUserConversions, PartialOverloading,
+                     Conversions, PO, Info.hasStrictPackMatch());
 }
 
 /// Determine whether a given function template has a simple explicit specifier
@@ -7894,18 +7867,14 @@ static bool 
isNonDependentlyExplicit(FunctionTemplateDecl *FTD) {
   return ExplicitSpecifier::getFromDecl(FTD->getTemplatedDecl()).isExplicit();
 }
 
-static bool hasDependentExplicit(FunctionTemplateDecl *FTD) {
-  return ExplicitSpecifier::getFromDecl(FTD->getTemplatedDecl()).getKind() ==
-         ExplicitSpecKind::Unresolved;
-}
-
-static void AddTemplateOverloadCandidateImmediately(
-    Sema &S, OverloadCandidateSet &CandidateSet,
+void Sema::AddTemplateOverloadCandidate(
     FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
     TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
-    bool SuppressUserConversions, bool PartialOverloading, bool AllowExplicit,
-    Sema::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
-    bool AggregateCandidateDeduction) {
+    OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
+    bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate,
+    OverloadCandidateParamOrder PO, bool AggregateCandidateDeduction) {
+  if (!CandidateSet.isNewCandidate(FunctionTemplate, PO))
+    return;
 
   // If the function template has a non-dependent explicit specification,
   // exclude it now if appropriate; we are not permitted to perform deduction
@@ -7932,14 +7901,14 @@ static void AddTemplateOverloadCandidateImmediately(
                              FunctionTemplate->getTemplateDepth());
   FunctionDecl *Specialization = nullptr;
   ConversionSequenceList Conversions;
-  if (TemplateDeductionResult Result = S.DeduceTemplateArguments(
+  if (TemplateDeductionResult Result = DeduceTemplateArguments(
           FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info,
           PartialOverloading, AggregateCandidateDeduction,
           /*PartialOrdering=*/false,
           /*ObjectType=*/QualType(),
           /*ObjectClassification=*/Expr::Classification(),
           [&](ArrayRef<QualType> ParamTypes) {
-            return S.CheckNonDependentConversions(
+            return CheckNonDependentConversions(
                 FunctionTemplate, ParamTypes, Args, CandidateSet, Conversions,
                 SuppressUserConversions, nullptr, QualType(), {}, PO);
           });
@@ -7963,8 +7932,8 @@ static void AddTemplateOverloadCandidateImmediately(
       Candidate.FailureKind = ovl_fail_bad_conversion;
     else {
       Candidate.FailureKind = ovl_fail_bad_deduction;
-      Candidate.DeductionFailure =
-          MakeDeductionFailureInfo(S.Context, Result, Info);
+      Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+                                                            Info);
     }
     return;
   }
@@ -7972,7 +7941,7 @@ static void AddTemplateOverloadCandidateImmediately(
   // Add the function template specialization produced by template argument
   // deduction as a candidate.
   assert(Specialization && "Missing function template specialization?");
-  S.AddOverloadCandidate(
+  AddOverloadCandidate(
       Specialization, FoundDecl, Args, CandidateSet, SuppressUserConversions,
       PartialOverloading, AllowExplicit,
       /*AllowExplicitConversions=*/false, IsADLCandidate, Conversions, PO,
@@ -7980,38 +7949,6 @@ static void AddTemplateOverloadCandidateImmediately(
       Info.hasStrictPackMatch());
 }
 
-void Sema::AddTemplateOverloadCandidate(
-    FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-    TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args,
-    OverloadCandidateSet &CandidateSet, bool SuppressUserConversions,
-    bool PartialOverloading, bool AllowExplicit, ADLCallKind IsADLCandidate,
-    OverloadCandidateParamOrder PO, bool AggregateCandidateDeduction) {
-  if (!CandidateSet.isNewCandidate(FunctionTemplate, PO))
-    return;
-
-  bool DependentExplicitSpecifier = hasDependentExplicit(FunctionTemplate);
-
-  if (ExplicitTemplateArgs ||
-      !CandidateSet.shouldDeferTemplateArgumentDeduction(getLangOpts()) ||
-      (isa<CXXConstructorDecl>(FunctionTemplate->getTemplatedDecl()) &&
-       DependentExplicitSpecifier)) {
-
-    AddTemplateOverloadCandidateImmediately(
-        *this, CandidateSet, FunctionTemplate, FoundDecl, ExplicitTemplateArgs,
-        Args, SuppressUserConversions, PartialOverloading, AllowExplicit,
-        IsADLCandidate, PO, AggregateCandidateDeduction);
-
-    if (DependentExplicitSpecifier)
-      CandidateSet.DisableResolutionByPerfectCandidate();
-    return;
-  }
-
-  CandidateSet.AddDeferredTemplateCandidate(
-      FunctionTemplate, FoundDecl, Args, SuppressUserConversions,
-      PartialOverloading, AllowExplicit, IsADLCandidate, PO,
-      AggregateCandidateDeduction);
-}
-
 bool Sema::CheckNonDependentConversions(
     FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes,
     ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet,
@@ -8327,12 +8264,16 @@ void Sema::AddConversionCandidate(
   }
 }
 
-static void AddTemplateConversionCandidateImmediately(
-    Sema &S, OverloadCandidateSet &CandidateSet,
+void Sema::AddTemplateConversionCandidate(
     FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-    CXXRecordDecl *ActingContext, Expr *From, QualType ToType,
-    bool AllowObjCConversionOnExplicit, bool AllowExplicit,
-    bool AllowResultConversion) {
+    CXXRecordDecl *ActingDC, Expr *From, QualType ToType,
+    OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit,
+    bool AllowExplicit, bool AllowResultConversion) {
+  assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) &&
+         "Only conversion function templates permitted here");
+
+  if (!CandidateSet.isNewCandidate(FunctionTemplate))
+    return;
 
   // If the function template has a non-dependent explicit specification,
   // exclude it now if appropriate; we are not permitted to perform deduction
@@ -8347,11 +8288,11 @@ static void AddTemplateConversionCandidateImmediately(
   }
 
   QualType ObjectType = From->getType();
-  Expr::Classification ObjectClassification = From->Classify(S.Context);
+  Expr::Classification ObjectClassification = From->Classify(getASTContext());
 
   TemplateDeductionInfo Info(CandidateSet.getLocation());
   CXXConversionDecl *Specialization = nullptr;
-  if (TemplateDeductionResult Result = S.DeduceTemplateArguments(
+  if (TemplateDeductionResult Result = DeduceTemplateArguments(
           FunctionTemplate, ObjectType, ObjectClassification, ToType,
           Specialization, Info);
       Result != TemplateDeductionResult::Success) {
@@ -8361,47 +8302,18 @@ static void AddTemplateConversionCandidateImmediately(
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_bad_deduction;
     Candidate.ExplicitCallArguments = 1;
-    Candidate.DeductionFailure =
-        MakeDeductionFailureInfo(S.Context, Result, Info);
+    Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
+                                                          Info);
     return;
   }
 
   // Add the conversion function template specialization produced by
   // template argument deduction as a candidate.
   assert(Specialization && "Missing function template specialization?");
-  S.AddConversionCandidate(Specialization, FoundDecl, ActingContext, From,
-                           ToType, CandidateSet, AllowObjCConversionOnExplicit,
-                           AllowExplicit, AllowResultConversion,
-                           Info.hasStrictPackMatch());
-}
-
-void Sema::AddTemplateConversionCandidate(
-    FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-    CXXRecordDecl *ActingDC, Expr *From, QualType ToType,
-    OverloadCandidateSet &CandidateSet, bool AllowObjCConversionOnExplicit,
-    bool AllowExplicit, bool AllowResultConversion) {
-  assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) &&
-         "Only conversion function templates permitted here");
-
-  if (!CandidateSet.isNewCandidate(FunctionTemplate))
-    return;
-
-  if (!CandidateSet.shouldDeferTemplateArgumentDeduction(getLangOpts()) ||
-      CandidateSet.getKind() ==
-          OverloadCandidateSet::CSK_InitByUserDefinedConversion ||
-      CandidateSet.getKind() == OverloadCandidateSet::CSK_InitByConstructor) {
-    AddTemplateConversionCandidateImmediately(
-        *this, CandidateSet, FunctionTemplate, FoundDecl, ActingDC, From,
-        ToType, AllowObjCConversionOnExplicit, AllowExplicit,
-        AllowResultConversion);
-
-    CandidateSet.DisableResolutionByPerfectCandidate();
-    return;
-  }
-
-  CandidateSet.AddDeferredConversionTemplateCandidate(
-      FunctionTemplate, FoundDecl, ActingDC, From, ToType,
-      AllowObjCConversionOnExplicit, AllowExplicit, AllowResultConversion);
+  AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType,
+                         CandidateSet, AllowObjCConversionOnExplicit,
+                         AllowExplicit, AllowResultConversion,
+                         Info.hasStrictPackMatch());
 }
 
 void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
@@ -8551,17 +8463,11 @@ void Sema::AddNonMemberOperatorCandidates(
     if (FunTmpl) {
       AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs,
                                    FunctionArgs, CandidateSet);
-      if (CandidateSet.getRewriteInfo().shouldAddReversed(*this, Args, FD)) {
-
-        // As template candidates are not deduced immediately,
-        // persist the array in the overload set.
-        ArrayRef<Expr *> Reversed = CandidateSet.getPersistentArgsArray(
-            FunctionArgs[1], FunctionArgs[0]);
-        AddTemplateOverloadCandidate(FunTmpl, F.getPair(), 
ExplicitTemplateArgs,
-                                     Reversed, CandidateSet, false, false, 
true,
-                                     ADLCallKind::NotADL,
-                                     OverloadCandidateParamOrder::Reversed);
-      }
+      if (CandidateSet.getRewriteInfo().shouldAddReversed(*this, Args, FD))
+        AddTemplateOverloadCandidate(
+            FunTmpl, F.getPair(), ExplicitTemplateArgs,
+            {FunctionArgs[1], FunctionArgs[0]}, CandidateSet, false, false,
+            true, ADLCallKind::NotADL, OverloadCandidateParamOrder::Reversed);
     } else {
       if (ExplicitTemplateArgs)
         continue;
@@ -10293,8 +10199,6 @@ 
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
   // FIXME: Pass in the explicit template arguments?
   ArgumentDependentLookup(Name, Loc, Args, Fns);
 
-  ArrayRef<Expr *> ReversedArgs;
-
   // Erase all of the candidates we already knew about.
   for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
                                    CandEnd = CandidateSet.end();
@@ -10334,15 +10238,9 @@ 
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
           /*AllowExplicit=*/true, ADLCallKind::UsesADL);
       if (CandidateSet.getRewriteInfo().shouldAddReversed(
               *this, Args, FTD->getTemplatedDecl())) {
-
-        // As template candidates are not deduced immediately,
-        // persist the array in the overload set.
-        if (ReversedArgs.empty())
-          ReversedArgs = CandidateSet.getPersistentArgsArray(Args[1], Args[0]);
-
         AddTemplateOverloadCandidate(
-            FTD, FoundDecl, ExplicitTemplateArgs, ReversedArgs, CandidateSet,
-            /*SuppressUserConversions=*/false, PartialOverloading,
+            FTD, FoundDecl, ExplicitTemplateArgs, {Args[1], Args[0]},
+            CandidateSet, /*SuppressUserConversions=*/false, 
PartialOverloading,
             /*AllowExplicit=*/true, ADLCallKind::UsesADL,
             OverloadCandidateParamOrder::Reversed);
       }
@@ -11015,147 +10913,23 @@ bool 
OverloadCandidate::NotValidBecauseConstraintExprHasError() const {
              ->Satisfaction.ContainsErrors;
 }
 
-void OverloadCandidateSet::AddDeferredTemplateCandidate(
-    FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-    ArrayRef<Expr *> Args, bool SuppressUserConversions,
-    bool PartialOverloading, bool AllowExplicit,
-    CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
-    bool AggregateCandidateDeduction) {
-
-  auto *C =
-      allocateDeferredCandidate<DeferredFunctionTemplateOverloadCandidate>();
-
-  C = new (C) DeferredFunctionTemplateOverloadCandidate{
-      {nullptr, DeferredFunctionTemplateOverloadCandidate::Function,
-       /*AllowObjCConversionOnExplicit=*/false,
-       /*AllowResultConversion=*/false, AllowExplicit, SuppressUserConversions,
-       PartialOverloading, AggregateCandidateDeduction},
-      FunctionTemplate,
-      FoundDecl,
-      Args,
-      IsADLCandidate,
-      PO};
-
-  HasDeferredTemplateConstructors |=
-      isa<CXXConstructorDecl>(FunctionTemplate->getTemplatedDecl());
-}
-
-void OverloadCandidateSet::AddDeferredMethodTemplateCandidate(
-    FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl,
-    CXXRecordDecl *ActingContext, QualType ObjectType,
-    Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
-    bool SuppressUserConversions, bool PartialOverloading,
-    OverloadCandidateParamOrder PO) {
-
-  assert(!isa<CXXConstructorDecl>(MethodTmpl->getTemplatedDecl()));
-
-  auto *C =
-      allocateDeferredCandidate<DeferredMethodTemplateOverloadCandidate>();
-
-  C = new (C) DeferredMethodTemplateOverloadCandidate{
-      {nullptr, DeferredFunctionTemplateOverloadCandidate::Method,
-       /*AllowObjCConversionOnExplicit=*/false,
-       /*AllowResultConversion=*/false,
-       /*AllowExplicit=*/false, SuppressUserConversions, PartialOverloading,
-       /*AggregateCandidateDeduction=*/false},
-      MethodTmpl,
-      FoundDecl,
-      Args,
-      ActingContext,
-      ObjectClassification,
-      ObjectType,
-      PO};
-}
-
-void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
-    FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
-    CXXRecordDecl *ActingContext, Expr *From, QualType ToType,
-    bool AllowObjCConversionOnExplicit, bool AllowExplicit,
-    bool AllowResultConversion) {
-
-  auto *C =
-      allocateDeferredCandidate<DeferredConversionTemplateOverloadCandidate>();
-
-  C = new (C) DeferredConversionTemplateOverloadCandidate{
-      {nullptr, DeferredFunctionTemplateOverloadCandidate::Conversion,
-       AllowObjCConversionOnExplicit, AllowResultConversion,
-       /*AllowExplicit=*/false,
-       /*SuppressUserConversions=*/false,
-       /*PartialOverloading*/ false,
-       /*AggregateCandidateDeduction=*/false},
-      FunctionTemplate,
-      FoundDecl,
-      ActingContext,
-      From,
-      ToType};
-}
-
-static void
-AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
-                             DeferredMethodTemplateOverloadCandidate &C) {
-
-  AddMethodTemplateCandidateImmediately(
-      S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext,
-      /*ExplicitTemplateArgs=*/nullptr, C.ObjectType, C.ObjectClassification,
-      C.Args, C.SuppressUserConversions, C.PartialOverloading, C.PO);
-}
-
-static void
-AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
-                             DeferredFunctionTemplateOverloadCandidate &C) {
-  AddTemplateOverloadCandidateImmediately(
-      S, CandidateSet, C.FunctionTemplate, C.FoundDecl,
-      /*ExplicitTemplateArgs=*/nullptr, C.Args, C.SuppressUserConversions,
-      C.PartialOverloading, C.AllowExplicit, C.IsADLCandidate, C.PO,
-      C.AggregateCandidateDeduction);
-}
-
-static void
-AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
-                             DeferredConversionTemplateOverloadCandidate &C) {
-  return AddTemplateConversionCandidateImmediately(
-      S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext, 
C.From,
-      C.ToType, C.AllowObjCConversionOnExplicit, C.AllowExplicit,
-      C.AllowResultConversion);
-}
-
-void OverloadCandidateSet::InjectNonDeducedTemplateCandidates(Sema &S) {
-  Candidates.reserve(Candidates.size() + DeferredCandidatesCount);
-  DeferredTemplateOverloadCandidate *Cand = FirstDeferredCandidate;
-  while (Cand) {
-    switch (Cand->Kind) {
-    case DeferredTemplateOverloadCandidate::Function:
-      AddTemplateOverloadCandidate(
-          S, *this,
-          *static_cast<DeferredFunctionTemplateOverloadCandidate *>(Cand));
-      break;
-    case DeferredTemplateOverloadCandidate::Method:
-      AddTemplateOverloadCandidate(
-          S, *this,
-          *static_cast<DeferredMethodTemplateOverloadCandidate *>(Cand));
-      break;
-    case DeferredTemplateOverloadCandidate::Conversion:
-      AddTemplateOverloadCandidate(
-          S, *this,
-          *static_cast<DeferredConversionTemplateOverloadCandidate *>(Cand));
-      break;
-    }
-    Cand = Cand->Next;
-  }
-  FirstDeferredCandidate = nullptr;
-  DeferredCandidatesCount = 0;
-}
-
+/// Computes the best viable function (C++ 13.3.3)
+/// within an overload candidate set.
+///
+/// \param Loc The location of the function name (or operator symbol) for
+/// which overload resolution occurs.
+///
+/// \param Best If overload resolution was successful or found a deleted
+/// function, \p Best points to the candidate function found.
+///
+/// \returns The result of overload resolution.
 OverloadingResult
-OverloadCandidateSet::ResultForBestCandidate(const iterator &Best) {
-  Best->Best = true;
-  if (Best->Function && Best->Function->isDeleted())
-    return OR_Deleted;
-  return OR_Success;
-}
+OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
+                                         iterator &Best) {
+  llvm::SmallVector<OverloadCandidate *, 16> Candidates;
+  std::transform(begin(), end(), std::back_inserter(Candidates),
+                 [](OverloadCandidate &Cand) { return &Cand; });
 
-void OverloadCandidateSet::CudaExcludeWrongSideCandidates(
-    Sema &S, SmallVectorImpl<OverloadCandidate *> &Candidates) {
   // [CUDA] HD->H or HD->D calls are technically not allowed by CUDA but
   // are accepted by both clang and NVCC. However, during a particular
   // compilation mode only one call variant is viable. We need to
@@ -11167,112 +10941,27 @@ void 
OverloadCandidateSet::CudaExcludeWrongSideCandidates(
   // -fgpu-exclude-wrong-side-overloads is off. When
   // -fgpu-exclude-wrong-side-overloads is on, all candidates are compared
   // uniformly in isBetterOverloadCandidate.
-  if (!S.getLangOpts().CUDA || S.getLangOpts().GPUExcludeWrongSideOverloads)
-    return;
-  const FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
-
-  bool ContainsSameSideCandidate =
-      llvm::any_of(Candidates, [&](const OverloadCandidate *Cand) {
-        // Check viable function only.
+  if (S.getLangOpts().CUDA && !S.getLangOpts().GPUExcludeWrongSideOverloads) {
+    const FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
+    bool ContainsSameSideCandidate =
+        llvm::any_of(Candidates, [&](OverloadCandidate *Cand) {
+          // Check viable function only.
+          return Cand->Viable && Cand->Function &&
+                 S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
+                     SemaCUDA::CFP_SameSide;
+        });
+    if (ContainsSameSideCandidate) {
+      auto IsWrongSideCandidate = [&](OverloadCandidate *Cand) {
+        // Check viable function only to avoid unnecessary data copying/moving.
         return Cand->Viable && Cand->Function &&
                S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
-                   SemaCUDA::CFP_SameSide;
-      });
-
-  if (!ContainsSameSideCandidate)
-    return;
-
-  auto IsWrongSideCandidate = [&](const OverloadCandidate *Cand) {
-    // Check viable function only to avoid unnecessary data copying/moving.
-    return Cand->Viable && Cand->Function &&
-           S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
-               SemaCUDA::CFP_WrongSide;
-  };
-  llvm::erase_if(Candidates, IsWrongSideCandidate);
-}
-
-/// Computes the best viable function (C++ 13.3.3)
-/// within an overload candidate set.
-///
-/// \param Loc The location of the function name (or operator symbol) for
-/// which overload resolution occurs.
-///
-/// \param Best If overload resolution was successful or found a deleted
-/// function, \p Best points to the candidate function found.
-///
-/// \returns The result of overload resolution.
-OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
-                                                           SourceLocation Loc,
-                                                           iterator &Best) {
-
-  assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
-         DeferredCandidatesCount == 0 &&
-             "Unexpected deferred template candidates");
-
-  bool TwoPhaseResolution =
-      DeferredCandidatesCount != 0 && !ResolutionByPerfectCandidateIsDisabled;
-
-  if (TwoPhaseResolution) {
-
-    PerfectViableFunction(S, Loc, Best);
-    if (Best != end())
-      return ResultForBestCandidate(Best);
-  }
-
-  InjectNonDeducedTemplateCandidates(S);
-  return BestViableFunctionImpl(S, Loc, Best);
-}
-
-void OverloadCandidateSet::PerfectViableFunction(
-    Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best) {
-
-  Best = end();
-  for (auto It = begin(); It != end(); ++It) {
-
-    if (!It->isPerfectMatch(S.getASTContext()))
-      continue;
-
-    // We found a suitable conversion function
-    // but if there is a template constructor in the target class
-    // we might prefer that instead.
-    if (HasDeferredTemplateConstructors &&
-        isa_and_nonnull<CXXConversionDecl>(It->Function)) {
-      Best = end();
-      break;
-    }
-
-    if (Best == end()) {
-      Best = It;
-      continue;
-    }
-    if (Best->Function && It->Function) {
-      FunctionDecl *D =
-          S.getMoreConstrainedFunction(Best->Function, It->Function);
-      if (D == nullptr) {
-        Best = end();
-        break;
-      }
-      if (D == It->Function)
-        Best = It;
-      continue;
+                   SemaCUDA::CFP_WrongSide;
+      };
+      llvm::erase_if(Candidates, IsWrongSideCandidate);
     }
-    // ambiguous
-    Best = end();
-    break;
   }
-}
-
-OverloadingResult OverloadCandidateSet::BestViableFunctionImpl(
-    Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best) {
-
-  llvm::SmallVector<OverloadCandidate *, 16> Candidates;
-  Candidates.reserve(this->Candidates.size());
-  std::transform(begin(), end(), std::back_inserter(Candidates),
-                 [](OverloadCandidate &Cand) { return &Cand; });
-
-  if (S.getLangOpts().CUDA)
-    CudaExcludeWrongSideCandidates(S, Candidates);
 
+  // Find the best viable function.
   Best = end();
   for (auto *Cand : Candidates) {
     Cand->Best = false;
@@ -11294,8 +10983,9 @@ OverloadingResult 
OverloadCandidateSet::BestViableFunctionImpl(
   if (Best == end())
     return OR_No_Viable_Function;
 
-  llvm::SmallVector<OverloadCandidate *, 4> PendingBest;
   llvm::SmallVector<const NamedDecl *, 4> EquivalentCands;
+
+  llvm::SmallVector<OverloadCandidate*, 4> PendingBest;
   PendingBest.push_back(&*Best);
   Best->Best = true;
 
@@ -11318,15 +11008,25 @@ OverloadingResult 
OverloadCandidateSet::BestViableFunctionImpl(
     }
   }
 
+  // If we found more than one best candidate, this is ambiguous.
   if (Best == end())
     return OR_Ambiguous;
 
-  OverloadingResult R = ResultForBestCandidate(Best);
+  // Best is the best viable function.
+  if (Best->Function && Best->Function->isDeleted())
+    return OR_Deleted;
+
+  if (auto *M = dyn_cast_or_null<CXXMethodDecl>(Best->Function);
+      Kind == CSK_AddressOfOverloadSet && M &&
+      M->isImplicitObjectMemberFunction()) {
+    return OR_No_Viable_Function;
+  }
 
   if (!EquivalentCands.empty())
     S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function,
                                                     EquivalentCands);
-  return R;
+
+  return OR_Success;
 }
 
 namespace {
@@ -13033,9 +12733,6 @@ SmallVector<OverloadCandidate *, 32> 
OverloadCandidateSet::CompleteCandidates(
     Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args,
     SourceLocation OpLoc,
     llvm::function_ref<bool(OverloadCandidate &)> Filter) {
-
-  InjectNonDeducedTemplateCandidates(S);
-
   // Sort the candidates by viability and position.  Sorting directly would
   // be prohibitive, so we make a set of pointers and sort those.
   SmallVector<OverloadCandidate*, 32> Cands;
@@ -14657,12 +14354,10 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, 
Expr *Fn,
                                          Expr *ExecConfig,
                                          bool AllowTypoCorrection,
                                          bool CalleesAddressIsTaken) {
-
-  OverloadCandidateSet::CandidateSetKind CSK =
-      CalleesAddressIsTaken ? OverloadCandidateSet::CSK_AddressOfOverloadSet
-                            : OverloadCandidateSet::CSK_Normal;
-
-  OverloadCandidateSet CandidateSet(Fn->getExprLoc(), CSK);
+  OverloadCandidateSet CandidateSet(
+      Fn->getExprLoc(), CalleesAddressIsTaken
+                            ? OverloadCandidateSet::CSK_AddressOfOverloadSet
+                            : OverloadCandidateSet::CSK_Normal);
   ExprResult result;
 
   if (buildOverloadedCallSet(S, Fn, ULE, Args, LParenLoc, &CandidateSet,
@@ -14678,17 +14373,6 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, 
Expr *Fn,
   OverloadingResult OverloadResult =
       CandidateSet.BestViableFunction(*this, Fn->getBeginLoc(), Best);
 
-  // [C++23][over.call.func]
-  // if overload resolution selects a non-static member function,
-  // the call is ill-formed;
-  if (CSK == OverloadCandidateSet::CSK_AddressOfOverloadSet &&
-      Best != CandidateSet.end()) {
-    if (auto *M = dyn_cast_or_null<CXXMethodDecl>(Best->Function);
-        M && M->isImplicitObjectMemberFunction()) {
-      OverloadResult = OR_No_Viable_Function;
-    }
-  }
-
   // Model the case with a call to a templated function whose definition
   // encloses the call and whose return type contains a placeholder type as if
   // the UnresolvedLookupExpr was type-dependent.
@@ -15024,24 +14708,18 @@ void Sema::LookupOverloadedBinOp(OverloadCandidateSet 
&CandidateSet,
   // rewritten candidates using these functions if necessary.
   AddNonMemberOperatorCandidates(Fns, Args, CandidateSet);
 
-  // As template candidates are not deduced immediately,
-  // persist the array in the overload set.
-  ArrayRef<Expr *> ReversedArgs;
-  if (CandidateSet.getRewriteInfo().allowsReversed(Op) ||
-      CandidateSet.getRewriteInfo().allowsReversed(ExtraOp))
-    ReversedArgs = CandidateSet.getPersistentArgsArray(Args[1], Args[0]);
-
   // Add operator candidates that are member functions.
   AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet);
   if (CandidateSet.getRewriteInfo().allowsReversed(Op))
-    AddMemberOperatorCandidates(Op, OpLoc, ReversedArgs, CandidateSet,
+    AddMemberOperatorCandidates(Op, OpLoc, {Args[1], Args[0]}, CandidateSet,
                                 OverloadCandidateParamOrder::Reversed);
 
   // In C++20, also add any rewritten member candidates.
   if (ExtraOp) {
     AddMemberOperatorCandidates(ExtraOp, OpLoc, Args, CandidateSet);
     if (CandidateSet.getRewriteInfo().allowsReversed(ExtraOp))
-      AddMemberOperatorCandidates(ExtraOp, OpLoc, ReversedArgs, CandidateSet,
+      AddMemberOperatorCandidates(ExtraOp, OpLoc, {Args[1], Args[0]},
+                                  CandidateSet,
                                   OverloadCandidateParamOrder::Reversed);
   }
 
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 0ecdbb3ffb89f..772962ac653f7 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -6142,9 +6142,9 @@ FunctionDecl 
*Sema::getMoreConstrainedFunction(FunctionDecl *FD1,
   assert(!FD1->getDescribedTemplate() && !FD2->getDescribedTemplate() &&
          "not for function templates");
   assert(!FD1->isFunctionTemplateSpecialization() ||
-         (isa<CXXConversionDecl, CXXConstructorDecl>(FD1)));
+         isa<CXXConversionDecl>(FD1));
   assert(!FD2->isFunctionTemplateSpecialization() ||
-         (isa<CXXConversionDecl, CXXConstructorDecl>(FD2)));
+         isa<CXXConversionDecl>(FD2));
 
   FunctionDecl *F1 = FD1;
   if (FunctionDecl *P = FD1->getTemplateInstantiationPattern(false))
diff --git 
a/clang/test/CXX/temp/temp.constr/temp.constr.atomic/constrant-satisfaction-conversions.cpp
 
b/clang/test/CXX/temp/temp.constr/temp.constr.atomic/constrant-satisfaction-conversions.cpp
index 083e743818121..ba8e2dc372e98 100644
--- 
a/clang/test/CXX/temp/temp.constr/temp.constr.atomic/constrant-satisfaction-conversions.cpp
+++ 
b/clang/test/CXX/temp/temp.constr/temp.constr.atomic/constrant-satisfaction-conversions.cpp
@@ -14,7 +14,7 @@ template<typename T> struct S {
 // expected-note@#FINST{{in instantiation of function template specialization}}
 template<typename T> requires (S<T>{})
 void f(T);
-void f(long);
+void f(int);
 
 // Ensure this applies to operator && as well.
 // expected-error@+3{{atomic constraint must be of type 'bool' (found 
'S<int>')}}
@@ -22,7 +22,7 @@ void f(long);
 // expected-note@#F2INST{{in instantiation of function template 
specialization}}
 template<typename T> requires (S<T>{} && true)
 void f2(T);
-void f2(long);
+void f2(int);
 
 template<typename T> requires requires {
   requires S<T>{};
@@ -36,12 +36,12 @@ template<typename T> requires requires {
   //
 }
 void f3(T);
-void f3(long);
+void f3(int);
 
 // Doesn't diagnose, since this is no longer a compound requirement.
 template<typename T> requires (bool(1 && 2))
 void f4(T);
-void f4(long);
+void f4(int);
 
 void g() {
   f(0); // #FINST
diff --git a/clang/test/SemaCUDA/function-overload.cu 
b/clang/test/SemaCUDA/function-overload.cu
index 3d05839af7528..4710c81763adf 100644
--- a/clang/test/SemaCUDA/function-overload.cu
+++ b/clang/test/SemaCUDA/function-overload.cu
@@ -1,3 +1,6 @@
+// REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
+
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-linux-gnu -fsyntax-only \
 // RUN:   -verify=host,hostdefer,devdefer,expected %s
 // RUN: %clang_cc1 -std=c++14 -triple nvptx64-nvidia-cuda -fsyntax-only \
diff --git a/clang/test/SemaCXX/implicit-member-functions.cpp 
b/clang/test/SemaCXX/implicit-member-functions.cpp
index 8350eac5b88a0..1554b1af5d59a 100644
--- a/clang/test/SemaCXX/implicit-member-functions.cpp
+++ b/clang/test/SemaCXX/implicit-member-functions.cpp
@@ -54,24 +54,31 @@ namespace PR7594 {
 namespace Recursion {
   template<typename T> struct InvokeCopyConstructor {
     static const T &get();
-    typedef decltype(T(get())) type;
+    typedef decltype(T(get())) type; // expected-error {{no matching conver}}
   };
   struct B;
   struct A {
+    // expected-note@-1 {{while substituting deduced template arguments}}
     typedef B type;
     template<typename T,
              typename = typename InvokeCopyConstructor<typename T::type>::type>
+    // expected-note@-1 {{in instantiation of template class}}
     A(const T &);
+    // expected-note@-1 {{in instantiation of default argument}}
   };
-  struct B {
-    B();
+  struct B { // expected-note {{while declaring the implicit copy constructor 
for 'B'}}
+    // expected-note@-1 {{candidate constructor (the implicit move }}
+    B(); // expected-note {{candidate constructor not viable}}
     A a;
   };
   // Triggering the declaration of B's copy constructor causes overload
-  // resolution to occur for A's copying constructor, which picks
-  // the implicit copy constructor of A.
-  // Because that copy constructor is always a perfect match the template
-  // candidate is not instantiated.
+  // resolution to occur for A's copying constructor, which instantiates
+  // InvokeCopyConstructor<B>, which triggers the declaration of B's copy
+  // constructor. Notionally, this happens when we get to the end of the
+  // definition of 'struct B', so there is no declared copy constructor yet.
+  //
+  // This behavior is g++-compatible, but isn't exactly right; the class is
+  // supposed to be incomplete when we implicitly declare its special members.
   B b = B();
 
 
diff --git a/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp 
b/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp
deleted file mode 100644
index 877816ca013ec..0000000000000
--- a/clang/test/SemaCXX/overload-resolution-deferred-templates.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -verify 
-std=c++11 %s
-// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -verify 
-std=c++20 %s
-// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -fsyntax-only -verify 
-std=c++2c %s
-
-template <typename T>
-struct Invalid { static_assert(false, "instantiated Invalid"); }; // 
#err-invalid
-
-template <typename T>
-int f(T a, Invalid<T> = {}); // #note-f
-
-// sanity check
-int e1 = f(0);
-//expected-error@#err-invalid {{static assertion failed: instantiated Invalid}}
-//expected-note@-2 {{in instantiation of default function argument expression 
for 'f<int>' required here}}
-//expected-note@#note-f {{in instantiation of template class 'Invalid<int>' 
requested here}}
-//expected-note@#note-f {{passing argument to parameter here}}
-
-int f(int);
-int ok1 = f(0);
-int e4 = f((const int&)(ok1));
-
-int f(int, int = 0);
-int ok2 = f(0, 0);
-
-int e2  = f(0L);
-//expected-error@#err-invalid {{static assertion failed: instantiated Invalid}}
-//expected-note@-2 {{in instantiation of default function argument expression 
for 'f<long>' required here}}
-//expected-note@#note-f {{in instantiation of template class 'Invalid<long>' 
requested here}}
-//expected-note@#note-f {{passing argument to parameter here}}
-
-int f(long);
-int ok3 = f(0L);
-
-template <typename T>
-struct Invalid2 { static_assert(false, "instantiated Invalid2"); }; // 
#err-qualifiers
-
-template <typename T>
-int ref(T a, Invalid2<T> = {}); // expected-note 2{{here}}
-int ref(int&);
-int ref1 = ref(ok3);
-int ref2 = ref((const int&)ok3); // expected-note {{here}}
-//expected-error@#err-qualifiers {{static assertion failed: instantiated 
Invalid2}}
-
-
-template <typename T>
-int f_alias(T a, Invalid<T> = {});
-using Alias = int;
-int f_alias(Alias);
-int ok4 = f_alias(0);
-
-#if __cplusplus >= 202002
-
-struct Copyable {
-  template <typename T>
-  requires __is_constructible(Copyable, T)
-  explicit Copyable(T op) noexcept; // #1
-  Copyable(const Copyable&) noexcept = default; // #2
-};
-static_assert(__is_constructible(Copyable, const Copyable&));
-
-struct ImplicitlyCopyable {
-  template <typename T>
-  requires __is_constructible(ImplicitlyCopyable, T)
-  explicit ImplicitlyCopyable(T op) = delete; // #1
-};
-static_assert(__is_constructible(ImplicitlyCopyable, const 
ImplicitlyCopyable&));
-
-
-struct Movable {
-  template <typename T>
-  requires __is_constructible(Movable, T) // #err-self-constraint-1
-  explicit Movable(T op) noexcept; // #1
-  Movable(Movable&&) noexcept = default; // #2
-};
-static_assert(__is_constructible(Movable, Movable&&));
-static_assert(__is_constructible(Movable, const Movable&));
-// expected-error@-1 {{static assertion failed due to requirement 
'__is_constructible(Movable, const Movable &)'}}
-
-static_assert(__is_constructible(Movable, int));
-// expected-error@-1{{static assertion failed due to requirement 
'__is_constructible(Movable, int)'}} \
-// expected-note@-1 2{{}}
-// expected-error@#err-self-constraint-1{{satisfaction of constraint 
'__is_constructible(Movable, T)' depends on itself}}
-// expected-note@#err-self-constraint-1 4{{}}
-
-template <typename T>
-struct Members {
-    constexpr auto f(auto) {
-        static_assert(false, "");
-    }
-    constexpr auto f(int) { return 1; }
-    constexpr auto f(int) requires true { return 2; }
-
-    constexpr auto g(auto) {
-        static_assert(false, "instantiated member"); //#err-qualified-member
-        return 0;
-    }
-    constexpr auto g(int) & { return 1; }
-
-    static constexpr auto s(auto) {
-        static_assert(false, "");
-    }
-    static constexpr auto s(int) {
-        return 1;
-    }
-    static constexpr auto s(int) requires true {
-        return 2;
-    }
-};
-
-static_assert(Members<int[1]>{}.f(0) == 2);
-static_assert(Members<int[2]>{}.g(0) == 0);
-// expected-error@#err-qualified-member {{static assertion failed: 
instantiated member}} \
-// expected-note@-1{{in instantiation of function template specialization 
'Members<int[2]>::g<int>' }}
-Members<int[3]> m1;
-static_assert(m1.g(0) == 1);
-static_assert(Members<int[3]>{}.s(0) == 2);
-
-
-namespace ConstructorInit{
-struct S {
-  template <typename T>
-  S(T&&) {}
-};
-struct Test {
-  operator S() = delete;
-};
-
-static_assert(__is_constructible(S, Test));
-}
-
-namespace RefBinding {
-
-template <typename> struct remove_reference;
-template <typename _Tp> struct remove_reference<_Tp &> {
-  using type = _Tp;
-};
-template <typename _Tp> remove_reference<_Tp>::type move(_Tp &&);
-template <typename _Head> struct _Head_base {
-  _Head_base(_Head &__h) : _M_head_impl(__h) {}
-  template <typename _UHead> _Head_base(_UHead &&);
-  _Head _M_head_impl;
-};
-
-template <typename _Elements> void forward_as_tuple(_Elements &&) {
-  _Head_base<_Elements &&>(_Elements{});
-}
-struct StringRef {
-  void operator[](const StringRef __k) { forward_as_tuple((move)(__k)); }
-};
-
-}
-
-template <class> struct tuple {};
-struct BonkersBananas {
-  template <class T> operator T();
-  template <class = void> explicit operator tuple<int>() = delete;
-};
-static_assert(!__is_constructible(tuple<int>, BonkersBananas));
-
-namespace GH62096 {
-template <typename T>
-struct Oops {
-  static_assert(sizeof(T) == 0); // #GH62096-err
-  static constexpr bool value = true;
-};
-
-template <class OPERATOR>
-concept Operator = Oops<OPERATOR>::value; // #GH62096-note1
-
-template <Operator OP> void f(OP op); // // #GH62096-note2
-void f(int);
-
-void g(int n) { f(n); } // OK
-void h(short n) { f(n); }
-// expected-error@#GH62096-err {{static assertion failed due to requirement 
'sizeof(short) == 0'}} \
-// expected-note@-1{{in instantiation of function template specialization}} \
-// expected-note@-1{{while checking constraint satisfaction for template}}
-// expected-note@#GH62096-note1{{in instantiation}}
-// expected-note@#GH62096-note1{{while substituting template arguments into 
constraint expression here}}
-// expected-note@#GH62096-note2{{while substituting template arguments into 
constraint expression here}}
-// expected-note@#GH62096-note2{{while checking the satisfaction of concept}}
-// expected-note@#GH62096-err {{expression evaluates}}
-}
-
-#endif
diff --git a/clang/test/SemaTemplate/instantiate-function-params.cpp 
b/clang/test/SemaTemplate/instantiate-function-params.cpp
index eb2a7c5d4e8d6..7dd5595de58a3 100644
--- a/clang/test/SemaTemplate/instantiate-function-params.cpp
+++ b/clang/test/SemaTemplate/instantiate-function-params.cpp
@@ -6,12 +6,13 @@ template<typename T1> struct if_ {
   typedef if_c< static_cast<bool>(T1::value)> almost_type_; // expected-note 
7{{in instantiation}}
 };
 template <class Model, void (Model::*)()> struct wrap_constraints { };
-template <class Model>
+template <class Model> 
 inline char has_constraints_(Model* , // expected-note 3{{candidate template 
ignored}}
-                               wrap_constraints<Model,&Model::constraints>* = 
0);
+                               wrap_constraints<Model,&Model::constraints>* = 
0); // expected-note 4{{in instantiation}}
+
 template <class Model> struct not_satisfied {
   static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // 
expected-error 3{{no matching function}} \
-  // expected-note 4{{in instantiation}}
+  // expected-note 4{{while substituting deduced template arguments into 
function template 'has_constraints_' [with }}
 };
 template <class ModelFn> struct requirement_;
 template <void(*)()> struct instantiate {
diff --git a/clang/test/Templight/templight-empty-entries-fix.cpp 
b/clang/test/Templight/templight-empty-entries-fix.cpp
index 7f34b10134929..d13b748068efe 100644
--- a/clang/test/Templight/templight-empty-entries-fix.cpp
+++ b/clang/test/Templight/templight-empty-entries-fix.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -templight-dump -Wno-unused-value %s 2>&1 | FileCheck %s
 
-void a(long) {
+void a() {
   [] {};
 }
 
@@ -17,14 +17,14 @@ void a(long) {
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:4:3'$}}
 // CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:4:3'$}}
 
-template <int = 0> void a(long) { a(0); }
+template <int = 0> void a() { a(); }
 
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+a$}}
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+Begin$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:35'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:31'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+unnamed template non-type parameter 0 of a$}}
 // CHECK: {{^kind:[ ]+DefaultTemplateArgumentInstantiation$}}
@@ -42,29 +42,29 @@ template <int = 0> void a(long) { a(0); }
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+End$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:35'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:31'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+'a<0>'$}}
 // CHECK: {{^kind:[ ]+TemplateInstantiation$}}
 // CHECK: {{^event:[ ]+Begin$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:35'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:31'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+'a<0>'$}}
 // CHECK: {{^kind:[ ]+TemplateInstantiation$}}
 // CHECK: {{^event:[ ]+End$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:35'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:20:31'$}}
 
 template <int> struct b { typedef int c; };
-template <bool d = true, class = typename b<d>::c> void a(long) { a(0); }
+template <bool d = true, class = typename b<d>::c> void a() { a(); }
 
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+a$}}
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+Begin$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:60:57'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:67'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+DefaultTemplateArgumentInstantiation$}}
@@ -130,25 +130,25 @@ template <bool d = true, class = typename b<d>::c> void 
a(long) { a(0); }
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+End$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:60:57'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:67'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+'a<true, int>'$}}
 // CHECK: {{^kind:[ ]+TemplateInstantiation$}}
 // CHECK: {{^event:[ ]+Begin$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:60:57'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:67'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+'a<true, int>'$}}
 // CHECK: {{^kind:[ ]+TemplateInstantiation$}}
 // CHECK: {{^event:[ ]+End$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:60:57'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:67'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+a$}}
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+Begin$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:67'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+unnamed template non-type parameter 0 of a$}}
 // CHECK: {{^kind:[ ]+DefaultTemplateArgumentInstantiation$}}
@@ -166,10 +166,34 @@ template <bool d = true, class = typename b<d>::c> void 
a(long) { a(0); }
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+End$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:67'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
 
 template <bool = true> void d(int = 0) { d(); }
 
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+a$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:60:57'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+a$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:60:57'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+a$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+a$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:20:25'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:60:63'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
@@ -225,41 +249,41 @@ void e() {
 }
 
 // CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:223:3\)'$}}
+// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:247:3\)'$}}
 // CHECK: {{^kind:[ ]+Memoization$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:224:5'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:248:5'$}}
 // CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:223:3\)'$}}
+// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:247:3\)'$}}
 // CHECK: {{^kind:[ ]+Memoization$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:224:5'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:248:5'$}}
 // CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:223:3\)'$}}
+// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:247:3\)'$}}
 // CHECK: {{^kind:[ ]+Memoization$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:224:5'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:248:5'$}}
 // CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:223:3\)'$}}
+// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:247:3\)'$}}
 // CHECK: {{^kind:[ ]+Memoization$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:224:5'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:248:5'$}}
 // CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:223:3\)'$}}
+// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:247:3\)'$}}
 // CHECK: {{^kind:[ ]+Memoization$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
 // CHECK-LABEL: {{^---$}}
-// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:223:3\)'$}}
+// CHECK: {{^name:[ ]+'\(unnamed struct at 
.*templight-empty-entries-fix.cpp:247:3\)'$}}
 // CHECK: {{^kind:[ ]+Memoization$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:223:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:247:3'$}}
 
 
 template <template<typename> class>
@@ -275,71 +299,71 @@ void foo() {
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:266:6'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:290:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}}
 // CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:265:35'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}}
 // CHECK: {{^poi:[ ]+''$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}}
 // CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:265:35'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}}
 // CHECK: {{^poi:[ ]+''$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}}
 // CHECK: {{^kind:[ ]+PartialOrderingTTP$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:265:35'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:5'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:5'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}}
 // CHECK: {{^kind:[ ]+PartialOrderingTTP$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:265:35'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:5'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:5'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:266:6'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:290:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:266:6'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:290:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:266:6'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:290:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+'d<C>'$}}
 // CHECK: {{^kind:[ ]+TemplateInstantiation$}}
 // CHECK: {{^event:[ ]+Begin$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:266:6'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:290:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+'d<C>'$}}
 // CHECK: {{^kind:[ ]+TemplateInstantiation$}}
 // CHECK: {{^event:[ ]+End$}}
-// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:266:6'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:290:6'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+Begin$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:171:29'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}
 // CHECK-LABEL: {{^---$}}
 // CHECK: {{^name:[ ]+d$}}
 // CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
 // CHECK: {{^event:[ ]+End$}}
 // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:171:29'$}}
-// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:271:3'$}}
+// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:3'$}}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to