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();
442 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
448 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
466 case APFloat::fcInfinity:
469 case APFloat::fcNormal:
472 case APFloat::fcZero:
506 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
515 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
524 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
526 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
534 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
545 assert(
Call->getNumArgs() == 1);
550 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
562 unsigned NumArgs =
Call->getNumArgs();
563 assert(NumArgs == 2 || NumArgs == 3);
565 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
580 PrimType AmountT = *S.getContext().classify(
Call->getArg(1)->getType());
581 PrimType ValueT = *S.getContext().classify(
Call->getArg(0)->getType());
602 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
605 uint64_t N =
Value.countr_zero();
614 assert(
Call->getArg(0)->isLValue());
620 }
else if (PtrT ==
PT_Ptr) {
624 assert(
false &&
"Unsupported pointer type passed to __builtin_addressof()");
635 TYPE_SWITCH(ArgT,
const T &Arg = S.Stk.peek<
T>(); S.Stk.push<
T>(Arg););
637 return Func->getDecl()->isConstexpr();
644 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
648 S.getCtx().getTargetInfo().getEHDataRegisterNumber(Arg.getZExtValue());
670 unsigned BuiltinOp =
Func->getBuiltinID();
671 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
672 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
678 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
679 PrimType ResultT = *S.getContext().classify(ResultType);
683 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
684 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
685 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
686 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
688 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
690 uint64_t LHSSize = LHS.getBitWidth();
691 uint64_t RHSSize = RHS.getBitWidth();
692 uint64_t ResultSize = S.getCtx().getTypeSize(ResultType);
693 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
699 if (IsSigned && !AllSigned)
702 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
703 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
710 llvm_unreachable(
"Invalid value for BuiltinOp");
711 case Builtin::BI__builtin_add_overflow:
712 case Builtin::BI__builtin_sadd_overflow:
713 case Builtin::BI__builtin_saddl_overflow:
714 case Builtin::BI__builtin_saddll_overflow:
715 case Builtin::BI__builtin_uadd_overflow:
716 case Builtin::BI__builtin_uaddl_overflow:
717 case Builtin::BI__builtin_uaddll_overflow:
718 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
719 : LHS.uadd_ov(RHS, Overflow);
721 case Builtin::BI__builtin_sub_overflow:
722 case Builtin::BI__builtin_ssub_overflow:
723 case Builtin::BI__builtin_ssubl_overflow:
724 case Builtin::BI__builtin_ssubll_overflow:
725 case Builtin::BI__builtin_usub_overflow:
726 case Builtin::BI__builtin_usubl_overflow:
727 case Builtin::BI__builtin_usubll_overflow:
728 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
729 : LHS.usub_ov(RHS, Overflow);
731 case Builtin::BI__builtin_mul_overflow:
732 case Builtin::BI__builtin_smul_overflow:
733 case Builtin::BI__builtin_smull_overflow:
734 case Builtin::BI__builtin_smulll_overflow:
735 case Builtin::BI__builtin_umul_overflow:
736 case Builtin::BI__builtin_umull_overflow:
737 case Builtin::BI__builtin_umulll_overflow:
738 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
739 : LHS.umul_ov(RHS, Overflow);
745 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
746 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
747 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
752 APSInt Temp =
Result.extOrTrunc(S.getCtx().getTypeSize(ResultType));
755 if (!APSInt::isSameValue(Temp,
Result))
763 assert(
Func->getDecl()->getReturnType()->isBooleanType());
773 unsigned BuiltinOp =
Func->getBuiltinID();
774 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
775 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
776 PrimType CarryT = *S.getContext().classify(
Call->getArg(2)->getType());
793 bool FirstOverflowed =
false;
794 bool SecondOverflowed =
false;
797 llvm_unreachable(
"Invalid value for BuiltinOp");
798 case Builtin::BI__builtin_addcb:
799 case Builtin::BI__builtin_addcs:
800 case Builtin::BI__builtin_addc:
801 case Builtin::BI__builtin_addcl:
802 case Builtin::BI__builtin_addcll:
804 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
806 case Builtin::BI__builtin_subcb:
807 case Builtin::BI__builtin_subcs:
808 case Builtin::BI__builtin_subc:
809 case Builtin::BI__builtin_subcl:
810 case Builtin::BI__builtin_subcll:
812 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
817 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
820 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
821 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
825 assert(
Call->getType() ==
Call->getArg(0)->getType());
834 unsigned BuiltinOp =
Func->getBuiltinID();
835 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
840 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
841 BuiltinOp != Builtin::BI__lzcnt &&
842 BuiltinOp != Builtin::BI__lzcnt64;
845 if (
Func->getBuiltinID() == Builtin::BI__builtin_clzg &&
846 Call->getNumArgs() == 2) {
848 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
866 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
870 if (
Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&
871 Call->getNumArgs() == 2) {
873 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
888 PrimType ReturnT = *S.getContext().classify(
Call->getType());
889 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
891 assert(Val.getActiveBits() <= 64);
894 { S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
905 unsigned BuiltinOp =
Func->getBuiltinID();
907 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
908 unsigned SizeValOffset = 0;
909 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
913 auto returnBool = [&S](
bool Value) ->
bool {
929 if (Size.isPowerOfTwo()) {
931 unsigned InlineWidthBits =
932 S.getCtx().getTargetInfo().getMaxAtomicInlineWidth();
933 if (Size <= S.getCtx().toCharUnitsFromBits(InlineWidthBits)) {
937 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
939 return returnBool(
true);
942 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
945 return returnBool(
true);
949 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
950 return returnBool(
true);
953 const Expr *PtrArg =
Call->getArg(1);
955 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
958 if (ICE->getCastKind() == CK_BitCast)
959 PtrArg = ICE->getSubExpr();
965 S.getCtx().getTypeAlignInChars(PointeeType) >= Size) {
967 return returnBool(
true);
973 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
974 return returnBool(
false);
990 Result.atIndex(0).initialize();
992 Result.atIndex(1).initialize();
1007 unsigned BuiltinOp =
Func->getBuiltinID();
1010 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1013 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1014 S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1017 unsigned SrcWidth = S.getCtx().getIntWidth(
Call->getArg(0)->getType());
1018 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1019 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1020 S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1021 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1031 APSInt Align = Alignment.extOrTrunc(Src.getBitWidth());
1032 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1034 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
1036 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1037 APSInt AlignedVal =
APSInt(Src & ~(Align - 1), Src.isUnsigned());
1040 assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1041 S.Stk.push<
Boolean>((Src & (Align - 1)) == 0);
1046 assert(FirstArgT ==
PT_Ptr);
1056 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1071 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1076 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1077 BuiltinOp == Builtin::BI__builtin_align_up);
1092 assert(Alignment.getBitWidth() <= 64 &&
1093 "Cannot handle > 64-bit address-space");
1094 uint64_t Alignment64 = Alignment.getZExtValue();
1097 ? llvm::alignDown(PtrOffset, Alignment64)
1098 : llvm::alignTo(PtrOffset, Alignment64));
1105 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1123 const auto &Ptr = S.Stk.peek<
Pointer>();
1124 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1126 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1127 uint64_t
Result = getPointerAuthStableSipHash(R);
1143 auto returnInt = [&S,
Call](
bool Value) ->
bool {
1167 auto Res =
C.interpretExpr(Arg, Arg->
isGLValue());
1168 if (Res.isInvalid()) {
1173 if (!Res.isInvalid() && !Res.empty()) {
1174 const APValue &LV = Res.toAPValue();
1177 if (
Base.isNull()) {
1179 return returnInt(
true);
1180 }
else if (
const auto *
E =
Base.dyn_cast<
const Expr *>()) {
1181 if (!isa<StringLiteral>(
E))
1182 return returnInt(
false);
1187 return returnInt(
true);
1190 return returnInt(
false);
1196 return returnInt(
true);
1199 return returnInt(
false);
1207 std::optional<PrimType> ReturnT = S.getContext().classify(
Call);
1210 case Builtin::BI__builtin_is_constant_evaluated:
1214 case Builtin::BI__builtin_assume:
1215 case Builtin::BI__assume:
1217 case Builtin::BI__builtin_strcmp:
1221 case Builtin::BI__builtin_strlen:
1225 case Builtin::BI__builtin_nan:
1226 case Builtin::BI__builtin_nanf:
1227 case Builtin::BI__builtin_nanl:
1228 case Builtin::BI__builtin_nanf16:
1229 case Builtin::BI__builtin_nanf128:
1233 case Builtin::BI__builtin_nans:
1234 case Builtin::BI__builtin_nansf:
1235 case Builtin::BI__builtin_nansl:
1236 case Builtin::BI__builtin_nansf16:
1237 case Builtin::BI__builtin_nansf128:
1242 case Builtin::BI__builtin_huge_val:
1243 case Builtin::BI__builtin_huge_valf:
1244 case Builtin::BI__builtin_huge_vall:
1245 case Builtin::BI__builtin_huge_valf16:
1246 case Builtin::BI__builtin_huge_valf128:
1247 case Builtin::BI__builtin_inf:
1248 case Builtin::BI__builtin_inff:
1249 case Builtin::BI__builtin_infl:
1250 case Builtin::BI__builtin_inff16:
1251 case Builtin::BI__builtin_inff128:
1255 case Builtin::BI__builtin_copysign:
1256 case Builtin::BI__builtin_copysignf:
1257 case Builtin::BI__builtin_copysignl:
1258 case Builtin::BI__builtin_copysignf128:
1263 case Builtin::BI__builtin_fmin:
1264 case Builtin::BI__builtin_fminf:
1265 case Builtin::BI__builtin_fminl:
1266 case Builtin::BI__builtin_fminf16:
1267 case Builtin::BI__builtin_fminf128:
1272 case Builtin::BI__builtin_fmax:
1273 case Builtin::BI__builtin_fmaxf:
1274 case Builtin::BI__builtin_fmaxl:
1275 case Builtin::BI__builtin_fmaxf16:
1276 case Builtin::BI__builtin_fmaxf128:
1281 case Builtin::BI__builtin_isnan:
1285 case Builtin::BI__builtin_issignaling:
1290 case Builtin::BI__builtin_isinf:
1295 case Builtin::BI__builtin_isinf_sign:
1300 case Builtin::BI__builtin_isfinite:
1304 case Builtin::BI__builtin_isnormal:
1308 case Builtin::BI__builtin_issubnormal:
1312 case Builtin::BI__builtin_iszero:
1316 case Builtin::BI__builtin_isfpclass:
1320 case Builtin::BI__builtin_fpclassify:
1325 case Builtin::BI__builtin_fabs:
1326 case Builtin::BI__builtin_fabsf:
1327 case Builtin::BI__builtin_fabsl:
1328 case Builtin::BI__builtin_fabsf128:
1333 case Builtin::BI__builtin_popcount:
1334 case Builtin::BI__builtin_popcountl:
1335 case Builtin::BI__builtin_popcountll:
1336 case Builtin::BI__builtin_popcountg:
1337 case Builtin::BI__popcnt16:
1338 case Builtin::BI__popcnt:
1339 case Builtin::BI__popcnt64:
1344 case Builtin::BI__builtin_parity:
1345 case Builtin::BI__builtin_parityl:
1346 case Builtin::BI__builtin_parityll:
1351 case Builtin::BI__builtin_clrsb:
1352 case Builtin::BI__builtin_clrsbl:
1353 case Builtin::BI__builtin_clrsbll:
1358 case Builtin::BI__builtin_bitreverse8:
1359 case Builtin::BI__builtin_bitreverse16:
1360 case Builtin::BI__builtin_bitreverse32:
1361 case Builtin::BI__builtin_bitreverse64:
1366 case Builtin::BI__builtin_classify_type:
1371 case Builtin::BI__builtin_expect:
1372 case Builtin::BI__builtin_expect_with_probability:
1377 case Builtin::BI__builtin_rotateleft8:
1378 case Builtin::BI__builtin_rotateleft16:
1379 case Builtin::BI__builtin_rotateleft32:
1380 case Builtin::BI__builtin_rotateleft64:
1381 case Builtin::BI_rotl8:
1382 case Builtin::BI_rotl16:
1383 case Builtin::BI_rotl:
1384 case Builtin::BI_lrotl:
1385 case Builtin::BI_rotl64:
1390 case Builtin::BI__builtin_rotateright8:
1391 case Builtin::BI__builtin_rotateright16:
1392 case Builtin::BI__builtin_rotateright32:
1393 case Builtin::BI__builtin_rotateright64:
1394 case Builtin::BI_rotr8:
1395 case Builtin::BI_rotr16:
1396 case Builtin::BI_rotr:
1397 case Builtin::BI_lrotr:
1398 case Builtin::BI_rotr64:
1403 case Builtin::BI__builtin_ffs:
1404 case Builtin::BI__builtin_ffsl:
1405 case Builtin::BI__builtin_ffsll:
1409 case Builtin::BIaddressof:
1410 case Builtin::BI__addressof:
1411 case Builtin::BI__builtin_addressof:
1416 case Builtin::BIas_const:
1417 case Builtin::BIforward:
1418 case Builtin::BIforward_like:
1419 case Builtin::BImove:
1420 case Builtin::BImove_if_noexcept:
1425 case Builtin::BI__builtin_eh_return_data_regno:
1430 case Builtin::BI__builtin_launder:
1435 case Builtin::BI__builtin_add_overflow:
1436 case Builtin::BI__builtin_sub_overflow:
1437 case Builtin::BI__builtin_mul_overflow:
1438 case Builtin::BI__builtin_sadd_overflow:
1439 case Builtin::BI__builtin_uadd_overflow:
1440 case Builtin::BI__builtin_uaddl_overflow:
1441 case Builtin::BI__builtin_uaddll_overflow:
1442 case Builtin::BI__builtin_usub_overflow:
1443 case Builtin::BI__builtin_usubl_overflow:
1444 case Builtin::BI__builtin_usubll_overflow:
1445 case Builtin::BI__builtin_umul_overflow:
1446 case Builtin::BI__builtin_umull_overflow:
1447 case Builtin::BI__builtin_umulll_overflow:
1448 case Builtin::BI__builtin_saddl_overflow:
1449 case Builtin::BI__builtin_saddll_overflow:
1450 case Builtin::BI__builtin_ssub_overflow:
1451 case Builtin::BI__builtin_ssubl_overflow:
1452 case Builtin::BI__builtin_ssubll_overflow:
1453 case Builtin::BI__builtin_smul_overflow:
1454 case Builtin::BI__builtin_smull_overflow:
1455 case Builtin::BI__builtin_smulll_overflow:
1460 case Builtin::BI__builtin_addcb:
1461 case Builtin::BI__builtin_addcs:
1462 case Builtin::BI__builtin_addc:
1463 case Builtin::BI__builtin_addcl:
1464 case Builtin::BI__builtin_addcll:
1465 case Builtin::BI__builtin_subcb:
1466 case Builtin::BI__builtin_subcs:
1467 case Builtin::BI__builtin_subc:
1468 case Builtin::BI__builtin_subcl:
1469 case Builtin::BI__builtin_subcll:
1474 case Builtin::BI__builtin_clz:
1475 case Builtin::BI__builtin_clzl:
1476 case Builtin::BI__builtin_clzll:
1477 case Builtin::BI__builtin_clzs:
1478 case Builtin::BI__builtin_clzg:
1479 case Builtin::BI__lzcnt16:
1480 case Builtin::BI__lzcnt:
1481 case Builtin::BI__lzcnt64:
1486 case Builtin::BI__builtin_ctz:
1487 case Builtin::BI__builtin_ctzl:
1488 case Builtin::BI__builtin_ctzll:
1489 case Builtin::BI__builtin_ctzs:
1490 case Builtin::BI__builtin_ctzg:
1495 case Builtin::BI__builtin_bswap16:
1496 case Builtin::BI__builtin_bswap32:
1497 case Builtin::BI__builtin_bswap64:
1502 case Builtin::BI__atomic_always_lock_free:
1503 case Builtin::BI__atomic_is_lock_free:
1504 case Builtin::BI__c11_atomic_is_lock_free:
1509 case Builtin::BI__builtin_complex:
1514 case Builtin::BI__builtin_is_aligned:
1515 case Builtin::BI__builtin_align_up:
1516 case Builtin::BI__builtin_align_down:
1521 case Builtin::BI__builtin_os_log_format_buffer_size:
1526 case Builtin::BI__builtin_ptrauth_string_discriminator:
1531 case Builtin::BI__builtin_constant_p:
1537 S.FFDiag(S.Current->getLocation(OpPC),
1538 diag::note_invalid_subexpr_in_const_expr)
1539 << S.Current->getRange(OpPC);
1549 int64_t &IntResult) {
1551 unsigned N =
E->getNumComponents();
1554 unsigned ArrayIndex = 0;
1556 for (
unsigned I = 0; I != N; ++I) {
1558 switch (
Node.getKind()) {
1569 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
1577 int64_t Index = ArrayIndices[ArrayIndex];
1578 const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType);
1582 CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType);
1583 Result += Index * ElementSize;
1602 CurrentType = BaseSpec->
getType();
1612 llvm_unreachable(
"Dependent OffsetOfExpr?");
1616 IntResult =
Result.getQuantity();
1633 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
1638static bool copyComposite(InterpState &S, CodePtr OpPC,
const Pointer &Src,
1639 Pointer &Dest,
bool Activate);
1641 Pointer &Dest,
bool Activate =
false) {
1645 auto copyField = [&](
const Record::Field &F,
bool Activate) ->
bool {
1647 if (std::optional<PrimType> FT = S.Ctx.classify(F.Decl->getType())) {
1664 for (
const Record::Field &F : R->
fields()) {
1669 if (!copyField(F,
true))
1673 if (!copyField(F, Activate))
1678 for (
const Record::Base &B : R->
bases()) {
1689 Pointer &Dest,
bool Activate =
false) {
1701 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
1712 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
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.
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.
unsigned getByteOffset() const
Returns the byte offset from the start.
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)
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_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.
@ 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.