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;
27class BlockExpr;
28
29namespace interp {
30class Function;
31class Program;
32class State;
33enum PrimType : unsigned;
34
35struct ParamOffset {
36 unsigned Offset;
37 bool IsPtr;
38};
39
40/// Holds all information required to evaluate constexpr code in a module.
41class Context final {
42public:
43 /// Initialises the constexpr VM.
44 Context(ASTContext &Ctx);
45
46 /// Cleans up the constexpr VM.
47 ~Context();
48
49 /// Checks if a function is a potential constant expression.
50 bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FnDecl);
51
52 /// Evaluates a toplevel expression as an rvalue.
53 bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result);
54
55 /// Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
56 bool evaluate(State &Parent, const Expr *E, APValue &Result,
57 ConstantExprKind Kind);
58
59 /// Evaluates a toplevel initializer.
60 bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result);
61
62 bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
63 const Expr *PtrExpr, APValue &Result);
64 bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
65 const Expr *PtrExpr, std::string &Result);
66
67 /// Returns the AST context.
68 ASTContext &getASTContext() const { return Ctx; }
69 /// Returns the language options.
70 const LangOptions &getLangOpts() const;
71 /// Returns CHAR_BIT.
72 unsigned getCharBit() const;
73 /// Return the floating-point semantics for T.
74 const llvm::fltSemantics &getFloatSemantics(QualType T) const;
75 /// Return the size of T in bits.
76 uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
77
78 /// Classifies a type.
79 std::optional<PrimType> classify(QualType T) const;
80
81 /// Classifies an expression.
82 std::optional<PrimType> classify(const Expr *E) const {
83 assert(E);
84 if (E->isGLValue())
85 return PT_Ptr;
86
87 return classify(T: E->getType());
88 }
89
90 const CXXMethodDecl *
91 getOverridingFunction(const CXXRecordDecl *DynamicDecl,
92 const CXXRecordDecl *StaticDecl,
93 const CXXMethodDecl *InitialFunction) const;
94
95 const Function *getOrCreateFunction(const FunctionDecl *FuncDecl);
96 const Function *getOrCreateObjCBlock(const BlockExpr *E);
97
98 /// Returns whether we should create a global variable for the
99 /// given ValueDecl.
100 static bool shouldBeGloballyIndexed(const ValueDecl *VD) {
101 if (const auto *V = dyn_cast<VarDecl>(Val: VD))
102 return V->hasGlobalStorage() || V->isConstexpr();
103
104 return false;
105 }
106
107 /// Returns the program. This is only needed for unittests.
108 Program &getProgram() const { return *P; }
109
110 unsigned collectBaseOffset(const RecordDecl *BaseDecl,
111 const RecordDecl *DerivedDecl) const;
112
113 const Record *getRecord(const RecordDecl *D) const;
114
115 unsigned getEvalID() const { return EvalID; }
116
117 /// Unevaluated builtins don't get their arguments put on the stack
118 /// automatically. They instead operate on the AST of their Call
119 /// Expression.
120 /// Similar information is available via ASTContext::BuiltinInfo,
121 /// but that is not correct for our use cases.
122 static bool isUnevaluatedBuiltin(unsigned ID);
123
124private:
125 /// Runs a function.
126 bool Run(State &Parent, const Function *Func);
127
128 template <typename ResultT>
129 bool evaluateStringRepr(State &Parent, const Expr *SizeExpr,
130 const Expr *PtrExpr, ResultT &Result);
131
132 /// Current compilation context.
133 ASTContext &Ctx;
134 /// Interpreter stack, shared across invocations.
135 InterpStack Stk;
136 /// Constexpr program.
137 std::unique_ptr<Program> P;
138 /// ID identifying an evaluation.
139 unsigned EvalID = 0;
140 /// Cached widths (in bits) of common types, for a faster classify().
141 unsigned ShortWidth;
142 unsigned IntWidth;
143 unsigned LongWidth;
144 unsigned LongLongWidth;
145};
146
147} // namespace interp
148} // namespace clang
149
150#endif
151