clang 20.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/ASTLambda.h"
21#include "clang/AST/Attr.h"
22#include "clang/AST/Decl.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 : uint32_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 };
45
47
48 Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
49
50 llvm::iterator_range<LocalVectorTy::const_iterator> locals() const {
51 return llvm::make_range(Descriptors.begin(), Descriptors.end());
52 }
53
54private:
55 /// Object descriptors in this block.
56 LocalVectorTy Descriptors;
57};
58
60 llvm::PointerUnion<const FunctionDecl *, const BlockExpr *>;
61
62/// Bytecode function.
63///
64/// Contains links to the bytecode of the function, as well as metadata
65/// describing all arguments and stack-local variables.
66///
67/// # Calling Convention
68///
69/// When calling a function, all argument values must be on the stack.
70///
71/// If the function has a This pointer (i.e. hasThisPointer() returns true,
72/// the argument values need to be preceeded by a Pointer for the This object.
73///
74/// If the function uses Return Value Optimization, the arguments (and
75/// potentially the This pointer) need to be preceeded by a Pointer pointing
76/// to the location to construct the returned value.
77///
78/// After the function has been called, it will remove all arguments,
79/// including RVO and This pointer, from the stack.
80///
81class Function final {
82public:
83 using ParamDescriptor = std::pair<PrimType, Descriptor *>;
84
85 /// Returns the size of the function's local stack.
86 unsigned getFrameSize() const { return FrameSize; }
87 /// Returns the size of the argument stack.
88 unsigned getArgSize() const { return ArgSize; }
89
90 /// Returns a pointer to the start of the code.
91 CodePtr getCodeBegin() const { return Code.data(); }
92 /// Returns a pointer to the end of the code.
93 CodePtr getCodeEnd() const { return Code.data() + Code.size(); }
94
95 /// Returns the original FunctionDecl.
96 const FunctionDecl *getDecl() const {
97 return Source.dyn_cast<const FunctionDecl *>();
98 }
99 const BlockExpr *getExpr() const {
100 return Source.dyn_cast<const BlockExpr *>();
101 }
102
103 /// Returns the name of the function decl this code
104 /// was generated for.
105 const std::string getName() const {
106 if (!Source)
107 return "<<expr>>";
108
109 return Source.get<const FunctionDecl *>()->getQualifiedNameAsString();
110 }
111
112 /// Returns a parameter descriptor.
113 ParamDescriptor getParamDescriptor(unsigned Offset) const;
114
115 /// Checks if the first argument is a RVO pointer.
116 bool hasRVO() const { return HasRVO; }
117
118 bool hasNonNullAttr() const { return getDecl()->hasAttr<NonNullAttr>(); }
119
120 /// Range over the scope blocks.
121 llvm::iterator_range<llvm::SmallVector<Scope, 2>::const_iterator>
122 scopes() const {
123 return llvm::make_range(Scopes.begin(), Scopes.end());
124 }
125
126 /// Range over argument types.
129 llvm::iterator_range<arg_reverse_iterator> args_reverse() const {
130 return llvm::reverse(ParamTypes);
131 }
132
133 /// Returns a specific scope.
134 Scope &getScope(unsigned Idx) { return Scopes[Idx]; }
135 const Scope &getScope(unsigned Idx) const { return Scopes[Idx]; }
136
137 /// Returns the source information at a given PC.
138 SourceInfo getSource(CodePtr PC) const;
139
140 /// Checks if the function is valid to call in constexpr.
141 bool isConstexpr() const { return IsValid || isLambdaStaticInvoker(); }
142
143 /// Checks if the function is virtual.
144 bool isVirtual() const;
145
146 /// Checks if the function is a constructor.
147 bool isConstructor() const {
148 return isa_and_nonnull<CXXConstructorDecl>(
149 Source.dyn_cast<const FunctionDecl *>());
150 }
151 /// Checks if the function is a destructor.
152 bool isDestructor() const {
153 return isa_and_nonnull<CXXDestructorDecl>(
154 Source.dyn_cast<const FunctionDecl *>());
155 }
156
157 /// Returns the parent record decl, if any.
159 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
160 Source.dyn_cast<const FunctionDecl *>()))
161 return MD->getParent();
162 return nullptr;
163 }
164
165 /// Returns whether this function is a lambda static invoker,
166 /// which we generate custom byte code for.
168 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
169 Source.dyn_cast<const FunctionDecl *>()))
170 return MD->isLambdaStaticInvoker();
171 return false;
172 }
173
174 /// Returns whether this function is the call operator
175 /// of a lambda record decl.
176 bool isLambdaCallOperator() const {
177 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
178 Source.dyn_cast<const FunctionDecl *>()))
180 return false;
181 }
182
183 /// Checks if the function is fully done compiling.
184 bool isFullyCompiled() const { return IsFullyCompiled; }
185
186 bool hasThisPointer() const { return HasThisPointer; }
187
188 /// Checks if the function already has a body attached.
189 bool hasBody() const { return HasBody; }
190
191 /// Checks if the function is defined.
192 bool isDefined() const { return Defined; }
193
194 bool isVariadic() const { return Variadic; }
195
196 unsigned getBuiltinID() const {
197 return Source.get<const FunctionDecl *>()->getBuiltinID();
198 }
199
200 bool isBuiltin() const {
201 return Source.get<const FunctionDecl *>()->getBuiltinID() != 0;
202 }
203
204 bool isUnevaluatedBuiltin() const { return IsUnevaluatedBuiltin; }
205
206 unsigned getNumParams() const { return ParamTypes.size(); }
207
208 /// Returns the number of parameter this function takes when it's called,
209 /// i.e excluding the instance pointer and the RVO pointer.
210 unsigned getNumWrittenParams() const {
211 assert(getNumParams() >= (unsigned)(hasThisPointer() + hasRVO()));
212 return getNumParams() - hasThisPointer() - hasRVO();
213 }
214 unsigned getWrittenArgSize() const {
215 return ArgSize - (align(primSize(PT_Ptr)) * (hasThisPointer() + hasRVO()));
216 }
217
219 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
220 Source.dyn_cast<const FunctionDecl *>()))
221 return MD->isExplicitObjectMemberFunction();
222 return false;
223 }
224
225 unsigned getParamOffset(unsigned ParamIndex) const {
226 return ParamOffsets[ParamIndex];
227 }
228
229private:
230 /// Construct a function representing an actual function.
231 Function(Program &P, FunctionDeclTy Source, unsigned ArgSize,
233 llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
234 llvm::SmallVectorImpl<unsigned> &&ParamOffsets, bool HasThisPointer,
235 bool HasRVO, bool UnevaluatedBuiltin);
236
237 /// Sets the code of a function.
238 void setCode(unsigned NewFrameSize, std::vector<std::byte> &&NewCode,
239 SourceMap &&NewSrcMap, llvm::SmallVector<Scope, 2> &&NewScopes,
240 bool NewHasBody) {
241 FrameSize = NewFrameSize;
242 Code = std::move(NewCode);
243 SrcMap = std::move(NewSrcMap);
244 Scopes = std::move(NewScopes);
245 IsValid = true;
246 HasBody = NewHasBody;
247 }
248
249 void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
250 void setDefined(bool D) { Defined = D; }
251
252private:
253 friend class Program;
254 friend class ByteCodeEmitter;
255
256 /// Program reference.
257 Program &P;
258 /// Declaration this function was compiled from.
259 FunctionDeclTy Source;
260 /// Local area size: storage + metadata.
261 unsigned FrameSize = 0;
262 /// Size of the argument stack.
263 unsigned ArgSize;
264 /// Program code.
265 std::vector<std::byte> Code;
266 /// Opcode-to-expression mapping.
267 SourceMap SrcMap;
268 /// List of block descriptors.
270 /// List of argument types.
272 /// Map from byte offset to parameter descriptor.
273 llvm::DenseMap<unsigned, ParamDescriptor> Params;
274 /// List of parameter offsets.
276 /// Flag to indicate if the function is valid.
277 bool IsValid = false;
278 /// Flag to indicate if the function is done being
279 /// compiled to bytecode.
280 bool IsFullyCompiled = false;
281 /// Flag indicating if this function takes the this pointer
282 /// as the first implicit argument
283 bool HasThisPointer = false;
284 /// Whether this function has Return Value Optimization, i.e.
285 /// the return value is constructed in the caller's stack frame.
286 /// This is done for functions that return non-primive values.
287 bool HasRVO = false;
288 /// If we've already compiled the function's body.
289 bool HasBody = false;
290 bool Defined = false;
291 bool Variadic = false;
292 bool IsUnevaluatedBuiltin = false;
293
294public:
295 /// Dumps the disassembled bytecode to \c llvm::errs().
296 void dump() const;
297 void dump(llvm::raw_ostream &OS) const;
298};
299
300} // namespace interp
301} // namespace clang
302
303#endif
This file provides some common utility functions for processing Lambda related AST Constructs.
StringRef P
const Decl * D
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6365
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
bool hasAttr() const
Definition: DeclBase.h:584
Represents a function declaration or definition.
Definition: Decl.h:1932
An emitter which links the program to bytecode for later use.
Pointer into the code segment.
Definition: Source.h:30
Bytecode function.
Definition: Function.h:81
Scope & getScope(unsigned Idx)
Returns a specific scope.
Definition: Function.h:134
CodePtr getCodeBegin() const
Returns a pointer to the start of the code.
Definition: Function.h:91
bool isDestructor() const
Checks if the function is a destructor.
Definition: Function.h:152
CodePtr getCodeEnd() const
Returns a pointer to the end of the code.
Definition: Function.h:93
const std::string getName() const
Returns the name of the function decl this code was generated for.
Definition: Function.h:105
unsigned getNumParams() const
Definition: Function.h:206
bool isDefined() const
Checks if the function is defined.
Definition: Function.h:192
bool hasNonNullAttr() const
Definition: Function.h:118
std::pair< PrimType, Descriptor * > ParamDescriptor
Definition: Function.h:83
const CXXRecordDecl * getParentDecl() const
Returns the parent record decl, if any.
Definition: Function.h:158
unsigned getFrameSize() const
Returns the size of the function's local stack.
Definition: Function.h:86
bool isLambdaCallOperator() const
Returns whether this function is the call operator of a lambda record decl.
Definition: Function.h:176
const BlockExpr * getExpr() const
Definition: Function.h:99
bool isBuiltin() const
Definition: Function.h:200
bool isFullyCompiled() const
Checks if the function is fully done compiling.
Definition: Function.h:184
bool isConstructor() const
Checks if the function is a constructor.
Definition: Function.h:147
unsigned getParamOffset(unsigned ParamIndex) const
Definition: Function.h:225
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
Definition: Function.h:96
bool hasBody() const
Checks if the function already has a body attached.
Definition: Function.h:189
bool hasThisPointer() const
Definition: Function.h:186
bool isVirtual() const
Checks if the function is virtual.
Definition: Function.cpp:50
unsigned getBuiltinID() const
Definition: Function.h:196
void dump() const
Dumps the disassembled bytecode to llvm::errs().
Definition: Disasm.cpp:64
bool isUnevaluatedBuiltin() const
Definition: Function.h:204
llvm::iterator_range< arg_reverse_iterator > args_reverse() const
Definition: Function.h:129
bool isConstexpr() const
Checks if the function is valid to call in constexpr.
Definition: Function.h:141
const Scope & getScope(unsigned Idx) const
Definition: Function.h:135
bool isThisPointerExplicit() const
Definition: Function.h:218
unsigned getNumWrittenParams() const
Returns the number of parameter this function takes when it's called, i.e excluding the instance poin...
Definition: Function.h:210
unsigned getWrittenArgSize() const
Definition: Function.h:214
unsigned getArgSize() const
Returns the size of the argument stack.
Definition: Function.h:88
bool isLambdaStaticInvoker() const
Returns whether this function is a lambda static invoker, which we generate custom byte code for.
Definition: Function.h:167
SmallVectorImpl< PrimType >::const_reverse_iterator arg_reverse_iterator
Range over argument types.
Definition: Function.h:128
bool isVariadic() const
Definition: Function.h:194
SourceInfo getSource(CodePtr PC) const
Returns the source information at a given PC.
Definition: Function.cpp:38
ParamDescriptor getParamDescriptor(unsigned Offset) const
Returns a parameter descriptor.
Definition: Function.cpp:32
llvm::iterator_range< llvm::SmallVector< Scope, 2 >::const_iterator > scopes() const
Range over the scope blocks.
Definition: Function.h:122
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition: Function.h:116
The program contains and links the bytecode for all functions.
Definition: Program.h:39
Describes a scope block.
Definition: Function.h:36
llvm::SmallVector< Local, 8 > LocalVectorTy
Definition: Function.h:46
llvm::iterator_range< LocalVectorTy::const_iterator > locals() const
Definition: Function.h:50
Scope(LocalVectorTy &&Descriptors)
Definition: Function.h:48
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:77
std::vector< std::pair< unsigned, SourceInfo > > SourceMap
Definition: Source.h:96
llvm::PointerUnion< const FunctionDecl *, const BlockExpr * > FunctionDeclTy
Definition: Function.h:60
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition: PrimType.h:126
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:33
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition: PrimType.cpp:23
The JSON file list parser is used to communicate input to InstallAPI.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
Definition: ASTLambda.h:27
unsigned int uint32_t
Describes a memory block created by an allocation site.
Definition: Descriptor.h:111
Information about a local's storage.
Definition: Function.h:39
unsigned Offset
Offset of the local in frame.
Definition: Function.h:41
Descriptor * Desc
Descriptor of the local.
Definition: Function.h:43