@@ -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
@@ -11004,16 +11006,20 @@ void OverloadCandidateSet::AddDeferredTemplateCandidate(
11004
11006
bool PartialOverloading, bool AllowExplicit,
11005
11007
CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
11006
11008
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};
11017
11023
HasDeferredTemplateConstructors |=
11018
11024
isa<CXXConstructorDecl>(FunctionTemplate->getTemplatedDecl());
11019
11025
}
@@ -11024,11 +11030,23 @@ void OverloadCandidateSet::AddDeferredMethodTemplateCandidate(
11024
11030
Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
11025
11031
bool SuppressUserConversions, bool PartialOverloading,
11026
11032
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};
11032
11050
}
11033
11051
11034
11052
void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
@@ -11037,18 +11055,26 @@ void OverloadCandidateSet::AddDeferredConversionTemplateCandidate(
11037
11055
bool AllowObjCConversionOnExplicit, bool AllowExplicit,
11038
11056
bool AllowResultConversion) {
11039
11057
11040
- DeferredConversionTemplateOverloadCandidate C{
11041
- FunctionTemplate, FoundDecl,
11042
- ActingContext, From,
11043
- ToType, AllowObjCConversionOnExplicit,
11044
- AllowExplicit, AllowResultConversion};
11058
+ auto *C =
11059
+ allocateDeferredCandidate<DeferredConversionTemplateOverloadCandidate>();
11045
11060
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};
11047
11073
}
11048
11074
11049
11075
static void
11050
11076
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11051
- DeferredMethodTemplateOverloadCandidate && C) {
11077
+ DeferredMethodTemplateOverloadCandidate &C) {
11052
11078
11053
11079
AddMethodTemplateCandidateImmediately(
11054
11080
S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext,
@@ -11058,7 +11084,7 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11058
11084
11059
11085
static void
11060
11086
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11061
- DeferredFunctionTemplateOverloadCandidate && C) {
11087
+ DeferredFunctionTemplateOverloadCandidate &C) {
11062
11088
AddTemplateOverloadCandidateImmediately(
11063
11089
S, CandidateSet, C.FunctionTemplate, C.FoundDecl,
11064
11090
/*ExplicitTemplateArgs=*/nullptr, C.Args, C.SuppressUserConversions,
@@ -11068,23 +11094,38 @@ AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11068
11094
11069
11095
static void
11070
11096
AddTemplateOverloadCandidate(Sema &S, OverloadCandidateSet &CandidateSet,
11071
- DeferredConversionTemplateOverloadCandidate && C) {
11097
+ DeferredConversionTemplateOverloadCandidate &C) {
11072
11098
return AddTemplateConversionCandidateImmediately(
11073
11099
S, CandidateSet, C.FunctionTemplate, C.FoundDecl, C.ActingContext, C.From,
11074
11100
C.ToType, C.AllowObjCConversionOnExplicit, C.AllowExplicit,
11075
11101
C.AllowResultConversion);
11076
11102
}
11077
11103
11078
11104
void 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;
11086
11126
}
11087
- DeferredCandidates.clear();
11127
+ FirstDeferredCandidate = nullptr;
11128
+ DeferredCandidatesCount = 0;
11088
11129
}
11089
11130
11090
11131
OverloadingResult
@@ -11147,10 +11188,10 @@ OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
11147
11188
iterator &Best) {
11148
11189
11149
11190
assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
11150
- DeferredCandidates.empty() &&
11191
+ DeferredCandidatesCount == 0 &&
11151
11192
"Unexpected deferred template candidate");
11152
11193
11153
- bool TwoPhaseResolution = !DeferredCandidates.empty() ;
11194
+ bool TwoPhaseResolution = DeferredCandidatesCount != 0 ;
11154
11195
11155
11196
if (TwoPhaseResolution) {
11156
11197
@@ -11261,7 +11302,7 @@ OverloadingResult OverloadCandidateSet::BestViableFunctionImpl(
11261
11302
11262
11303
OverloadingResult R = ResultForBestCandidate(Best);
11263
11304
11264
- if (DeferredCandidates.empty() && !EquivalentCands.empty())
11305
+ if (!EquivalentCands.empty())
11265
11306
S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function,
11266
11307
EquivalentCands);
11267
11308
return R;
0 commit comments