Program.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. #ifndef LLVM_CLANG_AST_INTERP_PROGRAM_H
  13. #define LLVM_CLANG_AST_INTERP_PROGRAM_H
  14. #include <map>
  15. #include <vector>
  16. #include "Function.h"
  17. #include "Pointer.h"
  18. #include "PrimType.h"
  19. #include "Record.h"
  20. #include "Source.h"
  21. #include "llvm/ADT/DenseMap.h"
  22. #include "llvm/ADT/PointerUnion.h"
  23. #include "llvm/ADT/StringRef.h"
  24. #include "llvm/Support/Allocator.h"
  25. namespace clang {
  26. class RecordDecl;
  27. class Expr;
  28. class FunctionDecl;
  29. class StringLiteral;
  30. class VarDecl;
  31. namespace interp {
  32. class Context;
  33. class Record;
  34. /// The program contains and links the bytecode for all functions.
  35. class Program {
  36. public:
  37. Program(Context &Ctx) : Ctx(Ctx) {}
  38. /// Marshals a native pointer to an ID for embedding in bytecode.
  39. unsigned getOrCreateNativePointer(const void *Ptr);
  40. /// Returns the value of a marshalled native pointer.
  41. const void *getNativePointer(unsigned Idx);
  42. /// Emits a string literal among global data.
  43. unsigned createGlobalString(const StringLiteral *S);
  44. /// Returns a pointer to a global.
  45. Pointer getPtrGlobal(unsigned Idx);
  46. /// Returns the value of a global.
  47. Block *getGlobal(unsigned Idx) {
  48. assert(Idx < Globals.size());
  49. return Globals[Idx]->block();
  50. }
  51. /// Finds a global's index.
  52. llvm::Optional<unsigned> getGlobal(const ValueDecl *VD);
  53. /// Returns or creates a global an creates an index to it.
  54. llvm::Optional<unsigned> getOrCreateGlobal(const ValueDecl *VD);
  55. /// Returns or creates a dummy value for parameters.
  56. llvm::Optional<unsigned> getOrCreateDummy(const ParmVarDecl *PD);
  57. /// Creates a global and returns its index.
  58. llvm::Optional<unsigned> createGlobal(const ValueDecl *VD);
  59. /// Creates a global from a lifetime-extended temporary.
  60. llvm::Optional<unsigned> createGlobal(const Expr *E);
  61. /// Creates a new function from a code range.
  62. template <typename... Ts>
  63. Function *createFunction(const FunctionDecl *Def, Ts &&... Args) {
  64. auto *Func = new Function(*this, Def, std::forward<Ts>(Args)...);
  65. Funcs.insert({Def, std::unique_ptr<Function>(Func)});
  66. return Func;
  67. }
  68. /// Creates an anonymous function.
  69. template <typename... Ts>
  70. Function *createFunction(Ts &&... Args) {
  71. auto *Func = new Function(*this, std::forward<Ts>(Args)...);
  72. AnonFuncs.emplace_back(Func);
  73. return Func;
  74. }
  75. /// Returns a function.
  76. Function *getFunction(const FunctionDecl *F);
  77. /// Returns a pointer to a function if it exists and can be compiled.
  78. /// If a function couldn't be compiled, an error is returned.
  79. /// If a function was not yet defined, a null pointer is returned.
  80. llvm::Expected<Function *> getOrCreateFunction(const FunctionDecl *F);
  81. /// Returns a record or creates one if it does not exist.
  82. Record *getOrCreateRecord(const RecordDecl *RD);
  83. /// Creates a descriptor for a primitive type.
  84. Descriptor *createDescriptor(const DeclTy &D, PrimType Type,
  85. bool IsConst = false,
  86. bool IsTemporary = false,
  87. bool IsMutable = false) {
  88. return allocateDescriptor(D, Type, IsConst, IsTemporary, IsMutable);
  89. }
  90. /// Creates a descriptor for a composite type.
  91. Descriptor *createDescriptor(const DeclTy &D, const Type *Ty,
  92. bool IsConst = false, bool IsTemporary = false,
  93. bool IsMutable = false);
  94. /// Context to manage declaration lifetimes.
  95. class DeclScope {
  96. public:
  97. DeclScope(Program &P, const VarDecl *VD) : P(P) { P.startDeclaration(VD); }
  98. ~DeclScope() { P.endDeclaration(); }
  99. private:
  100. Program &P;
  101. };
  102. /// Returns the current declaration ID.
  103. llvm::Optional<unsigned> getCurrentDecl() const {
  104. if (CurrentDeclaration == NoDeclaration)
  105. return llvm::Optional<unsigned>{};
  106. return LastDeclaration;
  107. }
  108. private:
  109. friend class DeclScope;
  110. llvm::Optional<unsigned> createGlobal(const DeclTy &D, QualType Ty,
  111. bool IsStatic, bool IsExtern);
  112. /// Reference to the VM context.
  113. Context &Ctx;
  114. /// Mapping from decls to cached bytecode functions.
  115. llvm::DenseMap<const FunctionDecl *, std::unique_ptr<Function>> Funcs;
  116. /// List of anonymous functions.
  117. std::vector<std::unique_ptr<Function>> AnonFuncs;
  118. /// Function relocation locations.
  119. llvm::DenseMap<const FunctionDecl *, std::vector<unsigned>> Relocs;
  120. /// Native pointers referenced by bytecode.
  121. std::vector<const void *> NativePointers;
  122. /// Cached native pointer indices.
  123. llvm::DenseMap<const void *, unsigned> NativePointerIndices;
  124. /// Custom allocator for global storage.
  125. using PoolAllocTy = llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator>;
  126. /// Descriptor + storage for a global object.
  127. ///
  128. /// Global objects never go out of scope, thus they do not track pointers.
  129. class Global {
  130. public:
  131. /// Create a global descriptor for string literals.
  132. template <typename... Tys>
  133. Global(Tys... Args) : B(std::forward<Tys>(Args)...) {}
  134. /// Allocates the global in the pool, reserving storate for data.
  135. void *operator new(size_t Meta, PoolAllocTy &Alloc, size_t Data) {
  136. return Alloc.Allocate(Meta + Data, alignof(void *));
  137. }
  138. /// Return a pointer to the data.
  139. char *data() { return B.data(); }
  140. /// Return a pointer to the block.
  141. Block *block() { return &B; }
  142. private:
  143. /// Required metadata - does not actually track pointers.
  144. Block B;
  145. };
  146. /// Allocator for globals.
  147. PoolAllocTy Allocator;
  148. /// Global objects.
  149. std::vector<Global *> Globals;
  150. /// Cached global indices.
  151. llvm::DenseMap<const void *, unsigned> GlobalIndices;
  152. /// Mapping from decls to record metadata.
  153. llvm::DenseMap<const RecordDecl *, Record *> Records;
  154. /// Dummy parameter to generate pointers from.
  155. llvm::DenseMap<const ParmVarDecl *, unsigned> DummyParams;
  156. /// Creates a new descriptor.
  157. template <typename... Ts>
  158. Descriptor *allocateDescriptor(Ts &&... Args) {
  159. return new (Allocator) Descriptor(std::forward<Ts>(Args)...);
  160. }
  161. /// No declaration ID.
  162. static constexpr unsigned NoDeclaration = (unsigned)-1;
  163. /// Last declaration ID.
  164. unsigned LastDeclaration = 0;
  165. /// Current declaration ID.
  166. unsigned CurrentDeclaration = NoDeclaration;
  167. /// Starts evaluating a declaration.
  168. void startDeclaration(const VarDecl *Decl) {
  169. LastDeclaration += 1;
  170. CurrentDeclaration = LastDeclaration;
  171. }
  172. /// Ends a global declaration.
  173. void endDeclaration() {
  174. CurrentDeclaration = NoDeclaration;
  175. }
  176. public:
  177. /// Dumps the disassembled bytecode to \c llvm::errs().
  178. void dump() const;
  179. void dump(llvm::raw_ostream &OS) const;
  180. };
  181. } // namespace interp
  182. } // namespace clang
  183. #endif