@@ -1124,6 +1124,8 @@ void OverloadCandidateSet::clear(CandidateSetKind CSK) {
11241124 Candidates.clear();
11251125 Functions.clear();
11261126 Kind = CSK;
1127+ FirstDeferredCandidate = nullptr;
1128+ DeferredCandidatesCount = 0;
11271129 HasDeferredTemplateConstructors = false;
11281130}
11291131
@@ -11004,16 +11006,20 @@ void OverloadCandidateSet::AddDeferredTemplateCandidate(
1100411006 bool PartialOverloading, bool AllowExplicit,
1100511007 CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
1100611008 bool AggregateCandidateDeduction) {
11007- DeferredFunctionTemplateOverloadCandidate C{FunctionTemplate,
11008- FoundDecl,
11009- Args,
11010- IsADLCandidate,
11011- PO,
11012- SuppressUserConversions,
11013- PartialOverloading,
11014- AllowExplicit,
11015- AggregateCandidateDeduction};
11016- DeferredCandidates.emplace_back(std::move(C));
11009+
11010+ auto *C =
11011+ allocateDeferredCandidate<DeferredFunctionTemplateOverloadCandidate>();
11012+
11013+ C = new (C) DeferredFunctionTemplateOverloadCandidate{
11014+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Function,
11015+ /*AllowObjCConversionOnExplicit=*/false,
11016+ /*AllowResultConversion=*/false, AllowExplicit, SuppressUserConversions,
11017+ PartialOverloading, AggregateCandidateDeduction},
11018+ FunctionTemplate,
11019+ FoundDecl,
11020+ Args,
11021+ IsADLCandidate,
11022+ PO};
1101711023 HasDeferredTemplateConstructors |=
1101811024 isa<CXXConstructorDecl>(FunctionTemplate->getTemplatedDecl());
1101911025}
@@ -11024,11 +11030,23 @@ void OverloadCandidateSet::AddDeferredMethodTemplateCandidate(
1102411030 Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
1102511031 bool SuppressUserConversions, bool PartialOverloading,
1102611032 OverloadCandidateParamOrder PO) {
11027- DeferredMethodTemplateOverloadCandidate C{
11028- MethodTmpl, FoundDecl, Args, ActingContext,
11029- ObjectClassification, ObjectType, PO, SuppressUserConversions,
11030- PartialOverloading};
11031- DeferredCandidates.emplace_back(std::move(C));
11033+
11034+ auto *C =
11035+ allocateDeferredCandidate<DeferredMethodTemplateOverloadCandidate>();
11036+
11037+ C = new (C) DeferredMethodTemplateOverloadCandidate{
11038+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Method,
11039+ /*AllowObjCConversionOnExplicit=*/false,
11040+ /*AllowResultConversion=*/false,
11041+ /*AllowExplicit=*/false, SuppressUserConversions, PartialOverloading,
11042+ /*AggregateCandidateDeduction=*/false},
11043+ MethodTmpl,
11044+ FoundDecl,
11045+ Args,
11046+ ActingContext,
11047+ ObjectClassification,
11048+ ObjectType,
11049+ PO};
1103211050}
1103311051
1103411052void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
@@ -11037,18 +11055,26 @@ void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
1103711055 bool AllowObjCConversionOnExplicit, bool AllowExplicit,
1103811056 bool AllowResultConversion) {
1103911057
11040- DeferredConversionTemplateOverloadCandidate C{
11041- FunctionTemplate, FoundDecl,
11042- ActingContext, From,
11043- ToType, AllowObjCConversionOnExplicit,
11044- AllowExplicit, AllowResultConversion};
11058+ auto *C =
11059+ allocateDeferredCandidate<DeferredConversionTemplateOverloadCandidate>();
1104511060
11046- DeferredCandidates.emplace_back(std::move(C));
11061+ C = new (C) DeferredConversionTemplateOverloadCandidate{
11062+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Conversion,
11063+ AllowObjCConversionOnExplicit, AllowResultConversion,
11064+ /*AllowExplicit=*/false,
11065+ /*SuppressUserConversions=*/false,
11066+ /*PartialOverloading*/ false,
11067+ /*AggregateCandidateDeduction=*/false},
11068+ FunctionTemplate,
11069+ FoundDecl,
11070+ ActingContext,
11071+ From,
11072+ ToType};
1104711073}
1104811074
1104911075static void
1105011076AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11051- DeferredMethodTemplateOverloadCandidate && C) {
11077+ DeferredMethodTemplateOverloadCandidate &C) {
1105211078
1105311079 AddMethodTemplateCandidateImmediately(
1105411080 S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext,
@@ -11058,7 +11084,7 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
1105811084
1105911085static void
1106011086AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11061- DeferredFunctionTemplateOverloadCandidate && C) {
11087+ DeferredFunctionTemplateOverloadCandidate &C) {
1106211088 AddTemplateOverloadCandidateImmediately(
1106311089 S, CandidateSet, C.FunctionTemplate, C.FoundDecl,
1106411090 /*ExplicitTemplateArgs=*/nullptr, C.Args, C.SuppressUserConversions,
@@ -11068,23 +11094,38 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
1106811094
1106911095static void
1107011096AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11071- DeferredConversionTemplateOverloadCandidate && C) {
11097+ DeferredConversionTemplateOverloadCandidate &C) {
1107211098 return AddTemplateConversionCandidateImmediately(
1107311099 S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext, C.From,
1107411100 C.ToType, C.AllowObjCConversionOnExplicit, C.AllowExplicit,
1107511101 C.AllowResultConversion);
1107611102}
1107711103
1107811104void OverloadCandidateSet::InjectNonDeducedTemplateCandidates(Sema &S) {
11079- Candidates.reserve(Candidates.size() + DeferredCandidates.size());
11080- for (auto &&Elem : DeferredCandidates) {
11081- std::visit(
11082- [&](auto &&Cand) {
11083- AddTemplateOverloadCandidate(S, *this, std::move(Cand));
11084- },
11085- Elem);
11105+ Candidates.reserve(Candidates.size() + DeferredCandidatesCount);
11106+ DeferredTemplateOverloadCandidate *Cand = FirstDeferredCandidate;
11107+ while (Cand) {
11108+ switch (Cand->Kind) {
11109+ case DeferredTemplateOverloadCandidate::Function:
11110+ AddTemplateOverloadCandidate(
11111+ S, *this,
11112+ *static_cast<DeferredFunctionTemplateOverloadCandidate *>(Cand));
11113+ break;
11114+ case DeferredTemplateOverloadCandidate::Method:
11115+ AddTemplateOverloadCandidate(
11116+ S, *this,
11117+ *static_cast<DeferredMethodTemplateOverloadCandidate *>(Cand));
11118+ break;
11119+ case DeferredTemplateOverloadCandidate::Conversion:
11120+ AddTemplateOverloadCandidate(
11121+ S, *this,
11122+ *static_cast<DeferredConversionTemplateOverloadCandidate *>(Cand));
11123+ break;
11124+ }
11125+ Cand = Cand->Next;
1108611126 }
11087- DeferredCandidates.clear();
11127+ FirstDeferredCandidate = nullptr;
11128+ DeferredCandidatesCount = 0;
1108811129}
1108911130
1109011131OverloadingResult
@@ -11147,10 +11188,10 @@ OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
1114711188 iterator &Best) {
1114811189
1114911190 assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
11150- DeferredCandidates.empty() &&
11191+ DeferredCandidatesCount == 0 &&
1115111192 "Unexpected deferred template candidate");
1115211193
11153- bool TwoPhaseResolution = !DeferredCandidates.empty() ;
11194+ bool TwoPhaseResolution = DeferredCandidatesCount != 0 ;
1115411195
1115511196 if (TwoPhaseResolution) {
1115611197
@@ -11261,7 +11302,7 @@ OverloadingResult OverloadCandidateSet::BestViableFunctionImpl(
1126111302
1126211303 OverloadingResult R = ResultForBestCandidate(Best);
1126311304
11264- if (DeferredCandidates.empty() && !EquivalentCands.empty())
11305+ if (!EquivalentCands.empty())
1126511306 S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function,
1126611307 EquivalentCands);
1126711308 return R;
0 commit comments