8#include "../ExprConstShared.h"
16#include "llvm/Support/SipHash.h"
24 for (
const Expr *
E :
C->arguments()) {
33 assert(
Frame->getFunction()->getNumParams() > Index);
34 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
35 return Frame->getParam<
T>(Offset);
39 const TargetInfo &TI = S.getCtx().getTargetInfo();
44 else if (IntWidth == 16)
46 llvm_unreachable(
"Int isn't 16 or 32 bit?");
50 const TargetInfo &TI = S.getCtx().getTargetInfo();
55 else if (LongWidth == 32)
57 else if (LongWidth == 16)
59 llvm_unreachable(
"long isn't 16, 32 or 64 bit?");
77 std::optional<PrimType>
T = S.getContext().classify(QT);
81 int64_t
V = Val.getSExtValue();
85 uint64_t
V = Val.getZExtValue();
92 if constexpr (std::is_same_v<T, APInt>)
98 !std::is_signed_v<T>),
104 ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
108 std::optional<PrimType> &
T) {
114 return Ret<X>(S, OpPC, Result);
129 llvm_unreachable(
"Unsupported return type for builtin function");
139 if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
140 Frame->Caller && S.getEvalStatus().
Diag) {
142 return F && F->isInStdNamespace() && F->getIdentifier() &&
143 F->getIdentifier()->isStr(
"is_constant_evaluated");
150 diag::warn_is_constant_evaluated_always_true_constexpr)
155 diag::warn_is_constant_evaluated_always_true_constexpr)
182 for (;; ++IndexA, ++IndexB) {
189 uint8_t CA = PA.
deref<uint8_t>();
190 uint8_t CB = PB.
deref<uint8_t>();
195 }
else if (CA < CB) {
199 if (CA == 0 || CB == 0)
224 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
230 uint8_t Val = ElemPtr.
deref<uint8_t>();
254 for (
unsigned I = 0;; ++I) {
260 if (Elem.
deref<int8_t>() == 0)
263 Str += Elem.
deref<
char>();
268 Fill = llvm::APInt(32, 0);
269 else if (StringRef(Str).getAsInteger(0, Fill))
272 const llvm::fltSemantics &TargetSemantics =
276 if (S.getCtx().getTargetInfo().isNan2008()) {
279 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
282 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
291 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
294 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
303 const llvm::fltSemantics &TargetSemantics =
333 else if (LHS.
isNan() || RHS < LHS)
353 else if (LHS.
isNan() || RHS > LHS)
388 bool IsInf = Arg.
isInf();
440 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
446 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
464 case APFloat::fcInfinity:
467 case APFloat::fcNormal:
470 case APFloat::fcZero:
504 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
513 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
522 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
524 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
532 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
543 assert(
Call->getNumArgs() == 1);
548 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
560 unsigned NumArgs =
Call->getNumArgs();
561 assert(NumArgs == 2 || NumArgs == 3);
563 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
578 PrimType AmountT = *S.getContext().classify(
Call->getArg(1)->getType());
579 PrimType ValueT = *S.getContext().classify(
Call->getArg(0)->getType());
600 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
603 uint64_t N =
Value.countr_zero();
612 assert(
Call->getArg(0)->isLValue());
618 }
else if (PtrT ==
PT_Ptr) {
622 assert(
false &&
"Unsupported pointer type passed to __builtin_addressof()");
633 TYPE_SWITCH(ArgT,
const T &Arg = S.Stk.peek<
T>(); S.Stk.push<
T>(Arg););
635 return Func->getDecl()->isConstexpr();
642 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
646 S.getCtx().getTargetInfo().getEHDataRegisterNumber(Arg.getZExtValue());
668 unsigned BuiltinOp =
Func->getBuiltinID();
669 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
670 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
676 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
677 PrimType ResultT = *S.getContext().classify(ResultType);
681 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
682 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
683 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
684 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
686 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
688 uint64_t LHSSize = LHS.getBitWidth();
689 uint64_t RHSSize = RHS.getBitWidth();
690 uint64_t ResultSize = S.getCtx().getTypeSize(ResultType);
691 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
697 if (IsSigned && !AllSigned)
700 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
701 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
708 llvm_unreachable(
"Invalid value for BuiltinOp");
709 case Builtin::BI__builtin_add_overflow:
710 case Builtin::BI__builtin_sadd_overflow:
711 case Builtin::BI__builtin_saddl_overflow:
712 case Builtin::BI__builtin_saddll_overflow:
713 case Builtin::BI__builtin_uadd_overflow:
714 case Builtin::BI__builtin_uaddl_overflow:
715 case Builtin::BI__builtin_uaddll_overflow:
716 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
717 : LHS.uadd_ov(RHS, Overflow);
719 case Builtin::BI__builtin_sub_overflow:
720 case Builtin::BI__builtin_ssub_overflow:
721 case Builtin::BI__builtin_ssubl_overflow:
722 case Builtin::BI__builtin_ssubll_overflow:
723 case Builtin::BI__builtin_usub_overflow:
724 case Builtin::BI__builtin_usubl_overflow:
725 case Builtin::BI__builtin_usubll_overflow:
726 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
727 : LHS.usub_ov(RHS, Overflow);
729 case Builtin::BI__builtin_mul_overflow:
730 case Builtin::BI__builtin_smul_overflow:
731 case Builtin::BI__builtin_smull_overflow:
732 case Builtin::BI__builtin_smulll_overflow:
733 case Builtin::BI__builtin_umul_overflow:
734 case Builtin::BI__builtin_umull_overflow:
735 case Builtin::BI__builtin_umulll_overflow:
736 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
737 : LHS.umul_ov(RHS, Overflow);
743 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
744 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
745 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
750 APSInt Temp =
Result.extOrTrunc(S.getCtx().getTypeSize(ResultType));
753 if (!APSInt::isSameValue(Temp,
Result))
761 assert(
Func->getDecl()->getReturnType()->isBooleanType());
771 unsigned BuiltinOp =
Func->getBuiltinID();
772 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
773 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
774 PrimType CarryT = *S.getContext().classify(
Call->getArg(2)->getType());
791 bool FirstOverflowed =
false;
792 bool SecondOverflowed =
false;
795 llvm_unreachable(
"Invalid value for BuiltinOp");
796 case Builtin::BI__builtin_addcb:
797 case Builtin::BI__builtin_addcs:
798 case Builtin::BI__builtin_addc:
799 case Builtin::BI__builtin_addcl:
800 case Builtin::BI__builtin_addcll:
802 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
804 case Builtin::BI__builtin_subcb:
805 case Builtin::BI__builtin_subcs:
806 case Builtin::BI__builtin_subc:
807 case Builtin::BI__builtin_subcl:
808 case Builtin::BI__builtin_subcll:
810 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
815 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
818 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
819 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
823 assert(
Call->getType() ==
Call->getArg(0)->getType());
832 unsigned BuiltinOp =
Func->getBuiltinID();
833 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
838 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
839 BuiltinOp != Builtin::BI__lzcnt &&
840 BuiltinOp != Builtin::BI__lzcnt64;
843 if (
Func->getBuiltinID() == Builtin::BI__builtin_clzg &&
844 Call->getNumArgs() == 2) {
846 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
864 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
868 if (
Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&
869 Call->getNumArgs() == 2) {
871 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
886 PrimType ReturnT = *S.getContext().classify(
Call->getType());
887 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
889 assert(Val.getActiveBits() <= 64);
892 { S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
903 unsigned BuiltinOp =
Func->getBuiltinID();
905 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
906 unsigned SizeValOffset = 0;
907 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
911 auto returnBool = [&S](
bool Value) ->
bool {
927 if (Size.isPowerOfTwo()) {
929 unsigned InlineWidthBits =
930 S.getCtx().getTargetInfo().getMaxAtomicInlineWidth();
931 if (Size <= S.getCtx().toCharUnitsFromBits(InlineWidthBits)) {
935 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
937 return returnBool(
true);
940 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
943 return returnBool(
true);
947 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
948 return returnBool(
true);
951 const Expr *PtrArg =
Call->getArg(1);
953 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
956 if (ICE->getCastKind() == CK_BitCast)
957 PtrArg = ICE->getSubExpr();
963 S.getCtx().getTypeAlignInChars(PointeeType) >= Size) {
965 return returnBool(
true);
971 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
972 return returnBool(
false);
988 Result.atIndex(0).initialize();
990 Result.atIndex(1).initialize();
1005 unsigned BuiltinOp =
Func->getBuiltinID();
1008 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1011 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1012 S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1015 unsigned SrcWidth = S.getCtx().getIntWidth(
Call->getArg(0)->getType());
1016 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1017 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1018 S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1019 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1029 APSInt Align = Alignment.extOrTrunc(Src.getBitWidth());
1030 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1032 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
1034 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1035 APSInt AlignedVal =
APSInt(Src & ~(Align - 1), Src.isUnsigned());
1038 assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1039 S.Stk.push<
Boolean>((Src & (Align - 1)) == 0);
1044 assert(FirstArgT ==
PT_Ptr);
1054 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1069 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1074 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1075 BuiltinOp == Builtin::BI__builtin_align_up);
1090 assert(Alignment.getBitWidth() <= 64 &&
1091 "Cannot handle > 64-bit address-space");
1092 uint64_t Alignment64 = Alignment.getZExtValue();
1095 ? llvm::alignDown(PtrOffset, Alignment64)
1096 : llvm::alignTo(PtrOffset, Alignment64));
1103 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1121 const auto &Ptr = S.Stk.peek<
Pointer>();
1122 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1124 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1125 uint64_t
Result = getPointerAuthStableSipHash(R);
1135 std::optional<PrimType> ReturnT = S.getContext().classify(
Call);
1138 case Builtin::BI__builtin_is_constant_evaluated:
1142 case Builtin::BI__builtin_assume:
1143 case Builtin::BI__assume:
1145 case Builtin::BI__builtin_strcmp:
1149 case Builtin::BI__builtin_strlen:
1153 case Builtin::BI__builtin_nan:
1154 case Builtin::BI__builtin_nanf:
1155 case Builtin::BI__builtin_nanl:
1156 case Builtin::BI__builtin_nanf16:
1157 case Builtin::BI__builtin_nanf128:
1161 case Builtin::BI__builtin_nans:
1162 case Builtin::BI__builtin_nansf:
1163 case Builtin::BI__builtin_nansl:
1164 case Builtin::BI__builtin_nansf16:
1165 case Builtin::BI__builtin_nansf128:
1170 case Builtin::BI__builtin_huge_val:
1171 case Builtin::BI__builtin_huge_valf:
1172 case Builtin::BI__builtin_huge_vall:
1173 case Builtin::BI__builtin_huge_valf16:
1174 case Builtin::BI__builtin_huge_valf128:
1175 case Builtin::BI__builtin_inf:
1176 case Builtin::BI__builtin_inff:
1177 case Builtin::BI__builtin_infl:
1178 case Builtin::BI__builtin_inff16:
1179 case Builtin::BI__builtin_inff128:
1183 case Builtin::BI__builtin_copysign:
1184 case Builtin::BI__builtin_copysignf:
1185 case Builtin::BI__builtin_copysignl:
1186 case Builtin::BI__builtin_copysignf128:
1191 case Builtin::BI__builtin_fmin:
1192 case Builtin::BI__builtin_fminf:
1193 case Builtin::BI__builtin_fminl:
1194 case Builtin::BI__builtin_fminf16:
1195 case Builtin::BI__builtin_fminf128:
1200 case Builtin::BI__builtin_fmax:
1201 case Builtin::BI__builtin_fmaxf:
1202 case Builtin::BI__builtin_fmaxl:
1203 case Builtin::BI__builtin_fmaxf16:
1204 case Builtin::BI__builtin_fmaxf128:
1209 case Builtin::BI__builtin_isnan:
1213 case Builtin::BI__builtin_issignaling:
1218 case Builtin::BI__builtin_isinf:
1223 case Builtin::BI__builtin_isinf_sign:
1228 case Builtin::BI__builtin_isfinite:
1232 case Builtin::BI__builtin_isnormal:
1236 case Builtin::BI__builtin_issubnormal:
1240 case Builtin::BI__builtin_iszero:
1244 case Builtin::BI__builtin_isfpclass:
1248 case Builtin::BI__builtin_fpclassify:
1253 case Builtin::BI__builtin_fabs:
1254 case Builtin::BI__builtin_fabsf:
1255 case Builtin::BI__builtin_fabsl:
1256 case Builtin::BI__builtin_fabsf128:
1261 case Builtin::BI__builtin_popcount:
1262 case Builtin::BI__builtin_popcountl:
1263 case Builtin::BI__builtin_popcountll:
1264 case Builtin::BI__builtin_popcountg:
1265 case Builtin::BI__popcnt16:
1266 case Builtin::BI__popcnt:
1267 case Builtin::BI__popcnt64:
1272 case Builtin::BI__builtin_parity:
1273 case Builtin::BI__builtin_parityl:
1274 case Builtin::BI__builtin_parityll:
1279 case Builtin::BI__builtin_clrsb:
1280 case Builtin::BI__builtin_clrsbl:
1281 case Builtin::BI__builtin_clrsbll:
1286 case Builtin::BI__builtin_bitreverse8:
1287 case Builtin::BI__builtin_bitreverse16:
1288 case Builtin::BI__builtin_bitreverse32:
1289 case Builtin::BI__builtin_bitreverse64:
1294 case Builtin::BI__builtin_classify_type:
1299 case Builtin::BI__builtin_expect:
1300 case Builtin::BI__builtin_expect_with_probability:
1305 case Builtin::BI__builtin_rotateleft8:
1306 case Builtin::BI__builtin_rotateleft16:
1307 case Builtin::BI__builtin_rotateleft32:
1308 case Builtin::BI__builtin_rotateleft64:
1309 case Builtin::BI_rotl8:
1310 case Builtin::BI_rotl16:
1311 case Builtin::BI_rotl:
1312 case Builtin::BI_lrotl:
1313 case Builtin::BI_rotl64:
1318 case Builtin::BI__builtin_rotateright8:
1319 case Builtin::BI__builtin_rotateright16:
1320 case Builtin::BI__builtin_rotateright32:
1321 case Builtin::BI__builtin_rotateright64:
1322 case Builtin::BI_rotr8:
1323 case Builtin::BI_rotr16:
1324 case Builtin::BI_rotr:
1325 case Builtin::BI_lrotr:
1326 case Builtin::BI_rotr64:
1331 case Builtin::BI__builtin_ffs:
1332 case Builtin::BI__builtin_ffsl:
1333 case Builtin::BI__builtin_ffsll:
1337 case Builtin::BIaddressof:
1338 case Builtin::BI__addressof:
1339 case Builtin::BI__builtin_addressof:
1344 case Builtin::BIas_const:
1345 case Builtin::BIforward:
1346 case Builtin::BIforward_like:
1347 case Builtin::BImove:
1348 case Builtin::BImove_if_noexcept:
1353 case Builtin::BI__builtin_eh_return_data_regno:
1358 case Builtin::BI__builtin_launder:
1363 case Builtin::BI__builtin_add_overflow:
1364 case Builtin::BI__builtin_sub_overflow:
1365 case Builtin::BI__builtin_mul_overflow:
1366 case Builtin::BI__builtin_sadd_overflow:
1367 case Builtin::BI__builtin_uadd_overflow:
1368 case Builtin::BI__builtin_uaddl_overflow:
1369 case Builtin::BI__builtin_uaddll_overflow:
1370 case Builtin::BI__builtin_usub_overflow:
1371 case Builtin::BI__builtin_usubl_overflow:
1372 case Builtin::BI__builtin_usubll_overflow:
1373 case Builtin::BI__builtin_umul_overflow:
1374 case Builtin::BI__builtin_umull_overflow:
1375 case Builtin::BI__builtin_umulll_overflow:
1376 case Builtin::BI__builtin_saddl_overflow:
1377 case Builtin::BI__builtin_saddll_overflow:
1378 case Builtin::BI__builtin_ssub_overflow:
1379 case Builtin::BI__builtin_ssubl_overflow:
1380 case Builtin::BI__builtin_ssubll_overflow:
1381 case Builtin::BI__builtin_smul_overflow:
1382 case Builtin::BI__builtin_smull_overflow:
1383 case Builtin::BI__builtin_smulll_overflow:
1388 case Builtin::BI__builtin_addcb:
1389 case Builtin::BI__builtin_addcs:
1390 case Builtin::BI__builtin_addc:
1391 case Builtin::BI__builtin_addcl:
1392 case Builtin::BI__builtin_addcll:
1393 case Builtin::BI__builtin_subcb:
1394 case Builtin::BI__builtin_subcs:
1395 case Builtin::BI__builtin_subc:
1396 case Builtin::BI__builtin_subcl:
1397 case Builtin::BI__builtin_subcll:
1402 case Builtin::BI__builtin_clz:
1403 case Builtin::BI__builtin_clzl:
1404 case Builtin::BI__builtin_clzll:
1405 case Builtin::BI__builtin_clzs:
1406 case Builtin::BI__builtin_clzg:
1407 case Builtin::BI__lzcnt16:
1408 case Builtin::BI__lzcnt:
1409 case Builtin::BI__lzcnt64:
1414 case Builtin::BI__builtin_ctz:
1415 case Builtin::BI__builtin_ctzl:
1416 case Builtin::BI__builtin_ctzll:
1417 case Builtin::BI__builtin_ctzs:
1418 case Builtin::BI__builtin_ctzg:
1423 case Builtin::BI__builtin_bswap16:
1424 case Builtin::BI__builtin_bswap32:
1425 case Builtin::BI__builtin_bswap64:
1430 case Builtin::BI__atomic_always_lock_free:
1431 case Builtin::BI__atomic_is_lock_free:
1432 case Builtin::BI__c11_atomic_is_lock_free:
1437 case Builtin::BI__builtin_complex:
1442 case Builtin::BI__builtin_is_aligned:
1443 case Builtin::BI__builtin_align_up:
1444 case Builtin::BI__builtin_align_down:
1449 case Builtin::BI__builtin_os_log_format_buffer_size:
1454 case Builtin::BI__builtin_ptrauth_string_discriminator:
1460 S.FFDiag(S.Current->getLocation(OpPC),
1461 diag::note_invalid_subexpr_in_const_expr)
1462 << S.Current->getRange(OpPC);
1472 int64_t &IntResult) {
1474 unsigned N =
E->getNumComponents();
1477 unsigned ArrayIndex = 0;
1479 for (
unsigned I = 0; I != N; ++I) {
1481 switch (
Node.getKind()) {
1492 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
1500 int64_t Index = ArrayIndices[ArrayIndex];
1501 const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType);
1505 CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType);
1506 Result += Index * ElementSize;
1525 CurrentType = BaseSpec->
getType();
1535 llvm_unreachable(
"Dependent OffsetOfExpr?");
1539 IntResult =
Result.getQuantity();
1556 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
1573 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
1587 for (
const Record::Field &F : R->
fields()) {
1589 if (std::optional<PrimType> FT = S.Ctx.classify(F.Decl->getType())) {
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],...
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?
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,...
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 ...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAs() const
Member-template getAs<specific type>'.
Wrapper around boolean types.
static Boolean from(T Value)
Pointer into the code segment.
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.
T & peek() const
Returns a reference to the value on the top of the stack.
A pointer to a memory block, live or dead.
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.
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.
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.
const Field * getField(const FieldDecl *FD) const
Returns a field.
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_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 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.