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 =
56 EvalResult.setSource(VD);
59 EvalResult.setInvalid();
61 return std::move(this->EvalResult);
73 auto *B =
new (Memory.get())
Block(D,
false);
87 unsigned Off = Locals.size();
88 Locals.insert({Off, std::move(Memory)});
110 CurrentLabel = ActiveLabel =
Label;
117 CurrentLabel =
Label;
121template <PrimType OpType>
bool EvalEmitter::emitRet(
const SourceInfo &Info) {
125 EvalResult.setValue(S.
Stk.
pop<
T>().toAPValue());
129template <>
bool EvalEmitter::emitRet<PT_Ptr>(
const SourceInfo &Info) {
135 if (ConvertResultToRValue) {
136 if (std::optional<APValue>
V = Ptr.
toRValue(Ctx)) {
137 EvalResult.setValue(*
V);
142 if (CheckFullyInitialized) {
146 std::optional<APValue> RValueResult = Ptr.
toRValue(Ctx);
149 EvalResult.setValue(*RValueResult);
157template <>
bool EvalEmitter::emitRet<PT_FnPtr>(
const SourceInfo &Info) {
165bool EvalEmitter::emitRetVoid(
const SourceInfo &Info) {
166 EvalResult.setValid();
170bool EvalEmitter::emitRetValue(
const SourceInfo &Info) {
173 EvalResult.setValue(*APV);
177 EvalResult.setInvalid();
181bool EvalEmitter::emitGetPtrLocal(uint32_t I,
const SourceInfo &Info) {
185 Block *B = getLocal(I);
190template <PrimType OpType>
191bool EvalEmitter::emitGetLocal(uint32_t I,
const SourceInfo &Info) {
197 Block *B = getLocal(I);
202template <PrimType OpType>
203bool EvalEmitter::emitSetLocal(uint32_t I,
const SourceInfo &Info) {
209 Block *B = getLocal(I);
217bool EvalEmitter::emitDestroy(uint32_t I,
const SourceInfo &Info) {
234#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
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
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.