@@ -407,6 +407,24 @@ class Sema;
407
407
Third == ICK_Identity;
408
408
}
409
409
410
+ // / A conversion sequence is perfect if it is an identity conversion and
411
+ // / the type of the source is the same as the type of the target.
412
+ bool isPerfect (const ASTContext &C) const {
413
+ if (!isIdentityConversion ())
414
+ return false ;
415
+ // If we are not performing a reference binding, we can skip comparing
416
+ // the types, which has a noticeable performance impact.
417
+ if (!ReferenceBinding) {
418
+ assert (First || C.hasSameUnqualifiedType (getFromType (), getToType (2 )));
419
+ return true ;
420
+ }
421
+ if (!C.hasSameType (getFromType (), getToType (2 )))
422
+ return false ;
423
+ if (BindsToRvalue && IsLvalueReference)
424
+ return false ;
425
+ return true ;
426
+ }
427
+
410
428
ImplicitConversionRank getRank () const ;
411
429
NarrowingKind
412
430
getNarrowingKind (ASTContext &Context, const Expr *Converted,
@@ -743,6 +761,12 @@ class Sema;
743
761
Standard.setAllToTypes (T);
744
762
}
745
763
764
+ // / A conversion sequence is perfect if it is an identity conversion and
765
+ // / the type of the source is the same as the type of the target.
766
+ bool isPerfect (const ASTContext &C) const {
767
+ return isStandard () && Standard.isPerfect (C);
768
+ }
769
+
746
770
// True iff this is a conversion sequence from an initializer list to an
747
771
// array or std::initializer.
748
772
bool hasInitializerListContainerType () const {
@@ -979,6 +1003,20 @@ class Sema;
979
1003
return false ;
980
1004
}
981
1005
1006
+ // An overload is a perfect match if the conversion
1007
+ // sequences for each argument are perfect.
1008
+ bool isPerfectMatch (const ASTContext &Ctx) const {
1009
+ if (!Viable)
1010
+ return false ;
1011
+ for (const auto &C : Conversions) {
1012
+ if (!C.isInitialized () || !C.isPerfect (Ctx))
1013
+ return false ;
1014
+ }
1015
+ if (isa_and_nonnull<CXXConversionDecl>(Function))
1016
+ return FinalConversion.isPerfect (Ctx);
1017
+ return true ;
1018
+ }
1019
+
982
1020
bool TryToFixBadConversion (unsigned Idx, Sema &S) {
983
1021
bool CanFix = Fix.tryToFixConversion (
984
1022
Conversions[Idx].Bad .FromExpr ,
@@ -1015,6 +1053,65 @@ class Sema;
1015
1053
RewriteKind(CRK_None) {}
1016
1054
};
1017
1055
1056
+ struct DeferredTemplateOverloadCandidate {
1057
+
1058
+ // intrusive linked list support for allocateDeferredCandidate
1059
+ DeferredTemplateOverloadCandidate *Next = nullptr ;
1060
+
1061
+ enum Kind { Function, Method, Conversion };
1062
+
1063
+ LLVM_PREFERRED_TYPE (Kind)
1064
+ unsigned Kind : 2 ;
1065
+ LLVM_PREFERRED_TYPE (bool )
1066
+ unsigned AllowObjCConversionOnExplicit : 1 ;
1067
+ LLVM_PREFERRED_TYPE (bool )
1068
+ unsigned AllowResultConversion : 1 ;
1069
+ LLVM_PREFERRED_TYPE (bool )
1070
+ unsigned AllowExplicit : 1 ;
1071
+ LLVM_PREFERRED_TYPE (bool )
1072
+ unsigned SuppressUserConversions : 1 ;
1073
+ LLVM_PREFERRED_TYPE (bool )
1074
+ unsigned PartialOverloading : 1 ;
1075
+ LLVM_PREFERRED_TYPE (bool )
1076
+ unsigned AggregateCandidateDeduction : 1 ;
1077
+ };
1078
+
1079
+ struct DeferredFunctionTemplateOverloadCandidate
1080
+ : public DeferredTemplateOverloadCandidate {
1081
+ FunctionTemplateDecl *FunctionTemplate;
1082
+ DeclAccessPair FoundDecl;
1083
+ ArrayRef<Expr *> Args;
1084
+ CallExpr::ADLCallKind IsADLCandidate;
1085
+ OverloadCandidateParamOrder PO;
1086
+ };
1087
+ static_assert (std::is_trivially_destructible_v<
1088
+ DeferredFunctionTemplateOverloadCandidate>);
1089
+
1090
+ struct DeferredMethodTemplateOverloadCandidate
1091
+ : public DeferredTemplateOverloadCandidate {
1092
+ FunctionTemplateDecl *FunctionTemplate;
1093
+ DeclAccessPair FoundDecl;
1094
+ ArrayRef<Expr *> Args;
1095
+ CXXRecordDecl *ActingContext;
1096
+ Expr::Classification ObjectClassification;
1097
+ QualType ObjectType;
1098
+ OverloadCandidateParamOrder PO;
1099
+ };
1100
+ static_assert (std::is_trivially_destructible_v<
1101
+ DeferredMethodTemplateOverloadCandidate>);
1102
+
1103
+ struct DeferredConversionTemplateOverloadCandidate
1104
+ : public DeferredTemplateOverloadCandidate {
1105
+ FunctionTemplateDecl *FunctionTemplate;
1106
+ DeclAccessPair FoundDecl;
1107
+ CXXRecordDecl *ActingContext;
1108
+ Expr *From;
1109
+ QualType ToType;
1110
+ };
1111
+
1112
+ static_assert (std::is_trivially_destructible_v<
1113
+ DeferredConversionTemplateOverloadCandidate>);
1114
+
1018
1115
// / OverloadCandidateSet - A set of overload candidates, used in C++
1019
1116
// / overload resolution (C++ 13.3).
1020
1117
class OverloadCandidateSet {
@@ -1043,6 +1140,11 @@ class Sema;
1043
1140
// / C++ [over.match.call.general]
1044
1141
// / Resolve a call through the address of an overload set.
1045
1142
CSK_AddressOfOverloadSet,
1143
+
1144
+ // / When doing overload resolution during code completion,
1145
+ // / we want to show all viable candidates, including otherwise
1146
+ // / deferred template candidates.
1147
+ CSK_CodeCompletion,
1046
1148
};
1047
1149
1048
1150
// / Information about operator rewrites to consider when adding operator
@@ -1117,16 +1219,27 @@ class Sema;
1117
1219
SmallVector<OverloadCandidate, 16 > Candidates;
1118
1220
llvm::SmallPtrSet<uintptr_t , 16 > Functions;
1119
1221
1120
- // Allocator for ConversionSequenceLists. We store the first few of these
1222
+ DeferredTemplateOverloadCandidate *FirstDeferredCandidate = nullptr ;
1223
+ unsigned DeferredCandidatesCount : 8 * sizeof (unsigned ) - 2 ;
1224
+ LLVM_PREFERRED_TYPE (bool )
1225
+ unsigned HasDeferredTemplateConstructors : 1;
1226
+ LLVM_PREFERRED_TYPE (bool )
1227
+ unsigned ResolutionByPerfectCandidateIsDisabled : 1;
1228
+
1229
+ // Allocator for ConversionSequenceLists and deferred candidate args.
1230
+ // We store the first few of these
1121
1231
// inline to avoid allocation for small sets.
1122
1232
llvm::BumpPtrAllocator SlabAllocator;
1123
1233
1124
1234
SourceLocation Loc;
1125
1235
CandidateSetKind Kind;
1126
1236
OperatorRewriteInfo RewriteInfo;
1127
1237
1238
+ // / Small storage size for ImplicitConversionSequences
1239
+ // / and the persisted arguments of deferred candidates.
1128
1240
constexpr static unsigned NumInlineBytes =
1129
- 24 * sizeof (ImplicitConversionSequence);
1241
+ 32 * sizeof (ImplicitConversionSequence);
1242
+
1130
1243
unsigned NumInlineBytesUsed = 0 ;
1131
1244
alignas (void *) char InlineSpace[NumInlineBytes];
1132
1245
@@ -1137,15 +1250,13 @@ class Sema;
1137
1250
// / from the slab allocator.
1138
1251
// / FIXME: It would probably be nice to have a SmallBumpPtrAllocator
1139
1252
// / instead.
1140
- // / FIXME: Now that this only allocates ImplicitConversionSequences, do we
1141
- // / want to un-generalize this?
1142
1253
template <typename T>
1143
1254
T *slabAllocate (unsigned N) {
1144
1255
// It's simpler if this doesn't need to consider alignment.
1145
1256
static_assert (alignof (T) == alignof (void *),
1146
1257
" Only works for pointer-aligned types." );
1147
- static_assert (std::is_trivial <T>::value ||
1148
- std::is_same <ImplicitConversionSequence, T>::value ,
1258
+ static_assert (std::is_trivially_destructible_v <T> ||
1259
+ ( std::is_same_v <ImplicitConversionSequence, T>) ,
1149
1260
" Add destruction logic to OverloadCandidateSet::clear()." );
1150
1261
1151
1262
unsigned NBytes = sizeof (T) * N;
@@ -1159,12 +1270,34 @@ class Sema;
1159
1270
return reinterpret_cast <T *>(FreeSpaceStart);
1160
1271
}
1161
1272
1273
+ // Because the size of OverloadCandidateSet has a noticeable impact on
1274
+ // performance, we store each deferred template candidate in the slab
1275
+ // allocator such that deferred candidates are ultimately a singly-linked
1276
+ // intrusive linked list. This ends up being much more efficient than a
1277
+ // SmallVector that is empty in the common case.
1278
+ template <typename T> T *allocateDeferredCandidate () {
1279
+ T *C = slabAllocate<T>(1 );
1280
+ if (!FirstDeferredCandidate)
1281
+ FirstDeferredCandidate = C;
1282
+ else {
1283
+ auto *F = FirstDeferredCandidate;
1284
+ while (F->Next )
1285
+ F = F->Next ;
1286
+ F->Next = C;
1287
+ }
1288
+ DeferredCandidatesCount++;
1289
+ return C;
1290
+ }
1291
+
1162
1292
void destroyCandidates ();
1163
1293
1164
1294
public:
1165
1295
OverloadCandidateSet (SourceLocation Loc, CandidateSetKind CSK,
1166
1296
OperatorRewriteInfo RewriteInfo = {})
1167
- : Loc(Loc), Kind(CSK), RewriteInfo(RewriteInfo) {}
1297
+ : FirstDeferredCandidate(nullptr ), DeferredCandidatesCount(0 ),
1298
+ HasDeferredTemplateConstructors(false ),
1299
+ ResolutionByPerfectCandidateIsDisabled(false ), Loc(Loc), Kind(CSK),
1300
+ RewriteInfo(RewriteInfo) {}
1168
1301
OverloadCandidateSet (const OverloadCandidateSet &) = delete;
1169
1302
OverloadCandidateSet &operator =(const OverloadCandidateSet &) = delete ;
1170
1303
~OverloadCandidateSet () { destroyCandidates (); }
@@ -1176,6 +1309,9 @@ class Sema;
1176
1309
// / Whether diagnostics should be deferred.
1177
1310
bool shouldDeferDiags (Sema &S, ArrayRef<Expr *> Args, SourceLocation OpLoc);
1178
1311
1312
+ // Whether the resolution of template candidates should be deferred
1313
+ bool shouldDeferTemplateArgumentDeduction (const LangOptions &Opts) const ;
1314
+
1179
1315
// / Determine when this overload candidate will be new to the
1180
1316
// / overload set.
1181
1317
bool isNewCandidate (Decl *F, OverloadCandidateParamOrder PO =
@@ -1199,8 +1335,10 @@ class Sema;
1199
1335
iterator begin () { return Candidates.begin (); }
1200
1336
iterator end () { return Candidates.end (); }
1201
1337
1202
- size_t size () const { return Candidates.size (); }
1203
- bool empty () const { return Candidates.empty (); }
1338
+ size_t size () const { return Candidates.size () + DeferredCandidatesCount; }
1339
+ bool empty () const {
1340
+ return Candidates.empty () && DeferredCandidatesCount == 0 ;
1341
+ }
1204
1342
1205
1343
// / Allocate storage for conversion sequences for NumConversions
1206
1344
// / conversions.
@@ -1216,6 +1354,24 @@ class Sema;
1216
1354
return ConversionSequenceList (Conversions, NumConversions);
1217
1355
}
1218
1356
1357
+ // / Provide storage for any Expr* arg that must be preserved
1358
+ // / until deferred template candidates are deduced.
1359
+ // / Typically this should be used for reversed operator arguments
1360
+ // / and any time the argument array is transformed while adding
1361
+ // / a template candidate.
1362
+ llvm::MutableArrayRef<Expr *> getPersistentArgsArray (unsigned N) {
1363
+ Expr **Exprs = slabAllocate<Expr *>(N);
1364
+ return llvm::MutableArrayRef<Expr *>(Exprs, N);
1365
+ }
1366
+
1367
+ template <typename ... T>
1368
+ llvm::MutableArrayRef<Expr *> getPersistentArgsArray (T *...Exprs) {
1369
+ llvm::MutableArrayRef<Expr *> Arr =
1370
+ getPersistentArgsArray (sizeof ...(Exprs));
1371
+ llvm::copy (std::initializer_list<Expr *>{Exprs...}, Arr.data ());
1372
+ return Arr;
1373
+ }
1374
+
1219
1375
// / Add a new candidate with NumConversions conversion sequence slots
1220
1376
// / to the overload set.
1221
1377
OverloadCandidate &addCandidate (unsigned NumConversions = 0 ,
@@ -1231,6 +1387,32 @@ class Sema;
1231
1387
return C;
1232
1388
}
1233
1389
1390
+ void AddDeferredTemplateCandidate (
1391
+ FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
1392
+ ArrayRef<Expr *> Args, bool SuppressUserConversions,
1393
+ bool PartialOverloading, bool AllowExplicit,
1394
+ CallExpr::ADLCallKind IsADLCandidate, OverloadCandidateParamOrder PO,
1395
+ bool AggregateCandidateDeduction);
1396
+
1397
+ void AddDeferredMethodTemplateCandidate (
1398
+ FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl,
1399
+ CXXRecordDecl *ActingContext, QualType ObjectType,
1400
+ Expr::Classification ObjectClassification, ArrayRef<Expr *> Args,
1401
+ bool SuppressUserConversions, bool PartialOverloading,
1402
+ OverloadCandidateParamOrder PO);
1403
+
1404
+ void AddDeferredConversionTemplateCandidate (
1405
+ FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl,
1406
+ CXXRecordDecl *ActingContext, Expr *From, QualType ToType,
1407
+ bool AllowObjCConversionOnExplicit, bool AllowExplicit,
1408
+ bool AllowResultConversion);
1409
+
1410
+ void InjectNonDeducedTemplateCandidates (Sema &S);
1411
+
1412
+ void DisableResolutionByPerfectCandidate () {
1413
+ ResolutionByPerfectCandidateIsDisabled = true ;
1414
+ }
1415
+
1234
1416
// / Find the best viable function on this overload set, if it exists.
1235
1417
OverloadingResult BestViableFunction (Sema &S, SourceLocation Loc,
1236
1418
OverloadCandidateSet::iterator& Best);
@@ -1263,6 +1445,15 @@ class Sema;
1263
1445
DestAS = AS;
1264
1446
}
1265
1447
1448
+ private:
1449
+ OverloadingResult ResultForBestCandidate (const iterator &Best);
1450
+ void CudaExcludeWrongSideCandidates (
1451
+ Sema &S, SmallVectorImpl<OverloadCandidate *> &Candidates);
1452
+ OverloadingResult
1453
+ BestViableFunctionImpl (Sema &S, SourceLocation Loc,
1454
+ OverloadCandidateSet::iterator &Best);
1455
+ void PerfectViableFunction (Sema &S, SourceLocation Loc,
1456
+ OverloadCandidateSet::iterator &Best);
1266
1457
};
1267
1458
1268
1459
bool isBetterOverloadCandidate (Sema &S, const OverloadCandidate &Cand1,
@@ -1311,6 +1502,21 @@ class Sema;
1311
1502
// parameter.
1312
1503
bool shouldEnforceArgLimit (bool PartialOverloading, FunctionDecl *Function);
1313
1504
1505
+ inline bool OverloadCandidateSet::shouldDeferTemplateArgumentDeduction (
1506
+ const LangOptions &Opts) const {
1507
+ return
1508
+ // For user defined conversion we need to check against different
1509
+ // combination of CV qualifiers and look at any explicit specifier, so
1510
+ // always deduce template candidates.
1511
+ Kind != CSK_InitByUserDefinedConversion
1512
+ // When doing code completion, we want to see all the
1513
+ // viable candidates.
1514
+ && Kind != CSK_CodeCompletion
1515
+ // CUDA may prefer template candidates even when a non-candidate
1516
+ // is a perfect match
1517
+ && !Opts.CUDA ;
1518
+ }
1519
+
1314
1520
} // namespace clang
1315
1521
1316
1522
#endif // LLVM_CLANG_SEMA_OVERLOAD_H
0 commit comments