1*a7dea167SDimitry Andric //===--- Context.h - Context for the constexpr VM ---------------*- C++ -*-===// 2*a7dea167SDimitry Andric // 3*a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*a7dea167SDimitry Andric // 7*a7dea167SDimitry Andric //===----------------------------------------------------------------------===// 8*a7dea167SDimitry Andric // 9*a7dea167SDimitry Andric // Defines the constexpr execution context. 10*a7dea167SDimitry Andric // 11*a7dea167SDimitry Andric // The execution context manages cached bytecode and the global context. 12*a7dea167SDimitry Andric // It invokes the compiler and interpreter, propagating errors. 13*a7dea167SDimitry Andric // 14*a7dea167SDimitry Andric //===----------------------------------------------------------------------===// 15*a7dea167SDimitry Andric 16*a7dea167SDimitry Andric #ifndef LLVM_CLANG_AST_INTERP_CONTEXT_H 17*a7dea167SDimitry Andric #define LLVM_CLANG_AST_INTERP_CONTEXT_H 18*a7dea167SDimitry Andric 19*a7dea167SDimitry Andric #include "Context.h" 20*a7dea167SDimitry Andric #include "InterpStack.h" 21*a7dea167SDimitry Andric #include "clang/AST/APValue.h" 22*a7dea167SDimitry Andric #include "llvm/ADT/PointerIntPair.h" 23*a7dea167SDimitry Andric 24*a7dea167SDimitry Andric namespace clang { 25*a7dea167SDimitry Andric class ASTContext; 26*a7dea167SDimitry Andric class LangOptions; 27*a7dea167SDimitry Andric class Stmt; 28*a7dea167SDimitry Andric class FunctionDecl; 29*a7dea167SDimitry Andric class VarDecl; 30*a7dea167SDimitry Andric 31*a7dea167SDimitry Andric namespace interp { 32*a7dea167SDimitry Andric class Function; 33*a7dea167SDimitry Andric class Program; 34*a7dea167SDimitry Andric class State; 35*a7dea167SDimitry Andric enum PrimType : unsigned; 36*a7dea167SDimitry Andric 37*a7dea167SDimitry Andric /// Wrapper around interpreter termination results. 38*a7dea167SDimitry Andric enum class InterpResult { 39*a7dea167SDimitry Andric /// Interpreter successfully computed a value. 40*a7dea167SDimitry Andric Success, 41*a7dea167SDimitry Andric /// Interpreter encountered an error and quit. 42*a7dea167SDimitry Andric Fail, 43*a7dea167SDimitry Andric /// Interpreter encountered an unimplemented feature, AST fallback. 44*a7dea167SDimitry Andric Bail, 45*a7dea167SDimitry Andric }; 46*a7dea167SDimitry Andric 47*a7dea167SDimitry Andric /// Holds all information required to evaluate constexpr code in a module. 48*a7dea167SDimitry Andric class Context { 49*a7dea167SDimitry Andric public: 50*a7dea167SDimitry Andric /// Initialises the constexpr VM. 51*a7dea167SDimitry Andric Context(ASTContext &Ctx); 52*a7dea167SDimitry Andric 53*a7dea167SDimitry Andric /// Cleans up the constexpr VM. 54*a7dea167SDimitry Andric ~Context(); 55*a7dea167SDimitry Andric 56*a7dea167SDimitry Andric /// Checks if a function is a potential constant expression. 57*a7dea167SDimitry Andric InterpResult isPotentialConstantExpr(State &Parent, 58*a7dea167SDimitry Andric const FunctionDecl *FnDecl); 59*a7dea167SDimitry Andric 60*a7dea167SDimitry Andric /// Evaluates a toplevel expression as an rvalue. 61*a7dea167SDimitry Andric InterpResult evaluateAsRValue(State &Parent, const Expr *E, APValue &Result); 62*a7dea167SDimitry Andric 63*a7dea167SDimitry Andric /// Evaluates a toplevel initializer. 64*a7dea167SDimitry Andric InterpResult evaluateAsInitializer(State &Parent, const VarDecl *VD, 65*a7dea167SDimitry Andric APValue &Result); 66*a7dea167SDimitry Andric 67*a7dea167SDimitry Andric /// Returns the AST context. 68*a7dea167SDimitry Andric ASTContext &getASTContext() const { return Ctx; } 69*a7dea167SDimitry Andric /// Returns the language options. 70*a7dea167SDimitry Andric const LangOptions &getLangOpts() const; 71*a7dea167SDimitry Andric /// Returns the interpreter stack. 72*a7dea167SDimitry Andric InterpStack &getStack() { return Stk; } 73*a7dea167SDimitry Andric /// Returns CHAR_BIT. 74*a7dea167SDimitry Andric unsigned getCharBit() const; 75*a7dea167SDimitry Andric 76*a7dea167SDimitry Andric /// Classifies an expression. 77*a7dea167SDimitry Andric llvm::Optional<PrimType> classify(QualType T); 78*a7dea167SDimitry Andric 79*a7dea167SDimitry Andric private: 80*a7dea167SDimitry Andric /// Runs a function. 81*a7dea167SDimitry Andric InterpResult Run(State &Parent, Function *Func, APValue &Result); 82*a7dea167SDimitry Andric 83*a7dea167SDimitry Andric /// Checks a result fromt the interpreter. 84*a7dea167SDimitry Andric InterpResult Check(State &Parent, llvm::Expected<bool> &&R); 85*a7dea167SDimitry Andric 86*a7dea167SDimitry Andric private: 87*a7dea167SDimitry Andric /// Current compilation context. 88*a7dea167SDimitry Andric ASTContext &Ctx; 89*a7dea167SDimitry Andric /// Flag to indicate if the use of the interpreter is mandatory. 90*a7dea167SDimitry Andric bool ForceInterp; 91*a7dea167SDimitry Andric /// Interpreter stack, shared across invocations. 92*a7dea167SDimitry Andric InterpStack Stk; 93*a7dea167SDimitry Andric /// Constexpr program. 94*a7dea167SDimitry Andric std::unique_ptr<Program> P; 95*a7dea167SDimitry Andric }; 96*a7dea167SDimitry Andric 97*a7dea167SDimitry Andric } // namespace interp 98*a7dea167SDimitry Andric } // namespace clang 99*a7dea167SDimitry Andric 100*a7dea167SDimitry Andric #endif 101