clang: lib/Sema/SemaTypeTraits.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
27#include "llvm/ADT/STLExtras.h"
28
29using namespace clang;
30
33 bool Assign) {
36
39 Expr *Arg = nullptr;
40 unsigned NumArgs;
41
44
45 if (Assign)
46 Name =
48 else
49 Name =
51
53 NumArgs = 1;
54 Arg = &FakeArg;
55
56
61
62
63
64
67
69 return nullptr;
70
71
72
74
75 for (NamedDecl *CandDecl : Candidates) {
76 if (CandDecl->isInvalidDecl())
77 continue;
78
82 if (Assign)
84 ThisTy, Classification,
86 else {
87 assert(CtorInfo);
90 true);
91 }
94 if (Assign)
96 Tmpl, Cand, const_cast<CXXRecordDecl *>(RD), nullptr, ThisTy,
97 Classification, llvm::ArrayRef(&Arg, NumArgs), OCS, true);
98 else {
99 assert(CtorInfo);
101 CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr,
103 }
104 }
105 }
106
112 default:
113 return nullptr;
114 }
115}
116
119 bool AllowUserDefined) {
121
123 return true;
124
127 return Decl && (AllowUserDefined || ->isUserProvided()) &&
128 ->isDeleted();
129}
130
134
136 return true;
137
141 return false;
142
143 return Decl && (AllowUserDefined || ->isUserProvided()) &&
144 ->isDeleted();
145}
146
147
148
149
150
151
152
153
154
155
158 false))
159 return false;
160
162 SemaRef, D, false))
163 return false;
164
166
167 if (!Dtr)
168 return true;
169
171
173 return false;
174
176}
177
178
179
182
184 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
185 if (!BaseDecl)
186 continue;
187
188
189 if (B.isVirtual() || (!BaseDecl->isDependentType() &&
191 return false;
192 }
193
194 bool IsUnion = D->isUnion();
196 if (Field->getType()->isDependentType())
197 continue;
198 if (Field->getType()->isReferenceType())
199 continue;
200
201
203 return false;
204
205
206
208 Field->getType()))
209 return false;
210 }
212}
213
217
219 return Info;
220
222
223 auto IsUnion = [&, Is = std::optional{}]() mutable {
224 if (!Is.has_value())
229 return *Is;
230 };
231
232 auto IsDefaultMovable = [&, Is = std::optional{}]() mutable {
233 if (!Is.has_value())
235 return *Is;
236 };
237
240 return false;
241
242
244 return false;
245
246
247 if (D->hasAttr())
248 return true;
249
250
251 if (IsUnion())
252 return true;
253
254
256 }();
257
258 return Info;
259}
260
262 if (std::optionalASTContext::CXXRecordDeclRelocationInfo Info =
263 getASTContext().getRelocationInfoForCXXRecord(&RD))
264 return Info->IsRelocatable;
268}
269
272
274 return false;
275
277 return false;
278
280 return false;
281
282 if (Context.containsNonRelocatablePointerAuth(Type))
283 return false;
284
286 return true;
287
290
291 return false;
292}
293
294
295
296
297
300 if (->getType()->isVariableArrayType())
301 return false;
302
303 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
304 << 1 << TypeTraitID;
305 return true;
306}
307
308
309
310
311
314 if (->getType()->isAtomicType())
315 return false;
316
317 S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)
318 << TypeTraitID;
319 return true;
320}
321
322
323
324
325
326
327
331
332
333
334
335
336
337
338
339
340 switch (UTT) {
341 default:
342 llvm_unreachable("not a UTT");
343
344 case UTT_IsCompleteType:
345
346
347
348
349
350
351 case UTT_IsVoid:
352 case UTT_IsIntegral:
353 case UTT_IsFloatingPoint:
354 case UTT_IsArray:
355 case UTT_IsBoundedArray:
356 case UTT_IsPointer:
357 case UTT_IsLvalueReference:
358 case UTT_IsRvalueReference:
359 case UTT_IsMemberFunctionPointer:
360 case UTT_IsMemberObjectPointer:
361 case UTT_IsEnum:
362 case UTT_IsScopedEnum:
363 case UTT_IsUnion:
364 case UTT_IsClass:
365 case UTT_IsFunction:
366 case UTT_IsReference:
367 case UTT_IsArithmetic:
368 case UTT_IsFundamental:
369 case UTT_IsObject:
370 case UTT_IsScalar:
371 case UTT_IsCompound:
372 case UTT_IsMemberPointer:
373 case UTT_IsTypedResourceElementCompatible:
374
375
376
377
378
379
380
381 case UTT_IsConst:
382 case UTT_IsVolatile:
383 case UTT_IsSigned:
384 case UTT_IsUnboundedArray:
385 case UTT_IsUnsigned:
386
387
388 case UTT_IsInterfaceClass:
389 return true;
390
391
392 case UTT_StructuredBindingSize:
393 return true;
394
395
396
397 case UTT_IsEmpty:
398 case UTT_IsPolymorphic:
399 case UTT_IsAbstract:
401 if (!RD->isUnion())
403 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
404 return true;
405
406
407
408 case UTT_IsFinal:
409 case UTT_IsSealed:
412 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
413 return true;
414
415
416 case UTT_IsAggregate:
417 case UTT_IsImplicitLifetime:
419 return true;
420
422 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
423
424
425
426 case UTT_HasUniqueObjectRepresentations:
429 return true;
431 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
432
433
434
435 case UTT_IsTrivial:
436 case UTT_IsTriviallyCopyable:
437 case UTT_IsStandardLayout:
438 case UTT_IsPOD:
439 case UTT_IsLiteral:
440 case UTT_IsBitwiseCloneable:
441
442
443 case UTT_IsTriviallyRelocatable:
444 case UTT_IsTriviallyEqualityComparable:
445 case UTT_IsCppTriviallyRelocatable:
446 case UTT_CanPassInRegs:
447
448
449
450 case UTT_HasNothrowAssign:
451 case UTT_HasNothrowMoveAssign:
452 case UTT_HasNothrowConstructor:
453 case UTT_HasNothrowCopy:
454 case UTT_HasTrivialAssign:
455 case UTT_HasTrivialMoveAssign:
456 case UTT_HasTrivialDefaultConstructor:
457 case UTT_HasTrivialMoveConstructor:
458 case UTT_HasTrivialCopy:
459 case UTT_HasTrivialDestructor:
460 case UTT_HasVirtualDestructor:
462 [[fallthrough]];
463
464
465 case UTT_IsDestructible:
466 case UTT_IsNothrowDestructible:
467 case UTT_IsTriviallyDestructible:
468 case UTT_IsIntangibleType:
470 return true;
471
473 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
474 }
475}
476
482 if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
483 return true;
484
485 DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op);
488 if (Self.LookupQualifiedName(Res, RD)) {
489 bool FoundOperator = false;
492 Op != OpEnd; ++Op) {
494 continue;
495
497 if ((Operator->*IsDesiredOp)()) {
498 FoundOperator = true;
500 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
502 return false;
503 }
504 }
505 return FoundOperator;
506 }
507 return false;
508}
509
513 if (Decl->isUnion())
514 return false;
515 if (Decl->isLambda())
516 return Decl->isCapturelessLambda();
517
519 {
524
525
528
530
532 Functions, &Operand, &Operand);
534 return false;
535
536 const auto *CallExpr = dyn_cast(Result.get());
538 return false;
540 auto ParamT = Callee->getParamDecl(0)->getType();
541 if (!Callee->isDefaulted())
542 return false;
543 if (!ParamT->isReferenceType() && ->isTriviallyCopyable())
544 return false;
546 return false;
547 }
548
549 return llvm::all_of(Decl->bases(),
551 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
552 return HasNonDeletedDefaultedEqualityComparison(
553 S, RD, KeyLoc);
554 return true;
555 }) &&
556 llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {
557 auto Type = FD->getType();
558 if (Type->isArrayType())
559 Type = Type->getBaseElementTypeUnsafe()
560 ->getCanonicalTypeUnqualified();
561
562 if (Type->isReferenceType() || Type->isEnumeralType())
563 return false;
564 if (const auto *RD = Type->getAsCXXRecordDecl())
565 return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
566 return true;
567 });
568}
569
572 QualType CanonicalType = Type.getCanonicalType();
575 return false;
576
579 return false;
580 }
581
583 CanonicalType, false);
584}
585
588
590 return false;
592 return false;
593
594
595
596
598 return false;
599
602 return true;
603
606
608 return true;
609
610 switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
612 return .isDestructedType();
614 return true;
615 default:
616 return false;
617 }
618}
619
624 assert(->isDependentType() && "Cannot evaluate traits of dependent type");
625
627 switch (UTT) {
628 default:
629 llvm_unreachable("not a UTT");
630
631
632 case UTT_IsVoid:
633 return T->isVoidType();
634 case UTT_IsIntegral:
635 return T->isIntegralType(C);
636 case UTT_IsFloatingPoint:
637 return T->isFloatingType();
638 case UTT_IsArray:
639
640
641 if (const auto *CAT = C.getAsConstantArrayType(T))
642 return CAT->getSize() != 0;
643 return T->isArrayType();
644 case UTT_IsBoundedArray:
646 return false;
647
648
649 if (const auto *CAT = C.getAsConstantArrayType(T))
650 return CAT->getSize() != 0;
651 return T->isArrayType() && ->isIncompleteArrayType();
652 case UTT_IsUnboundedArray:
654 return false;
655 return T->isIncompleteArrayType();
656 case UTT_IsPointer:
657 return T->isAnyPointerType();
658 case UTT_IsLvalueReference:
659 return T->isLValueReferenceType();
660 case UTT_IsRvalueReference:
661 return T->isRValueReferenceType();
662 case UTT_IsMemberFunctionPointer:
663 return T->isMemberFunctionPointerType();
664 case UTT_IsMemberObjectPointer:
665 return T->isMemberDataPointerType();
666 case UTT_IsEnum:
667 return T->isEnumeralType();
668 case UTT_IsScopedEnum:
669 return T->isScopedEnumeralType();
670 case UTT_IsUnion:
671 return T->isUnionType();
672 case UTT_IsClass:
673 return T->isClassType() || T->isStructureType() || T->isInterfaceType();
674 case UTT_IsFunction:
675 return T->isFunctionType();
676
677
678
679 case UTT_IsReference:
680 return T->isReferenceType();
681 case UTT_IsArithmetic:
682 return T->isArithmeticType() && ->isEnumeralType();
683 case UTT_IsFundamental:
684 return T->isFundamentalType();
685 case UTT_IsObject:
686 return T->isObjectType();
687 case UTT_IsScalar:
688
689
690
691
692 if (T->isObjCLifetimeType()) {
693 switch (T.getObjCLifetime()) {
696 return true;
697
701 return false;
702 }
703 }
704
705 return T->isScalarType();
706 case UTT_IsCompound:
707 return T->isCompoundType();
708 case UTT_IsMemberPointer:
709 return T->isMemberPointerType();
710
711
712
713 case UTT_IsConst:
714 return T.isConstQualified();
715 case UTT_IsVolatile:
716 return T.isVolatileQualified();
717 case UTT_IsTrivial:
718 return T.isTrivialType(C);
719 case UTT_IsTriviallyCopyable:
720 return T.isTriviallyCopyableType(C);
721 case UTT_IsStandardLayout:
722 return T->isStandardLayoutType();
723 case UTT_IsPOD:
725 case UTT_IsLiteral:
726 return T->isLiteralType(C);
727 case UTT_IsEmpty:
728 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
730 return false;
731 case UTT_IsPolymorphic:
732 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
734 return false;
735 case UTT_IsAbstract:
736 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
738 return false;
739 case UTT_IsAggregate:
740
741
742
743 return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
744 T->isAnyComplexType();
745
746
747
748 case UTT_IsInterfaceClass:
749 return false;
750 case UTT_IsFinal:
751 case UTT_IsSealed:
752 if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
753 return RD->hasAttr();
754 return false;
755 case UTT_IsSigned:
756
757
758 return T->isFloatingType() ||
759 (T->isSignedIntegerType() && ->isEnumeralType());
760 case UTT_IsUnsigned:
761
762 return T->isUnsignedIntegerType() && ->isEnumeralType();
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780 case UTT_HasTrivialDefaultConstructor:
781
782
783
784
786 return true;
787 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
790 return false;
791 case UTT_HasTrivialMoveConstructor:
792
793
794
796 return true;
797 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
800 return false;
801 case UTT_HasTrivialCopy:
802
803
804
805
806
807 if (T.isPODType(C) || T->isReferenceType())
808 return true;
812 return false;
813 case UTT_HasTrivialMoveAssign:
814
815
816
818 return true;
819 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
822 return false;
823 case UTT_HasTrivialAssign:
824
825
826
827
828
829
830
831
832
833
834
835
836 if (T.isConstQualified())
837 return false;
839 return true;
843 return false;
844 case UTT_IsDestructible:
845 case UTT_IsTriviallyDestructible:
846 case UTT_IsNothrowDestructible:
847
848
849 if (T->isReferenceType())
850 return true;
851
852
853 if (T->isObjCLifetimeType() &&
855 return true;
856
857
858
859
860 if (T->isIncompleteType() || T->isFunctionType())
861 return false;
862
863
864
865 if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
866 return false;
867
868
869
870
871
872 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
875 return false;
876
877
878
880 return false;
882 return false;
883 if (UTT == UTT_IsNothrowDestructible) {
885 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
887 return false;
888 }
889 }
890 return true;
891
892 case UTT_HasTrivialDestructor:
893
894
895
896
897
898
899 if (T.isPODType(C) || T->isReferenceType())
900 return true;
901
902
903 if (T->isObjCLifetimeType() &&
905 return true;
906
907 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
909 return false;
910
911 case UTT_HasNothrowAssign:
912
913
914
915
916
917
918
919 if (C.getBaseElementType(T).isConstQualified())
920 return false;
921 if (T->isReferenceType())
922 return false;
923 if (T.isPODType(C) || T->isObjCLifetimeType())
924 return true;
925
926 if (auto *RD = T->getAsCXXRecordDecl())
931 return false;
932 case UTT_HasNothrowMoveAssign:
933
934
935
937 return true;
938
939 if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
944 return false;
945 case UTT_HasNothrowCopy:
946
947
948
949
950
951 if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())
952 return true;
956 return true;
957
958 bool FoundConstructor = false;
959 unsigned FoundTQs;
960 for (const auto *ND : Self.LookupConstructors(RD)) {
961
962
963
965 continue;
966
968 continue;
970 if (Constructor->isCopyConstructor(FoundTQs)) {
971 FoundConstructor = true;
973 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
974 if (!CPT)
975 return false;
976
977
979 return false;
980 }
981 }
982
983 return FoundConstructor;
984 }
985 return false;
986 case UTT_HasNothrowConstructor:
987
988
989
990
991
992 if (T.isPODType(C) || T->isObjCLifetimeType())
993 return true;
994 if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
996 return true;
997
998 bool FoundConstructor = false;
999 for (const auto *ND : Self.LookupConstructors(RD)) {
1000
1002 continue;
1003
1005 continue;
1007 if (Constructor->isDefaultConstructor()) {
1008 FoundConstructor = true;
1010 CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1011 if (!CPT)
1012 return false;
1013
1014
1016 return false;
1017 }
1018 }
1019 return FoundConstructor;
1020 }
1021 return false;
1022 case UTT_HasVirtualDestructor:
1023
1024
1025
1029 return false;
1030
1031
1032
1033
1034 case UTT_IsCompleteType:
1035
1036
1037
1038 return ->isIncompleteType();
1039 case UTT_HasUniqueObjectRepresentations:
1040 return C.hasUniqueObjectRepresentations(T);
1041 case UTT_IsTriviallyRelocatable:
1043 case UTT_IsBitwiseCloneable:
1044 return T.isBitwiseCloneableType(C);
1045 case UTT_IsCppTriviallyRelocatable:
1046 return Self.IsCXXTriviallyRelocatableType(T);
1047 case UTT_CanPassInRegs:
1048 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && .hasQualifiers())
1050 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
1051 return false;
1052 case UTT_IsTriviallyEqualityComparable:
1054 case UTT_IsImplicitLifetime: {
1056 tok::kw___builtin_is_implicit_lifetime);
1058 tok::kw___builtin_is_implicit_lifetime);
1059
1060
1061
1062
1063
1064 QualType UnqualT = T->getCanonicalTypeUnqualified();
1066 return true;
1068 return true;
1070 if (!RD)
1071 return false;
1072
1073
1074
1075
1076
1077
1080 return true;
1081 bool HasTrivialNonDeletedDtr =
1083 if (!HasTrivialNonDeletedDtr)
1084 return false;
1086 if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
1087 continue;
1088 if (Ctr->isTrivial())
1089 return true;
1090 }
1094 return true;
1097 return true;
1100 return true;
1101 return false;
1102 }
1103 case UTT_IsIntangibleType:
1104 assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature");
1105 if (->isVoidType() &&
->isIncompleteArrayType())
1107 diag::err_incomplete_type))
1108 return false;
1110 tok::kw___builtin_hlsl_is_intangible))
1111 return false;
1112 return T->isHLSLIntangibleType();
1113
1114 case UTT_IsTypedResourceElementCompatible:
1115 assert(Self.getLangOpts().HLSL &&
1116 "typed resource element compatible types are an HLSL-only feature");
1117 if (T->isIncompleteType())
1118 return false;
1119
1120 return Self.HLSL().IsTypedResourceElementCompatible(T);
1121 }
1122}
1123
1128
1131 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1132
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1164
1165
1169
1170
1172 LhsT = Self.Context.getRValueReferenceType(LhsT);
1173
1174
1181
1182
1183
1189 if (Init.Failed())
1191
1195
1196 return Result;
1197}
1198
1203 bool IsDependent) {
1204 if (IsDependent)
1206
1207 switch (Kind) {
1208 case TypeTrait::UTT_StructuredBindingSize: {
1209 QualType T = Args[0]->getType();
1210 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1213 if (!Size) {
1214 S.Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;
1216 }
1219 break;
1220 }
1221 default:
1222 llvm_unreachable("Not a SizeT type trait");
1223 }
1224}
1225
1230 bool IsDependent) {
1231 if (IsDependent)
1232 return false;
1233
1236
1237
1238
1239 if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1240 Kind != BTT_ReferenceConstructsFromTemporary &&
1241 Kind != BTT_ReferenceConvertsFromTemporary)
1243
1244 switch (Kind) {
1245 case clang::BTT_ReferenceBindsToTemporary:
1246 case clang::BTT_ReferenceConstructsFromTemporary:
1247 case clang::BTT_ReferenceConvertsFromTemporary:
1248 case clang::TT_IsConstructible:
1249 case clang::TT_IsNothrowConstructible:
1250 case clang::TT_IsTriviallyConstructible: {
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264 assert(!Args.empty());
1265
1266
1267
1268
1269 for (const auto *TSI : Args) {
1270 QualType ArgTy = TSI->getType();
1272 continue;
1273
1275 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1276 return false;
1277 }
1278
1279
1280 QualType T = Args[0]->getType();
1281 if (T->isIncompleteType() || T->isFunctionType())
1282 return false;
1283
1284
1287 return false;
1288
1289
1290
1291
1292 bool UseRawObjectType =
1293 Kind == clang::BTT_ReferenceBindsToTemporary ||
1294 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1295 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1296
1297 llvm::BumpPtrAllocator OpaqueExprAllocator;
1299 ArgExprs.reserve(Args.size() - 1);
1300 for (unsigned I = 1, N = Args.size(); I != N; ++I) {
1301 QualType ArgTy = Args[I]->getType();
1302 if ((ArgTy->isObjectType() && !UseRawObjectType) ||
1305 ArgExprs.push_back(
1310 }
1311
1312
1313
1321 Kind == clang::BTT_ReferenceConvertsFromTemporary
1325 if (Init.Failed())
1326 return false;
1327
1328 ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
1330 return false;
1331
1332 if (Kind == clang::TT_IsConstructible)
1333 return true;
1334
1335 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1336 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1337 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1338 if (->isReferenceType())
1339 return false;
1340
1341
1342 if (T.getNonReferenceType()->isFunctionType())
1343 return false;
1344
1345 if (.isDirectReferenceBinding())
1346 return true;
1347
1348 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1349 return false;
1350
1351 QualType U = Args[1]->getType();
1352 if (U->isReferenceType())
1353 return false;
1354
1360 OpaqueExprAllocator)
1362 }
1363
1364 if (Kind == clang::TT_IsNothrowConstructible)
1366
1367 if (Kind == clang::TT_IsTriviallyConstructible) {
1368
1369
1370 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1371 return false;
1372
1373
1374
1375 return !Result.get()->hasNonTrivialCall(S.Context);
1376 }
1377
1378 llvm_unreachable("unhandled type trait");
1379 return false;
1380 }
1381 default:
1382 llvm_unreachable("not a TT");
1383 }
1384
1385 return false;
1386}
1387
1388namespace {
1391 switch (Kind) {
1392 case UTT_HasNothrowAssign:
1393 case UTT_HasNothrowMoveAssign:
1394 Replacement = BTT_IsNothrowAssignable;
1395 break;
1396 case UTT_HasNothrowCopy:
1397 case UTT_HasNothrowConstructor:
1398 Replacement = TT_IsNothrowConstructible;
1399 break;
1400 case UTT_HasTrivialAssign:
1401 case UTT_HasTrivialMoveAssign:
1402 Replacement = BTT_IsTriviallyAssignable;
1403 break;
1404 case UTT_HasTrivialCopy:
1405 Replacement = UTT_IsTriviallyCopyable;
1406 break;
1407 case UTT_HasTrivialDefaultConstructor:
1408 case UTT_HasTrivialMoveConstructor:
1409 Replacement = TT_IsTriviallyConstructible;
1410 break;
1411 case UTT_HasTrivialDestructor:
1412 Replacement = UTT_IsTriviallyDestructible;
1413 break;
1414 case UTT_IsTriviallyRelocatable:
1415 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1416 break;
1417 case BTT_ReferenceBindsToTemporary:
1418 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1419 break;
1420 default:
1421 return;
1422 }
1423 S.Diag(KWLoc, diag::warn_deprecated_builtin)
1425}
1426}
1427
1429 if (Arity && N != Arity) {
1430 Diag(Loc, diag::err_type_trait_arity)
1431 << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
1432 return false;
1433 }
1434
1435 if (!Arity && N == 0) {
1436 Diag(Loc, diag::err_type_trait_arity)
1437 << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1438 return false;
1439 }
1440 return true;
1441}
1442
1447
1449 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1452}
1453
1459
1461 *this, Kind, KWLoc, Args[0]->getType()))
1463
1464 DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
1465
1467 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1468 if (Args[I]->getType()->isDependentType()) {
1470 break;
1471 }
1472 }
1473
1479 KWLoc, Kind, Args, RParenLoc, Result);
1480 }
1485 Args, RParenLoc, Result);
1486 }
1487 }
1488 llvm_unreachable("unhandled type trait return type");
1489}
1490
1495 ConvertedArgs.reserve(Args.size());
1496
1497 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1500 if (!TInfo)
1501 TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
1502
1503 ConvertedArgs.push_back(TInfo);
1504 }
1505
1506 return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
1507}
1508
1511
1512
1513
1514
1515
1516 const RecordType *lhsRecord = LhsT->getAsCanonical();
1517 const RecordType *rhsRecord = RhsT->getAsCanonical();
1518 if (!rhsRecord || !lhsRecord) {
1521 if (!LHSObjTy || !RHSObjTy)
1522 return false;
1523
1526 if (!BaseInterface || !DerivedInterface)
1527 return false;
1528
1530 diag::err_incomplete_type_used_in_type_trait_expr))
1531 return false;
1532
1533 return BaseInterface->isSuperClassOf(DerivedInterface);
1534 }
1535
1536 assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1537 (lhsRecord == rhsRecord));
1538
1539
1540
1541 if (lhsRecord && lhsRecord->getDecl()->isUnion())
1542 return false;
1543 if (rhsRecord && rhsRecord->getDecl()->isUnion())
1544 return false;
1545
1546 if (lhsRecord == rhsRecord)
1547 return true;
1548
1549
1550
1551
1552
1554 diag::err_incomplete_type_used_in_type_trait_expr))
1555 return false;
1556
1559}
1560
1567
1569 "Cannot evaluate traits of dependent types");
1570
1571 switch (BTT) {
1572 case BTT_IsBaseOf:
1574
1575 case BTT_IsVirtualBaseOf: {
1576 const RecordType *BaseRecord = LhsT->getAsCanonical();
1577 const RecordType *DerivedRecord = RhsT->getAsCanonical();
1578
1579 if (!BaseRecord || !DerivedRecord) {
1581 tok::kw___builtin_is_virtual_base_of);
1583 tok::kw___builtin_is_virtual_base_of);
1584 return false;
1585 }
1586
1587 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1588 return false;
1589
1590 if (!BaseRecord->isStructureOrClassType() ||
1591 !DerivedRecord->isStructureOrClassType())
1592 return false;
1593
1595 diag::err_incomplete_type))
1596 return false;
1597
1600 }
1601 case BTT_IsSame:
1602 return Self.Context.hasSameType(LhsT, RhsT);
1603 case BTT_TypeCompatible: {
1604
1606 QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1607 QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1608 return Self.Context.typesAreCompatible(Lhs, Rhs);
1609 }
1610 case BTT_IsConvertible:
1611 case BTT_IsConvertibleTo:
1612 case BTT_IsNothrowConvertible: {
1615 llvm::BumpPtrAllocator OpaqueExprAllocator;
1617 OpaqueExprAllocator);
1618 if (Result.isInvalid())
1619 return false;
1620
1621 if (BTT != BTT_IsNothrowConvertible)
1622 return true;
1623
1624 return Self.canThrow(Result.get()) == CT_Cannot;
1625 }
1626
1627 case BTT_IsAssignable:
1628 case BTT_IsNothrowAssignable:
1629 case BTT_IsTriviallyAssignable: {
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1642 Self.RequireCompleteType(
1644 diag::err_incomplete_type_used_in_type_trait_expr))
1645 return false;
1647 Self.RequireCompleteType(
1649 diag::err_incomplete_type_used_in_type_trait_expr))
1650 return false;
1651
1652
1654 return false;
1655
1656
1657
1659 if (Ty->isObjectType() || Ty->isFunctionType())
1660 Ty = Self.Context.getRValueReferenceType(Ty);
1661 return {KeyLoc, Ty.getNonLValueExprType(Self.Context),
1663 };
1664
1665 auto Lhs = createDeclValExpr(LhsT);
1666 auto Rhs = createDeclValExpr(RhsT);
1667
1668
1669
1675 Self.BuildBinOp(nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1676 if (Result.isInvalid())
1677 return false;
1678
1679
1680 Self.CheckUnusedVolatileAssignment(Result.get());
1681
1683 return false;
1684
1685 if (BTT == BTT_IsAssignable)
1686 return true;
1687
1688 if (BTT == BTT_IsNothrowAssignable)
1689 return Self.canThrow(Result.get()) == CT_Cannot;
1690
1691 if (BTT == BTT_IsTriviallyAssignable) {
1692
1693
1695 return false;
1697 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1698 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1699 return false;
1700 return !Result.get()->hasNonTrivialCall(Self.Context);
1701 }
1702
1703 llvm_unreachable("unhandled type trait");
1704 return false;
1705 }
1706 case BTT_IsLayoutCompatible: {
1709 diag::err_incomplete_type);
1712 diag::err_incomplete_type);
1713
1716
1717 return Self.IsLayoutCompatible(LhsT, RhsT);
1718 }
1719 case BTT_IsPointerInterconvertibleBaseOf: {
1721 .getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1723 diag::err_incomplete_type);
1724 }
1725
1727 tok::kw___is_pointer_interconvertible_base_of);
1729 tok::kw___is_pointer_interconvertible_base_of);
1730
1731 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1732 }
1733 case BTT_IsDeducible: {
1736 return Self.DeduceTemplateArgumentsFromType(
1737 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1739 }
1740 case BTT_IsScalarizedLayoutCompatible: {
1743 diag::err_incomplete_type))
1744 return true;
1747 diag::err_incomplete_type))
1748 return true;
1749
1751 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1753 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1754
1755 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1756 }
1757 case BTT_LtSynthesizesFromSpaceship:
1758 case BTT_LeSynthesizesFromSpaceship:
1759 case BTT_GtSynthesizesFromSpaceship:
1760 case BTT_GeSynthesizesFromSpaceship: {
1765
1776
1777 auto OpKind = [&] {
1778 switch (BTT) {
1779 case BTT_LtSynthesizesFromSpaceship:
1780 return BinaryOperatorKind::BO_LT;
1781 case BTT_LeSynthesizesFromSpaceship:
1782 return BinaryOperatorKind::BO_LE;
1783 case BTT_GtSynthesizesFromSpaceship:
1784 return BinaryOperatorKind::BO_GT;
1785 case BTT_GeSynthesizesFromSpaceship:
1786 return BinaryOperatorKind::BO_GE;
1787 default:
1788 llvm_unreachable("Trying to Synthesize non-comparison operator?");
1789 }
1790 }();
1791
1793 Self.LookupBinOp(Self.TUScope, KeyLoc, OpKind, Functions);
1794
1796 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1798 return false;
1799
1801 }
1802 default:
1803 llvm_unreachable("not a BTT");
1804 }
1805 llvm_unreachable("Unknown type trait or not implemented");
1806}
1807
1813 if (!TSInfo)
1814 TSInfo = Context.getTrivialTypeSourceInfo(T);
1815
1817}
1818
1822 assert(->isDependentType() && "Cannot evaluate traits of dependent type");
1823
1824 switch (ATT) {
1825 case ATT_ArrayRank:
1826 if (T->isArrayType()) {
1827 unsigned Dim = 0;
1828 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1830 T = AT->getElementType();
1831 }
1832 return Dim;
1833 }
1834 return 0;
1835
1836 case ATT_ArrayExtent: {
1837 llvm::APSInt Value;
1838 uint64_t Dim;
1839 if (Self.VerifyIntegerConstantExpression(
1840 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
1841 .isInvalid())
1842 return 0;
1843 if (Value.isSigned() && Value.isNegative()) {
1844 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1846 return 0;
1847 }
1848 Dim = Value.getLimitedValue();
1849
1850 if (T->isArrayType()) {
1851 unsigned D = 0;
1852 bool Matched = false;
1853 while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1854 if (Dim == D) {
1855 Matched = true;
1856 break;
1857 }
1858 ++D;
1859 T = AT->getElementType();
1860 }
1861
1862 if (Matched && T->isArrayType()) {
1864 Self.Context.getAsConstantArrayType(T))
1865 return CAT->getLimitedSize();
1866 }
1867 }
1868 return 0;
1869 }
1870 }
1871 llvm_unreachable("Unknown type trait or not implemented");
1872}
1873
1878
1879
1880
1881 uint64_t Value = 0;
1882 if (->isDependentType())
1884
1885
1886
1887
1888
1889
1891 RParen, Context.getSizeType());
1892}
1893
1896
1897 if (!Queried)
1899
1901
1903}
1904
1906 switch (ET) {
1907 case ET_IsLValueExpr:
1909 case ET_IsRValueExpr:
1911 }
1912 llvm_unreachable("Expression trait not covered by switch");
1913}
1914
1918
1924 }
1925
1927
1930}
1931
1933 return llvm::StringSwitch<std::optional>(Name)
1934 .Case("is_trivially_relocatable",
1935 TypeTrait::UTT_IsCppTriviallyRelocatable)
1936 .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1937 .Case("is_assignable", TypeTrait::BTT_IsAssignable)
1938 .Case("is_empty", TypeTrait::UTT_IsEmpty)
1939 .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1940 .Case("is_aggregate", TypeTrait::UTT_IsAggregate)
1941 .Case("is_constructible", TypeTrait::TT_IsConstructible)
1942 .Case("is_final", TypeTrait::UTT_IsFinal)
1943 .Case("is_abstract", TypeTrait::UTT_IsAbstract)
1944 .Default(std::nullopt);
1945}
1946
1948 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1949
1950
1951
1952
1953
1956 std::optional Trait;
1957
1958
1959 if (const auto *TraitExpr = dyn_cast(E)) {
1960 Trait = TraitExpr->getTrait();
1961 for (const auto *Arg : TraitExpr->getArgs())
1962 Args.push_back(Arg->getType());
1963 return {{Trait.value(), std::move(Args)}};
1964 }
1965 const auto *Ref = dyn_cast(E);
1966 if (!Ref)
1967 return std::nullopt;
1968
1969
1970 if (const auto *VD =
1971 dyn_cast(Ref->getDecl())) {
1972 if (!VD->isInStdNamespace())
1973 return std::nullopt;
1974 StringRef Name = VD->getIdentifier()->getName();
1975 if (!Name.consume_back("_v"))
1976 return std::nullopt;
1978 if (!Trait)
1979 return std::nullopt;
1980 for (const auto &Arg : VD->getTemplateArgs().asArray()) {
1982 for (const auto &InnerArg : Arg.pack_elements())
1983 Args.push_back(InnerArg.getAsType());
1985 Args.push_back(Arg.getAsType());
1986 } else {
1987 llvm_unreachable("Unexpected kind");
1988 }
1989 }
1990 return {{Trait.value(), std::move(Args)}};
1991 }
1992
1993
1994 if (const auto *VD = dyn_cast(Ref->getDecl());
1995 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
1998 return std::nullopt;
1999 const auto *Ts = Qualifier.getAsType()->getAs();
2000 if (!Ts)
2001 return std::nullopt;
2002 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2004 return std::nullopt;
2006 if (!Trait)
2007 return std::nullopt;
2008 for (const auto &Arg : Ts->template_arguments())
2009 Args.push_back(Arg.getAsType());
2010 return {{Trait.value(), std::move(Args)}};
2011 }
2012 return std::nullopt;
2013}
2014
2019 if (Has)
2020 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2021 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2022 };
2031 return;
2032 }
2033
2035 const auto *Decl = cast_or_null(
2037 if (Decl && Decl->isUserProvided())
2038 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2039 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2041 }
2045 if (Decl && Decl->isUserProvided())
2046 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2047 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2049 }
2051 Dtr = Dtr->getCanonicalDecl();
2052 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2053 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2054 << diag::TraitNotSatisfiedReason::DeletedDtr << 1
2055 << Dtr->getSourceRange();
2056 }
2057}
2058
2063 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2064 if (B.isVirtual())
2065 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2066 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2067 << B.getSourceRange();
2069 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2070 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2071 << B.getSourceRange();
2072 }
2074 if (!Field->getType()->isReferenceType() &&
2076 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2077 << diag::TraitNotSatisfiedReason::NTRField << Field
2078 << Field->getType() << Field->getSourceRange();
2079 }
2081 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2082 << diag::TraitNotSatisfiedReason::DeletedDtr << 0
2084
2085 if (D->hasAttr())
2086 return;
2088}
2089
2093 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2094 << T << diag::TraitName::TriviallyRelocatable;
2095 if (T->isVariablyModifiedType())
2096 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2097 << diag::TraitNotSatisfiedReason::VLA;
2098
2099 if (T->isReferenceType())
2100 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2101 << diag::TraitNotSatisfiedReason::Ref;
2102 T = T.getNonReferenceType();
2103
2104 if (T.hasNonTrivialObjCLifetime())
2105 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2106 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2107
2110 return;
2111
2114
2115 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2116}
2117
2122 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2123 if (B.isVirtual())
2124 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2125 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2126 << B.getSourceRange();
2127 if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2128 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2129 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2130 << B.getSourceRange();
2131 }
2132 }
2134 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2135 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2136 << diag::TraitNotSatisfiedReason::NTCField << Field
2137 << Field->getType() << Field->getSourceRange();
2138 }
2141 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2142 << diag::TraitNotSatisfiedReason::DeletedDtr
2144
2146 if (Method->isTrivial() || !Method->isUserProvided()) {
2147 continue;
2148 }
2149 auto SpecialMemberKind =
2151 switch (SpecialMemberKind) {
2156 bool IsAssignment =
2159 bool IsMove =
2162
2163 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2164 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2165 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2166 << IsMove << Method->getSourceRange();
2167 break;
2168 }
2169 default:
2170 break;
2171 }
2172 }
2173}
2174
2178 if (Ts.empty()) {
2179 return;
2180 }
2181
2182 bool ContainsVoid = false;
2183 for (const QualType &ArgTy : Ts) {
2184 ContainsVoid |= ArgTy->isVoidType();
2185 }
2186
2187 if (ContainsVoid)
2188 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2189 << diag::TraitNotSatisfiedReason::CVVoidType;
2190
2192 if (T->isFunctionType())
2193 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2194 << diag::TraitNotSatisfiedReason::FunctionType;
2195
2196 if (T->isIncompleteArrayType())
2197 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2198 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2199
2202 return;
2203
2204 llvm::BumpPtrAllocator OpaqueExprAllocator;
2206 ArgExprs.reserve(Ts.size() - 1);
2207 for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2211 ArgExprs.push_back(
2215 }
2216
2224
2225 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2226 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2227}
2228
2231 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2232 << T << diag::TraitName::TriviallyCopyable;
2233
2234 if (T->isReferenceType())
2235 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2236 << diag::TraitNotSatisfiedReason::Ref;
2237
2240 return;
2241
2244
2245 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2246}
2247
2251
2253 if (Ty->isObjectType() || Ty->isFunctionType())
2255 return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2257 };
2258
2259 auto LHS = createDeclValExpr(T);
2260 auto RHS = createDeclValExpr(U);
2261
2266 SemaRef.BuildBinOp(nullptr, Loc, BO_Assign, &LHS, &RHS);
2267
2269 return;
2270
2271 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2272}
2273
2276
2277 for (const auto *Field : D->fields()) {
2278 if (Field->isZeroLengthBitField())
2279 continue;
2280 if (Field->isBitField()) {
2281 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2282 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2283 << Field->getSourceRange();
2284 continue;
2285 }
2286 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2287 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2288 << Field->getType() << Field->getSourceRange();
2289 }
2290
2291
2292 for (const auto *M : D->methods()) {
2293 if (M->isVirtual()) {
2294 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2295 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2296 << M->getSourceRange();
2297 break;
2298 }
2299 }
2300
2301
2302 for (const auto &B : D->bases()) {
2303 const auto *BR = B.getType()->getAsCXXRecordDecl();
2304 if (!BR || BR->isInvalidDecl())
2305 continue;
2306 if (B.isVirtual()) {
2307 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2308 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2309 << B.getSourceRange();
2310 }
2311 if (!BR->isEmpty()) {
2312 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2313 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2314 << B.getSourceRange();
2315 }
2316 }
2317}
2318
2320
2321 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2322
2323
2324
2325
2326 if (T->isReferenceType())
2327 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2328 << diag::TraitNotSatisfiedReason::Ref;
2329 T = T.getNonReferenceType();
2330
2332 T = AT->getElementType();
2333
2334 if (auto *D = T->getAsCXXRecordDecl()) {
2335 if (D->hasDefinition()) {
2337 S.Diag(D->getLocation(), diag::note_defined_here) << D;
2338 }
2339 }
2340}
2341
2345 return;
2346
2347
2349 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2350 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2352 return;
2353 }
2354}
2355
2357
2358 S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2359 if (T->isReferenceType()) {
2360 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2361 << diag::TraitNotSatisfiedReason::Ref;
2362 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2363 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2364 return;
2365 }
2366
2368 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2369 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2370 return;
2371 }
2372 if (T->isFunctionType()) {
2373 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2374 << diag::TraitNotSatisfiedReason::FunctionType;
2375 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2376 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2377 return;
2378 }
2379 if (->isRecordType()) {
2380 S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2381 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2382 return;
2383 }
2384 if (const auto *D = T->getAsCXXRecordDecl())
2386}
2387
2389 int NumBasesWithFields = 0;
2391 const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2393 continue;
2394
2396 if (!Field->isUnnamedBitField()) {
2397 if (++NumBasesWithFields > 1)
2398 return true;
2399 break;
2400 }
2401 }
2402 }
2403 return false;
2404}
2405
2409 assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2410 if (B.isVirtual()) {
2411 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2412 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2413 << B.getSourceRange();
2414 }
2415 if (!B.getType()->isStandardLayoutType()) {
2416 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2417 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2418 << B.getSourceRange();
2419 }
2420 }
2421
2422 const FieldDecl *FirstField = nullptr;
2424
2426 if (Field->isUnnamedBitField())
2427 continue;
2428
2429
2430 if (!FirstField) {
2431 FirstField = Field;
2432 FirstAccess = Field->getAccess();
2433 continue;
2434 }
2435
2436
2437 if (Field->getAccess() != FirstAccess) {
2438
2439 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2440 << diag::TraitNotSatisfiedReason::MixedAccess;
2441
2442 SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2443 << FirstField;
2444
2445 SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2446 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2447 << FirstField;
2448
2449
2450 break;
2451 }
2452 }
2454 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2455 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2456 }
2458
2460
2461 for (const auto *M : D->methods()) {
2462 if (M->isVirtual()) {
2463 VirtualMD = M;
2464 break;
2465 }
2466 }
2467 if (VirtualMD) {
2468 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2469 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2470 SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2471 << VirtualMD;
2472 } else {
2473
2474 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2475 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2476 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2477 }
2478 }
2480 if (!Field->getType()->isStandardLayoutType()) {
2481 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2482 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2483 << Field->getType() << Field->getSourceRange();
2484 }
2485 }
2486
2491 Indirect = BaseDef;
2492 return false;
2493 }
2494 return true;
2495 });
2496 if (Indirect) {
2497 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2498 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2500 }
2501 }
2502}
2503
2506 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2507 << T << diag::TraitName::StandardLayout;
2508
2509
2510 if (T->isVariablyModifiedType()) {
2511 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2512 << diag::TraitNotSatisfiedReason::VLA;
2513 return;
2514 }
2515
2516 if (T->isReferenceType()) {
2517 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2518 << diag::TraitNotSatisfiedReason::Ref;
2519 return;
2520 }
2521 T = T.getNonReferenceType();
2524 return;
2525
2528
2529 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2530}
2531
2535 if (Ctor->isUserProvided())
2536 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2537 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2538 if (Ctor->isInheritingConstructor())
2539 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2540 << diag::TraitNotSatisfiedReason::InheritedCtr;
2541 }
2542
2543 if (llvm::any_of(D->decls(), [](auto const *Sub) {
2544 return isa(Sub);
2545 })) {
2546 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2547 << diag::TraitNotSatisfiedReason::InheritedCtr;
2548 }
2549
2551 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2552 << diag::TraitNotSatisfiedReason::PolymorphicType
2554
2556 if (B.isVirtual()) {
2557 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2558 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2559 << B.getSourceRange();
2560 continue;
2561 }
2566 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2567 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2569 break;
2570 default:
2571 break;
2572 }
2573 }
2574
2576 if (Method->isVirtual()) {
2577 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2578 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2579 << Method->getSourceRange();
2580 }
2581 }
2582
2588 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2589 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2591 break;
2592 default:
2593 break;
2594 }
2595 }
2596
2597 SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2598}
2599
2602 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2603 << T << diag::TraitName::Aggregate;
2604
2605 if (T->isVoidType())
2606 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2607 << diag::TraitNotSatisfiedReason::CVVoidType;
2608
2609 T = T.getNonReferenceType();
2612 return;
2613
2616}
2617
2620
2621
2623 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2624 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2625 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2626 << B.getType() << B.getSourceRange();
2627 }
2628 }
2629}
2630
2633 SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2634 << T << diag::TraitName::Abstract;
2635
2636 if (T->isReferenceType()) {
2637 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2638 << diag::TraitNotSatisfiedReason::Ref;
2639 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2640 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2641 return;
2642 }
2643
2644 if (T->isUnionType()) {
2645 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2646 << diag::TraitNotSatisfiedReason::UnionType;
2647 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2648 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2649 return;
2650 }
2651
2653 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2654 << diag::TraitNotSatisfiedReason::ArrayType;
2655 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2656 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2657 return;
2658 }
2659
2660 if (T->isFunctionType()) {
2661 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2662 << diag::TraitNotSatisfiedReason::FunctionType;
2663 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2664 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2665 return;
2666 }
2667
2668 if (T->isPointerType()) {
2669 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2670 << diag::TraitNotSatisfiedReason::PointerType;
2671 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2672 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2673 return;
2674 }
2675
2676 if (->isStructureOrClassType()) {
2677 SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2678 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2679 return;
2680 }
2681
2685}
2686
2690 return;
2691
2693 if (!TraitInfo)
2694 return;
2695
2696 const auto &[Trait, Args] = TraitInfo.value();
2697 switch (Trait) {
2698 case UTT_IsCppTriviallyRelocatable:
2700 break;
2701 case UTT_IsTriviallyCopyable:
2703 break;
2704 case BTT_IsAssignable:
2706 break;
2707 case UTT_IsEmpty:
2709 break;
2710 case UTT_IsStandardLayout:
2712 break;
2713 case TT_IsConstructible:
2715 break;
2716 case UTT_IsAggregate:
2718 break;
2719 case UTT_IsFinal: {
2722 break;
2726 break;
2727 }
2728 case UTT_IsAbstract:
2730 break;
2731 default:
2732 break;
2733 }
2734}
static CanQualType GetReturnType(QualType RetTy)
Returns the "extra-canonicalized" return type, which discards qualifiers on the return type.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the Diagnostic IDs-related interfaces.
TokenType getType() const
Returns the token's type, e.g.
This file declares semantic analysis for HLSL constructs.
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs, SourceLocation KeyLoc)
Definition SemaTypeTraits.cpp:1561
static bool HasNonDeletedDefaultedEqualityComparison(Sema &S, const CXXRecordDecl *Decl, SourceLocation KeyLoc)
Definition SemaTypeTraits.cpp:510
static void DiagnoseNonAbstractReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2618
static APValue EvaluateSizeTTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
Definition SemaTypeTraits.cpp:1199
static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not a VLA.
Definition SemaTypeTraits.cpp:298
static bool HasNoThrowOperator(CXXRecordDecl *RD, OverloadedOperatorKind Op, Sema &Self, SourceLocation KeyLoc, ASTContext &C, bool(CXXRecordDecl::*HasTrivial)() const, bool(CXXRecordDecl::*HasNonTrivial)() const, bool(CXXMethodDecl::*IsDesiredOp)() const)
Definition SemaTypeTraits.cpp:477
static std::optional< TypeTrait > StdNameToTypeTrait(StringRef Name)
Definition SemaTypeTraits.cpp:1932
static void DiagnoseNonConstructibleReason(Sema &SemaRef, SourceLocation Loc, const llvm::SmallVector< clang::QualType, 1 > &Ts)
Definition SemaTypeTraits.cpp:2175
static bool IsEligibleForTrivialRelocation(Sema &SemaRef, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:180
static CXXMethodDecl * LookupSpecialMemberFromXValue(Sema &SemaRef, const CXXRecordDecl *RD, bool Assign)
Definition SemaTypeTraits.cpp:31
static bool hasSuitableMoveAssignmentOperatorForRelocation(Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined)
Definition SemaTypeTraits.cpp:131
static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not an atomic type (_Atomic).
Definition SemaTypeTraits.cpp:312
static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2406
static void DiagnoseIsFinalReason(Sema &S, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2342
static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2274
static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2388
static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E)
Definition SemaTypeTraits.cpp:1905
static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E)
Definition SemaTypeTraits.cpp:1954
std::optional< std::pair< TypeTrait, llvm::SmallVector< QualType, 1 > > > ExtractedTypeTraitInfo
Definition SemaTypeTraits.cpp:1947
static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2059
static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, QualType T, QualType U)
Definition SemaTypeTraits.cpp:2248
static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T)
Definition SemaTypeTraits.cpp:586
static void DiagnoseNonDefaultMovable(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2015
static bool IsDefaultMovable(Sema &SemaRef, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:156
static bool hasSuitableConstructorForRelocation(Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined)
Definition SemaTypeTraits.cpp:117
static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2118
static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, SourceLocation KeyLoc, TypeSourceInfo *TInfo)
Definition SemaTypeTraits.cpp:620
static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, QualType T, Expr *DimExpr, SourceLocation KeyLoc)
Definition SemaTypeTraits.cpp:1819
static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, SourceLocation Loc, QualType ArgTy)
Check the completeness of a type in a unary type trait.
Definition SemaTypeTraits.cpp:328
static ExprResult CheckConvertibilityForTypeTraits(Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs, SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator)
Definition SemaTypeTraits.cpp:1129
TypeTraitReturnType
Definition SemaTypeTraits.cpp:1443
@ SizeT
Definition SemaTypeTraits.cpp:1445
@ Bool
Definition SemaTypeTraits.cpp:1444
static void DiagnoseNonAggregateReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:2532
static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
Definition SemaTypeTraits.cpp:1226
static bool isTriviallyEqualityComparableType(Sema &S, QualType Type, SourceLocation KeyLoc)
Definition SemaTypeTraits.cpp:570
Defines various enumerations that describe declaration and type specifiers.
Defines enumerations for the type traits support.
C Language Family Type Representation.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
QualType getRValueReferenceType(QualType T) const
Return the uniqued reference to the type for an rvalue reference to the specified type.
DeclarationNameTable DeclarationNames
void setRelocationInfoForCXXRecord(const CXXRecordDecl *, CXXRecordDeclRelocationInfo)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool containsAddressDiscriminatedPointerAuth(QualType T) const
Examines a given type, and returns whether the type itself is address discriminated,...
bool hasUniqueObjectRepresentations(QualType Ty, bool CheckIfTriviallyCopyable=true) const
Return true if the specified type has unique object representations according to (C++17 [meta....
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
TypeSourceInfo * CreateTypeSourceInfo(QualType T, unsigned Size=0) const
Allocate an uninitialized TypeSourceInfo.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
Represents a C++ destructor within a class.
CXXDestructorDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool hasTrivialMoveAssignment() const
Determine whether this class has a trivial move assignment operator (C++11 [class....
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasSimpleMoveConstructor() const
true if we know for sure that this class has a single, accessible, unambiguous move constructor that ...
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool hasUserDeclaredDestructor() const
Determine whether this class has a user-declared destructor.
bool defaultedMoveConstructorIsDeleted() const
true if a defaulted move constructor for this class would be deleted.
bool hasUserDeclaredMoveAssignment() const
Determine whether this class has had a move assignment declared by the user.
bool hasDeletedDestructor() const
Returns the destructor decl for this class.
bool hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12)
bool needsImplicitDefaultConstructor() const
Determine if we need to declare a default constructor for this class.
bool needsImplicitMoveConstructor() const
Determine whether this class should get an implicit move constructor or if any existing special membe...
bool hasUserDeclaredCopyAssignment() const
Determine whether this class has a user-declared copy assignment operator.
method_range methods() const
CXXRecordDecl * getDefinition() const
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class....
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool defaultedCopyConstructorIsDeleted() const
true if a defaulted copy constructor for this class would be deleted.
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11,...
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool needsImplicitCopyConstructor() const
Determine whether this class needs an implicit copy constructor to be lazily declared.
bool hasSimpleMoveAssignment() const
true if we know for sure that this class has a single, accessible, unambiguous move assignment operat...
bool hasNonTrivialMoveConstructor() const
Determine whether this class has a non-trivial move constructor (C++11 [class.copy]p12)
bool hasDirectFields() const
Determine whether this class has direct non-static data members.
bool hasUserDeclaredCopyConstructor() const
Determine whether this class has a user-declared copy constructor.
bool hasDefinition() const
bool hasSimpleCopyConstructor() const
true if we know for sure that this class has a single, accessible, unambiguous copy constructor that ...
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
bool hasNonTrivialMoveAssignment() const
Determine whether this class has a non-trivial move assignment operator (C++11 [class....
bool hasUserDeclaredMoveOperation() const
Whether this class has a user-declared move constructor or assignment operator.
bool hasNonTrivialDefaultConstructor() const
Determine whether this class has a non-trivial default constructor (C++11 [class.ctor]p5).
bool hasUserDeclaredMoveConstructor() const
Determine whether this class has had a move constructor declared by the user.
bool forallBases(ForallBasesCallback BaseMatches) const
Determines if the given callback holds for all the direct or indirect base classes of this type.
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6,...
bool hasSimpleCopyAssignment() const
true if we know for sure that this class has a single, accessible, unambiguous copy assignment operat...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
Represents the canonical version of C arrays with a specified constant size.
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContextLookupResult lookup_result
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
ASTContext & getASTContext() const LLVM_READONLY
bool isInvalidDecl() const
SourceLocation getLocation() const
AccessSpecifier getAccess() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
RAII object that enters a new expression evaluation context.
The return type of classify().
This represents one expression.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
An expression trait intrinsic.
Represents a member of a struct/union/class.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isDeleted() const
Whether this function has been deleted.
bool isDefaulted() const
Whether this function is defaulted.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Declaration of a template function.
StringRef getName() const
Return the actual identifier string.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDirect(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a direct initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
Represents the results of name lookup.
UnresolvedSetImpl::iterator iterator
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a C++ nested name specifier, such as "\::std::vector::".
@ Type
A type, stored as a Type*.
Represents an ObjC class declaration.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const
isSuperClassOf - Return true if this class is the specified class or is a super class of the specifie...
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
@ CSK_Normal
Normal lookup.
SmallVectorImpl< OverloadCandidate >::iterator iterator
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best)
Find the best viable function on this overload set, if it exists.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
bool hasNonTrivialObjCLifetime() const
@ PCK_Trivial
The type does not fall into any of the following categories.
@ PCK_ARCStrong
The type is an Objective-C retainable pointer type that is qualified with the ARC __strong qualifier.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
field_range fields() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
CXXSpecialMemberKind asSpecialMember() const
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
bool hasErrorOccurred() const
Determine whether any SFINAE errors have been trapped.
Sema - This implements semantic analysis and AST building for C.
DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD)
Determine the kind of defaulting that would be done for a given function.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
ExprResult ActOnExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
ActOnExpressionTrait - Parsed one of the unary type trait support pseudo-functions.
Definition SemaTypeTraits.cpp:1894
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
Definition SemaTypeTraits.cpp:270
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
Definition SemaTypeTraits.cpp:1509
void DiagnoseTypeTraitDetails(const Expr *E)
If E represents a built-in type trait, or a known standard type trait, try to print more information ...
Definition SemaTypeTraits.cpp:2687
ASTContext & getASTContext() const
void LookupBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, UnresolvedSetImpl &Functions)
ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, bool RequiresADL=true, bool AllowRewrittenCandidates=true, FunctionDecl *DefaultedFn=nullptr)
Create a binary operation that may resolve to an overloaded operator.
bool CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N)
Definition SemaTypeTraits.cpp:1428
ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType LhsTy, Expr *DimExpr, SourceLocation RParen)
ActOnArrayTypeTrait - Parsed one of the binary type trait support pseudo-functions.
Definition SemaTypeTraits.cpp:1808
void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, OverloadCandidateParamOrder PO={})
Add a C++ member function template as a candidate to the candidate set, using template argument deduc...
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false)
Add a C++ function template specialization as a candidate in the candidate set, using template argume...
const LangOptions & getLangOpts() const
void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, bool AllowExplicitConversion=false, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, ConversionSequenceList EarlyConversions={}, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false, bool StrictPackMatch=false)
AddOverloadCandidate - Adds the given function to the set of candidate functions, using the given fun...
ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc)
Definition SemaTypeTraits.cpp:1454
ExprResult BuildExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
Definition SemaTypeTraits.cpp:1915
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
void AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversion=false, OverloadCandidateParamOrder PO={})
AddMethodCandidate - Adds a named decl (which is some kind of method) as a method candidate to the gi...
CanThrowResult canThrow(const Stmt *E)
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
ASTContext::CXXRecordDeclRelocationInfo CheckCXX2CRelocatable(const clang::CXXRecordDecl *D)
Definition SemaTypeTraits.cpp:215
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression=false)
ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< ParsedType > Args, SourceLocation RParenLoc)
Parsed one of the type trait support pseudo-functions.
Definition SemaTypeTraits.cpp:1491
ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, TypeSourceInfo *TSInfo, Expr *DimExpr, SourceLocation RParen)
Definition SemaTypeTraits.cpp:1874
UnsignedOrNone GetDecompositionElementCount(QualType DecompType, SourceLocation Loc)
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
@ Pack
The template argument is actually a parameter pack.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)
Create a new type trait expression.
The base class of the type hierarchy.
bool isIncompleteArrayType() const
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
const T * castAs() const
Member-template castAs.
bool isEnumeralType() const
bool isScalarType() const
bool isVariableArrayType() const
bool isLValueReferenceType() const
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAggregateType() const
Determines whether the type is a C++ aggregate type or C aggregate or union type.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isStructureOrClassType() const
bool isVectorType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs'.
A set of unresolved declarations.
Provides information about an attempted template argument deduction, whose success or failure was des...
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
bool isa(CodeGen::Address addr)
ArrayTypeTrait
Names for the array type traits.
unsigned getTypeTraitArity(TypeTrait T) LLVM_READONLY
Return the arity of the type trait T.
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
@ Result
The result type of a method or function.
const FunctionProtoType * T
CXXSpecialMemberKind
Kinds of C++ special members.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
@ Success
Template argument deduction was successful.
U cast(CodeGen::Address addr)
ConstructorInfo getConstructorInfo(NamedDecl *ND)
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
TypeTrait
Names for traits that operate specifically on types.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...