8#include "../ExprConstShared.h"
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)); });
126 return AT->getElementType();
135 auto Loc = S.Current->getSource(OpPC);
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))
163 unsigned Depth = S.Current->getDepth();
165 return F && F->isInStdNamespace() && F->getIdentifier() &&
166 F->getIdentifier()->isStr(
"is_constant_evaluated");
171 if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
172 S.getEvalStatus().
Diag &&
177 diag::warn_is_constant_evaluated_always_true_constexpr)
180 S.report(
Call->getExprLoc(),
181 diag::warn_is_constant_evaluated_always_true_constexpr)
182 <<
"__builtin_is_constant_evaluated" <<
Call->getSourceRange();
194 assert(
Call->getNumArgs() == 1);
195 discard(S.Stk, *S.getContext().classify(
Call->getArg(0)));
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)
306 if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
308 assert(ElemSize == AC.getTypeSizeInChars(AC.getWCharType()).getQuantity());
312 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
321 Val = ElemPtr.
deref<uint8_t>();
324 Val = ElemPtr.
deref<uint16_t>();
327 Val = ElemPtr.
deref<uint32_t>();
330 llvm_unreachable(
"Unsupported char size");
355 for (
unsigned I = 0;; ++I) {
361 if (Elem.
deref<int8_t>() == 0)
364 Str += Elem.
deref<
char>();
369 Fill = llvm::APInt(32, 0);
370 else if (StringRef(Str).getAsInteger(0, Fill))
373 const llvm::fltSemantics &TargetSemantics =
375 Call->getDirectCallee()->getReturnType());
381 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
384 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
393 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
396 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
406 const llvm::fltSemantics &TargetSemantics =
408 Call->getDirectCallee()->getReturnType());
411 Result.copy(APFloat::getInf(TargetSemantics));
484 bool IsInf = F.isInfinity();
487 pushInteger(S, IsInf ? (F.isNegative() ? -1 : 1) : 0,
Call->getType());
547 case Builtin::BI__builtin_isgreater:
549 case Builtin::BI__builtin_isgreaterequal:
551 case Builtin::BI__builtin_isless:
553 case Builtin::BI__builtin_islessequal:
555 case Builtin::BI__builtin_islessgreater: {
560 case Builtin::BI__builtin_isunordered:
563 llvm_unreachable(
"Unexpected builtin ID: Should be a floating point "
564 "comparison function");
576 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
580 int32_t
Result =
static_cast<int32_t
>(
581 (F.
classify() & std::move(FPClassArg)).getZExtValue());
594 PrimType IntT = *S.getContext().classify(
Call->getArg(0));
596 for (
unsigned I = 0; I != 5; ++I)
604 case APFloat::fcInfinity:
607 case APFloat::fcNormal:
610 case APFloat::fcZero:
623 if (!In.isNegative())
626 Floating Output = S.allocFloat(In.getSemantics());
648 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
651 APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
false))
653 if (Val.isNegative())
663 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
667 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
677 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
686 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
688 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
695 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
705 assert(
Call->getNumArgs() == 1);
710 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
722 unsigned NumArgs =
Call->getNumArgs();
723 assert(NumArgs == 2 || NumArgs == 3);
725 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
739 PrimType AmountT = *S.getContext().classify(
Call->getArg(1)->getType());
740 PrimType ValueT = *S.getContext().classify(
Call->getArg(0)->getType());
760 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
763 uint64_t N =
Value.countr_zero();
772 assert(
Call->getArg(0)->isLValue());
775 "Unsupported pointer type passed to __builtin_addressof()");
783 return Call->getDirectCallee()->isConstexpr();
789 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
801 unsigned BuiltinOp) {
806 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
807 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
810 QualType ResultType =
Call->getArg(2)->getType()->getPointeeType();
811 PrimType ResultT = *S.getContext().classify(ResultType);
815 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
816 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
817 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
818 bool IsSigned = LHS.isSigned() || RHS.isSigned() ||
820 bool AllSigned = LHS.isSigned() && RHS.isSigned() &&
822 uint64_t LHSSize = LHS.getBitWidth();
823 uint64_t RHSSize = RHS.getBitWidth();
825 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
831 if (IsSigned && !AllSigned)
834 LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
835 RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
842 llvm_unreachable(
"Invalid value for BuiltinOp");
843 case Builtin::BI__builtin_add_overflow:
844 case Builtin::BI__builtin_sadd_overflow:
845 case Builtin::BI__builtin_saddl_overflow:
846 case Builtin::BI__builtin_saddll_overflow:
847 case Builtin::BI__builtin_uadd_overflow:
848 case Builtin::BI__builtin_uaddl_overflow:
849 case Builtin::BI__builtin_uaddll_overflow:
850 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
851 : LHS.uadd_ov(RHS, Overflow);
853 case Builtin::BI__builtin_sub_overflow:
854 case Builtin::BI__builtin_ssub_overflow:
855 case Builtin::BI__builtin_ssubl_overflow:
856 case Builtin::BI__builtin_ssubll_overflow:
857 case Builtin::BI__builtin_usub_overflow:
858 case Builtin::BI__builtin_usubl_overflow:
859 case Builtin::BI__builtin_usubll_overflow:
860 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
861 : LHS.usub_ov(RHS, Overflow);
863 case Builtin::BI__builtin_mul_overflow:
864 case Builtin::BI__builtin_smul_overflow:
865 case Builtin::BI__builtin_smull_overflow:
866 case Builtin::BI__builtin_smulll_overflow:
867 case Builtin::BI__builtin_umul_overflow:
868 case Builtin::BI__builtin_umull_overflow:
869 case Builtin::BI__builtin_umulll_overflow:
870 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
871 : LHS.umul_ov(RHS, Overflow);
877 if (BuiltinOp == Builtin::BI__builtin_add_overflow ||
878 BuiltinOp == Builtin::BI__builtin_sub_overflow ||
879 BuiltinOp == Builtin::BI__builtin_mul_overflow) {
887 if (!APSInt::isSameValue(Temp,
Result))
897 assert(
Call->getDirectCallee()->getReturnType()->isBooleanType());
907 PrimType LHST = *S.getContext().classify(
Call->getArg(0)->getType());
908 PrimType RHST = *S.getContext().classify(
Call->getArg(1)->getType());
920 bool FirstOverflowed =
false;
921 bool SecondOverflowed =
false;
924 llvm_unreachable(
"Invalid value for BuiltinOp");
925 case Builtin::BI__builtin_addcb:
926 case Builtin::BI__builtin_addcs:
927 case Builtin::BI__builtin_addc:
928 case Builtin::BI__builtin_addcl:
929 case Builtin::BI__builtin_addcll:
931 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
933 case Builtin::BI__builtin_subcb:
934 case Builtin::BI__builtin_subcs:
935 case Builtin::BI__builtin_subc:
936 case Builtin::BI__builtin_subcl:
937 case Builtin::BI__builtin_subcll:
939 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
944 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
946 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
947 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
951 assert(
Call->getType() ==
Call->getArg(0)->getType());
958 unsigned BuiltinOp) {
960 std::optional<APSInt> Fallback;
961 if (BuiltinOp == Builtin::BI__builtin_clzg &&
Call->getNumArgs() == 2) {
962 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
966 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
970 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
976 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
977 BuiltinOp != Builtin::BI__lzcnt &&
978 BuiltinOp != Builtin::BI__lzcnt64;
996 unsigned BuiltinID) {
997 std::optional<APSInt> Fallback;
998 if (BuiltinID == Builtin::BI__builtin_ctzg &&
Call->getNumArgs() == 2) {
999 PrimType FallbackT = *S.getContext().classify(
Call->getArg(1));
1003 if (
Call->getArg(0)->getType()->isExtVectorBoolType()) {
1007 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1026 PrimType ReturnT = *S.getContext().classify(
Call->getType());
1027 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1029 assert(Val.getActiveBits() <= 64);
1032 { S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
1041 unsigned BuiltinOp) {
1042 auto returnBool = [&S](
bool Value) ->
bool {
1047 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1062 if (Size.isPowerOfTwo()) {
1064 unsigned InlineWidthBits =
1071 return returnBool(
true);
1074 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
1076 return returnBool(
true);
1080 if (
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
1081 return returnBool(
true);
1084 const Expr *PtrArg =
Call->getArg(1);
1086 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
1089 if (ICE->getCastKind() == CK_BitCast)
1090 PtrArg = ICE->getSubExpr();
1098 return returnBool(
true);
1104 if (BuiltinOp == Builtin::BI__atomic_always_lock_free)
1105 return returnBool(
false);
1115 PrimType ValT = *S.getContext().classify(
Call->getArg(0));
1118 auto returnBool = [&S](
bool Value) ->
bool {
1124 if (Size.isPowerOfTwo()) {
1126 unsigned InlineWidthBits =
1129 return returnBool(
true);
1145 Result.initializeAllElements();
1158 unsigned BuiltinOp) {
1159 PrimType AlignmentT = *S.Ctx.classify(
Call->getArg(1));
1162 if (Alignment < 0 || !Alignment.isPowerOf2()) {
1163 S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1167 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1168 if (APSInt::compareValues(Alignment, MaxValue) > 0) {
1169 S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1170 << MaxValue <<
Call->getArg(0)->getType() << Alignment;
1180 APInt AlignMinusOne = Alignment.extOrTrunc(Src.getBitWidth()) - 1;
1181 if (BuiltinOp == Builtin::BI__builtin_align_up) {
1183 APSInt((Src + AlignMinusOne) & ~AlignMinusOne, Src.isUnsigned());
1185 }
else if (BuiltinOp == Builtin::BI__builtin_align_down) {
1186 APSInt AlignedVal =
APSInt(Src & ~AlignMinusOne, Src.isUnsigned());
1189 assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1190 S.Stk.push<
Boolean>((Src & AlignMinusOne) == 0);
1195 assert(FirstArgT ==
PT_Ptr);
1205 if (BuiltinOp == Builtin::BI__builtin_is_aligned) {
1220 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1225 assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1226 BuiltinOp == Builtin::BI__builtin_align_up);
1241 assert(Alignment.getBitWidth() <= 64 &&
1242 "Cannot handle > 64-bit address-space");
1243 uint64_t Alignment64 = Alignment.getZExtValue();
1246 ? llvm::alignDown(PtrOffset, Alignment64)
1247 : llvm::alignTo(PtrOffset, Alignment64));
1254 S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1262 assert(
Call->getNumArgs() == 2 ||
Call->getNumArgs() == 3);
1264 std::optional<APSInt> ExtraOffset;
1265 if (
Call->getNumArgs() == 3)
1281 if (BaseAlignment < Align) {
1282 S.CCEDiag(
Call->getArg(0),
1283 diag::note_constexpr_baa_insufficient_alignment)
1284 << 0 << BaseAlignment.
getQuantity() << Align.getQuantity();
1293 if (AVOffset.
alignTo(Align) != AVOffset) {
1295 S.CCEDiag(
Call->getArg(0),
1296 diag::note_constexpr_baa_insufficient_alignment)
1297 << 1 << AVOffset.
getQuantity() << Align.getQuantity();
1299 S.CCEDiag(
Call->getArg(0),
1300 diag::note_constexpr_baa_value_insufficient_alignment)
1312 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1313 !
Call->getArg(1)->getType()->isIntegerType())
1321 unsigned BitWidth = Val.getBitWidth();
1322 uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
1323 uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
1324 Length = Length > BitWidth ? BitWidth : Length;
1327 if (Length == 0 || Shift >= BitWidth) {
1332 uint64_t
Result = Val.getZExtValue() >> Shift;
1333 Result &= llvm::maskTrailingOnes<uint64_t>(Length);
1342 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1343 !
Call->getArg(1)->getType()->isIntegerType() ||
1353 unsigned BitWidth = Val.getBitWidth();
1354 uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
1356 if (Index < BitWidth)
1357 Val.clearHighBits(BitWidth - Index);
1368 !
Call->getArg(0)->getType()->isIntegerType())
1372 pushInteger(S, Val.countLeadingZeros(), CallType);
1381 !
Call->getArg(0)->getType()->isIntegerType())
1385 pushInteger(S, Val.countTrailingZeros(), CallType);
1392 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1393 !
Call->getArg(1)->getType()->isIntegerType())
1402 unsigned BitWidth = Val.getBitWidth();
1404 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I) {
1406 Result.setBitVal(I, Val[
P++]);
1415 if (
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1416 !
Call->getArg(1)->getType()->isIntegerType())
1425 unsigned BitWidth = Val.getBitWidth();
1427 for (
unsigned I = 0,
P = 0; I != BitWidth; ++I) {
1429 Result.setBitVal(
P++, Val[I]);
1440 unsigned BuiltinOp) {
1441 if (
Call->getNumArgs() != 4 || !
Call->getArg(0)->getType()->isIntegerType() ||
1442 !
Call->getArg(1)->getType()->isIntegerType() ||
1443 !
Call->getArg(2)->getType()->isIntegerType())
1448 PrimType CarryInT = *S.getContext().classify(
Call->getArg(0));
1449 PrimType LHST = *S.getContext().classify(
Call->getArg(1));
1450 PrimType RHST = *S.getContext().classify(
Call->getArg(2));
1455 bool IsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
1456 BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
1458 unsigned BitWidth = LHS.getBitWidth();
1459 unsigned CarryInBit = CarryIn.ugt(0) ? 1 : 0;
1461 IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
1462 : (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
1466 APSInt(ExResult.extractBits(1, BitWidth),
true);
1468 QualType CarryOutType =
Call->getArg(3)->getType()->getPointeeType();
1469 PrimType CarryOutT = *S.getContext().classify(CarryOutType);
1491 const auto &Ptr = S.Stk.pop<
Pointer>();
1492 assert(Ptr.getFieldDesc()->isPrimitiveArray());
1496 assert(Ptr.getFieldDesc()->getNumElems() >= 1);
1497 StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1498 uint64_t
Result = getPointerAuthStableSipHash(R);
1509 auto [NewCall, ElemType] = S.getStdAllocatorCaller(
"allocate");
1511 if (ElemType.isNull()) {
1513 ? diag::note_constexpr_new_untyped
1514 : diag::note_constexpr_new);
1519 if (ElemType->isIncompleteType() || ElemType->isFunctionType()) {
1520 S.FFDiag(
Call, diag::note_constexpr_new_not_complete_object_type)
1521 << (ElemType->isIncompleteType() ? 0 : 1) << ElemType;
1528 unsigned NumArgs =
Call->getNumArgs();
1529 assert(NumArgs >= 1);
1532 if (
Call->getArg(NumArgs - 1)->getType()->isNothrowT())
1536 Args = Args.drop_front();
1539 for (
const Expr *Arg : Args)
1540 discard(S.Stk, *S.getContext().classify(Arg));
1545 assert(!ElemSize.
isZero());
1548 APInt NumElems, Remainder;
1550 APInt::udivrem(
Bytes, ElemSizeAP, NumElems, Remainder);
1551 if (Remainder != 0) {
1553 S.FFDiag(
Call, diag::note_constexpr_operator_new_bad_size)
1559 if (NumElems.getActiveBits() >
1564 S.FFDiag(
Loc, diag::note_constexpr_new_too_large)
1565 << NumElems.getZExtValue();
1572 bool IsArray = NumElems.ugt(1);
1573 OptPrimType ElemT = S.getContext().classify(ElemType);
1577 Allocator.allocate(NewCall, *ElemT, NumElems.getZExtValue(),
1589 S.P.createDescriptor(NewCall, ElemType.getTypePtr(), std::nullopt);
1591 Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
1604 Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1614 const Expr *Source =
nullptr;
1615 const Block *BlockToDelete =
nullptr;
1617 if (S.checkingPotentialConstantExpression()) {
1623 if (!S.getStdAllocatorCaller(
"deallocate")) {
1633 S.CCEDiag(
Call, diag::note_constexpr_deallocate_null);
1638 BlockToDelete = Ptr.
block();
1641 S.FFDiag(
Call, diag::note_constexpr_delete_not_heap_alloc)
1647 assert(BlockToDelete);
1651 std::optional<DynamicAllocator::Form> AllocForm =
1652 Allocator.getAllocationForm(Source);
1654 if (!Allocator.deallocate(Source, BlockToDelete, S)) {
1657 S.FFDiag(
Loc, diag::note_constexpr_double_delete);
1680 assert(
Call->getType() == ElemType);
1681 PrimType ElemT = *S.getContext().classify(ElemType);
1686 unsigned BitWidth =
Result.bitWidth();
1687 for (
unsigned I = 1; I != NumElems; ++I) {
1691 if (ID == Builtin::BI__builtin_reduce_add) {
1693 unsigned OverflowBits = BitWidth + 1;
1695 (PrevResult.toAPSInt(OverflowBits) +
1696 Elem.toAPSInt(OverflowBits)));
1699 }
else if (ID == Builtin::BI__builtin_reduce_mul) {
1701 unsigned OverflowBits = BitWidth * 2;
1703 (PrevResult.toAPSInt(OverflowBits) *
1704 Elem.toAPSInt(OverflowBits)));
1708 }
else if (ID == Builtin::BI__builtin_reduce_and) {
1710 }
else if (ID == Builtin::BI__builtin_reduce_or) {
1712 }
else if (ID == Builtin::BI__builtin_reduce_xor) {
1714 }
else if (ID == Builtin::BI__builtin_reduce_min) {
1717 }
else if (ID == Builtin::BI__builtin_reduce_max) {
1721 llvm_unreachable(
"Unhandled vector reduce builtin");
1733 unsigned BuiltinID) {
1734 assert(
Call->getNumArgs() == 1);
1737 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
1752 assert(
Call->getArg(0)->getType()->isVectorType());
1761 PrimType ElemT = *S.getContext().classify(ElemType);
1764 for (
unsigned I = 0; I != NumElems; ++I) {
1767 Dst.
elem<
T>(I) = T::from(
static_cast<T>(
1785 unsigned BuiltinID) {
1786 assert(
Call->getNumArgs() == 1);
1787 if (
Call->getArg(0)->getType()->isIntegerType()) {
1788 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
1791 if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1799 assert(
Call->getArg(0)->getType()->isVectorType());
1808 PrimType ElemT = *S.getContext().classify(ElemType);
1812 for (
unsigned I = 0; I != NumElems; ++I) {
1814 if (BuiltinID == Builtin::BI__builtin_elementwise_popcount) {
1815 Dst.
elem<
T>(I) = T::from(Arg.
elem<
T>(I).toAPSInt().popcount());
1818 T::from(Arg.
elem<
T>(I).toAPSInt().reverseBits().getZExtValue());
1832 unsigned BuiltinID) {
1833 const bool HasZeroArg =
Call->getNumArgs() == 2;
1834 const bool IsCTTZ = BuiltinID == Builtin::BI__builtin_elementwise_cttz;
1835 assert(
Call->getNumArgs() == 1 || HasZeroArg);
1836 if (
Call->getArg(0)->getType()->isIntegerType()) {
1837 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
1839 std::optional<APSInt> ZeroVal;
1852 S.FFDiag(S.Current->getSource(OpPC),
1853 diag::note_constexpr_countzeroes_zero)
1858 if (BuiltinID == Builtin::BI__builtin_elementwise_ctlz) {
1869 assert(
Call->getArg(1)->getType()->isVectorType() &&
1871 Call->getArg(1)->getType()));
1873 ZeroArg = S.Stk.pop<
Pointer>();
1876 assert(
Call->getArg(0)->getType()->isVectorType());
1885 PrimType ElemT = *S.getContext().classify(ElemType);
1889 for (
unsigned I = 0; I != NumElems; ++I) {
1892 if (EltVal.isZero()) {
1894 Dst.atIndex(I).deref<T>() = ZeroArg.atIndex(I).deref<T>();
1898 S.FFDiag(S.Current->getSource(OpPC),
1899 diag::note_constexpr_countzeroes_zero)
1903 }
else if (IsCTTZ) {
1904 Dst.
atIndex(I).deref<T>() = T::from(EltVal.countTrailingZeros());
1906 Dst.
atIndex(I).deref<T>() = T::from(EltVal.countLeadingZeros());
1918 assert(
Call->getNumArgs() == 3);
1925 assert(!Size.isSigned() &&
"memcpy and friends take an unsigned size");
1927 if (ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
1931 (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove ||
1932 ID == Builtin::BI__builtin_wmemmove || ID == Builtin::BIwmemmove);
1933 bool WChar = ID == Builtin::BIwmemcpy || ID == Builtin::BIwmemmove ||
1934 ID == Builtin::BI__builtin_wmemcpy ||
1935 ID == Builtin::BI__builtin_wmemmove;
1938 if (Size.isZero()) {
1943 if (SrcPtr.
isZero() || DestPtr.isZero()) {
1945 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
1946 << Move << WChar << !SrcPtr.
isZero()
1953 std::string DiagVal =
"(void *)";
1956 : std::to_string(DestPtr.getIntegerRepresentation());
1957 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
1958 << Move << WChar << DestPtr.isIntegralPointer() << DiagVal;
1963 if (DestPtr.isDummy() || SrcPtr.
isDummy())
1966 if (DestPtr.getType()->isIncompleteType()) {
1967 S.FFDiag(S.Current->getSource(OpPC),
1968 diag::note_constexpr_memcpy_incomplete_type)
1969 << Move << DestPtr.getType();
1973 S.FFDiag(S.Current->getSource(OpPC),
1974 diag::note_constexpr_memcpy_incomplete_type)
1981 S.FFDiag(S.Current->getSource(OpPC),
1982 diag::note_constexpr_memcpy_incomplete_type)
1983 << Move << DestElemType;
1987 size_t RemainingDestElems;
1988 if (DestPtr.getFieldDesc()->isArray()) {
1989 RemainingDestElems = DestPtr.isUnknownSizeArray()
1991 : (DestPtr.getNumElems() - DestPtr.getIndex());
1993 RemainingDestElems = 1;
1998 uint64_t WCharSize =
2000 Size *=
APSInt(
APInt(Size.getBitWidth(), WCharSize,
false),
2004 if (Size.urem(DestElemSize) != 0) {
2005 S.FFDiag(S.Current->getSource(OpPC),
2006 diag::note_constexpr_memcpy_unsupported)
2007 << Move << WChar << 0 << DestElemType << Size << DestElemSize;
2012 size_t RemainingSrcElems;
2018 RemainingSrcElems = 1;
2023 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_type_pun)
2024 << Move << SrcElemType << DestElemType;
2029 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_nontrivial)
2030 << Move << DestElemType;
2035 size_t RemainingDestBytes = RemainingDestElems * DestElemSize;
2036 size_t RemainingSrcBytes = RemainingSrcElems * SrcElemSize;
2037 if (Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) {
2038 APInt N = Size.udiv(DestElemSize);
2039 S.FFDiag(S.Current->getSource(OpPC),
2040 diag::note_constexpr_memcpy_unsupported)
2041 << Move << WChar << (Size.ugt(RemainingSrcBytes) ? 1 : 2)
2042 << DestElemType <<
toString(N, 10,
false);
2047 if (!Move && Pointer::pointToSameBlock(SrcPtr, DestPtr)) {
2059 unsigned N = Size.getZExtValue();
2061 if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||
2062 (DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) {
2063 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_overlap)
2069 assert(Size.getZExtValue() % DestElemSize == 0);
2086 assert(
Call->getNumArgs() == 3);
2092 if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
2093 ID == Builtin::BIwmemcmp)
2096 if (Size.isZero()) {
2102 (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);
2111 S.FFDiag(S.Current->getSource(OpPC),
2112 diag::note_constexpr_memcmp_unsupported)
2118 if (PtrA.isDummy() || PtrB.
isDummy())
2141 unsigned ElemSize = 1;
2146 size_t ByteSize = Size.getZExtValue() * ElemSize;
2147 size_t CmpSize = std::min(MinBufferSize, ByteSize);
2149 for (
size_t I = 0; I != CmpSize; I += ElemSize) {
2152 T A = *reinterpret_cast<T *>(BufferA.Data.get() + I);
2153 T B = *reinterpret_cast<T *>(BufferB.Data.get() + I);
2155 pushInteger(S, -1, Call->getType());
2164 std::byte A = BufferA.
Data[I];
2165 std::byte B = BufferB.
Data[I];
2180 if (ByteSize <= CmpSize) {
2181 pushInteger(S, 0,
Call->getType());
2189 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
2190 <<
AK_Read << S.Current->getRange(OpPC);
2198 if (ID == Builtin::BImemchr || ID == Builtin::BIwcschr ||
2199 ID == Builtin::BIstrchr || ID == Builtin::BIwmemchr)
2202 std::optional<APSInt> MaxLength;
2203 PrimType DesiredT = *S.getContext().classify(
Call->getArg(1));
2204 if (
Call->getNumArgs() == 3) {
2205 PrimType MaxT = *S.getContext().classify(
Call->getArg(2));
2211 if (MaxLength && MaxLength->isZero()) {
2218 S.FFDiag(S.Current->getSource(OpPC),
2219 diag::note_constexpr_ltor_incomplete_type)
2226 S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_null)
2234 bool IsRawByte = ID == Builtin::BImemchr || ID == Builtin::BI__builtin_memchr;
2238 S.FFDiag(S.Current->getSource(OpPC),
2239 diag::note_constexpr_memchr_unsupported)
2244 if (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr) {
2254 uint64_t DesiredVal;
2255 if (ID == Builtin::BIwmemchr || ID == Builtin::BI__builtin_wmemchr ||
2256 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr) {
2258 DesiredVal = Desired.getZExtValue();
2264 (ID == Builtin::BIstrchr || ID == Builtin::BI__builtin_strchr ||
2265 ID == Builtin::BIwcschr || ID == Builtin::BI__builtin_wcschr);
2274 (Index + Step) > 0 ? Ptr.
atIndex(Index + Step) : Ptr;
2281 ElemT, {
V =
static_cast<uint64_t
>(ElemPtr.
deref<
T>().toUnsigned()); });
2283 if (
V == DesiredVal) {
2288 if (StopAtZero &&
V == 0)
2292 if (MaxLength && Step == MaxLength->getZExtValue())
2316 return std::nullopt;
2322 unsigned Result = 0;
2325 while (
P.isField() ||
P.isArrayElement()) {
2329 if (
P.isArrayElement()) {
2332 if (
P.isOnePastEnd())
2333 Result += ElemSize *
P.getNumElems();
2335 Result += ElemSize *
P.getIndex();
2336 P =
P.expand().getArray();
2337 }
else if (
P.isBaseClass()) {
2338 const auto *RD = cast<CXXRecordDecl>(
D->asDecl());
2341 const Record *BaseRecord =
P.getRecord();
2349 }
else if (
P.isField()) {
2354 uint64_t FieldOffset =
2357 Result += FieldOffset;
2360 llvm_unreachable(
"Unhandled descriptor type");
2369 while (!
P.isRoot()) {
2371 if (
P.isArrayElement()) {
2372 P =
P.expand().getArray();
2375 if (
P.isBaseClass()) {
2376 if (
P.getRecord()->getNumFields() > 0)
2384 assert(
P.getField());
2385 if (
P.getField()->getFieldIndex() != R->getNumFields() - 1)
2396 auto isFlexibleArrayMember = [&](
const Descriptor *FieldDesc) {
2398 FAMKind StrictFlexArraysLevel =
2401 if (StrictFlexArraysLevel == FAMKind::Default)
2404 unsigned NumElems = FieldDesc->getNumElems();
2405 if (NumElems == 0 && StrictFlexArraysLevel != FAMKind::IncompleteOnly)
2408 if (NumElems == 1 && StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
2418 isFlexibleArrayMember(FieldDesc);
2425 PrimType KindT = *S.getContext().classify(
Call->getArg(1));
2431 unsigned Kind =
popToAPSInt(S.Stk, KindT).getZExtValue();
2432 assert(Kind <= 3 &&
"unexpected kind");
2433 bool UseFieldDesc = (Kind & 1u);
2434 bool ReportMinimum = (Kind & 2u);
2437 if (
Call->getArg(0)->HasSideEffects(ASTCtx)) {
2440 pushInteger(S, Kind <= 1 ? -1 : 0, Call->getType());
2455 if (!UseFieldDesc || DetermineForCompleteObject) {
2457 if (ReportMinimum && !DetermineForCompleteObject)
2480 unsigned ByteOffset;
2492 assert(ByteOffset <= *FullSize);
2493 unsigned Result = *FullSize - ByteOffset;
2502 if (!S.inConstantContext())
2507 auto Error = [&](
int Diag) {
2508 bool CalledFromStd =
false;
2509 const auto *Callee = S.Current->getCallee();
2510 if (Callee && Callee->isInStdNamespace()) {
2514 S.CCEDiag(CalledFromStd
2515 ? S.Current->Caller->getSource(S.Current->getRetPC())
2516 : S.Current->getSource(OpPC),
2517 diag::err_invalid_is_within_lifetime)
2518 << (CalledFromStd ?
"std::is_within_lifetime"
2519 :
"__builtin_is_within_lifetime")
2529 bool Result = Ptr.
getLifetime() != Lifetime::Ended;
2542 if (llvm::is_contained(S.InitializingBlocks, Ptr.
block()))
2554 assert(
Call->getNumArgs() == 2);
2557 if (!
Call->getArg(0)->getType()->isVectorType()) {
2558 assert(!
Call->getArg(1)->getType()->isVectorType());
2560 S.Stk, *S.getContext().classify(
Call->getArg(1)->getType()));
2562 S.Stk, *S.getContext().classify(
Call->getArg(0)->getType()));
2568 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2569 assert(VT->getElementType()->isIntegralOrEnumerationType());
2570 PrimType ElemT = *S.getContext().classify(VT->getElementType());
2571 unsigned NumElems = VT->getNumElements();
2572 bool DestUnsigned =
Call->getType()->isUnsignedIntegerOrEnumerationType();
2575 if (!
Call->getArg(1)->getType()->isVectorType()) {
2576 assert(
Call->getArg(1)->getType()->isIntegralOrEnumerationType());
2579 S.Stk, *S.getContext().classify(
Call->getArg(1)->getType()));
2583 for (
unsigned I = 0; I != NumElems; ++I) {
2585 Dst.elem<
T>(I) =
static_cast<T>(
2589 Dst.initializeAllElements();
2594 assert(
Call->getArg(0)->getType()->isVectorType() &&
2595 Call->getArg(1)->getType()->isVectorType());
2596 assert(VT->getElementType() ==
2598 assert(VT->getNumElements() ==
2600 assert(VT->getElementType()->isIntegralOrEnumerationType());
2605 for (
unsigned I = 0; I != NumElems; ++I) {
2607 APSInt Elem1 = LHS.elem<
T>(I).toAPSInt();
2609 Dst.elem<
T>(I) =
static_cast<T>(
APSInt(
Fn(Elem1, Elem2), DestUnsigned));
2612 Dst.initializeAllElements();
2619 unsigned BuiltinID) {
2620 assert(
Call->getNumArgs() == 2);
2631 assert(!
Call->getArg(1)->getType()->isVectorType());
2633 S.Stk, *S.getContext().classify(
Call->getArg(1)->getType()));
2635 S.Stk, *S.getContext().classify(
Call->getArg(0)->getType()));
2637 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2638 Result = std::max(LHS, RHS);
2639 }
else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2640 Result = std::min(LHS, RHS);
2642 llvm_unreachable(
"Wrong builtin ID");
2650 assert(
Call->getArg(0)->getType()->isVectorType() &&
2651 Call->getArg(1)->getType()->isVectorType());
2652 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2653 assert(VT->getElementType() ==
2655 assert(VT->getNumElements() ==
2657 assert(VT->getElementType()->isIntegralOrEnumerationType());
2662 PrimType ElemT = *S.getContext().classify(VT->getElementType());
2663 unsigned NumElems = VT->getNumElements();
2664 for (
unsigned I = 0; I != NumElems; ++I) {
2668 Elem1 = LHS.elem<
T>(I).toAPSInt();
2669 Elem2 = RHS.
elem<
T>(I).toAPSInt();
2673 if (BuiltinID == Builtin::BI__builtin_elementwise_max) {
2674 Result =
APSInt(std::max(Elem1, Elem2),
2675 Call->getType()->isUnsignedIntegerOrEnumerationType());
2676 }
else if (BuiltinID == Builtin::BI__builtin_elementwise_min) {
2677 Result =
APSInt(std::min(Elem1, Elem2),
2678 Call->getType()->isUnsignedIntegerOrEnumerationType());
2680 llvm_unreachable(
"Wrong builtin ID");
2684 { Dst.elem<
T>(I) =
static_cast<T>(Result); });
2686 Dst.initializeAllElements();
2693 unsigned BuiltinID) {
2694 assert(
Call->getArg(0)->getType()->isVectorType() &&
2695 Call->getArg(1)->getType()->isVectorType());
2700 const auto *VT =
Call->getArg(0)->getType()->castAs<
VectorType>();
2701 PrimType ElemT = *S.getContext().classify(VT->getElementType());
2702 unsigned SourceLen = VT->getNumElements();
2704 PrimType DstElemT = *S.getContext().classify(
2706 unsigned DstElem = 0;
2707 for (
unsigned I = 0; I != SourceLen; I += 2) {
2711 Elem1 = LHS.elem<
T>(I).toAPSInt();
2712 Elem2 = RHS.
elem<
T>(I).toAPSInt();
2716 switch (BuiltinID) {
2717 case clang::X86::BI__builtin_ia32_pmuludq128:
2718 case clang::X86::BI__builtin_ia32_pmuludq256:
2719 case clang::X86::BI__builtin_ia32_pmuludq512:
2720 Result =
APSInt(llvm::APIntOps::muluExtended(Elem1, Elem2),
2723 case clang::X86::BI__builtin_ia32_pmuldq128:
2724 case clang::X86::BI__builtin_ia32_pmuldq256:
2725 case clang::X86::BI__builtin_ia32_pmuldq512:
2726 Result =
APSInt(llvm::APIntOps::mulsExtended(Elem1, Elem2),
2731 { Dst.elem<
T>(DstElem) =
static_cast<T>(Result); });
2735 Dst.initializeAllElements();
2741 assert(
Call->getNumArgs() == 3);
2744 llvm::RoundingMode RM = getRoundingMode(FPO);
2760 F.fusedMultiplyAdd(Y.getAPFloat(), Z.
getAPFloat(), RM);
2761 Floating Result = S.allocFloat(
X.getSemantics());
2779 assert(ElemT->isRealFloatingType());
2786 for (
unsigned I = 0; I != NumElems; ++I) {
2789 APFloat Y = VY.elem<
T>(I).getAPFloat();
2791 (void)
X.fusedMultiplyAdd(Y, Z, RM);
2794 Dst.initializeAllElements();
2803 PrimType MaskT = *S.getContext().classify(
Call->getArg(0));
2809 unsigned NumElems = LHS.getNumElems();
2810 PrimType ElemT = LHS.getFieldDesc()->getPrimType();
2813 for (
unsigned I = 0; I != NumElems; ++I) {
2821 Elem = Mask[I] ? LHS.elem<
T>(I).toAPSInt() : RHS.
elem<
T>(I).toAPSInt();
2824 { Dst.
elem<
T>(I) =
static_cast<T>(Elem); });
2833 uint32_t BuiltinID) {
2838 switch (BuiltinID) {
2839 case Builtin::BI__builtin_is_constant_evaluated:
2842 case Builtin::BI__builtin_assume:
2843 case Builtin::BI__assume:
2846 case Builtin::BI__builtin_strcmp:
2847 case Builtin::BIstrcmp:
2848 case Builtin::BI__builtin_strncmp:
2849 case Builtin::BIstrncmp:
2850 case Builtin::BI__builtin_wcsncmp:
2851 case Builtin::BIwcsncmp:
2852 case Builtin::BI__builtin_wcscmp:
2853 case Builtin::BIwcscmp:
2856 case Builtin::BI__builtin_strlen:
2857 case Builtin::BIstrlen:
2858 case Builtin::BI__builtin_wcslen:
2859 case Builtin::BIwcslen:
2862 case Builtin::BI__builtin_nan:
2863 case Builtin::BI__builtin_nanf:
2864 case Builtin::BI__builtin_nanl:
2865 case Builtin::BI__builtin_nanf16:
2866 case Builtin::BI__builtin_nanf128:
2869 case Builtin::BI__builtin_nans:
2870 case Builtin::BI__builtin_nansf:
2871 case Builtin::BI__builtin_nansl:
2872 case Builtin::BI__builtin_nansf16:
2873 case Builtin::BI__builtin_nansf128:
2876 case Builtin::BI__builtin_huge_val:
2877 case Builtin::BI__builtin_huge_valf:
2878 case Builtin::BI__builtin_huge_vall:
2879 case Builtin::BI__builtin_huge_valf16:
2880 case Builtin::BI__builtin_huge_valf128:
2881 case Builtin::BI__builtin_inf:
2882 case Builtin::BI__builtin_inff:
2883 case Builtin::BI__builtin_infl:
2884 case Builtin::BI__builtin_inff16:
2885 case Builtin::BI__builtin_inff128:
2888 case Builtin::BI__builtin_copysign:
2889 case Builtin::BI__builtin_copysignf:
2890 case Builtin::BI__builtin_copysignl:
2891 case Builtin::BI__builtin_copysignf128:
2894 case Builtin::BI__builtin_fmin:
2895 case Builtin::BI__builtin_fminf:
2896 case Builtin::BI__builtin_fminl:
2897 case Builtin::BI__builtin_fminf16:
2898 case Builtin::BI__builtin_fminf128:
2901 case Builtin::BI__builtin_fminimum_num:
2902 case Builtin::BI__builtin_fminimum_numf:
2903 case Builtin::BI__builtin_fminimum_numl:
2904 case Builtin::BI__builtin_fminimum_numf16:
2905 case Builtin::BI__builtin_fminimum_numf128:
2908 case Builtin::BI__builtin_fmax:
2909 case Builtin::BI__builtin_fmaxf:
2910 case Builtin::BI__builtin_fmaxl:
2911 case Builtin::BI__builtin_fmaxf16:
2912 case Builtin::BI__builtin_fmaxf128:
2915 case Builtin::BI__builtin_fmaximum_num:
2916 case Builtin::BI__builtin_fmaximum_numf:
2917 case Builtin::BI__builtin_fmaximum_numl:
2918 case Builtin::BI__builtin_fmaximum_numf16:
2919 case Builtin::BI__builtin_fmaximum_numf128:
2922 case Builtin::BI__builtin_isnan:
2925 case Builtin::BI__builtin_issignaling:
2928 case Builtin::BI__builtin_isinf:
2931 case Builtin::BI__builtin_isinf_sign:
2934 case Builtin::BI__builtin_isfinite:
2937 case Builtin::BI__builtin_isnormal:
2940 case Builtin::BI__builtin_issubnormal:
2943 case Builtin::BI__builtin_iszero:
2946 case Builtin::BI__builtin_signbit:
2947 case Builtin::BI__builtin_signbitf:
2948 case Builtin::BI__builtin_signbitl:
2951 case Builtin::BI__builtin_isgreater:
2952 case Builtin::BI__builtin_isgreaterequal:
2953 case Builtin::BI__builtin_isless:
2954 case Builtin::BI__builtin_islessequal:
2955 case Builtin::BI__builtin_islessgreater:
2956 case Builtin::BI__builtin_isunordered:
2959 case Builtin::BI__builtin_isfpclass:
2962 case Builtin::BI__builtin_fpclassify:
2965 case Builtin::BI__builtin_fabs:
2966 case Builtin::BI__builtin_fabsf:
2967 case Builtin::BI__builtin_fabsl:
2968 case Builtin::BI__builtin_fabsf128:
2971 case Builtin::BI__builtin_abs:
2972 case Builtin::BI__builtin_labs:
2973 case Builtin::BI__builtin_llabs:
2976 case Builtin::BI__builtin_popcount:
2977 case Builtin::BI__builtin_popcountl:
2978 case Builtin::BI__builtin_popcountll:
2979 case Builtin::BI__builtin_popcountg:
2980 case Builtin::BI__popcnt16:
2981 case Builtin::BI__popcnt:
2982 case Builtin::BI__popcnt64:
2985 case Builtin::BI__builtin_parity:
2986 case Builtin::BI__builtin_parityl:
2987 case Builtin::BI__builtin_parityll:
2990 case Builtin::BI__builtin_clrsb:
2991 case Builtin::BI__builtin_clrsbl:
2992 case Builtin::BI__builtin_clrsbll:
2995 case Builtin::BI__builtin_bitreverse8:
2996 case Builtin::BI__builtin_bitreverse16:
2997 case Builtin::BI__builtin_bitreverse32:
2998 case Builtin::BI__builtin_bitreverse64:
3001 case Builtin::BI__builtin_classify_type:
3004 case Builtin::BI__builtin_expect:
3005 case Builtin::BI__builtin_expect_with_probability:
3008 case Builtin::BI__builtin_rotateleft8:
3009 case Builtin::BI__builtin_rotateleft16:
3010 case Builtin::BI__builtin_rotateleft32:
3011 case Builtin::BI__builtin_rotateleft64:
3012 case Builtin::BI_rotl8:
3013 case Builtin::BI_rotl16:
3014 case Builtin::BI_rotl:
3015 case Builtin::BI_lrotl:
3016 case Builtin::BI_rotl64:
3019 case Builtin::BI__builtin_rotateright8:
3020 case Builtin::BI__builtin_rotateright16:
3021 case Builtin::BI__builtin_rotateright32:
3022 case Builtin::BI__builtin_rotateright64:
3023 case Builtin::BI_rotr8:
3024 case Builtin::BI_rotr16:
3025 case Builtin::BI_rotr:
3026 case Builtin::BI_lrotr:
3027 case Builtin::BI_rotr64:
3030 case Builtin::BI__builtin_ffs:
3031 case Builtin::BI__builtin_ffsl:
3032 case Builtin::BI__builtin_ffsll:
3035 case Builtin::BIaddressof:
3036 case Builtin::BI__addressof:
3037 case Builtin::BI__builtin_addressof:
3041 case Builtin::BIas_const:
3042 case Builtin::BIforward:
3043 case Builtin::BIforward_like:
3044 case Builtin::BImove:
3045 case Builtin::BImove_if_noexcept:
3049 case Builtin::BI__builtin_eh_return_data_regno:
3052 case Builtin::BI__builtin_launder:
3056 case Builtin::BI__builtin_add_overflow:
3057 case Builtin::BI__builtin_sub_overflow:
3058 case Builtin::BI__builtin_mul_overflow:
3059 case Builtin::BI__builtin_sadd_overflow:
3060 case Builtin::BI__builtin_uadd_overflow:
3061 case Builtin::BI__builtin_uaddl_overflow:
3062 case Builtin::BI__builtin_uaddll_overflow:
3063 case Builtin::BI__builtin_usub_overflow:
3064 case Builtin::BI__builtin_usubl_overflow:
3065 case Builtin::BI__builtin_usubll_overflow:
3066 case Builtin::BI__builtin_umul_overflow:
3067 case Builtin::BI__builtin_umull_overflow:
3068 case Builtin::BI__builtin_umulll_overflow:
3069 case Builtin::BI__builtin_saddl_overflow:
3070 case Builtin::BI__builtin_saddll_overflow:
3071 case Builtin::BI__builtin_ssub_overflow:
3072 case Builtin::BI__builtin_ssubl_overflow:
3073 case Builtin::BI__builtin_ssubll_overflow:
3074 case Builtin::BI__builtin_smul_overflow:
3075 case Builtin::BI__builtin_smull_overflow:
3076 case Builtin::BI__builtin_smulll_overflow:
3079 case Builtin::BI__builtin_addcb:
3080 case Builtin::BI__builtin_addcs:
3081 case Builtin::BI__builtin_addc:
3082 case Builtin::BI__builtin_addcl:
3083 case Builtin::BI__builtin_addcll:
3084 case Builtin::BI__builtin_subcb:
3085 case Builtin::BI__builtin_subcs:
3086 case Builtin::BI__builtin_subc:
3087 case Builtin::BI__builtin_subcl:
3088 case Builtin::BI__builtin_subcll:
3091 case Builtin::BI__builtin_clz:
3092 case Builtin::BI__builtin_clzl:
3093 case Builtin::BI__builtin_clzll:
3094 case Builtin::BI__builtin_clzs:
3095 case Builtin::BI__builtin_clzg:
3096 case Builtin::BI__lzcnt16:
3097 case Builtin::BI__lzcnt:
3098 case Builtin::BI__lzcnt64:
3101 case Builtin::BI__builtin_ctz:
3102 case Builtin::BI__builtin_ctzl:
3103 case Builtin::BI__builtin_ctzll:
3104 case Builtin::BI__builtin_ctzs:
3105 case Builtin::BI__builtin_ctzg:
3108 case Builtin::BI__builtin_elementwise_ctlz:
3109 case Builtin::BI__builtin_elementwise_cttz:
3113 case Builtin::BI__builtin_bswap16:
3114 case Builtin::BI__builtin_bswap32:
3115 case Builtin::BI__builtin_bswap64:
3118 case Builtin::BI__atomic_always_lock_free:
3119 case Builtin::BI__atomic_is_lock_free:
3122 case Builtin::BI__c11_atomic_is_lock_free:
3125 case Builtin::BI__builtin_complex:
3128 case Builtin::BI__builtin_is_aligned:
3129 case Builtin::BI__builtin_align_up:
3130 case Builtin::BI__builtin_align_down:
3133 case Builtin::BI__builtin_assume_aligned:
3136 case clang::X86::BI__builtin_ia32_bextr_u32:
3137 case clang::X86::BI__builtin_ia32_bextr_u64:
3138 case clang::X86::BI__builtin_ia32_bextri_u32:
3139 case clang::X86::BI__builtin_ia32_bextri_u64:
3142 case clang::X86::BI__builtin_ia32_bzhi_si:
3143 case clang::X86::BI__builtin_ia32_bzhi_di:
3146 case clang::X86::BI__builtin_ia32_lzcnt_u16:
3147 case clang::X86::BI__builtin_ia32_lzcnt_u32:
3148 case clang::X86::BI__builtin_ia32_lzcnt_u64:
3151 case clang::X86::BI__builtin_ia32_tzcnt_u16:
3152 case clang::X86::BI__builtin_ia32_tzcnt_u32:
3153 case clang::X86::BI__builtin_ia32_tzcnt_u64:
3156 case clang::X86::BI__builtin_ia32_pdep_si:
3157 case clang::X86::BI__builtin_ia32_pdep_di:
3160 case clang::X86::BI__builtin_ia32_pext_si:
3161 case clang::X86::BI__builtin_ia32_pext_di:
3164 case clang::X86::BI__builtin_ia32_addcarryx_u32:
3165 case clang::X86::BI__builtin_ia32_addcarryx_u64:
3166 case clang::X86::BI__builtin_ia32_subborrow_u32:
3167 case clang::X86::BI__builtin_ia32_subborrow_u64:
3171 case Builtin::BI__builtin_os_log_format_buffer_size:
3174 case Builtin::BI__builtin_ptrauth_string_discriminator:
3177 case Builtin::BI__noop:
3181 case Builtin::BI__builtin_operator_new:
3184 case Builtin::BI__builtin_operator_delete:
3187 case Builtin::BI__arithmetic_fence:
3190 case Builtin::BI__builtin_reduce_add:
3191 case Builtin::BI__builtin_reduce_mul:
3192 case Builtin::BI__builtin_reduce_and:
3193 case Builtin::BI__builtin_reduce_or:
3194 case Builtin::BI__builtin_reduce_xor:
3195 case Builtin::BI__builtin_reduce_min:
3196 case Builtin::BI__builtin_reduce_max:
3199 case Builtin::BI__builtin_elementwise_popcount:
3200 case Builtin::BI__builtin_elementwise_bitreverse:
3204 case Builtin::BI__builtin_elementwise_abs:
3207 case Builtin::BI__builtin_memcpy:
3208 case Builtin::BImemcpy:
3209 case Builtin::BI__builtin_wmemcpy:
3210 case Builtin::BIwmemcpy:
3211 case Builtin::BI__builtin_memmove:
3212 case Builtin::BImemmove:
3213 case Builtin::BI__builtin_wmemmove:
3214 case Builtin::BIwmemmove:
3217 case Builtin::BI__builtin_memcmp:
3218 case Builtin::BImemcmp:
3219 case Builtin::BI__builtin_bcmp:
3220 case Builtin::BIbcmp:
3221 case Builtin::BI__builtin_wmemcmp:
3222 case Builtin::BIwmemcmp:
3225 case Builtin::BImemchr:
3226 case Builtin::BI__builtin_memchr:
3227 case Builtin::BIstrchr:
3228 case Builtin::BI__builtin_strchr:
3229 case Builtin::BIwmemchr:
3230 case Builtin::BI__builtin_wmemchr:
3231 case Builtin::BIwcschr:
3232 case Builtin::BI__builtin_wcschr:
3233 case Builtin::BI__builtin_char_memchr:
3236 case Builtin::BI__builtin_object_size:
3237 case Builtin::BI__builtin_dynamic_object_size:
3240 case Builtin::BI__builtin_is_within_lifetime:
3243 case Builtin::BI__builtin_elementwise_add_sat:
3246 return LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS);
3249 case Builtin::BI__builtin_elementwise_sub_sat:
3252 return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
3255 case clang::X86::BI__builtin_ia32_pmulhuw128:
3256 case clang::X86::BI__builtin_ia32_pmulhuw256:
3257 case clang::X86::BI__builtin_ia32_pmulhuw512:
3259 llvm::APIntOps::mulhu);
3261 case clang::X86::BI__builtin_ia32_pmulhw128:
3262 case clang::X86::BI__builtin_ia32_pmulhw256:
3263 case clang::X86::BI__builtin_ia32_pmulhw512:
3265 llvm::APIntOps::mulhs);
3267 case clang::X86::BI__builtin_ia32_psllv2di:
3268 case clang::X86::BI__builtin_ia32_psllv4di:
3269 case clang::X86::BI__builtin_ia32_psllv4si:
3270 case clang::X86::BI__builtin_ia32_psllv8si:
3271 case clang::X86::BI__builtin_ia32_psllwi128:
3272 case clang::X86::BI__builtin_ia32_psllwi256:
3273 case clang::X86::BI__builtin_ia32_psllwi512:
3274 case clang::X86::BI__builtin_ia32_pslldi128:
3275 case clang::X86::BI__builtin_ia32_pslldi256:
3276 case clang::X86::BI__builtin_ia32_pslldi512:
3277 case clang::X86::BI__builtin_ia32_psllqi128:
3278 case clang::X86::BI__builtin_ia32_psllqi256:
3279 case clang::X86::BI__builtin_ia32_psllqi512:
3282 if (RHS.uge(LHS.getBitWidth())) {
3283 return APInt::getZero(LHS.getBitWidth());
3285 return LHS.shl(RHS.getZExtValue());
3288 case clang::X86::BI__builtin_ia32_psrav4si:
3289 case clang::X86::BI__builtin_ia32_psrav8si:
3290 case clang::X86::BI__builtin_ia32_psrawi128:
3291 case clang::X86::BI__builtin_ia32_psrawi256:
3292 case clang::X86::BI__builtin_ia32_psrawi512:
3293 case clang::X86::BI__builtin_ia32_psradi128:
3294 case clang::X86::BI__builtin_ia32_psradi256:
3295 case clang::X86::BI__builtin_ia32_psradi512:
3296 case clang::X86::BI__builtin_ia32_psraqi128:
3297 case clang::X86::BI__builtin_ia32_psraqi256:
3298 case clang::X86::BI__builtin_ia32_psraqi512:
3301 if (RHS.uge(LHS.getBitWidth())) {
3302 return LHS.ashr(LHS.getBitWidth() - 1);
3304 return LHS.ashr(RHS.getZExtValue());
3307 case clang::X86::BI__builtin_ia32_psrlv2di:
3308 case clang::X86::BI__builtin_ia32_psrlv4di:
3309 case clang::X86::BI__builtin_ia32_psrlv4si:
3310 case clang::X86::BI__builtin_ia32_psrlv8si:
3311 case clang::X86::BI__builtin_ia32_psrlwi128:
3312 case clang::X86::BI__builtin_ia32_psrlwi256:
3313 case clang::X86::BI__builtin_ia32_psrlwi512:
3314 case clang::X86::BI__builtin_ia32_psrldi128:
3315 case clang::X86::BI__builtin_ia32_psrldi256:
3316 case clang::X86::BI__builtin_ia32_psrldi512:
3317 case clang::X86::BI__builtin_ia32_psrlqi128:
3318 case clang::X86::BI__builtin_ia32_psrlqi256:
3319 case clang::X86::BI__builtin_ia32_psrlqi512:
3322 if (RHS.uge(LHS.getBitWidth())) {
3323 return APInt::getZero(LHS.getBitWidth());
3325 return LHS.lshr(RHS.getZExtValue());
3328 case clang::X86::BI__builtin_ia32_vprotbi:
3329 case clang::X86::BI__builtin_ia32_vprotdi:
3330 case clang::X86::BI__builtin_ia32_vprotqi:
3331 case clang::X86::BI__builtin_ia32_vprotwi:
3332 case clang::X86::BI__builtin_ia32_prold128:
3333 case clang::X86::BI__builtin_ia32_prold256:
3334 case clang::X86::BI__builtin_ia32_prold512:
3335 case clang::X86::BI__builtin_ia32_prolq128:
3336 case clang::X86::BI__builtin_ia32_prolq256:
3337 case clang::X86::BI__builtin_ia32_prolq512:
3339 S, OpPC,
Call, BuiltinID,
3340 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotl(RHS); });
3342 case clang::X86::BI__builtin_ia32_prord128:
3343 case clang::X86::BI__builtin_ia32_prord256:
3344 case clang::X86::BI__builtin_ia32_prord512:
3345 case clang::X86::BI__builtin_ia32_prorq128:
3346 case clang::X86::BI__builtin_ia32_prorq256:
3347 case clang::X86::BI__builtin_ia32_prorq512:
3349 S, OpPC,
Call, BuiltinID,
3350 [](
const APSInt &LHS,
const APSInt &RHS) {
return LHS.rotr(RHS); });
3352 case Builtin::BI__builtin_elementwise_max:
3353 case Builtin::BI__builtin_elementwise_min:
3356 case clang::X86::BI__builtin_ia32_pmuldq128:
3357 case clang::X86::BI__builtin_ia32_pmuldq256:
3358 case clang::X86::BI__builtin_ia32_pmuldq512:
3359 case clang::X86::BI__builtin_ia32_pmuludq128:
3360 case clang::X86::BI__builtin_ia32_pmuludq256:
3361 case clang::X86::BI__builtin_ia32_pmuludq512:
3364 case Builtin::BI__builtin_elementwise_fma:
3367 case X86::BI__builtin_ia32_selectb_128:
3368 case X86::BI__builtin_ia32_selectb_256:
3369 case X86::BI__builtin_ia32_selectb_512:
3370 case X86::BI__builtin_ia32_selectw_128:
3371 case X86::BI__builtin_ia32_selectw_256:
3372 case X86::BI__builtin_ia32_selectw_512:
3373 case X86::BI__builtin_ia32_selectd_128:
3374 case X86::BI__builtin_ia32_selectd_256:
3375 case X86::BI__builtin_ia32_selectd_512:
3376 case X86::BI__builtin_ia32_selectq_128:
3377 case X86::BI__builtin_ia32_selectq_256:
3378 case X86::BI__builtin_ia32_selectq_512:
3379 case X86::BI__builtin_ia32_selectph_128:
3380 case X86::BI__builtin_ia32_selectph_256:
3381 case X86::BI__builtin_ia32_selectph_512:
3382 case X86::BI__builtin_ia32_selectpbf_128:
3383 case X86::BI__builtin_ia32_selectpbf_256:
3384 case X86::BI__builtin_ia32_selectpbf_512:
3385 case X86::BI__builtin_ia32_selectps_128:
3386 case X86::BI__builtin_ia32_selectps_256:
3387 case X86::BI__builtin_ia32_selectps_512:
3388 case X86::BI__builtin_ia32_selectpd_128:
3389 case X86::BI__builtin_ia32_selectpd_256:
3390 case X86::BI__builtin_ia32_selectpd_512:
3394 S.FFDiag(S.Current->getLocation(OpPC),
3395 diag::note_invalid_subexpr_in_const_expr)
3396 << S.Current->getRange(OpPC);
3401 llvm_unreachable(
"Unhandled builtin ID");
3407 unsigned N =
E->getNumComponents();
3410 unsigned ArrayIndex = 0;
3412 for (
unsigned I = 0; I != N; ++I) {
3414 switch (
Node.getKind()) {
3418 if (!RD || RD->isInvalidDecl())
3422 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
3431 int64_t Index = ArrayIndices[ArrayIndex];
3437 Result += Index * ElementSize;
3448 if (!RD || RD->isInvalidDecl())
3453 CurrentType = BaseSpec->
getType();
3463 llvm_unreachable(
"Dependent OffsetOfExpr?");
3467 IntResult = Result.getQuantity();
3484 FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
3494 Dest.deref<T>().~T();
3495 new (&Dest.deref<T>()) T();
3502 for (
const Record::Field &F : R->
fields()) {
3510 for (
unsigned I = 0, N = Desc->
getNumElems(); I != N; ++I) {
3512 Dest.deref<T>().~T();
3513 new (&Dest.deref<T>()) T();
3520 for (
unsigned I = 0, N = Desc->
getNumElems(); I != N; ++I) {
3528static bool copyComposite(InterpState &S, CodePtr OpPC,
const Pointer &Src,
3529 Pointer &Dest,
bool Activate);
3531 Pointer &Dest,
bool Activate =
false) {
3535 auto copyField = [&](
const Record::Field &F,
bool Activate) ->
bool {
3537 if (
OptPrimType FT = S.Ctx.classify(F.Decl->getType())) {
3554 for (
const Record::Field &F : R->
fields()) {
3559 if (!copyField(F,
true))
3568 if (!copyField(F, Activate))
3573 for (
const Record::Base &B : R->
bases()) {
3575 if (!copyRecord(S, OpPC, Src.
atField(B.Offset), DestBase, Activate))
3584 Pointer &Dest,
bool Activate =
false) {
3596 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
3609 for (
unsigned I = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
3619 return copyRecord(S, OpPC, Src, Dest, Activate);
Defines enum values for all the target-independent builtin functions.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
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...
SourceLocation getLocation() 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...
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.
StrictFlexArraysLevelKind
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Helper class for OffsetOfExpr.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
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...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() 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.
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.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
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.
Manages dynamic memory allocations done during bytecode interpretation.
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
CodePtr getRetPC() const
Returns the return address of the frame.
Stack frame storing temporaries and parameters.
T pop()
Returns the value from the top of the stack and removes it.
void discard()
Discards the top value from the stack.
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.
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.
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.
const Descriptor * getDeclDesc() const
Accessor for information about the declaration site.
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
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.
const Record * getRecord() const
Returns the record descriptor of a class.
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.
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 bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC, const CallExpr *Call)
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_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 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.
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)
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_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 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 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 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_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)
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_int_binop(InterpState &S, CodePtr OpPC, const CallExpr *Call, unsigned BuiltinID, llvm::function_ref< APInt(const APSInt &, const APSInt &)> 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)
The JSON file list parser is used to communicate input to InstallAPI.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Result
The result type of a method or function.
const FunctionProtoType * T
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.