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 for (
const auto *TSI : Args) {
1297 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1303 if (T->isIncompleteType() || T->isFunctionType())
1314 bool UseRawObjectType =
1315 Kind == clang::BTT_ReferenceBindsToTemporary ||
1316 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1317 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1319 llvm::BumpPtrAllocator OpaqueExprAllocator;
1321 ArgExprs.reserve(Args.size() - 1);
1322 for (
unsigned I = 1, N = Args.size(); I != N; ++I) {
1323 QualType ArgTy = Args[I]->getType();
1343 Kind == clang::BTT_ReferenceConvertsFromTemporary
1354 if (Kind == clang::TT_IsConstructible)
1357 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1358 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1359 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1360 if (!T->isReferenceType())
1364 if (T.getNonReferenceType()->isFunctionType())
1367 if (!
Init.isDirectReferenceBinding())
1370 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1374 if (
U->isReferenceType())
1382 OpaqueExprAllocator)
1386 if (Kind == clang::TT_IsNothrowConstructible)
1389 if (Kind == clang::TT_IsTriviallyConstructible) {
1392 if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1400 llvm_unreachable(
"unhandled type trait");
1404 llvm_unreachable(
"not a TT");
1414 case UTT_HasNothrowAssign:
1415 case UTT_HasNothrowMoveAssign:
1416 Replacement = BTT_IsNothrowAssignable;
1418 case UTT_HasNothrowCopy:
1419 case UTT_HasNothrowConstructor:
1420 Replacement = TT_IsNothrowConstructible;
1422 case UTT_HasTrivialAssign:
1423 case UTT_HasTrivialMoveAssign:
1424 Replacement = BTT_IsTriviallyAssignable;
1426 case UTT_HasTrivialCopy:
1427 Replacement = UTT_IsTriviallyCopyable;
1429 case UTT_HasTrivialDefaultConstructor:
1430 case UTT_HasTrivialMoveConstructor:
1431 Replacement = TT_IsTriviallyConstructible;
1433 case UTT_HasTrivialDestructor:
1434 Replacement = UTT_IsTriviallyDestructible;
1436 case UTT_IsTriviallyRelocatable:
1437 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1439 case BTT_ReferenceBindsToTemporary:
1440 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1445 S.
Diag(KWLoc, diag::warn_deprecated_builtin)
1451 if (Arity && N != Arity) {
1452 Diag(Loc, diag::err_type_trait_arity)
1453 << Arity << 0 << (Arity > 1) << (
int)N <<
SourceRange(Loc);
1457 if (!Arity && N == 0) {
1458 Diag(Loc, diag::err_type_trait_arity)
1471 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1483 *
this, Kind, KWLoc, Args[0]->
getType()))
1486 DiagnoseBuiltinDeprecation(*
this, Kind, KWLoc);
1489 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1490 if (Args[I]->
getType()->isDependentType()) {
1501 KWLoc, Kind, Args, RParenLoc,
Result);
1507 Args, RParenLoc,
Result);
1510 llvm_unreachable(
"unhandled type trait return type");
1517 ConvertedArgs.reserve(Args.size());
1519 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1523 TInfo =
Context.getTrivialTypeSourceInfo(T, KWLoc);
1525 ConvertedArgs.push_back(TInfo);
1538 const RecordType *lhsRecord = LhsT->
getAsCanonical<RecordType>();
1539 const RecordType *rhsRecord = RhsT->
getAsCanonical<RecordType>();
1540 if (!rhsRecord || !lhsRecord) {
1543 if (!LHSObjTy || !RHSObjTy)
1548 if (!BaseInterface || !DerivedInterface)
1552 diag::err_incomplete_type_used_in_type_trait_expr))
1558 assert(
Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1559 (lhsRecord == rhsRecord));
1563 if (lhsRecord && lhsRecord->getDecl()->isUnion())
1565 if (rhsRecord && rhsRecord->getDecl()->isUnion())
1568 if (lhsRecord == rhsRecord)
1576 diag::err_incomplete_type_used_in_type_trait_expr))
1591 "Cannot evaluate traits of dependent types");
1597 case BTT_IsVirtualBaseOf: {
1598 const RecordType *BaseRecord = LhsT->
getAsCanonical<RecordType>();
1599 const RecordType *DerivedRecord = RhsT->
getAsCanonical<RecordType>();
1601 if (!BaseRecord || !DerivedRecord) {
1603 tok::kw___builtin_is_virtual_base_of);
1605 tok::kw___builtin_is_virtual_base_of);
1609 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1612 if (!BaseRecord->isStructureOrClassType() ||
1613 !DerivedRecord->isStructureOrClassType())
1617 diag::err_incomplete_type))
1624 return Self.Context.hasSameType(LhsT, RhsT);
1625 case BTT_TypeCompatible: {
1628 QualType Lhs =
Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1629 QualType Rhs =
Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1630 return Self.Context.typesAreCompatible(Lhs, Rhs);
1632 case BTT_IsConvertible:
1633 case BTT_IsConvertibleTo:
1634 case BTT_IsNothrowConvertible: {
1637 llvm::BumpPtrAllocator OpaqueExprAllocator;
1639 OpaqueExprAllocator);
1643 if (BTT != BTT_IsNothrowConvertible)
1649 case BTT_IsAssignable:
1650 case BTT_IsNothrowAssignable:
1651 case BTT_IsTriviallyAssignable: {
1664 Self.RequireCompleteType(
1666 diag::err_incomplete_type_used_in_type_trait_expr))
1669 Self.RequireCompleteType(
1671 diag::err_incomplete_type_used_in_type_trait_expr))
1681 if (Ty->isObjectType() || Ty->isFunctionType())
1682 Ty =
Self.Context.getRValueReferenceType(Ty);
1683 return {KeyLoc, Ty.getNonLValueExprType(
Self.Context),
1687 auto Lhs = createDeclValExpr(LhsT);
1688 auto Rhs = createDeclValExpr(RhsT);
1697 Self.BuildBinOp(
nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1702 Self.CheckUnusedVolatileAssignment(
Result.get());
1707 if (BTT == BTT_IsAssignable)
1710 if (BTT == BTT_IsNothrowAssignable)
1713 if (BTT == BTT_IsTriviallyAssignable) {
1719 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1720 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1722 return !
Result.get()->hasNonTrivialCall(
Self.Context);
1725 llvm_unreachable(
"unhandled type trait");
1728 case BTT_IsLayoutCompatible: {
1731 diag::err_incomplete_type);
1734 diag::err_incomplete_type);
1739 return Self.IsLayoutCompatible(LhsT, RhsT);
1741 case BTT_IsPointerInterconvertibleBaseOf: {
1743 !
Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1745 diag::err_incomplete_type);
1749 tok::kw___is_pointer_interconvertible_base_of);
1751 tok::kw___is_pointer_interconvertible_base_of);
1753 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1755 case BTT_IsDeducible: {
1758 return Self.DeduceTemplateArgumentsFromType(
1759 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1762 case BTT_IsScalarizedLayoutCompatible: {
1765 diag::err_incomplete_type))
1769 diag::err_incomplete_type))
1773 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1775 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1777 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1779 case BTT_LtSynthesizesFromSpaceship:
1780 case BTT_LeSynthesizesFromSpaceship:
1781 case BTT_GtSynthesizesFromSpaceship:
1782 case BTT_GeSynthesizesFromSpaceship: {
1801 case BTT_LtSynthesizesFromSpaceship:
1802 return BinaryOperatorKind::BO_LT;
1803 case BTT_LeSynthesizesFromSpaceship:
1804 return BinaryOperatorKind::BO_LE;
1805 case BTT_GtSynthesizesFromSpaceship:
1806 return BinaryOperatorKind::BO_GT;
1807 case BTT_GeSynthesizesFromSpaceship:
1808 return BinaryOperatorKind::BO_GE;
1810 llvm_unreachable(
"Trying to Synthesize non-comparison operator?");
1815 Self.LookupBinOp(
Self.TUScope, KeyLoc, OpKind, Functions);
1818 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1825 llvm_unreachable(
"not a BTT");
1827 llvm_unreachable(
"Unknown type trait or not implemented");
1836 TSInfo =
Context.getTrivialTypeSourceInfo(T);
1844 assert(!T->isDependentType() &&
"Cannot evaluate traits of dependent type");
1848 if (T->isArrayType()) {
1850 while (
const ArrayType *AT =
Self.Context.getAsArrayType(T)) {
1852 T = AT->getElementType();
1858 case ATT_ArrayExtent: {
1861 if (
Self.VerifyIntegerConstantExpression(
1862 DimExpr, &
Value, diag::err_dimension_expr_not_constant_integer)
1865 if (
Value.isSigned() &&
Value.isNegative()) {
1866 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1872 if (T->isArrayType()) {
1874 bool Matched =
false;
1875 while (
const ArrayType *AT =
Self.Context.getAsArrayType(T)) {
1881 T = AT->getElementType();
1884 if (Matched && T->isArrayType()) {
1886 Self.Context.getAsConstantArrayType(T))
1887 return CAT->getLimitedSize();
1893 llvm_unreachable(
"Unknown type trait or not implemented");
1904 if (!T->isDependentType())
1913 RParen,
Context.getSizeType());
1929 case ET_IsLValueExpr:
1931 case ET_IsRValueExpr:
1934 llvm_unreachable(
"Expression trait not covered by switch");
1955 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
1956 .Case(
"is_trivially_relocatable",
1957 TypeTrait::UTT_IsCppTriviallyRelocatable)
1958 .Case(
"is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1959 .Case(
"is_assignable", TypeTrait::BTT_IsAssignable)
1960 .Case(
"is_empty", TypeTrait::UTT_IsEmpty)
1961 .Case(
"is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1962 .Case(
"is_aggregate", TypeTrait::UTT_IsAggregate)
1963 .Case(
"is_constructible", TypeTrait::TT_IsConstructible)
1964 .Case(
"is_final", TypeTrait::UTT_IsFinal)
1965 .Case(
"is_abstract", TypeTrait::UTT_IsAbstract)
1966 .Default(std::nullopt);
1970 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1978 std::optional<TypeTrait> Trait;
1981 if (
const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
1982 Trait = TraitExpr->getTrait();
1983 for (
const auto *Arg : TraitExpr->getArgs())
1984 Args.push_back(Arg->getType());
1985 return {{Trait.value(), std::move(Args)}};
1987 const auto *Ref = dyn_cast<DeclRefExpr>(E);
1989 return std::nullopt;
1992 if (
const auto *VD =
1993 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
1994 if (!VD->isInStdNamespace())
1995 return std::nullopt;
1996 StringRef Name = VD->getIdentifier()->getName();
1997 if (!Name.consume_back(
"_v"))
1998 return std::nullopt;
2001 return std::nullopt;
2002 for (
const auto &Arg : VD->getTemplateArgs().asArray()) {
2004 for (
const auto &InnerArg : Arg.pack_elements())
2005 Args.push_back(InnerArg.getAsType());
2007 Args.push_back(Arg.getAsType());
2009 llvm_unreachable(
"Unexpected kind");
2012 return {{Trait.value(), std::move(Args)}};
2016 if (
const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2017 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr(
"value")) {
2020 return std::nullopt;
2021 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
2023 return std::nullopt;
2024 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2026 return std::nullopt;
2029 return std::nullopt;
2030 for (
const auto &Arg : Ts->template_arguments())
2031 Args.push_back(Arg.getAsType());
2032 return {{Trait.value(), std::move(Args)}};
2034 return std::nullopt;
2042 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2043 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2057 const auto *
Decl = cast_or_null<CXXConstructorDecl>(
2059 if (
Decl &&
Decl->isUserProvided())
2060 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2061 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2067 if (
Decl &&
Decl->isUserProvided())
2068 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2069 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2073 Dtr = Dtr->getCanonicalDecl();
2074 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2075 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2076 << diag::TraitNotSatisfiedReason::DeletedDtr << 1
2077 << Dtr->getSourceRange();
2085 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2087 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2088 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2089 << B.getSourceRange();
2091 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2092 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2093 << B.getSourceRange();
2096 if (!Field->getType()->isReferenceType() &&
2098 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2099 << diag::TraitNotSatisfiedReason::NTRField << Field
2100 << Field->getType() << Field->getSourceRange();
2103 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2104 << diag::TraitNotSatisfiedReason::DeletedDtr << 0
2113 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2114 << T << diag::TraitName::TriviallyRelocatable;
2115 if (T->isVariablyModifiedType())
2116 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2117 << diag::TraitNotSatisfiedReason::VLA;
2119 if (T->isReferenceType())
2120 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2121 << diag::TraitNotSatisfiedReason::Ref;
2122 T = T.getNonReferenceType();
2124 if (T.hasNonTrivialObjCLifetime())
2125 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2126 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2142 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2144 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2145 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2146 << B.getSourceRange();
2147 if (!B.getType().isTriviallyCopyableType(D->
getASTContext())) {
2148 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2149 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2150 << B.getSourceRange();
2154 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2155 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2156 << diag::TraitNotSatisfiedReason::NTCField << Field
2157 << Field->getType() << Field->getSourceRange();
2161 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2162 << diag::TraitNotSatisfiedReason::DeletedDtr
2166 if (Method->isTrivial() || !Method->isUserProvided()) {
2169 auto SpecialMemberKind =
2171 switch (SpecialMemberKind) {
2183 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2184 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2185 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2186 << IsMove << Method->getSourceRange();
2202 bool ContainsVoid =
false;
2204 ContainsVoid |= ArgTy->isVoidType();
2208 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2209 << diag::TraitNotSatisfiedReason::CVVoidType;
2212 if (T->isFunctionType())
2213 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2214 << diag::TraitNotSatisfiedReason::FunctionType;
2216 if (T->isIncompleteArrayType())
2217 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2218 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2224 llvm::BumpPtrAllocator OpaqueExprAllocator;
2226 ArgExprs.reserve(Ts.size() - 1);
2227 for (
unsigned I = 1, N = Ts.size(); I != N; ++I) {
2245 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2251 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2252 << T << diag::TraitName::TriviallyCopyable;
2254 if (T->isReferenceType())
2255 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2256 << diag::TraitNotSatisfiedReason::Ref;
2273 if (Ty->isObjectType() || Ty->isFunctionType())
2275 return {Loc, Ty.getNonLValueExprType(SemaRef.
Context),
2279 auto LHS = createDeclValExpr(T);
2280 auto RHS = createDeclValExpr(
U);
2286 SemaRef.
BuildBinOp(
nullptr, Loc, BO_Assign, &LHS, &RHS);
2297 for (
const auto *Field : D->
fields()) {
2298 if (Field->isZeroLengthBitField())
2300 if (Field->isBitField()) {
2301 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2302 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2303 << Field->getSourceRange();
2306 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2307 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2308 << Field->getType() << Field->getSourceRange();
2312 for (
const auto *M : D->
methods()) {
2313 if (M->isVirtual()) {
2314 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2315 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2316 << M->getSourceRange();
2322 for (
const auto &B : D->
bases()) {
2323 const auto *BR = B.getType()->getAsCXXRecordDecl();
2324 if (!BR || BR->isInvalidDecl())
2326 if (B.isVirtual()) {
2327 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2328 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2329 << B.getSourceRange();
2331 if (!BR->isEmpty()) {
2332 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2333 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2334 << B.getSourceRange();
2341 S.
Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2346 if (T->isReferenceType())
2347 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2348 << diag::TraitNotSatisfiedReason::Ref;
2349 T = T.getNonReferenceType();
2352 T = AT->getElementType();
2354 if (
auto *D = T->getAsCXXRecordDecl()) {
2355 if (D->hasDefinition()) {
2357 S.
Diag(D->getLocation(), diag::note_defined_here) << D;
2369 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2370 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2378 S.
Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Final;
2379 if (T->isReferenceType()) {
2380 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2381 << diag::TraitNotSatisfiedReason::Ref;
2382 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2383 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2388 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2389 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2392 if (T->isFunctionType()) {
2393 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2394 << diag::TraitNotSatisfiedReason::FunctionType;
2395 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2396 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2399 if (!T->isRecordType()) {
2400 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2401 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2404 if (
const auto *D = T->getAsCXXRecordDecl())
2409 int NumBasesWithFields = 0;
2416 if (!Field->isUnnamedBitField()) {
2417 if (++NumBasesWithFields > 1)
2429 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2430 if (B.isVirtual()) {
2431 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2432 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2433 << B.getSourceRange();
2435 if (!B.getType()->isStandardLayoutType()) {
2436 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2437 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2438 << B.getSourceRange();
2446 if (Field->isUnnamedBitField())
2457 if (Field->getAccess() != FirstAccess) {
2459 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2460 << diag::TraitNotSatisfiedReason::MixedAccess;
2465 SemaRef.
Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2466 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2474 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2475 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2481 for (
const auto *M : D->
methods()) {
2482 if (M->isVirtual()) {
2488 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2489 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2490 SemaRef.
Diag(VirtualMD->getLocation(), diag::note_defined_here)
2494 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2495 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2496 SemaRef.
Diag(D->getLocation(), diag::note_defined_here) << D;
2500 if (!Field->getType()->isStandardLayoutType()) {
2501 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2502 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2503 << Field->getType() << Field->getSourceRange();
2517 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2518 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2526 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2527 << T << diag::TraitName::StandardLayout;
2530 if (T->isVariablyModifiedType()) {
2531 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2532 << diag::TraitNotSatisfiedReason::VLA;
2536 if (T->isReferenceType()) {
2537 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2538 << diag::TraitNotSatisfiedReason::Ref;
2541 T = T.getNonReferenceType();
2555 if (Ctor->isUserProvided())
2556 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2557 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2558 if (Ctor->isInheritingConstructor())
2559 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2560 << diag::TraitNotSatisfiedReason::InheritedCtr;
2563 if (llvm::any_of(D->
decls(), [](
auto const *Sub) {
2564 return isa<ConstructorUsingShadowDecl>(Sub);
2566 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2567 << diag::TraitNotSatisfiedReason::InheritedCtr;
2571 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2572 << diag::TraitNotSatisfiedReason::PolymorphicType
2576 if (B.isVirtual()) {
2577 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2578 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2579 << B.getSourceRange();
2586 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2587 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2596 if (Method->isVirtual()) {
2597 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2598 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2599 << Method->getSourceRange();
2608 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2609 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2622 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2623 << T << diag::TraitName::Aggregate;
2625 if (T->isVoidType())
2626 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2627 << diag::TraitNotSatisfiedReason::CVVoidType;
2629 T = T.getNonReferenceType();
2643 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2644 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2645 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2646 << B.getType() << B.getSourceRange();
2653 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2654 << T << diag::TraitName::Abstract;
2656 if (T->isReferenceType()) {
2657 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2658 << diag::TraitNotSatisfiedReason::Ref;
2659 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2660 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2664 if (T->isUnionType()) {
2665 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2666 << diag::TraitNotSatisfiedReason::UnionType;
2667 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2668 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2673 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2674 << diag::TraitNotSatisfiedReason::ArrayType;
2675 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2676 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2680 if (T->isFunctionType()) {
2681 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2682 << diag::TraitNotSatisfiedReason::FunctionType;
2683 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2684 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2688 if (T->isPointerType()) {
2689 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2690 << diag::TraitNotSatisfiedReason::PointerType;
2691 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2692 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2696 if (!T->isStructureOrClassType()) {
2697 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2698 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2716 const auto &[Trait, Args] = TraitInfo.value();
2718 case UTT_IsCppTriviallyRelocatable:
2721 case UTT_IsTriviallyCopyable:
2724 case BTT_IsAssignable:
2730 case UTT_IsStandardLayout:
2733 case TT_IsConstructible:
2736 case UTT_IsAggregate:
2748 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...