16 using namespace clang;
24 : Ctx(Ctx), P(P), S(Parent, P, Stk, Ctx, this), Result(Result) {
33 return llvm::make_error<ByteCodeGenError>(*BailLocation);
41 return llvm::make_error<ByteCodeGenError>(*BailLocation);
54 auto *B =
new (Memory.get())
Block(D,
false);
58 unsigned Off = Locals.size();
59 Locals.insert({Off, std::move(Memory)});
87 CurrentLabel = ActiveLabel =
Label;
98 template <PrimType OpType>
bool EvalEmitter::emitRet(
const SourceInfo &Info) {
102 return ReturnValue<T>(S.
Stk.
pop<T>(), Result);
105 bool EvalEmitter::emitRetVoid(
const SourceInfo &Info) {
return true; }
107 bool EvalEmitter::emitRetValue(
const SourceInfo &Info) {
109 std::function<bool(QualType, const Pointer &, APValue &)> Composite;
112 Ty = AT->getValueType();
115 auto *
Record = Ptr.getRecord();
116 assert(
Record &&
"Missing record descriptor");
119 if (RT->getDecl()->isUnion()) {
124 QualType FieldTy = F.Decl->getType();
129 Ok &= Composite(FieldTy, FP, Value);
134 R =
APValue(ActiveField, Value);
142 for (
unsigned I = 0; I < NF; ++I) {
151 Ok &= Composite(FieldTy, FP, Value);
155 for (
unsigned I = 0; I < NB; ++I) {
159 Ok &= Composite(BaseTy, BP, R.getStructBase(I));
162 for (
unsigned I = 0; I < NV; ++I) {
166 Ok &= Composite(VirtBaseTy, VP, R.getStructBase(NB + I));
173 QualType ElemTy = AT->getElementType();
177 for (
unsigned I = 0; I < NumElems; ++I) {
183 Ok &= Composite(ElemTy, EP.
narrow(), Slot);
188 llvm_unreachable(
"invalid value to return");
193 return Composite(Ptr.getType(), Ptr, Result);
196 bool EvalEmitter::emitGetPtrLocal(uint32_t I,
const SourceInfo &Info) {
200 auto It = Locals.find(I);
201 assert(It != Locals.end() &&
"Missing local variable");
206 template <PrimType OpType>
207 bool EvalEmitter::emitGetLocal(uint32_t I,
const SourceInfo &Info) {
213 auto It = Locals.find(I);
214 assert(It != Locals.end() &&
"Missing local variable");
215 auto *B =
reinterpret_cast<Block *
>(It->second.get());
216 S.
Stk.
push<T>(*
reinterpret_cast<T *
>(B + 1));
220 template <PrimType OpType>
221 bool EvalEmitter::emitSetLocal(uint32_t I,
const SourceInfo &Info) {
227 auto It = Locals.find(I);
228 assert(It != Locals.end() &&
"Missing local variable");
229 auto *B =
reinterpret_cast<Block *
>(It->second.get());
230 *
reinterpret_cast<T *
>(B + 1) = S.
Stk.
pop<T>();
234 bool EvalEmitter::emitDestroy(uint32_t I,
const SourceInfo &Info) {
240 assert(It != Locals.end() &&
"Missing local variable");
241 S.
deallocate(reinterpret_cast<Block *>(It->second.get()));
251 #define GET_EVAL_IMPL 252 #include "Opcodes.inc"
A (possibly-)qualified type.
InterpFrame * Current
The current frame.
Mapping from primitive types to their representation.
Pointer into the code segment.
void push(Tys &&... Args)
Constructs a value in place on the top of the stack.
Frame storing local variables.
const Base * getBase(const RecordDecl *FD) const
Returns a base descriptor.
LabelTy getLabel()
Create a label.
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
bool jumpFalse(const LabelTy &Label)
Describes the statement/declaration an opcode was generated from.
Holds all information required to evaluate constexpr code in a module.
Pointer atIndex(unsigned Idx) const
Offsets a pointer inside an array.
llvm::Optional< PrimType > classify(QualType T)
Classifies an expression.
A pointer to a memory block, live or dead.
EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk, APValue &Result)
Represents a member of a struct/union/class.
T pop()
Returns the value from the top of the stack and removes it.
InterpStack & Stk
Temporary stack.
A memory block, either on the stack or in the heap.
Structure/Class descriptor.
unsigned getNumVirtualBases()
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
bool isActive() const
Checks if the object is active.
Describes a memory block created by an allocation site.
virtual bool visitDecl(const VarDecl *VD)=0
llvm::Expected< bool > interpretDecl(const VarDecl *VD)
Stack frame storing temporaries and parameters.
llvm::Expected< bool > interpretExpr(const Expr *E)
This represents one expression.
Information about a local's storage.
ASTContext & getASTContext() const
Returns the AST context.
void invokeCtor()
Invokes the constructor.
Local createLocal(Descriptor *D)
Callback for registering a local.
APValue & getStructField(unsigned i)
unsigned Offset
Offset of the local in frame.
QualType getRecordType(const RecordDecl *Decl) const
The program contains and links the bytecode for all functions.
unsigned getNumElems() const
Returns the number of elements.
APValue & getArrayInitializedElt(unsigned I)
Pointer narrow() const
Restricts the scope of an array element pointer.
Encodes a location in the source.
unsigned getAllocSize() const
Returns the allocated size, including metadata.
void emitLabel(LabelTy Label)
Define a label.
Dataflow Directional Tag Classes.
llvm::SmallVector< SmallVector< Local, 8 >, 2 > Descriptors
Local descriptors.
bool fallthrough(const LabelTy &Label)
llvm::iterator_range< const_field_iter > fields() const
bool jump(const LabelTy &Label)
void deallocate(Block *B)
Deallocates a pointer.
Describes a record field.
T & deref() const
Dereferences the pointer, if it's live.
Pointer atField(unsigned Off) const
Creates a pointer to a field.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
#define TYPE_SWITCH(Expr, B)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Interface for the VM to interact with the AST walker's context.
const Field * getField(const FieldDecl *FD) const
Returns a field.
virtual bool visitExpr(const Expr *E)=0
Methods implemented by the compiler.
const Base * getVirtualBase(const RecordDecl *RD) const
Returns a virtual base descriptor.
bool jumpTrue(const LabelTy &Label)
Emits jumps.