clang 23.0.0git
Function.h
Go to the documentation of this file.
1//===--- Function.h - Bytecode function for the 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 Function class which holds all bytecode function-specific data.
10//
11// The scope class which describes local variables is also defined here.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_INTERP_FUNCTION_H
16#define LLVM_CLANG_AST_INTERP_FUNCTION_H
17
18#include "Descriptor.h"
19#include "Source.h"
20#include "clang/AST/Attr.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclCXX.h"
23#include "llvm/ADT/PointerUnion.h"
24#include "llvm/Support/raw_ostream.h"
25
26namespace clang {
27namespace interp {
28class Program;
29class ByteCodeEmitter;
30class Pointer;
31enum PrimType : uint8_t;
32
33/// Describes a scope block.
34///
35/// The block gathers all the descriptors of the locals defined in this block.
36class Scope final {
37public:
38 /// Information about a local's storage.
39 struct Local {
40 /// Offset of the local in frame.
41 unsigned Offset;
42 /// Descriptor of the local.
44 /// If the cleanup for this local should be emitted.
45 bool EnabledByDefault = true;
46 };
47
49
50 Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
51
52 llvm::iterator_range<LocalVectorTy::const_iterator> locals() const {
53 return llvm::make_range(Descriptors.begin(), Descriptors.end());
54 }
55
56 llvm::iterator_range<LocalVectorTy::const_reverse_iterator>
58 return llvm::reverse(Descriptors);
59 }
60
61private:
62 /// Object descriptors in this block.
63 LocalVectorTy Descriptors;
64};
65
67 llvm::PointerUnion<const FunctionDecl *, const BlockExpr *>;
68
69/// Bytecode function.
70///
71/// Contains links to the bytecode of the function, as well as metadata
72/// describing all arguments and stack-local variables.
73///
74/// # Calling Convention
75///
76/// When calling a function, all argument values must be on the stack.
77///
78/// If the function has a This pointer (i.e. hasThisPointer() returns true,
79/// the argument values need to be preceeded by a Pointer for the This object.
80///
81/// If the function uses Return Value Optimization, the arguments (and
82/// potentially the This pointer) need to be preceeded by a Pointer pointing
83/// to the location to construct the returned value.
84///
85/// After the function has been called, it will remove all arguments,
86/// including RVO and This pointer, from the stack.
87///
88/// The parameters saved in a clang::intepr::Function include both the
89/// instance pointer as well as the RVO pointer.
90///
91/// \verbatim
92/// Stack position when calling ─────┐
93/// this Function │
94/// ▼
95/// ┌─────┬──────┬────────┬────────┬─────┬────────────────────┐
96/// │ RVO │ This │ Param1 │ Param2 │ ... │ │
97/// └─────┴──────┴────────┴────────┴─────┴────────────────────┘
98/// \endverbatim
99class Function final {
100public:
110
113 /// Offset on the stack.
114 unsigned Offset;
115 /// Offset in the InterpFrame.
116 unsigned BlockOffset;
121 };
122
123 /// Returns the size of the function's local stack.
124 unsigned getFrameSize() const { return FrameSize; }
125 /// Returns the size of the argument stack.
126 unsigned getArgSize() const { return ArgSize; }
127
128 /// Returns a pointer to the start of the code.
129 CodePtr getCodeBegin() const { return Code.data(); }
130 /// Returns a pointer to the end of the code.
131 CodePtr getCodeEnd() const { return Code.data() + Code.size(); }
132
133 /// Returns the original FunctionDecl.
134 const FunctionDecl *getDecl() const {
135 return dyn_cast<const FunctionDecl *>(Source);
136 }
137 const BlockExpr *getExpr() const {
138 return dyn_cast<const BlockExpr *>(Source);
139 }
140
141 /// Returns the name of the function decl this code
142 /// was generated for.
143 std::string getName() const {
144 if (!Source || !getDecl())
145 return "<<expr>>";
146
148 }
149
150 /// Returns a parameter descriptor.
151 ParamDescriptor getParamDescriptor(unsigned Index) const {
152 return ParamDescriptors[Index];
153 }
154
155 /// Checks if the first argument is a RVO pointer.
156 bool hasRVO() const { return HasRVO; }
157
158 bool hasNonNullAttr() const { return getDecl()->hasAttr<NonNullAttr>(); }
159
160 /// Range over the scope blocks.
161 llvm::iterator_range<llvm::SmallVector<Scope, 2>::const_iterator>
162 scopes() const {
163 return llvm::make_range(Scopes.begin(), Scopes.end());
164 }
165
166 /// Range over argument types.
169 llvm::iterator_range<arg_reverse_iterator> args_reverse() const {
170 return llvm::reverse(ParamDescriptors);
171 }
172
173 /// Returns a specific scope.
174 Scope &getScope(unsigned Idx) { return Scopes[Idx]; }
175 const Scope &getScope(unsigned Idx) const { return Scopes[Idx]; }
176
177 /// Returns the source information at a given PC.
178 SourceInfo getSource(CodePtr PC) const;
179
180 /// Checks if the function is valid to call.
181 bool isValid() const { return IsValid || isLambdaStaticInvoker(); }
182
183 /// Checks if the function is virtual.
184 bool isVirtual() const { return Virtual; };
185 bool isImmediate() const { return Immediate; }
186 bool isConstexpr() const { return Constexpr; }
187
188 /// Checks if the function is a constructor.
189 bool isConstructor() const {
190 return Kind == FunctionKind::Ctor || Kind == FunctionKind::CopyOrMoveCtor;
191 }
193 return Kind == FunctionKind::CopyOrMoveCtor;
194 }
195
196 /// Checks if the function is a destructor.
197 bool isDestructor() const { return Kind == FunctionKind::Dtor; }
198 /// Checks if the function is copy or move operator.
199 bool isCopyOrMoveOperator() const {
201 }
202
203 /// Returns whether this function is a lambda static invoker,
204 /// which we generate custom byte code for.
207 }
208
209 /// Returns whether this function is the call operator
210 /// of a lambda record decl.
211 bool isLambdaCallOperator() const {
213 }
214
215 /// Returns the parent record decl, if any.
217 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
218 dyn_cast<const FunctionDecl *>(Source)))
219 return MD->getParent();
220 return nullptr;
221 }
222
223 /// Checks if the function is fully done compiling.
224 bool isFullyCompiled() const { return IsFullyCompiled; }
225
226 bool hasThisPointer() const { return HasThisPointer; }
227
228 /// Checks if the function already has a body attached.
229 bool hasBody() const { return HasBody; }
230
231 /// Checks if the function is defined.
232 bool isDefined() const { return Defined; }
233
234 bool isVariadic() const { return Variadic; }
235
236 unsigned getNumParams() const {
237 return ParamDescriptors.size() + hasThisPointer() + hasRVO();
238 }
239
240 /// Returns the number of parameter this function takes when it's called,
241 /// i.e excluding the instance pointer and the RVO pointer.
242 unsigned getNumWrittenParams() const {
243 assert(getNumParams() >= (unsigned)(hasThisPointer() + hasRVO()));
244 return ParamDescriptors.size();
245 }
246 unsigned getWrittenArgSize() const {
247 return ArgSize - (align(primSize(PT_Ptr)) * (hasThisPointer() + hasRVO()));
248 }
249
251 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
252 dyn_cast<const FunctionDecl *>(Source)))
253 return MD->isExplicitObjectMemberFunction();
254 return false;
255 }
256
257private:
258 /// Construct a function representing an actual function.
259 Function(Program &P, FunctionDeclTy Source, unsigned ArgSize,
261 bool HasThisPointer, bool HasRVO, bool IsLambdaStaticInvoker);
262
263 /// Sets the code of a function.
264 void setCode(FunctionDeclTy Source, unsigned NewFrameSize,
265 llvm::SmallVector<std::byte> &&NewCode, SourceMap &&NewSrcMap,
266 llvm::SmallVector<Scope, 2> &&NewScopes, bool NewHasBody,
267 bool NewIsValid) {
268 this->Source = Source;
269 FrameSize = NewFrameSize;
270 Code = std::move(NewCode);
271 SrcMap = std::move(NewSrcMap);
272 Scopes = std::move(NewScopes);
273 IsValid = NewIsValid;
274 HasBody = NewHasBody;
275 }
276
277 void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
278 void setDefined(bool D) { Defined = D; }
279
280private:
281 friend class Program;
282 friend class ByteCodeEmitter;
283 friend class Context;
284
285 /// Program reference.
286 Program &P;
287 /// Function Kind.
288 FunctionKind Kind;
289 /// Declaration this function was compiled from.
290 FunctionDeclTy Source;
291 /// Local area size: storage + metadata.
292 unsigned FrameSize = 0;
293 /// Size of the argument stack.
294 unsigned ArgSize;
295 /// Program code.
297 /// Opcode-to-expression mapping.
298 SourceMap SrcMap;
299 /// List of block descriptors.
301 /// List of all parameters, including RVO and instance pointer.
302 llvm::SmallVector<ParamDescriptor> ParamDescriptors;
303 /// Flag to indicate if the function is valid.
304 LLVM_PREFERRED_TYPE(bool)
305 unsigned IsValid : 1;
306 /// Flag to indicate if the function is done being
307 /// compiled to bytecode.
308 LLVM_PREFERRED_TYPE(bool)
309 unsigned IsFullyCompiled : 1;
310 /// Flag indicating if this function takes the this pointer
311 /// as the first implicit argument
312 LLVM_PREFERRED_TYPE(bool)
313 unsigned HasThisPointer : 1;
314 /// Whether this function has Return Value Optimization, i.e.
315 /// the return value is constructed in the caller's stack frame.
316 /// This is done for functions that return non-primive values.
317 LLVM_PREFERRED_TYPE(bool)
318 unsigned HasRVO : 1;
319 /// If we've already compiled the function's body.
320 LLVM_PREFERRED_TYPE(bool)
321 unsigned HasBody : 1;
322 LLVM_PREFERRED_TYPE(bool)
323 unsigned Defined : 1;
324 LLVM_PREFERRED_TYPE(bool)
325 unsigned Variadic : 1;
326 LLVM_PREFERRED_TYPE(bool)
327 unsigned Virtual : 1;
328 LLVM_PREFERRED_TYPE(bool)
329 unsigned Immediate : 1;
330 LLVM_PREFERRED_TYPE(bool)
331 unsigned Constexpr : 1;
332
333public:
334 /// Dumps the disassembled bytecode to \c llvm::errs().
335 void dump() const { dump({}); }
336 void dump(CodePtr PC) const;
337 void dump(llvm::raw_ostream &OS, CodePtr PC = {}) const;
338};
339
340} // namespace interp
341} // namespace clang
342
343#endif
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6673
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
bool hasAttr() const
Definition DeclBase.h:585
Represents a function declaration or definition.
Definition Decl.h:2018
std::string getQualifiedNameAsString() const
Definition Decl.cpp:1681
An emitter which links the program to bytecode for later use.
Pointer into the code segment.
Definition Source.h:30
friend class Program
Definition Function.h:281
Scope & getScope(unsigned Idx)
Returns a specific scope.
Definition Function.h:174
CodePtr getCodeBegin() const
Returns a pointer to the start of the code.
Definition Function.h:129
bool isDestructor() const
Checks if the function is a destructor.
Definition Function.h:197
CodePtr getCodeEnd() const
Returns a pointer to the end of the code.
Definition Function.h:131
friend class ByteCodeEmitter
Definition Function.h:282
std::string getName() const
Returns the name of the function decl this code was generated for.
Definition Function.h:143
bool isVirtual() const
Checks if the function is virtual.
Definition Function.h:184
unsigned getNumParams() const
Definition Function.h:236
bool isDefined() const
Checks if the function is defined.
Definition Function.h:232
bool hasNonNullAttr() const
Definition Function.h:158
const CXXRecordDecl * getParentDecl() const
Returns the parent record decl, if any.
Definition Function.h:216
unsigned getFrameSize() const
Returns the size of the function's local stack.
Definition Function.h:124
bool isLambdaCallOperator() const
Returns whether this function is the call operator of a lambda record decl.
Definition Function.h:211
const BlockExpr * getExpr() const
Definition Function.h:137
bool isFullyCompiled() const
Checks if the function is fully done compiling.
Definition Function.h:224
bool isConstructor() const
Checks if the function is a constructor.
Definition Function.h:189
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
Definition Function.h:134
bool hasBody() const
Checks if the function already has a body attached.
Definition Function.h:229
bool hasThisPointer() const
Definition Function.h:226
void dump(llvm::raw_ostream &OS, CodePtr PC={}) const
llvm::iterator_range< arg_reverse_iterator > args_reverse() const
Definition Function.h:169
bool isConstexpr() const
Definition Function.h:186
const Scope & getScope(unsigned Idx) const
Definition Function.h:175
bool isThisPointerExplicit() const
Definition Function.h:250
unsigned getNumWrittenParams() const
Returns the number of parameter this function takes when it's called, i.e excluding the instance poin...
Definition Function.h:242
friend class Context
Definition Function.h:283
unsigned getWrittenArgSize() const
Definition Function.h:246
unsigned getArgSize() const
Returns the size of the argument stack.
Definition Function.h:126
bool isLambdaStaticInvoker() const
Returns whether this function is a lambda static invoker, which we generate custom byte code for.
Definition Function.h:205
ParamDescriptor getParamDescriptor(unsigned Index) const
Returns a parameter descriptor.
Definition Function.h:151
bool isVariadic() const
Definition Function.h:234
SourceInfo getSource(CodePtr PC) const
Returns the source information at a given PC.
Definition Function.cpp:56
bool isValid() const
Checks if the function is valid to call.
Definition Function.h:181
void dump() const
Dumps the disassembled bytecode to llvm::errs().
Definition Function.h:335
bool isImmediate() const
Definition Function.h:185
bool isCopyOrMoveConstructor() const
Definition Function.h:192
bool isCopyOrMoveOperator() const
Checks if the function is copy or move operator.
Definition Function.h:199
llvm::iterator_range< llvm::SmallVector< Scope, 2 >::const_iterator > scopes() const
Range over the scope blocks.
Definition Function.h:162
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition Function.h:156
SmallVectorImpl< ParamDescriptor >::const_reverse_iterator arg_reverse_iterator
Range over argument types.
Definition Function.h:167
A pointer to a memory block, live or dead.
Definition Pointer.h:97
The program contains and links the bytecode for all functions.
Definition Program.h:36
Describes a scope block.
Definition Function.h:36
llvm::SmallVector< Local, 8 > LocalVectorTy
Definition Function.h:48
llvm::iterator_range< LocalVectorTy::const_iterator > locals() const
Definition Function.h:52
Scope(LocalVectorTy &&Descriptors)
Definition Function.h:50
llvm::iterator_range< LocalVectorTy::const_reverse_iterator > locals_reverse() const
Definition Function.h:57
Describes the statement/declaration an opcode was generated from.
Definition Source.h:74
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition PrimType.h:201
llvm::PointerUnion< const FunctionDecl *, const BlockExpr * > FunctionDeclTy
Definition Function.h:66
PrimType
Enumeration of the primitive types of the VM.
Definition PrimType.h:34
std::vector< std::pair< unsigned, SourceInfo > > SourceMap
Definition Source.h:98
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition PrimType.cpp:24
The JSON file list parser is used to communicate input to InstallAPI.
Describes a memory block created by an allocation site.
Definition Descriptor.h:123
unsigned BlockOffset
Offset in the InterpFrame.
Definition Function.h:116
unsigned Offset
Offset on the stack.
Definition Function.h:114
ParamDescriptor(const Descriptor *Desc, unsigned Offset, unsigned BlockOffset, PrimType T)
Definition Function.h:118
Information about a local's storage.
Definition Function.h:39
unsigned Offset
Offset of the local in frame.
Definition Function.h:41
bool EnabledByDefault
If the cleanup for this local should be emitted.
Definition Function.h:45
Descriptor * Desc
Descriptor of the local.
Definition Function.h:43