8#include "../ExprConstShared.h"
23 for (
const Expr *E :
C->arguments()) {
32 assert(
Frame->getFunction()->getNumParams() > Index);
33 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
34 return Frame->getParam<
T>(Offset);
38 const TargetInfo &TI = S.getCtx().getTargetInfo();
43 else if (IntWidth == 16)
45 llvm_unreachable(
"Int isn't 16 or 32 bit?");
49 const TargetInfo &TI = S.getCtx().getTargetInfo();
54 else if (LongWidth == 32)
56 else if (LongWidth == 16)
58 llvm_unreachable(
"long isn't 16, 32 or 64 bit?");
76 std::optional<PrimType>
T = S.getContext().classify(QT);
80 int64_t
V = Val.getSExtValue();
84 uint64_t
V = Val.getZExtValue();
91 if constexpr (std::is_same_v<T, APInt>)
97 !std::is_signed_v<T>),
103 ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
107 std::optional<PrimType> &
T) {
113 return Ret<X>(S, OpPC, Result);
128 llvm_unreachable(
"Unsupported return type for builtin function");
138 if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
139 Frame->Caller && S.getEvalStatus().
Diag) {
141 return F && F->isInStdNamespace() && F->getIdentifier() &&
142 F->getIdentifier()->isStr(
"is_constant_evaluated");
149 diag::warn_is_constant_evaluated_always_true_constexpr)
150 <<
"std::is_constant_evaluated";
154 diag::warn_is_constant_evaluated_always_true_constexpr)
155 <<
"__builtin_is_constant_evaluated";
181 for (;; ++IndexA, ++IndexB) {
188 uint8_t CA = PA.
deref<uint8_t>();
189 uint8_t CB = PB.
deref<uint8_t>();
194 }
else if (CA < CB) {
198 if (CA == 0 || CB == 0)
223 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
229 uint8_t Val = ElemPtr.
deref<uint8_t>();
253 for (
unsigned I = 0;; ++I) {
259 if (Elem.
deref<int8_t>() == 0)
262 Str += Elem.
deref<
char>();
267 Fill = llvm::APInt(32, 0);
268 else if (StringRef(Str).getAsInteger(0, Fill))
271 const llvm::fltSemantics &TargetSemantics =
275 if (S.getCtx().getTargetInfo().isNan2008()) {
278 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
281 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
290 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
293 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
302 const llvm::fltSemantics &TargetSemantics =
332 else if (LHS.
isNan() || RHS < LHS)
352 else if (LHS.
isNan() || RHS > LHS)
387 bool IsInf = Arg.
isInf();
439 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
445 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
463 case APFloat::fcInfinity:
466 case APFloat::fcNormal:
469 case APFloat::fcZero:
503 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
512 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
521 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
523 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
531 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
542 assert(
Call->getNumArgs() == 1);
547 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
559 unsigned NumArgs =
Call->getNumArgs();
560 assert(NumArgs == 2 || NumArgs == 3);
562 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
577 PrimType AmountT = *S.getContext().classify(
Call->getArg(1)->getType());
578 PrimType ValueT = *S.getContext().classify(
Call->getArg(0)->getType());
599 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
602 uint64_t N =
Value.countr_zero();
612 S.getContext().classify(
Call->getArg(0)->getType()).value_or(
PT_Ptr);
617 }
else if (PtrT ==
PT_Ptr) {
621 assert(
false &&
"Unsupported pointer type passed to __builtin_addressof()");
632 TYPE_SWITCH(ArgT,
const T &Arg = S.Stk.peek<
T>(); S.Stk.push<
T>(Arg););
634 return Func->getDecl()->isConstexpr();
641 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
645 S.getCtx().getTargetInfo().getEHDataRegisterNumber(Arg.getZExtValue());
667 unsigned BuiltinOp =
Func->getBuiltinID();
668 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
669 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
675 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
676 PrimType ResultT = *S.getContext().classify(ResultType);
680 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
681 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
682 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
683 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
685 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
687 uint64_t LHSSize = LHS.getBitWidth();
688 uint64_t RHSSize = RHS.getBitWidth();
689 uint64_t ResultSize = S.getCtx().getTypeSize(ResultType);
690 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
696 if (IsSigned && !AllSigned)
699 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
700 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
707 llvm_unreachable(
"Invalid value for BuiltinOp");
708 case Builtin::BI__builtin_add_overflow:
709 case Builtin::BI__builtin_sadd_overflow:
710 case Builtin::BI__builtin_saddl_overflow:
711 case Builtin::BI__builtin_saddll_overflow:
712 case Builtin::BI__builtin_uadd_overflow:
713 case Builtin::BI__builtin_uaddl_overflow:
714 case Builtin::BI__builtin_uaddll_overflow:
715 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
716 : LHS.uadd_ov(RHS, Overflow);
718 case Builtin::BI__builtin_sub_overflow:
719 case Builtin::BI__builtin_ssub_overflow:
720 case Builtin::BI__builtin_ssubl_overflow:
721 case Builtin::BI__builtin_ssubll_overflow:
722 case Builtin::BI__builtin_usub_overflow:
723 case Builtin::BI__builtin_usubl_overflow:
724 case Builtin::BI__builtin_usubll_overflow:
725 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
726 : LHS.usub_ov(RHS, Overflow);
728 case Builtin::BI__builtin_mul_overflow:
729 case Builtin::BI__builtin_smul_overflow:
730 case Builtin::BI__builtin_smull_overflow:
731 case Builtin::BI__builtin_smulll_overflow:
732 case Builtin::BI__builtin_umul_overflow:
733 case Builtin::BI__builtin_umull_overflow:
734 case Builtin::BI__builtin_umulll_overflow:
735 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
736 : LHS.umul_ov(RHS, Overflow);
742 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
743 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
744 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
749 APSInt Temp =
Result.extOrTrunc(S.getCtx().getTypeSize(ResultType));
752 if (!APSInt::isSameValue(Temp,
Result))
760 assert(
Func->getDecl()->getReturnType()->isBooleanType());
770 unsigned BuiltinOp =
Func->getBuiltinID();
771 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
772 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
773 PrimType CarryT = *S.getContext().classify(
Call->getArg(2)->getType());
790 bool FirstOverflowed =
false;
791 bool SecondOverflowed =
false;
794 llvm_unreachable(
"Invalid value for BuiltinOp");
795 case Builtin::BI__builtin_addcb:
796 case Builtin::BI__builtin_addcs:
797 case Builtin::BI__builtin_addc:
798 case Builtin::BI__builtin_addcl:
799 case Builtin::BI__builtin_addcll:
801 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
803 case Builtin::BI__builtin_subcb:
804 case Builtin::BI__builtin_subcs:
805 case Builtin::BI__builtin_subc:
806 case Builtin::BI__builtin_subcl:
807 case Builtin::BI__builtin_subcll:
809 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
814 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
817 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
818 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
822 assert(
Call->getType() ==
Call->getArg(0)->getType());
831 unsigned BuiltinOp =
Func->getBuiltinID();
832 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
837 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
838 BuiltinOp != Builtin::BI__lzcnt &&
839 BuiltinOp != Builtin::BI__lzcnt64;
842 if (
Func->getBuiltinID() == Builtin::BI__builtin_clzg &&
843 Call->getNumArgs() == 2) {
845 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
863 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
867 if (
Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&
868 Call->getNumArgs() == 2) {
870 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
885 PrimType ReturnT = *S.getContext().classify(
Call->getType());
886 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
888 assert(Val.getActiveBits() <= 64);
891 { S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
902 unsigned BuiltinOp =
Func->getBuiltinID();
904 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
905 unsigned SizeValOffset = 0;
906 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
910 auto returnBool = [&S](
bool Value) ->
bool {
926 if (Size.isPowerOfTwo()) {
928 unsigned InlineWidthBits =
929 S.getCtx().getTargetInfo().getMaxAtomicInlineWidth();
930 if (Size <= S.getCtx().toCharUnitsFromBits(InlineWidthBits)) {
934 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
936 return returnBool(
true);
939 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
942 return returnBool(
true);
951 S.getCtx().getTypeAlignInChars(PointeeType) >= Size)
952 return returnBool(
true);
956 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
957 return returnBool(
false);
973 Result.atIndex(0).initialize();
975 Result.atIndex(1).initialize();
990 unsigned BuiltinOp =
Func->getBuiltinID();
996 if (Alignment < 0 || !Alignment.isPowerOf2()) {
997 S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1000 unsigned SrcWidth = S.getCtx().getIntWidth(
Call->getArg(0)->getType());
1001 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1002 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1003 S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1004 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1014 APSInt Align = Alignment.extOrTrunc(Src.getBitWidth());
1015 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1017 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
1019 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1020 APSInt AlignedVal =
APSInt(Src & ~(Align - 1), Src.isUnsigned());
1023 assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1024 S.Stk.push<
Boolean>((Src & (Align - 1)) == 0);
1029 assert(FirstArgT ==
PT_Ptr);
1039 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1054 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1059 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1060 BuiltinOp == Builtin::BI__builtin_align_up);
1075 assert(Alignment.getBitWidth() <= 64 &&
1076 "Cannot handle > 64-bit address-space");
1077 uint64_t Alignment64 = Alignment.getZExtValue();
1080 ? llvm::alignDown(PtrOffset, Alignment64)
1081 : llvm::alignTo(PtrOffset, Alignment64));
1088 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1108 std::optional<PrimType> ReturnT = S.getContext().classify(
Call);
1111 case Builtin::BI__builtin_is_constant_evaluated:
1115 case Builtin::BI__builtin_assume:
1116 case Builtin::BI__assume:
1118 case Builtin::BI__builtin_strcmp:
1122 case Builtin::BI__builtin_strlen:
1126 case Builtin::BI__builtin_nan:
1127 case Builtin::BI__builtin_nanf:
1128 case Builtin::BI__builtin_nanl:
1129 case Builtin::BI__builtin_nanf16:
1130 case Builtin::BI__builtin_nanf128:
1134 case Builtin::BI__builtin_nans:
1135 case Builtin::BI__builtin_nansf:
1136 case Builtin::BI__builtin_nansl:
1137 case Builtin::BI__builtin_nansf16:
1138 case Builtin::BI__builtin_nansf128:
1143 case Builtin::BI__builtin_huge_val:
1144 case Builtin::BI__builtin_huge_valf:
1145 case Builtin::BI__builtin_huge_vall:
1146 case Builtin::BI__builtin_huge_valf16:
1147 case Builtin::BI__builtin_huge_valf128:
1148 case Builtin::BI__builtin_inf:
1149 case Builtin::BI__builtin_inff:
1150 case Builtin::BI__builtin_infl:
1151 case Builtin::BI__builtin_inff16:
1152 case Builtin::BI__builtin_inff128:
1156 case Builtin::BI__builtin_copysign:
1157 case Builtin::BI__builtin_copysignf:
1158 case Builtin::BI__builtin_copysignl:
1159 case Builtin::BI__builtin_copysignf128:
1164 case Builtin::BI__builtin_fmin:
1165 case Builtin::BI__builtin_fminf:
1166 case Builtin::BI__builtin_fminl:
1167 case Builtin::BI__builtin_fminf16:
1168 case Builtin::BI__builtin_fminf128:
1173 case Builtin::BI__builtin_fmax:
1174 case Builtin::BI__builtin_fmaxf:
1175 case Builtin::BI__builtin_fmaxl:
1176 case Builtin::BI__builtin_fmaxf16:
1177 case Builtin::BI__builtin_fmaxf128:
1182 case Builtin::BI__builtin_isnan:
1186 case Builtin::BI__builtin_issignaling:
1191 case Builtin::BI__builtin_isinf:
1196 case Builtin::BI__builtin_isinf_sign:
1201 case Builtin::BI__builtin_isfinite:
1205 case Builtin::BI__builtin_isnormal:
1209 case Builtin::BI__builtin_issubnormal:
1213 case Builtin::BI__builtin_iszero:
1217 case Builtin::BI__builtin_isfpclass:
1221 case Builtin::BI__builtin_fpclassify:
1226 case Builtin::BI__builtin_fabs:
1227 case Builtin::BI__builtin_fabsf:
1228 case Builtin::BI__builtin_fabsl:
1229 case Builtin::BI__builtin_fabsf128:
1234 case Builtin::BI__builtin_popcount:
1235 case Builtin::BI__builtin_popcountl:
1236 case Builtin::BI__builtin_popcountll:
1237 case Builtin::BI__builtin_popcountg:
1238 case Builtin::BI__popcnt16:
1239 case Builtin::BI__popcnt:
1240 case Builtin::BI__popcnt64:
1245 case Builtin::BI__builtin_parity:
1246 case Builtin::BI__builtin_parityl:
1247 case Builtin::BI__builtin_parityll:
1252 case Builtin::BI__builtin_clrsb:
1253 case Builtin::BI__builtin_clrsbl:
1254 case Builtin::BI__builtin_clrsbll:
1259 case Builtin::BI__builtin_bitreverse8:
1260 case Builtin::BI__builtin_bitreverse16:
1261 case Builtin::BI__builtin_bitreverse32:
1262 case Builtin::BI__builtin_bitreverse64:
1267 case Builtin::BI__builtin_classify_type:
1272 case Builtin::BI__builtin_expect:
1273 case Builtin::BI__builtin_expect_with_probability:
1278 case Builtin::BI__builtin_rotateleft8:
1279 case Builtin::BI__builtin_rotateleft16:
1280 case Builtin::BI__builtin_rotateleft32:
1281 case Builtin::BI__builtin_rotateleft64:
1282 case Builtin::BI_rotl8:
1283 case Builtin::BI_rotl16:
1284 case Builtin::BI_rotl:
1285 case Builtin::BI_lrotl:
1286 case Builtin::BI_rotl64:
1291 case Builtin::BI__builtin_rotateright8:
1292 case Builtin::BI__builtin_rotateright16:
1293 case Builtin::BI__builtin_rotateright32:
1294 case Builtin::BI__builtin_rotateright64:
1295 case Builtin::BI_rotr8:
1296 case Builtin::BI_rotr16:
1297 case Builtin::BI_rotr:
1298 case Builtin::BI_lrotr:
1299 case Builtin::BI_rotr64:
1304 case Builtin::BI__builtin_ffs:
1305 case Builtin::BI__builtin_ffsl:
1306 case Builtin::BI__builtin_ffsll:
1310 case Builtin::BIaddressof:
1311 case Builtin::BI__addressof:
1312 case Builtin::BI__builtin_addressof:
1317 case Builtin::BIas_const:
1318 case Builtin::BIforward:
1319 case Builtin::BIforward_like:
1320 case Builtin::BImove:
1321 case Builtin::BImove_if_noexcept:
1326 case Builtin::BI__builtin_eh_return_data_regno:
1331 case Builtin::BI__builtin_launder:
1332 case Builtin::BI__builtin___CFStringMakeConstantString:
1333 case Builtin::BI__builtin___NSStringMakeConstantString:
1338 case Builtin::BI__builtin_add_overflow:
1339 case Builtin::BI__builtin_sub_overflow:
1340 case Builtin::BI__builtin_mul_overflow:
1341 case Builtin::BI__builtin_sadd_overflow:
1342 case Builtin::BI__builtin_uadd_overflow:
1343 case Builtin::BI__builtin_uaddl_overflow:
1344 case Builtin::BI__builtin_uaddll_overflow:
1345 case Builtin::BI__builtin_usub_overflow:
1346 case Builtin::BI__builtin_usubl_overflow:
1347 case Builtin::BI__builtin_usubll_overflow:
1348 case Builtin::BI__builtin_umul_overflow:
1349 case Builtin::BI__builtin_umull_overflow:
1350 case Builtin::BI__builtin_umulll_overflow:
1351 case Builtin::BI__builtin_saddl_overflow:
1352 case Builtin::BI__builtin_saddll_overflow:
1353 case Builtin::BI__builtin_ssub_overflow:
1354 case Builtin::BI__builtin_ssubl_overflow:
1355 case Builtin::BI__builtin_ssubll_overflow:
1356 case Builtin::BI__builtin_smul_overflow:
1357 case Builtin::BI__builtin_smull_overflow:
1358 case Builtin::BI__builtin_smulll_overflow:
1363 case Builtin::BI__builtin_addcb:
1364 case Builtin::BI__builtin_addcs:
1365 case Builtin::BI__builtin_addc:
1366 case Builtin::BI__builtin_addcl:
1367 case Builtin::BI__builtin_addcll:
1368 case Builtin::BI__builtin_subcb:
1369 case Builtin::BI__builtin_subcs:
1370 case Builtin::BI__builtin_subc:
1371 case Builtin::BI__builtin_subcl:
1372 case Builtin::BI__builtin_subcll:
1377 case Builtin::BI__builtin_clz:
1378 case Builtin::BI__builtin_clzl:
1379 case Builtin::BI__builtin_clzll:
1380 case Builtin::BI__builtin_clzs:
1381 case Builtin::BI__builtin_clzg:
1382 case Builtin::BI__lzcnt16:
1383 case Builtin::BI__lzcnt:
1384 case Builtin::BI__lzcnt64:
1389 case Builtin::BI__builtin_ctz:
1390 case Builtin::BI__builtin_ctzl:
1391 case Builtin::BI__builtin_ctzll:
1392 case Builtin::BI__builtin_ctzs:
1393 case Builtin::BI__builtin_ctzg:
1398 case Builtin::BI__builtin_bswap16:
1399 case Builtin::BI__builtin_bswap32:
1400 case Builtin::BI__builtin_bswap64:
1405 case Builtin::BI__atomic_always_lock_free:
1406 case Builtin::BI__atomic_is_lock_free:
1407 case Builtin::BI__c11_atomic_is_lock_free:
1412 case Builtin::BI__builtin_complex:
1417 case Builtin::BI__builtin_is_aligned:
1418 case Builtin::BI__builtin_align_up:
1419 case Builtin::BI__builtin_align_down:
1424 case Builtin::BI__builtin_os_log_format_buffer_size:
1430 S.FFDiag(S.Current->getLocation(OpPC),
1431 diag::note_invalid_subexpr_in_const_expr)
1432 << S.Current->getRange(OpPC);
1442 int64_t &IntResult) {
1447 unsigned ArrayIndex = 0;
1449 for (
unsigned I = 0; I != N; ++I) {
1451 switch (
Node.getKind()) {
1462 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
1470 int64_t Index = ArrayIndices[ArrayIndex];
1471 const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType);
1475 CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType);
1476 Result += Index * ElementSize;
1495 CurrentType = BaseSpec->
getType();
1505 llvm_unreachable(
"Dependent OffsetOfExpr?");
1509 IntResult =
Result.getQuantity();
1526 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
1543 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
1557 for (
const Record::Field &F : R->
fields()) {
1559 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,...
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
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
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,...
QualType getType() const
Return the type wrapped by this type source info.
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 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.
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.
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_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)
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)
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a value can be loaded from a block.
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)
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.
bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer is a dummy pointer.
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.