Path: blob/main/contrib/llvm-project/clang/lib/AST/Interp/Context.h
35292 views
//===--- Context.h - Context for the constexpr 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 constexpr execution context.9//10// The execution context manages cached bytecode and the global context.11// It invokes the compiler and interpreter, propagating errors.12//13//===----------------------------------------------------------------------===//1415#ifndef LLVM_CLANG_AST_INTERP_CONTEXT_H16#define LLVM_CLANG_AST_INTERP_CONTEXT_H1718#include "InterpStack.h"1920namespace clang {21class ASTContext;22class LangOptions;23class FunctionDecl;24class VarDecl;25class APValue;2627namespace interp {28class Function;29class Program;30class State;31enum PrimType : unsigned;3233struct ParamOffset {34unsigned Offset;35bool IsPtr;36};3738/// Holds all information required to evaluate constexpr code in a module.39class Context final {40public:41/// Initialises the constexpr VM.42Context(ASTContext &Ctx);4344/// Cleans up the constexpr VM.45~Context();4647/// Checks if a function is a potential constant expression.48bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FnDecl);4950/// Evaluates a toplevel expression as an rvalue.51bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result);5253/// Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.54bool evaluate(State &Parent, const Expr *E, APValue &Result);5556/// Evaluates a toplevel initializer.57bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result);5859/// Returns the AST context.60ASTContext &getASTContext() const { return Ctx; }61/// Returns the language options.62const LangOptions &getLangOpts() const;63/// Returns the interpreter stack.64InterpStack &getStack() { return Stk; }65/// Returns CHAR_BIT.66unsigned getCharBit() const;67/// Return the floating-point semantics for T.68const llvm::fltSemantics &getFloatSemantics(QualType T) const;69/// Return the size of T in bits.70uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }7172/// Classifies a type.73std::optional<PrimType> classify(QualType T) const;7475/// Classifies an expression.76std::optional<PrimType> classify(const Expr *E) const {77assert(E);78if (E->isGLValue()) {79if (E->getType()->isFunctionType())80return PT_FnPtr;81return PT_Ptr;82}8384return classify(E->getType());85}8687const CXXMethodDecl *88getOverridingFunction(const CXXRecordDecl *DynamicDecl,89const CXXRecordDecl *StaticDecl,90const CXXMethodDecl *InitialFunction) const;9192const Function *getOrCreateFunction(const FunctionDecl *FD);9394/// Returns whether we should create a global variable for the95/// given ValueDecl.96static bool shouldBeGloballyIndexed(const ValueDecl *VD) {97if (const auto *V = dyn_cast<VarDecl>(VD))98return V->hasGlobalStorage() || V->isConstexpr();99100return false;101}102103/// Returns the program. This is only needed for unittests.104Program &getProgram() const { return *P.get(); }105106unsigned collectBaseOffset(const RecordDecl *BaseDecl,107const RecordDecl *DerivedDecl) const;108109const Record *getRecord(const RecordDecl *D) const;110111unsigned getEvalID() const { return EvalID; }112113private:114/// Runs a function.115bool Run(State &Parent, const Function *Func, APValue &Result);116117/// Current compilation context.118ASTContext &Ctx;119/// Interpreter stack, shared across invocations.120InterpStack Stk;121/// Constexpr program.122std::unique_ptr<Program> P;123/// ID identifying an evaluation.124unsigned EvalID = 0;125};126127} // namespace interp128} // namespace clang129130#endif131132133