@@ -1124,6 +1124,8 @@ void OverloadCandidateSet::clear(CandidateSetKind CSK) {
1124
1124
Candidates.clear();
1125
1125
Functions.clear();
1126
1126
Kind = CSK;
1127
+ FirstDeferredCandidate = nullptr;
1128
+ DeferredCandidatesCount = 0;
1127
1129
HasDeferredTemplateConstructors = false;
1128
1130
}
1129
1131
@@ -11008,16 +11010,20 @@ void OverloadCandidateSet::AddDeferredTemplateCandidate(
11008
11010
bool PartialOverloading, bool AllowExplicit,
11009
11011
CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
11010
11012
bool AggregateCandidateDeduction) {
11011
- DeferredFunctionTemplateOverloadCandidate C{FunctionTemplate,
11012
- FoundDecl,
11013
- Args,
11014
- IsADLCandidate,
11015
- PO,
11016
- SuppressUserConversions,
11017
- PartialOverloading,
11018
- AllowExplicit,
11019
- AggregateCandidateDeduction};
11020
- DeferredCandidates.emplace_back(std::move(C));
11013
+
11014
+ auto *C =
11015
+ allocateDeferredCandidate<DeferredFunctionTemplateOverloadCandidate>();
11016
+
11017
+ C = new (C) DeferredFunctionTemplateOverloadCandidate{
11018
+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Function,
11019
+ /*AllowObjCConversionOnExplicit=*/false,
11020
+ /*AllowResultConversion=*/false, AllowExplicit, SuppressUserConversions,
11021
+ PartialOverloading, AggregateCandidateDeduction},
11022
+ FunctionTemplate,
11023
+ FoundDecl,
11024
+ Args,
11025
+ IsADLCandidate,
11026
+ PO};
11021
11027
HasDeferredTemplateConstructors |=
11022
11028
isa<CXXConstructorDecl>(FunctionTemplate->getTemplatedDecl());
11023
11029
}
@@ -11028,11 +11034,23 @@ void OverloadCandidateSet::AddDeferredMethodTemplateCandidate(
11028
11034
Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
11029
11035
bool SuppressUserConversions, bool PartialOverloading,
11030
11036
OverloadCandidateParamOrder PO) {
11031
- DeferredMethodTemplateOverloadCandidate C{
11032
- MethodTmpl, FoundDecl, Args, ActingContext,
11033
- ObjectClassification, ObjectType, PO, SuppressUserConversions,
11034
- PartialOverloading};
11035
- DeferredCandidates.emplace_back(std::move(C));
11037
+
11038
+ auto *C =
11039
+ allocateDeferredCandidate<DeferredMethodTemplateOverloadCandidate>();
11040
+
11041
+ C = new (C) DeferredMethodTemplateOverloadCandidate{
11042
+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Method,
11043
+ /*AllowObjCConversionOnExplicit=*/false,
11044
+ /*AllowResultConversion=*/false,
11045
+ /*AllowExplicit=*/false, SuppressUserConversions, PartialOverloading,
11046
+ /*AggregateCandidateDeduction=*/false},
11047
+ MethodTmpl,
11048
+ FoundDecl,
11049
+ Args,
11050
+ ActingContext,
11051
+ ObjectClassification,
11052
+ ObjectType,
11053
+ PO};
11036
11054
}
11037
11055
11038
11056
void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
@@ -11041,18 +11059,26 @@ void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
11041
11059
bool AllowObjCConversionOnExplicit, bool AllowExplicit,
11042
11060
bool AllowResultConversion) {
11043
11061
11044
- DeferredConversionTemplateOverloadCandidate C{
11045
- FunctionTemplate, FoundDecl,
11046
- ActingContext, From,
11047
- ToType, AllowObjCConversionOnExplicit,
11048
- AllowExplicit, AllowResultConversion};
11062
+ auto *C =
11063
+ allocateDeferredCandidate<DeferredConversionTemplateOverloadCandidate>();
11049
11064
11050
- DeferredCandidates.emplace_back(std::move(C));
11065
+ C = new (C) DeferredConversionTemplateOverloadCandidate{
11066
+ {nullptr, DeferredFunctionTemplateOverloadCandidate::Conversion,
11067
+ AllowObjCConversionOnExplicit, AllowResultConversion,
11068
+ /*AllowExplicit=*/false,
11069
+ /*SuppressUserConversions=*/false,
11070
+ /*PartialOverloading*/ false,
11071
+ /*AggregateCandidateDeduction=*/false},
11072
+ FunctionTemplate,
11073
+ FoundDecl,
11074
+ ActingContext,
11075
+ From,
11076
+ ToType};
11051
11077
}
11052
11078
11053
11079
static void
11054
11080
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11055
- DeferredMethodTemplateOverloadCandidate && C) {
11081
+ DeferredMethodTemplateOverloadCandidate &C) {
11056
11082
11057
11083
AddMethodTemplateCandidateImmediately(
11058
11084
S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext,
@@ -11062,7 +11088,7 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11062
11088
11063
11089
static void
11064
11090
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11065
- DeferredFunctionTemplateOverloadCandidate && C) {
11091
+ DeferredFunctionTemplateOverloadCandidate &C) {
11066
11092
AddTemplateOverloadCandidateImmediately(
11067
11093
S, CandidateSet, C.FunctionTemplate, C.FoundDecl,
11068
11094
/*ExplicitTemplateArgs=*/nullptr, C.Args, C.SuppressUserConversions,
@@ -11072,23 +11098,38 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11072
11098
11073
11099
static void
11074
11100
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11075
- DeferredConversionTemplateOverloadCandidate && C) {
11101
+ DeferredConversionTemplateOverloadCandidate &C) {
11076
11102
return AddTemplateConversionCandidateImmediately(
11077
11103
S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext, C.From,
11078
11104
C.ToType, C.AllowObjCConversionOnExplicit, C.AllowExplicit,
11079
11105
C.AllowResultConversion);
11080
11106
}
11081
11107
11082
11108
void OverloadCandidateSet::InjectNonDeducedTemplateCandidates(Sema &S) {
11083
- Candidates.reserve(Candidates.size() + DeferredCandidates.size());
11084
- for (auto &&Elem : DeferredCandidates) {
11085
- std::visit(
11086
- [&](auto &&Cand) {
11087
- AddTemplateOverloadCandidate(S, *this, std::move(Cand));
11088
- },
11089
- Elem);
11109
+ Candidates.reserve(Candidates.size() + DeferredCandidatesCount);
11110
+ DeferredTemplateOverloadCandidate *Cand = FirstDeferredCandidate;
11111
+ while (Cand) {
11112
+ switch (Cand->Kind) {
11113
+ case DeferredTemplateOverloadCandidate::Function:
11114
+ AddTemplateOverloadCandidate(
11115
+ S, *this,
11116
+ *static_cast<DeferredFunctionTemplateOverloadCandidate *>(Cand));
11117
+ break;
11118
+ case DeferredTemplateOverloadCandidate::Method:
11119
+ AddTemplateOverloadCandidate(
11120
+ S, *this,
11121
+ *static_cast<DeferredMethodTemplateOverloadCandidate *>(Cand));
11122
+ break;
11123
+ case DeferredTemplateOverloadCandidate::Conversion:
11124
+ AddTemplateOverloadCandidate(
11125
+ S, *this,
11126
+ *static_cast<DeferredConversionTemplateOverloadCandidate *>(Cand));
11127
+ break;
11128
+ }
11129
+ Cand = Cand->Next;
11090
11130
}
11091
- DeferredCandidates.clear();
11131
+ FirstDeferredCandidate = nullptr;
11132
+ DeferredCandidatesCount = 0;
11092
11133
}
11093
11134
11094
11135
OverloadingResult
@@ -11151,10 +11192,10 @@ OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
11151
11192
iterator &Best) {
11152
11193
11153
11194
assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
11154
- DeferredCandidates.empty() &&
11195
+ DeferredCandidatesCount == 0 &&
11155
11196
"Unexpected deferred template candidate");
11156
11197
11157
- bool TwoPhaseResolution = !DeferredCandidates.empty() ;
11198
+ bool TwoPhaseResolution = DeferredCandidatesCount != 0 ;
11158
11199
11159
11200
if (TwoPhaseResolution) {
11160
11201
@@ -11265,7 +11306,7 @@ OverloadingResult OverloadCandidateSet::BestViableFunctionImpl(
11265
11306
11266
11307
OverloadingResult R = ResultForBestCandidate(Best);
11267
11308
11268
- if (DeferredCandidates.empty() && !EquivalentCands.empty())
11309
+ if (!EquivalentCands.empty())
11269
11310
S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function,
11270
11311
EquivalentCands);
11271
11312
return R;
0 commit comments