clang 24.0.0git
Context.h
Go to the documentation of this file.
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"
21
22namespace clang {
23class LangOptions;
24class FunctionDecl;
25class VarDecl;
26class APValue;
27class BlockExpr;
28
29namespace interp {
30class Function;
31class Program;
32class State;
33enum PrimType : uint8_t;
34
36 unsigned Offset;
37 bool IsPtr;
38};
39
40struct FuncParam {
41 unsigned Index;
42 bool IsPtr;
43};
44
45class EvalIDScope;
46/// Holds all information required to evaluate constexpr code in a module.
47class Context final {
48public:
49 /// Initialises the constexpr VM.
50 explicit Context(ASTContext &Ctx);
51
52 /// Cleans up the constexpr VM.
54
55 /// Checks if a function is a potential constant expression.
56 bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FD);
57 void isPotentialConstantExprUnevaluated(State &Parent, const Expr *E,
58 const FunctionDecl *FD);
59
60 /// Evaluates a toplevel expression as an rvalue.
61 bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result);
62
63 /// Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
64 bool evaluate(State &Parent, const Expr *E, APValue &Result,
65 ConstantExprKind Kind);
66
67 /// Evaluates a toplevel initializer.
68 bool evaluateAsInitializer(State &Parent, const VarDecl *VD, const Expr *Init,
70
71 /// Evaluates the destruction of a variable.
72 bool evaluateDestruction(State &Parent, const VarDecl *VD, APValue Value);
73
74 bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
75 const Expr *PtrExpr, APValue &Result);
76 bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
77 const Expr *PtrExpr, std::string &Result);
78
79 /// Evaluate \param E and if it can be evaluated to a null-terminated string,
80 /// copy the result into \param Result.
81 bool evaluateString(State &Parent, const Expr *E, std::string &Result);
82
83 /// Evalute \param E and if it can be evaluated to a string literal,
84 /// run strlen() on it.
85 std::optional<uint64_t> evaluateStrlen(State &Parent, const Expr *E);
86
87 /// If \param E evaluates to a pointer the number of accessible bytes
88 /// past the pointer is estimated in \param Result as if evaluated by
89 /// the builtin function __builtin_object_size. This is a best effort
90 /// approximation, when Kind & 2 == 0 the object size is less
91 /// than or equal to the estimated size, when Kind & 2 == 1 the
92 /// true value is greater than or equal to the estimated size.
93 /// When Kind & 1 == 1 only bytes belonging to the same subobject
94 /// as the one referred to by E are considered, when Kind & 1 == 0
95 /// bytes belonging to the same storage (stack, heap allocation,
96 /// global variable) are considered.
97 std::optional<uint64_t> tryEvaluateObjectSize(State &Parent, const Expr *E,
98 unsigned Kind, bool IsDynamic);
99
100 std::optional<bool> evaluateWithSubstitution(State &Parent,
101 const FunctionDecl *Callee,
103 const Expr *This,
104 const Expr *Condition);
105
106 /// Returns the AST context.
107 ASTContext &getASTContext() const { return Ctx; }
108 /// Returns the language options.
109 const LangOptions &getLangOpts() const;
110 /// Returns CHAR_BIT.
111 unsigned getCharBit() const;
112 /// Return the floating-point semantics for T.
113 const llvm::fltSemantics &getFloatSemantics(QualType T) const;
114 /// Return the size of T in bits.
115 uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
116
117 /// Classifies a type.
119
120 /// Classifies an expression.
121 OptPrimType classify(const Expr *E) const {
122 assert(E);
123 if (E->isGLValue())
124 return PT_Ptr;
125
126 return classify(E->getType());
127 }
128
129 bool canClassify(QualType T) const {
130 T = T.getCanonicalType();
131 if (const auto *BT = dyn_cast<BuiltinType>(T)) {
132 if (BT->isInteger() || BT->isFloatingPoint())
133 return true;
134 if (BT->getKind() == BuiltinType::NullPtr ||
135 BT->getKind() == BuiltinType::BoundMember)
136 return true;
137 }
138 if (T->isPointerOrReferenceType())
139 return true;
140
141 if (T->isArrayType() || T->isRecordType() || T->isAnyComplexType() ||
142 T->isVectorType())
143 return false;
144
145 if (T->isEnumeralType())
146 return true;
147
148 return classify(T) != std::nullopt;
149 }
150 bool canClassify(const Expr *E) const {
151 if (E->isGLValue())
152 return true;
153 return canClassify(E->getType());
154 }
155
156 const CXXMethodDecl *
157 getOverridingFunction(const CXXRecordDecl *DynamicDecl,
158 const CXXRecordDecl *StaticDecl,
159 const CXXMethodDecl *InitialFunction) const;
160
161 const Function *getOrCreateFunction(const FunctionDecl *FuncDecl);
162 const Function *getOrCreateObjCBlock(const BlockExpr *E);
163
164 /// Returns whether we should create a global variable for the
165 /// given ValueDecl.
166 static bool shouldBeGloballyIndexed(const ValueDecl *VD) {
167 if (const auto *V = dyn_cast<VarDecl>(VD))
168 return V->hasGlobalStorage() || V->isConstexpr();
169
170 return false;
171 }
172
173 /// Returns the program. This is only needed for unittests.
174 Program &getProgram() const { return *P; }
175
176 unsigned collectBaseOffset(const RecordDecl *BaseDecl,
177 const RecordDecl *DerivedDecl) const;
178
179 const Record *getRecord(const RecordDecl *D) const;
180
181 unsigned getEvalID() const { return EvalID; }
182
183 /// Unevaluated builtins don't get their arguments put on the stack
184 /// automatically. They instead operate on the AST of their Call
185 /// Expression.
186 /// Similar information is available via ASTContext::BuiltinInfo,
187 /// but that is not correct for our use cases.
188 static bool isUnevaluatedBuiltin(unsigned ID);
189
190private:
191 friend class EvalIDScope;
192 /// Runs a function.
193 bool Run(State &Parent, const Function *Func);
194
195 template <typename ResultT>
196 bool evaluateStringRepr(State &Parent, const Expr *SizeExpr,
197 const Expr *PtrExpr, ResultT &Result);
198
199 /// Current compilation context.
200 ASTContext &Ctx;
201 /// Interpreter stack, shared across invocations.
202 InterpStack Stk;
203 /// Constexpr program.
204 std::unique_ptr<Program> P;
205 /// ID identifying an evaluation.
206 unsigned EvalID = 0;
207 /// Cached widths (in bits) of common types, for a faster classify().
208 unsigned ShortWidth;
209 unsigned IntWidth;
210 unsigned LongWidth;
211 unsigned LongLongWidth;
212};
213
215public:
216 EvalIDScope(Context &Ctx) : Ctx(Ctx), OldID(Ctx.EvalID) { ++Ctx.EvalID; }
217 ~EvalIDScope() { Ctx.EvalID = OldID; }
218 EvalIDScope(const EvalIDScope &) = delete;
220
221private:
222 Context &Ctx;
223 const unsigned OldID;
224};
225
226} // namespace interp
227} // namespace clang
228
229#endif
Defines the clang::ASTContext interface.
#define V(N, I)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6722
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2149
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
This represents one expression.
Definition Expr.h:113
bool isGLValue() const
Definition Expr.h:288
QualType getType() const
Definition Expr.h:145
Represents a function declaration or definition.
Definition Decl.h:2059
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A (possibly-)qualified type.
Definition TypeBase.h:938
Represents a struct/union/class.
Definition Decl.h:4460
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
Represents a variable declaration or definition.
Definition Decl.h:933
Holds all information required to evaluate constexpr code in a module.
Definition Context.h:47
const LangOptions & getLangOpts() const
Returns the language options.
Definition Context.cpp:472
OptPrimType classify(const Expr *E) const
Classifies an expression.
Definition Context.h:121
const Function * getOrCreateObjCBlock(const BlockExpr *E)
Definition Context.cpp:748
~Context()
Cleans up the constexpr VM.
Context(ASTContext &Ctx)
Initialises the constexpr VM.
Definition Context.cpp:29
bool evaluateCharRange(State &Parent, const Expr *SizeExpr, const Expr *PtrExpr, APValue &Result)
Definition Context.cpp:266
std::optional< uint64_t > evaluateStrlen(State &Parent, const Expr *E)
Evalute.
Definition Context.cpp:347
std::optional< bool > evaluateWithSubstitution(State &Parent, const FunctionDecl *Callee, ArrayRef< const Expr * > Args, const Expr *This, const Expr *Condition)
Definition Context.cpp:446
friend class EvalIDScope
Definition Context.h:191
bool evaluateString(State &Parent, const Expr *E, std::string &Result)
Evaluate.
Definition Context.cpp:282
static bool isUnevaluatedBuiltin(unsigned ID)
Unevaluated builtins don't get their arguments put on the stack automatically.
Definition Context.cpp:821
unsigned getCharBit() const
Returns CHAR_BIT.
Definition Context.cpp:586
bool canClassify(const Expr *E) const
Definition Context.h:150
Program & getProgram() const
Returns the program. This is only needed for unittests.
Definition Context.h:174
const llvm::fltSemantics & getFloatSemantics(QualType T) const
Return the floating-point semantics for T.
Definition Context.cpp:592
static bool shouldBeGloballyIndexed(const ValueDecl *VD)
Returns whether we should create a global variable for the given ValueDecl.
Definition Context.h:166
std::optional< uint64_t > tryEvaluateObjectSize(State &Parent, const Expr *E, unsigned Kind, bool IsDynamic)
If.
Definition Context.cpp:413
void isPotentialConstantExprUnevaluated(State &Parent, const Expr *E, const FunctionDecl *FD)
Definition Context.cpp:60
unsigned collectBaseOffset(const RecordDecl *BaseDecl, const RecordDecl *DerivedDecl) const
Definition Context.cpp:786
bool evaluateDestruction(State &Parent, const VarDecl *VD, APValue Value)
Evaluates the destruction of a variable.
Definition Context.cpp:164
const Record * getRecord(const RecordDecl *D) const
Definition Context.cpp:817
bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FD)
Checks if a function is a potential constant expression.
Definition Context.cpp:40
const Function * getOrCreateFunction(const FunctionDecl *FuncDecl)
Definition Context.cpp:651
ASTContext & getASTContext() const
Returns the AST context.
Definition Context.h:107
uint32_t getBitWidth(QualType T) const
Return the size of T in bits.
Definition Context.h:115
OptPrimType classify(QualType T) const
Classifies a type.
Definition Context.cpp:506
bool canClassify(QualType T) const
Definition Context.h:129
bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result)
Evaluates a toplevel expression as an rvalue.
Definition Context.cpp:73
const CXXMethodDecl * getOverridingFunction(const CXXRecordDecl *DynamicDecl, const CXXRecordDecl *StaticDecl, const CXXMethodDecl *InitialFunction) const
Definition Context.cpp:615
bool evaluate(State &Parent, const Expr *E, APValue &Result, ConstantExprKind Kind)
Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
Definition Context.cpp:103
bool evaluateAsInitializer(State &Parent, const VarDecl *VD, const Expr *Init, APValue &Result)
Evaluates a toplevel initializer.
Definition Context.cpp:132
unsigned getEvalID() const
Definition Context.h:181
EvalIDScope & operator=(const EvalIDScope &)=delete
EvalIDScope(const EvalIDScope &)=delete
EvalIDScope(Context &Ctx)
Definition Context.h:216
Bytecode function.
Definition Function.h:98
Stack frame storing temporaries and parameters.
Definition InterpStack.h:25
The program contains and links the bytecode for all functions.
Definition Program.h:37
Structure/Class descriptor.
Definition Record.h:26
Interface for the VM to interact with the AST walker's context.
Definition State.h:79
bool This(InterpState &S, CodePtr OpPC)
Definition Interp.h:3232
PrimType
Enumeration of the primitive types of the VM.
Definition PrimType.h:34
bool Init(InterpState &S, CodePtr OpPC)
Definition Interp.h:2413
Top level wrappers for InstallAPI frontend operations.
Expr::ConstantExprKind ConstantExprKind
Definition Expr.h:1062
@ Result
The result type of a method or function.
Definition TypeBase.h:906
const FunctionProtoType * T
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t