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