8#include "../ExprConstShared.h"
21 assert(
Frame->getFunction()->getNumParams() > Index);
22 unsigned Offset =
Frame->getFunction()->getParamOffset(Index);
23 return Frame->getParam<T>(Offset);
27 const TargetInfo &TI = S.getCtx().getTargetInfo();
32 else if (IntWidth == 16)
34 llvm_unreachable(
"Int isn't 16 or 32 bit?");
44 T Val = Stk.
peek<T>(Offset);
46 APInt(Val.bitWidth(),
static_cast<uint64_t
>(Val), T::isSigned()));
60 llvm_unreachable(
"Int isn't 16 or 32 bit?");
64 bool Signed = Val.isSigned();
67 switch (Val.getBitWidth()) {
85 llvm_unreachable(
"Invalid integer bitwidth");
91 switch (Val.getBitWidth()) {
109 llvm_unreachable(
"Invalid integer bitwidth");
114 const TargetInfo &TI = S.getCtx().getTargetInfo();
117 switch (SizeTWidth) {
128 llvm_unreachable(
"We don't handle this size_t size.");
133 std::optional<PrimType> &T) {
139 return Ret<X>(S, OpPC, Result);
152 llvm_unreachable(
"Unsupported return type for builtin function");
171 for (;; ++IndexA, ++IndexB) {
178 uint8_t CA = PA.
deref<uint8_t>();
179 uint8_t CB = PB.
deref<uint8_t>();
184 }
else if (CA < CB) {
188 if (CA == 0 || CB == 0)
212 for (
size_t I = StrPtr.
getIndex();; ++I, ++Len) {
218 uint8_t Val = ElemPtr.
deref<uint8_t>();
241 for (
unsigned I = 0;; ++I) {
247 if (Elem.
deref<int8_t>() == 0)
250 Str += Elem.
deref<
char>();
255 Fill = llvm::APInt(32, 0);
256 else if (StringRef(Str).getAsInteger(0, Fill))
259 const llvm::fltSemantics &TargetSemantics =
263 if (S.getCtx().getTargetInfo().isNan2008()) {
266 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
269 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
278 llvm::APFloat::getQNaN(TargetSemantics,
false, &Fill));
281 llvm::APFloat::getSNaN(TargetSemantics,
false, &Fill));
290 const llvm::fltSemantics &TargetSemantics =
320 else if (LHS.
isNan() || RHS < LHS)
340 else if (LHS.
isNan() || RHS > LHS)
373 bool IsInf = Arg.
isInf();
424 PrimType FPClassArgT = *S.getContext().classify(
Call->getArg(1)->getType());
430 static_cast<int32_t
>((F.
classify() & FPClassArg).getZExtValue());
447 case APFloat::fcInfinity:
450 case APFloat::fcNormal:
453 case APFloat::fcZero:
487 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
496 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
498 pushInt(S, Val.popcount() % 2);
505 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
507 pushInt(S, Val.getBitWidth() - Val.getSignificantBits());
515 PrimType ArgT = *S.getContext().classify(
Call->getArg(0)->getType());
526 assert(
Call->getNumArgs() == 1);
531 int32_t ReturnVal =
static_cast<int32_t
>(ResultClass);
541 QualType ReturnType =
Call->getCallReturnType(S.getCtx());
542 std::optional<PrimType> ReturnT = S.getContext().classify(ReturnType);
547 case Builtin::BI__builtin_is_constant_evaluated:
550 case Builtin::BI__builtin_assume:
552 case Builtin::BI__builtin_strcmp:
556 case Builtin::BI__builtin_strlen:
560 case Builtin::BI__builtin_nan:
561 case Builtin::BI__builtin_nanf:
562 case Builtin::BI__builtin_nanl:
563 case Builtin::BI__builtin_nanf16:
564 case Builtin::BI__builtin_nanf128:
568 case Builtin::BI__builtin_nans:
569 case Builtin::BI__builtin_nansf:
570 case Builtin::BI__builtin_nansl:
571 case Builtin::BI__builtin_nansf16:
572 case Builtin::BI__builtin_nansf128:
577 case Builtin::BI__builtin_huge_val:
578 case Builtin::BI__builtin_huge_valf:
579 case Builtin::BI__builtin_huge_vall:
580 case Builtin::BI__builtin_huge_valf16:
581 case Builtin::BI__builtin_huge_valf128:
582 case Builtin::BI__builtin_inf:
583 case Builtin::BI__builtin_inff:
584 case Builtin::BI__builtin_infl:
585 case Builtin::BI__builtin_inff16:
586 case Builtin::BI__builtin_inff128:
590 case Builtin::BI__builtin_copysign:
591 case Builtin::BI__builtin_copysignf:
592 case Builtin::BI__builtin_copysignl:
593 case Builtin::BI__builtin_copysignf128:
598 case Builtin::BI__builtin_fmin:
599 case Builtin::BI__builtin_fminf:
600 case Builtin::BI__builtin_fminl:
601 case Builtin::BI__builtin_fminf16:
602 case Builtin::BI__builtin_fminf128:
607 case Builtin::BI__builtin_fmax:
608 case Builtin::BI__builtin_fmaxf:
609 case Builtin::BI__builtin_fmaxl:
610 case Builtin::BI__builtin_fmaxf16:
611 case Builtin::BI__builtin_fmaxf128:
616 case Builtin::BI__builtin_isnan:
620 case Builtin::BI__builtin_issignaling:
625 case Builtin::BI__builtin_isinf:
630 case Builtin::BI__builtin_isinf_sign:
635 case Builtin::BI__builtin_isfinite:
639 case Builtin::BI__builtin_isnormal:
643 case Builtin::BI__builtin_issubnormal:
647 case Builtin::BI__builtin_iszero:
651 case Builtin::BI__builtin_isfpclass:
655 case Builtin::BI__builtin_fpclassify:
660 case Builtin::BI__builtin_fabs:
661 case Builtin::BI__builtin_fabsf:
662 case Builtin::BI__builtin_fabsl:
663 case Builtin::BI__builtin_fabsf128:
668 case Builtin::BI__builtin_popcount:
669 case Builtin::BI__builtin_popcountl:
670 case Builtin::BI__builtin_popcountll:
671 case Builtin::BI__popcnt16:
672 case Builtin::BI__popcnt:
673 case Builtin::BI__popcnt64:
678 case Builtin::BI__builtin_parity:
679 case Builtin::BI__builtin_parityl:
680 case Builtin::BI__builtin_parityll:
685 case Builtin::BI__builtin_clrsb:
686 case Builtin::BI__builtin_clrsbl:
687 case Builtin::BI__builtin_clrsbll:
692 case Builtin::BI__builtin_bitreverse8:
693 case Builtin::BI__builtin_bitreverse16:
694 case Builtin::BI__builtin_bitreverse32:
695 case Builtin::BI__builtin_bitreverse64:
700 case Builtin::BI__builtin_classify_type:
714 int64_t &IntResult) {
719 unsigned ArrayIndex = 0;
721 for (
unsigned I = 0; I != N; ++I) {
723 switch (
Node.getKind()) {
734 assert(FieldIndex < RL.
getFieldCount() &&
"offsetof field in wrong type");
742 int64_t Index = ArrayIndices[ArrayIndex];
743 const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType);
747 CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType);
748 Result += Index * ElementSize;
767 CurrentType = BaseSpec->
getType();
777 llvm_unreachable(
"Dependent OffsetOfExpr?");
781 IntResult =
Result.getQuantity();
798 FieldPtr.
deref<T>() = T::from(IntValue.getSExtValue()));
Defines enum values for all the target-independent builtin functions.
GCCTypeClass
Values returned by __builtin_classify_type, chosen to match the values produced by GCC's builtin.
GCCTypeClass EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts)
EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way as GCC.
#define INT_TYPE_SWITCH(Expr, B)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a base class of a C++ class.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits - This is an opaque type for sizes expressed in character units.
bool isInvalidDecl() const
This represents one expression.
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...
QualType getReturnType() const
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
Helper class for OffsetOfExpr.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
A (possibly-)qualified type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Represents a struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
const LangOptions & getLangOpts() const
Exposes information about the current target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...
IntType getSizeType() const
QualType getType() const
Return the type wrapped by this type source info.
const T * getAs() const
Member-template getAs<specific type>'.
Wrapper around boolean types.
static Boolean from(T Value)
Pointer into the code segment.
const APFloat & getAPFloat() const
llvm::FPClassTest classify() const
static Floating getInf(const llvm::fltSemantics &Sem)
static Floating abs(const Floating &F)
APFloat::fltCategory getCategory() const
Base class for stack frames, shared between VM and walker.
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
unsigned getBuiltinID() const
Wrapper around numeric types.
static Integral from(ValT Value)
Frame storing local variables.
Stack frame storing temporaries and parameters.
T & peek() const
Returns a reference to the value on the top of the stack.
A pointer to a memory block, live or dead.
int64_t getIndex() const
Returns the index into an array.
Pointer atIndex(unsigned Idx) const
Offsets a pointer inside an array.
Pointer atField(unsigned Off) const
Creates a pointer to a field.
T & deref() const
Dereferences the pointer, if it's live.
unsigned getNumElems() const
Returns the number of elements.
QualType getType() const
Returns the type of the innermost field.
const Descriptor * getFieldDesc() const
Accessors for information about the innermost field.
void initialize() const
Initializes a field.
const Record * getRecord() const
Returns the record descriptor of a class.
Structure/Class descriptor.
const Field * getField(const FieldDecl *FD) const
Returns a field.
unsigned getNumFields() const
Defines the clang::TargetInfo interface.
static void pushAPSInt(InterpState &S, const APSInt &Val)
static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
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 bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, llvm::ArrayRef< int64_t > ArrayIndices, int64_t &Result)
Interpret an offsetof operation.
static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool Signaling)
bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, const Pointer &Ptr, const APSInt &IntValue)
Sets the given integral value to the pointer, which is of a std::{weak,partial,strong}_ordering type.
static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func)
static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static void pushInt(InterpState &S, int32_t Val)
Pushes Val to the stack, as a target-dependent 'int'.
static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static T getParam(const InterpFrame *Frame, unsigned Index)
PrimType getIntPrimType(const InterpState &S)
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is in range.
bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK)
Checks if a pointer is live and accessible.
static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, std::optional< PrimType > &T)
PrimType
Enumeration of the primitive types of the VM.
static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func)
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a value can be loaded from a block.
bool CheckArray(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if the array is offsetable.
static void pushSizeT(InterpState &S, uint64_t Val)
static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call)
Interpret a builtin function.
static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, bool CheckSign)
static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const InterpFrame *Frame)
bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr)
Checks if a pointer is a dummy pointer.
static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func)
Five int values followed by one floating value.
static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
Defined as __builtin_isnan(...), to accommodate the fact that it can take a float,...
static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
First parameter to __builtin_isfpclass is the floating value, the second one is an integral value.
static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call)
static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F)
bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result)
@ Result
The result type of a method or function.
bool isPrimitiveArray() const
Checks if the descriptor is of an array of primitives.