diff options
Diffstat (limited to 'clang/lib/AST/Interp/ByteCodeExprGen.h')
-rw-r--r-- | clang/lib/AST/Interp/ByteCodeExprGen.h | 340 |
1 files changed, 0 insertions, 340 deletions
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h deleted file mode 100644 index f0ec1203292..00000000000 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ /dev/null @@ -1,340 +0,0 @@ -//===--- ByteCodeExprGen.h - Code generator for expressions -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Defines the constexpr bytecode compiler. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H -#define LLVM_CLANG_AST_INTERP_BYTECODEEXPRGEN_H - -#include "ByteCodeEmitter.h" -#include "EvalEmitter.h" -#include "Pointer.h" -#include "Record.h" -#include "Type.h" -#include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" -#include "clang/AST/StmtVisitor.h" -#include "llvm/ADT/Optional.h" - -namespace clang { -class QualType; - -namespace interp { -class Function; -class State; - -template <class Emitter> class LocalScope; -template <class Emitter> class RecordScope; -template <class Emitter> class VariableScope; -template <class Emitter> class DeclScope; -template <class Emitter> class OptionScope; - -/// Compilation context for expressions. -template <class Emitter> -class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>, - public Emitter { -protected: - // Emitters for opcodes of various arities. - using NullaryFn = bool (ByteCodeExprGen::*)(const SourceInfo &); - using UnaryFn = bool (ByteCodeExprGen::*)(PrimType, const SourceInfo &); - using BinaryFn = bool (ByteCodeExprGen::*)(PrimType, PrimType, - const SourceInfo &); - - // Aliases for types defined in the emitter. - using LabelTy = typename Emitter::LabelTy; - using AddrTy = typename Emitter::AddrTy; - - // Reference to a function generating the pointer of an initialized object.s - using InitFnRef = std::function<bool()>; - - /// Current compilation context. - Context &Ctx; - /// Program to link to. - Program &P; - -public: - /// Initializes the compiler and the backend emitter. - template <typename... Tys> - ByteCodeExprGen(Context &Ctx, Program &P, Tys &&... Args) - : Emitter(Ctx, P, Args...), Ctx(Ctx), P(P) {} - - // Expression visitors - result returned on stack. - bool VisitCastExpr(const CastExpr *E); - bool VisitIntegerLiteral(const IntegerLiteral *E); - bool VisitParenExpr(const ParenExpr *E); - bool VisitBinaryOperator(const BinaryOperator *E); - -protected: - bool visitExpr(const Expr *E) override; - bool visitDecl(const VarDecl *VD) override; - -protected: - /// Emits scope cleanup instructions. - void emitCleanup(); - - /// Returns a record type from a record or pointer type. - const RecordType *getRecordTy(QualType Ty); - - /// Returns a record from a record or pointer type. - Record *getRecord(QualType Ty); - Record *getRecord(const RecordDecl *RD); - - /// Returns the size int bits of an integer. - unsigned getIntWidth(QualType Ty) { - auto &ASTContext = Ctx.getASTContext(); - return ASTContext.getIntWidth(Ty); - } - - /// Returns the value of CHAR_BIT. - unsigned getCharBit() const { - auto &ASTContext = Ctx.getASTContext(); - return ASTContext.getTargetInfo().getCharWidth(); - } - - /// Classifies a type. - llvm::Optional<PrimType> classify(const Expr *E) const { - return E->isGLValue() ? PT_Ptr : classify(E->getType()); - } - llvm::Optional<PrimType> classify(QualType Ty) const { - return Ctx.classify(Ty); - } - - /// Checks if a pointer needs adjustment. - bool needsAdjust(QualType Ty) const { - return true; - } - - /// Classifies a known primitive type - PrimType classifyPrim(QualType Ty) const { - if (auto T = classify(Ty)) { - return *T; - } - llvm_unreachable("not a primitive type"); - } - - /// Evaluates an expression for side effects and discards the result. - bool discard(const Expr *E); - /// Evaluates an expression and places result on stack. - bool visit(const Expr *E); - /// Compiles an initializer for a local. - bool visitInitializer(const Expr *E, InitFnRef GenPtr); - - /// Visits an expression and converts it to a boolean. - bool visitBool(const Expr *E); - - /// Visits an initializer for a local. - bool visitLocalInitializer(const Expr *Init, unsigned I) { - return visitInitializer(Init, [this, I, Init] { - return this->emitGetPtrLocal(I, Init); - }); - } - - /// Visits an initializer for a global. - bool visitGlobalInitializer(const Expr *Init, unsigned I) { - return visitInitializer(Init, [this, I, Init] { - return this->emitGetPtrGlobal(I, Init); - }); - } - - /// Visits a delegated initializer. - bool visitThisInitializer(const Expr *I) { - return visitInitializer(I, [this, I] { return this->emitThis(I); }); - } - - /// Creates a local primitive value. - unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsMutable, - bool IsExtended = false); - - /// Allocates a space storing a local given its type. - llvm::Optional<unsigned> allocateLocal(DeclTy &&Decl, - bool IsExtended = false); - -private: - friend class VariableScope<Emitter>; - friend class LocalScope<Emitter>; - friend class RecordScope<Emitter>; - friend class DeclScope<Emitter>; - friend class OptionScope<Emitter>; - - /// Emits a zero initializer. - bool visitZeroInitializer(PrimType T, const Expr *E); - - /// Fetches a member of a structure given by a pointer. - bool visitIndirectMember(const BinaryOperator *E); - - /// Emits a cast between two types. - bool emitConv(PrimType From, QualType FromTy, PrimType To, QualType ToTy, - const Expr *Cast); - - enum class DerefKind { - /// Value is read and pushed to stack. - Read, - /// Direct method generates a value which is written. Returns pointer. - Write, - /// Direct method receives the value, pushes mutated value. Returns pointer. - ReadWrite, - }; - - /// Method to directly load a value. If the value can be fetched directly, - /// the direct handler is called. Otherwise, a pointer is left on the stack - /// and the indirect handler is expected to operate on that. - bool dereference(const Expr *LV, DerefKind AK, - llvm::function_ref<bool(PrimType)> Direct, - llvm::function_ref<bool(PrimType)> Indirect); - bool dereferenceParam(const Expr *LV, PrimType T, const ParmVarDecl *PD, - DerefKind AK, - llvm::function_ref<bool(PrimType)> Direct, - llvm::function_ref<bool(PrimType)> Indirect); - bool dereferenceVar(const Expr *LV, PrimType T, const VarDecl *PD, - DerefKind AK, llvm::function_ref<bool(PrimType)> Direct, - llvm::function_ref<bool(PrimType)> Indirect); - - /// Emits an APInt constant. - bool emitConst(PrimType T, unsigned NumBits, const llvm::APInt &Value, - const Expr *E); - - /// Emits an integer constant. - template <typename T> bool emitConst(const Expr *E, T Value) { - QualType Ty = E->getType(); - unsigned NumBits = getIntWidth(Ty); - APInt WrappedValue(NumBits, Value, std::is_signed<T>::value); - return emitConst(*Ctx.classify(Ty), NumBits, WrappedValue, E); - } - - /// Visits a constant function invocation. - bool getPtrConstFn(const FunctionDecl *FD, const Expr *E); - /// Returns a pointer to a variable declaration. - bool getPtrVarDecl(const VarDecl *VD, const Expr *E); - - /// Returns the index of a global. - llvm::Optional<unsigned> getGlobalIdx(const VarDecl *VD); - - /// Emits the initialized pointer. - bool emitInitFn() { - assert(InitFn && "missing initializer"); - return (*InitFn)(); - } - -protected: - /// Variable to storage mapping. - llvm::DenseMap<const ValueDecl *, Scope::Local> Locals; - - /// OpaqueValueExpr to location mapping. - llvm::DenseMap<const OpaqueValueExpr *, unsigned> OpaqueExprs; - - /// Current scope. - VariableScope<Emitter> *VarScope = nullptr; - - /// Current argument index. - llvm::Optional<uint64_t> ArrayIndex; - - /// Flag indicating if return value is to be discarded. - bool DiscardResult = false; - - /// Expression being initialized. - llvm::Optional<InitFnRef> InitFn = {}; -}; - -extern template class ByteCodeExprGen<ByteCodeEmitter>; -extern template class ByteCodeExprGen<EvalEmitter>; - -/// Scope chain managing the variable lifetimes. -template <class Emitter> class VariableScope { -public: - virtual ~VariableScope() { Ctx->VarScope = this->Parent; } - - void add(const Scope::Local &Local, bool IsExtended) { - if (IsExtended) - this->addExtended(Local); - else - this->addLocal(Local); - } - - virtual void addLocal(const Scope::Local &Local) { - if (this->Parent) - this->Parent->addLocal(Local); - } - - virtual void addExtended(const Scope::Local &Local) { - if (this->Parent) - this->Parent->addExtended(Local); - } - - virtual void emitDestruction() {} - - VariableScope *getParent() { return Parent; } - -protected: - VariableScope(ByteCodeExprGen<Emitter> *Ctx) - : Ctx(Ctx), Parent(Ctx->VarScope) { - Ctx->VarScope = this; - } - - /// ByteCodeExprGen instance. - ByteCodeExprGen<Emitter> *Ctx; - /// Link to the parent scope. - VariableScope *Parent; -}; - -/// Scope for local variables. -/// -/// When the scope is destroyed, instructions are emitted to tear down -/// all variables declared in this scope. -template <class Emitter> class LocalScope : public VariableScope<Emitter> { -public: - LocalScope(ByteCodeExprGen<Emitter> *Ctx) : VariableScope<Emitter>(Ctx) {} - - ~LocalScope() override { this->emitDestruction(); } - - void addLocal(const Scope::Local &Local) override { - if (!Idx.hasValue()) { - Idx = this->Ctx->Descriptors.size(); - this->Ctx->Descriptors.emplace_back(); - } - - this->Ctx->Descriptors[*Idx].emplace_back(Local); - } - - void emitDestruction() override { - if (!Idx.hasValue()) - return; - this->Ctx->emitDestroy(*Idx, SourceInfo{}); - } - -protected: - /// Index of the scope in the chain. - Optional<unsigned> Idx; -}; - -/// Scope for storage declared in a compound statement. -template <class Emitter> class BlockScope final : public LocalScope<Emitter> { -public: - BlockScope(ByteCodeExprGen<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {} - - void addExtended(const Scope::Local &Local) override { - llvm_unreachable("Cannot create temporaries in full scopes"); - } -}; - -/// Expression scope which tracks potentially lifetime extended -/// temporaries which are hoisted to the parent scope on exit. -template <class Emitter> class ExprScope final : public LocalScope<Emitter> { -public: - ExprScope(ByteCodeExprGen<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {} - - void addExtended(const Scope::Local &Local) override { - this->Parent->addLocal(Local); - } -}; - -} // namespace interp -} // namespace clang - -#endif |