[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / AST / Interp / EvalEmitter.h
blob5a9be18c34a03bcc5cd718e8d93cf3c75d94bc8e
1 //===--- EvalEmitter.h - Instruction emitter for the VM ---------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines the instruction emitters.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_AST_INTERP_EVALEMITTER_H
14 #define LLVM_CLANG_AST_INTERP_EVALEMITTER_H
16 #include "InterpState.h"
17 #include "PrimType.h"
18 #include "Source.h"
19 #include "llvm/Support/Error.h"
21 namespace clang {
22 namespace interp {
23 class Context;
24 class Function;
25 class InterpStack;
26 class Program;
27 enum Opcode : uint32_t;
29 /// An emitter which evaluates opcodes as they are emitted.
30 class EvalEmitter : public SourceMapper {
31 public:
32 using LabelTy = uint32_t;
33 using AddrTy = uintptr_t;
34 using Local = Scope::Local;
36 llvm::Expected<bool> interpretExpr(const Expr *E);
37 llvm::Expected<bool> interpretDecl(const VarDecl *VD);
39 protected:
40 EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk,
41 APValue &Result);
43 virtual ~EvalEmitter();
45 /// Define a label.
46 void emitLabel(LabelTy Label);
47 /// Create a label.
48 LabelTy getLabel();
50 /// Methods implemented by the compiler.
51 virtual bool visitExpr(const Expr *E) = 0;
52 virtual bool visitDecl(const VarDecl *VD) = 0;
54 bool bail(const Stmt *S) { return bail(S->getBeginLoc()); }
55 bool bail(const Decl *D) { return bail(D->getBeginLoc()); }
56 bool bail(const SourceLocation &Loc);
58 /// Emits jumps.
59 bool jumpTrue(const LabelTy &Label);
60 bool jumpFalse(const LabelTy &Label);
61 bool jump(const LabelTy &Label);
62 bool fallthrough(const LabelTy &Label);
64 /// Callback for registering a local.
65 Local createLocal(Descriptor *D);
67 /// Returns the source location of the current opcode.
68 SourceInfo getSource(const Function *F, CodePtr PC) const override {
69 return (F && F->hasBody()) ? F->getSource(PC) : CurrentSource;
72 /// Parameter indices.
73 llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params;
74 /// Lambda captures.
75 llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;
76 /// Offset of the This parameter in a lambda record.
77 unsigned LambdaThisCapture = 0;
78 /// Local descriptors.
79 llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;
81 private:
82 /// Current compilation context.
83 Context &Ctx;
84 /// Current program.
85 Program &P;
86 /// Callee evaluation state.
87 InterpState S;
88 /// Location to write the result to.
89 APValue &Result;
91 /// Temporaries which require storage.
92 llvm::DenseMap<unsigned, std::unique_ptr<char[]>> Locals;
94 Block *getLocal(unsigned Index) const {
95 auto It = Locals.find(Index);
96 assert(It != Locals.end() && "Missing local variable");
97 return reinterpret_cast<Block *>(It->second.get());
100 // The emitter always tracks the current instruction and sets OpPC to a token
101 // value which is mapped to the location of the opcode being evaluated.
102 CodePtr OpPC;
103 /// Location of a failure.
104 std::optional<SourceLocation> BailLocation;
105 /// Location of the current instruction.
106 SourceInfo CurrentSource;
108 /// Next label ID to generate - first label is 1.
109 LabelTy NextLabel = 1;
110 /// Label being executed - 0 is the entry label.
111 LabelTy CurrentLabel = 0;
112 /// Active block which should be executed.
113 LabelTy ActiveLabel = 0;
115 /// Since expressions can only jump forward, predicated execution is
116 /// used to deal with if-else statements.
117 bool isActive() const { return CurrentLabel == ActiveLabel; }
119 protected:
120 #define GET_EVAL_PROTO
121 #include "Opcodes.inc"
122 #undef GET_EVAL_PROTO
125 } // namespace interp
126 } // namespace clang
128 #endif