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 a type.
74 std::optional<PrimType> classify(QualType T) const;
75
76 /// Classifies an expression.
77 std::optional<PrimType> classify(const Expr *E) const {
78 if (E->isGLValue()) {
79 if (E->getType()->isFunctionType())
80 return PT_FnPtr;
81 return PT_Ptr;
82 }
83
84 return classify(T: E->getType());
85 }
86
87 const CXXMethodDecl *
88 getOverridingFunction(const CXXRecordDecl *DynamicDecl,
89 const CXXRecordDecl *StaticDecl,
90 const CXXMethodDecl *InitialFunction) const;
91
92 const Function *getOrCreateFunction(const FunctionDecl *FD);
93
94 /// Returns whether we should create a global variable for the
95 /// given ValueDecl.
96 static bool shouldBeGloballyIndexed(const ValueDecl *VD) {
97 if (const auto *V = dyn_cast<VarDecl>(Val: VD))
98 return V->hasGlobalStorage() || V->isConstexpr();
99
100 return false;
101 }
102
103 /// Returns the program. This is only needed for unittests.
104 Program &getProgram() const { return *P.get(); }
105
106private:
107 /// Runs a function.
108 bool Run(State &Parent, const Function *Func, APValue &Result);
109
110 /// Checks a result from the interpreter.
111 bool Check(State &Parent, llvm::Expected<bool> &&R);
112
113 /// Current compilation context.
114 ASTContext &Ctx;
115 /// Interpreter stack, shared across invocations.
116 InterpStack Stk;
117 /// Constexpr program.
118 std::unique_ptr<Program> P;
119};
120
121} // namespace interp
122} // namespace clang
123
124#endif
125

source code of clang/lib/AST/Interp/Context.h