74 if (CandDecl->isInvalidDecl())
82 ThisTy, Classification,
99 CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl,
nullptr,
109 return cast<CXXMethodDecl>(Best->Function)->getCanonicalDecl();
117 bool AllowUserDefined) {
120 if (
D->hasSimpleMoveConstructor() ||
D->hasSimpleCopyConstructor())
125 return Decl && (AllowUserDefined || !
Decl->isUserProvided()) &&
133 if (
D->hasSimpleMoveAssignment() ||
D->hasSimpleCopyAssignment())
141 return Decl && (AllowUserDefined || !
Decl->isUserProvided()) &&
182 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
187 if (B.isVirtual() || (!BaseDecl->isDependentType() &&
192 bool IsUnion =
D->isUnion();
194 if (Field->getType()->isDependentType())
196 if (Field->getType()->isReferenceType())
209 return !
D->hasDeletedDestructor();
217 const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
221 if (!BaseDecl->isDependentType() &&
227 if (Field->getType()->isDependentType())
234 return !
D->hasDeletedDestructor();
244 assert(
D->hasDefinition());
248 auto HasSuitableSMP = [&] {
255 auto IsUnion = [&, Is = std::optional<bool>{}]()
mutable {
257 Is =
D->isUnion() && !
D->hasUserDeclaredCopyConstructor() &&
258 !
D->hasUserDeclaredCopyAssignment() &&
259 !
D->hasUserDeclaredMoveOperation() &&
260 !
D->hasUserDeclaredDestructor();
270 Info.IsRelocatable = [&] {
271 if (
D->isDependentType())
279 if (
D->
hasAttr<TriviallyRelocatableAttr>())
290 Info.IsReplaceable = [&] {
291 if (
D->isDependentType())
300 return HasSuitableSMP();
304 return HasSuitableSMP();
314 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
316 return Info->IsRelocatable;
348 if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
350 return Info->IsReplaceable;
358 if (
Type.isConstQualified() ||
Type.isVolatileQualified())
371 return ::IsCXXReplaceableType(*
this, RD);
384 S.
Diag(
T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
398 S.
Diag(
T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)
423 llvm_unreachable(
"not a UTT");
425 case UTT_IsCompleteType:
434 case UTT_IsFloatingPoint:
436 case UTT_IsBoundedArray:
438 case UTT_IsLvalueReference:
439 case UTT_IsRvalueReference:
440 case UTT_IsMemberFunctionPointer:
441 case UTT_IsMemberObjectPointer:
443 case UTT_IsScopedEnum:
447 case UTT_IsReference:
448 case UTT_IsArithmetic:
449 case UTT_IsFundamental:
453 case UTT_IsMemberPointer:
454 case UTT_IsTypedResourceElementCompatible:
465 case UTT_IsUnboundedArray:
469 case UTT_IsInterfaceClass:
473 case UTT_StructuredBindingSize:
479 case UTT_IsPolymorphic:
484 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
493 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
497 case UTT_IsAggregate:
498 case UTT_IsImplicitLifetime:
503 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
507 case UTT_HasUniqueObjectRepresentations:
512 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
517 case UTT_IsTriviallyCopyable:
518 case UTT_IsStandardLayout:
521 case UTT_IsBitwiseCloneable:
524 case UTT_IsTriviallyRelocatable:
525 case UTT_IsTriviallyEqualityComparable:
526 case UTT_IsCppTriviallyRelocatable:
527 case UTT_IsReplaceable:
528 case UTT_CanPassInRegs:
532 case UTT_HasNothrowAssign:
533 case UTT_HasNothrowMoveAssign:
534 case UTT_HasNothrowConstructor:
535 case UTT_HasNothrowCopy:
536 case UTT_HasTrivialAssign:
537 case UTT_HasTrivialMoveAssign:
538 case UTT_HasTrivialDefaultConstructor:
539 case UTT_HasTrivialMoveConstructor:
540 case UTT_HasTrivialCopy:
541 case UTT_HasTrivialDestructor:
542 case UTT_HasVirtualDestructor:
547 case UTT_IsDestructible:
548 case UTT_IsNothrowDestructible:
549 case UTT_IsTriviallyDestructible:
550 case UTT_IsIntangibleType:
555 Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
564 if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
570 if (
Self.LookupQualifiedName(Res, RD)) {
571 bool FoundOperator =
false;
575 if (isa<FunctionTemplateDecl>(*Op))
579 if ((Operator->*IsDesiredOp)()) {
580 FoundOperator =
true;
582 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
587 return FoundOperator;
597 if (
Decl->isLambda())
598 return Decl->isCapturelessLambda();
614 Functions, &Operand, &Operand);
618 const auto *
CallExpr = dyn_cast<CXXOperatorCallExpr>(
Result.get());
622 auto ParamT = Callee->getParamDecl(0)->getType();
623 if (!Callee->isDefaulted())
625 if (!ParamT->isReferenceType() && !
Decl->isTriviallyCopyable())
631 return llvm::all_of(
Decl->bases(),
633 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
634 return HasNonDeletedDefaultedEqualityComparison(
639 auto Type = FD->getType();
640 if (Type->isArrayType())
641 Type = Type->getBaseElementTypeUnsafe()
642 ->getCanonicalTypeUnqualified();
644 if (Type->isReferenceType() || Type->isEnumeralType())
646 if (const auto *RD = Type->getAsCXXRecordDecl())
647 return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
665 CanonicalType,
false);
692 switch (
T.isNonTrivialToPrimitiveDestructiveMove()) {
694 return !
T.isDestructedType();
706 assert(!
T->
isDependentType() &&
"Cannot evaluate traits of dependent type");
711 llvm_unreachable(
"not a UTT");
718 case UTT_IsFloatingPoint:
723 if (
const auto *CAT =
C.getAsConstantArrayType(
T))
724 return CAT->getSize() != 0;
726 case UTT_IsBoundedArray:
731 if (
const auto *CAT =
C.getAsConstantArrayType(
T))
732 return CAT->getSize() != 0;
734 case UTT_IsUnboundedArray:
740 case UTT_IsLvalueReference:
742 case UTT_IsRvalueReference:
744 case UTT_IsMemberFunctionPointer:
746 case UTT_IsMemberObjectPointer:
750 case UTT_IsScopedEnum:
761 case UTT_IsReference:
763 case UTT_IsArithmetic:
765 case UTT_IsFundamental:
775 switch (
T.getObjCLifetime()) {
790 case UTT_IsMemberPointer:
796 return T.isConstQualified();
798 return T.isVolatileQualified();
800 return T.isTrivialType(
C);
801 case UTT_IsTriviallyCopyable:
802 return T.isTriviallyCopyableType(
C);
803 case UTT_IsStandardLayout:
806 return T.isPODType(
C);
813 case UTT_IsPolymorphic:
821 case UTT_IsAggregate:
830 case UTT_IsInterfaceClass:
835 return RD->
hasAttr<FinalAttr>();
862 case UTT_HasTrivialDefaultConstructor:
873 case UTT_HasTrivialMoveConstructor:
883 case UTT_HasTrivialCopy:
895 case UTT_HasTrivialMoveAssign:
905 case UTT_HasTrivialAssign:
918 if (
T.isConstQualified())
926 case UTT_IsDestructible:
927 case UTT_IsTriviallyDestructible:
928 case UTT_IsNothrowDestructible:
947 if (UTT == UTT_IsTriviallyDestructible &&
T.isDestructedType())
954 if (
auto *RD =
C.getBaseElementType(
T)->getAsCXXRecordDecl()) {
965 if (UTT == UTT_IsNothrowDestructible) {
967 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
974 case UTT_HasTrivialDestructor:
993 case UTT_HasNothrowAssign:
1001 if (
C.getBaseElementType(
T).isConstQualified())
1014 case UTT_HasNothrowMoveAssign:
1021 if (
auto *RD =
C.getBaseElementType(
T)->getAsCXXRecordDecl())
1027 case UTT_HasNothrowCopy:
1040 bool FoundConstructor =
false;
1042 for (
const auto *ND :
Self.LookupConstructors(RD)) {
1046 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1049 if (isa<UsingDecl>(ND))
1051 auto *
Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1053 FoundConstructor =
true;
1055 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
1065 return FoundConstructor;
1068 case UTT_HasNothrowConstructor:
1076 if (
CXXRecordDecl *RD =
C.getBaseElementType(
T)->getAsCXXRecordDecl()) {
1081 bool FoundConstructor =
false;
1082 for (
const auto *ND :
Self.LookupConstructors(RD)) {
1084 if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1087 if (isa<UsingDecl>(ND))
1089 auto *
Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1091 FoundConstructor =
true;
1093 CPT =
Self.ResolveExceptionSpec(KeyLoc, CPT);
1102 return FoundConstructor;
1105 case UTT_HasVirtualDestructor:
1117 case UTT_IsCompleteType:
1122 case UTT_HasUniqueObjectRepresentations:
1123 return C.hasUniqueObjectRepresentations(
T);
1124 case UTT_IsTriviallyRelocatable:
1126 case UTT_IsBitwiseCloneable:
1127 return T.isBitwiseCloneableType(
C);
1128 case UTT_IsCppTriviallyRelocatable:
1129 return Self.IsCXXTriviallyRelocatableType(
T);
1130 case UTT_IsReplaceable:
1131 return Self.IsCXXReplaceableType(
T);
1132 case UTT_CanPassInRegs:
1135 Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) <<
T;
1137 case UTT_IsTriviallyEqualityComparable:
1139 case UTT_IsImplicitLifetime: {
1141 tok::kw___builtin_is_implicit_lifetime);
1143 tok::kw___builtin_is_implicit_lifetime);
1173 case UTT_IsIntangibleType:
1174 assert(
Self.getLangOpts().HLSL &&
"intangible types are HLSL-only feature");
1177 diag::err_incomplete_type))
1180 tok::kw___builtin_hlsl_is_intangible))
1184 case UTT_IsTypedResourceElementCompatible:
1185 assert(
Self.getLangOpts().HLSL &&
1186 "typed resource element compatible types are an HLSL-only feature");
1190 return Self.HLSL().IsTypedResourceElementCompatible(
T);
1201 SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1242 LhsT =
Self.Context.getRValueReferenceType(LhsT);
1278 case TypeTrait::UTT_StructuredBindingSize: {
1280 SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1284 S.
Diag(KWLoc, diag::err_arg_is_not_destructurable) <<
T << ArgRange;
1292 llvm_unreachable(
"Not a SizeT type trait");
1309 if (Kind <=
BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1310 Kind != BTT_ReferenceConstructsFromTemporary &&
1311 Kind != BTT_ReferenceConvertsFromTemporary)
1315 case clang::BTT_ReferenceBindsToTemporary:
1316 case clang::BTT_ReferenceConstructsFromTemporary:
1317 case clang::BTT_ReferenceConvertsFromTemporary:
1318 case clang::TT_IsConstructible:
1319 case clang::TT_IsNothrowConstructible:
1320 case clang::TT_IsTriviallyConstructible: {
1334 assert(!Args.empty());
1339 for (
const auto *TSI : Args) {
1345 KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1362 bool UseRawObjectType =
1363 Kind == clang::BTT_ReferenceBindsToTemporary ||
1364 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1365 Kind == clang::BTT_ReferenceConvertsFromTemporary;
1367 llvm::BumpPtrAllocator OpaqueExprAllocator;
1369 ArgExprs.reserve(Args.size() - 1);
1370 for (
unsigned I = 1, N = Args.size(); I != N; ++I) {
1371 QualType ArgTy = Args[I]->getType();
1391 Kind == clang::BTT_ReferenceConvertsFromTemporary
1402 if (Kind == clang::TT_IsConstructible)
1405 if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1406 Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1407 Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1415 if (!
Init.isDirectReferenceBinding())
1418 if (Kind == clang::BTT_ReferenceBindsToTemporary)
1422 if (
U->isReferenceType())
1430 OpaqueExprAllocator)
1434 if (Kind == clang::TT_IsNothrowConstructible)
1437 if (Kind == clang::TT_IsTriviallyConstructible) {
1440 if (
T.getNonReferenceType().hasNonTrivialObjCLifetime())
1448 llvm_unreachable(
"unhandled type trait");
1452 llvm_unreachable(
"not a TT");
1462 case UTT_HasNothrowAssign:
1463 case UTT_HasNothrowMoveAssign:
1464 Replacement = BTT_IsNothrowAssignable;
1466 case UTT_HasNothrowCopy:
1467 case UTT_HasNothrowConstructor:
1468 Replacement = TT_IsNothrowConstructible;
1470 case UTT_HasTrivialAssign:
1471 case UTT_HasTrivialMoveAssign:
1472 Replacement = BTT_IsTriviallyAssignable;
1474 case UTT_HasTrivialCopy:
1475 Replacement = UTT_IsTriviallyCopyable;
1477 case UTT_HasTrivialDefaultConstructor:
1478 case UTT_HasTrivialMoveConstructor:
1479 Replacement = TT_IsTriviallyConstructible;
1481 case UTT_HasTrivialDestructor:
1482 Replacement = UTT_IsTriviallyDestructible;
1484 case UTT_IsTriviallyRelocatable:
1485 Replacement = clang::UTT_IsCppTriviallyRelocatable;
1487 case BTT_ReferenceBindsToTemporary:
1488 Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1493 S.
Diag(KWLoc, diag::warn_deprecated_builtin)
1499 if (Arity && N != Arity) {
1500 Diag(
Loc, diag::err_type_trait_arity)
1505 if (!Arity && N == 0) {
1506 Diag(
Loc, diag::err_type_trait_arity)
1519 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1520 return TypeTraitReturnType::SizeT;
1521 return TypeTraitReturnType::Bool;
1531 *
this, Kind, KWLoc, Args[0]->getType()))
1534 DiagnoseBuiltinDeprecation(*
this, Kind, KWLoc);
1537 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1538 if (Args[I]->getType()->isDependentType()) {
1545 case TypeTraitReturnType::Bool: {
1549 KWLoc, Kind, Args, RParenLoc,
Result);
1551 case TypeTraitReturnType::SizeT: {
1555 Args, RParenLoc,
Result);
1558 llvm_unreachable(
"unhandled type trait return type");
1565 ConvertedArgs.reserve(Args.size());
1567 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
1573 ConvertedArgs.push_back(TInfo);
1588 if (!rhsRecord || !lhsRecord) {
1591 if (!LHSObjTy || !RHSObjTy)
1596 if (!BaseInterface || !DerivedInterface)
1600 diag::err_incomplete_type_used_in_type_trait_expr))
1607 (lhsRecord == rhsRecord));
1613 if (rhsRecord && rhsRecord->getOriginalDecl()->isUnion())
1616 if (lhsRecord == rhsRecord)
1624 diag::err_incomplete_type_used_in_type_trait_expr))
1627 return cast<CXXRecordDecl>(rhsRecord->getOriginalDecl())
1639 "Cannot evaluate traits of dependent types");
1645 case BTT_IsVirtualBaseOf: {
1649 if (!BaseRecord || !DerivedRecord) {
1651 tok::kw___builtin_is_virtual_base_of);
1653 tok::kw___builtin_is_virtual_base_of);
1657 if (BaseRecord->
isUnionType() || DerivedRecord->isUnionType())
1661 !DerivedRecord->isStructureOrClassType())
1665 diag::err_incomplete_type))
1668 return cast<CXXRecordDecl>(DerivedRecord->getOriginalDecl())
1669 ->isVirtuallyDerivedFrom(
1673 return Self.Context.hasSameType(LhsT, RhsT);
1674 case BTT_TypeCompatible: {
1677 QualType Lhs =
Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1678 QualType Rhs =
Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1679 return Self.Context.typesAreCompatible(Lhs, Rhs);
1681 case BTT_IsConvertible:
1682 case BTT_IsConvertibleTo:
1683 case BTT_IsNothrowConvertible: {
1686 llvm::BumpPtrAllocator OpaqueExprAllocator;
1688 OpaqueExprAllocator);
1692 if (BTT != BTT_IsNothrowConvertible)
1698 case BTT_IsAssignable:
1699 case BTT_IsNothrowAssignable:
1700 case BTT_IsTriviallyAssignable: {
1713 Self.RequireCompleteType(
1715 diag::err_incomplete_type_used_in_type_trait_expr))
1718 Self.RequireCompleteType(
1720 diag::err_incomplete_type_used_in_type_trait_expr))
1730 if (Ty->isObjectType() || Ty->isFunctionType())
1731 Ty =
Self.Context.getRValueReferenceType(Ty);
1732 return {KeyLoc, Ty.getNonLValueExprType(
Self.Context),
1736 auto Lhs = createDeclValExpr(LhsT);
1737 auto Rhs = createDeclValExpr(RhsT);
1746 Self.BuildBinOp(
nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1751 Self.CheckUnusedVolatileAssignment(
Result.get());
1756 if (BTT == BTT_IsAssignable)
1759 if (BTT == BTT_IsNothrowAssignable)
1762 if (BTT == BTT_IsTriviallyAssignable) {
1771 return !
Result.get()->hasNonTrivialCall(
Self.Context);
1774 llvm_unreachable(
"unhandled type trait");
1777 case BTT_IsLayoutCompatible: {
1780 diag::err_incomplete_type);
1783 diag::err_incomplete_type);
1788 return Self.IsLayoutCompatible(LhsT, RhsT);
1790 case BTT_IsPointerInterconvertibleBaseOf: {
1792 !
Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1794 diag::err_incomplete_type);
1798 tok::kw___is_pointer_interconvertible_base_of);
1800 tok::kw___is_pointer_interconvertible_base_of);
1802 return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1804 case BTT_IsDeducible: {
1805 const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);
1807 return Self.DeduceTemplateArgumentsFromType(
1808 TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1811 case BTT_IsScalarizedLayoutCompatible: {
1814 diag::err_incomplete_type))
1818 diag::err_incomplete_type))
1822 Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1824 Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1826 return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1828 case BTT_LtSynthesisesFromSpaceship:
1829 case BTT_LeSynthesisesFromSpaceship:
1830 case BTT_GtSynthesisesFromSpaceship:
1831 case BTT_GeSynthesisesFromSpaceship: {
1850 case BTT_LtSynthesisesFromSpaceship:
1851 return BinaryOperatorKind::BO_LT;
1852 case BTT_LeSynthesisesFromSpaceship:
1853 return BinaryOperatorKind::BO_LE;
1854 case BTT_GtSynthesisesFromSpaceship:
1855 return BinaryOperatorKind::BO_GT;
1856 case BTT_GeSynthesisesFromSpaceship:
1857 return BinaryOperatorKind::BO_GE;
1859 llvm_unreachable(
"Trying to Synthesize non-comparison operator?");
1864 Self.LookupBinOp(
Self.TUScope, KeyLoc, OpKind, Functions);
1867 Self.CreateOverloadedBinOp(KeyLoc, OpKind, Functions, &LHS, &RHS);
1871 return isa<CXXRewrittenBinaryOperator>(
Result.get());
1874 llvm_unreachable(
"not a BTT");
1876 llvm_unreachable(
"Unknown type trait or not implemented");
1893 assert(!
T->
isDependentType() &&
"Cannot evaluate traits of dependent type");
1901 T = AT->getElementType();
1907 case ATT_ArrayExtent: {
1910 if (
Self.VerifyIntegerConstantExpression(
1911 DimExpr, &
Value, diag::err_dimension_expr_not_constant_integer)
1914 if (
Value.isSigned() &&
Value.isNegative()) {
1915 Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1923 bool Matched =
false;
1930 T = AT->getElementType();
1935 Self.Context.getAsConstantArrayType(
T))
1936 return CAT->getLimitedSize();
1942 llvm_unreachable(
"Unknown type trait or not implemented");
1978 case ET_IsLValueExpr:
1980 case ET_IsRValueExpr:
1983 llvm_unreachable(
"Expression trait not covered by switch");
2004 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
2005 .Case(
"is_trivially_relocatable",
2006 TypeTrait::UTT_IsCppTriviallyRelocatable)
2007 .Case(
"is_replaceable", TypeTrait::UTT_IsReplaceable)
2008 .Case(
"is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
2009 .Case(
"is_assignable", TypeTrait::BTT_IsAssignable)
2010 .Case(
"is_empty", TypeTrait::UTT_IsEmpty)
2011 .Case(
"is_standard_layout", TypeTrait::UTT_IsStandardLayout)
2012 .Case(
"is_constructible", TypeTrait::TT_IsConstructible)
2013 .Case(
"is_final", TypeTrait::UTT_IsFinal)
2014 .Default(std::nullopt);
2018 std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
2026 std::optional<TypeTrait> Trait;
2029 if (
const auto *TraitExpr = dyn_cast<TypeTraitExpr>(
E)) {
2030 Trait = TraitExpr->getTrait();
2031 for (
const auto *Arg : TraitExpr->getArgs())
2032 Args.push_back(Arg->getType());
2033 return {{Trait.value(), std::move(Args)}};
2035 const auto *Ref = dyn_cast<DeclRefExpr>(
E);
2037 return std::nullopt;
2040 if (
const auto *VD =
2041 dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
2042 if (!VD->isInStdNamespace())
2043 return std::nullopt;
2044 StringRef Name = VD->getIdentifier()->getName();
2045 if (!Name.consume_back(
"_v"))
2046 return std::nullopt;
2049 return std::nullopt;
2050 for (
const auto &Arg : VD->getTemplateArgs().asArray()) {
2052 for (
const auto &InnerArg : Arg.pack_elements())
2053 Args.push_back(InnerArg.getAsType());
2055 Args.push_back(Arg.getAsType());
2057 llvm_unreachable(
"Unexpected kind");
2060 return {{Trait.value(), std::move(Args)}};
2064 if (
const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2065 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr(
"value")) {
2068 return std::nullopt;
2071 return std::nullopt;
2072 const TemplateDecl *
D = Ts->getTemplateName().getAsTemplateDecl();
2074 return std::nullopt;
2077 return std::nullopt;
2078 for (
const auto &Arg : Ts->template_arguments())
2079 Args.push_back(Arg.getAsType());
2080 return {{Trait.value(), std::move(Args)}};
2082 return std::nullopt;
2090 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2091 << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2094 D->hasUserDeclaredCopyConstructor());
2096 D->hasUserDeclaredCopyAssignment());
2098 D->hasUserDeclaredMoveConstructor());
2100 D->hasUserDeclaredMoveAssignment());
2104 if (!
D->hasSimpleMoveConstructor() && !
D->hasSimpleCopyConstructor()) {
2105 const auto *
Decl = cast_or_null<CXXConstructorDecl>(
2107 if (
Decl &&
Decl->isUserProvided())
2108 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2109 << diag::TraitNotSatisfiedReason::UserProvidedCtr
2112 if (!
D->hasSimpleMoveAssignment() && !
D->hasSimpleCopyAssignment()) {
2115 if (
Decl &&
Decl->isUserProvided())
2116 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2117 << diag::TraitNotSatisfiedReason::UserProvidedAssign
2121 Dtr = Dtr->getCanonicalDecl();
2122 if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2123 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2124 << diag::TraitNotSatisfiedReason::DeletedDtr << 1
2125 << Dtr->getSourceRange();
2133 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2135 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2136 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2137 << B.getSourceRange();
2139 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2140 << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2141 << B.getSourceRange();
2144 if (!Field->getType()->isReferenceType() &&
2146 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2147 << diag::TraitNotSatisfiedReason::NTRField << Field
2148 << Field->getType() << Field->getSourceRange();
2150 if (
D->hasDeletedDestructor())
2151 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2152 << diag::TraitNotSatisfiedReason::DeletedDtr << 0
2155 if (
D->
hasAttr<TriviallyRelocatableAttr>())
2163 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait)
2164 <<
T << diag::TraitName::TriviallyRelocatable;
2166 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2167 << diag::TraitNotSatisfiedReason::VLA;
2170 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2171 << diag::TraitNotSatisfiedReason::Ref;
2172 T =
T.getNonReferenceType();
2174 if (
T.hasNonTrivialObjCLifetime())
2175 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2176 << diag::TraitNotSatisfiedReason::HasArcLifetime;
2182 if (
D->hasDefinition())
2191 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2193 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2194 << diag::TraitNotSatisfiedReason::NonReplaceableBase << B.getType()
2195 << B.getSourceRange();
2199 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2200 << diag::TraitNotSatisfiedReason::NonReplaceableField << Field
2201 << Field->getType() << Field->getSourceRange();
2203 if (
D->hasDeletedDestructor())
2204 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2205 << diag::TraitNotSatisfiedReason::DeletedDtr << 0
2208 if (!
D->hasSimpleMoveConstructor() && !
D->hasSimpleCopyConstructor()) {
2209 const auto *
Decl = cast<CXXConstructorDecl>(
2212 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2213 << diag::TraitNotSatisfiedReason::DeletedCtr
2216 if (!
D->hasSimpleMoveAssignment() && !
D->hasSimpleCopyAssignment()) {
2220 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2221 << diag::TraitNotSatisfiedReason::DeletedAssign
2232 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait)
2233 <<
T << diag::TraitName::Replaceable;
2236 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2237 << diag::TraitNotSatisfiedReason::VLA;
2240 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2241 << diag::TraitNotSatisfiedReason::Ref;
2242 T =
T.getNonReferenceType();
2244 if (
T.isConstQualified())
2245 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2246 << diag::TraitNotSatisfiedReason::Const;
2248 if (
T.isVolatileQualified())
2249 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2250 << diag::TraitNotSatisfiedReason::Volatile;
2260 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2261 << diag::TraitNotSatisfiedReason::NotScalarOrClass << IsArray;
2268 if (
D->hasDefinition())
2278 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2280 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2281 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2282 << B.getSourceRange();
2284 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2285 << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2286 << B.getSourceRange();
2290 if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2291 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2292 << diag::TraitNotSatisfiedReason::NTCField << Field
2293 << Field->getType() << Field->getSourceRange();
2296 if (
D->hasDeletedDestructor() || (Dtr && !Dtr->
isTrivial()))
2297 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2298 << diag::TraitNotSatisfiedReason::DeletedDtr
2302 if (
Method->isTrivial() || !
Method->isUserProvided()) {
2305 auto SpecialMemberKind =
2307 switch (SpecialMemberKind) {
2319 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2320 << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2321 : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2322 << IsMove <<
Method->getSourceRange();
2338 bool ContainsVoid =
false;
2340 ContainsVoid |= ArgTy->isVoidType();
2344 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2345 << diag::TraitNotSatisfiedReason::CVVoidType;
2349 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2350 << diag::TraitNotSatisfiedReason::FunctionType;
2353 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2354 << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2360 llvm::BumpPtrAllocator OpaqueExprAllocator;
2362 ArgExprs.reserve(Ts.size() - 1);
2363 for (
unsigned I = 1, N = Ts.size(); I != N; ++I) {
2381 Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2387 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait)
2388 <<
T << diag::TraitName::TriviallyCopyable;
2391 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2392 << diag::TraitNotSatisfiedReason::Ref;
2398 if (
D->hasDefinition())
2409 if (Ty->isObjectType() || Ty->isFunctionType())
2411 return {
Loc, Ty.getNonLValueExprType(SemaRef.
Context),
2415 auto LHS = createDeclValExpr(
T);
2416 auto RHS = createDeclValExpr(
U);
2433 for (
const auto *Field :
D->fields()) {
2434 if (Field->isZeroLengthBitField())
2436 if (Field->isBitField()) {
2437 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2438 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2439 << Field->getSourceRange();
2442 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2443 << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2444 << Field->getType() << Field->getSourceRange();
2448 for (
const auto *M :
D->methods()) {
2449 if (M->isVirtual()) {
2450 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2451 << diag::TraitNotSatisfiedReason::VirtualFunction << M
2452 << M->getSourceRange();
2458 for (
const auto &B :
D->bases()) {
2459 const auto *BR = B.getType()->getAsCXXRecordDecl();
2460 if (!BR || BR->isInvalidDecl())
2462 if (B.isVirtual()) {
2463 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2464 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2465 << B.getSourceRange();
2467 if (!BR->isEmpty()) {
2468 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2469 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2470 << B.getSourceRange();
2477 S.
Diag(
Loc, diag::note_unsatisfied_trait) <<
T << diag::TraitName::Empty;
2483 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2484 << diag::TraitNotSatisfiedReason::Ref;
2485 T =
T.getNonReferenceType();
2488 T = AT->getElementType();
2491 if (
D->hasDefinition()) {
2504 if (!
D->isEffectivelyFinal()) {
2505 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2506 << diag::TraitNotSatisfiedReason::NotMarkedFinal;
2514 S.
Diag(
Loc, diag::note_unsatisfied_trait) <<
T << diag::TraitName::Final;
2516 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2517 << diag::TraitNotSatisfiedReason::Ref;
2518 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2519 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2524 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2525 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2529 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2530 << diag::TraitNotSatisfiedReason::FunctionType;
2531 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2532 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2536 S.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2537 << diag::TraitNotSatisfiedReason::NotClassOrUnion;
2545 int NumBasesWithFields = 0;
2552 if (!Field->isUnnamedBitField()) {
2553 if (++NumBasesWithFields > 1)
2565 assert(B.getType()->getAsCXXRecordDecl() &&
"invalid base?");
2566 if (B.isVirtual()) {
2567 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2568 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2569 << B.getSourceRange();
2571 if (!B.getType()->isStandardLayoutType()) {
2572 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2573 << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2574 << B.getSourceRange();
2582 if (Field->isUnnamedBitField())
2588 FirstAccess = Field->getAccess();
2593 if (Field->getAccess() != FirstAccess) {
2595 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2596 << diag::TraitNotSatisfiedReason::MixedAccess;
2601 SemaRef.
Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2602 << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2610 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2611 << diag::TraitNotSatisfiedReason::MultipleDataBase;
2613 if (
D->isPolymorphic()) {
2617 for (
const auto *M :
D->methods()) {
2618 if (M->isVirtual()) {
2624 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2625 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2626 SemaRef.
Diag(VirtualMD->getLocation(), diag::note_defined_here)
2630 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2631 << diag::TraitNotSatisfiedReason::VirtualFunction <<
D;
2636 if (!Field->getType()->isStandardLayoutType()) {
2637 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2638 << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2639 << Field->getType() << Field->getSourceRange();
2643 if (
D->hasDirectFields()) {
2653 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2654 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields <<
Indirect
2662 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait)
2663 <<
T << diag::TraitName::StandardLayout;
2667 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2668 << diag::TraitNotSatisfiedReason::VLA;
2673 SemaRef.
Diag(
Loc, diag::note_unsatisfied_trait_reason)
2674 << diag::TraitNotSatisfiedReason::Ref;
2677 T =
T.getNonReferenceType();
2682 if (
D->hasDefinition())
2697 const auto &[Trait, Args] = TraitInfo.value();
2699 case UTT_IsCppTriviallyRelocatable:
2702 case UTT_IsReplaceable:
2705 case UTT_IsTriviallyCopyable:
2708 case BTT_IsAssignable:
2714 case UTT_IsStandardLayout:
2717 case TT_IsConstructible:
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 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 IsEligibleForReplacement(Sema &SemaRef, const CXXRecordDecl *D)
static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E)
static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E)
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)
std::optional< std::pair< TypeTrait, llvm::SmallVector< QualType, 1 > > > ExtractedTypeTraitInfo
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 DiagnoseNonReplaceableReason(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 IsCXXReplaceableType(Sema &S, const CXXRecordDecl *RD)
static bool isTriviallyEqualityComparableType(Sema &S, QualType Type, SourceLocation KeyLoc)
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
bool containsNonRelocatablePointerAuth(QualType T)
Examines a given type, and returns whether the type itself or any data it transitively contains has a...
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,...
CanQualType getLogicalOperationType() const
The result type of logical operations, '<', '>', '!=', etc.
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.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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
std::optional< CXXRecordDeclRelocationInfo > getRelocationInfoForCXXRecord(const CXXRecordDecl *) const
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++ 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 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 hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12)
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 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 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 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 hasNonTrivialDefaultConstructor() const
Determine whether this class has a non-trivial default constructor (C++11 [class.ctor]p5).
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6,...
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)
The results of name lookup within a DeclContext.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name 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
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.
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.
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.
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.
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...
Represents a class type in Objective C.
ObjCInterfaceDecl * getInterface() const
Gets the interface declaration for this object type, if the base type really is an interface.
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
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
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
ASTContext::CXXRecordDeclRelocationInfo CheckCXX2CRelocatableAndReplaceable(const clang::CXXRecordDecl *D)
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)
bool IsCXXReplaceableType(QualType T)
Determines if a type is replaceable according to the C++26 rules.
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...
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
@ 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.).
Represents a type template specialization; the template must be a class template, a type alias templa...
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 isStructureType() const
bool isLiteralType(const ASTContext &Ctx) const
Return true if this is a literal type (C++11 [basic.types]p10)
bool isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isRValueReferenceType() const
bool isFundamentalType() const
Tests whether the type is categorized as a fundamental type.
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.
bool isArithmeticType() const
CanQualType getCanonicalTypeUnqualified() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isHLSLIntangibleType() const
bool isEnumeralType() const
bool isScalarType() const
bool isInterfaceType() const
bool isVariableArrayType() const
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
bool isExtVectorType() const
bool isMemberDataPointerType() 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.
bool isAnyComplexType() const
bool isCompoundType() const
Tests whether the type is categorized as a compound type.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
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 isMemberFunctionPointerType() 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...
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isScopedEnumeralType() const
Determine whether this type is a scoped enumeration type.
The iterator over UnresolvedSets.
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.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
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.
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.
const FunctionProtoType * T
@ Success
Template argument deduction was successful.
ConstructorInfo getConstructorInfo(NamedDecl *ND)
TypeTrait
Names for traits that operate specifically on types.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...