21 : Ctx(Ctx),
P(
P), S(
Parent,
P, Stk, Ctx, this), EvalResult(&Ctx) {
28 for (
auto &[K,
V] : Locals) {
36 bool ConvertResultToRValue) {
37 this->ConvertResultToRValue = ConvertResultToRValue;
38 EvalResult.setSource(E);
43 EvalResult.setInvalid();
46 return std::move(this->EvalResult);
51 this->CheckFullyInitialized = CheckFullyInitialized;
52 this->ConvertResultToRValue =
55 EvalResult.setSource(VD);
58 EvalResult.setInvalid();
60 return std::move(this->EvalResult);
72 auto *B =
new (Memory.get())
Block(D,
false);
86 unsigned Off = Locals.size();
87 Locals.insert({Off, std::move(Memory)});
109 CurrentLabel = ActiveLabel =
Label;
116 CurrentLabel =
Label;
120template <PrimType OpType>
bool EvalEmitter::emitRet(
const SourceInfo &Info) {
124 EvalResult.setValue(S.
Stk.
pop<T>().toAPValue());
128template <>
bool EvalEmitter::emitRet<PT_Ptr>(
const SourceInfo &Info) {
134 if (ConvertResultToRValue) {
135 if (std::optional<APValue>
V = Ptr.
toRValue(Ctx)) {
136 EvalResult.setValue(*
V);
141 if (CheckFullyInitialized) {
145 std::optional<APValue> RValueResult = Ptr.
toRValue(Ctx);
148 EvalResult.setValue(*RValueResult);
156template <>
bool EvalEmitter::emitRet<PT_FnPtr>(
const SourceInfo &Info) {
164bool EvalEmitter::emitRetVoid(
const SourceInfo &Info) {
165 EvalResult.setValid();
169bool EvalEmitter::emitRetValue(
const SourceInfo &Info) {
172 EvalResult.setValue(*APV);
176 EvalResult.setInvalid();
180bool EvalEmitter::emitGetPtrLocal(uint32_t I,
const SourceInfo &Info) {
184 Block *B = getLocal(I);
189template <PrimType OpType>
190bool EvalEmitter::emitGetLocal(uint32_t I,
const SourceInfo &Info) {
196 Block *B = getLocal(I);
201template <PrimType OpType>
202bool EvalEmitter::emitSetLocal(uint32_t I,
const SourceInfo &Info) {
208 Block *B = getLocal(I);
209 *
reinterpret_cast<T *
>(B->
data()) = S.
Stk.
pop<T>();
216bool EvalEmitter::emitDestroy(uint32_t I,
const SourceInfo &Info) {
233#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.
bool isAnyComplexType() 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
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.
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.