brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · a9f87db Raw
153 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// Defines the instruction emitters.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_AST_INTERP_EVALEMITTER_H14#define LLVM_CLANG_AST_INTERP_EVALEMITTER_H15 16#include "EvaluationResult.h"17#include "InterpState.h"18#include "PrimType.h"19#include "Record.h"20#include "Source.h"21 22namespace clang {23namespace interp {24class Context;25class Function;26class InterpStack;27class Program;28enum Opcode : uint32_t;29 30/// An emitter which evaluates opcodes as they are emitted.31class EvalEmitter : public SourceMapper {32public:33  using LabelTy = uint32_t;34  using AddrTy = uintptr_t;35  using Local = Scope::Local;36  using PtrCallback = llvm::function_ref<bool(const Pointer &)>;37 38  EvaluationResult interpretExpr(const Expr *E,39                                 bool ConvertResultToRValue = false,40                                 bool DestroyToplevelScope = false);41  EvaluationResult interpretDecl(const VarDecl *VD, const Expr *Init,42                                 bool CheckFullyInitialized);43  /// Interpret the given Expr to a Pointer.44  EvaluationResult interpretAsPointer(const Expr *E, PtrCallback PtrCB);45  /// Interpret the given expression as if it was in the body of the given46  /// function, i.e. the parameters of the function are available for use.47  bool interpretCall(const FunctionDecl *FD, const Expr *E);48 49  /// Clean up all resources.50  void cleanup();51 52protected:53  EvalEmitter(Context &Ctx, Program &P, State &Parent, InterpStack &Stk);54 55  virtual ~EvalEmitter();56 57  /// Define a label.58  void emitLabel(LabelTy Label);59  /// Create a label.60  LabelTy getLabel();61 62  /// Methods implemented by the compiler.63  virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;64  virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,65                                  bool ConstantContext) = 0;66  virtual bool visitFunc(const FunctionDecl *F) = 0;67  virtual bool visit(const Expr *E) = 0;68  virtual bool emitBool(bool V, const Expr *E) = 0;69 70  /// Emits jumps.71  bool jumpTrue(const LabelTy &Label);72  bool jumpFalse(const LabelTy &Label);73  bool jump(const LabelTy &Label);74  bool fallthrough(const LabelTy &Label);75  /// Speculative execution.76  bool speculate(const CallExpr *E, const LabelTy &EndLabel);77 78  /// Since expressions can only jump forward, predicated execution is79  /// used to deal with if-else statements.80  bool isActive() const { return CurrentLabel == ActiveLabel; }81  bool checkingForUndefinedBehavior() const {82    return S.checkingForUndefinedBehavior();83  }84 85  /// Callback for registering a local.86  Local createLocal(Descriptor *D);87 88  /// Returns the source location of the current opcode.89  SourceInfo getSource(const Function *F, CodePtr PC) const override {90    return (F && F->hasBody()) ? F->getSource(PC) : CurrentSource;91  }92 93  /// Parameter indices.94  llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params;95  /// Lambda captures.96  llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;97  /// Offset of the This parameter in a lambda record.98  ParamOffset LambdaThisCapture{0, false};99  /// Local descriptors.100  llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;101  std::optional<SourceInfo> LocOverride = std::nullopt;102 103private:104  /// Current compilation context.105  Context &Ctx;106  /// Current program.107  Program &P;108  /// Callee evaluation state.109  InterpState S;110  /// Location to write the result to.111  EvaluationResult EvalResult;112  /// Whether the result should be converted to an RValue.113  bool ConvertResultToRValue = false;114  /// Whether we should check if the result has been fully115  /// initialized.116  bool CheckFullyInitialized = false;117  /// Callback to call when using interpretAsPointer.118  std::optional<PtrCallback> PtrCB;119 120  /// Temporaries which require storage.121  llvm::SmallVector<std::unique_ptr<char[]>> Locals;122 123  Block *getLocal(unsigned Index) const {124    assert(Index < Locals.size());125    return reinterpret_cast<Block *>(Locals[Index].get());126  }127 128  void updateGlobalTemporaries();129 130  // The emitter always tracks the current instruction and sets OpPC to a token131  // value which is mapped to the location of the opcode being evaluated.132  CodePtr OpPC;133  /// Location of the current instruction.134  SourceInfo CurrentSource;135 136  /// Next label ID to generate - first label is 1.137  LabelTy NextLabel = 1;138  /// Label being executed - 0 is the entry label.139  LabelTy CurrentLabel = 0;140  /// Active block which should be executed.141  LabelTy ActiveLabel = 0;142 143protected:144#define GET_EVAL_PROTO145#include "Opcodes.inc"146#undef GET_EVAL_PROTO147};148 149} // namespace interp150} // namespace clang151 152#endif153