@@ -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
@@ -11012,16 +11014,20 @@ void OverloadCandidateSet::AddDeferredTemplateCandidate(
11012
11014
bool PartialOverloading, bool AllowExplicit,
11013
11015
CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
11014
11016
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};
11025
11031
HasDeferredTemplateConstructors |=
11026
11032
isa<CXXConstructorDecl>(FunctionTemplate->getTemplatedDecl());
11027
11033
}
@@ -11032,11 +11038,23 @@ void OverloadCandidateSet::AddDeferredMethodTemplateCandidate(
11032
11038
Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
11033
11039
bool SuppressUserConversions, bool PartialOverloading,
11034
11040
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};
11040
11058
}
11041
11059
11042
11060
void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
@@ -11045,18 +11063,26 @@ void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
11045
11063
bool AllowObjCConversionOnExplicit, bool AllowExplicit,
11046
11064
bool AllowResultConversion) {
11047
11065
11048
- DeferredConversionTemplateOverloadCandidate C{
11049
- FunctionTemplate, FoundDecl,
11050
- ActingContext, From,
11051
- ToType, AllowObjCConversionOnExplicit,
11052
- AllowExplicit, AllowResultConversion};
11066
+ auto *C =
11067
+ allocateDeferredCandidate<DeferredConversionTemplateOverloadCandidate>();
11053
11068
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};
11055
11081
}
11056
11082
11057
11083
static void
11058
11084
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11059
- DeferredMethodTemplateOverloadCandidate && C) {
11085
+ DeferredMethodTemplateOverloadCandidate &C) {
11060
11086
11061
11087
AddMethodTemplateCandidateImmediately(
11062
11088
S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext,
@@ -11066,7 +11092,7 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11066
11092
11067
11093
static void
11068
11094
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11069
- DeferredFunctionTemplateOverloadCandidate && C) {
11095
+ DeferredFunctionTemplateOverloadCandidate &C) {
11070
11096
AddTemplateOverloadCandidateImmediately(
11071
11097
S, CandidateSet, C.FunctionTemplate, C.FoundDecl,
11072
11098
/*ExplicitTemplateArgs=*/nullptr, C.Args, C.SuppressUserConversions,
@@ -11076,23 +11102,38 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11076
11102
11077
11103
static void
11078
11104
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11079
- DeferredConversionTemplateOverloadCandidate && C) {
11105
+ DeferredConversionTemplateOverloadCandidate &C) {
11080
11106
return AddTemplateConversionCandidateImmediately(
11081
11107
S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext, C.From,
11082
11108
C.ToType, C.AllowObjCConversionOnExplicit, C.AllowExplicit,
11083
11109
C.AllowResultConversion);
11084
11110
}
11085
11111
11086
11112
void 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;
11094
11134
}
11095
- DeferredCandidates.clear();
11135
+ FirstDeferredCandidate = nullptr;
11136
+ DeferredCandidatesCount = 0;
11096
11137
}
11097
11138
11098
11139
OverloadingResult
@@ -11155,10 +11196,10 @@ OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
11155
11196
iterator &Best) {
11156
11197
11157
11198
assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
11158
- DeferredCandidates.empty() &&
11199
+ DeferredCandidatesCount == 0 &&
11159
11200
"Unexpected deferred template candidate");
11160
11201
11161
- bool TwoPhaseResolution = !DeferredCandidates.empty() ;
11202
+ bool TwoPhaseResolution = DeferredCandidatesCount != 0 ;
11162
11203
11163
11204
if (TwoPhaseResolution) {
11164
11205
@@ -11269,7 +11310,7 @@ OverloadingResult OverloadCandidateSet::BestViableFunctionImpl(
11269
11310
11270
11311
OverloadingResult R = ResultForBestCandidate(Best);
11271
11312
11272
- if (DeferredCandidates.empty() && !EquivalentCands.empty())
11313
+ if (!EquivalentCands.empty())
11273
11314
S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function,
11274
11315
EquivalentCands);
11275
11316
return R;
0 commit comments