8#include "../ExprConstShared.h"
18#include "llvm/Support/SipHash.h"
26 for (
const Expr *
E :
C->arguments()) {
35 assert(
Frame->getFunction()->getNumParams() > Index);
36 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
37 return Frame->getParam<
T>(Offset);
41 const TargetInfo &TI = S.getCtx().getTargetInfo();
46 else if (IntWidth == 16)
48 llvm_unreachable(
"Int isn't 16 or 32 bit?");
52 const TargetInfo &TI = S.getCtx().getTargetInfo();
57 else if (LongWidth == 32)
59 else if (LongWidth == 16)
61 llvm_unreachable(
"long isn't 16, 32 or 64 bit?");
79 std::optional<PrimType>
T = S.getContext().classify(QT);
83 int64_t
V = Val.getSExtValue();
87 uint64_t
V = Val.getZExtValue();
94 if constexpr (std::is_same_v<T, APInt>)
100 !std::is_signed_v<T>),
106 ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
110 std::optional<PrimType> &
T) {
116 return Ret<X>(S, OpPC, Result);
131 llvm_unreachable(
"Unsupported return type for builtin function");
141 if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
142 Frame->Caller && S.getEvalStatus().
Diag) {
144 return F && F->isInStdNamespace() && F->getIdentifier() &&
145 F->getIdentifier()->isStr(
"is_constant_evaluated");
152 diag::warn_is_constant_evaluated_always_true_constexpr)
157 diag::warn_is_constant_evaluated_always_true_constexpr)
184 for (;; ++IndexA, ++IndexB) {
191 uint8_t CA = PA.
deref<uint8_t>();
192 uint8_t CB = PB.
deref<uint8_t>();
197 }
else if (CA < CB) {
201 if (CA == 0 || CB == 0)
226 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
232 uint8_t Val = ElemPtr.
deref<uint8_t>();
256 for (
unsigned I = 0;; ++I) {
262 if (Elem.
deref<int8_t>() == 0)
265 Str += Elem.
deref<
char>();
270 Fill = llvm::APInt(32, 0);
271 else if (StringRef(Str).getAsInteger(0, Fill))
274 const llvm::fltSemantics &TargetSemantics =
278 if (S.getCtx().getTargetInfo().isNan2008()) {
281 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
284 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
293 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
296 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
305 const llvm::fltSemantics &TargetSemantics =
335 else if (LHS.
isNan() || RHS < LHS)
355 else if (LHS.
isNan() || RHS > LHS)
390 bool IsInf = Arg.
isInf();
457 case Builtin::BI__builtin_isgreater:
459 case Builtin::BI__builtin_isgreaterequal:
461 case Builtin::BI__builtin_isless:
463 case Builtin::BI__builtin_islessequal:
465 case Builtin::BI__builtin_islessgreater: {
470 case Builtin::BI__builtin_isunordered:
473 llvm_unreachable(
"Unexpected builtin ID: Should be a floating point "
474 "comparison function");
487 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
493 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
511 case APFloat::fcInfinity:
514 case APFloat::fcNormal:
517 case APFloat::fcZero:
551 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
560 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
569 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
571 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
579 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
590 assert(
Call->getNumArgs() == 1);
595 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
607 unsigned NumArgs =
Call->getNumArgs();
608 assert(NumArgs == 2 || NumArgs == 3);
610 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
625 PrimType AmountT = *S.getContext().classify(
Call->getArg(1)->getType());
626 PrimType ValueT = *S.getContext().classify(
Call->getArg(0)->getType());
647 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
650 uint64_t N =
Value.countr_zero();
659 assert(
Call->getArg(0)->isLValue());
665 }
else if (PtrT ==
PT_Ptr) {
669 assert(
false &&
"Unsupported pointer type passed to __builtin_addressof()");
680 TYPE_SWITCH(ArgT,
const T &Arg = S.Stk.peek<
T>(); S.Stk.push<
T>(Arg););
682 return Func->getDecl()->isConstexpr();
689 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
693 S.getCtx().getTargetInfo().getEHDataRegisterNumber(Arg.getZExtValue());
715 unsigned BuiltinOp =
Func->getBuiltinID();
716 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
717 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
723 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
724 PrimType ResultT = *S.getContext().classify(ResultType);
728 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
729 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
730 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
731 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
733 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
735 uint64_t LHSSize = LHS.getBitWidth();
736 uint64_t RHSSize = RHS.getBitWidth();
737 uint64_t ResultSize = S.getCtx().getTypeSize(ResultType);
738 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
744 if (IsSigned && !AllSigned)
747 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
748 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
755 llvm_unreachable(
"Invalid value for BuiltinOp");
756 case Builtin::BI__builtin_add_overflow:
757 case Builtin::BI__builtin_sadd_overflow:
758 case Builtin::BI__builtin_saddl_overflow:
759 case Builtin::BI__builtin_saddll_overflow:
760 case Builtin::BI__builtin_uadd_overflow:
761 case Builtin::BI__builtin_uaddl_overflow:
762 case Builtin::BI__builtin_uaddll_overflow:
763 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
764 : LHS.uadd_ov(RHS, Overflow);
766 case Builtin::BI__builtin_sub_overflow:
767 case Builtin::BI__builtin_ssub_overflow:
768 case Builtin::BI__builtin_ssubl_overflow:
769 case Builtin::BI__builtin_ssubll_overflow:
770 case Builtin::BI__builtin_usub_overflow:
771 case Builtin::BI__builtin_usubl_overflow:
772 case Builtin::BI__builtin_usubll_overflow:
773 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
774 : LHS.usub_ov(RHS, Overflow);
776 case Builtin::BI__builtin_mul_overflow:
777 case Builtin::BI__builtin_smul_overflow:
778 case Builtin::BI__builtin_smull_overflow:
779 case Builtin::BI__builtin_smulll_overflow:
780 case Builtin::BI__builtin_umul_overflow:
781 case Builtin::BI__builtin_umull_overflow:
782 case Builtin::BI__builtin_umulll_overflow:
783 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
784 : LHS.umul_ov(RHS, Overflow);
790 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
791 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
792 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
797 APSInt Temp =
Result.extOrTrunc(S.getCtx().getTypeSize(ResultType));
800 if (!APSInt::isSameValue(Temp,
Result))
808 assert(
Func->getDecl()->getReturnType()->isBooleanType());
818 unsigned BuiltinOp =
Func->getBuiltinID();
819 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
820 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
821 PrimType CarryT = *S.getContext().classify(
Call->getArg(2)->getType());
838 bool FirstOverflowed =
false;
839 bool SecondOverflowed =
false;
842 llvm_unreachable(
"Invalid value for BuiltinOp");
843 case Builtin::BI__builtin_addcb:
844 case Builtin::BI__builtin_addcs:
845 case Builtin::BI__builtin_addc:
846 case Builtin::BI__builtin_addcl:
847 case Builtin::BI__builtin_addcll:
849 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
851 case Builtin::BI__builtin_subcb:
852 case Builtin::BI__builtin_subcs:
853 case Builtin::BI__builtin_subc:
854 case Builtin::BI__builtin_subcl:
855 case Builtin::BI__builtin_subcll:
857 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
862 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
865 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
866 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
870 assert(
Call->getType() ==
Call->getArg(0)->getType());
879 unsigned BuiltinOp =
Func->getBuiltinID();
880 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
885 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
886 BuiltinOp != Builtin::BI__lzcnt &&
887 BuiltinOp != Builtin::BI__lzcnt64;
890 if (
Func->getBuiltinID() == Builtin::BI__builtin_clzg &&
891 Call->getNumArgs() == 2) {
893 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
911 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
915 if (
Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&
916 Call->getNumArgs() == 2) {
918 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
933 PrimType ReturnT = *S.getContext().classify(
Call->getType());
934 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
936 assert(Val.getActiveBits() <= 64);
939 { S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
950 unsigned BuiltinOp =
Func->getBuiltinID();
952 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
953 unsigned SizeValOffset = 0;
954 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
958 auto returnBool = [&S](
bool Value) ->
bool {
974 if (Size.isPowerOfTwo()) {
976 unsigned InlineWidthBits =
977 S.getCtx().getTargetInfo().getMaxAtomicInlineWidth();
978 if (Size <= S.getCtx().toCharUnitsFromBits(InlineWidthBits)) {
982 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
984 return returnBool(
true);
987 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
990 return returnBool(
true);
994 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
995 return returnBool(
true);
998 const Expr *PtrArg =
Call->getArg(1);
1000 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
1003 if (ICE->getCastKind() == CK_BitCast)
1004 PtrArg = ICE->getSubExpr();
1010 S.getCtx().getTypeAlignInChars(PointeeType) >= Size) {
1012 return returnBool(
true);
1018 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
1019 return returnBool(
false);
1035 Result.atIndex(0).initialize();
1037 Result.atIndex(1).initialize();
1052 unsigned BuiltinOp =
Func->getBuiltinID();
1055 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1058 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1059 S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1062 unsigned SrcWidth = S.getCtx().getIntWidth(
Call->getArg(0)->getType());
1063 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1064 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1065 S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1066 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1076 APSInt Align = Alignment.extOrTrunc(Src.getBitWidth());
1077 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1079 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
1081 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1082 APSInt AlignedVal =
APSInt(Src & ~(Align - 1), Src.isUnsigned());
1085 assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1086 S.Stk.push<
Boolean>((Src & (Align - 1)) == 0);
1091 assert(FirstArgT ==
PT_Ptr);
1101 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1116 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1121 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1122 BuiltinOp == Builtin::BI__builtin_align_up);
1137 assert(Alignment.getBitWidth() <= 64 &&
1138 "Cannot handle > 64-bit address-space");
1139 uint64_t Alignment64 = Alignment.getZExtValue();
1142 ? llvm::alignDown(PtrOffset, Alignment64)
1143 : llvm::alignTo(PtrOffset, Alignment64));
1150 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1168 const auto &Ptr = S.Stk.peek<
Pointer>();
1169 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1171 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1172 uint64_t
Result = getPointerAuthStableSipHash(R);
1188 auto returnInt = [&S,
Call](
bool Value) ->
bool {
1212 auto Res =
C.interpretExpr(Arg, Arg->
isGLValue());
1213 if (Res.isInvalid()) {
1218 if (!Res.isInvalid() && !Res.empty()) {
1219 const APValue &LV = Res.toAPValue();
1222 if (
Base.isNull()) {
1224 return returnInt(
true);
1225 }
else if (
const auto *
E =
Base.dyn_cast<
const Expr *>()) {
1226 if (!isa<StringLiteral>(
E))
1227 return returnInt(
false);
1232 return returnInt(
true);
1235 return returnInt(
false);
1241 return returnInt(
true);
1244 return returnInt(
false);
1252 std::optional<PrimType> ReturnT = S.getContext().classify(
Call);
1255 case Builtin::BI__builtin_is_constant_evaluated:
1259 case Builtin::BI__builtin_assume:
1260 case Builtin::BI__assume:
1262 case Builtin::BI__builtin_strcmp:
1266 case Builtin::BI__builtin_strlen:
1270 case Builtin::BI__builtin_nan:
1271 case Builtin::BI__builtin_nanf:
1272 case Builtin::BI__builtin_nanl:
1273 case Builtin::BI__builtin_nanf16:
1274 case Builtin::BI__builtin_nanf128:
1278 case Builtin::BI__builtin_nans:
1279 case Builtin::BI__builtin_nansf:
1280 case Builtin::BI__builtin_nansl:
1281 case Builtin::BI__builtin_nansf16:
1282 case Builtin::BI__builtin_nansf128:
1287 case Builtin::BI__builtin_huge_val:
1288 case Builtin::BI__builtin_huge_valf:
1289 case Builtin::BI__builtin_huge_vall:
1290 case Builtin::BI__builtin_huge_valf16:
1291 case Builtin::BI__builtin_huge_valf128:
1292 case Builtin::BI__builtin_inf:
1293 case Builtin::BI__builtin_inff:
1294 case Builtin::BI__builtin_infl:
1295 case Builtin::BI__builtin_inff16:
1296 case Builtin::BI__builtin_inff128:
1300 case Builtin::BI__builtin_copysign:
1301 case Builtin::BI__builtin_copysignf:
1302 case Builtin::BI__builtin_copysignl:
1303 case Builtin::BI__builtin_copysignf128:
1308 case Builtin::BI__builtin_fmin:
1309 case Builtin::BI__builtin_fminf:
1310 case Builtin::BI__builtin_fminl:
1311 case Builtin::BI__builtin_fminf16:
1312 case Builtin::BI__builtin_fminf128:
1317 case Builtin::BI__builtin_fmax:
1318 case Builtin::BI__builtin_fmaxf:
1319 case Builtin::BI__builtin_fmaxl:
1320 case Builtin::BI__builtin_fmaxf16:
1321 case Builtin::BI__builtin_fmaxf128:
1326 case Builtin::BI__builtin_isnan:
1330 case Builtin::BI__builtin_issignaling:
1335 case Builtin::BI__builtin_isinf:
1340 case Builtin::BI__builtin_isinf_sign:
1345 case Builtin::BI__builtin_isfinite:
1349 case Builtin::BI__builtin_isnormal:
1353 case Builtin::BI__builtin_issubnormal:
1357 case Builtin::BI__builtin_iszero:
1361 case Builtin::BI__builtin_signbit:
1362 case Builtin::BI__builtin_signbitf:
1363 case Builtin::BI__builtin_signbitl:
1367 case Builtin::BI__builtin_isgreater:
1368 case Builtin::BI__builtin_isgreaterequal:
1369 case Builtin::BI__builtin_isless:
1370 case Builtin::BI__builtin_islessequal:
1371 case Builtin::BI__builtin_islessgreater:
1372 case Builtin::BI__builtin_isunordered:
1376 case Builtin::BI__builtin_isfpclass:
1380 case Builtin::BI__builtin_fpclassify:
1385 case Builtin::BI__builtin_fabs:
1386 case Builtin::BI__builtin_fabsf:
1387 case Builtin::BI__builtin_fabsl:
1388 case Builtin::BI__builtin_fabsf128:
1393 case Builtin::BI__builtin_popcount:
1394 case Builtin::BI__builtin_popcountl:
1395 case Builtin::BI__builtin_popcountll:
1396 case Builtin::BI__builtin_popcountg:
1397 case Builtin::BI__popcnt16:
1398 case Builtin::BI__popcnt:
1399 case Builtin::BI__popcnt64:
1404 case Builtin::BI__builtin_parity:
1405 case Builtin::BI__builtin_parityl:
1406 case Builtin::BI__builtin_parityll:
1411 case Builtin::BI__builtin_clrsb:
1412 case Builtin::BI__builtin_clrsbl:
1413 case Builtin::BI__builtin_clrsbll:
1418 case Builtin::BI__builtin_bitreverse8:
1419 case Builtin::BI__builtin_bitreverse16:
1420 case Builtin::BI__builtin_bitreverse32:
1421 case Builtin::BI__builtin_bitreverse64:
1426 case Builtin::BI__builtin_classify_type:
1431 case Builtin::BI__builtin_expect:
1432 case Builtin::BI__builtin_expect_with_probability:
1437 case Builtin::BI__builtin_rotateleft8:
1438 case Builtin::BI__builtin_rotateleft16:
1439 case Builtin::BI__builtin_rotateleft32:
1440 case Builtin::BI__builtin_rotateleft64:
1441 case Builtin::BI_rotl8:
1442 case Builtin::BI_rotl16:
1443 case Builtin::BI_rotl:
1444 case Builtin::BI_lrotl:
1445 case Builtin::BI_rotl64:
1450 case Builtin::BI__builtin_rotateright8:
1451 case Builtin::BI__builtin_rotateright16:
1452 case Builtin::BI__builtin_rotateright32:
1453 case Builtin::BI__builtin_rotateright64:
1454 case Builtin::BI_rotr8:
1455 case Builtin::BI_rotr16:
1456 case Builtin::BI_rotr:
1457 case Builtin::BI_lrotr:
1458 case Builtin::BI_rotr64:
1463 case Builtin::BI__builtin_ffs:
1464 case Builtin::BI__builtin_ffsl:
1465 case Builtin::BI__builtin_ffsll:
1469 case Builtin::BIaddressof:
1470 case Builtin::BI__addressof:
1471 case Builtin::BI__builtin_addressof:
1476 case Builtin::BIas_const:
1477 case Builtin::BIforward:
1478 case Builtin::BIforward_like:
1479 case Builtin::BImove:
1480 case Builtin::BImove_if_noexcept:
1485 case Builtin::BI__builtin_eh_return_data_regno:
1490 case Builtin::BI__builtin_launder:
1495 case Builtin::BI__builtin_add_overflow:
1496 case Builtin::BI__builtin_sub_overflow:
1497 case Builtin::BI__builtin_mul_overflow:
1498 case Builtin::BI__builtin_sadd_overflow:
1499 case Builtin::BI__builtin_uadd_overflow:
1500 case Builtin::BI__builtin_uaddl_overflow:
1501 case Builtin::BI__builtin_uaddll_overflow:
1502 case Builtin::BI__builtin_usub_overflow:
1503 case Builtin::BI__builtin_usubl_overflow:
1504 case Builtin::BI__builtin_usubll_overflow:
1505 case Builtin::BI__builtin_umul_overflow:
1506 case Builtin::BI__builtin_umull_overflow:
1507 case Builtin::BI__builtin_umulll_overflow:
1508 case Builtin::BI__builtin_saddl_overflow:
1509 case Builtin::BI__builtin_saddll_overflow:
1510 case Builtin::BI__builtin_ssub_overflow:
1511 case Builtin::BI__builtin_ssubl_overflow:
1512 case Builtin::BI__builtin_ssubll_overflow:
1513 case Builtin::BI__builtin_smul_overflow:
1514 case Builtin::BI__builtin_smull_overflow:
1515 case Builtin::BI__builtin_smulll_overflow:
1520 case Builtin::BI__builtin_addcb:
1521 case Builtin::BI__builtin_addcs:
1522 case Builtin::BI__builtin_addc:
1523 case Builtin::BI__builtin_addcl:
1524 case Builtin::BI__builtin_addcll:
1525 case Builtin::BI__builtin_subcb:
1526 case Builtin::BI__builtin_subcs:
1527 case Builtin::BI__builtin_subc:
1528 case Builtin::BI__builtin_subcl:
1529 case Builtin::BI__builtin_subcll:
1534 case Builtin::BI__builtin_clz:
1535 case Builtin::BI__builtin_clzl:
1536 case Builtin::BI__builtin_clzll:
1537 case Builtin::BI__builtin_clzs:
1538 case Builtin::BI__builtin_clzg:
1539 case Builtin::BI__lzcnt16:
1540 case Builtin::BI__lzcnt:
1541 case Builtin::BI__lzcnt64:
1546 case Builtin::BI__builtin_ctz:
1547 case Builtin::BI__builtin_ctzl:
1548 case Builtin::BI__builtin_ctzll:
1549 case Builtin::BI__builtin_ctzs:
1550 case Builtin::BI__builtin_ctzg:
1555 case Builtin::BI__builtin_bswap16:
1556 case Builtin::BI__builtin_bswap32:
1557 case Builtin::BI__builtin_bswap64:
1562 case Builtin::BI__atomic_always_lock_free:
1563 case Builtin::BI__atomic_is_lock_free:
1564 case Builtin::BI__c11_atomic_is_lock_free:
1569 case Builtin::BI__builtin_complex:
1574 case Builtin::BI__builtin_is_aligned:
1575 case Builtin::BI__builtin_align_up:
1576 case Builtin::BI__builtin_align_down:
1581 case Builtin::BI__builtin_os_log_format_buffer_size:
1586 case Builtin::BI__builtin_ptrauth_string_discriminator:
1591 case Builtin::BI__builtin_constant_p:
1597 S.FFDiag(S.Current->getLocation(OpPC),
1598 diag::note_invalid_subexpr_in_const_expr)
1599 << S.Current->getRange(OpPC);
1609 int64_t &IntResult) {
1611 unsigned N =
E->getNumComponents();
1614 unsigned ArrayIndex = 0;
1616 for (
unsigned I = 0; I != N; ++I) {
1618 switch (
Node.getKind()) {
1629 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
1637 int64_t Index = ArrayIndices[ArrayIndex];
1638 const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType);
1642 CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType);
1643 Result += Index * ElementSize;
1662 CurrentType = BaseSpec->
getType();
1672 llvm_unreachable(
"Dependent OffsetOfExpr?");
1676 IntResult =
Result.getQuantity();
1693 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
1698static bool copyComposite(InterpState &S, CodePtr OpPC,
const Pointer &Src,
1699 Pointer &Dest,
bool Activate);
1701 Pointer &Dest,
bool Activate =
false) {
1705 auto copyField = [&](
const Record::Field &F,
bool Activate) ->
bool {
1707 if (std::optional<PrimType> FT = S.Ctx.classify(F.Decl->getType())) {
1724 for (
const Record::Field &F : R->
fields()) {
1729 if (!copyField(F,
true))
1733 if (!copyField(F, Activate))
1738 for (
const Record::Base &B : R->
bases()) {
1749 Pointer &Dest,
bool Activate =
false) {
1761 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
1772 return copyRecord(S, OpPC, Src, Dest, Activate);
Defines enum values for all the target-independent builtin functions.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
#define INT_TYPE_SWITCH_NO_BOOL(Expr, B)
#define INT_TYPE_SWITCH(Expr, B)
#define TYPE_SWITCH(Expr, B)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
CharUnits & getLValueOffset()
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a base class of a C++ class.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
bool isInvalidDecl() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Represents a function declaration or definition.
QualType getReturnType() const
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
const LangOptions & getLangOpts() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Exposes information about the current target.
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
Symbolic representation of typeid(T) for some type T.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isPointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isAnyComplexType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
Wrapper around boolean types.
static Boolean from(T Value)
Pointer into the code segment.
Compilation context for expressions.
const APFloat & getAPFloat() const
llvm::FPClassTest classify() const
ComparisonCategoryResult compare(const Floating &RHS) const
static Floating getInf(const llvm::fltSemantics &Sem)
static Floating abs(const Floating &F)
APFloat::fltCategory getCategory() const
Base class for stack frames, shared between VM and walker.
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
unsigned getBuiltinID() const
Frame storing local variables.
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
CodePtr getRetPC() const
Returns the return address of the frame.
const FunctionDecl * getCallee() const override
Returns the caller.
Stack frame storing temporaries and parameters.
void clear()
Clears the stack without calling any destructors.
T & peek() const
Returns a reference to the value on the top of the stack.
A pointer to a memory block, live or dead.
bool isInitialized() const
Checks if an object was initialized.
Pointer atIndex(uint64_t Idx) const
Offsets a pointer inside an array.
bool isDummy() const
Checks if the pointer points to a dummy value.
int64_t getIndex() const
Returns the index into an array.
bool isActive() const
Checks if the object is active.
Pointer atField(unsigned Off) const
Creates a pointer to a field.
T & deref() const
Dereferences the pointer, if it's live.
unsigned getNumElems() const
Returns the number of elements.
void activate() const
Activats a field.
bool isIntegralPointer() const
QualType getType() const
Returns the type of the innermost field.
bool isLive() const
Checks if the pointer is live.
uint64_t getByteOffset() const
Returns the byte offset from the start.
bool isZero() const
Checks if the pointer is null.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
uint64_t getIntegerRepresentation() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
void initialize() const
Initializes a field.
const Record * getRecord() const
Returns the record descriptor of a class.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool __atomic_always_lock_free(size_t, void const volatile*) bool __atomic_is_lock_free(size_t,...
static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset=0)
Peek an integer value from the stack into an APSInt.
static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp_floating_comparison(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, llvm::ArrayRef< int64_t > ArrayIndices, int64_t &Result)
Interpret an offsetof operation.
static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool Signaling)
bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const APSInt &IntValue)
Sets the given integral value to the pointer, which is of a std::{weak,partial,strong}_ordering type.
static bool interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func)
static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Three integral values followed by a pointer (lhs, rhs, carry, carryOut).
static bool interp__builtin_signbit(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static unsigned callArgSize(const InterpState &S, const CallExpr *C)
static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_os_log_format_buffer_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_is_aligned() __builtin_align_up() __builtin_align_down() The first parameter is either an i...
static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a value can be loaded from a block.
static T getParam(const InterpFrame *Frame, unsigned Index)
PrimType getIntPrimType(const InterpState &S)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, std::optional< PrimType > &T)
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
PrimType
Enumeration of the primitive types of the VM.
static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate)
static bool copyRecord(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate=false)
static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func)
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool CheckSign, const CallExpr *Call)
static bool interp__builtin_move(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool noopPointer(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Just takes the first Argument to the call and puts it on the stack.
static void pushInteger(InterpState &S, const APSInt &Val, QualType QT)
Pushes Val on the stack as the type given by QT.
static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
PrimType getLongPrimType(const InterpState &S)
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_complex(Float A, float B);
static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is a dummy pointer.
static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
static void assignInteger(Pointer &Dest, PrimType ValueT, const APSInt &Value)
static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call)
Interpret a builtin function.
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Five int values followed by one floating value.
static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
Defined as __builtin_isnan(...), to accommodate the fact that it can take a float,...
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call, bool Right)
rotateleft(value, amount)
constexpr bool isIntegralType(PrimType T)
static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
First parameter to __builtin_isfpclass is the floating value, the second one is an integral value.
static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result)
static bool interp__builtin_bswap(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
The JSON file list parser is used to communicate input to InstallAPI.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.
const FunctionProtoType * T
Describes a memory block created by an allocation site.
unsigned getNumElems() const
Returns the number of elements stored in the block.
bool isPrimitive() const
Checks if the descriptor is of a primitive.
const ValueDecl * asValueDecl() const
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
PrimType getPrimType() const
bool isRecord() const
Checks if the descriptor is of a record.
const Record *const ElemRecord
Pointer to the record, if block contains records.