clang  14.0.0git
Program.h
Go to the documentation of this file.
1 //===--- Program.h - Bytecode for the constexpr 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 a program which organises and links multiple bytecode functions.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_AST_INTERP_PROGRAM_H
14 #define LLVM_CLANG_AST_INTERP_PROGRAM_H
15 
16 #include <map>
17 #include <vector>
18 #include "Function.h"
19 #include "Pointer.h"
20 #include "PrimType.h"
21 #include "Record.h"
22 #include "Source.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/PointerUnion.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Support/Allocator.h"
27 
28 namespace clang {
29 class RecordDecl;
30 class Expr;
31 class FunctionDecl;
32 class StringLiteral;
33 class VarDecl;
34 
35 namespace interp {
36 class Context;
37 class Record;
38 
39 /// The program contains and links the bytecode for all functions.
40 class Program {
41 public:
42  Program(Context &Ctx) : Ctx(Ctx) {}
43 
44  /// Marshals a native pointer to an ID for embedding in bytecode.
45  unsigned getOrCreateNativePointer(const void *Ptr);
46 
47  /// Returns the value of a marshalled native pointer.
48  const void *getNativePointer(unsigned Idx);
49 
50  /// Emits a string literal among global data.
51  unsigned createGlobalString(const StringLiteral *S);
52 
53  /// Returns a pointer to a global.
54  Pointer getPtrGlobal(unsigned Idx);
55 
56  /// Returns the value of a global.
57  Block *getGlobal(unsigned Idx) {
58  assert(Idx < Globals.size());
59  return Globals[Idx]->block();
60  }
61 
62  /// Finds a global's index.
64 
65  /// Returns or creates a global an creates an index to it.
67 
68  /// Returns or creates a dummy value for parameters.
70 
71  /// Creates a global and returns its index.
73 
74  /// Creates a global from a lifetime-extended temporary.
76 
77  /// Creates a new function from a code range.
78  template <typename... Ts>
79  Function *createFunction(const FunctionDecl *Def, Ts &&... Args) {
80  auto *Func = new Function(*this, Def, std::forward<Ts>(Args)...);
81  Funcs.insert({Def, std::unique_ptr<Function>(Func)});
82  return Func;
83  }
84  /// Creates an anonymous function.
85  template <typename... Ts>
86  Function *createFunction(Ts &&... Args) {
87  auto *Func = new Function(*this, std::forward<Ts>(Args)...);
88  AnonFuncs.emplace_back(Func);
89  return Func;
90  }
91 
92  /// Returns a function.
94 
95  /// Returns a pointer to a function if it exists and can be compiled.
96  /// If a function couldn't be compiled, an error is returned.
97  /// If a function was not yet defined, a null pointer is returned.
99 
100  /// Returns a record or creates one if it does not exist.
101  Record *getOrCreateRecord(const RecordDecl *RD);
102 
103  /// Creates a descriptor for a primitive type.
105  bool IsConst = false,
106  bool IsTemporary = false,
107  bool IsMutable = false) {
108  return allocateDescriptor(D, Type, IsConst, IsTemporary, IsMutable);
109  }
110 
111  /// Creates a descriptor for a composite type.
112  Descriptor *createDescriptor(const DeclTy &D, const Type *Ty,
113  bool IsConst = false, bool IsTemporary = false,
114  bool IsMutable = false);
115 
116  /// Context to manage declaration lifetimes.
117  class DeclScope {
118  public:
119  DeclScope(Program &P, const VarDecl *VD) : P(P) { P.startDeclaration(VD); }
120  ~DeclScope() { P.endDeclaration(); }
121 
122  private:
123  Program &P;
124  };
125 
126  /// Returns the current declaration ID.
128  if (CurrentDeclaration == NoDeclaration)
129  return llvm::Optional<unsigned>{};
130  return LastDeclaration;
131  }
132 
133 private:
134  friend class DeclScope;
135 
137  bool IsStatic, bool IsExtern);
138 
139  /// Reference to the VM context.
140  Context &Ctx;
141  /// Mapping from decls to cached bytecode functions.
142  llvm::DenseMap<const FunctionDecl *, std::unique_ptr<Function>> Funcs;
143  /// List of anonymous functions.
144  std::vector<std::unique_ptr<Function>> AnonFuncs;
145 
146  /// Function relocation locations.
147  llvm::DenseMap<const FunctionDecl *, std::vector<unsigned>> Relocs;
148 
149  /// Native pointers referenced by bytecode.
150  std::vector<const void *> NativePointers;
151  /// Cached native pointer indices.
152  llvm::DenseMap<const void *, unsigned> NativePointerIndices;
153 
154  /// Custom allocator for global storage.
155  using PoolAllocTy = llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator>;
156 
157  /// Descriptor + storage for a global object.
158  ///
159  /// Global objects never go out of scope, thus they do not track pointers.
160  class Global {
161  public:
162  /// Create a global descriptor for string literals.
163  template <typename... Tys>
164  Global(Tys... Args) : B(std::forward<Tys>(Args)...) {}
165 
166  /// Allocates the global in the pool, reserving storate for data.
167  void *operator new(size_t Meta, PoolAllocTy &Alloc, size_t Data) {
168  return Alloc.Allocate(Meta + Data, alignof(void *));
169  }
170 
171  /// Return a pointer to the data.
172  char *data() { return B.data(); }
173  /// Return a pointer to the block.
174  Block *block() { return &B; }
175 
176  private:
177  /// Required metadata - does not actually track pointers.
178  Block B;
179  };
180 
181  /// Allocator for globals.
182  PoolAllocTy Allocator;
183 
184  /// Global objects.
185  std::vector<Global *> Globals;
186  /// Cached global indices.
187  llvm::DenseMap<const void *, unsigned> GlobalIndices;
188 
189  /// Mapping from decls to record metadata.
190  llvm::DenseMap<const RecordDecl *, Record *> Records;
191 
192  /// Dummy parameter to generate pointers from.
193  llvm::DenseMap<const ParmVarDecl *, unsigned> DummyParams;
194 
195  /// Creates a new descriptor.
196  template <typename... Ts>
197  Descriptor *allocateDescriptor(Ts &&... Args) {
198  return new (Allocator) Descriptor(std::forward<Ts>(Args)...);
199  }
200 
201  /// No declaration ID.
202  static constexpr unsigned NoDeclaration = (unsigned)-1;
203  /// Last declaration ID.
204  unsigned LastDeclaration = 0;
205  /// Current declaration ID.
206  unsigned CurrentDeclaration = NoDeclaration;
207 
208  /// Starts evaluating a declaration.
209  void startDeclaration(const VarDecl *Decl) {
210  LastDeclaration += 1;
211  CurrentDeclaration = LastDeclaration;
212  }
213 
214  /// Ends a global declaration.
215  void endDeclaration() {
216  CurrentDeclaration = NoDeclaration;
217  }
218 
219 public:
220  /// Dumps the disassembled bytecode to \c llvm::errs().
221  void dump() const;
222  void dump(llvm::raw_ostream &OS) const;
223 };
224 
225 } // namespace interp
226 } // namespace clang
227 
228 #endif
Pointer.h
clang::interp::Program::createFunction
Function * createFunction(Ts &&... Args)
Creates an anonymous function.
Definition: Program.h:86
clang::interp::Program::DeclScope::~DeclScope
~DeclScope()
Definition: Program.h:120
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:674
clang::interp::Program::DeclScope
Context to manage declaration lifetimes.
Definition: Program.h:117
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1663
llvm::Optional< unsigned >
clang::interp::Context
Holds all information required to evaluate constexpr code in a module.
Definition: Context.h:36
clang::interp::Program::getCurrentDecl
llvm::Optional< unsigned > getCurrentDecl() const
Returns the current declaration ID.
Definition: Program.h:127
llvm::Expected
Definition: LLVM.h:41
clang::interp::Program::getFunction
Function * getFunction(const FunctionDecl *F)
Returns a function.
Definition: Program.cpp:203
clang::interp::Pointer
A pointer to a memory block, live or dead.
Definition: Pointer.h:36
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1491
clang::interp::Program::getGlobal
Block * getGlobal(unsigned Idx)
Returns the value of a global.
Definition: Program.h:57
Source.h
clang::interp::Program::DeclScope::DeclScope
DeclScope(Program &P, const VarDecl *VD)
Definition: Program.h:119
clang::interp::Program::createDescriptor
Descriptor * createDescriptor(const DeclTy &D, PrimType Type, bool IsConst=false, bool IsTemporary=false, bool IsMutable=false)
Creates a descriptor for a primitive type.
Definition: Program.h:104
clang::interp::Block
A memory block, either on the stack or in the heap.
Definition: InterpBlock.h:35
clang::interp::PrimType
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:27
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:874
clang::StringLiteral
StringLiteral - This represents a string literal expression, e.g.
Definition: Expr.h:1767
PrimType.h
clang::interp::Program::getOrCreateNativePointer
unsigned getOrCreateNativePointer(const void *Ptr)
Marshals a native pointer to an ID for embedding in bytecode.
Definition: Program.cpp:21
clang::interp::Program::getOrCreateFunction
llvm::Expected< Function * > getOrCreateFunction(const FunctionDecl *F)
Returns a pointer to a function if it exists and can be compiled.
Definition: Program.cpp:209
clang::interp::Program::getOrCreateGlobal
llvm::Optional< unsigned > getOrCreateGlobal(const ValueDecl *VD)
Returns or creates a global an creates an index to it.
Definition: Program.cpp:126
clang::interp::Program::getOrCreateRecord
Record * getOrCreateRecord(const RecordDecl *RD)
Returns a record or creates one if it does not exist.
Definition: Program.cpp:222
clang::interp::Program::getPtrGlobal
Pointer getPtrGlobal(unsigned Idx)
Returns a pointer to a global.
Definition: Program.cpp:97
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:674
clang::interp::Program::dump
void dump() const
Dumps the disassembled bytecode to llvm::errs().
Definition: Disasm.cpp:74
std
Definition: Format.h:4275
clang::interp::Program::getOrCreateDummy
llvm::Optional< unsigned > getOrCreateDummy(const ParmVarDecl *PD)
Returns or creates a dummy value for parameters.
Definition: Program.cpp:137
IsStatic
bool IsStatic
Definition: Format.cpp:2441
clang::interp::Descriptor
Describes a memory block created by an allocation site.
Definition: Descriptor.h:51
clang::interp::Program::Program
Program(Context &Ctx)
Definition: Program.h:42
clang
Definition: CalledOnceCheck.h:17
clang::interp::Program::createFunction
Function * createFunction(const FunctionDecl *Def, Ts &&... Args)
Creates a new function from a code range.
Definition: Program.h:79
Function.h
clang::interp::Function
Bytecode function.
Definition: Function.h:59
clang::DeclaratorContext::Block
@ Block
unsigned
clang::interp::DeclTy
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:26
clang::interp::Program::createGlobalString
unsigned createGlobalString(const StringLiteral *S)
Emits a string literal among global data.
Definition: Program.cpp:36
clang::interp::Program
The program contains and links the bytecode for all functions.
Definition: Program.h:40
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::interp::Program::createGlobal
llvm::Optional< unsigned > createGlobal(const ValueDecl *VD)
Creates a global and returns its index.
Definition: Program.cpp:156
clang::interp::Record
Structure/Class descriptor.
Definition: Record.h:23
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1855
clang::RecordDecl
Represents a struct/union/class.
Definition: Decl.h:3866
clang::interp::Program::getNativePointer
const void * getNativePointer(unsigned Idx)
Returns the value of a marshalled native pointer.
Definition: Program.cpp:32
Record.h