1 //===--- EvalEmitter.h - Instruction emitter for the VM ---------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Defines the instruction emitters.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_AST_INTERP_EVALEMITTER_H
14 #define LLVM_CLANG_AST_INTERP_EVALEMITTER_H
16 #include "ByteCodeGenError.h"
18 #include "InterpStack.h"
19 #include "InterpState.h"
23 #include "llvm/Support/Error.h"
33 enum Opcode : uint32_t;
35 /// An emitter which evaluates opcodes as they are emitted.
36 class EvalEmitter : public SourceMapper {
38 using LabelTy = uint32_t;
39 using AddrTy = uintptr_t;
40 using Local = Scope::Local;
42 llvm::Expected<bool> interpretExpr(const Expr *E);
43 llvm::Expected<bool> interpretDecl(const VarDecl *VD);
46 EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk,
49 virtual ~EvalEmitter() {}
52 void emitLabel(LabelTy Label);
56 /// Methods implemented by the compiler.
57 virtual bool visitExpr(const Expr *E) = 0;
58 virtual bool visitDecl(const VarDecl *VD) = 0;
60 bool bail(const Stmt *S) { return bail(S->getBeginLoc()); }
61 bool bail(const Decl *D) { return bail(D->getBeginLoc()); }
62 bool bail(const SourceLocation &Loc);
65 bool jumpTrue(const LabelTy &Label);
66 bool jumpFalse(const LabelTy &Label);
67 bool jump(const LabelTy &Label);
68 bool fallthrough(const LabelTy &Label);
70 /// Callback for registering a local.
71 Local createLocal(Descriptor *D);
73 /// Returns the source location of the current opcode.
74 SourceInfo getSource(Function *F, CodePtr PC) const override {
75 return F ? F->getSource(PC) : CurrentSource;
78 /// Parameter indices.
79 llvm::DenseMap<const ParmVarDecl *, unsigned> Params;
80 /// Local descriptors.
81 llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
84 /// Current compilation context.
88 /// Callee evaluation state.
90 /// Location to write the result to.
93 /// Temporaries which require storage.
94 llvm::DenseMap<unsigned, std::unique_ptr<char[]>> Locals;
96 // The emitter always tracks the current instruction and sets OpPC to a token
97 // value which is mapped to the location of the opcode being evaluated.
99 /// Location of a failure.
100 llvm::Optional<SourceLocation> BailLocation;
101 /// Location of the current instruction.
102 SourceInfo CurrentSource;
104 /// Next label ID to generate - first label is 1.
105 LabelTy NextLabel = 1;
106 /// Label being executed - 0 is the entry label.
107 LabelTy CurrentLabel = 0;
108 /// Active block which should be executed.
109 LabelTy ActiveLabel = 0;
111 /// Since expressions can only jump forward, predicated execution is
112 /// used to deal with if-else statements.
113 bool isActive() { return CurrentLabel == ActiveLabel; }
115 /// Helper to invoke a method.
116 bool ExecuteCall(Function *F, Pointer &&This, const SourceInfo &Info);
117 /// Helper to emit a diagnostic on a missing method.
118 bool ExecuteNoCall(const FunctionDecl *F, const SourceInfo &Info);
121 #define GET_EVAL_PROTO
122 #include "Opcodes.inc"
123 #undef GET_EVAL_PROTO
126 } // namespace interp