Function.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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. #ifndef LLVM_CLANG_AST_INTERP_FUNCTION_H
  15. #define LLVM_CLANG_AST_INTERP_FUNCTION_H
  16. #include "Pointer.h"
  17. #include "Source.h"
  18. #include "clang/AST/Decl.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. namespace clang {
  21. namespace interp {
  22. class Program;
  23. class ByteCodeEmitter;
  24. enum PrimType : uint32_t;
  25. /// Describes a scope block.
  26. ///
  27. /// The block gathers all the descriptors of the locals defined in this block.
  28. class Scope final {
  29. public:
  30. /// Information about a local's storage.
  31. struct Local {
  32. /// Offset of the local in frame.
  33. unsigned Offset;
  34. /// Descriptor of the local.
  35. Descriptor *Desc;
  36. };
  37. using LocalVectorTy = llvm::SmallVector<Local, 8>;
  38. Scope(LocalVectorTy &&Descriptors) : Descriptors(std::move(Descriptors)) {}
  39. llvm::iterator_range<LocalVectorTy::const_iterator> locals() const {
  40. return llvm::make_range(Descriptors.begin(), Descriptors.end());
  41. }
  42. private:
  43. /// Object descriptors in this block.
  44. LocalVectorTy Descriptors;
  45. };
  46. /// Bytecode function.
  47. ///
  48. /// Contains links to the bytecode of the function, as well as metadata
  49. /// describing all arguments and stack-local variables.
  50. ///
  51. /// # Calling Convention
  52. ///
  53. /// When calling a function, all argument values must be on the stack.
  54. ///
  55. /// If the function has a This pointer (i.e. hasThisPointer() returns true,
  56. /// the argument values need to be preceeded by a Pointer for the This object.
  57. ///
  58. /// If the function uses Return Value Optimization, the arguments (and
  59. /// potentially the This pointer) need to be proceeded by a Pointer pointing
  60. /// to the location to construct the returned value.
  61. ///
  62. /// After the function has been called, it will remove all arguments,
  63. /// including RVO and This pointer, from the stack.
  64. ///
  65. class Function final {
  66. public:
  67. using ParamDescriptor = std::pair<PrimType, Descriptor *>;
  68. /// Returns the size of the function's local stack.
  69. unsigned getFrameSize() const { return FrameSize; }
  70. /// Returns the size of the argument stack.
  71. unsigned getArgSize() const { return ArgSize; }
  72. /// Returns a pointer to the start of the code.
  73. CodePtr getCodeBegin() const { return Code.data(); }
  74. /// Returns a pointer to the end of the code.
  75. CodePtr getCodeEnd() const { return Code.data() + Code.size(); }
  76. /// Returns the original FunctionDecl.
  77. const FunctionDecl *getDecl() const { return F; }
  78. /// Returns the name of the function decl this code
  79. /// was generated for.
  80. const std::string getName() const { return F->getNameInfo().getAsString(); }
  81. /// Returns the location.
  82. SourceLocation getLoc() const { return Loc; }
  83. /// Returns a parameter descriptor.
  84. ParamDescriptor getParamDescriptor(unsigned Offset) const;
  85. /// Checks if the first argument is a RVO pointer.
  86. bool hasRVO() const { return HasRVO; }
  87. /// Range over the scope blocks.
  88. llvm::iterator_range<llvm::SmallVector<Scope, 2>::const_iterator>
  89. scopes() const {
  90. return llvm::make_range(Scopes.begin(), Scopes.end());
  91. }
  92. /// Range over argument types.
  93. using arg_reverse_iterator =
  94. SmallVectorImpl<PrimType>::const_reverse_iterator;
  95. llvm::iterator_range<arg_reverse_iterator> args_reverse() const {
  96. return llvm::reverse(ParamTypes);
  97. }
  98. /// Returns a specific scope.
  99. Scope &getScope(unsigned Idx) { return Scopes[Idx]; }
  100. const Scope &getScope(unsigned Idx) const { return Scopes[Idx]; }
  101. /// Returns the source information at a given PC.
  102. SourceInfo getSource(CodePtr PC) const;
  103. /// Checks if the function is valid to call in constexpr.
  104. bool isConstexpr() const { return IsValid; }
  105. /// Checks if the function is virtual.
  106. bool isVirtual() const;
  107. /// Checks if the function is a constructor.
  108. bool isConstructor() const { return isa<CXXConstructorDecl>(F); }
  109. /// Checks if the function is fully done compiling.
  110. bool isFullyCompiled() const { return IsFullyCompiled; }
  111. bool hasThisPointer() const { return HasThisPointer; }
  112. // Checks if the funtion already has a body attached.
  113. bool hasBody() const { return HasBody; }
  114. unsigned getNumParams() const { return ParamTypes.size(); }
  115. private:
  116. /// Construct a function representing an actual function.
  117. Function(Program &P, const FunctionDecl *F, unsigned ArgSize,
  118. llvm::SmallVector<PrimType, 8> &&ParamTypes,
  119. llvm::DenseMap<unsigned, ParamDescriptor> &&Params,
  120. bool HasThisPointer, bool HasRVO);
  121. /// Sets the code of a function.
  122. void setCode(unsigned NewFrameSize, std::vector<char> &&NewCode, SourceMap &&NewSrcMap,
  123. llvm::SmallVector<Scope, 2> &&NewScopes) {
  124. FrameSize = NewFrameSize;
  125. Code = std::move(NewCode);
  126. SrcMap = std::move(NewSrcMap);
  127. Scopes = std::move(NewScopes);
  128. IsValid = true;
  129. HasBody = true;
  130. }
  131. void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
  132. private:
  133. friend class Program;
  134. friend class ByteCodeEmitter;
  135. /// Program reference.
  136. Program &P;
  137. /// Location of the executed code.
  138. SourceLocation Loc;
  139. /// Declaration this function was compiled from.
  140. const FunctionDecl *F;
  141. /// Local area size: storage + metadata.
  142. unsigned FrameSize = 0;
  143. /// Size of the argument stack.
  144. unsigned ArgSize;
  145. /// Program code.
  146. std::vector<char> Code;
  147. /// Opcode-to-expression mapping.
  148. SourceMap SrcMap;
  149. /// List of block descriptors.
  150. llvm::SmallVector<Scope, 2> Scopes;
  151. /// List of argument types.
  152. llvm::SmallVector<PrimType, 8> ParamTypes;
  153. /// Map from byte offset to parameter descriptor.
  154. llvm::DenseMap<unsigned, ParamDescriptor> Params;
  155. /// Flag to indicate if the function is valid.
  156. bool IsValid = false;
  157. /// Flag to indicate if the function is done being
  158. /// compiled to bytecode.
  159. bool IsFullyCompiled = false;
  160. /// Flag indicating if this function takes the this pointer
  161. /// as the first implicit argument
  162. bool HasThisPointer = false;
  163. /// Whether this function has Return Value Optimization, i.e.
  164. /// the return value is constructed in the caller's stack frame.
  165. /// This is done for functions that return non-primive values.
  166. bool HasRVO = false;
  167. /// If we've already compiled the function's body.
  168. bool HasBody = false;
  169. public:
  170. /// Dumps the disassembled bytecode to \c llvm::errs().
  171. void dump() const;
  172. void dump(llvm::raw_ostream &OS) const;
  173. };
  174. } // namespace interp
  175. } // namespace clang
  176. #endif