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