(
const Expr*
E:
C->arguments()) {
38assert(
Frame->getFunction()->getNumParams() > Index);
39 unsignedOffset =
Frame->getFunction()->getParamOffset(Index);
40 return Frame->getParam<
T>(Offset);
45 unsignedOffset =
Frame->getFunction()->getParamOffset(Index);
47R =
Frame->getParam<
T>(Offset).toAPSInt());
57 else if(IntWidth == 16)
59llvm_unreachable(
"Int isn't 16 or 32 bit?");
68 else if(LongWidth == 32)
70 else if(LongWidth == 16)
72llvm_unreachable(
"long isn't 16, 32 or 64 bit?");
90std::optional<PrimType>
T= S.getContext().classify(QT);
95int64_t
V= Val.getSExtValue();
99uint64_t
V= Val.getZExtValue();
104template<
typenameT>
106 if constexpr(std::is_same_v<T, APInt>)
108 else if constexpr(std::is_same_v<T, APSInt>)
112 APSInt(
APInt(
sizeof(
T) * 8,
static_cast<uint64_t
>(Val),
113std::is_signed_v<T>),
114!std::is_signed_v<T>),
120ValueT, { Dest.
deref<
T>() = T::from(
static_cast<T>(
Value)); });
124std::optional<PrimType> &
T) {
130 return Ret<X>(S, OpPC); 147llvm_unreachable(
"Unsupported return type for builtin function");
154 auto Loc= S.Current->getSource(OpPC);
156S.CCEDiag(
Loc, diag::note_constexpr_invalid_function)
160S.CCEDiag(
Loc, diag::note_invalid_subexpr_in_const_expr);
166 unsignedDepth = S.Current->getDepth();
168 returnF && F->isInStdNamespace() && F->getIdentifier() &&
169F->getIdentifier()->isStr(
"is_constant_evaluated");
174 if(S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
175S.getEvalStatus().
Diag&&
176(Depth == 1 || (Depth == 2 && isStdCall(Caller->
getCallee())))) {
180diag::warn_is_constant_evaluated_always_true_constexpr)
185diag::warn_is_constant_evaluated_always_true_constexpr)
197 unsignedID =
Func->getBuiltinID();
201 if(ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp)
204uint64_t Limit = ~static_cast<uint64_t>(0);
205 if(ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp)
227 for(;; ++IndexA, ++IndexB, ++Steps) {
237uint8_t CA = PA.
deref<uint8_t>();
238uint8_t CB = PB.
deref<uint8_t>();
243}
else if(CA < CB) {
247 if(CA == 0 || CB == 0)
258 unsignedID =
Func->getBuiltinID();
261 if(ID == Builtin::BIstrlen || ID == Builtin::BIwcslen)
276 if(ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) {
278assert(ElemSize == AC.getTypeSizeInChars(AC.getWCharType()).getQuantity());
282 for(
size_tI = StrPtr.
getIndex();; ++I, ++Len) {
291Val = ElemPtr.
deref<uint8_t>();
294Val = ElemPtr.
deref<uint16_t>();
297Val = ElemPtr.
deref<uint32_t>();
300llvm_unreachable(
"Unsupported char size");
325 for(
unsignedI = 0;; ++I) {
331 if(Elem.
deref<int8_t>() == 0)
334Str += Elem.
deref<
char>();
339Fill = llvm::APInt(32, 0);
340 else if(StringRef(Str).getAsInteger(0, Fill))
343 constllvm::fltSemantics &TargetSemantics =
350llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
353llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
362llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
365llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
374 constllvm::fltSemantics &TargetSemantics =
408 else if(LHS.
isNan() || RHS < LHS)
432 else if(LHS.
isNan() || RHS > LHS)
468 boolIsInf = Arg.
isInf();
535 caseBuiltin::BI__builtin_isgreater:
537 caseBuiltin::BI__builtin_isgreaterequal:
539 caseBuiltin::BI__builtin_isless:
541 caseBuiltin::BI__builtin_islessequal:
543 caseBuiltin::BI__builtin_islessgreater: {
548 caseBuiltin::BI__builtin_isunordered:
551llvm_unreachable(
"Unexpected builtin ID: Should be a floating point " 552 "comparison function");
565 PrimTypeFPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
571 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
589 caseAPFloat::fcInfinity:
592 caseAPFloat::fcNormal:
595 caseAPFloat::fcZero:
628 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
631 APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
false))
633 if(Val.isNegative())
643 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
652 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
661 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
663 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(),
Call->getType());
671 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
682assert(
Call->getNumArgs() == 1);
687int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
699 unsignedNumArgs =
Call->getNumArgs();
700assert(NumArgs == 2 || NumArgs == 3);
702 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
717 PrimTypeAmountT = *S.getContext().classify(
Call->getArg(1)->getType());
718 PrimTypeValueT = *S.getContext().classify(
Call->getArg(0)->getType());
739 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
742uint64_t N =
Value.countr_zero();
751assert(
Call->getArg(0)->isLValue());
757}
else if(PtrT ==
PT_Ptr) {
761assert(
false&&
"Unsupported pointer type passed to __builtin_addressof()");
772 TYPE_SWITCH(ArgT,
const T&Arg = S.Stk.peek<
T>(); S.Stk.push<
T>(Arg););
774 return Func->getDecl()->isConstexpr();
781 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
807 unsignedBuiltinOp =
Func->getBuiltinID();
808 PrimTypeRHST = *S.getContext().classify(
Call->getArg(1)->getType());
809 PrimTypeLHST = *S.getContext().classify(
Call->getArg(0)->getType());
815 QualTypeResultType =
Call->getArg(2)->getType()->getPointeeType();
816 PrimTypeResultT = *S.getContext().classify(ResultType);
820 if(BuiltinOp == Builtin::BI__builtin_add_overflow ||
821BuiltinOp == Builtin::BI__builtin_sub_overflow ||
822BuiltinOp == Builtin::BI__builtin_mul_overflow) {
823 boolIsSigned = LHS.isSigned() || RHS.isSigned() ||
825 boolAllSigned = LHS.isSigned() && RHS.isSigned() &&
827uint64_t LHSSize = LHS.getBitWidth();
828uint64_t RHSSize = RHS.getBitWidth();
830uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize);
836 if(IsSigned && !AllSigned)
839LHS =
APSInt(LHS.extOrTrunc(MaxBits), !IsSigned);
840RHS =
APSInt(RHS.extOrTrunc(MaxBits), !IsSigned);
847llvm_unreachable(
"Invalid value for BuiltinOp");
848 caseBuiltin::BI__builtin_add_overflow:
849 caseBuiltin::BI__builtin_sadd_overflow:
850 caseBuiltin::BI__builtin_saddl_overflow:
851 caseBuiltin::BI__builtin_saddll_overflow:
852 caseBuiltin::BI__builtin_uadd_overflow:
853 caseBuiltin::BI__builtin_uaddl_overflow:
854 caseBuiltin::BI__builtin_uaddll_overflow:
855 Result= LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow)
856: LHS.uadd_ov(RHS, Overflow);
858 caseBuiltin::BI__builtin_sub_overflow:
859 caseBuiltin::BI__builtin_ssub_overflow:
860 caseBuiltin::BI__builtin_ssubl_overflow:
861 caseBuiltin::BI__builtin_ssubll_overflow:
862 caseBuiltin::BI__builtin_usub_overflow:
863 caseBuiltin::BI__builtin_usubl_overflow:
864 caseBuiltin::BI__builtin_usubll_overflow:
865 Result= LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow)
866: LHS.usub_ov(RHS, Overflow);
868 caseBuiltin::BI__builtin_mul_overflow:
869 caseBuiltin::BI__builtin_smul_overflow:
870 caseBuiltin::BI__builtin_smull_overflow:
871 caseBuiltin::BI__builtin_smulll_overflow:
872 caseBuiltin::BI__builtin_umul_overflow:
873 caseBuiltin::BI__builtin_umull_overflow:
874 caseBuiltin::BI__builtin_umulll_overflow:
875 Result= LHS.isSigned() ? LHS.smul_ov(RHS, Overflow)
876: LHS.umul_ov(RHS, Overflow);
882 if(BuiltinOp == Builtin::BI__builtin_add_overflow ||
883BuiltinOp == Builtin::BI__builtin_sub_overflow ||
884BuiltinOp == Builtin::BI__builtin_mul_overflow) {
892 if(!APSInt::isSameValue(Temp,
Result))
900assert(
Func->getDecl()->getReturnType()->isBooleanType());
901S.Stk.push<
Boolean>(Overflow);
910 unsignedBuiltinOp =
Func->getBuiltinID();
911 PrimTypeLHST = *S.getContext().classify(
Call->getArg(0)->getType());
912 PrimTypeRHST = *S.getContext().classify(
Call->getArg(1)->getType());
913 PrimTypeCarryT = *S.getContext().classify(
Call->getArg(2)->getType());
930 boolFirstOverflowed =
false;
931 boolSecondOverflowed =
false;
934llvm_unreachable(
"Invalid value for BuiltinOp");
935 caseBuiltin::BI__builtin_addcb:
936 caseBuiltin::BI__builtin_addcs:
937 caseBuiltin::BI__builtin_addc:
938 caseBuiltin::BI__builtin_addcl:
939 caseBuiltin::BI__builtin_addcll:
941LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed);
943 caseBuiltin::BI__builtin_subcb:
944 caseBuiltin::BI__builtin_subcs:
945 caseBuiltin::BI__builtin_subc:
946 caseBuiltin::BI__builtin_subcl:
947 caseBuiltin::BI__builtin_subcll:
949LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed);
954CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed);
957 QualTypeCarryOutType =
Call->getArg(3)->getType()->getPointeeType();
958 PrimTypeCarryOutT = *S.getContext().classify(CarryOutType);
962assert(
Call->getType() ==
Call->getArg(0)->getType());
971 unsignedBuiltinOp =
Func->getBuiltinID();
972 PrimTypeValT = *S.getContext().classify(
Call->getArg(0));
977 boolZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 &&
978BuiltinOp != Builtin::BI__lzcnt &&
979BuiltinOp != Builtin::BI__lzcnt64;
982 if(
Func->getBuiltinID() == Builtin::BI__builtin_clzg &&
983 Call->getNumArgs() == 2) {
985 PrimTypeFallbackT = *S.getContext().classify(
Call->getArg(1));
1003 PrimTypeValT = *S.getContext().classify(
Call->getArg(0));
1007 if(
Func->getBuiltinID() == Builtin::BI__builtin_ctzg &&
1008 Call->getNumArgs() == 2) {
1010 PrimTypeFallbackT = *S.getContext().classify(
Call->getArg(1));
1025 PrimTypeReturnT = *S.getContext().classify(
Call->getType());
1026 PrimTypeValT = *S.getContext().classify(
Call->getArg(0));
1028assert(Val.getActiveBits() <= 64);
1031{ S.Stk.push<
T>(T::from(Val.byteSwap().getZExtValue())); });
1042 unsignedBuiltinOp =
Func->getBuiltinID();
1044 PrimTypeValT = *S.getContext().classify(
Call->getArg(0));
1045 unsignedSizeValOffset = 0;
1046 if(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free)
1050 autoreturnBool = [&S](
bool Value) ->
bool{
1066 if(Size.isPowerOfTwo()) {
1068 unsignedInlineWidthBits =
1074 if(BuiltinOp == Builtin::BI__c11_atomic_is_lock_free ||
1076 returnreturnBool(
true);
1079assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free);
1082 returnreturnBool(
true);
1086 if(
APSInt(
APInt(64, IntVal,
false),
true).isAligned(Size.getAsAlign()))
1087 returnreturnBool(
true);
1090 const Expr*PtrArg =
Call->getArg(1);
1092 if(
const auto*ICE = dyn_cast<ImplicitCastExpr>(PtrArg)) {
1095 if(ICE->getCastKind() == CK_BitCast)
1096PtrArg = ICE->getSubExpr();
1104 returnreturnBool(
true);
1110 if(BuiltinOp == Builtin::BI__atomic_always_lock_free)
1111 returnreturnBool(
false);
1127 Result.atIndex(0).initialize();
1129 Result.atIndex(1).initialize();
1144 unsignedBuiltinOp =
Func->getBuiltinID();
1147 PrimTypeAlignmentT = *S.Ctx.classify(
Call->getArg(1));
1150 if(Alignment < 0 || !Alignment.isPowerOf2()) {
1151S.FFDiag(
Call, diag::note_constexpr_invalid_alignment) << Alignment;
1155 APSIntMaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1));
1156 if(APSInt::compareValues(Alignment, MaxValue) > 0) {
1157S.FFDiag(
Call, diag::note_constexpr_alignment_too_big)
1158<< MaxValue <<
Call->getArg(0)->getType() << Alignment;
1164 PrimTypeFirstArgT = *S.Ctx.classify(
Call->getArg(0));
1168 APSIntAlign = Alignment.extOrTrunc(Src.getBitWidth());
1169 if(BuiltinOp == Builtin::BI__builtin_align_up) {
1171 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned());
1173}
else if(BuiltinOp == Builtin::BI__builtin_align_down) {
1174 APSIntAlignedVal =
APSInt(Src & ~(Align - 1), Src.isUnsigned());
1177assert(*S.Ctx.classify(
Call->getType()) ==
PT_Bool);
1178S.Stk.push<
Boolean>((Src & (Align - 1)) == 0);
1183assert(FirstArgT ==
PT_Ptr);
1193 if(BuiltinOp == Builtin::BI__builtin_is_aligned) {
1195S.Stk.push<
Boolean>(
true);
1204S.Stk.push<
Boolean>(
false);
1208S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_compute)
1213assert(BuiltinOp == Builtin::BI__builtin_align_down ||
1214BuiltinOp == Builtin::BI__builtin_align_up);
1229assert(Alignment.getBitWidth() <= 64 &&
1230 "Cannot handle > 64-bit address-space");
1231uint64_t Alignment64 = Alignment.getZExtValue();
1234? llvm::alignDown(PtrOffset, Alignment64)
1235: llvm::alignTo(PtrOffset, Alignment64));
1242S.FFDiag(
Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment;
1251assert(
Call->getNumArgs() == 2 ||
Call->getNumArgs() == 3);
1254std::optional<PrimType> PtrT = S.Ctx.classify(
Call->getArg(0));
1260std::optional<APSInt> ExtraOffset;
1262 if(
Call->getNumArgs() == 2) {
1265 PrimTypeAlignmentT = *S.Ctx.classify(
Call->getArg(1));
1266 PrimTypeExtraOffsetT = *S.Ctx.classify(
Call->getArg(2));
1283 if(BaseAlignment < Align) {
1284S.CCEDiag(
Call->getArg(0),
1285diag::note_constexpr_baa_insufficient_alignment)
1295 if(AVOffset.
alignTo(Align) != AVOffset) {
1297S.CCEDiag(
Call->getArg(0),
1298diag::note_constexpr_baa_insufficient_alignment)
1301S.CCEDiag(
Call->getArg(0),
1302diag::note_constexpr_baa_value_insufficient_alignment)
1315 if(
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1316!
Call->getArg(1)->getType()->isIntegerType())
1325 unsignedBitWidth = Val.getBitWidth();
1326uint64_t Shift = Index.extractBitsAsZExtValue(8, 0);
1327uint64_t Length = Index.extractBitsAsZExtValue(8, 8);
1328Length = Length > BitWidth ? BitWidth : Length;
1331 if(Length == 0 || Shift >= BitWidth) {
1336uint64_t
Result= Val.getZExtValue() >> Shift;
1337 Result&= llvm::maskTrailingOnes<uint64_t>(Length);
1347 if(
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1348!
Call->getArg(1)->getType()->isIntegerType() ||
1359 unsignedBitWidth = Val.getBitWidth();
1360uint64_t Index = Idx.extractBitsAsZExtValue(8, 0);
1362 if(Index < BitWidth)
1363Val.clearHighBits(BitWidth - Index);
1375!
Call->getArg(0)->getType()->isIntegerType())
1379 pushInteger(S, Val.countLeadingZeros(), CallType);
1389!
Call->getArg(0)->getType()->isIntegerType())
1393 pushInteger(S, Val.countTrailingZeros(), CallType);
1401 if(
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1402!
Call->getArg(1)->getType()->isIntegerType())
1412 unsignedBitWidth = Val.getBitWidth();
1414 for(
unsignedI = 0,
P= 0; I != BitWidth; ++I) {
1416 Result.setBitVal(I, Val[
P++]);
1426 if(
Call->getNumArgs() != 2 || !
Call->getArg(0)->getType()->isIntegerType() ||
1427!
Call->getArg(1)->getType()->isIntegerType())
1437 unsignedBitWidth = Val.getBitWidth();
1439 for(
unsignedI = 0,
P= 0; I != BitWidth; ++I) {
1441 Result.setBitVal(
P++, Val[I]);
1452 if(
Call->getNumArgs() != 4 || !
Call->getArg(0)->getType()->isIntegerType() ||
1453!
Call->getArg(1)->getType()->isIntegerType() ||
1454!
Call->getArg(2)->getType()->isIntegerType())
1457 unsignedBuiltinOp =
Func->getBuiltinID();
1462 boolIsAdd = BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u32 ||
1463BuiltinOp == clang::X86::BI__builtin_ia32_addcarryx_u64;
1465 unsignedBitWidth = LHS.getBitWidth();
1466 unsignedCarryInBit = CarryIn.ugt(0) ? 1 : 0;
1468IsAdd ? (LHS.zext(BitWidth + 1) + (RHS.zext(BitWidth + 1) + CarryInBit))
1469: (LHS.zext(BitWidth + 1) - (RHS.zext(BitWidth + 1) + CarryInBit));
1473 APSInt(ExResult.extractBits(1, BitWidth),
true);
1476 QualTypeCarryOutType =
Call->getArg(3)->getType()->getPointeeType();
1477 PrimTypeCarryOutT = *S.getContext().classify(CarryOutType);
1499 const auto&Ptr = S.Stk.peek<
Pointer>();
1500assert(Ptr.getFieldDesc()->isPrimitiveArray());
1502StringRef R(&Ptr.deref<
char>(), Ptr.getFieldDesc()->getNumElems() - 1);
1503uint64_t
Result= getPointerAuthStableSipHash(R);
1516 const Expr*Arg =
Call->getArg(0);
1519 autoreturnInt = [&S,
Call](
bool Value) ->
bool{
1541 autoPrevDiags = S.getEvalStatus().
Diag;
1542S.getEvalStatus().
Diag=
nullptr;
1545 autoRes =
C.interpretExpr(Arg,
Arg->
isGLValue());
1546S.getEvalStatus().
Diag= PrevDiags;
1547 if(Res.isInvalid()) {
1550 returnreturnInt(
false);
1554 const APValue&LV = Res.toAPValue();
1557 if(
Base.isNull()) {
1559 returnreturnInt(
true);
1560}
else if(
const auto*
E=
Base.dyn_cast<
const Expr*>()) {
1561 if(!isa<StringLiteral>(
E))
1562 returnreturnInt(
false);
1567 returnreturnInt(
true);
1570 returnreturnInt(
false);
1576 returnreturnInt(
true);
1579 returnreturnInt(
false);
1590 const CallExpr*NewCall =
nullptr;
1596 const auto*MD = dyn_cast_if_present<CXXMethodDecl>(
Func->getDecl());
1600 if(!FnII || !FnII->
isStr(
"allocate"))
1604dyn_cast<ClassTemplateSpecializationDecl>(MD->getParent());
1610 if(CTSD->isInStdNamespace() && ClassII && ClassII->
isStr(
"allocator") &&
1612ElemType = TAL[0].getAsType();
1613NewCall = cast<CallExpr>(F->Caller->getExpr(F->getRetPC()));
1618 if(ElemType.
isNull()) {
1620? diag::note_constexpr_new_untyped
1621: diag::note_constexpr_new);
1627S.FFDiag(
Call, diag::note_constexpr_new_not_complete_object_type)
1634assert(!ElemSize.
isZero());
1637 APIntNumElems, Remainder;
1639APInt::udivrem(
Bytes, ElemSizeAP, NumElems, Remainder);
1640 if(Remainder != 0) {
1642S.FFDiag(
Call, diag::note_constexpr_operator_new_bad_size)
1643<<
Bytes<<
APSInt(ElemSizeAP,
true) << ElemType;
1648 if(NumElems.getActiveBits() >
1653S.FFDiag(
Loc, diag::note_constexpr_new_too_large)
1654<< NumElems.getZExtValue();
1658std::optional<PrimType> ElemT = S.getContext().classify(ElemType);
1661 if(NumElems.ule(1)) {
1666 Block*B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1673assert(NumElems.ugt(1));
1676Allocator.allocate(NewCall, *ElemT, NumElems.getZExtValue(),
1685 const Descriptor*Desc = S.P.createDescriptor(
1687 false,
false,
false,
1690 if(NumElems.ule(1)) {
1691 Block*B = Allocator.allocate(Desc, S.getContext().getEvalID(),
1699Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
1710 const Expr*Source =
nullptr;
1711 const Block*BlockToDelete =
nullptr;
1717S.CCEDiag(
Call, diag::note_constexpr_deallocate_null);
1722BlockToDelete = Ptr.
block();
1724assert(BlockToDelete);
1728std::optional<DynamicAllocator::Form> AllocForm =
1729Allocator.getAllocationForm(Source);
1731 if(!Allocator.deallocate(Source, BlockToDelete, S)) {
1734S.FFDiag(
Loc, diag::note_constexpr_double_delete);
1759 unsignedID =
Func->getBuiltinID();
1761assert(
Call->getType() == ElemType);
1762 PrimTypeElemT = *S.getContext().classify(ElemType);
1767 unsignedBitWidth =
Result.bitWidth();
1768 for(
unsignedI = 1; I != NumElems; ++I) {
1769 TElem = Arg.
atIndex(I).deref<T>();
1772 if(ID == Builtin::BI__builtin_reduce_add) {
1774 unsignedOverflowBits = BitWidth + 1;
1776(PrevResult.toAPSInt(OverflowBits) +
1777Elem.toAPSInt(OverflowBits)));
1780}
else if(ID == Builtin::BI__builtin_reduce_mul) {
1782 unsignedOverflowBits = BitWidth * 2;
1784(PrevResult.toAPSInt(OverflowBits) *
1785Elem.toAPSInt(OverflowBits)));
1789}
else if(ID == Builtin::BI__builtin_reduce_and) {
1791}
else if(ID == Builtin::BI__builtin_reduce_or) {
1793}
else if(ID == Builtin::BI__builtin_reduce_xor) {
1796llvm_unreachable(
"Unhandled vector reduce builtin");
1810assert(
Call->getNumArgs() == 1);
1811 if(
Call->getArg(0)->getType()->isIntegerType()) {
1812 PrimTypeArgT = *S.getContext().classify(
Call->getArg(0)->getType());
1818assert(
Call->getArg(0)->getType()->isVectorType());
1827 PrimTypeElemT = *S.getContext().classify(ElemType);
1831 for(
unsignedI = 0; I != NumElems; ++I) {
1834T::from(Arg.
atIndex(I).
deref<
T>().toAPSInt().popcount());
1845assert(
Call->getNumArgs() == 3);
1846 unsignedID =
Func->getBuiltinID();
1852assert(!Size.isSigned() &&
"memcpy and friends take an unsigned size");
1854 if(ID == Builtin::BImemcpy || ID == Builtin::BImemmove)
1857 boolMove = (ID == Builtin::BI__builtin_memmove || ID == Builtin::BImemmove);
1860 if(Size.isZero()) {
1861S.Stk.push<
Pointer>(DestPtr);
1867S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_null)
1868<<
Move <<
false<< !SrcPtr.
isZero()
1878 size_tRemainingDestElems;
1885DestElemType = DestPtr.
getType();
1886RemainingDestElems = 1;
1890 if(Size.urem(DestElemSize) != 0) {
1891S.FFDiag(S.Current->getSource(OpPC),
1892diag::note_constexpr_memcpy_unsupported)
1893<< Move <<
false<< 0 << DestElemType << Size
1899 size_tRemainingSrcElems;
1906SrcElemType = SrcPtr.
getType();
1907RemainingSrcElems = 1;
1912S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_type_pun)
1913<< Move << SrcElemType << DestElemType;
1918 size_tRemainingDestBytes = RemainingDestElems * DestElemSize;
1919 size_tRemainingSrcBytes = RemainingSrcElems * SrcElemSize;
1920 if(Size.ugt(RemainingDestBytes) || Size.ugt(RemainingSrcBytes)) {
1921 APIntN = Size.udiv(DestElemSize);
1922S.FFDiag(S.Current->getSource(OpPC),
1923diag::note_constexpr_memcpy_unsupported)
1924<< Move <<
false<< (Size.ugt(RemainingSrcBytes) ? 1 : 2)
1925<< DestElemType <<
toString(N, 10,
false);
1933 unsignedN = Size.getZExtValue();
1935 if((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) ||
1936(DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) {
1937S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_overlap)
1943assert(Size.getZExtValue() % DestElemSize == 0);
1947S.Stk.push<
Pointer>(DestPtr);
1960assert(
Call->getNumArgs() == 3);
1961 unsignedID =
Func->getBuiltinID();
1967 if(ID == Builtin::BImemcmp || ID == Builtin::BIbcmp ||
1968ID == Builtin::BIwmemcmp)
1971 if(Size.isZero()) {
1977(ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp);
1984S.FFDiag(S.Current->getSource(OpPC),
1985diag::note_constexpr_memcmp_unsupported)
2014 unsignedElemSize = 1;
2019 size_tByteSize = Size.getZExtValue() * ElemSize;
2020 size_tCmpSize = std::min(MinBufferSize, ByteSize);
2022 for(
size_tI = 0; I != CmpSize; I += ElemSize) {
2025T A = *reinterpret_cast<T *>(BufferA.Data.get() + I);
2026T B = *reinterpret_cast<T *>(BufferB.Data.get() + I);
2028pushInteger(S, -1, Call->getType());
2036std::byte A = BufferA.
Data[I];
2037std::byte B = BufferB.
Data[I];
2051 if(ByteSize <= CmpSize) {
2060S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end)
2061<<
AK_Read<< S.Current->getRange(OpPC);
2069std::optional<PrimType> ReturnT = S.getContext().classify(
Call);
2071 switch(BuiltinID) {
2072 caseBuiltin::BI__builtin_is_constant_evaluated:
2076 caseBuiltin::BI__builtin_assume:
2077 caseBuiltin::BI__assume:
2079 caseBuiltin::BI__builtin_strcmp:
2080 caseBuiltin::BIstrcmp:
2081 caseBuiltin::BI__builtin_strncmp:
2082 caseBuiltin::BIstrncmp:
2086 caseBuiltin::BI__builtin_strlen:
2087 caseBuiltin::BIstrlen:
2088 caseBuiltin::BI__builtin_wcslen:
2089 caseBuiltin::BIwcslen:
2093 caseBuiltin::BI__builtin_nan:
2094 caseBuiltin::BI__builtin_nanf:
2095 caseBuiltin::BI__builtin_nanl:
2096 caseBuiltin::BI__builtin_nanf16:
2097 caseBuiltin::BI__builtin_nanf128:
2101 caseBuiltin::BI__builtin_nans:
2102 caseBuiltin::BI__builtin_nansf:
2103 caseBuiltin::BI__builtin_nansl:
2104 caseBuiltin::BI__builtin_nansf16:
2105 caseBuiltin::BI__builtin_nansf128:
2110 caseBuiltin::BI__builtin_huge_val:
2111 caseBuiltin::BI__builtin_huge_valf:
2112 caseBuiltin::BI__builtin_huge_vall:
2113 caseBuiltin::BI__builtin_huge_valf16:
2114 caseBuiltin::BI__builtin_huge_valf128:
2115 caseBuiltin::BI__builtin_inf:
2116 caseBuiltin::BI__builtin_inff:
2117 caseBuiltin::BI__builtin_infl:
2118 caseBuiltin::BI__builtin_inff16:
2119 caseBuiltin::BI__builtin_inff128:
2123 caseBuiltin::BI__builtin_copysign:
2124 caseBuiltin::BI__builtin_copysignf:
2125 caseBuiltin::BI__builtin_copysignl:
2126 caseBuiltin::BI__builtin_copysignf128:
2131 caseBuiltin::BI__builtin_fmin:
2132 caseBuiltin::BI__builtin_fminf:
2133 caseBuiltin::BI__builtin_fminl:
2134 caseBuiltin::BI__builtin_fminf16:
2135 caseBuiltin::BI__builtin_fminf128:
2140 caseBuiltin::BI__builtin_fminimum_num:
2141 caseBuiltin::BI__builtin_fminimum_numf:
2142 caseBuiltin::BI__builtin_fminimum_numl:
2143 caseBuiltin::BI__builtin_fminimum_numf16:
2144 caseBuiltin::BI__builtin_fminimum_numf128:
2149 caseBuiltin::BI__builtin_fmax:
2150 caseBuiltin::BI__builtin_fmaxf:
2151 caseBuiltin::BI__builtin_fmaxl:
2152 caseBuiltin::BI__builtin_fmaxf16:
2153 caseBuiltin::BI__builtin_fmaxf128:
2158 caseBuiltin::BI__builtin_fmaximum_num:
2159 caseBuiltin::BI__builtin_fmaximum_numf:
2160 caseBuiltin::BI__builtin_fmaximum_numl:
2161 caseBuiltin::BI__builtin_fmaximum_numf16:
2162 caseBuiltin::BI__builtin_fmaximum_numf128:
2167 caseBuiltin::BI__builtin_isnan:
2171 caseBuiltin::BI__builtin_issignaling:
2176 caseBuiltin::BI__builtin_isinf:
2181 caseBuiltin::BI__builtin_isinf_sign:
2186 caseBuiltin::BI__builtin_isfinite:
2190 caseBuiltin::BI__builtin_isnormal:
2194 caseBuiltin::BI__builtin_issubnormal:
2198 caseBuiltin::BI__builtin_iszero:
2202 caseBuiltin::BI__builtin_signbit:
2203 caseBuiltin::BI__builtin_signbitf:
2204 caseBuiltin::BI__builtin_signbitl:
2208 caseBuiltin::BI__builtin_isgreater:
2209 caseBuiltin::BI__builtin_isgreaterequal:
2210 caseBuiltin::BI__builtin_isless:
2211 caseBuiltin::BI__builtin_islessequal:
2212 caseBuiltin::BI__builtin_islessgreater:
2213 caseBuiltin::BI__builtin_isunordered:
2217 caseBuiltin::BI__builtin_isfpclass:
2221 caseBuiltin::BI__builtin_fpclassify:
2226 caseBuiltin::BI__builtin_fabs:
2227 caseBuiltin::BI__builtin_fabsf:
2228 caseBuiltin::BI__builtin_fabsl:
2229 caseBuiltin::BI__builtin_fabsf128:
2234 caseBuiltin::BI__builtin_abs:
2235 caseBuiltin::BI__builtin_labs:
2236 caseBuiltin::BI__builtin_llabs:
2241 caseBuiltin::BI__builtin_popcount:
2242 caseBuiltin::BI__builtin_popcountl:
2243 caseBuiltin::BI__builtin_popcountll:
2244 caseBuiltin::BI__builtin_popcountg:
2245 caseBuiltin::BI__popcnt16:
2246 caseBuiltin::BI__popcnt:
2247 caseBuiltin::BI__popcnt64:
2252 caseBuiltin::BI__builtin_parity:
2253 caseBuiltin::BI__builtin_parityl:
2254 caseBuiltin::BI__builtin_parityll:
2259 caseBuiltin::BI__builtin_clrsb:
2260 caseBuiltin::BI__builtin_clrsbl:
2261 caseBuiltin::BI__builtin_clrsbll:
2266 caseBuiltin::BI__builtin_bitreverse8:
2267 caseBuiltin::BI__builtin_bitreverse16:
2268 caseBuiltin::BI__builtin_bitreverse32:
2269 caseBuiltin::BI__builtin_bitreverse64:
2274 caseBuiltin::BI__builtin_classify_type:
2279 caseBuiltin::BI__builtin_expect:
2280 caseBuiltin::BI__builtin_expect_with_probability:
2285 caseBuiltin::BI__builtin_rotateleft8:
2286 caseBuiltin::BI__builtin_rotateleft16:
2287 caseBuiltin::BI__builtin_rotateleft32:
2288 caseBuiltin::BI__builtin_rotateleft64:
2289 caseBuiltin::BI_rotl8:
2290 caseBuiltin::BI_rotl16:
2291 caseBuiltin::BI_rotl:
2292 caseBuiltin::BI_lrotl:
2293 caseBuiltin::BI_rotl64:
2298 caseBuiltin::BI__builtin_rotateright8:
2299 caseBuiltin::BI__builtin_rotateright16:
2300 caseBuiltin::BI__builtin_rotateright32:
2301 caseBuiltin::BI__builtin_rotateright64:
2302 caseBuiltin::BI_rotr8:
2303 caseBuiltin::BI_rotr16:
2304 caseBuiltin::BI_rotr:
2305 caseBuiltin::BI_lrotr:
2306 caseBuiltin::BI_rotr64:
2311 caseBuiltin::BI__builtin_ffs:
2312 caseBuiltin::BI__builtin_ffsl:
2313 caseBuiltin::BI__builtin_ffsll:
2317 caseBuiltin::BIaddressof:
2318 caseBuiltin::BI__addressof:
2319 caseBuiltin::BI__builtin_addressof:
2324 caseBuiltin::BIas_const:
2325 caseBuiltin::BIforward:
2326 caseBuiltin::BIforward_like:
2327 caseBuiltin::BImove:
2328 caseBuiltin::BImove_if_noexcept:
2333 caseBuiltin::BI__builtin_eh_return_data_regno:
2338 caseBuiltin::BI__builtin_launder:
2343 caseBuiltin::BI__builtin_add_overflow:
2344 caseBuiltin::BI__builtin_sub_overflow:
2345 caseBuiltin::BI__builtin_mul_overflow:
2346 caseBuiltin::BI__builtin_sadd_overflow:
2347 caseBuiltin::BI__builtin_uadd_overflow:
2348 caseBuiltin::BI__builtin_uaddl_overflow:
2349 caseBuiltin::BI__builtin_uaddll_overflow:
2350 caseBuiltin::BI__builtin_usub_overflow:
2351 caseBuiltin::BI__builtin_usubl_overflow:
2352 caseBuiltin::BI__builtin_usubll_overflow:
2353 caseBuiltin::BI__builtin_umul_overflow:
2354 caseBuiltin::BI__builtin_umull_overflow:
2355 caseBuiltin::BI__builtin_umulll_overflow:
2356 caseBuiltin::BI__builtin_saddl_overflow:
2357 caseBuiltin::BI__builtin_saddll_overflow:
2358 caseBuiltin::BI__builtin_ssub_overflow:
2359 caseBuiltin::BI__builtin_ssubl_overflow:
2360 caseBuiltin::BI__builtin_ssubll_overflow:
2361 caseBuiltin::BI__builtin_smul_overflow:
2362 caseBuiltin::BI__builtin_smull_overflow:
2363 caseBuiltin::BI__builtin_smulll_overflow:
2368 caseBuiltin::BI__builtin_addcb:
2369 caseBuiltin::BI__builtin_addcs:
2370 caseBuiltin::BI__builtin_addc:
2371 caseBuiltin::BI__builtin_addcl:
2372 caseBuiltin::BI__builtin_addcll:
2373 caseBuiltin::BI__builtin_subcb:
2374 caseBuiltin::BI__builtin_subcs:
2375 caseBuiltin::BI__builtin_subc:
2376 caseBuiltin::BI__builtin_subcl:
2377 caseBuiltin::BI__builtin_subcll:
2382 caseBuiltin::BI__builtin_clz:
2383 caseBuiltin::BI__builtin_clzl:
2384 caseBuiltin::BI__builtin_clzll:
2385 caseBuiltin::BI__builtin_clzs:
2386 caseBuiltin::BI__builtin_clzg:
2387 caseBuiltin::BI__lzcnt16:
2388 caseBuiltin::BI__lzcnt:
2389 caseBuiltin::BI__lzcnt64:
2394 caseBuiltin::BI__builtin_ctz:
2395 caseBuiltin::BI__builtin_ctzl:
2396 caseBuiltin::BI__builtin_ctzll:
2397 caseBuiltin::BI__builtin_ctzs:
2398 caseBuiltin::BI__builtin_ctzg:
2403 caseBuiltin::BI__builtin_bswap16:
2404 caseBuiltin::BI__builtin_bswap32:
2405 caseBuiltin::BI__builtin_bswap64:
2410 caseBuiltin::BI__atomic_always_lock_free:
2411 caseBuiltin::BI__atomic_is_lock_free:
2412 caseBuiltin::BI__c11_atomic_is_lock_free:
2417 caseBuiltin::BI__builtin_complex:
2422 caseBuiltin::BI__builtin_is_aligned:
2423 caseBuiltin::BI__builtin_align_up:
2424 caseBuiltin::BI__builtin_align_down:
2429 caseBuiltin::BI__builtin_assume_aligned:
2434 caseclang::X86::BI__builtin_ia32_bextr_u32:
2435 caseclang::X86::BI__builtin_ia32_bextr_u64:
2436 caseclang::X86::BI__builtin_ia32_bextri_u32:
2437 caseclang::X86::BI__builtin_ia32_bextri_u64:
2442 caseclang::X86::BI__builtin_ia32_bzhi_si:
2443 caseclang::X86::BI__builtin_ia32_bzhi_di:
2448 caseclang::X86::BI__builtin_ia32_lzcnt_u16:
2449 caseclang::X86::BI__builtin_ia32_lzcnt_u32:
2450 caseclang::X86::BI__builtin_ia32_lzcnt_u64:
2455 caseclang::X86::BI__builtin_ia32_tzcnt_u16:
2456 caseclang::X86::BI__builtin_ia32_tzcnt_u32:
2457 caseclang::X86::BI__builtin_ia32_tzcnt_u64:
2462 caseclang::X86::BI__builtin_ia32_pdep_si:
2463 caseclang::X86::BI__builtin_ia32_pdep_di:
2468 caseclang::X86::BI__builtin_ia32_pext_si:
2469 caseclang::X86::BI__builtin_ia32_pext_di:
2474 caseclang::X86::BI__builtin_ia32_addcarryx_u32:
2475 caseclang::X86::BI__builtin_ia32_addcarryx_u64:
2476 caseclang::X86::BI__builtin_ia32_subborrow_u32:
2477 caseclang::X86::BI__builtin_ia32_subborrow_u64:
2482 caseBuiltin::BI__builtin_os_log_format_buffer_size:
2487 caseBuiltin::BI__builtin_ptrauth_string_discriminator:
2492 caseBuiltin::BI__builtin_constant_p:
2497 caseBuiltin::BI__noop:
2501 caseBuiltin::BI__builtin_operator_new:
2506 caseBuiltin::BI__builtin_operator_delete:
2511 caseBuiltin::BI__arithmetic_fence:
2516 caseBuiltin::BI__builtin_reduce_add:
2517 caseBuiltin::BI__builtin_reduce_mul:
2518 caseBuiltin::BI__builtin_reduce_and:
2519 caseBuiltin::BI__builtin_reduce_or:
2520 caseBuiltin::BI__builtin_reduce_xor:
2525 caseBuiltin::BI__builtin_elementwise_popcount:
2530 caseBuiltin::BI__builtin_memcpy:
2531 caseBuiltin::BImemcpy:
2532 caseBuiltin::BI__builtin_memmove:
2533 caseBuiltin::BImemmove:
2538 caseBuiltin::BI__builtin_memcmp:
2539 caseBuiltin::BImemcmp:
2540 caseBuiltin::BI__builtin_bcmp:
2541 caseBuiltin::BIbcmp:
2542 caseBuiltin::BI__builtin_wmemcmp:
2543 caseBuiltin::BIwmemcmp:
2549S.FFDiag(S.Current->getLocation(OpPC),
2550diag::note_invalid_subexpr_in_const_expr)
2551<< S.Current->getRange(OpPC);
2561int64_t &IntResult) {
2563 unsignedN =
E->getNumComponents();
2566 unsignedArrayIndex = 0;
2568 for(
unsignedI = 0; I != N; ++I) {
2570 switch(
Node.getKind()) {
2581assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
2590int64_t Index = ArrayIndices[ArrayIndex];
2596 Result+= Index * ElementSize;
2615CurrentType = BaseSpec->
getType();
2625llvm_unreachable(
"Dependent OffsetOfExpr?");
2629IntResult =
Result.getQuantity();
2646FieldPtr.
deref<
T>() = T::from(IntValue.getSExtValue()));
2651static boolcopyComposite(InterpState &S, CodePtr OpPC,
const Pointer&Src,
2652 Pointer&Dest,
boolActivate);
2654 Pointer&Dest,
boolActivate =
false) {
2658 autocopyField = [&](
constRecord::Field &F,
boolActivate) ->
bool{
2660 if(std::optional<PrimType> FT = S.Ctx.classify(F.Decl->getType())) {
2677 for(
constRecord::Field &F : R->
fields()) {
2682 if(!copyField(F,
true))
2686 if(!copyField(F, Activate))
2691 for(
constRecord::Base &B : R->
bases()) {
2693 if(!copyRecord(S, OpPC, Src.
atField(B.Offset), DestBase, Activate))
2702 Pointer&Dest,
boolActivate =
false) {
2714 for(
unsignedI = 0, N = DestDesc->
getNumElems(); I != N; ++I) {
2725 returncopyRecord(S, OpPC, Src, Dest, Activate);
Defines enum values for all the target-independent builtin functions.
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.
#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.
Enumerates target-specific builtins in their own namespaces within namespace clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
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
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.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
std::string getQuotedName(unsigned ID) const
Return a quoted name for the specified builtin for use in diagnostics.
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...
bool isInvalidDecl() const
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Represents a function declaration or definition.
QualType getReturnType() const
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.
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 isNull() const
Return true if this QualType doesn't point to a type yet.
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...
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
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...
Exposes information about the current target.
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...
virtual int getEHDataRegisterNumber(unsigned RegNo) const
Return the register number that __builtin_eh_return_regno would return with the specified argument.
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
virtual bool isNan2008() const
Returns true if NaN encoding is IEEE 754-2008.
A template argument list.
unsigned size() const
Retrieve the number of template arguments in this template argument list.
@ Type
The template argument is a type.
Symbolic representation of typeid(T) for some type T.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isAnyComplexType() const
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() 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.
Compilation context for expressions.
Manages dynamic memory allocations done during bytecode interpretation.
const APFloat & getAPFloat() const
llvm::FPClassTest classify() const
ComparisonCategoryResult compare(const Floating &RHS) const
static Floating getInf(const llvm::fltSemantics &Sem)
static Floating abs(const Floating &F)
APFloat::fltCategory getCategory() const
Base class for stack frames, shared between VM and walker.
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
unsigned getBuiltinID() const
Frame storing local variables.
const Expr * getExpr(CodePtr PC) const
InterpFrame * Caller
The frame of the previous function.
CodePtr getRetPC() const
Returns the return address of the frame.
const FunctionDecl * getCallee() const override
Returns the caller.
Stack frame storing temporaries and parameters.
void clear()
Clears the stack without calling any destructors.
T & peek() const
Returns a reference to the value on the top of the stack.
A pointer to a memory block, live or dead.
bool isInitialized() const
Checks if an object was initialized.
Pointer atIndex(uint64_t Idx) const
Offsets a pointer inside an array.
bool isDummy() const
Checks if the pointer points to a dummy value.
int64_t getIndex() const
Returns the index into an array.
bool isActive() const
Checks if the object is active.
Pointer atField(unsigned Off) const
Creates a pointer to a field.
T & deref() const
Dereferences the pointer, if it's live.
unsigned getNumElems() const
Returns the number of elements.
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 isLive() const
Checks if the pointer is live.
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.
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.
uint64_t getIntegerRepresentation() const
bool isBlockPointer() const
const Block * block() const
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
size_t elemSize() const
Returns the element size of the innermost field.
void initialize() const
Initializes a field.
const Record * getRecord() const
Returns the record descriptor of a class.
Structure/Class descriptor.
bool isUnion() const
Checks if the record is a union.
const Field * getField(const FieldDecl *FD) const
Returns a field.
llvm::iterator_range< const_base_iter > bases() const
unsigned getNumFields() const
llvm::iterator_range< const_field_iter > fields() const
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_atomic_lock_free(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool __atomic_always_lock_free(size_t, void const volatile*) bool __atomic_is_lock_free(size_t,...
bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, BitcastBuffer &Buffer, bool ReturnOnUninit)
static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset=0)
Peek an integer value from the stack into an APSInt.
static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static PrimType getLongPrimType(const InterpState &S)
static bool interp__builtin_assume_aligned(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_assume_aligned(Ptr, Alignment[, ExtraOffset])
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_operator_delete(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp_floating_comparison(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, llvm::ArrayRef< int64_t > ArrayIndices, int64_t &Result)
Interpret an offsetof operation.
static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool Signaling)
bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const APSInt &IntValue)
Sets the given integral value to the pointer, which is of a std::{weak,partial,strong}_ordering type.
static bool interp__builtin_ptrauth_string_discriminator(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool retPrimValue(InterpState &S, CodePtr OpPC, std::optional< PrimType > &T)
static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func)
static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_operator_new(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Three integral values followed by a pointer (lhs, rhs, carry, carryOut).
static bool interp__builtin_signbit(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_arithmetic_fence(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_ia32_bzhi(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static unsigned callArgSize(const InterpState &S, const CallExpr *C)
static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_vector_reduce(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_os_log_format_buffer_size(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_is_aligned() __builtin_align_up() __builtin_align_down() The first parameter is either an i...
static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool RetVoid(InterpState &S, CodePtr &PC)
static bool isOneByteCharacterType(QualType T)
Determine if T is a character type for which we guarantee that sizeof(T) == 1.
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a value can be loaded from a block.
static bool interp__builtin_abs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static T getParam(const InterpFrame *Frame, unsigned Index)
static bool interp__builtin_ia32_lzcnt(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
static bool interp__builtin_ia32_pext(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Can be called with an integer or vector as the first and only parameter.
static bool handleOverflow(InterpState &S, CodePtr OpPC, const T &SrcValue)
PrimType
Enumeration of the primitive types of the VM.
static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool copyComposite(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest, bool Activate)
static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool CheckSign, const CallExpr *Call)
static bool interp__builtin_move(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, bool IsNumBuiltin)
static APSInt getAPSIntParam(const InterpFrame *Frame, unsigned Index)
static bool noopPointer(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Just takes the first Argument to the call and puts it on the stack.
static void pushInteger(InterpState &S, const APSInt &Val, QualType QT)
Pushes Val on the stack as the type given by QT.
static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
__builtin_complex(Float A, float B);
static bool interp__builtin_ia32_tzcnt(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is a dummy pointer.
static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
static bool interp__builtin_ia32_pdep(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static PrimType getIntPrimType(const InterpState &S)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
static void assignInteger(Pointer &Dest, PrimType ValueT, const APSInt &Value)
static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call, uint32_t BuiltinID)
Interpret a builtin function.
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const CallExpr *Call)
static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
Five int values followed by one floating value.
static bool interp__builtin_ia32_bextr(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool IsNumBuiltin)
static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, const CallExpr *Call)
Defined as __builtin_isnan(...), to accommodate the fact that it can take a float,...
bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest)
Copy the contents of Src into Dest.
static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call, bool Right)
rotateleft(value, amount)
constexpr bool isIntegralType(PrimType T)
static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
First parameter to __builtin_isfpclass is the floating value, the second one is an integral value.
static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC, unsigned ID)
static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_ia32_addcarry_subborrow(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static void swapBytes(std::byte *M, size_t N)
static bool interp__builtin_bswap(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
The JSON file list parser is used to communicate input to InstallAPI.
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
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
const ValueDecl * asValueDecl() const
static constexpr unsigned MaxArrayElemBytes
Maximum number of bytes to be used for array elements.
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.
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.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4