Path: blob/main/contrib/llvm-project/clang/lib/AST/ByteCode/ByteCodeEmitter.h
213799 views
//===--- ByteCodeEmitter.h - Instruction emitter for the VM -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Defines the instruction emitters.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_CLANG_AST_INTERP_LINKEMITTER_H13#define LLVM_CLANG_AST_INTERP_LINKEMITTER_H1415#include "Context.h"16#include "PrimType.h"17#include "Program.h"18#include "Source.h"1920namespace clang {21namespace interp {22enum Opcode : uint32_t;2324/// An emitter which links the program to bytecode for later use.25class ByteCodeEmitter {26protected:27using LabelTy = uint32_t;28using AddrTy = uintptr_t;29using Local = Scope::Local;3031public:32/// Compiles the function into the module.33void compileFunc(const FunctionDecl *FuncDecl, Function *Func = nullptr);3435protected:36ByteCodeEmitter(Context &Ctx, Program &P) : Ctx(Ctx), P(P) {}3738virtual ~ByteCodeEmitter() {}3940/// Define a label.41void emitLabel(LabelTy Label);42/// Create a label.43LabelTy getLabel() { return ++NextLabel; }4445/// Methods implemented by the compiler.46virtual bool visitFunc(const FunctionDecl *E) = 0;47virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;48virtual bool visitDeclAndReturn(const VarDecl *E, bool ConstantContext) = 0;49virtual bool visit(const Expr *E) = 0;50virtual bool emitBool(bool V, const Expr *E) = 0;5152/// Emits jumps.53bool jumpTrue(const LabelTy &Label);54bool jumpFalse(const LabelTy &Label);55bool jump(const LabelTy &Label);56bool fallthrough(const LabelTy &Label);57/// Speculative execution.58bool speculate(const CallExpr *E, const LabelTy &EndLabel);5960/// We're always emitting bytecode.61bool isActive() const { return true; }62bool checkingForUndefinedBehavior() const { return false; }6364/// Callback for local registration.65Local createLocal(Descriptor *D);6667/// Parameter indices.68llvm::DenseMap<const ParmVarDecl *, ParamOffset> Params;69/// Lambda captures.70llvm::DenseMap<const ValueDecl *, ParamOffset> LambdaCaptures;71/// Offset of the This parameter in a lambda record.72ParamOffset LambdaThisCapture{0, false};73/// Local descriptors.74llvm::SmallVector<SmallVector<Local, 8>, 2> Descriptors;7576private:77/// Current compilation context.78Context &Ctx;79/// Program to link to.80Program &P;81/// Index of the next available label.82LabelTy NextLabel = 0;83/// Offset of the next local variable.84unsigned NextLocalOffset = 0;85/// Label information for linker.86llvm::DenseMap<LabelTy, unsigned> LabelOffsets;87/// Location of label relocations.88llvm::DenseMap<LabelTy, llvm::SmallVector<unsigned, 5>> LabelRelocs;89/// Program code.90std::vector<std::byte> Code;91/// Opcode to expression mapping.92SourceMap SrcMap;9394/// Returns the offset for a jump or records a relocation.95int32_t getOffset(LabelTy Label);9697/// Emits an opcode.98template <typename... Tys>99bool emitOp(Opcode Op, const Tys &...Args, const SourceInfo &L);100101protected:102#define GET_LINK_PROTO103#include "Opcodes.inc"104#undef GET_LINK_PROTO105};106107} // namespace interp108} // namespace clang109110#endif111112113