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:
380 case UTT_IsUnboundedArray:
384 case UTT_IsInterfaceClass:
388 case UTT_StructuredBindingSize:
394 case UTT_IsPolymorphic:
399 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
408 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
412 case UTT_IsAggregate:
413 case UTT_IsImplicitLifetime:
418 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
422 case UTT_HasUniqueObjectRepresentations:
427 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
432 case UTT_IsTriviallyCopyable:
433 case UTT_IsStandardLayout:
436 case UTT_IsBitwiseCloneable:
439 case UTT_IsTriviallyRelocatable:
440 case UTT_IsTriviallyEqualityComparable:
441 case UTT_IsCppTriviallyRelocatable:
442 case UTT_CanPassInRegs:
446 case UTT_HasNothrowAssign:
447 case UTT_HasNothrowMoveAssign:
448 case UTT_HasNothrowConstructor:
449 case UTT_HasNothrowCopy:
450 case UTT_HasTrivialAssign:
451 case UTT_HasTrivialMoveAssign:
452 case UTT_HasTrivialDefaultConstructor:
453 case UTT_HasTrivialMoveConstructor:
454 case UTT_HasTrivialCopy:
455 case UTT_HasTrivialDestructor:
456 case UTT_HasVirtualDestructor:
461 case UTT_IsDestructible:
462 case UTT_IsNothrowDestructible:
463 case UTT_IsTriviallyDestructible:
464 case UTT_IsIntangibleType:
469 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
478 if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
484 if (
Self.LookupQualifiedName(Res, RD)) {
485 bool FoundOperator =
false;
493 if ((Operator->*IsDesiredOp)()) {
494 FoundOperator =
true;
496 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
501 return FoundOperator;
511 if (
Decl->isLambda())
512 return Decl->isCapturelessLambda();
528 Functions, &Operand, &Operand);
532 const auto *
CallExpr = dyn_cast<CXXOperatorCallExpr>(Result.get());
536 auto ParamT = Callee->getParamDecl(0)->getType();
537 if (!Callee->isDefaulted())
539 if (!ParamT->isReferenceType() && !
Decl->isTriviallyCopyable())
545 return llvm::all_of(
Decl->bases(),
547 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
548 return HasNonDeletedDefaultedEqualityComparison(
553 auto Type = FD->getType();
554 if (Type->isArrayType())
555 Type = Type->getBaseElementTypeUnsafe()
556 ->getCanonicalTypeUnqualified();
558 if (Type->isReferenceType() || Type->isEnumeralType())
560 if (const auto *RD = Type->getAsCXXRecordDecl())
561 return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
579 CanonicalType,
false);
606 switch (
T.isNonTrivialToPrimitiveDestructiveMove()) {
608 return !
T.isDestructedType();
620 assert(!
T->isDependentType() &&
"Cannot evaluate traits of dependent type");
625 llvm_unreachable(
"not a UTT");
629 return T->isVoidType();
631 return T->isIntegralType(
C);
632 case UTT_IsFloatingPoint:
633 return T->isFloatingType();
637 if (
const auto *CAT =
C.getAsConstantArrayType(
T))
638 return CAT->getSize() != 0;
639 return T->isArrayType();
640 case UTT_IsBoundedArray:
645 if (
const auto *CAT =
C.getAsConstantArrayType(
T))
646 return CAT->getSize() != 0;
647 return T->isArrayType() && !
T->isIncompleteArrayType();
648 case UTT_IsUnboundedArray:
651 return T->isIncompleteArrayType();
653 return T->isAnyPointerType();
654 case UTT_IsLvalueReference:
655 return T->isLValueReferenceType();
656 case UTT_IsRvalueReference:
657 return T->isRValueReferenceType();
658 case UTT_IsMemberFunctionPointer:
659 return T->isMemberFunctionPointerType();
660 case UTT_IsMemberObjectPointer:
661 return T->isMemberDataPointerType();
663 return T->isEnumeralType();
664 case UTT_IsScopedEnum:
665 return T->isScopedEnumeralType();
667 return T->isUnionType();
669 return T->isClassType() ||
T->isStructureType() ||
T->isInterfaceType();
671 return T->isFunctionType();
675 case UTT_IsReference:
676 return T->isReferenceType();
677 case UTT_IsArithmetic:
678 return T->isArithmeticType() && !
T->isEnumeralType();
679 case UTT_IsFundamental:
680 return T->isFundamentalType();
682 return T->isObjectType();
688 if (
T->isObjCLifetimeType()) {
689 switch (
T.getObjCLifetime()) {
701 return T->isScalarType();
703 return T->isCompoundType();
704 case UTT_IsMemberPointer:
705 return T->isMemberPointerType();
710 return T.isConstQualified();
712 return T.isVolatileQualified();
714 return T.isTrivialType(
C);
715 case UTT_IsTriviallyCopyable:
716 return T.isTriviallyCopyableType(
C);
717 case UTT_IsStandardLayout:
718 return T->isStandardLayoutType();
720 return T.isPODType(
C);
722 return T->isLiteralType(
C);
727 case UTT_IsPolymorphic:
735 case UTT_IsAggregate:
739 return T->isAggregateType() ||
T->isVectorType() ||
T->isExtVectorType() ||
740 T->isAnyComplexType();
744 case UTT_IsInterfaceClass:
749 return RD->
hasAttr<FinalAttr>();
754 return T->isFloatingType() ||
755 (
T->isSignedIntegerType() && !
T->isEnumeralType());
758 return T->isUnsignedIntegerType() && !
T->isEnumeralType();
776 case UTT_HasTrivialDefaultConstructor:
787 case UTT_HasTrivialMoveConstructor:
797 case UTT_HasTrivialCopy:
803 if (
T.isPODType(
C) ||
T->isReferenceType())
809 case UTT_HasTrivialMoveAssign:
819 case UTT_HasTrivialAssign:
832 if (
T.isConstQualified())
840 case UTT_IsDestructible:
841 case UTT_IsTriviallyDestructible:
842 case UTT_IsNothrowDestructible:
845 if (
T->isReferenceType())
849 if (
T->isObjCLifetimeType() &&
856 if (
T->isIncompleteType() ||
T->isFunctionType())
861 if (UTT == UTT_IsTriviallyDestructible &&
T.isDestructedType())
868 if (
auto *RD =
C.getBaseElementType(
T)->getAsCXXRecordDecl()) {
879 if (UTT == UTT_IsNothrowDestructible) {
881 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
888 case UTT_HasTrivialDestructor:
895 if (
T.isPODType(
C) ||
T->isReferenceType())
899 if (
T->isObjCLifetimeType() &&
907 case UTT_HasNothrowAssign:
915 if (
C.getBaseElementType(
T).isConstQualified())
917 if (
T->isReferenceType())
919 if (
T.isPODType(
C) ||
T->isObjCLifetimeType())
922 if (
auto *RD =
T->getAsCXXRecordDecl())
928 case UTT_HasNothrowMoveAssign:
935 if (
auto *RD =
C.getBaseElementType(
T)->getAsCXXRecordDecl())
941 case UTT_HasNothrowCopy:
947 if (
T.isPODType(
C) ||
T->isReferenceType() ||
T->isObjCLifetimeType())
954 bool FoundConstructor =
false;
956 for (
const auto *ND :
Self.LookupConstructors(RD)) {
967 FoundConstructor =
true;
969 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
979 return FoundConstructor;
982 case UTT_HasNothrowConstructor:
988 if (
T.isPODType(
C) ||
T->isObjCLifetimeType())
990 if (
CXXRecordDecl *RD =
C.getBaseElementType(
T)->getAsCXXRecordDecl()) {
994 bool FoundConstructor =
false;
995 for (
const auto *ND :
Self.LookupConstructors(RD)) {
1004 FoundConstructor =
true;
1006 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
1015 return FoundConstructor;
1018 case UTT_HasVirtualDestructor:
1030 case UTT_IsCompleteType:
1034 return !
T->isIncompleteType();
1035 case UTT_HasUniqueObjectRepresentations:
1036 return C.hasUniqueObjectRepresentations(
T);
1037 case UTT_IsTriviallyRelocatable:
1039 case UTT_IsBitwiseCloneable:
1040 return T.isBitwiseCloneableType(
C);
1041 case UTT_IsCppTriviallyRelocatable:
1042 return Self.IsCXXTriviallyRelocatableType(
T);
1043 case UTT_CanPassInRegs:
1044 if (
CXXRecordDecl *RD =
T->getAsCXXRecordDecl(); RD && !
T.hasQualifiers())
1046 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) <<
T;
1048 case UTT_IsTriviallyEqualityComparable:
1050 case UTT_IsImplicitLifetime: {
1052 tok::kw___builtin_is_implicit_lifetime);
1054 tok::kw___builtin_is_implicit_lifetime);
1060 QualType UnqualT =
T->getCanonicalTypeUnqualified();
1077 bool HasTrivialNonDeletedDtr =
1079 if (!HasTrivialNonDeletedDtr)
1082 if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
1084 if (Ctr->isTrivial())
1099 case UTT_IsIntangibleType:
1100 assert(
Self.getLangOpts().HLSL &&
"intangible types are HLSL-only feature");
1101 if (!
T->isVoidType() && !
T->isIncompleteArrayType())
1103 diag::err_incomplete_type))
1106 tok::kw___builtin_hlsl_is_intangible))
1108 return T->isHLSLIntangibleType();
1110 case UTT_IsTypedResourceElementCompatible:
1111 assert(
Self.getLangOpts().HLSL &&
1112 "typed resource element compatible types are an HLSL-only feature");
1113 if (
T->isIncompleteType())
1116 return Self.HLSL().IsTypedResourceElementCompatible(
T);
1127 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1168 LhsT =
Self.Context.getRValueReferenceType(LhsT);
1204 case TypeTrait::UTT_StructuredBindingSize: {
1206 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1210 S.
Diag(KWLoc, diag::err_arg_is_not_destructurable) <<
T << ArgRange;
1218 llvm_unreachable(
"Not a SizeT type trait");
1235 if (Kind <=
BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1236 Kind != BTT_ReferenceConstructsFromTemporary &&
1237 Kind != BTT_ReferenceConvertsFromTemporary)
1241 case clang::BTT_ReferenceBindsToTemporary:
1242 case clang::BTT_ReferenceConstructsFromTemporary:
1243 case clang::BTT_ReferenceConvertsFromTemporary:
1244 case clang::TT_IsConstructible:
1245 case clang::TT_IsNothrowConstructible:
1246 case clang::TT_IsTriviallyConstructible: {
1260 assert(!Args.empty());
1265 for (
const auto *TSI : Args) {
1271 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1277 if (
T->isIncompleteType() ||
T->isFunctionType())
1288 bool UseRawObjectType =
1289 Kind == clang::BTT_ReferenceBindsToTemporary ||
1290 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1291 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1293 llvm::BumpPtrAllocator OpaqueExprAllocator;
1295 ArgExprs.reserve(Args.size() - 1);
1296 for (
unsigned I = 1, N = Args.size(); I != N; ++I) {
1297 QualType ArgTy = Args[I]->getType();
1317 Kind == clang::BTT_ReferenceConvertsFromTemporary
1328 if (Kind == clang::TT_IsConstructible)
1331 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1332 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1333 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1334 if (!
T->isReferenceType())
1338 if (
T.getNonReferenceType()->isFunctionType())
1341 if (!
Init.isDirectReferenceBinding())
1344 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1348 if (
U->isReferenceType())
1356 OpaqueExprAllocator)
1360 if (Kind == clang::TT_IsNothrowConstructible)
1363 if (Kind == clang::TT_IsTriviallyConstructible) {
1366 if (
T.getNonReferenceType().hasNonTrivialObjCLifetime())
1371 return !Result.get()->hasNonTrivialCall(S.
Context);
1374 llvm_unreachable(
"unhandled type trait");
1378 llvm_unreachable(
"not a TT");
1388 case UTT_HasNothrowAssign:
1389 case UTT_HasNothrowMoveAssign:
1390 Replacement = BTT_IsNothrowAssignable;
1392 case UTT_HasNothrowCopy:
1393 case UTT_HasNothrowConstructor:
1394 Replacement = TT_IsNothrowConstructible;
1396 case UTT_HasTrivialAssign:
1397 case UTT_HasTrivialMoveAssign:
1398 Replacement = BTT_IsTriviallyAssignable;
1400 case UTT_HasTrivialCopy:
1401 Replacement = UTT_IsTriviallyCopyable;
1403 case UTT_HasTrivialDefaultConstructor:
1404 case UTT_HasTrivialMoveConstructor:
1405 Replacement = TT_IsTriviallyConstructible;
1407 case UTT_HasTrivialDestructor:
1408 Replacement = UTT_IsTriviallyDestructible;
1410 case UTT_IsTriviallyRelocatable:
1411 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1413 case BTT_ReferenceBindsToTemporary:
1414 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1419 S.
Diag(KWLoc, diag::warn_deprecated_builtin)
1425 if (Arity && N != Arity) {
1426 Diag(Loc, diag::err_type_trait_arity)
1427 << Arity << 0 << (Arity > 1) << (
int)N <<
SourceRange(Loc);
1431 if (!Arity && N == 0) {
1432 Diag(Loc, diag::err_type_trait_arity)
1445 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1457 *
this, Kind, KWLoc, Args[0]->
getType()))
1460 DiagnoseBuiltinDeprecation(*
this, Kind, KWLoc);
1463 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1464 if (Args[I]->
getType()->isDependentType()) {
1475 KWLoc, Kind, Args, RParenLoc,
Result);
1481 Args, RParenLoc,
Result);
1484 llvm_unreachable(
"unhandled type trait return type");
1491 ConvertedArgs.reserve(Args.size());
1493 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1497 TInfo =
Context.getTrivialTypeSourceInfo(
T, KWLoc);
1499 ConvertedArgs.push_back(TInfo);
1512 const RecordType *lhsRecord = LhsT->
getAsCanonical<RecordType>();
1513 const RecordType *rhsRecord = RhsT->
getAsCanonical<RecordType>();
1514 if (!rhsRecord || !lhsRecord) {
1517 if (!LHSObjTy || !RHSObjTy)
1522 if (!BaseInterface || !DerivedInterface)
1526 diag::err_incomplete_type_used_in_type_trait_expr))
1532 assert(
Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1533 (lhsRecord == rhsRecord));
1537 if (lhsRecord && lhsRecord->getDecl()->isUnion())
1539 if (rhsRecord && rhsRecord->getDecl()->isUnion())
1542 if (lhsRecord == rhsRecord)
1550 diag::err_incomplete_type_used_in_type_trait_expr))
1565 "Cannot evaluate traits of dependent types");
1571 case BTT_IsVirtualBaseOf: {
1572 const RecordType *BaseRecord = LhsT->
getAsCanonical<RecordType>();
1573 const RecordType *DerivedRecord = RhsT->
getAsCanonical<RecordType>();
1575 if (!BaseRecord || !DerivedRecord) {
1577 tok::kw___builtin_is_virtual_base_of);
1579 tok::kw___builtin_is_virtual_base_of);
1583 if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1586 if (!BaseRecord->isStructureOrClassType() ||
1587 !DerivedRecord->isStructureOrClassType())
1591 diag::err_incomplete_type))
1598 return Self.Context.hasSameType(LhsT, RhsT);
1599 case BTT_TypeCompatible: {
1602 QualType Lhs =
Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1603 QualType Rhs =
Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1604 return Self.Context.typesAreCompatible(Lhs, Rhs);
1606 case BTT_IsConvertible:
1607 case BTT_IsConvertibleTo:
1608 case BTT_IsNothrowConvertible: {
1611 llvm::BumpPtrAllocator OpaqueExprAllocator;
1613 OpaqueExprAllocator);
1614 if (Result.isInvalid())
1617 if (BTT != BTT_IsNothrowConvertible)
1623 case BTT_IsAssignable:
1624 case BTT_IsNothrowAssignable:
1625 case BTT_IsTriviallyAssignable: {
1638 Self.RequireCompleteType(
1640 diag::err_incomplete_type_used_in_type_trait_expr))
1643 Self.RequireCompleteType(
1645 diag::err_incomplete_type_used_in_type_trait_expr))
1655 if (Ty->isObjectType() || Ty->isFunctionType())
1656 Ty =
Self.Context.getRValueReferenceType(Ty);
1657 return {KeyLoc, Ty.getNonLValueExprType(
Self.Context),
1661 auto Lhs = createDeclValExpr(LhsT);
1662 auto Rhs = createDeclValExpr(RhsT);
1671 Self.BuildBinOp(
nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1672 if (Result.isInvalid())
1676 Self.CheckUnusedVolatileAssignment(Result.get());
1681 if (BTT == BTT_IsAssignable)
1684 if (BTT == BTT_IsNothrowAssignable)
1687 if (BTT == BTT_IsTriviallyAssignable) {
1693 if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1694 Context.containsAddressDiscriminatedPointerAuth(RhsT))
1696 return !Result.get()->hasNonTrivialCall(
Self.Context);
1699 llvm_unreachable(
"unhandled type trait");
1702 case BTT_IsLayoutCompatible: {
1705 diag::err_incomplete_type);
1708 diag::err_incomplete_type);
1713 return Self.IsLayoutCompatible(LhsT, RhsT);
1715 case BTT_IsPointerInterconvertibleBaseOf: {
1717 !
Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1719 diag::err_incomplete_type);
1723 tok::kw___is_pointer_interconvertible_base_of);
1725 tok::kw___is_pointer_interconvertible_base_of);
1727 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1729 case BTT_IsDeducible: {
1732 return Self.DeduceTemplateArgumentsFromType(
1733 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1736 case BTT_IsScalarizedLayoutCompatible: {
1739 diag::err_incomplete_type))
1743 diag::err_incomplete_type))
1747 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1749 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1751 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1753 case BTT_LtSynthesizesFromSpaceship:
1754 case BTT_LeSynthesizesFromSpaceship:
1755 case BTT_GtSynthesizesFromSpaceship:
1756 case BTT_GeSynthesizesFromSpaceship: {
1775 case BTT_LtSynthesizesFromSpaceship:
1776 return BinaryOperatorKind::BO_LT;
1777 case BTT_LeSynthesizesFromSpaceship:
1778 return BinaryOperatorKind::BO_LE;
1779 case BTT_GtSynthesizesFromSpaceship:
1780 return BinaryOperatorKind::BO_GT;
1781 case BTT_GeSynthesizesFromSpaceship:
1782 return BinaryOperatorKind::BO_GE;
1784 llvm_unreachable(
"Trying to Synthesize non-comparison operator?");
1789 Self.LookupBinOp(
Self.TUScope, KeyLoc, OpKind, Functions);
1792 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1799 llvm_unreachable(
"not a BTT");
1801 llvm_unreachable(
"Unknown type trait or not implemented");
1810 TSInfo =
Context.getTrivialTypeSourceInfo(
T);
1818 assert(!
T->isDependentType() &&
"Cannot evaluate traits of dependent type");
1822 if (
T->isArrayType()) {
1826 T = AT->getElementType();
1832 case ATT_ArrayExtent: {
1835 if (
Self.VerifyIntegerConstantExpression(
1836 DimExpr, &
Value, diag::err_dimension_expr_not_constant_integer)
1839 if (
Value.isSigned() &&
Value.isNegative()) {
1840 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1846 if (
T->isArrayType()) {
1848 bool Matched =
false;
1855 T = AT->getElementType();
1858 if (Matched &&
T->isArrayType()) {
1860 Self.Context.getAsConstantArrayType(
T))
1861 return CAT->getLimitedSize();
1867 llvm_unreachable(
"Unknown type trait or not implemented");
1878 if (!
T->isDependentType())
1887 RParen,
Context.getSizeType());
1903 case ET_IsLValueExpr:
1905 case ET_IsRValueExpr:
1908 llvm_unreachable(
"Expression trait not covered by switch");
1929 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
1930 .Case(
"is_trivially_relocatable",
1931 TypeTrait::UTT_IsCppTriviallyRelocatable)
1932 .Case(
"is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1933 .Case(
"is_assignable", TypeTrait::BTT_IsAssignable)
1934 .Case(
"is_empty", TypeTrait::UTT_IsEmpty)
1935 .Case(
"is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1936 .Case(
"is_aggregate", TypeTrait::UTT_IsAggregate)
1937 .Case(
"is_constructible", TypeTrait::TT_IsConstructible)
1938 .Case(
"is_final", TypeTrait::UTT_IsFinal)
1939 .Case(
"is_abstract", TypeTrait::UTT_IsAbstract)
1940 .Default(std::nullopt);
1944 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1952 std::optional<TypeTrait> Trait;
1955 if (
const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
1956 Trait = TraitExpr->getTrait();
1957 for (
const auto *Arg : TraitExpr->getArgs())
1958 Args.push_back(Arg->getType());
1959 return {{Trait.value(), std::move(Args)}};
1961 const auto *Ref = dyn_cast<DeclRefExpr>(E);
1963 return std::nullopt;
1966 if (
const auto *VD =
1967 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
1968 if (!VD->isInStdNamespace())
1969 return std::nullopt;
1970 StringRef Name = VD->getIdentifier()->getName();
1971 if (!Name.consume_back(
"_v"))
1972 return std::nullopt;
1975 return std::nullopt;
1976 for (
const auto &Arg : VD->getTemplateArgs().asArray()) {
1978 for (
const auto &InnerArg : Arg.pack_elements())
1979 Args.push_back(InnerArg.getAsType());
1981 Args.push_back(Arg.getAsType());
1983 llvm_unreachable(
"Unexpected kind");
1986 return {{Trait.value(), std::move(Args)}};
1990 if (
const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
1991 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr(
"value")) {
1994 return std::nullopt;
1995 const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
1997 return std::nullopt;
1998 const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2000 return std::nullopt;
2003 return std::nullopt;
2004 for (
const auto &Arg : Ts->template_arguments())
2005 Args.push_back(Arg.getAsType());
2006 return {{Trait.value(), std::move(Args)}};
2008 return std::nullopt;
2016 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2017 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2031 const auto *
Decl = cast_or_null<CXXConstructorDecl>(
2033 if (
Decl &&
Decl->isUserProvided())
2034 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2035 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2041 if (
Decl &&
Decl->isUserProvided())
2042 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2043 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2047 Dtr = Dtr->getCanonicalDecl();
2048 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2049 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2050 << diag::TraitNotSatisfiedReason::DeletedDtr << 1
2051 << Dtr->getSourceRange();
2059 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2061 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2062 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2063 << B.getSourceRange();
2065 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2066 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2067 << B.getSourceRange();
2070 if (!Field->getType()->isReferenceType() &&
2072 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2073 << diag::TraitNotSatisfiedReason::NTRField << Field
2074 << Field->getType() << Field->getSourceRange();
2077 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2078 << diag::TraitNotSatisfiedReason::DeletedDtr << 0
2087 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2088 <<
T << diag::TraitName::TriviallyRelocatable;
2089 if (
T->isVariablyModifiedType())
2090 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2091 << diag::TraitNotSatisfiedReason::VLA;
2093 if (
T->isReferenceType())
2094 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2095 << diag::TraitNotSatisfiedReason::Ref;
2096 T =
T.getNonReferenceType();
2098 if (
T.hasNonTrivialObjCLifetime())
2099 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2100 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2116 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2118 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2119 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2120 << B.getSourceRange();
2121 if (!B.getType().isTriviallyCopyableType(D->
getASTContext())) {
2122 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2123 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2124 << B.getSourceRange();
2128 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2129 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2130 << diag::TraitNotSatisfiedReason::NTCField << Field
2131 << Field->getType() << Field->getSourceRange();
2135 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2136 << diag::TraitNotSatisfiedReason::DeletedDtr
2140 if (Method->isTrivial() || !Method->isUserProvided()) {
2143 auto SpecialMemberKind =
2145 switch (SpecialMemberKind) {
2157 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2158 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2159 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2160 << IsMove << Method->getSourceRange();
2176 bool ContainsVoid =
false;
2178 ContainsVoid |= ArgTy->isVoidType();
2182 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2183 << diag::TraitNotSatisfiedReason::CVVoidType;
2186 if (
T->isFunctionType())
2187 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2188 << diag::TraitNotSatisfiedReason::FunctionType;
2190 if (
T->isIncompleteArrayType())
2191 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2192 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2198 llvm::BumpPtrAllocator OpaqueExprAllocator;
2200 ArgExprs.reserve(Ts.size() - 1);
2201 for (
unsigned I = 1, N = Ts.size(); I != N; ++I) {
2219 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2225 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2226 <<
T << diag::TraitName::TriviallyCopyable;
2228 if (
T->isReferenceType())
2229 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2230 << diag::TraitNotSatisfiedReason::Ref;
2247 if (Ty->isObjectType() || Ty->isFunctionType())
2249 return {Loc, Ty.getNonLValueExprType(SemaRef.
Context),
2253 auto LHS = createDeclValExpr(
T);
2254 auto RHS = createDeclValExpr(
U);
2260 SemaRef.
BuildBinOp(
nullptr, Loc, BO_Assign, &LHS, &RHS);
2271 for (
const auto *Field : D->
fields()) {
2272 if (Field->isZeroLengthBitField())
2274 if (Field->isBitField()) {
2275 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2276 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2277 << Field->getSourceRange();
2280 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2281 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2282 << Field->getType() << Field->getSourceRange();
2286 for (
const auto *M : D->
methods()) {
2287 if (M->isVirtual()) {
2288 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2289 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2290 << M->getSourceRange();
2296 for (
const auto &B : D->
bases()) {
2297 const auto *BR = B.getType()->getAsCXXRecordDecl();
2298 if (!BR || BR->isInvalidDecl())
2300 if (B.isVirtual()) {
2301 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2302 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2303 << B.getSourceRange();
2305 if (!BR->isEmpty()) {
2306 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2307 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2308 << B.getSourceRange();
2315 S.
Diag(Loc, diag::note_unsatisfied_trait) <<
T << diag::TraitName::Empty;
2320 if (
T->isReferenceType())
2321 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2322 << diag::TraitNotSatisfiedReason::Ref;
2323 T =
T.getNonReferenceType();
2326 T = AT->getElementType();
2328 if (
auto *D =
T->getAsCXXRecordDecl()) {
2329 if (D->hasDefinition()) {
2331 S.
Diag(D->getLocation(), diag::note_defined_here) << D;
2343 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2344 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2352 S.
Diag(Loc, diag::note_unsatisfied_trait) <<
T << diag::TraitName::Final;
2353 if (
T->isReferenceType()) {
2354 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2355 << diag::TraitNotSatisfiedReason::Ref;
2356 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2357 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2362 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2363 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2366 if (
T->isFunctionType()) {
2367 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2368 << diag::TraitNotSatisfiedReason::FunctionType;
2369 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2370 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2373 if (!
T->isRecordType()) {
2374 S.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2375 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2378 if (
const auto *D =
T->getAsCXXRecordDecl())
2383 int NumBasesWithFields = 0;
2390 if (!Field->isUnnamedBitField()) {
2391 if (++NumBasesWithFields > 1)
2403 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2404 if (B.isVirtual()) {
2405 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2406 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2407 << B.getSourceRange();
2409 if (!B.getType()->isStandardLayoutType()) {
2410 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2411 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2412 << B.getSourceRange();
2420 if (Field->isUnnamedBitField())
2431 if (Field->getAccess() != FirstAccess) {
2433 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2434 << diag::TraitNotSatisfiedReason::MixedAccess;
2439 SemaRef.
Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2440 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2448 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2449 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2455 for (
const auto *M : D->
methods()) {
2456 if (M->isVirtual()) {
2462 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2463 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2464 SemaRef.
Diag(VirtualMD->getLocation(), diag::note_defined_here)
2468 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2469 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2470 SemaRef.
Diag(D->getLocation(), diag::note_defined_here) << D;
2474 if (!Field->getType()->isStandardLayoutType()) {
2475 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2476 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2477 << Field->getType() << Field->getSourceRange();
2491 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2492 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2500 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2501 <<
T << diag::TraitName::StandardLayout;
2504 if (
T->isVariablyModifiedType()) {
2505 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2506 << diag::TraitNotSatisfiedReason::VLA;
2510 if (
T->isReferenceType()) {
2511 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2512 << diag::TraitNotSatisfiedReason::Ref;
2515 T =
T.getNonReferenceType();
2529 if (Ctor->isUserProvided())
2530 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2531 << diag::TraitNotSatisfiedReason::UserDeclaredCtr;
2532 if (Ctor->isInheritingConstructor())
2533 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2534 << diag::TraitNotSatisfiedReason::InheritedCtr;
2537 if (llvm::any_of(D->
decls(), [](
auto const *Sub) {
2538 return isa<ConstructorUsingShadowDecl>(Sub);
2540 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2541 << diag::TraitNotSatisfiedReason::InheritedCtr;
2545 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2546 << diag::TraitNotSatisfiedReason::PolymorphicType
2550 if (B.isVirtual()) {
2551 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2552 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2553 << B.getSourceRange();
2560 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2561 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectBase
2570 if (Method->isVirtual()) {
2571 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2572 << diag::TraitNotSatisfiedReason::VirtualFunction << Method
2573 << Method->getSourceRange();
2582 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2583 << diag::TraitNotSatisfiedReason::PrivateProtectedDirectDataMember
2596 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2597 <<
T << diag::TraitName::Aggregate;
2599 if (
T->isVoidType())
2600 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2601 << diag::TraitNotSatisfiedReason::CVVoidType;
2603 T =
T.getNonReferenceType();
2617 if (B.getType()->castAsCXXRecordDecl()->isAbstract()) {
2618 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2619 << diag::TraitNotSatisfiedReason::OverridesAllPureVirtual
2620 << B.getType() << B.getSourceRange();
2627 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait)
2628 <<
T << diag::TraitName::Abstract;
2630 if (
T->isReferenceType()) {
2631 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2632 << diag::TraitNotSatisfiedReason::Ref;
2633 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2634 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2638 if (
T->isUnionType()) {
2639 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2640 << diag::TraitNotSatisfiedReason::UnionType;
2641 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2642 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2647 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2648 << diag::TraitNotSatisfiedReason::ArrayType;
2649 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2650 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2654 if (
T->isFunctionType()) {
2655 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2656 << diag::TraitNotSatisfiedReason::FunctionType;
2657 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2658 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2662 if (
T->isPointerType()) {
2663 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2664 << diag::TraitNotSatisfiedReason::PointerType;
2665 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2666 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2670 if (!
T->isStructureOrClassType()) {
2671 SemaRef.
Diag(Loc, diag::note_unsatisfied_trait_reason)
2672 << diag::TraitNotSatisfiedReason::NotStructOrClass;
2690 const auto &[Trait, Args] = TraitInfo.value();
2692 case UTT_IsCppTriviallyRelocatable:
2695 case UTT_IsTriviallyCopyable:
2698 case BTT_IsAssignable:
2704 case UTT_IsStandardLayout:
2707 case TT_IsConstructible:
2710 case UTT_IsAggregate:
2722 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.
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 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 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
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
@ Pack
The template argument is actually a parameter pack.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
static TypeTraitExpr * Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc, bool Value)
Create a new type trait expression.
The base class of the type hierarchy.
bool isIncompleteArrayType() const
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
const T * castAs() const
Member-template castAs<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.
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
@ Result
The result type of a method or function.
const FunctionProtoType * T
CXXSpecialMemberKind
Kinds of C++ special members.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
const char * getTraitSpelling(ExpressionTrait T) LLVM_READONLY
Return the spelling of the type trait TT. Never null.
@ Success
Template argument deduction was successful.
U cast(CodeGen::Address addr)
ConstructorInfo getConstructorInfo(NamedDecl *ND)
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ActionResult< Expr * > ExprResult
TypeTrait
Names for traits that operate specifically on types.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...