22 : Ctx(Ctx),
P(
P), S(
Parent,
P, Stk, Ctx, this), Result(Result) {
29 for (
auto &[K,
V] : Locals) {
40 return llvm::make_error<ByteCodeGenError>(*BailLocation);
48 return llvm::make_error<ByteCodeGenError>(*BailLocation);
61 auto *B =
new (Memory.get())
Block(D,
false);
75 unsigned Off = Locals.size();
76 Locals.insert({Off, std::move(Memory)});
104 CurrentLabel = ActiveLabel =
Label;
111 CurrentLabel =
Label;
115template <PrimType OpType>
bool EvalEmitter::emitRet(
const SourceInfo &Info) {
119 return ReturnValue<T>(S.
Stk.
pop<T>(), Result);
122bool EvalEmitter::emitRetVoid(
const SourceInfo &Info) {
return true; }
124bool EvalEmitter::emitRetValue(
const SourceInfo &Info) {
129 Ty = AT->getValueType();
132 const auto *
Record = Ptr.getRecord();
133 assert(
Record &&
"Missing record descriptor");
136 if (RT->getDecl()->isUnion()) {
141 QualType FieldTy = F.Decl->getType();
143 if (std::optional<PrimType> T = Ctx.
classify(FieldTy)) {
146 Ok &= Composite(FieldTy, FP,
Value);
159 for (
unsigned I = 0; I < NF; ++I) {
165 if (std::optional<PrimType> T = Ctx.
classify(FieldTy)) {
168 Ok &= Composite(FieldTy, FP,
Value);
172 for (
unsigned I = 0; I < NB; ++I) {
176 Ok &= Composite(BaseTy, BP, R.getStructBase(I));
179 for (
unsigned I = 0; I < NV; ++I) {
183 Ok &= Composite(VirtBaseTy, VP, R.getStructBase(NB + I));
195 const size_t NumElems = Ptr.getNumElems();
196 QualType ElemTy = AT->getElementType();
200 for (
unsigned I = 0; I < NumElems; ++I) {
203 if (std::optional<PrimType> T = Ctx.
classify(ElemTy)) {
206 Ok &= Composite(ElemTy, EP.
narrow(), Slot);
211 llvm_unreachable(
"invalid value to return");
216 return Composite(Ptr.getType(), Ptr, Result);
219bool EvalEmitter::emitGetPtrLocal(uint32_t I,
const SourceInfo &Info) {
223 Block *B = getLocal(I);
228template <PrimType OpType>
229bool EvalEmitter::emitGetLocal(uint32_t I,
const SourceInfo &Info) {
235 Block *B = getLocal(I);
240template <PrimType OpType>
241bool EvalEmitter::emitSetLocal(uint32_t I,
const SourceInfo &Info) {
247 Block *B = getLocal(I);
248 *
reinterpret_cast<T *
>(B->
data()) = S.
Stk.
pop<T>();
255bool EvalEmitter::emitDestroy(uint32_t I,
const SourceInfo &Info) {
272#include "Opcodes.inc"
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define TYPE_SWITCH(Expr, B)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APValue & getArrayInitializedElt(unsigned I)
QualType getRecordType(const RecordDecl *Decl) const
This represents one expression.
Represents a member of a struct/union/class.
A (possibly-)qualified type.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Encodes a location in the source.
bool isIncompleteArrayType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
const T * getAs() const
Member-template getAs<specific type>'.
Represents a variable declaration or definition.
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.
ASTContext & getASTContext() const
Returns the AST context.
std::optional< PrimType > classify(QualType T) const
Classifies an expression.
bool jump(const LabelTy &Label)
virtual bool visitExpr(const Expr *E)=0
Methods implemented by the compiler.
EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk, APValue &Result)
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.
llvm::Expected< bool > interpretDecl(const VarDecl *VD)
llvm::Expected< bool > interpretExpr(const Expr *E)
llvm::SmallVector< SmallVector< Local, 8 >, 2 > Descriptors
Local descriptors.
virtual bool visitDecl(const VarDecl *VD)=0
bool jumpTrue(const LabelTy &Label)
Emits jumps.
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.
A pointer to a memory block, live or dead.
Pointer narrow() const
Restricts the scope of an array element pointer.
Pointer atIndex(unsigned Idx) const
Offsets a pointer inside 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.
The program contains and links the bytecode for all functions.
Structure/Class descriptor.
unsigned getNumBases() const
const Field * getField(const FieldDecl *FD) const
Returns a field.
const Base * getVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
unsigned getNumFields() const
unsigned getNumVirtualBases() const
llvm::iterator_range< const_field_iter > fields() const
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
Describes the statement/declaration an opcode was generated from.
Interface for the VM to interact with the AST walker's context.
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.
Describes a record field.
Information about a local's storage.
unsigned Offset
Offset of the local in frame.