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/Support/raw_ostream.h"
24 
25 namespace clang {
26 namespace interp {
27 class Program;
28 class ByteCodeEmitter;
29 class Pointer;
30 enum PrimType : uint32_t;
31 
32 /// Describes a scope block.
33 ///
34 /// The block gathers all the descriptors of the locals defined in this block.
35 class Scope final {
36 public:
37  /// Information about a local's storage.
38  struct Local {
39  /// Offset of the local in frame.
40  unsigned Offset;
41  /// Descriptor of the local.
43  };
44 
46 
47  Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
48 
49  llvm::iterator_range<LocalVectorTy::const_iterator> locals() const {
50  return llvm::make_range(Descriptors.begin(), Descriptors.end());
51  }
52 
53 private:
54  /// Object descriptors in this block.
55  LocalVectorTy Descriptors;
56 };
57 
58 /// Bytecode function.
59 ///
60 /// Contains links to the bytecode of the function, as well as metadata
61 /// describing all arguments and stack-local variables.
62 ///
63 /// # Calling Convention
64 ///
65 /// When calling a function, all argument values must be on the stack.
66 ///
67 /// If the function has a This pointer (i.e. hasThisPointer() returns true,
68 /// the argument values need to be preceeded by a Pointer for the This object.
69 ///
70 /// If the function uses Return Value Optimization, the arguments (and
71 /// potentially the This pointer) need to be preceeded by a Pointer pointing
72 /// to the location to construct the returned value.
73 ///
74 /// After the function has been called, it will remove all arguments,
75 /// including RVO and This pointer, from the stack.
76 ///
77 class Function final {
78 public:
79  using ParamDescriptor = std::pair<PrimType, Descriptor *>;
80 
81  /// Returns the size of the function's local stack.
82  unsigned getFrameSize() const { return FrameSize; }
83  /// Returns the size of the argument stack.
84  unsigned getArgSize() const { return ArgSize; }
85 
86  /// Returns a pointer to the start of the code.
87  CodePtr getCodeBegin() const { return Code.data(); }
88  /// Returns a pointer to the end of the code.
89  CodePtr getCodeEnd() const { return Code.data() + Code.size(); }
90 
91  /// Returns the original FunctionDecl.
92  const FunctionDecl *getDecl() const { return F; }
93 
94  /// Returns the name of the function decl this code
95  /// was generated for.
96  const std::string getName() const {
97  if (!F)
98  return "<<expr>>";
99 
100  return F->getQualifiedNameAsString();
101  }
102 
103  /// Returns a parameter descriptor.
104  ParamDescriptor getParamDescriptor(unsigned Offset) const;
105 
106  /// Checks if the first argument is a RVO pointer.
107  bool hasRVO() const { return HasRVO; }
108 
109  bool hasNonNullAttr() const { return getDecl()->hasAttr<NonNullAttr>(); }
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.
143  const CXXRecordDecl *getParentDecl() const {
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.
151  bool isLambdaStaticInvoker() const {
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))
161  return clang::isLambdaCallOperator(MD);
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  /// Returns the number of parameter this function takes when it's called,
187  /// i.e excluding the instance pointer and the RVO pointer.
188  unsigned getNumWrittenParams() const {
189  assert(getNumParams() >= (unsigned)(hasThisPointer() + hasRVO()));
190  return getNumParams() - hasThisPointer() - hasRVO();
191  }
192  unsigned getWrittenArgSize() const {
193  return ArgSize - (align(primSize(PT_Ptr)) * (hasThisPointer() + hasRVO()));
194  }
195 
196  bool isThisPointerExplicit() const {
197  if (const auto *MD = dyn_cast<CXXMethodDecl>(F))
198  return MD->isExplicitObjectMemberFunction();
199  return false;
200  }
201 
202  unsigned getParamOffset(unsigned ParamIndex) const {
203  return ParamOffsets[ParamIndex];
204  }
205 
206 private:
207  /// Construct a function representing an actual function.
208  Function(Program &P, const FunctionDecl *F, unsigned ArgSize,
209  llvm::SmallVectorImpl<PrimType> &&ParamTypes,
210  llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
211  llvm::SmallVectorImpl<unsigned> &&ParamOffsets, bool HasThisPointer,
212  bool HasRVO, bool UnevaluatedBuiltin);
213 
214  /// Sets the code of a function.
215  void setCode(unsigned NewFrameSize, std::vector<std::byte> &&NewCode,
216  SourceMap &&NewSrcMap, llvm::SmallVector<Scope, 2> &&NewScopes,
217  bool NewHasBody) {
218  FrameSize = NewFrameSize;
219  Code = std::move(NewCode);
220  SrcMap = std::move(NewSrcMap);
221  Scopes = std::move(NewScopes);
222  IsValid = true;
223  HasBody = NewHasBody;
224  }
225 
226  void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
227  void setDefined(bool D) { Defined = D; }
228 
229 private:
230  friend class Program;
231  friend class ByteCodeEmitter;
232 
233  /// Program reference.
234  Program &P;
235  /// Declaration this function was compiled from.
236  const FunctionDecl *F;
237  /// Local area size: storage + metadata.
238  unsigned FrameSize = 0;
239  /// Size of the argument stack.
240  unsigned ArgSize;
241  /// Program code.
242  std::vector<std::byte> Code;
243  /// Opcode-to-expression mapping.
244  SourceMap SrcMap;
245  /// List of block descriptors.
247  /// List of argument types.
249  /// Map from byte offset to parameter descriptor.
250  llvm::DenseMap<unsigned, ParamDescriptor> Params;
251  /// List of parameter offsets.
252  llvm::SmallVector<unsigned, 8> ParamOffsets;
253  /// Flag to indicate if the function is valid.
254  bool IsValid = false;
255  /// Flag to indicate if the function is done being
256  /// compiled to bytecode.
257  bool IsFullyCompiled = false;
258  /// Flag indicating if this function takes the this pointer
259  /// as the first implicit argument
260  bool HasThisPointer = false;
261  /// Whether this function has Return Value Optimization, i.e.
262  /// the return value is constructed in the caller's stack frame.
263  /// This is done for functions that return non-primive values.
264  bool HasRVO = false;
265  /// If we've already compiled the function's body.
266  bool HasBody = false;
267  bool Defined = false;
268  bool Variadic = false;
269  bool IsUnevaluatedBuiltin = false;
270 
271 public:
272  /// Dumps the disassembled bytecode to \c llvm::errs().
273  void dump() const;
274  void dump(llvm::raw_ostream &OS) const;
275 };
276 
277 } // namespace interp
278 } // namespace clang
279 
280 #endif
This file provides some common utility functions for processing Lambda related AST Constructs.
StringRef P
const Decl * D
unsigned Offset
Definition: Format.cpp:3003
llvm::raw_ostream & OS
Definition: Logger.cpp:24
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:1933
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition: Decl.cpp:3622
std::string getQualifiedNameAsString(bool WithGlobalNsPrefix=false) const
Definition: Decl.cpp:1668
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:77
CodePtr getCodeBegin() const
Returns a pointer to the start of the code.
Definition: Function.h:87
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:89
const Scope & getScope(unsigned Idx) const
Definition: Function.h:126
const std::string getName() const
Returns the name of the function decl this code was generated for.
Definition: Function.h:96
unsigned getNumParams() const
Definition: Function.h:184
bool isDefined() const
Checks if the function is defined.
Definition: Function.h:174
bool hasNonNullAttr() const
Definition: Function.h:109
Scope & getScope(unsigned Idx)
Returns a specific scope.
Definition: Function.h:125
std::pair< PrimType, Descriptor * > ParamDescriptor
Definition: Function.h:79
llvm::iterator_range< arg_reverse_iterator > args_reverse() const
Definition: Function.h:120
unsigned getFrameSize() const
Returns the size of the function's local stack.
Definition: Function.h:82
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:202
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
const FunctionDecl * getDecl() const
Returns the original FunctionDecl.
Definition: Function.h:92
unsigned getBuiltinID() const
Definition: Function.h:178
void dump() const
Dumps the disassembled bytecode to llvm::errs().
Definition: Disasm.cpp:64
llvm::iterator_range< llvm::SmallVector< Scope, 2 >::const_iterator > scopes() const
Range over the scope blocks.
Definition: Function.h:113
bool isUnevaluatedBuiltin() const
Definition: Function.h:182
bool isConstexpr() const
Checks if the function is valid to call in constexpr.
Definition: Function.h:132
bool isThisPointerExplicit() const
Definition: Function.h:196
unsigned getNumWrittenParams() const
Returns the number of parameter this function takes when it's called, i.e excluding the instance poin...
Definition: Function.h:188
unsigned getWrittenArgSize() const
Definition: Function.h:192
unsigned getArgSize() const
Returns the size of the argument stack.
Definition: Function.h:84
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:35
ParamDescriptor getParamDescriptor(unsigned Offset) const
Returns a parameter descriptor.
Definition: Function.cpp:29
const CXXRecordDecl * getParentDecl() const
Returns the parent record decl, if any.
Definition: Function.h:143
bool hasRVO() const
Checks if the first argument is a RVO pointer.
Definition: Function.h:107
The program contains and links the bytecode for all functions.
Definition: Program.h:39
Describes a scope block.
Definition: Function.h:35
llvm::SmallVector< Local, 8 > LocalVectorTy
Definition: Function.h:45
Scope(LocalVectorTy &&Descriptors)
Definition: Function.h:47
llvm::iterator_range< LocalVectorTy::const_iterator > locals() const
Definition: Function.h:49
Describes the statement/declaration an opcode was generated from.
Definition: Source.h:77
std::vector< std::pair< unsigned, SourceInfo > > SourceMap
Definition: Source.h:96
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:38
unsigned Offset
Offset of the local in frame.
Definition: Function.h:40
Descriptor * Desc
Descriptor of the local.
Definition: Function.h:42