21 : Ctx(Ctx),
P(
P), S(
Parent,
P, Stk, Ctx, this), EvalResult(&Ctx) {
28 for (
auto &[K,
V] : Locals) {
36 bool ConvertResultToRValue) {
38 this->ConvertResultToRValue = ConvertResultToRValue;
39 EvalResult.setSource(E);
44 EvalResult.setInvalid();
47 return std::move(this->EvalResult);
52 this->CheckFullyInitialized = CheckFullyInitialized;
53 this->ConvertResultToRValue =
57 EvalResult.setSource(VD);
60 EvalResult.setInvalid();
62 return std::move(this->EvalResult);
74 auto *B =
new (Memory.get())
Block(D,
false);
88 unsigned Off = Locals.size();
89 Locals.insert({Off, std::move(Memory)});
111 CurrentLabel = ActiveLabel =
Label;
118 CurrentLabel =
Label;
122template <PrimType OpType>
bool EvalEmitter::emitRet(
const SourceInfo &Info) {
126 EvalResult.setValue(S.
Stk.
pop<
T>().toAPValue());
130template <>
bool EvalEmitter::emitRet<PT_Ptr>(
const SourceInfo &Info) {
136 if (ConvertResultToRValue) {
137 if (std::optional<APValue>
V = Ptr.
toRValue(Ctx)) {
138 EvalResult.setValue(*
V);
143 if (CheckFullyInitialized) {
147 std::optional<APValue> RValueResult = Ptr.
toRValue(Ctx);
150 EvalResult.setValue(*RValueResult);
158template <>
bool EvalEmitter::emitRet<PT_FnPtr>(
const SourceInfo &Info) {
166bool EvalEmitter::emitRetVoid(
const SourceInfo &Info) {
167 EvalResult.setValid();
171bool EvalEmitter::emitRetValue(
const SourceInfo &Info) {
174 EvalResult.setValue(*APV);
178 EvalResult.setInvalid();
182bool EvalEmitter::emitGetPtrLocal(uint32_t I,
const SourceInfo &Info) {
186 Block *B = getLocal(I);
191template <PrimType OpType>
192bool EvalEmitter::emitGetLocal(uint32_t I,
const SourceInfo &Info) {
198 Block *B = getLocal(I);
203template <PrimType OpType>
204bool EvalEmitter::emitSetLocal(uint32_t I,
const SourceInfo &Info) {
210 Block *B = getLocal(I);
218bool EvalEmitter::emitDestroy(uint32_t I,
const SourceInfo &Info) {
235#include "Opcodes.inc"
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static bool CheckFullyInitialized(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value)
Check that this evaluated value is fully-initialized and can be loaded by an lvalue-to-rvalue convers...
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...
bool isAnyComplexType() const
bool isVectorType() const
Represents a variable declaration or definition.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
A memory block, either on the stack or in the heap.
void invokeDtor()
Invokes the Destructor.
std::byte * data()
Returns a pointer to the stored data.
void invokeCtor()
Invokes the constructor.
std::byte * rawData()
Returns a pointer to the raw data, including metadata.
bool isInitialized() const
Pointer into the code segment.
Holds all information required to evaluate constexpr code in a module.
bool jump(const LabelTy &Label)
EvaluationResult interpretExpr(const Expr *E, bool ConvertResultToRValue=false)
EvaluationResult interpretDecl(const VarDecl *VD, bool CheckFullyInitialized)
virtual bool visitExpr(const Expr *E)=0
Methods implemented by the compiler.
bool jumpFalse(const LabelTy &Label)
Local createLocal(Descriptor *D)
Callback for registering a local.
void emitLabel(LabelTy Label)
Define a label.
bool fallthrough(const LabelTy &Label)
LabelTy getLabel()
Create a label.
EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk)
llvm::SmallVector< SmallVector< Local, 8 >, 2 > Descriptors
Local descriptors.
virtual bool visitDecl(const VarDecl *VD)=0
bool jumpTrue(const LabelTy &Label)
Emits jumps.
Defines the result of an evaluation.
bool checkFullyInitialized(InterpState &S, const Pointer &Ptr) const
Frame storing local variables.
Stack frame storing temporaries and parameters.
T pop()
Returns the value from the top of the stack and removes it.
void push(Tys &&... Args)
Constructs a value in place on the top of the stack.
InterpStack & Stk
Temporary stack.
InterpFrame * Current
The current frame.
void deallocate(Block *B)
Deallocates a pointer.
ASTContext & getCtx() const override
void setEvalLocation(SourceLocation SL)
A pointer to a memory block, live or dead.
std::optional< APValue > toRValue(const Context &Ctx) const
Converts the pointer to an APValue that is an rvalue.
APValue toAPValue() const
Converts the pointer to an APValue.
The program contains and links the bytecode for all functions.
Describes the statement/declaration an opcode was generated from.
Interface for the VM to interact with the AST walker's context.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
Describes a memory block created by an allocation site.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
Inline descriptor embedded in structures and arrays.
unsigned IsActive
Flag indicating if the field is the active member of a union.
unsigned IsBase
Flag indicating if the field is an embedded base class.
unsigned Offset
Offset inside the structure/array.
unsigned IsInitialized
For primitive fields, it indicates if the field was initialized.
unsigned IsConst
Flag indicating if the storage is constant or not.
unsigned IsFieldMutable
Flag indicating if the field is mutable (if in a record).
Mapping from primitive types to their representation.
Information about a local's storage.
unsigned Offset
Offset of the local in frame.