@@ -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
@@ -11012,16 +11014,20 @@ void OverloadCandidateSet::AddDeferredTemplateCandidate(
1101211014 bool PartialOverloading, bool AllowExplicit,
1101311015 CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
1101411016 bool AggregateCandidateDeduction) {
11015- DeferredFunctionTemplateOverloadCandidate C{FunctionTemplate,
11016- FoundDecl,
11017- Args,
11018- IsADLCandidate,
11019- PO,
11020- SuppressUserConversions,
11021- PartialOverloading,
11022- AllowExplicit,
11023- AggregateCandidateDeduction};
11024- DeferredCandidates.emplace_back(std::move(C));
11017+
11018+ auto *C =
11019+ allocateDeferredCandidate<DeferredFunctionTemplateOverloadCandidate>();
11020+
11021+ C = new (C) DeferredFunctionTemplateOverloadCandidate{
11022+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Function,
11023+ /*AllowObjCConversionOnExplicit=*/false,
11024+ /*AllowResultConversion=*/false, AllowExplicit, SuppressUserConversions,
11025+ PartialOverloading, AggregateCandidateDeduction},
11026+ FunctionTemplate,
11027+ FoundDecl,
11028+ Args,
11029+ IsADLCandidate,
11030+ PO};
1102511031 HasDeferredTemplateConstructors |=
1102611032 isa<CXXConstructorDecl>(FunctionTemplate->getTemplatedDecl());
1102711033}
@@ -11032,11 +11038,23 @@ void OverloadCandidateSet::AddDeferredMethodTemplateCandidate(
1103211038 Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
1103311039 bool SuppressUserConversions, bool PartialOverloading,
1103411040 OverloadCandidateParamOrder PO) {
11035- DeferredMethodTemplateOverloadCandidate C{
11036- MethodTmpl, FoundDecl, Args, ActingContext,
11037- ObjectClassification, ObjectType, PO, SuppressUserConversions,
11038- PartialOverloading};
11039- DeferredCandidates.emplace_back(std::move(C));
11041+
11042+ auto *C =
11043+ allocateDeferredCandidate<DeferredMethodTemplateOverloadCandidate>();
11044+
11045+ C = new (C) DeferredMethodTemplateOverloadCandidate{
11046+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Method,
11047+ /*AllowObjCConversionOnExplicit=*/false,
11048+ /*AllowResultConversion=*/false,
11049+ /*AllowExplicit=*/false, SuppressUserConversions, PartialOverloading,
11050+ /*AggregateCandidateDeduction=*/false},
11051+ MethodTmpl,
11052+ FoundDecl,
11053+ Args,
11054+ ActingContext,
11055+ ObjectClassification,
11056+ ObjectType,
11057+ PO};
1104011058}
1104111059
1104211060void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
@@ -11045,18 +11063,26 @@ void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
1104511063 bool AllowObjCConversionOnExplicit, bool AllowExplicit,
1104611064 bool AllowResultConversion) {
1104711065
11048- DeferredConversionTemplateOverloadCandidate C{
11049- FunctionTemplate, FoundDecl,
11050- ActingContext, From,
11051- ToType, AllowObjCConversionOnExplicit,
11052- AllowExplicit, AllowResultConversion};
11066+ auto *C =
11067+ allocateDeferredCandidate<DeferredConversionTemplateOverloadCandidate>();
1105311068
11054- DeferredCandidates.emplace_back(std::move(C));
11069+ C = new (C) DeferredConversionTemplateOverloadCandidate{
11070+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Conversion,
11071+ AllowObjCConversionOnExplicit, AllowResultConversion,
11072+ /*AllowExplicit=*/false,
11073+ /*SuppressUserConversions=*/false,
11074+ /*PartialOverloading*/ false,
11075+ /*AggregateCandidateDeduction=*/false},
11076+ FunctionTemplate,
11077+ FoundDecl,
11078+ ActingContext,
11079+ From,
11080+ ToType};
1105511081}
1105611082
1105711083static void
1105811084AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11059- DeferredMethodTemplateOverloadCandidate && C) {
11085+ DeferredMethodTemplateOverloadCandidate &C) {
1106011086
1106111087 AddMethodTemplateCandidateImmediately(
1106211088 S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext,
@@ -11066,7 +11092,7 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
1106611092
1106711093static void
1106811094AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11069- DeferredFunctionTemplateOverloadCandidate && C) {
11095+ DeferredFunctionTemplateOverloadCandidate &C) {
1107011096 AddTemplateOverloadCandidateImmediately(
1107111097 S, CandidateSet, C.FunctionTemplate, C.FoundDecl,
1107211098 /*ExplicitTemplateArgs=*/nullptr, C.Args, C.SuppressUserConversions,
@@ -11076,23 +11102,38 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
1107611102
1107711103static void
1107811104AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11079- DeferredConversionTemplateOverloadCandidate && C) {
11105+ DeferredConversionTemplateOverloadCandidate &C) {
1108011106 return AddTemplateConversionCandidateImmediately(
1108111107 S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext, C.From,
1108211108 C.ToType, C.AllowObjCConversionOnExplicit, C.AllowExplicit,
1108311109 C.AllowResultConversion);
1108411110}
1108511111
1108611112void OverloadCandidateSet::InjectNonDeducedTemplateCandidates(Sema &S) {
11087- Candidates.reserve(Candidates.size() + DeferredCandidates.size());
11088- for (auto &&Elem : DeferredCandidates) {
11089- std::visit(
11090- [&](auto &&Cand) {
11091- AddTemplateOverloadCandidate(S, *this, std::move(Cand));
11092- },
11093- Elem);
11113+ Candidates.reserve(Candidates.size() + DeferredCandidatesCount);
11114+ DeferredTemplateOverloadCandidate *Cand = FirstDeferredCandidate;
11115+ while (Cand) {
11116+ switch (Cand->Kind) {
11117+ case DeferredTemplateOverloadCandidate::Function:
11118+ AddTemplateOverloadCandidate(
11119+ S, *this,
11120+ *static_cast<DeferredFunctionTemplateOverloadCandidate *>(Cand));
11121+ break;
11122+ case DeferredTemplateOverloadCandidate::Method:
11123+ AddTemplateOverloadCandidate(
11124+ S, *this,
11125+ *static_cast<DeferredMethodTemplateOverloadCandidate *>(Cand));
11126+ break;
11127+ case DeferredTemplateOverloadCandidate::Conversion:
11128+ AddTemplateOverloadCandidate(
11129+ S, *this,
11130+ *static_cast<DeferredConversionTemplateOverloadCandidate *>(Cand));
11131+ break;
11132+ }
11133+ Cand = Cand->Next;
1109411134 }
11095- DeferredCandidates.clear();
11135+ FirstDeferredCandidate = nullptr;
11136+ DeferredCandidatesCount = 0;
1109611137}
1109711138
1109811139OverloadingResult
@@ -11155,10 +11196,10 @@ OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
1115511196 iterator &Best) {
1115611197
1115711198 assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
11158- DeferredCandidates.empty() &&
11199+ DeferredCandidatesCount == 0 &&
1115911200 "Unexpected deferred template candidate");
1116011201
11161- bool TwoPhaseResolution = !DeferredCandidates.empty() ;
11202+ bool TwoPhaseResolution = DeferredCandidatesCount != 0 ;
1116211203
1116311204 if (TwoPhaseResolution) {
1116411205
@@ -11269,7 +11310,7 @@ OverloadingResult OverloadCandidateSet::BestViableFunctionImpl(
1126911310
1127011311 OverloadingResult R = ResultForBestCandidate(Best);
1127111312
11272- if (DeferredCandidates.empty() && !EquivalentCands.empty())
11313+ if (!EquivalentCands.empty())
1127311314 S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function,
1127411315 EquivalentCands);
1127511316 return R;
0 commit comments