@@ -408,13 +408,17 @@ class Sema;
408
408
}
409
409
410
410
bool isPerfect (const ASTContext &C) const {
411
- if (!isIdentityConversion ())
411
+ if (!isIdentityConversion ())
412
412
return false ;
413
- if (!ReferenceBinding)
413
+ // If we are not performing a reference binding, we can skip comparing
414
+ // the types, which has a noticeable performance impact.
415
+ if (!ReferenceBinding) {
416
+ assert (C.hasSameType (getFromType (), getToType (2 )));
414
417
return true ;
415
- if (!C.hasSameType (getFromType (), getToType (2 )))
418
+ }
419
+ if (!C.hasSameType (getFromType (), getToType (2 )))
416
420
return false ;
417
- if (BindsToRvalue && IsLvalueReference)
421
+ if (BindsToRvalue && IsLvalueReference)
418
422
return false ;
419
423
return true ;
420
424
}
@@ -755,6 +759,9 @@ class Sema;
755
759
Standard.setAllToTypes (T);
756
760
}
757
761
762
+ // / A conversion sequence is perfect if
763
+ // / it is an identity conversion and
764
+ // / the type of the source is the same as the type of the target.
758
765
bool isPerfect (const ASTContext &C) const {
759
766
return isStandard () && Standard.isPerfect (C);
760
767
}
@@ -995,6 +1002,8 @@ class Sema;
995
1002
return false ;
996
1003
}
997
1004
1005
+ // An overload is a perfect match if the conversion
1006
+ // sequences for each argument are perfect.
998
1007
bool isPerfectMatch (const ASTContext &Ctx) const {
999
1008
if (!Viable)
1000
1009
return false ;
@@ -1046,7 +1055,10 @@ class Sema;
1046
1055
};
1047
1056
1048
1057
struct DeferredTemplateOverloadCandidate {
1058
+
1059
+ // intrusive linked list support for allocateDeferredCandidate
1049
1060
DeferredTemplateOverloadCandidate *Next = nullptr ;
1061
+
1050
1062
enum Kind { Function, Method, Conversion };
1051
1063
1052
1064
LLVM_PREFERRED_TYPE (Kind)
@@ -1256,6 +1268,11 @@ class Sema;
1256
1268
return reinterpret_cast <T *>(FreeSpaceStart);
1257
1269
}
1258
1270
1271
+ // Because the size of OverloadCandidateSet has a noticeable impact on
1272
+ // performance, we store each deferred template candidate in the slab
1273
+ // allocator such that deferred candidates are ultimately a singly-linked
1274
+ // intrusive linked list. This ends up being much more efficient than a
1275
+ // SmallVector that is empty in the common case.
1259
1276
template <typename T> T *allocateDeferredCandidate () {
1260
1277
T *C = slabAllocate<T>(1 );
1261
1278
if (!FirstDeferredCandidate)
0 commit comments