19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/SipHash.h"
28 case Builtin::BIas_const:
29 case Builtin::BIforward:
30 case Builtin::BIforward_like:
32 case Builtin::BImove_if_noexcept:
33 case Builtin::BIaddressof:
34 case Builtin::BI__addressof:
35 case Builtin::BI__builtin_addressof:
36 case Builtin::BI__builtin_launder:
76 int64_t
V = Val.getSExtValue();
80 uint64_t
V = Val.getZExtValue();
87 if constexpr (std::is_same_v<T, APInt>)
89 else if constexpr (std::is_same_v<T, APSInt>)
95 !std::is_signed_v<T>),
112 ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
121 if (
T->isPointerType())
125 if (
const auto *AT =
T->getAsArrayTypeUnsafe())
126 return AT->getElementType();
137 S.
CCEDiag(Loc, diag::note_constexpr_invalid_function)
141 S.
CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
147 "Not a boolean vector");
151 llvm::APSInt
Result(NumElems, 0);
152 for (
unsigned I = 0; I != NumElems; ++I) {
153 if (Val.
elem<
bool>(I))
165 return F && F->isInStdNamespace() && F->getIdentifier() &&
166 F->getIdentifier()->isStr(
"is_constant_evaluated");
177 diag::warn_is_constant_evaluated_always_true_constexpr)
181 diag::warn_is_constant_evaluated_always_true_constexpr)
182 <<
"__builtin_is_constant_evaluated" <<
Call->getSourceRange();
194 assert(
Call->getNumArgs() == 1);
202 uint64_t Limit = ~static_cast<uint64_t>(0);
203 if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp ||
204 ID == Builtin::BIwcsncmp || ID == Builtin::BI__builtin_wcsncmp)
210 if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp ||
211 ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp)
222 if (A.isDummy() || B.
isDummy())
227 bool IsWide = ID == Builtin::BIwcscmp || ID == Builtin::BIwcsncmp ||
228 ID == Builtin::BI__builtin_wcscmp ||
229 ID == Builtin::BI__builtin_wcsncmp;
230 assert(A.getFieldDesc()->isPrimitiveArray());
239 auto returnResult = [&](
int V) ->
bool {
244 unsigned IndexA = A.getIndex();
247 for (;; ++IndexA, ++IndexB, ++Steps) {
263 return returnResult(1);
265 return returnResult(-1);
266 if (CA.isZero() || CB.isZero())
267 return returnResult(0);
272 uint8_t CA = PA.
deref<uint8_t>();
273 uint8_t CB = PB.
deref<uint8_t>();
276 return returnResult(1);
278 return returnResult(-1);
279 if (CA == 0 || CB == 0)
280 return returnResult(0);
283 return returnResult(0);
291 if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen)
309 if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
315 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
324 Val = ElemPtr.
deref<uint8_t>();
327 Val = ElemPtr.
deref<uint16_t>();
330 Val = ElemPtr.
deref<uint32_t>();
333 llvm_unreachable(
"Unsupported char size");
358 for (
unsigned I = 0;; ++I) {
364 if (Elem.
deref<int8_t>() == 0)
367 Str += Elem.
deref<
char>();
372 Fill = llvm::APInt(32, 0);
373 else if (StringRef(Str).getAsInteger(0, Fill))
376 const llvm::fltSemantics &TargetSemantics =
378 Call->getDirectCallee()->getReturnType());
384 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
387 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
396 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
399 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
409 const llvm::fltSemantics &TargetSemantics =
411 Call->getDirectCallee()->getReturnType());
414 Result.copy(APFloat::getInf(TargetSemantics));
487 bool IsInf = F.isInfinity();
490 pushInteger(S, IsInf ? (F.isNegative() ? -1 : 1) : 0,
Call->getType());
550 case Builtin::BI__builtin_isgreater:
552 case Builtin::BI__builtin_isgreaterequal:
554 case Builtin::BI__builtin_isless:
556 case Builtin::BI__builtin_islessequal:
558 case Builtin::BI__builtin_islessgreater: {
563 case Builtin::BI__builtin_isunordered:
566 llvm_unreachable(
"Unexpected builtin ID: Should be a floating point "
567 "comparison function");
583 int32_t
Result =
static_cast<int32_t
>(
584 (F.
classify() & std::move(FPClassArg)).getZExtValue());
599 for (
unsigned I = 0; I != 5; ++I)
607 case APFloat::fcInfinity:
610 case APFloat::fcNormal:
613 case APFloat::fcZero:
626 if (!In.isNegative())
654 APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
false))
656 if (Val.isNegative())
666 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
691 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
708 assert(
Call->getNumArgs() == 1);
713 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
725 unsigned NumArgs =
Call->getNumArgs();
726 assert(NumArgs == 2 || NumArgs == 3);
766 uint64_t N =
Value.countr_zero();
775 assert(
Call->getArg(0)->isLValue());
778 "Unsupported pointer type passed to __builtin_addressof()");
786 return Call->getDirectCallee()->isConstexpr();
804 unsigned BuiltinOp) {
813 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
818 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
819 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
820 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
821 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
823 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
825 uint64_t LHSSize = LHS.getBitWidth();
826 uint64_t RHSSize = RHS.getBitWidth();
828 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
834 if (IsSigned && !AllSigned)
837 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
838 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
845 llvm_unreachable(
"Invalid value for BuiltinOp");
846 case Builtin::BI__builtin_add_overflow:
847 case Builtin::BI__builtin_sadd_overflow:
848 case Builtin::BI__builtin_saddl_overflow:
849 case Builtin::BI__builtin_saddll_overflow:
850 case Builtin::BI__builtin_uadd_overflow:
851 case Builtin::BI__builtin_uaddl_overflow:
852 case Builtin::BI__builtin_uaddll_overflow:
853 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
854 : LHS.uadd_ov(RHS, Overflow);
856 case Builtin::BI__builtin_sub_overflow:
857 case Builtin::BI__builtin_ssub_overflow:
858 case Builtin::BI__builtin_ssubl_overflow:
859 case Builtin::BI__builtin_ssubll_overflow:
860 case Builtin::BI__builtin_usub_overflow:
861 case Builtin::BI__builtin_usubl_overflow:
862 case Builtin::BI__builtin_usubll_overflow:
863 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
864 : LHS.usub_ov(RHS, Overflow);
866 case Builtin::BI__builtin_mul_overflow:
867 case Builtin::BI__builtin_smul_overflow:
868 case Builtin::BI__builtin_smull_overflow:
869 case Builtin::BI__builtin_smulll_overflow:
870 case Builtin::BI__builtin_umul_overflow:
871 case Builtin::BI__builtin_umull_overflow:
872 case Builtin::BI__builtin_umulll_overflow:
873 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
874 : LHS.umul_ov(RHS, Overflow);
880 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
881 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
882 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
890 if (!APSInt::isSameValue(Temp,
Result))
900 assert(
Call->getDirectCallee()->getReturnType()->isBooleanType());
926 bool FirstOverflowed =
false;
927 bool SecondOverflowed =
false;
930 llvm_unreachable(
"Invalid value for BuiltinOp");
931 case Builtin::BI__builtin_addcb:
932 case Builtin::BI__builtin_addcs:
933 case Builtin::BI__builtin_addc:
934 case Builtin::BI__builtin_addcl:
935 case Builtin::BI__builtin_addcll:
937 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
939 case Builtin::BI__builtin_subcb:
940 case Builtin::BI__builtin_subcs:
941 case Builtin::BI__builtin_subc:
942 case Builtin::BI__builtin_subcl:
943 case Builtin::BI__builtin_subcll:
945 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
950 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
952 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
957 assert(
Call->getType() ==
Call->getArg(0)->getType());
964 unsigned BuiltinOp) {
966 std::optional<APSInt> Fallback;
967 if (BuiltinOp == Builtin::BI__builtin_clzg &&
Call->getNumArgs() == 2) {
972 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
982 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
983 BuiltinOp != Builtin::BI__lzcnt &&
984 BuiltinOp != Builtin::BI__lzcnt64;
1002 unsigned BuiltinID) {
1003 std::optional<APSInt> Fallback;
1004 if (BuiltinID == Builtin::BI__builtin_ctzg &&
Call->getNumArgs() == 2) {
1009 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
1035 assert(Val.getActiveBits() <= 64);
1038 { S.
Stk.
push<
T>(T::from(Val.byteSwap().getZExtValue())); });
1047 unsigned BuiltinOp) {
1048 auto returnBool = [&S](
bool Value) ->
bool {
1068 if (Size.isPowerOfTwo()) {
1070 unsigned InlineWidthBits =
1077 return returnBool(
true);
1080 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
1082 return returnBool(
true);
1086 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
1087 return returnBool(
true);
1090 const Expr *PtrArg =
Call->getArg(1);
1092 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
1095 if (ICE->getCastKind() == CK_BitCast)
1096 PtrArg = ICE->getSubExpr();
1104 return returnBool(
true);
1110 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
1111 return returnBool(
false);
1124 auto returnBool = [&S](
bool Value) ->
bool {
1130 if (Size.isPowerOfTwo()) {
1132 unsigned InlineWidthBits =
1135 return returnBool(
true);
1151 Result.initializeAllElements();
1164 unsigned BuiltinOp) {
1168 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1169 S.
FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1173 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1174 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1175 S.
FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1176 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1186 APInt AlignMinusOne = Alignment.extOrTrunc(Src.getBitWidth()) - 1;
1187 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1189 APSInt((Src + AlignMinusOne) & ~AlignMinusOne, Src.isUnsigned());
1191 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1192 APSInt AlignedVal =
APSInt(Src & ~AlignMinusOne, Src.isUnsigned());
1201 assert(FirstArgT ==
PT_Ptr);
1211 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1226 S.
FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1231 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1232 BuiltinOp == Builtin::BI__builtin_align_up);
1247 assert(Alignment.getBitWidth() <= 64 &&
1248 "Cannot handle > 64-bit address-space");
1249 uint64_t Alignment64 = Alignment.getZExtValue();
1252 ? llvm::alignDown(PtrOffset, Alignment64)
1253 : llvm::alignTo(PtrOffset, Alignment64));
1260 S.
FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1268 assert(
Call->getNumArgs() == 2 ||
Call->getNumArgs() == 3);
1270 std::optional<APSInt> ExtraOffset;
1271 if (
Call->getNumArgs() == 3)
1287 if (BaseAlignment < Align) {
1289 diag::note_constexpr_baa_insufficient_alignment)
1290 << 0 << BaseAlignment.
getQuantity() << Align.getQuantity();
1299 if (AVOffset.
alignTo(Align) != AVOffset) {
1302 diag::note_constexpr_baa_insufficient_alignment)
1303 << 1 << AVOffset.
getQuantity() << Align.getQuantity();
1306 diag::note_constexpr_baa_value_insufficient_alignment)
1318 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1319 !
Call->getArg(1)->getType()->isIntegerType())
1327 unsigned BitWidth = Val.getBitWidth();
1328 uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
1329 uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
1330 Length = Length > BitWidth ? BitWidth : Length;
1333 if (Length == 0 || Shift >= BitWidth) {
1338 uint64_t
Result = Val.getZExtValue() >> Shift;
1339 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
1348 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1349 !
Call->getArg(1)->getType()->isIntegerType() ||
1359 unsigned BitWidth = Val.getBitWidth();
1360 uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
1362 if (Index < BitWidth)
1363 Val.clearHighBits(BitWidth - Index);
1374 !
Call->getArg(0)->getType()->isIntegerType())
1378 pushInteger(S, Val.countLeadingZeros(), CallType);
1387 !
Call->getArg(0)->getType()->isIntegerType())
1391 pushInteger(S, Val.countTrailingZeros(), CallType);
1398 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1399 !
Call->getArg(1)->getType()->isIntegerType())
1408 unsigned BitWidth = Val.getBitWidth();
1410 for (
unsigned I = 0, P = 0; I != BitWidth; ++I) {
1412 Result.setBitVal(I, Val[P++]);
1421 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1422 !
Call->getArg(1)->getType()->isIntegerType())
1431 unsigned BitWidth = Val.getBitWidth();
1433 for (
unsigned I = 0, P = 0; I != BitWidth; ++I) {
1435 Result.setBitVal(P++, Val[I]);
1446 unsigned BuiltinOp) {
1447 if (
Call->getNumArgs() != 4 || !
Call->getArg(0)->getType()->isIntegerType() ||
1448 !
Call->getArg(1)->getType()->isIntegerType() ||
1449 !
Call->getArg(2)->getType()->isIntegerType())
1461 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
1462 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
1464 unsigned BitWidth = LHS.getBitWidth();
1465 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
1467 IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
1468 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
1472 APSInt(ExResult.extractBits(1, BitWidth),
true);
1474 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
1498 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1502 assert(Ptr.getFieldDesc()->getNumElems() >= 1);
1503 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1504 uint64_t
Result = getPointerAuthStableSipHash(R);
1517 if (ElemType.isNull()) {
1519 ? diag::note_constexpr_new_untyped
1520 : diag::note_constexpr_new);
1525 if (ElemType->isIncompleteType() || ElemType->isFunctionType()) {
1526 S.
FFDiag(
Call, diag::note_constexpr_new_not_complete_object_type)
1527 << (ElemType->isIncompleteType() ? 0 : 1) << ElemType;
1534 unsigned NumArgs =
Call->getNumArgs();
1535 assert(NumArgs >= 1);
1538 if (
Call->getArg(NumArgs - 1)->getType()->isNothrowT())
1542 Args = Args.drop_front();
1545 for (
const Expr *Arg : Args)
1551 assert(!ElemSize.
isZero());
1554 APInt NumElems, Remainder;
1556 APInt::udivrem(
Bytes, ElemSizeAP, NumElems, Remainder);
1557 if (Remainder != 0) {
1559 S.
FFDiag(
Call, diag::note_constexpr_operator_new_bad_size)
1565 if (NumElems.getActiveBits() >
1570 S.
FFDiag(Loc, diag::note_constexpr_new_too_large)
1571 << NumElems.getZExtValue();
1578 bool IsArray = NumElems.ugt(1);
1583 Allocator.
allocate(NewCall, *ElemT, NumElems.getZExtValue(),
1620 const Expr *Source =
nullptr;
1621 const Block *BlockToDelete =
nullptr;
1639 S.
CCEDiag(
Call, diag::note_constexpr_deallocate_null);
1644 BlockToDelete = Ptr.
block();
1647 S.
FFDiag(
Call, diag::note_constexpr_delete_not_heap_alloc)
1650 S.
Note(D->getLocation(), diag::note_declared_at);
1653 assert(BlockToDelete);
1657 std::optional<DynamicAllocator::Form> AllocForm =
1660 if (!Allocator.
deallocate(Source, BlockToDelete, S)) {
1663 S.
FFDiag(Loc, diag::note_constexpr_double_delete);
1686 assert(
Call->getType() == ElemType);
1692 unsigned BitWidth =
Result.bitWidth();
1693 for (
unsigned I = 1; I != NumElems; ++I) {
1697 if (ID == Builtin::BI__builtin_reduce_add) {
1699 unsigned OverflowBits = BitWidth + 1;
1701 (PrevResult.toAPSInt(OverflowBits) +
1702 Elem.toAPSInt(OverflowBits)));
1705 }
else if (ID == Builtin::BI__builtin_reduce_mul) {
1707 unsigned OverflowBits = BitWidth * 2;
1709 (PrevResult.toAPSInt(OverflowBits) *
1710 Elem.toAPSInt(OverflowBits)));
1714 }
else if (ID == Builtin::BI__builtin_reduce_and) {
1716 }
else if (ID == Builtin::BI__builtin_reduce_or) {
1718 }
else if (ID == Builtin::BI__builtin_reduce_xor) {
1720 }
else if (ID == Builtin::BI__builtin_reduce_min) {
1723 }
else if (ID == Builtin::BI__builtin_reduce_max) {
1727 llvm_unreachable(
"Unhandled vector reduce builtin");
1739 unsigned BuiltinID) {
1740 assert(
Call->getNumArgs() == 1);
1758 assert(
Call->getArg(0)->getType()->isVectorType());
1770 for (
unsigned I = 0; I != NumElems; ++I) {
1773 Dst.
elem<
T>(I) = T::from(
static_cast<T>(
1791 unsigned BuiltinID) {
1792 assert(
Call->getNumArgs() == 1);
1793 if (
Call->getArg(0)->getType()->isIntegerType()) {
1797 if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1805 assert(
Call->getArg(0)->getType()->isVectorType());
1818 for (
unsigned I = 0; I != NumElems; ++I) {
1820 if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1821 Dst.
elem<
T>(I) = T::from(Arg.
elem<
T>(I).toAPSInt().popcount());
1824 T::from(Arg.
elem<
T>(I).toAPSInt().reverseBits().getZExtValue());
1838 unsigned BuiltinID) {
1839 const bool HasZeroArg =
Call->getNumArgs() == 2;
1840 const bool IsCTTZ = BuiltinID == Builtin::BI__builtin_elementwise_cttz;
1841 assert(
Call->getNumArgs() == 1 || HasZeroArg);
1842 if (
Call->getArg(0)->getType()->isIntegerType()) {
1845 std::optional<APSInt> ZeroVal;
1859 diag::note_constexpr_countzeroes_zero)
1864 if (BuiltinID == Builtin::BI__builtin_elementwise_ctlz) {
1875 assert(
Call->getArg(1)->getType()->isVectorType() &&
1877 Call->getArg(1)->getType()));
1882 assert(
Call->getArg(0)->getType()->isVectorType());
1895 for (
unsigned I = 0; I != NumElems; ++I) {
1898 if (EltVal.isZero()) {
1905 diag::note_constexpr_countzeroes_zero)
1909 }
else if (IsCTTZ) {
1910 Dst.
atIndex(I).
deref<
T>() = T::from(EltVal.countTrailingZeros());
1912 Dst.
atIndex(I).
deref<
T>() = T::from(EltVal.countLeadingZeros());
1924 assert(
Call->getNumArgs() == 3);
1931 assert(!Size.isSigned() &&
"memcpy and friends take an unsigned size");
1933 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
1937 (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove ||
1938 ID == Builtin::BI__builtin_wmemmove || ID == Builtin::BIwmemmove);
1939 bool WChar = ID == Builtin::BIwmemcpy || ID == Builtin::BIwmemmove ||
1940 ID == Builtin::BI__builtin_wmemcpy ||
1941 ID == Builtin::BI__builtin_wmemmove;
1944 if (Size.isZero()) {
1949 if (SrcPtr.
isZero() || DestPtr.isZero()) {
1952 << Move << WChar << !SrcPtr.
isZero()
1959 std::string DiagVal =
"(void *)";
1962 : std::to_string(DestPtr.getIntegerRepresentation());
1964 << Move << WChar << DestPtr.isIntegralPointer() << DiagVal;
1969 if (DestPtr.isDummy() || SrcPtr.
isDummy())
1972 if (DestPtr.getType()->isIncompleteType()) {
1974 diag::note_constexpr_memcpy_incomplete_type)
1975 << Move << DestPtr.getType();
1980 diag::note_constexpr_memcpy_incomplete_type)
1988 diag::note_constexpr_memcpy_incomplete_type)
1989 << Move << DestElemType;
1993 size_t RemainingDestElems;
1994 if (DestPtr.getFieldDesc()->isArray()) {
1995 RemainingDestElems = DestPtr.isUnknownSizeArray()
1997 : (DestPtr.getNumElems() - DestPtr.getIndex());
1999 RemainingDestElems = 1;
2004 uint64_t WCharSize =
2006 Size *=
APSInt(
APInt(Size.getBitWidth(), WCharSize,
false),
2010 if (Size.urem(DestElemSize) != 0) {
2012 diag::note_constexpr_memcpy_unsupported)
2013 << Move << WChar << 0 << DestElemType << Size << DestElemSize;
2018 size_t RemainingSrcElems;
2024 RemainingSrcElems = 1;
2030 << Move << SrcElemType << DestElemType;
2036 << Move << DestElemType;
2041 size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
2042 size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
2043 if (Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) {
2044 APInt N = Size.udiv(DestElemSize);
2046 diag::note_constexpr_memcpy_unsupported)
2047 << Move << WChar << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
2048 << DestElemType <<
toString(N, 10,
false);
2065 unsigned N = Size.getZExtValue();
2067 if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||
2068 (DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) {
2075 assert(Size.getZExtValue() % DestElemSize == 0);
2086 return T->isCharType() ||
T->isChar8Type();
2092 assert(
Call->getNumArgs() == 3);
2098 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
2099 ID == Builtin::BIwmemcmp)
2102 if (Size.isZero()) {
2108 (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);
2118 diag::note_constexpr_memcmp_unsupported)
2124 if (PtrA.isDummy() || PtrB.
isDummy())
2147 unsigned ElemSize = 1;
2152 size_t ByteSize = Size.getZExtValue() * ElemSize;
2153 size_t CmpSize = std::min(MinBufferSize, ByteSize);
2155 for (
size_t I = 0; I != CmpSize; I += ElemSize) {
2158 T A = *reinterpret_cast<T *>(BufferA.Data.get() + I);
2159 T B = *reinterpret_cast<T *>(BufferB.Data.get() + I);
2161 pushInteger(S, -1, Call->getType());
2170 std::byte A = BufferA.
Data[I];
2171 std::byte B = BufferB.
Data[I];
2186 if (ByteSize <= CmpSize) {
2195 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
2196 <<
AK_Read << S.Current->getRange(OpPC);
2204 if (ID == Builtin::BImemchr || ID == Builtin::BIwcschr ||
2205 ID == Builtin::BIstrchr || ID == Builtin::BIwmemchr)
2208 std::optional<APSInt> MaxLength;
2210 if (
Call->getNumArgs() == 3) {
2217 if (MaxLength && MaxLength->isZero()) {
2225 diag::note_constexpr_ltor_incomplete_type)
2240 bool IsRawByte = ID == Builtin::BImemchr || ID == Builtin::BI__builtin_memchr;
2245 diag::note_constexpr_memchr_unsupported)
2250 if (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr) {
2260 uint64_t DesiredVal;
2261 if (ID == Builtin::BIwmemchr || ID == Builtin::BI__builtin_wmemchr ||
2262 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr) {
2264 DesiredVal = Desired.getZExtValue();
2270 (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr ||
2271 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr);
2280 (Index + Step) > 0 ? Ptr.
atIndex(Index + Step) : Ptr;
2287 ElemT, {
V =
static_cast<uint64_t
>(ElemPtr.
deref<
T>().toUnsigned()); });
2289 if (
V == DesiredVal) {
2294 if (StopAtZero &&
V == 0)
2298 if (MaxLength && Step == MaxLength->getZExtValue())
2322 return std::nullopt;
2360 uint64_t FieldOffset =
2366 llvm_unreachable(
"Unhandled descriptor type");
2402 auto isFlexibleArrayMember = [&](
const Descriptor *FieldDesc) {
2404 FAMKind StrictFlexArraysLevel =
2407 if (StrictFlexArraysLevel == FAMKind::Default)
2410 unsigned NumElems = FieldDesc->getNumElems();
2411 if (NumElems == 0 && StrictFlexArraysLevel != FAMKind::IncompleteOnly)
2414 if (NumElems == 1 && StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
2424 isFlexibleArrayMember(FieldDesc);
2438 assert(Kind <= 3 &&
"unexpected kind");
2439 bool UseFieldDesc = (Kind & 1u);
2440 bool ReportMinimum = (Kind & 2u);
2443 if (
Call->getArg(0)->HasSideEffects(ASTCtx)) {
2461 if (!UseFieldDesc || DetermineForCompleteObject) {
2463 if (ReportMinimum && !DetermineForCompleteObject)
2486 unsigned ByteOffset;
2498 assert(ByteOffset <= *FullSize);
2499 unsigned Result = *FullSize - ByteOffset;
2514 bool CalledFromStd =
false;
2516 if (Callee && Callee->isInStdNamespace()) {
2518 CalledFromStd = Identifier && Identifier->
isStr(
"is_within_lifetime");
2523 diag::err_invalid_is_within_lifetime)
2524 << (CalledFromStd ?
"std::is_within_lifetime"
2525 :
"__builtin_is_within_lifetime")
2560 assert(
Call->getNumArgs() == 2);
2563 if (!
Call->getArg(0)->getType()->isVectorType()) {
2564 assert(!
Call->getArg(1)->getType()->isVectorType());
2574 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2575 assert(VT->getElementType()->isIntegralOrEnumerationType());
2577 unsigned NumElems = VT->getNumElements();
2578 bool DestUnsigned =
Call->getType()->isUnsignedIntegerOrEnumerationType();
2581 if (!
Call->getArg(1)->getType()->isVectorType()) {
2582 assert(
Call->getArg(1)->getType()->isIntegralOrEnumerationType());
2589 for (
unsigned I = 0; I != NumElems; ++I) {
2591 Dst.elem<
T>(I) =
static_cast<T>(
2600 assert(
Call->getArg(0)->getType()->isVectorType() &&
2601 Call->getArg(1)->getType()->isVectorType());
2602 assert(VT->getElementType() ==
2604 assert(VT->getNumElements() ==
2606 assert(VT->getElementType()->isIntegralOrEnumerationType());
2611 for (
unsigned I = 0; I != NumElems; ++I) {
2613 APSInt Elem1 = LHS.elem<
T>(I).toAPSInt();
2615 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(
Fn(Elem1, Elem2), DestUnsigned));
2625 unsigned BuiltinID) {
2626 assert(
Call->getNumArgs() == 2);
2637 assert(!
Call->getArg(1)->getType()->isVectorType());
2643 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2644 Result = std::max(LHS, RHS);
2645 }
else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2646 Result = std::min(LHS, RHS);
2648 llvm_unreachable(
"Wrong builtin ID");
2656 assert(
Call->getArg(0)->getType()->isVectorType() &&
2657 Call->getArg(1)->getType()->isVectorType());
2658 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2659 assert(VT->getElementType() ==
2661 assert(VT->getNumElements() ==
2663 assert(VT->getElementType()->isIntegralOrEnumerationType());
2669 unsigned NumElems = VT->getNumElements();
2670 for (
unsigned I = 0; I != NumElems; ++I) {
2674 Elem1 = LHS.elem<
T>(I).toAPSInt();
2675 Elem2 = RHS.
elem<
T>(I).toAPSInt();
2679 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2681 Call->getType()->isUnsignedIntegerOrEnumerationType());
2682 }
else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2684 Call->getType()->isUnsignedIntegerOrEnumerationType());
2686 llvm_unreachable(
"Wrong builtin ID");
2690 { Dst.elem<
T>(I) =
static_cast<T>(
Result); });
2692 Dst.initializeAllElements();
2699 unsigned BuiltinID) {
2700 assert(
Call->getArg(0)->getType()->isVectorType() &&
2701 Call->getArg(1)->getType()->isVectorType());
2706 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2708 unsigned SourceLen = VT->getNumElements();
2712 unsigned DstElem = 0;
2713 for (
unsigned I = 0; I != SourceLen; I += 2) {
2717 Elem1 = LHS.elem<
T>(I).toAPSInt();
2718 Elem2 = RHS.
elem<
T>(I).toAPSInt();
2722 switch (BuiltinID) {
2723 case clang::X86::BI__builtin_ia32_pmuludq128:
2724 case clang::X86::BI__builtin_ia32_pmuludq256:
2725 case clang::X86::BI__builtin_ia32_pmuludq512:
2726 Result =
APSInt(llvm::APIntOps::muluExtended(Elem1, Elem2),
2729 case clang::X86::BI__builtin_ia32_pmuldq128:
2730 case clang::X86::BI__builtin_ia32_pmuldq256:
2731 case clang::X86::BI__builtin_ia32_pmuldq512:
2732 Result =
APSInt(llvm::APIntOps::mulsExtended(Elem1, Elem2),
2737 { Dst.elem<
T>(DstElem) =
static_cast<T>(
Result); });
2741 Dst.initializeAllElements();
2748 const APFloat &, llvm::RoundingMode)>
2750 assert(
Call->getNumArgs() == 3);
2787 assert(ElemT->isRealFloatingType());
2794 for (
unsigned I = 0; I != NumElems; ++I) {
2797 APFloat Y = VY.elem<
T>(I).getAPFloat();
2817 unsigned NumElems = LHS.getNumElems();
2818 PrimType ElemT = LHS.getFieldDesc()->getPrimType();
2821 for (
unsigned I = 0; I != NumElems; ++I) {
2829 Elem = Mask[I] ? LHS.elem<
T>(I).toAPSInt() : RHS.
elem<
T>(I).toAPSInt();
2832 { Dst.
elem<
T>(I) =
static_cast<T>(Elem); });
2848 assert(FalseVec.getNumElems() == TrueVec.
getNumElems());
2849 assert(FalseVec.getNumElems() == Dst.getNumElems());
2850 unsigned NumElems = FalseVec.getNumElems();
2851 PrimType ElemT = FalseVec.getFieldDesc()->getPrimType();
2852 PrimType DstElemT = Dst.getFieldDesc()->getPrimType();
2854 for (
unsigned I = 0; I != NumElems; ++I) {
2855 bool MaskBit = Mask[I % 8];
2861 assert(DstElemT == ElemT);
2864 static_cast<T>(MaskBit ? TrueVec.
elem<
T>(I).toAPSInt()
2865 : FalseVec.elem<
T>(I).toAPSInt());
2869 Dst.initializeAllElements();
2878 assert(
Call->getNumArgs() == 3);
2896 unsigned NumElems = VecT->getNumElements();
2897 bool DestUnsigned =
Call->getType()->isUnsignedIntegerOrEnumerationType();
2907 for (
unsigned I = 0; I != NumElems; ++I) {
2909 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(
2910 Fn(Op0.elem<
T>(I).toAPSInt(), Op1.
elem<
T>(I).toAPSInt(), Op2),
2924 for (
unsigned I = 0; I != NumElems; ++I) {
2927 Val0 = Op0.elem<
T>(I).toAPSInt();
2928 Val1 = Op1.elem<
T>(I).toAPSInt();
2929 Val2 = Op2.
elem<
T>(I).toAPSInt();
2933 { Dst.elem<
T>(I) =
static_cast<T>(
Result); });
2941 uint32_t BuiltinID) {
2946 switch (BuiltinID) {
2947 case Builtin::BI__builtin_is_constant_evaluated:
2950 case Builtin::BI__builtin_assume:
2951 case Builtin::BI__assume:
2954 case Builtin::BI__builtin_strcmp:
2955 case Builtin::BIstrcmp:
2956 case Builtin::BI__builtin_strncmp:
2957 case Builtin::BIstrncmp:
2958 case Builtin::BI__builtin_wcsncmp:
2959 case Builtin::BIwcsncmp:
2960 case Builtin::BI__builtin_wcscmp:
2961 case Builtin::BIwcscmp:
2964 case Builtin::BI__builtin_strlen:
2965 case Builtin::BIstrlen:
2966 case Builtin::BI__builtin_wcslen:
2967 case Builtin::BIwcslen:
2970 case Builtin::BI__builtin_nan:
2971 case Builtin::BI__builtin_nanf:
2972 case Builtin::BI__builtin_nanl:
2973 case Builtin::BI__builtin_nanf16:
2974 case Builtin::BI__builtin_nanf128:
2977 case Builtin::BI__builtin_nans:
2978 case Builtin::BI__builtin_nansf:
2979 case Builtin::BI__builtin_nansl:
2980 case Builtin::BI__builtin_nansf16:
2981 case Builtin::BI__builtin_nansf128:
2984 case Builtin::BI__builtin_huge_val:
2985 case Builtin::BI__builtin_huge_valf:
2986 case Builtin::BI__builtin_huge_vall:
2987 case Builtin::BI__builtin_huge_valf16:
2988 case Builtin::BI__builtin_huge_valf128:
2989 case Builtin::BI__builtin_inf:
2990 case Builtin::BI__builtin_inff:
2991 case Builtin::BI__builtin_infl:
2992 case Builtin::BI__builtin_inff16:
2993 case Builtin::BI__builtin_inff128:
2996 case Builtin::BI__builtin_copysign:
2997 case Builtin::BI__builtin_copysignf:
2998 case Builtin::BI__builtin_copysignl:
2999 case Builtin::BI__builtin_copysignf128:
3002 case Builtin::BI__builtin_fmin:
3003 case Builtin::BI__builtin_fminf:
3004 case Builtin::BI__builtin_fminl:
3005 case Builtin::BI__builtin_fminf16:
3006 case Builtin::BI__builtin_fminf128:
3009 case Builtin::BI__builtin_fminimum_num:
3010 case Builtin::BI__builtin_fminimum_numf:
3011 case Builtin::BI__builtin_fminimum_numl:
3012 case Builtin::BI__builtin_fminimum_numf16:
3013 case Builtin::BI__builtin_fminimum_numf128:
3016 case Builtin::BI__builtin_fmax:
3017 case Builtin::BI__builtin_fmaxf:
3018 case Builtin::BI__builtin_fmaxl:
3019 case Builtin::BI__builtin_fmaxf16:
3020 case Builtin::BI__builtin_fmaxf128:
3023 case Builtin::BI__builtin_fmaximum_num:
3024 case Builtin::BI__builtin_fmaximum_numf:
3025 case Builtin::BI__builtin_fmaximum_numl:
3026 case Builtin::BI__builtin_fmaximum_numf16:
3027 case Builtin::BI__builtin_fmaximum_numf128:
3030 case Builtin::BI__builtin_isnan:
3033 case Builtin::BI__builtin_issignaling:
3036 case Builtin::BI__builtin_isinf:
3039 case Builtin::BI__builtin_isinf_sign:
3042 case Builtin::BI__builtin_isfinite:
3045 case Builtin::BI__builtin_isnormal:
3048 case Builtin::BI__builtin_issubnormal:
3051 case Builtin::BI__builtin_iszero:
3054 case Builtin::BI__builtin_signbit:
3055 case Builtin::BI__builtin_signbitf:
3056 case Builtin::BI__builtin_signbitl:
3059 case Builtin::BI__builtin_isgreater:
3060 case Builtin::BI__builtin_isgreaterequal:
3061 case Builtin::BI__builtin_isless:
3062 case Builtin::BI__builtin_islessequal:
3063 case Builtin::BI__builtin_islessgreater:
3064 case Builtin::BI__builtin_isunordered:
3067 case Builtin::BI__builtin_isfpclass:
3070 case Builtin::BI__builtin_fpclassify:
3073 case Builtin::BI__builtin_fabs:
3074 case Builtin::BI__builtin_fabsf:
3075 case Builtin::BI__builtin_fabsl:
3076 case Builtin::BI__builtin_fabsf128:
3079 case Builtin::BI__builtin_abs:
3080 case Builtin::BI__builtin_labs:
3081 case Builtin::BI__builtin_llabs:
3084 case Builtin::BI__builtin_popcount:
3085 case Builtin::BI__builtin_popcountl:
3086 case Builtin::BI__builtin_popcountll:
3087 case Builtin::BI__builtin_popcountg:
3088 case Builtin::BI__popcnt16:
3089 case Builtin::BI__popcnt:
3090 case Builtin::BI__popcnt64:
3093 case Builtin::BI__builtin_parity:
3094 case Builtin::BI__builtin_parityl:
3095 case Builtin::BI__builtin_parityll:
3098 case Builtin::BI__builtin_clrsb:
3099 case Builtin::BI__builtin_clrsbl:
3100 case Builtin::BI__builtin_clrsbll:
3103 case Builtin::BI__builtin_bitreverse8:
3104 case Builtin::BI__builtin_bitreverse16:
3105 case Builtin::BI__builtin_bitreverse32:
3106 case Builtin::BI__builtin_bitreverse64:
3109 case Builtin::BI__builtin_classify_type:
3112 case Builtin::BI__builtin_expect:
3113 case Builtin::BI__builtin_expect_with_probability:
3116 case Builtin::BI__builtin_rotateleft8:
3117 case Builtin::BI__builtin_rotateleft16:
3118 case Builtin::BI__builtin_rotateleft32:
3119 case Builtin::BI__builtin_rotateleft64:
3120 case Builtin::BI_rotl8:
3121 case Builtin::BI_rotl16:
3122 case Builtin::BI_rotl:
3123 case Builtin::BI_lrotl:
3124 case Builtin::BI_rotl64:
3127 case Builtin::BI__builtin_rotateright8:
3128 case Builtin::BI__builtin_rotateright16:
3129 case Builtin::BI__builtin_rotateright32:
3130 case Builtin::BI__builtin_rotateright64:
3131 case Builtin::BI_rotr8:
3132 case Builtin::BI_rotr16:
3133 case Builtin::BI_rotr:
3134 case Builtin::BI_lrotr:
3135 case Builtin::BI_rotr64:
3138 case Builtin::BI__builtin_ffs:
3139 case Builtin::BI__builtin_ffsl:
3140 case Builtin::BI__builtin_ffsll:
3143 case Builtin::BIaddressof:
3144 case Builtin::BI__addressof:
3145 case Builtin::BI__builtin_addressof:
3149 case Builtin::BIas_const:
3150 case Builtin::BIforward:
3151 case Builtin::BIforward_like:
3152 case Builtin::BImove:
3153 case Builtin::BImove_if_noexcept:
3157 case Builtin::BI__builtin_eh_return_data_regno:
3160 case Builtin::BI__builtin_launder:
3164 case Builtin::BI__builtin_add_overflow:
3165 case Builtin::BI__builtin_sub_overflow:
3166 case Builtin::BI__builtin_mul_overflow:
3167 case Builtin::BI__builtin_sadd_overflow:
3168 case Builtin::BI__builtin_uadd_overflow:
3169 case Builtin::BI__builtin_uaddl_overflow:
3170 case Builtin::BI__builtin_uaddll_overflow:
3171 case Builtin::BI__builtin_usub_overflow:
3172 case Builtin::BI__builtin_usubl_overflow:
3173 case Builtin::BI__builtin_usubll_overflow:
3174 case Builtin::BI__builtin_umul_overflow:
3175 case Builtin::BI__builtin_umull_overflow:
3176 case Builtin::BI__builtin_umulll_overflow:
3177 case Builtin::BI__builtin_saddl_overflow:
3178 case Builtin::BI__builtin_saddll_overflow:
3179 case Builtin::BI__builtin_ssub_overflow:
3180 case Builtin::BI__builtin_ssubl_overflow:
3181 case Builtin::BI__builtin_ssubll_overflow:
3182 case Builtin::BI__builtin_smul_overflow:
3183 case Builtin::BI__builtin_smull_overflow:
3184 case Builtin::BI__builtin_smulll_overflow:
3187 case Builtin::BI__builtin_addcb:
3188 case Builtin::BI__builtin_addcs:
3189 case Builtin::BI__builtin_addc:
3190 case Builtin::BI__builtin_addcl:
3191 case Builtin::BI__builtin_addcll:
3192 case Builtin::BI__builtin_subcb:
3193 case Builtin::BI__builtin_subcs:
3194 case Builtin::BI__builtin_subc:
3195 case Builtin::BI__builtin_subcl:
3196 case Builtin::BI__builtin_subcll:
3199 case Builtin::BI__builtin_clz:
3200 case Builtin::BI__builtin_clzl:
3201 case Builtin::BI__builtin_clzll:
3202 case Builtin::BI__builtin_clzs:
3203 case Builtin::BI__builtin_clzg:
3204 case Builtin::BI__lzcnt16:
3205 case Builtin::BI__lzcnt:
3206 case Builtin::BI__lzcnt64:
3209 case Builtin::BI__builtin_ctz:
3210 case Builtin::BI__builtin_ctzl:
3211 case Builtin::BI__builtin_ctzll:
3212 case Builtin::BI__builtin_ctzs:
3213 case Builtin::BI__builtin_ctzg:
3216 case Builtin::BI__builtin_elementwise_ctlz:
3217 case Builtin::BI__builtin_elementwise_cttz:
3221 case Builtin::BI__builtin_bswap16:
3222 case Builtin::BI__builtin_bswap32:
3223 case Builtin::BI__builtin_bswap64:
3226 case Builtin::BI__atomic_always_lock_free:
3227 case Builtin::BI__atomic_is_lock_free:
3230 case Builtin::BI__c11_atomic_is_lock_free:
3233 case Builtin::BI__builtin_complex:
3236 case Builtin::BI__builtin_is_aligned:
3237 case Builtin::BI__builtin_align_up:
3238 case Builtin::BI__builtin_align_down:
3241 case Builtin::BI__builtin_assume_aligned:
3244 case clang::X86::BI__builtin_ia32_bextr_u32:
3245 case clang::X86::BI__builtin_ia32_bextr_u64:
3246 case clang::X86::BI__builtin_ia32_bextri_u32:
3247 case clang::X86::BI__builtin_ia32_bextri_u64:
3250 case clang::X86::BI__builtin_ia32_bzhi_si:
3251 case clang::X86::BI__builtin_ia32_bzhi_di:
3254 case clang::X86::BI__builtin_ia32_lzcnt_u16:
3255 case clang::X86::BI__builtin_ia32_lzcnt_u32:
3256 case clang::X86::BI__builtin_ia32_lzcnt_u64:
3259 case clang::X86::BI__builtin_ia32_tzcnt_u16:
3260 case clang::X86::BI__builtin_ia32_tzcnt_u32:
3261 case clang::X86::BI__builtin_ia32_tzcnt_u64:
3264 case clang::X86::BI__builtin_ia32_pdep_si:
3265 case clang::X86::BI__builtin_ia32_pdep_di:
3268 case clang::X86::BI__builtin_ia32_pext_si:
3269 case clang::X86::BI__builtin_ia32_pext_di:
3272 case clang::X86::BI__builtin_ia32_addcarryx_u32:
3273 case clang::X86::BI__builtin_ia32_addcarryx_u64:
3274 case clang::X86::BI__builtin_ia32_subborrow_u32:
3275 case clang::X86::BI__builtin_ia32_subborrow_u64:
3279 case Builtin::BI__builtin_os_log_format_buffer_size:
3282 case Builtin::BI__builtin_ptrauth_string_discriminator:
3285 case Builtin::BI__noop:
3289 case Builtin::BI__builtin_operator_new:
3292 case Builtin::BI__builtin_operator_delete:
3295 case Builtin::BI__arithmetic_fence:
3298 case Builtin::BI__builtin_reduce_add:
3299 case Builtin::BI__builtin_reduce_mul:
3300 case Builtin::BI__builtin_reduce_and:
3301 case Builtin::BI__builtin_reduce_or:
3302 case Builtin::BI__builtin_reduce_xor:
3303 case Builtin::BI__builtin_reduce_min:
3304 case Builtin::BI__builtin_reduce_max:
3307 case Builtin::BI__builtin_elementwise_popcount:
3308 case Builtin::BI__builtin_elementwise_bitreverse:
3312 case Builtin::BI__builtin_elementwise_abs:
3315 case Builtin::BI__builtin_memcpy:
3316 case Builtin::BImemcpy:
3317 case Builtin::BI__builtin_wmemcpy:
3318 case Builtin::BIwmemcpy:
3319 case Builtin::BI__builtin_memmove:
3320 case Builtin::BImemmove:
3321 case Builtin::BI__builtin_wmemmove:
3322 case Builtin::BIwmemmove:
3325 case Builtin::BI__builtin_memcmp:
3326 case Builtin::BImemcmp:
3327 case Builtin::BI__builtin_bcmp:
3328 case Builtin::BIbcmp:
3329 case Builtin::BI__builtin_wmemcmp:
3330 case Builtin::BIwmemcmp:
3333 case Builtin::BImemchr:
3334 case Builtin::BI__builtin_memchr:
3335 case Builtin::BIstrchr:
3336 case Builtin::BI__builtin_strchr:
3337 case Builtin::BIwmemchr:
3338 case Builtin::BI__builtin_wmemchr:
3339 case Builtin::BIwcschr:
3340 case Builtin::BI__builtin_wcschr:
3341 case Builtin::BI__builtin_char_memchr:
3344 case Builtin::BI__builtin_object_size:
3345 case Builtin::BI__builtin_dynamic_object_size:
3348 case Builtin::BI__builtin_is_within_lifetime:
3351 case Builtin::BI__builtin_elementwise_add_sat:
3354 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
3357 case Builtin::BI__builtin_elementwise_sub_sat:
3360 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
3363 case clang::X86::BI__builtin_ia32_pavgb128:
3364 case clang::X86::BI__builtin_ia32_pavgw128:
3365 case clang::X86::BI__builtin_ia32_pavgb256:
3366 case clang::X86::BI__builtin_ia32_pavgw256:
3367 case clang::X86::BI__builtin_ia32_pavgb512:
3368 case clang::X86::BI__builtin_ia32_pavgw512:
3370 llvm::APIntOps::avgCeilU);
3372 case clang::X86::BI__builtin_ia32_pmulhuw128:
3373 case clang::X86::BI__builtin_ia32_pmulhuw256:
3374 case clang::X86::BI__builtin_ia32_pmulhuw512:
3376 llvm::APIntOps::mulhu);
3378 case clang::X86::BI__builtin_ia32_pmulhw128:
3379 case clang::X86::BI__builtin_ia32_pmulhw256:
3380 case clang::X86::BI__builtin_ia32_pmulhw512:
3382 llvm::APIntOps::mulhs);
3384 case clang::X86::BI__builtin_ia32_psllv2di:
3385 case clang::X86::BI__builtin_ia32_psllv4di:
3386 case clang::X86::BI__builtin_ia32_psllv4si:
3387 case clang::X86::BI__builtin_ia32_psllv8di:
3388 case clang::X86::BI__builtin_ia32_psllv8hi:
3389 case clang::X86::BI__builtin_ia32_psllv8si:
3390 case clang::X86::BI__builtin_ia32_psllv16hi:
3391 case clang::X86::BI__builtin_ia32_psllv16si:
3392 case clang::X86::BI__builtin_ia32_psllv32hi:
3393 case clang::X86::BI__builtin_ia32_psllwi128:
3394 case clang::X86::BI__builtin_ia32_psllwi256:
3395 case clang::X86::BI__builtin_ia32_psllwi512:
3396 case clang::X86::BI__builtin_ia32_pslldi128:
3397 case clang::X86::BI__builtin_ia32_pslldi256:
3398 case clang::X86::BI__builtin_ia32_pslldi512:
3399 case clang::X86::BI__builtin_ia32_psllqi128:
3400 case clang::X86::BI__builtin_ia32_psllqi256:
3401 case clang::X86::BI__builtin_ia32_psllqi512:
3404 if (RHS.uge(LHS.getBitWidth())) {
3405 return APInt::getZero(LHS.getBitWidth());
3407 return LHS.shl(RHS.getZExtValue());
3410 case clang::X86::BI__builtin_ia32_psrav4si:
3411 case clang::X86::BI__builtin_ia32_psrav8di:
3412 case clang::X86::BI__builtin_ia32_psrav8hi:
3413 case clang::X86::BI__builtin_ia32_psrav8si:
3414 case clang::X86::BI__builtin_ia32_psrav16hi:
3415 case clang::X86::BI__builtin_ia32_psrav16si:
3416 case clang::X86::BI__builtin_ia32_psrav32hi:
3417 case clang::X86::BI__builtin_ia32_psravq128:
3418 case clang::X86::BI__builtin_ia32_psravq256:
3419 case clang::X86::BI__builtin_ia32_psrawi128:
3420 case clang::X86::BI__builtin_ia32_psrawi256:
3421 case clang::X86::BI__builtin_ia32_psrawi512:
3422 case clang::X86::BI__builtin_ia32_psradi128:
3423 case clang::X86::BI__builtin_ia32_psradi256:
3424 case clang::X86::BI__builtin_ia32_psradi512:
3425 case clang::X86::BI__builtin_ia32_psraqi128:
3426 case clang::X86::BI__builtin_ia32_psraqi256:
3427 case clang::X86::BI__builtin_ia32_psraqi512:
3430 if (RHS.uge(LHS.getBitWidth())) {
3431 return LHS.ashr(LHS.getBitWidth() - 1);
3433 return LHS.ashr(RHS.getZExtValue());
3436 case clang::X86::BI__builtin_ia32_psrlv2di:
3437 case clang::X86::BI__builtin_ia32_psrlv4di:
3438 case clang::X86::BI__builtin_ia32_psrlv4si:
3439 case clang::X86::BI__builtin_ia32_psrlv8di:
3440 case clang::X86::BI__builtin_ia32_psrlv8hi:
3441 case clang::X86::BI__builtin_ia32_psrlv8si:
3442 case clang::X86::BI__builtin_ia32_psrlv16hi:
3443 case clang::X86::BI__builtin_ia32_psrlv16si:
3444 case clang::X86::BI__builtin_ia32_psrlv32hi:
3445 case clang::X86::BI__builtin_ia32_psrlwi128:
3446 case clang::X86::BI__builtin_ia32_psrlwi256:
3447 case clang::X86::BI__builtin_ia32_psrlwi512:
3448 case clang::X86::BI__builtin_ia32_psrldi128:
3449 case clang::X86::BI__builtin_ia32_psrldi256:
3450 case clang::X86::BI__builtin_ia32_psrldi512:
3451 case clang::X86::BI__builtin_ia32_psrlqi128:
3452 case clang::X86::BI__builtin_ia32_psrlqi256:
3453 case clang::X86::BI__builtin_ia32_psrlqi512:
3456 if (RHS.uge(LHS.getBitWidth())) {
3457 return APInt::getZero(LHS.getBitWidth());
3459 return LHS.lshr(RHS.getZExtValue());
3462 case clang::X86::BI__builtin_ia32_vprotbi:
3463 case clang::X86::BI__builtin_ia32_vprotdi:
3464 case clang::X86::BI__builtin_ia32_vprotqi:
3465 case clang::X86::BI__builtin_ia32_vprotwi:
3466 case clang::X86::BI__builtin_ia32_prold128:
3467 case clang::X86::BI__builtin_ia32_prold256:
3468 case clang::X86::BI__builtin_ia32_prold512:
3469 case clang::X86::BI__builtin_ia32_prolq128:
3470 case clang::X86::BI__builtin_ia32_prolq256:
3471 case clang::X86::BI__builtin_ia32_prolq512:
3474 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
3476 case clang::X86::BI__builtin_ia32_prord128:
3477 case clang::X86::BI__builtin_ia32_prord256:
3478 case clang::X86::BI__builtin_ia32_prord512:
3479 case clang::X86::BI__builtin_ia32_prorq128:
3480 case clang::X86::BI__builtin_ia32_prorq256:
3481 case clang::X86::BI__builtin_ia32_prorq512:
3484 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
3486 case Builtin::BI__builtin_elementwise_max:
3487 case Builtin::BI__builtin_elementwise_min:
3490 case clang::X86::BI__builtin_ia32_pmuldq128:
3491 case clang::X86::BI__builtin_ia32_pmuldq256:
3492 case clang::X86::BI__builtin_ia32_pmuldq512:
3493 case clang::X86::BI__builtin_ia32_pmuludq128:
3494 case clang::X86::BI__builtin_ia32_pmuludq256:
3495 case clang::X86::BI__builtin_ia32_pmuludq512:
3498 case Builtin::BI__builtin_elementwise_fma:
3502 llvm::RoundingMode RM) {
3504 F.fusedMultiplyAdd(Y, Z, RM);
3508 case X86::BI__builtin_ia32_vpshldd128:
3509 case X86::BI__builtin_ia32_vpshldd256:
3510 case X86::BI__builtin_ia32_vpshldd512:
3511 case X86::BI__builtin_ia32_vpshldq128:
3512 case X86::BI__builtin_ia32_vpshldq256:
3513 case X86::BI__builtin_ia32_vpshldq512:
3514 case X86::BI__builtin_ia32_vpshldw128:
3515 case X86::BI__builtin_ia32_vpshldw256:
3516 case X86::BI__builtin_ia32_vpshldw512:
3520 return llvm::APIntOps::fshl(Hi, Lo, Amt);
3523 case X86::BI__builtin_ia32_vpshrdd128:
3524 case X86::BI__builtin_ia32_vpshrdd256:
3525 case X86::BI__builtin_ia32_vpshrdd512:
3526 case X86::BI__builtin_ia32_vpshrdq128:
3527 case X86::BI__builtin_ia32_vpshrdq256:
3528 case X86::BI__builtin_ia32_vpshrdq512:
3529 case X86::BI__builtin_ia32_vpshrdw128:
3530 case X86::BI__builtin_ia32_vpshrdw256:
3531 case X86::BI__builtin_ia32_vpshrdw512:
3536 return llvm::APIntOps::fshr(Hi, Lo, Amt);
3539 case clang::X86::BI__builtin_ia32_blendpd:
3540 case clang::X86::BI__builtin_ia32_blendpd256:
3541 case clang::X86::BI__builtin_ia32_blendps:
3542 case clang::X86::BI__builtin_ia32_blendps256:
3543 case clang::X86::BI__builtin_ia32_pblendw128:
3544 case clang::X86::BI__builtin_ia32_pblendw256:
3545 case clang::X86::BI__builtin_ia32_pblendd128:
3546 case clang::X86::BI__builtin_ia32_pblendd256:
3549 case clang::X86::BI__builtin_ia32_blendvpd:
3550 case clang::X86::BI__builtin_ia32_blendvpd256:
3551 case clang::X86::BI__builtin_ia32_blendvps:
3552 case clang::X86::BI__builtin_ia32_blendvps256:
3556 llvm::RoundingMode) {
return C.isNegative() ?
T : F; });
3558 case clang::X86::BI__builtin_ia32_pblendvb128:
3559 case clang::X86::BI__builtin_ia32_pblendvb256:
3562 return ((
APInt)
C).isNegative() ?
T : F;
3565 case X86::BI__builtin_ia32_selectb_128:
3566 case X86::BI__builtin_ia32_selectb_256:
3567 case X86::BI__builtin_ia32_selectb_512:
3568 case X86::BI__builtin_ia32_selectw_128:
3569 case X86::BI__builtin_ia32_selectw_256:
3570 case X86::BI__builtin_ia32_selectw_512:
3571 case X86::BI__builtin_ia32_selectd_128:
3572 case X86::BI__builtin_ia32_selectd_256:
3573 case X86::BI__builtin_ia32_selectd_512:
3574 case X86::BI__builtin_ia32_selectq_128:
3575 case X86::BI__builtin_ia32_selectq_256:
3576 case X86::BI__builtin_ia32_selectq_512:
3577 case X86::BI__builtin_ia32_selectph_128:
3578 case X86::BI__builtin_ia32_selectph_256:
3579 case X86::BI__builtin_ia32_selectph_512:
3580 case X86::BI__builtin_ia32_selectpbf_128:
3581 case X86::BI__builtin_ia32_selectpbf_256:
3582 case X86::BI__builtin_ia32_selectpbf_512:
3583 case X86::BI__builtin_ia32_selectps_128:
3584 case X86::BI__builtin_ia32_selectps_256:
3585 case X86::BI__builtin_ia32_selectps_512:
3586 case X86::BI__builtin_ia32_selectpd_128:
3587 case X86::BI__builtin_ia32_selectpd_256:
3588 case X86::BI__builtin_ia32_selectpd_512:
3591 case Builtin::BI__builtin_elementwise_fshl:
3593 llvm::APIntOps::fshl);
3594 case Builtin::BI__builtin_elementwise_fshr:
3596 llvm::APIntOps::fshr);
3600 diag::note_invalid_subexpr_in_const_expr)
3606 llvm_unreachable(
"Unhandled builtin ID");
3615 unsigned ArrayIndex = 0;
3617 for (
unsigned I = 0; I != N; ++I) {
3623 if (!RD || RD->isInvalidDecl())
3627 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
3636 int64_t Index = ArrayIndices[ArrayIndex];
3642 Result += Index * ElementSize;
3653 if (!RD || RD->isInvalidDecl())
3658 CurrentType = BaseSpec->
getType();
3668 llvm_unreachable(
"Dependent OffsetOfExpr?");
3672 IntResult =
Result.getQuantity();
3689 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
3699 Dest.deref<T>().~T();
3700 new (&Dest.deref<T>()) T();
3707 for (
const Record::Field &F : R->
fields()) {
3715 for (
unsigned I = 0, N = Desc->
getNumElems(); I != N; ++I) {
3717 Dest.deref<T>().~T();
3718 new (&Dest.deref<T>()) T();
3725 for (
unsigned I = 0, N = Desc->
getNumElems(); I != N; ++I) {
3733static bool copyComposite(InterpState &S, CodePtr OpPC,
const Pointer &Src,
3734 Pointer &Dest,
bool Activate);
3740 auto copyField = [&](
const Record::Field &F,
bool Activate) ->
bool {
3759 for (
const Record::Field &F : R->
fields()) {
3764 if (!copyField(F,
true))
3778 for (
const Record::Base &B : R->
bases()) {
3801 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
3814 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
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.
CharUnits GetAlignOfExpr(const ASTContext &Ctx, const Expr *E, UnaryExprOrTypeTrait ExprKind)
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
static bool isOneByteCharacterType(QualType T)
static bool isUserWritingOffTheEnd(const ASTContext &Ctx, const LValue &LVal)
Attempts to detect a user writing into a piece of memory that's impossible to figure out the size of ...
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
#define INT_TYPE_SWITCH_NO_BOOL(Expr, B)
#define INT_TYPE_SWITCH(Expr, B)
#define TYPE_SWITCH(Expr, B)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static QualType getPointeeType(const MemRegion *R)
Enumerates target-specific builtins in their own namespaces within namespace clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
CharUnits & getLValueOffset()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
Builtin::Context & BuiltinInfo
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
const LangOptions & getLangOpts() const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
QualType getWCharType() const
Return the unique wchar_t type available in C++ (and available as __wchar_t as a Microsoft extension)...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
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.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - 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
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
bool isConstantEvaluated(unsigned ID) const
Return true if this function can be constant evaluated by Clang frontend.
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.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
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...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Represents a function declaration or definition.
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StrictFlexArraysLevelKind
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.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ 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.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
virtual int getEHDataRegisterNumber(unsigned RegNo) const
Return the register number that __builtin_eh_return_regno would return with the specified argument.
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
QualType getType() const
Return the type wrapped by this type source info.
bool isBooleanType() const
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 ...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
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,...
bool isVectorType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
A memory block, either on the stack or in the heap.
const Descriptor * getDescriptor() const
Returns the block's descriptor.
Wrapper around boolean types.
static Boolean from(T Value)
Pointer into the code segment.
const LangOptions & getLangOpts() const
Returns the language options.
OptPrimType classify(QualType T) const
Classifies a type.
unsigned getEvalID() const
Manages dynamic memory allocations done during bytecode interpretation.
bool deallocate(const Expr *Source, const Block *BlockToDelete, InterpState &S)
Deallocate the given source+block combination.
std::optional< Form > getAllocationForm(const Expr *Source) const
Checks whether the allocation done at the given source is an array allocation.
Block * allocate(const Descriptor *D, unsigned EvalID, Form AllocForm)
Allocate ONE element of the given descriptor.
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
void copy(const APFloat &F)
llvm::FPClassTest classify() const
ComparisonCategoryResult compare(const Floating &RHS) const
APFloat::fltCategory getCategory() const
APFloat getAPFloat() const
Base class for stack frames, shared between VM and walker.
virtual const FunctionDecl * getCallee() const =0
Returns the called function's declaration.
If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Frame storing local variables.
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
SourceInfo getSource(CodePtr PC) const
Map a location to a source.
CodePtr getRetPC() const
Returns the return address of the frame.
SourceLocation getLocation(CodePtr PC) const
SourceRange getRange(CodePtr PC) const
unsigned getDepth() const
const FunctionDecl * getCallee() const override
Returns the caller.
Stack frame storing temporaries and parameters.
T pop()
Returns the value from the top of the stack and removes it.
void push(Tys &&...Args)
Constructs a value in place on the top of the stack.
void discard()
Discards the top value from the stack.
T & peek() const
Returns a reference to the value on the top of the stack.
Expr::EvalStatus & getEvalStatus() const override
Context & getContext() const
DynamicAllocator & getAllocator()
Context & Ctx
Interpreter Context.
Floating allocFloat(const llvm::fltSemantics &Sem)
llvm::SmallVector< const Block * > InitializingBlocks
List of blocks we're currently running either constructors or destructors for.
ASTContext & getASTContext() const override
InterpStack & Stk
Temporary stack.
const VarDecl * EvaluatingDecl
Declaration we're initializing/evaluting, if any.
InterpFrame * Current
The current frame.
T allocAP(unsigned BitWidth)
StdAllocatorCaller getStdAllocatorCaller(StringRef Name) const
bool inConstantContext() const
Program & P
Reference to the module containing all bytecode.
PrimType value_or(PrimType PT) const
A pointer to a memory block, live or dead.
Pointer narrow() const
Restricts the scope of an array element pointer.
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.
Pointer getArray() const
Returns the parent array.
bool isUnknownSizeArray() const
Checks if the structure is an array of unknown size.
void activate() const
Activats a field.
bool isIntegralPointer() const
QualType getType() const
Returns the type of the innermost field.
bool isArrayElement() const
Checks if the pointer points to an array.
void initializeAllElements() const
Initialize all elements of a primitive array at once.
bool isLive() const
Checks if the pointer is live.
T & elem(unsigned I) const
Dereferences the element at index I.
Pointer getBase() const
Returns a pointer to the object of which this pointer is a field.
uint64_t getByteOffset() const
Returns the byte offset from the start.
std::string toDiagnosticString(const ASTContext &Ctx) const
Converts the pointer to a string usable in diagnostics.
bool isZero() const
Checks if the pointer is null.
bool isRoot() const
Pointer points directly to a block.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
static bool pointToSameBlock(const Pointer &A, const Pointer &B)
Checks if both given pointers point to the same block.
APValue toAPValue(const ASTContext &ASTCtx) const
Converts the pointer to an APValue.
bool isOnePastEnd() const
Checks if the index is one past end.
uint64_t getIntegerRepresentation() const
const FieldDecl * getField() const
Returns the field information.
Pointer expand() const
Expands a pointer to the containing array, undoing narrowing.
bool isBlockPointer() const
const Block * block() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
bool isVirtualBaseClass() const
bool isBaseClass() const
Checks if a structure is a base class.
size_t elemSize() const
Returns the element size of the innermost field.
bool canBeInitialized() const
If this pointer has an InlineDescriptor we can use to initialize.
Lifetime getLifetime() const
void initialize() const
Initializes a field.
bool isField() const
Checks if the item is a field in an object.
const Record * getRecord() const
Returns the record descriptor of a class.
Descriptor * createDescriptor(const DeclTy &D, PrimType T, const Type *SourceTy=nullptr, Descriptor::MetadataSize MDSize=std::nullopt, bool IsConst=false, bool IsTemporary=false, bool IsMutable=false, bool IsVolatile=false)
Creates a descriptor for a primitive type.
Structure/Class descriptor.
const RecordDecl * getDecl() const
Returns the underlying declaration.
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
Describes the statement/declaration an opcode was generated from.
OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId)
Add a note to a prior diagnostic.
DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId)
Directly reports a diagnostic message.
OptionalDiagnostic FFDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation could not be folded (FF => FoldFailure)
const LangOptions & getLangOpts() const
OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation does not produce a C++11 core constant expression.
bool checkingPotentialConstantExpression() const
Are we checking whether the expression is a potential constant expression?
Defines the clang::TargetInfo interface.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E, OSLogBufferLayout &layout)
static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC, const CallExpr *Call)
static void assignInteger(InterpState &S, const Pointer &Dest, PrimType ValueT, const APSInt &Value)
bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, BitcastBuffer &Buffer, bool ReturnOnUninit)
static Floating abs(InterpState &S, const Floating &In)
static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin)
static bool interp__builtin_elementwise_maxmin(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinID)
static bool interp__builtin_bswap(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_elementwise_triop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &, const APSInt &)> Fn)
static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_assume(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool CheckNewDeleteForms(InterpState &S, CodePtr OpPC, DynamicAllocator::Form AllocForm, DynamicAllocator::Form DeleteForm, const Descriptor *D, const Expr *NewExpr)
Diagnose mismatched new[]/delete or new/delete[] pairs.
static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Defined as __builtin_isnan(...), to accommodate the fact that it can take a float,...
static llvm::RoundingMode getRoundingMode(FPOptions FPO)
static bool interp__builtin_elementwise_countzeroes(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
Can be called with an integer or vector as the first and only parameter.
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin)
static bool interp__builtin_blend(InterpState &S, CodePtr OpPC, const CallExpr *Call)
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}...
static bool interp__builtin_operator_delete(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
bool __atomic_always_lock_free(size_t, void const volatile*) bool __atomic_is_lock_free(size_t,...
static llvm::APSInt convertBoolVectorToInt(const Pointer &Val)
static bool interp__builtin_move(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer points to a mutable field.
static bool interp__builtin_ia32_lzcnt(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
__builtin_is_aligned() __builtin_align_up() __builtin_align_down() The first parameter is either an i...
static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, bool Right)
rotateleft(value, amount)
static bool Activate(InterpState &S, CodePtr OpPC)
static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
(CarryIn, LHS, RHS, Result)
static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool isOneByteCharacterType(QualType T)
Determine if T is a character type for which we guarantee that sizeof(T) == 1.
static unsigned computePointerOffset(const ASTContext &ASTCtx, const Pointer &Ptr)
Compute the byte offset of Ptr in the full declaration.
static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a value can be loaded from a block.
static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinOp)
static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool CheckSign, const CallExpr *Call)
static bool interp__builtin_os_log_format_buffer_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, ArrayRef< int64_t > ArrayIndices, int64_t &Result)
Interpret an offsetof operation.
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
static bool pointsToLastObject(const Pointer &Ptr)
Does Ptr point to the last subobject?
static bool interp__builtin_select(InterpState &S, CodePtr OpPC, const CallExpr *Call)
AVX512 predicated move: "Result = Mask[] ? LHS[] : RHS[]".
static bool interp__builtin_ia32_pmul(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinID)
static void discard(InterpStack &Stk, PrimType T)
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
Five int values followed by one floating value.
static bool interp__builtin_abs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp_floating_comparison(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue)
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_c11_atomic_is_lock_free(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool __c11_atomic_is_lock_free(size_t)
static void zeroAll(Pointer &Dest)
static bool interp__builtin_elementwise_int_binop(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APInt(const APSInt &, const APSInt &)> Fn)
static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_arithmetic_fence(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 CallExpr *Call)
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, uint32_t BuiltinID)
Interpret a builtin function.
static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
__builtin_complex(Float A, float B);
bool CheckDummy(InterpState &S, CodePtr OpPC, const Block *B, AccessKinds AK)
Checks if a pointer is a dummy pointer.
static bool interp__builtin_assume_aligned(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
__builtin_assume_aligned(Ptr, Alignment[, ExtraOffset])
static bool interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_memchr(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
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_operator_new(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
static bool interp__builtin_elementwise_abs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
Can be called with an integer or vector as the first and only parameter.
static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_signbit(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool Error(InterpState &S, CodePtr OpPC)
Do nothing and just abort execution.
static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned ID)
static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned ID)
static bool interp__builtin_elementwise_triop_fp(InterpState &S, CodePtr OpPC, const CallExpr *Call, llvm::function_ref< APFloat(const APFloat &, const APFloat &, const APFloat &, llvm::RoundingMode)> Fn)
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_object_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinOp)
Three integral values followed by a pointer (lhs, rhs, carry, carryOut).
bool CheckArraySize(InterpState &S, CodePtr OpPC, uint64_t NumElems)
static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, unsigned BuiltinID)
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static APSInt popToAPSInt(InterpStack &Stk, PrimType T)
static std::optional< unsigned > computeFullDescSize(const ASTContext &ASTCtx, const Descriptor *Desc)
static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
First parameter to __builtin_isfpclass is the floating value, the second one is an integral value.
static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call, bool Signaling)
static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
constexpr bool isIntegralType(PrimType T)
static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static LLVM_ATTRIBUTE_UNUSED bool isNoopBuiltin(unsigned ID)
static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC, unsigned ID)
static QualType getElemType(const Pointer &P)
static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static void swapBytes(std::byte *M, size_t N)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Track what bits have been initialized to known values and which ones have indeterminate value.
std::unique_ptr< std::byte[]> Data
size_t getQuantity() const
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.
QualType getElemQualType() const
bool isCompositeArray() const
Checks if the descriptor is of an array of composites.
const ValueDecl * asValueDecl() const
static constexpr unsigned MaxArrayElemBytes
Maximum number of bytes to be used for array elements.
const Decl * asDecl() const
static constexpr MetadataSize InlineDescMD
unsigned getElemSize() const
returns the size of an element when the structure is viewed as an array.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.
const VarDecl * asVarDecl() const
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.
const Expr * asExpr() const
bool isArray() const
Checks if the descriptor is of an array.
Mapping from primitive types to their representation.