[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / AST / Interp / Function.h
blobbe9b1733635f72523e9ba9dc494b73d5b218024e
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.
11 // The scope class which describes local variables is also defined here.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_AST_INTERP_FUNCTION_H
16 #define LLVM_CLANG_AST_INTERP_FUNCTION_H
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"
24 namespace clang {
25 namespace interp {
26 class Program;
27 class ByteCodeEmitter;
28 class Pointer;
29 enum PrimType : uint32_t;
31 /// Describes a scope block.
32 ///
33 /// The block gathers all the descriptors of the locals defined in this block.
34 class Scope final {
35 public:
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.
41 Descriptor *Desc;
44 using LocalVectorTy = llvm::SmallVector<Local, 8>;
46 Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
48 llvm::iterator_range<LocalVectorTy::const_iterator> locals() const {
49 return llvm::make_range(Descriptors.begin(), Descriptors.end());
52 private:
53 /// Object descriptors in this block.
54 LocalVectorTy Descriptors;
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 ///
76 class Function final {
77 public:
78 using ParamDescriptor = std::pair<PrimType, Descriptor *>;
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; }
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(); }
90 /// Returns the original FunctionDecl.
91 const FunctionDecl *getDecl() const { return F; }
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>>";
99 return F->getQualifiedNameAsString();
102 /// Returns the location.
103 SourceLocation getLoc() const { return Loc; }
105 /// Returns a parameter descriptor.
106 ParamDescriptor getParamDescriptor(unsigned Offset) const;
108 /// Checks if the first argument is a RVO pointer.
109 bool hasRVO() const { return HasRVO; }
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());
117 /// Range over argument types.
118 using arg_reverse_iterator =
119 SmallVectorImpl<PrimType>::const_reverse_iterator;
120 llvm::iterator_range<arg_reverse_iterator> args_reverse() const {
121 return llvm::reverse(ParamTypes);
124 /// Returns a specific scope.
125 Scope &getScope(unsigned Idx) { return Scopes[Idx]; }
126 const Scope &getScope(unsigned Idx) const { return Scopes[Idx]; }
128 /// Returns the source information at a given PC.
129 SourceInfo getSource(CodePtr PC) const;
131 /// Checks if the function is valid to call in constexpr.
132 bool isConstexpr() const { return IsValid || isLambdaStaticInvoker(); }
134 /// Checks if the function is virtual.
135 bool isVirtual() const;
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); }
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;
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;
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;
165 /// Checks if the function is fully done compiling.
166 bool isFullyCompiled() const { return IsFullyCompiled; }
168 bool hasThisPointer() const { return HasThisPointer; }
170 /// Checks if the function already has a body attached.
171 bool hasBody() const { return HasBody; }
173 /// Checks if the function is defined.
174 bool isDefined() const { return Defined; }
176 bool isVariadic() const { return Variadic; }
178 unsigned getBuiltinID() const { return F->getBuiltinID(); }
180 bool isBuiltin() const { return F->getBuiltinID() != 0; }
182 /// Does this function need its arguments to be classified at runtime
183 /// rather than at bytecode-compile-time?
184 bool needsRuntimeArgPop(const ASTContext &Ctx) const;
186 unsigned getNumParams() const { return ParamTypes.size(); }
188 unsigned getParamOffset(unsigned ParamIndex) const {
189 return ParamOffsets[ParamIndex];
192 private:
193 /// Construct a function representing an actual function.
194 Function(Program &P, const FunctionDecl *F, unsigned ArgSize,
195 llvm::SmallVectorImpl<PrimType> &&ParamTypes,
196 llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
197 llvm::SmallVectorImpl<unsigned> &&ParamOffsets, bool HasThisPointer,
198 bool HasRVO);
200 /// Sets the code of a function.
201 void setCode(unsigned NewFrameSize, std::vector<std::byte> &&NewCode,
202 SourceMap &&NewSrcMap, llvm::SmallVector<Scope, 2> &&NewScopes,
203 bool NewHasBody) {
204 FrameSize = NewFrameSize;
205 Code = std::move(NewCode);
206 SrcMap = std::move(NewSrcMap);
207 Scopes = std::move(NewScopes);
208 IsValid = true;
209 HasBody = NewHasBody;
212 void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
213 void setDefined(bool D) { Defined = D; }
215 private:
216 friend class Program;
217 friend class ByteCodeEmitter;
219 /// Program reference.
220 Program &P;
221 /// Location of the executed code.
222 SourceLocation Loc;
223 /// Declaration this function was compiled from.
224 const FunctionDecl *F;
225 /// Local area size: storage + metadata.
226 unsigned FrameSize = 0;
227 /// Size of the argument stack.
228 unsigned ArgSize;
229 /// Program code.
230 std::vector<std::byte> Code;
231 /// Opcode-to-expression mapping.
232 SourceMap SrcMap;
233 /// List of block descriptors.
234 llvm::SmallVector<Scope, 2> Scopes;
235 /// List of argument types.
236 llvm::SmallVector<PrimType, 8> ParamTypes;
237 /// Map from byte offset to parameter descriptor.
238 llvm::DenseMap<unsigned, ParamDescriptor> Params;
239 /// List of parameter offsets.
240 llvm::SmallVector<unsigned, 8> ParamOffsets;
241 /// Flag to indicate if the function is valid.
242 bool IsValid = false;
243 /// Flag to indicate if the function is done being
244 /// compiled to bytecode.
245 bool IsFullyCompiled = false;
246 /// Flag indicating if this function takes the this pointer
247 /// as the first implicit argument
248 bool HasThisPointer = false;
249 /// Whether this function has Return Value Optimization, i.e.
250 /// the return value is constructed in the caller's stack frame.
251 /// This is done for functions that return non-primive values.
252 bool HasRVO = false;
253 /// If we've already compiled the function's body.
254 bool HasBody = false;
255 bool Defined = false;
256 bool Variadic = false;
258 public:
259 /// Dumps the disassembled bytecode to \c llvm::errs().
260 void dump() const;
261 void dump(llvm::raw_ostream &OS) const;
264 } // namespace interp
265 } // namespace clang
267 #endif