xref: /freebsd/contrib/llvm-project/clang/lib/AST/Interp/Function.h (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
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 "Pointer.h"
19 #include "Source.h"
20 #include "clang/AST/Decl.h"
21 #include "llvm/Support/raw_ostream.h"
22 
23 namespace clang {
24 namespace interp {
25 class Program;
26 class ByteCodeEmitter;
27 enum PrimType : uint32_t;
28 
29 /// Describes a scope block.
30 ///
31 /// The block gathers all the descriptors of the locals defined in this block.
32 class Scope {
33 public:
34   /// Information about a local's storage.
35   struct Local {
36     /// Offset of the local in frame.
37     unsigned Offset;
38     /// Descriptor of the local.
39     Descriptor *Desc;
40   };
41 
42   using LocalVectorTy = llvm::SmallVector<Local, 8>;
43 
44   Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
45 
46   llvm::iterator_range<LocalVectorTy::iterator> locals() {
47     return llvm::make_range(Descriptors.begin(), Descriptors.end());
48   }
49 
50 private:
51   /// Object descriptors in this block.
52   LocalVectorTy Descriptors;
53 };
54 
55 /// Bytecode function.
56 ///
57 /// Contains links to the bytecode of the function, as well as metadata
58 /// describing all arguments and stack-local variables.
59 class Function {
60 public:
61   using ParamDescriptor = std::pair<PrimType, Descriptor *>;
62 
63   /// Returns the size of the function's local stack.
64   unsigned getFrameSize() const { return FrameSize; }
65   /// Returns the size of the argument stackx
66   unsigned getArgSize() const { return ArgSize; }
67 
68   /// Returns a pointer to the start of the code.
69   CodePtr getCodeBegin() const;
70   /// Returns a pointer to the end of the code.
71   CodePtr getCodeEnd() const;
72 
73   /// Returns the original FunctionDecl.
74   const FunctionDecl *getDecl() const { return F; }
75 
76   /// Returns the lcoation.
77   SourceLocation getLoc() const { return Loc; }
78 
79   /// Returns a parameter descriptor.
80   ParamDescriptor getParamDescriptor(unsigned Offset) const;
81 
82   /// Checks if the first argument is a RVO pointer.
83   bool hasRVO() const { return ParamTypes.size() != Params.size(); }
84 
85   /// Range over the scope blocks.
86   llvm::iterator_range<llvm::SmallVector<Scope, 2>::iterator> scopes() {
87     return llvm::make_range(Scopes.begin(), Scopes.end());
88   }
89 
90   /// Range over argument types.
91   using arg_reverse_iterator = SmallVectorImpl<PrimType>::reverse_iterator;
92   llvm::iterator_range<arg_reverse_iterator> args_reverse() {
93     return llvm::make_range(ParamTypes.rbegin(), ParamTypes.rend());
94   }
95 
96   /// Returns a specific scope.
97   Scope &getScope(unsigned Idx) { return Scopes[Idx]; }
98 
99   /// Returns the source information at a given PC.
100   SourceInfo getSource(CodePtr PC) const;
101 
102   /// Checks if the function is valid to call in constexpr.
103   bool isConstexpr() const { return IsValid; }
104 
105   /// Checks if the function is virtual.
106   bool isVirtual() const;
107 
108   /// Checks if the function is a constructor.
109   bool isConstructor() const { return isa<CXXConstructorDecl>(F); }
110 
111 private:
112   /// Construct a function representing an actual function.
113   Function(Program &P, const FunctionDecl *F, unsigned ArgSize,
114            llvm::SmallVector<PrimType, 8> &&ParamTypes,
115            llvm::DenseMap<unsigned, ParamDescriptor> &&Params);
116 
117   /// Sets the code of a function.
118   void setCode(unsigned NewFrameSize, std::vector<char> &&NewCode, SourceMap &&NewSrcMap,
119                llvm::SmallVector<Scope, 2> &&NewScopes) {
120     FrameSize = NewFrameSize;
121     Code = std::move(NewCode);
122     SrcMap = std::move(NewSrcMap);
123     Scopes = std::move(NewScopes);
124     IsValid = true;
125   }
126 
127 private:
128   friend class Program;
129   friend class ByteCodeEmitter;
130 
131   /// Program reference.
132   Program &P;
133   /// Location of the executed code.
134   SourceLocation Loc;
135   /// Declaration this function was compiled from.
136   const FunctionDecl *F;
137   /// Local area size: storage + metadata.
138   unsigned FrameSize;
139   /// Size of the argument stack.
140   unsigned ArgSize;
141   /// Program code.
142   std::vector<char> Code;
143   /// Opcode-to-expression mapping.
144   SourceMap SrcMap;
145   /// List of block descriptors.
146   llvm::SmallVector<Scope, 2> Scopes;
147   /// List of argument types.
148   llvm::SmallVector<PrimType, 8> ParamTypes;
149   /// Map from byte offset to parameter descriptor.
150   llvm::DenseMap<unsigned, ParamDescriptor> Params;
151   /// Flag to indicate if the function is valid.
152   bool IsValid = false;
153 
154 public:
155   /// Dumps the disassembled bytecode to \c llvm::errs().
156   void dump() const;
157   void dump(llvm::raw_ostream &OS) const;
158 };
159 
160 } // namespace interp
161 } // namespace clang
162 
163 #endif
164