27#include "llvm/ADT/STLExtras.h"
76 if (CandDecl->isInvalidDecl())
84 ThisTy, Classification,
101 CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl,
nullptr,
119 bool AllowUserDefined) {
127 return Decl && (AllowUserDefined || !
Decl->isUserProvided()) &&
143 return Decl && (AllowUserDefined || !
Decl->isUserProvided()) &&
184 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
189 if (B.isVirtual() || (!BaseDecl->isDependentType() &&
196 if (Field->getType()->isDependentType())
198 if (Field->getType()->isReferenceType())
223 auto IsUnion = [&, Is = std::optional<bool>{}]()
mutable {
258 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
260 return Info->IsRelocatable;
278 if (
Context.containsNonRelocatablePointerAuth(
Type))
296 if (!T->getType()->isVariableArrayType())
299 S.
Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
310 if (!T->getType()->isAtomicType())
313 S.
Diag(T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)
338 llvm_unreachable(
"not a UTT");
340 case UTT_IsCompleteType:
349 case UTT_IsFloatingPoint:
351 case UTT_IsBoundedArray:
353 case UTT_IsLvalueReference:
354 case UTT_IsRvalueReference:
355 case UTT_IsMemberFunctionPointer:
356 case UTT_IsMemberObjectPointer:
358 case UTT_IsScopedEnum:
362 case UTT_IsReference:
363 case UTT_IsArithmetic:
364 case UTT_IsFundamental:
368 case UTT_IsMemberPointer:
369 case UTT_IsTypedResourceElementCompatible:
370 case UTT_IsConstantBufferElementCompatible:
381 case UTT_IsUnboundedArray:
385 case UTT_IsInterfaceClass:
389 case UTT_StructuredBindingSize:
395 case UTT_IsPolymorphic:
400 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
409 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
413 case UTT_IsAggregate:
414 case UTT_IsImplicitLifetime:
419 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
423 case UTT_HasUniqueObjectRepresentations:
428 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
433 case UTT_IsTriviallyCopyable:
434 case UTT_IsStandardLayout:
437 case UTT_IsBitwiseCloneable:
440 case UTT_IsTriviallyRelocatable:
441 case UTT_IsTriviallyEqualityComparable:
442 case UTT_IsCppTriviallyRelocatable:
443 case UTT_CanPassInRegs:
447 case UTT_HasNothrowAssign:
448 case UTT_HasNothrowMoveAssign:
449 case UTT_HasNothrowConstructor:
450 case UTT_HasNothrowCopy:
451 case UTT_HasTrivialAssign:
452 case UTT_HasTrivialMoveAssign:
453 case UTT_HasTrivialDefaultConstructor:
454 case UTT_HasTrivialMoveConstructor:
455 case UTT_HasTrivialCopy:
456 case UTT_HasTrivialDestructor:
457 case UTT_HasVirtualDestructor:
462 case UTT_IsDestructible:
463 case UTT_IsNothrowDestructible:
464 case UTT_IsTriviallyDestructible:
465 case UTT_IsIntangibleType:
470 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
479 if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
485 if (
Self.LookupQualifiedName(Res, RD)) {
486 bool FoundOperator =
false;
494 if ((Operator->*IsDesiredOp)()) {
495 FoundOperator =
true;
497 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
502 return FoundOperator;
523 Functions, &Operand, &Operand);
527 const auto *
CallExpr = dyn_cast<CXXOperatorCallExpr>(
Result.get());
531 auto ParamT = Callee->getParamDecl(0)->getType();
532 if (!Callee->isDefaulted())
534 if (!ParamT->isReferenceType()) {
547 if (
Decl->isLambda())
548 return Decl->isCapturelessLambda();
553 return llvm::all_of(
Decl->bases(),
555 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
556 return HasNonDeletedDefaultedEqualityComparison(
561 auto Type = FD->getType();
562 if (Type->isArrayType())
563 Type = Type->getBaseElementTypeUnsafe()
564 ->getCanonicalTypeUnqualified();
566 if (Type->isReferenceType())
568 if (Type->isEnumeralType()) {
570 Type->castAs<EnumType>()->getDecl()->getDefinitionOrSelf();
571 return equalityComparisonIsDefaulted(S, ED, KeyLoc);
587 CanonicalType->
castAs<EnumType>()->getDecl()->getDefinitionOrSelf();
597 CanonicalType,
false);
624 switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
626 return !T.isDestructedType();
638 assert(!T->isDependentType() &&
"Cannot evaluate traits of dependent type");
643 llvm_unreachable(
"not a UTT");
647 return T->isVoidType();
649 return T->isIntegralType(
C);
650 case UTT_IsFloatingPoint:
651 return T->isFloatingType();
655 if (
const auto *CAT =
C.getAsConstantArrayType(T))
656 return CAT->getSize() != 0;
657 return T->isArrayType();
658 case UTT_IsBoundedArray:
663 if (
const auto *CAT =
C.getAsConstantArrayType(T))
664 return CAT->getSize() != 0;
665 return T->isArrayType() && !T->isIncompleteArrayType();
666 case UTT_IsUnboundedArray:
669 return T->isIncompleteArrayType();
671 return T->isAnyPointerType();
672 case UTT_IsLvalueReference:
673 return T->isLValueReferenceType();
674 case UTT_IsRvalueReference:
675 return T->isRValueReferenceType();
676 case UTT_IsMemberFunctionPointer:
677 return T->isMemberFunctionPointerType();
678 case UTT_IsMemberObjectPointer:
679 return T->isMemberDataPointerType();
681 return T->isEnumeralType();
682 case UTT_IsScopedEnum:
683 return T->isScopedEnumeralType();
685 return T->isUnionType();
687 return T->isClassType() || T->isStructureType() || T->isInterfaceType();
689 return T->isFunctionType();
693 case UTT_IsReference:
694 return T->isReferenceType();
695 case UTT_IsArithmetic:
696 return T->isArithmeticType() && !T->isEnumeralType();
697 case UTT_IsFundamental:
698 return T->isFundamentalType();
700 return T->isObjectType();
706 if (T->isObjCLifetimeType()) {
707 switch (T.getObjCLifetime()) {
719 return T->isScalarType();
721 return T->isCompoundType();
722 case UTT_IsMemberPointer:
723 return T->isMemberPointerType();
728 return T.isConstQualified();
730 return T.isVolatileQualified();
732 return T.isTrivialType(
C);
733 case UTT_IsTriviallyCopyable:
734 return T.isTriviallyCopyableType(
C);
735 case UTT_IsStandardLayout:
736 return T->isStandardLayoutType();
738 return T.isPODType(
C);
740 return T->isLiteralType(
C);
745 case UTT_IsPolymorphic:
753 case UTT_IsAggregate:
757 return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
758 T->isAnyComplexType();
762 case UTT_IsInterfaceClass:
767 return RD->
hasAttr<FinalAttr>();
772 return T->isFloatingType() ||
773 (T->isSignedIntegerType() && !T->isEnumeralType());
776 return T->isUnsignedIntegerType() && !T->isEnumeralType();
794 case UTT_HasTrivialDefaultConstructor:
801 if (
CXXRecordDecl *RD =
C.getBaseElementType(T)->getAsCXXRecordDecl())
805 case UTT_HasTrivialMoveConstructor:
811 if (
CXXRecordDecl *RD =
C.getBaseElementType(T)->getAsCXXRecordDecl())
815 case UTT_HasTrivialCopy:
821 if (T.isPODType(
C) || T->isReferenceType())
827 case UTT_HasTrivialMoveAssign:
833 if (
CXXRecordDecl *RD =
C.getBaseElementType(T)->getAsCXXRecordDecl())
837 case UTT_HasTrivialAssign:
850 if (T.isConstQualified())
858 case UTT_IsDestructible:
859 case UTT_IsTriviallyDestructible:
860 case UTT_IsNothrowDestructible:
863 if (T->isReferenceType())
867 if (T->isObjCLifetimeType() &&
874 if (T->isIncompleteType() || T->isFunctionType())
879 if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
886 if (
auto *RD =
C.getBaseElementType(T)->getAsCXXRecordDecl()) {
897 if (UTT == UTT_IsNothrowDestructible) {
899 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
906 case UTT_HasTrivialDestructor:
913 if (T.isPODType(
C) || T->isReferenceType())
917 if (T->isObjCLifetimeType() &&
921 if (
CXXRecordDecl *RD =
C.getBaseElementType(T)->getAsCXXRecordDecl())
925 case UTT_HasNothrowAssign:
933 if (
C.getBaseElementType(T).isConstQualified())
935 if (T->isReferenceType())
937 if (T.isPODType(
C) || T->isObjCLifetimeType())
940 if (
auto *RD = T->getAsCXXRecordDecl())
946 case UTT_HasNothrowMoveAssign:
953 if (
auto *RD =
C.getBaseElementType(T)->getAsCXXRecordDecl())
959 case UTT_HasNothrowCopy:
965 if (T.isPODType(
C) || T->isReferenceType() || T->isObjCLifetimeType())
972 bool FoundConstructor =
false;
974 for (
const auto *ND :
Self.LookupConstructors(RD)) {
985 FoundConstructor =
true;
987 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
997 return FoundConstructor;
1000 case UTT_HasNothrowConstructor:
1006 if (T.isPODType(
C) || T->isObjCLifetimeType())
1008 if (
CXXRecordDecl *RD =
C.getBaseElementType(T)->getAsCXXRecordDecl()) {
1012 bool FoundConstructor =
false;
1013 for (
const auto *ND :
Self.LookupConstructors(RD)) {
1022 FoundConstructor =
true;
1024 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
1033 return FoundConstructor;
1036 case UTT_HasVirtualDestructor:
1048 case UTT_IsCompleteType:
1052 return !T->isIncompleteType();
1053 case UTT_HasUniqueObjectRepresentations:
1054 return C.hasUniqueObjectRepresentations(T);
1055 case UTT_IsTriviallyRelocatable:
1057 case UTT_IsBitwiseCloneable:
1058 return T.isBitwiseCloneableType(
C);
1059 case UTT_IsCppTriviallyRelocatable:
1060 return Self.IsCXXTriviallyRelocatableType(T);
1061 case UTT_CanPassInRegs:
1062 if (
CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
1064 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
1066 case UTT_IsTriviallyEqualityComparable:
1068 case UTT_IsImplicitLifetime: {
1070 tok::kw___builtin_is_implicit_lifetime);
1072 tok::kw___builtin_is_implicit_lifetime);
1095 bool HasTrivialNonDeletedDtr =
1097 if (!HasTrivialNonDeletedDtr)
1100 if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
1102 if (Ctr->isTrivial())
1117 case UTT_IsIntangibleType:
1118 assert(
Self.getLangOpts().HLSL &&
"intangible types are HLSL-only feature");
1119 if (!T->isVoidType() && !T->isIncompleteArrayType())
1121 diag::err_incomplete_type))
1124 tok::kw___builtin_hlsl_is_intangible))
1126 return T->isHLSLIntangibleType();
1128 case UTT_IsTypedResourceElementCompatible:
1129 assert(
Self.getLangOpts().HLSL &&
1130 "typed resource element compatible types are an HLSL-only feature");
1131 if (T->isIncompleteType())
1134 return Self.HLSL().IsTypedResourceElementCompatible(T);
1136 case UTT_IsConstantBufferElementCompatible:
1137 assert(
Self.getLangOpts().HLSL &&
1138 "constant buffer element compatible types are an HLSL-only feature");
1139 if (T->isIncompleteType())
1142 return Self.HLSL().IsConstantBufferElementCompatible(T);
1153 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1194 LhsT =
Self.Context.getRValueReferenceType(LhsT);
1230 case TypeTrait::UTT_StructuredBindingSize: {
1232 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1236 S.
Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;
1244 llvm_unreachable(
"Not a SizeT type trait");
1261 if (Kind <=
BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1262 Kind != BTT_ReferenceConstructsFromTemporary &&
1263 Kind != BTT_ReferenceConvertsFromTemporary)
1267 case clang::BTT_ReferenceBindsToTemporary:
1268 case clang::BTT_ReferenceConstructsFromTemporary:
1269 case clang::BTT_ReferenceConvertsFromTemporary:
1270 case clang::TT_IsConstructible:
1271 case clang::TT_IsNothrowConstructible:
1272 case clang::TT_IsTriviallyConstructible: {
1286 assert(!Args.empty());
1291 bool UseRawObjectType =
1292 Kind == clang::BTT_ReferenceBindsToTemporary ||
1293 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1294 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1299 for (
const auto *TSI : Args) {
1305 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1311 if (T->isIncompleteType() || T->isFunctionType() ||
1312 (UseRawObjectType && !T->isReferenceType()))
1320 llvm::BumpPtrAllocator OpaqueExprAllocator;
1322 ArgExprs.reserve(Args.size() - 1);
1323 for (
unsigned I = 1, N = Args.size(); I != N; ++I) {
1324 QualType ArgTy = Args[I]->getType();
1344 Kind == clang::BTT_ReferenceConvertsFromTemporary
1355 if (Kind == clang::TT_IsConstructible)
1358 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1359 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1360 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1361 if (!T->isReferenceType())
1365 if (T.getNonReferenceType()->isFunctionType())
1368 if (!
Init.isDirectReferenceBinding())
1371 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1375 if (
U->isReferenceType())
1383 OpaqueExprAllocator)
1387 if (Kind == clang::TT_IsNothrowConstructible)
1390 if (Kind == clang::TT_IsTriviallyConstructible) {
1393 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1401 llvm_unreachable(
"unhandled type trait");
1405 llvm_unreachable(
"not a TT");
1415 case UTT_HasNothrowAssign:
1416 case UTT_HasNothrowMoveAssign:
1417 Replacement = BTT_IsNothrowAssignable;
1419 case UTT_HasNothrowCopy:
1420 case UTT_HasNothrowConstructor:
1421 Replacement = TT_IsNothrowConstructible;
1423 case UTT_HasTrivialAssign:
1424 case UTT_HasTrivialMoveAssign:
1425 Replacement = BTT_IsTriviallyAssignable;
1427 case UTT_HasTrivialCopy:
1428 Replacement = UTT_IsTriviallyCopyable;
1430 case UTT_HasTrivialDefaultConstructor:
1431 case UTT_HasTrivialMoveConstructor:
1432 Replacement = TT_IsTriviallyConstructible;
1434 case UTT_HasTrivialDestructor:
1435 Replacement = UTT_IsTriviallyDestructible;
1437 case UTT_IsTriviallyRelocatable:
1438 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1440 case BTT_ReferenceBindsToTemporary:
1441 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1446 S.
Diag(KWLoc, diag::warn_deprecated_builtin)
1452 if (Arity && N != Arity) {
1453 Diag(Loc, diag::err_type_trait_arity)
1454 << Arity << 0 << (Arity > 1) << (
int)N <<
SourceRange(Loc);
1458 if (!Arity && N == 0) {
1459 Diag(Loc, diag::err_type_trait_arity)
1472 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1484 *
this, Kind, KWLoc, Args[0]->
getType()))
1487 DiagnoseBuiltinDeprecation(*
this, Kind, KWLoc);
1490 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1491 if (Args[I]->
getType()->isDependentType()) {
1502 KWLoc, Kind, Args, RParenLoc,
Result);
1508 Args, RParenLoc,
Result);
1511 llvm_unreachable(
"unhandled type trait return type");
1518 ConvertedArgs.reserve(Args.size());
1520 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1524 TInfo =
Context.getTrivialTypeSourceInfo(T, KWLoc);
1526 ConvertedArgs.push_back(TInfo);
1539 const RecordType *lhsRecord = LhsT->
getAsCanonical<RecordType>();
1540 const RecordType *rhsRecord = RhsT->
getAsCanonical<RecordType>();
1541 if (!rhsRecord || !lhsRecord) {
1544 if (!LHSObjTy || !RHSObjTy)
1549 if (!BaseInterface || !DerivedInterface)
1553 diag::err_incomplete_type_used_in_type_trait_expr))
1559 assert(
Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1560 (lhsRecord == rhsRecord));
1564 if (lhsRecord && lhsRecord->getDecl()->isUnion())
1566 if (rhsRecord && rhsRecord->getDecl()->isUnion())
1569 if (lhsRecord == rhsRecord)
1577 diag::err_incomplete_type_used_in_type_trait_expr))
1592 "Cannot evaluate traits of dependent types");
1598 case BTT_IsVirtualBaseOf: {
1599 const RecordType *BaseRecord = LhsT->
getAsCanonical<RecordType>();
1600 const RecordType *DerivedRecord = RhsT->
getAsCanonical<RecordType>();
1602 if (!BaseRecord || !DerivedRecord) {
1604 tok::kw___builtin_is_virtual_base_of);
1606 tok::kw___builtin_is_virtual_base_of);
1610 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1613 if (!BaseRecord->isStructureOrClassType() ||
1614 !DerivedRecord->isStructureOrClassType())
1618 diag::err_incomplete_type))
1625 return Self.Context.hasSameType(LhsT, RhsT);
1626 case BTT_TypeCompatible: {
1629 QualType Lhs =
Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1630 QualType Rhs =
Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1631 return Self.Context.typesAreCompatible(Lhs, Rhs);
1633 case BTT_IsConvertible:
1634 case BTT_IsConvertibleTo:
1635 case BTT_IsNothrowConvertible: {
1638 llvm::BumpPtrAllocator OpaqueExprAllocator;
1640 OpaqueExprAllocator);
1644 if (BTT != BTT_IsNothrowConvertible)
1650 case BTT_IsAssignable:
1651 case BTT_IsNothrowAssignable:
1652 case BTT_IsTriviallyAssignable: {
1665 Self.RequireCompleteType(
1667 diag::err_incomplete_type_used_in_type_trait_expr))
1670 Self.RequireCompleteType(
1672 diag::err_incomplete_type_used_in_type_trait_expr))
1682 if (Ty->isObjectType() || Ty->isFunctionType())
1683 Ty =
Self.Context.getRValueReferenceType(Ty);
1684 return {KeyLoc, Ty.getNonLValueExprType(
Self.Context),
1688 auto Lhs = createDeclValExpr(LhsT);
1689 auto Rhs = createDeclValExpr(RhsT);
1698 Self.BuildBinOp(
nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1703 Self.CheckUnusedVolatileAssignment(
Result.get());
1708 if (BTT == BTT_IsAssignable)
1711 if (BTT == BTT_IsNothrowAssignable)
1714 if (BTT == BTT_IsTriviallyAssignable) {
1720 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1721 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1723 return !
Result.get()->hasNonTrivialCall(
Self.Context);
1726 llvm_unreachable(
"unhandled type trait");
1729 case BTT_IsLayoutCompatible: {
1732 diag::err_incomplete_type);
1735 diag::err_incomplete_type);
1740 return Self.IsLayoutCompatible(LhsT, RhsT);
1742 case BTT_IsPointerInterconvertibleBaseOf: {
1744 !
Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1746 diag::err_incomplete_type);
1750 tok::kw___is_pointer_interconvertible_base_of);
1752 tok::kw___is_pointer_interconvertible_base_of);
1754 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1756 case BTT_IsDeducible: {
1759 return Self.DeduceTemplateArgumentsFromType(
1760 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1763 case BTT_IsScalarizedLayoutCompatible: {
1766 diag::err_incomplete_type))
1770 diag::err_incomplete_type))
1774 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1776 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1778 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1780 case BTT_LtSynthesizesFromSpaceship:
1781 case BTT_LeSynthesizesFromSpaceship:
1782 case BTT_GtSynthesizesFromSpaceship:
1783 case BTT_GeSynthesizesFromSpaceship: {
1802 case BTT_LtSynthesizesFromSpaceship:
1803 return BinaryOperatorKind::BO_LT;
1804 case BTT_LeSynthesizesFromSpaceship:
1805 return BinaryOperatorKind::BO_LE;
1806 case BTT_GtSynthesizesFromSpaceship:
1807 return BinaryOperatorKind::BO_GT;
1808 case BTT_GeSynthesizesFromSpaceship:
1809 return BinaryOperatorKind::BO_GE;
1811 llvm_unreachable(
"Trying to Synthesize non-comparison operator?");
1816 Self.LookupBinOp(
Self.TUScope, KeyLoc, OpKind, Functions);
1819 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1826 llvm_unreachable(
"not a BTT");
1828 llvm_unreachable(
"Unknown type trait or not implemented");
1837 TSInfo =
Context.getTrivialTypeSourceInfo(T);
1845 assert(!T->isDependentType() &&
"Cannot evaluate traits of dependent type");
1849 if (T->isArrayType()) {
1851 while (
const ArrayType *AT =
Self.Context.getAsArrayType(T)) {
1853 T = AT->getElementType();
1859 case ATT_ArrayExtent: {
1862 if (
Self.VerifyIntegerConstantExpression(
1863 DimExpr, &
Value, diag::err_dimension_expr_not_constant_integer)
1866 if (
Value.isSigned() &&
Value.isNegative()) {
1867 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1873 if (T->isArrayType()) {
1875 bool Matched =
false;
1876 while (
const ArrayType *AT =
Self.Context.getAsArrayType(T)) {
1882 T = AT->getElementType();
1885 if (Matched && T->isArrayType()) {
1887 Self.Context.getAsConstantArrayType(T))
1888 return CAT->getLimitedSize();
1894 llvm_unreachable(
"Unknown type trait or not implemented");
1905 if (!T->isDependentType())
1914 RParen,
Context.getSizeType());
1930 case ET_IsLValueExpr:
1932 case ET_IsRValueExpr:
1935 llvm_unreachable(
"Expression trait not covered by switch");
1956 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
1957 .Case(
"is_trivially_relocatable",
1958 TypeTrait::UTT_IsCppTriviallyRelocatable)
1959 .Case(
"is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1960 .Case(
"is_assignable", TypeTrait::BTT_IsAssignable)
1961 .Case(
"is_empty", TypeTrait::UTT_IsEmpty)
1962 .Case(
"is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1963 .Case(
"is_aggregate", TypeTrait::UTT_IsAggregate)
1964 .Case(
"is_constructible", TypeTrait::TT_IsConstructible)
1965 .Case(
"is_final", TypeTrait::UTT_IsFinal)
1966 .Case(
"is_abstract", TypeTrait::UTT_IsAbstract)
1967 .Default(std::nullopt);
1971 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1979 std::optional<TypeTrait> Trait;
1982 if (
const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
1983 Trait = TraitExpr->getTrait();
1984 for (
const auto *Arg : TraitExpr->getArgs())
1985 Args.push_back(Arg->getType());
1986 return {{Trait.value(), std::move(Args)}};
1988 const auto *Ref = dyn_cast<DeclRefExpr>(E);
1990 return std::nullopt;
1993 if (
const auto *VD =
1994 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
1995 if (!VD->isInStdNamespace())
1996 return std::nullopt;
1997 StringRef Name = VD->getIdentifier()->getName();
1998 if (!Name.consume_back(
"_v"))
1999 return std::nullopt;
2002 return std::nullopt;
2003 for (
const auto &Arg : VD->getTemplateArgs().asArray()) {
2005 for (
const auto &InnerArg : Arg.pack_elements())
2006 Args.push_back(InnerArg.getAsType());
2008 Args.push_back(Arg.getAsType());
2010 llvm_unreachable(
"Unexpected kind");
2013 return {{Trait.value(), std::move(Args)}};
2017 if (
const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2018 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr(
"value")) {
2021 return std::nullopt;
2022 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2024 return std::nullopt;
2025 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2027 return std::nullopt;
2030 return std::nullopt;
2031 for (
const auto &Arg : Ts->template_arguments())
2032 Args.push_back(Arg.getAsType());
2033 return {{Trait.value(), std::move(Args)}};
2035 return std::nullopt;
2043 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2044 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2058 const auto *
Decl = cast_or_null<CXXConstructorDecl>(
2060 if (
Decl &&
Decl->isUserProvided())
2061 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2062 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2068 if (
Decl &&
Decl->isUserProvided())
2069 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2070 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2074 Dtr = Dtr->getCanonicalDecl();
2075 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2076 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2077 << diag::TraitNotSatisfiedReason::DeletedDtr << 1
2078 << Dtr->getSourceRange();
2086 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2088 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2089 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2090 << B.getSourceRange();
2092 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2093 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2094 << B.getSourceRange();
2097 if (!Field->getType()->isReferenceType() &&
2099 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2100 << diag::TraitNotSatisfiedReason::NTRField << Field
2101 << Field->getType() << Field->getSourceRange();
2104 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2105 << diag::TraitNotSatisfiedReason::DeletedDtr << 0
2114 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2115 << T << diag::TraitName::TriviallyRelocatable;
2116 if (T->isVariablyModifiedType())
2117 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2118 << diag::TraitNotSatisfiedReason::VLA;
2120 if (T->isReferenceType())
2121 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2122 << diag::TraitNotSatisfiedReason::Ref;
2123 T = T.getNonReferenceType();
2125 if (T.hasNonTrivialObjCLifetime())
2126 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2127 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2143 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2145 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2146 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2147 << B.getSourceRange();
2148 if (!B.getType().isTriviallyCopyableType(D->
getASTContext())) {
2149 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2150 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2151 << B.getSourceRange();
2155 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2156 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2157 << diag::TraitNotSatisfiedReason::NTCField << Field
2158 << Field->getType() << Field->getSourceRange();
2162 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2163 << diag::TraitNotSatisfiedReason::DeletedDtr
2167 if (Method->isTrivial() || !Method->isUserProvided()) {
2170 auto SpecialMemberKind =
2172 switch (SpecialMemberKind) {
2184 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2185 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2186 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2187 << IsMove << Method->getSourceRange();
2203 bool ContainsVoid =
false;
2205 ContainsVoid |= ArgTy->isVoidType();
2209 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2210 << diag::TraitNotSatisfiedReason::CVVoidType;
2213 if (T->isFunctionType())
2214 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2215 << diag::TraitNotSatisfiedReason::FunctionType;
2217 if (T->isIncompleteArrayType())
2218 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2219 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2225 llvm::BumpPtrAllocator OpaqueExprAllocator;
2227 ArgExprs.reserve(Ts.size() - 1);
2228 for (
unsigned I = 1, N = Ts.size(); I != N; ++I) {
2246 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2252 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2253 << T << diag::TraitName::TriviallyCopyable;
2255 if (T->isReferenceType())
2256 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2257 << diag::TraitNotSatisfiedReason::Ref;
2274 if (Ty->isObjectType() || Ty->isFunctionType())
2276 return {Loc, Ty.getNonLValueExprType(SemaRef.
Context),
2280 auto LHS = createDeclValExpr(T);
2281 auto RHS = createDeclValExpr(
U);
2287 SemaRef.
BuildBinOp(
nullptr, Loc, BO_Assign, &LHS, &RHS);
2298 for (
const auto *Field : D->
fields()) {
2299 if (Field->isZeroLengthBitField())
2301 if (Field->isBitField()) {
2302 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2303 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2304 << Field->getSourceRange();
2307 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2308 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2309 << Field->getType() << Field->getSourceRange();
2313 for (
const auto *M : D->
methods()) {
2314 if (M->isVirtual()) {
2315 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2316 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2317 << M->getSourceRange();
2323 for (
const auto &B : D->
bases()) {
2324 const auto *BR = B.getType()->getAsCXXRecordDecl();
2325 if (!BR || BR->isInvalidDecl())
2327 if (B.isVirtual()) {
2328 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2329 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2330 << B.getSourceRange();
2332 if (!BR->isEmpty()) {
2333 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2334 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2335 << B.getSourceRange();
2342 S.
Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2347 if (T->isReferenceType())
2348 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2349 << diag::TraitNotSatisfiedReason::Ref;
2350 T = T.getNonReferenceType();
2353 T = AT->getElementType();
2355 if (
auto *D = T->getAsCXXRecordDecl()) {
2356 if (D->hasDefinition()) {
2358 S.
Diag(D->getLocation(), diag::note_defined_here) << D;
2370 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2371 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2379 S.
Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2380 if (T->isReferenceType()) {
2381 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2382 << diag::TraitNotSatisfiedReason::Ref;
2383 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2384 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2389 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2390 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2393 if (T->isFunctionType()) {
2394 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2395 << diag::TraitNotSatisfiedReason::FunctionType;
2396 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2397 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2400 if (!T->isRecordType()) {
2401 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2402 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2405 if (
const auto *D = T->getAsCXXRecordDecl())
2410 int NumBasesWithFields = 0;
2417 if (!Field->isUnnamedBitField()) {
2418 if (++NumBasesWithFields > 1)
2430 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2431 if (B.isVirtual()) {
2432 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2433 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2434 << B.getSourceRange();
2436 if (!B.getType()->isStandardLayoutType()) {
2437 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2438 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2439 << B.getSourceRange();
2447 if (Field->isUnnamedBitField())
2458 if (Field->getAccess() != FirstAccess) {
2460 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2461 << diag::TraitNotSatisfiedReason::MixedAccess;
2466 SemaRef.
Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2467 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2475 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2476 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2482 for (
const auto *M : D->
methods()) {
2483 if (M->isVirtual()) {
2489 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2490 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2491 SemaRef.
Diag(VirtualMD->getLocation(), diag::note_defined_here)
2495 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2496 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2497 SemaRef.
Diag(D->getLocation(), diag::note_defined_here) << D;
2501 if (!Field->getType()->isStandardLayoutType()) {
2502 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2503 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2504 << Field->getType() << Field->getSourceRange();
2518 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2519 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2527 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2528 << T << diag::TraitName::StandardLayout;
2531 if (T->isVariablyModifiedType()) {
2532 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2533 << diag::TraitNotSatisfiedReason::VLA;
2537 if (T->isReferenceType()) {
2538 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2539 << diag::TraitNotSatisfiedReason::Ref;
2542 T = T.getNonReferenceType();
2556 if (Ctor->isUserProvided())
2557 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2558 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2559 if (Ctor->isInheritingConstructor())
2560 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2561 << diag::TraitNotSatisfiedReason::InheritedCtr;
2564 if (llvm::any_of(D->
decls(), [](
auto const *Sub) {
2565 return isa<ConstructorUsingShadowDecl>(Sub);
2567 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2568 << diag::TraitNotSatisfiedReason::InheritedCtr;
2572 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2573 << diag::TraitNotSatisfiedReason::PolymorphicType
2577 if (B.isVirtual()) {
2578 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2579 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2580 << B.getSourceRange();
2587 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2588 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2597 if (Method->isVirtual()) {
2598 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2599 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2600 << Method->getSourceRange();
2609 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2610 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2623 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2624 << T << diag::TraitName::Aggregate;
2626 if (T->isVoidType())
2627 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2628 << diag::TraitNotSatisfiedReason::CVVoidType;
2630 T = T.getNonReferenceType();
2644 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2645 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2646 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2647 << B.getType() << B.getSourceRange();
2654 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2655 << T << diag::TraitName::Abstract;
2657 if (T->isReferenceType()) {
2658 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2659 << diag::TraitNotSatisfiedReason::Ref;
2660 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2661 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2665 if (T->isUnionType()) {
2666 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2667 << diag::TraitNotSatisfiedReason::UnionType;
2668 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2669 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2674 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2675 << diag::TraitNotSatisfiedReason::ArrayType;
2676 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2677 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2681 if (T->isFunctionType()) {
2682 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2683 << diag::TraitNotSatisfiedReason::FunctionType;
2684 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2685 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2689 if (T->isPointerType()) {
2690 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2691 << diag::TraitNotSatisfiedReason::PointerType;
2692 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2693 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2697 if (!T->isStructureOrClassType()) {
2698 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2699 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2717 const auto &[Trait, Args] = TraitInfo.value();
2719 case UTT_IsCppTriviallyRelocatable:
2722 case UTT_IsTriviallyCopyable:
2725 case BTT_IsAssignable:
2731 case UTT_IsStandardLayout:
2734 case TT_IsConstructible:
2737 case UTT_IsAggregate:
2749 case UTT_IsAbstract:
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.
Result
Implement __builtin_bit_cast and related operations.
This file declares semantic analysis for HLSL constructs.
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs, SourceLocation KeyLoc)
static bool HasNonDeletedDefaultedEqualityComparison(Sema &S, const CXXRecordDecl *Decl, SourceLocation KeyLoc)
static void DiagnoseNonAbstractReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static APValue EvaluateSizeTTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not a VLA.
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)
static std::optional< TypeTrait > StdNameToTypeTrait(StringRef Name)
static void DiagnoseNonConstructibleReason(Sema &SemaRef, SourceLocation Loc, const llvm::SmallVector< clang::QualType, 1 > &Ts)
static bool IsEligibleForTrivialRelocation(Sema &SemaRef, const CXXRecordDecl *D)
static CXXMethodDecl * LookupSpecialMemberFromXValue(Sema &SemaRef, const CXXRecordDecl *RD, bool Assign)
static bool hasSuitableMoveAssignmentOperatorForRelocation(Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined)
static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T, clang::tok::TokenKind TypeTraitID)
Checks that type T is not an atomic type (_Atomic).
static bool equalityComparisonIsDefaulted(Sema &S, const TagDecl *Decl, SourceLocation KeyLoc)
static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static void DiagnoseIsFinalReason(Sema &S, SourceLocation Loc, const CXXRecordDecl *D)
static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc, const CXXRecordDecl *D)
static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D)
static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E)
static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E)
std::optional< std::pair< TypeTrait, llvm::SmallVector< QualType, 1 > > > ExtractedTypeTraitInfo
static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc, QualType T, QualType U)
static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T)
static void DiagnoseNonDefaultMovable(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static bool IsDefaultMovable(Sema &SemaRef, const CXXRecordDecl *D)
static bool hasSuitableConstructorForRelocation(Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined)
static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT, SourceLocation KeyLoc, TypeSourceInfo *TInfo)
static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, QualType T, Expr *DimExpr, SourceLocation KeyLoc)
static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT, SourceLocation Loc, QualType ArgTy)
Check the completeness of a type in a unary type trait.
static ExprResult CheckConvertibilityForTypeTraits(Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs, SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator)
static void DiagnoseNonAggregateReason(Sema &SemaRef, SourceLocation Loc, const CXXRecordDecl *D)
static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool IsDependent)
static bool isTriviallyEqualityComparableType(Sema &S, QualType Type, SourceLocation KeyLoc)
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 isTriviallyCopyable() const
Determine whether this class is considered trivially copyable per (C++11 [class]p6).
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<int>::".
@ 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.
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
void DiagnoseTypeTraitDetails(const Expr *E)
If E represents a built-in type trait, or a known standard type trait, try to print more information ...
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)
ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, ParsedType LhsTy, Expr *DimExpr, SourceLocation RParen)
ActOnArrayTypeTrait - Parsed one of the binary type trait support pseudo-functions.
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)
ExprResult BuildExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
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)
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.
ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, TypeSourceInfo *TSInfo, Expr *DimExpr, SourceLocation RParen)
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
Represents the declaration of a struct/union/class/enum.
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.
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
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<specific type>'.
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.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ 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.
OptionalUnsigned< unsigned > UnsignedOrNone
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...