1a07aba5dSTimm Baeder //===--- Context.h - Context for the constexpr VM ---------------*- C++ -*-===// 2a07aba5dSTimm Baeder // 3a07aba5dSTimm Baeder // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a07aba5dSTimm Baeder // See https://llvm.org/LICENSE.txt for license information. 5a07aba5dSTimm Baeder // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a07aba5dSTimm Baeder // 7a07aba5dSTimm Baeder //===----------------------------------------------------------------------===// 8a07aba5dSTimm Baeder // 9a07aba5dSTimm Baeder // Defines the constexpr execution context. 10a07aba5dSTimm Baeder // 11a07aba5dSTimm Baeder // The execution context manages cached bytecode and the global context. 12a07aba5dSTimm Baeder // It invokes the compiler and interpreter, propagating errors. 13a07aba5dSTimm Baeder // 14a07aba5dSTimm Baeder //===----------------------------------------------------------------------===// 15a07aba5dSTimm Baeder 16a07aba5dSTimm Baeder #ifndef LLVM_CLANG_AST_INTERP_CONTEXT_H 17a07aba5dSTimm Baeder #define LLVM_CLANG_AST_INTERP_CONTEXT_H 18a07aba5dSTimm Baeder 19a07aba5dSTimm Baeder #include "InterpStack.h" 20a07aba5dSTimm Baeder 21a07aba5dSTimm Baeder namespace clang { 22a07aba5dSTimm Baeder class ASTContext; 23a07aba5dSTimm Baeder class LangOptions; 24a07aba5dSTimm Baeder class FunctionDecl; 25a07aba5dSTimm Baeder class VarDecl; 26a07aba5dSTimm Baeder class APValue; 27a07aba5dSTimm Baeder 28a07aba5dSTimm Baeder namespace interp { 29a07aba5dSTimm Baeder class Function; 30a07aba5dSTimm Baeder class Program; 31a07aba5dSTimm Baeder class State; 32a07aba5dSTimm Baeder enum PrimType : unsigned; 33a07aba5dSTimm Baeder 34a07aba5dSTimm Baeder struct ParamOffset { 35a07aba5dSTimm Baeder unsigned Offset; 36a07aba5dSTimm Baeder bool IsPtr; 37a07aba5dSTimm Baeder }; 38a07aba5dSTimm Baeder 39a07aba5dSTimm Baeder /// Holds all information required to evaluate constexpr code in a module. 40a07aba5dSTimm Baeder class Context final { 41a07aba5dSTimm Baeder public: 42a07aba5dSTimm Baeder /// Initialises the constexpr VM. 43a07aba5dSTimm Baeder Context(ASTContext &Ctx); 44a07aba5dSTimm Baeder 45a07aba5dSTimm Baeder /// Cleans up the constexpr VM. 46a07aba5dSTimm Baeder ~Context(); 47a07aba5dSTimm Baeder 48a07aba5dSTimm Baeder /// Checks if a function is a potential constant expression. 49a07aba5dSTimm Baeder bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FnDecl); 50a07aba5dSTimm Baeder 51a07aba5dSTimm Baeder /// Evaluates a toplevel expression as an rvalue. 52a07aba5dSTimm Baeder bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result); 53a07aba5dSTimm Baeder 54a07aba5dSTimm Baeder /// Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion. 5583fea8b8STimm Baeder bool evaluate(State &Parent, const Expr *E, APValue &Result, 5683fea8b8STimm Baeder ConstantExprKind Kind); 57a07aba5dSTimm Baeder 58a07aba5dSTimm Baeder /// Evaluates a toplevel initializer. 59a07aba5dSTimm Baeder bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result); 60a07aba5dSTimm Baeder 61a07aba5dSTimm Baeder /// Returns the AST context. 62a07aba5dSTimm Baeder ASTContext &getASTContext() const { return Ctx; } 63a07aba5dSTimm Baeder /// Returns the language options. 64a07aba5dSTimm Baeder const LangOptions &getLangOpts() const; 65a07aba5dSTimm Baeder /// Returns the interpreter stack. 66a07aba5dSTimm Baeder InterpStack &getStack() { return Stk; } 67a07aba5dSTimm Baeder /// Returns CHAR_BIT. 68a07aba5dSTimm Baeder unsigned getCharBit() const; 69a07aba5dSTimm Baeder /// Return the floating-point semantics for T. 70a07aba5dSTimm Baeder const llvm::fltSemantics &getFloatSemantics(QualType T) const; 71a07aba5dSTimm Baeder /// Return the size of T in bits. 72a07aba5dSTimm Baeder uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); } 73a07aba5dSTimm Baeder 74a07aba5dSTimm Baeder /// Classifies a type. 75a07aba5dSTimm Baeder std::optional<PrimType> classify(QualType T) const; 76a07aba5dSTimm Baeder 77a07aba5dSTimm Baeder /// Classifies an expression. 78a07aba5dSTimm Baeder std::optional<PrimType> classify(const Expr *E) const { 79a07aba5dSTimm Baeder assert(E); 80a07aba5dSTimm Baeder if (E->isGLValue()) { 81a07aba5dSTimm Baeder if (E->getType()->isFunctionType()) 82a07aba5dSTimm Baeder return PT_FnPtr; 83a07aba5dSTimm Baeder return PT_Ptr; 84a07aba5dSTimm Baeder } 85a07aba5dSTimm Baeder 86a07aba5dSTimm Baeder return classify(E->getType()); 87a07aba5dSTimm Baeder } 88a07aba5dSTimm Baeder 89a07aba5dSTimm Baeder const CXXMethodDecl * 90a07aba5dSTimm Baeder getOverridingFunction(const CXXRecordDecl *DynamicDecl, 91a07aba5dSTimm Baeder const CXXRecordDecl *StaticDecl, 92a07aba5dSTimm Baeder const CXXMethodDecl *InitialFunction) const; 93a07aba5dSTimm Baeder 94a07aba5dSTimm Baeder const Function *getOrCreateFunction(const FunctionDecl *FD); 95a07aba5dSTimm Baeder 96a07aba5dSTimm Baeder /// Returns whether we should create a global variable for the 97a07aba5dSTimm Baeder /// given ValueDecl. 98a07aba5dSTimm Baeder static bool shouldBeGloballyIndexed(const ValueDecl *VD) { 99a07aba5dSTimm Baeder if (const auto *V = dyn_cast<VarDecl>(VD)) 100a07aba5dSTimm Baeder return V->hasGlobalStorage() || V->isConstexpr(); 101a07aba5dSTimm Baeder 102a07aba5dSTimm Baeder return false; 103a07aba5dSTimm Baeder } 104a07aba5dSTimm Baeder 105a07aba5dSTimm Baeder /// Returns the program. This is only needed for unittests. 106a07aba5dSTimm Baeder Program &getProgram() const { return *P.get(); } 107a07aba5dSTimm Baeder 108a07aba5dSTimm Baeder unsigned collectBaseOffset(const RecordDecl *BaseDecl, 109a07aba5dSTimm Baeder const RecordDecl *DerivedDecl) const; 110a07aba5dSTimm Baeder 111a07aba5dSTimm Baeder const Record *getRecord(const RecordDecl *D) const; 112a07aba5dSTimm Baeder 113a07aba5dSTimm Baeder unsigned getEvalID() const { return EvalID; } 114a07aba5dSTimm Baeder 115a07aba5dSTimm Baeder private: 116a07aba5dSTimm Baeder /// Runs a function. 117*82ed9c03STimm Baeder bool Run(State &Parent, const Function *Func); 118a07aba5dSTimm Baeder 119a07aba5dSTimm Baeder /// Current compilation context. 120a07aba5dSTimm Baeder ASTContext &Ctx; 121a07aba5dSTimm Baeder /// Interpreter stack, shared across invocations. 122a07aba5dSTimm Baeder InterpStack Stk; 123a07aba5dSTimm Baeder /// Constexpr program. 124a07aba5dSTimm Baeder std::unique_ptr<Program> P; 125a07aba5dSTimm Baeder /// ID identifying an evaluation. 126a07aba5dSTimm Baeder unsigned EvalID = 0; 127a07aba5dSTimm Baeder }; 128a07aba5dSTimm Baeder 129a07aba5dSTimm Baeder } // namespace interp 130a07aba5dSTimm Baeder } // namespace clang 131a07aba5dSTimm Baeder 132a07aba5dSTimm Baeder #endif 133