1//===--- Context.h - Context for the constexpr 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 constexpr execution context. 10// 11// The execution context manages cached bytecode and the global context. 12// It invokes the compiler and interpreter, propagating errors. 13// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_CLANG_AST_INTERP_CONTEXT_H 17#define LLVM_CLANG_AST_INTERP_CONTEXT_H 18 19#include "InterpStack.h" 20 21namespace clang { 22class ASTContext; 23class LangOptions; 24class FunctionDecl; 25class VarDecl; 26class APValue; 27 28namespace interp { 29class Function; 30class Program; 31class State; 32enum PrimType : unsigned; 33 34struct ParamOffset { 35 unsigned Offset; 36 bool IsPtr; 37}; 38 39/// Holds all information required to evaluate constexpr code in a module. 40class Context final { 41public: 42 /// Initialises the constexpr VM. 43 Context(ASTContext &Ctx); 44 45 /// Cleans up the constexpr VM. 46 ~Context(); 47 48 /// Checks if a function is a potential constant expression. 49 bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FnDecl); 50 51 /// Evaluates a toplevel expression as an rvalue. 52 bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result); 53 54 /// Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion. 55 bool evaluate(State &Parent, const Expr *E, APValue &Result); 56 57 /// Evaluates a toplevel initializer. 58 bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result); 59 60 /// Returns the AST context. 61 ASTContext &getASTContext() const { return Ctx; } 62 /// Returns the language options. 63 const LangOptions &getLangOpts() const; 64 /// Returns the interpreter stack. 65 InterpStack &getStack() { return Stk; } 66 /// Returns CHAR_BIT. 67 unsigned getCharBit() const; 68 /// Return the floating-point semantics for T. 69 const llvm::fltSemantics &getFloatSemantics(QualType T) const; 70 /// Return the size of T in bits. 71 uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); } 72 73 /// Classifies an expression. 74 std::optional<PrimType> classify(QualType T) const; 75 76 const CXXMethodDecl * 77 getOverridingFunction(const CXXRecordDecl *DynamicDecl, 78 const CXXRecordDecl *StaticDecl, 79 const CXXMethodDecl *InitialFunction) const; 80 81 const Function *getOrCreateFunction(const FunctionDecl *FD); 82 83 /// Returns whether we should create a global variable for the 84 /// given ValueDecl. 85 static bool shouldBeGloballyIndexed(const ValueDecl *VD) { 86 if (const auto *V = dyn_cast<VarDecl>(VD)) 87 return V->hasGlobalStorage() || V->isConstexpr(); 88 89 return false; 90 } 91 92 /// Returns the program. This is only needed for unittests. 93 Program &getProgram() const { return *P.get(); } 94 95private: 96 /// Runs a function. 97 bool Run(State &Parent, const Function *Func, APValue &Result); 98 99 /// Checks a result from the interpreter. 100 bool Check(State &Parent, llvm::Expected<bool> &&R); 101 102 /// Current compilation context. 103 ASTContext &Ctx; 104 /// Interpreter stack, shared across invocations. 105 InterpStack Stk; 106 /// Constexpr program. 107 std::unique_ptr<Program> P; 108}; 109 110} // namespace interp 111} // namespace clang 112 113#endif 114