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