BitcodeWriter.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. //===-- BitcodeWriter.h - ClangDoc Bitcode Writer --------------*- 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. // This file implements a writer for serializing the clang-doc internal
  10. // representation to LLVM bitcode. The writer takes in a stream and emits the
  11. // generated bitcode to that stream.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H
  15. #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H
  16. #include "Representation.h"
  17. #include "clang/AST/AST.h"
  18. #include "llvm/ADT/DenseMap.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/Bitstream/BitstreamWriter.h"
  22. #include <initializer_list>
  23. #include <vector>
  24. namespace clang {
  25. namespace doc {
  26. // Current version number of clang-doc bitcode.
  27. // Should be bumped when removing or changing BlockIds, RecordIds, or
  28. // BitCodeConstants, though they can be added without breaking it.
  29. static const unsigned VersionNumber = 3;
  30. struct BitCodeConstants {
  31. static constexpr unsigned RecordSize = 32U;
  32. static constexpr unsigned SignatureBitSize = 8U;
  33. static constexpr unsigned SubblockIDSize = 4U;
  34. static constexpr unsigned BoolSize = 1U;
  35. static constexpr unsigned IntSize = 16U;
  36. static constexpr unsigned StringLengthSize = 16U;
  37. static constexpr unsigned FilenameLengthSize = 16U;
  38. static constexpr unsigned LineNumberSize = 32U;
  39. static constexpr unsigned ReferenceTypeSize = 8U;
  40. static constexpr unsigned USRLengthSize = 6U;
  41. static constexpr unsigned USRBitLengthSize = 8U;
  42. static constexpr unsigned char Signature[4] = {'D', 'O', 'C', 'S'};
  43. static constexpr int USRHashSize = 20;
  44. };
  45. // New Ids need to be added to both the enum here and the relevant IdNameMap in
  46. // the implementation file.
  47. enum BlockId {
  48. BI_VERSION_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
  49. BI_NAMESPACE_BLOCK_ID,
  50. BI_ENUM_BLOCK_ID,
  51. BI_ENUM_VALUE_BLOCK_ID,
  52. BI_TYPE_BLOCK_ID,
  53. BI_FIELD_TYPE_BLOCK_ID,
  54. BI_MEMBER_TYPE_BLOCK_ID,
  55. BI_RECORD_BLOCK_ID,
  56. BI_BASE_RECORD_BLOCK_ID,
  57. BI_FUNCTION_BLOCK_ID,
  58. BI_COMMENT_BLOCK_ID,
  59. BI_REFERENCE_BLOCK_ID,
  60. BI_TEMPLATE_BLOCK_ID,
  61. BI_TEMPLATE_SPECIALIZATION_BLOCK_ID,
  62. BI_TEMPLATE_PARAM_BLOCK_ID,
  63. BI_TYPEDEF_BLOCK_ID,
  64. BI_LAST,
  65. BI_FIRST = BI_VERSION_BLOCK_ID
  66. };
  67. // New Ids need to be added to the enum here, and to the relevant IdNameMap and
  68. // initialization list in the implementation file.
  69. enum RecordId {
  70. VERSION = 1,
  71. FUNCTION_USR,
  72. FUNCTION_NAME,
  73. FUNCTION_DEFLOCATION,
  74. FUNCTION_LOCATION,
  75. FUNCTION_ACCESS,
  76. FUNCTION_IS_METHOD,
  77. COMMENT_KIND,
  78. COMMENT_TEXT,
  79. COMMENT_NAME,
  80. COMMENT_DIRECTION,
  81. COMMENT_PARAMNAME,
  82. COMMENT_CLOSENAME,
  83. COMMENT_SELFCLOSING,
  84. COMMENT_EXPLICIT,
  85. COMMENT_ATTRKEY,
  86. COMMENT_ATTRVAL,
  87. COMMENT_ARG,
  88. FIELD_TYPE_NAME,
  89. FIELD_DEFAULT_VALUE,
  90. MEMBER_TYPE_NAME,
  91. MEMBER_TYPE_ACCESS,
  92. NAMESPACE_USR,
  93. NAMESPACE_NAME,
  94. NAMESPACE_PATH,
  95. ENUM_USR,
  96. ENUM_NAME,
  97. ENUM_DEFLOCATION,
  98. ENUM_LOCATION,
  99. ENUM_SCOPED,
  100. ENUM_VALUE_NAME,
  101. ENUM_VALUE_VALUE,
  102. ENUM_VALUE_EXPR,
  103. RECORD_USR,
  104. RECORD_NAME,
  105. RECORD_PATH,
  106. RECORD_DEFLOCATION,
  107. RECORD_LOCATION,
  108. RECORD_TAG_TYPE,
  109. RECORD_IS_TYPE_DEF,
  110. BASE_RECORD_USR,
  111. BASE_RECORD_NAME,
  112. BASE_RECORD_PATH,
  113. BASE_RECORD_TAG_TYPE,
  114. BASE_RECORD_IS_VIRTUAL,
  115. BASE_RECORD_ACCESS,
  116. BASE_RECORD_IS_PARENT,
  117. REFERENCE_USR,
  118. REFERENCE_NAME,
  119. REFERENCE_QUAL_NAME,
  120. REFERENCE_TYPE,
  121. REFERENCE_PATH,
  122. REFERENCE_FIELD,
  123. TEMPLATE_PARAM_CONTENTS,
  124. TEMPLATE_SPECIALIZATION_OF,
  125. TYPEDEF_USR,
  126. TYPEDEF_NAME,
  127. TYPEDEF_DEFLOCATION,
  128. TYPEDEF_IS_USING,
  129. RI_LAST,
  130. RI_FIRST = VERSION
  131. };
  132. static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST;
  133. static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST;
  134. // Identifiers for differentiating between subblocks
  135. enum class FieldId {
  136. F_default,
  137. F_namespace,
  138. F_parent,
  139. F_vparent,
  140. F_type,
  141. F_child_namespace,
  142. F_child_record
  143. };
  144. class ClangDocBitcodeWriter {
  145. public:
  146. ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream) : Stream(Stream) {
  147. emitHeader();
  148. emitBlockInfoBlock();
  149. emitVersionBlock();
  150. }
  151. // Write a specific info to a bitcode stream.
  152. bool dispatchInfoForWrite(Info *I);
  153. // Block emission of different info types.
  154. void emitBlock(const NamespaceInfo &I);
  155. void emitBlock(const RecordInfo &I);
  156. void emitBlock(const BaseRecordInfo &I);
  157. void emitBlock(const FunctionInfo &I);
  158. void emitBlock(const EnumInfo &I);
  159. void emitBlock(const EnumValueInfo &I);
  160. void emitBlock(const TypeInfo &B);
  161. void emitBlock(const TypedefInfo &B);
  162. void emitBlock(const FieldTypeInfo &B);
  163. void emitBlock(const MemberTypeInfo &T);
  164. void emitBlock(const CommentInfo &B);
  165. void emitBlock(const TemplateInfo &T);
  166. void emitBlock(const TemplateSpecializationInfo &T);
  167. void emitBlock(const TemplateParamInfo &T);
  168. void emitBlock(const Reference &B, FieldId F);
  169. private:
  170. class AbbreviationMap {
  171. llvm::DenseMap<unsigned, unsigned> Abbrevs;
  172. public:
  173. AbbreviationMap() : Abbrevs(RecordIdCount) {}
  174. void add(RecordId RID, unsigned AbbrevID);
  175. unsigned get(RecordId RID) const;
  176. };
  177. class StreamSubBlockGuard {
  178. llvm::BitstreamWriter &Stream;
  179. public:
  180. StreamSubBlockGuard(llvm::BitstreamWriter &Stream_, BlockId ID)
  181. : Stream(Stream_) {
  182. // NOTE: SubBlockIDSize could theoretically be calculated on the fly,
  183. // based on the initialization list of records in each block.
  184. Stream.EnterSubblock(ID, BitCodeConstants::SubblockIDSize);
  185. }
  186. StreamSubBlockGuard(const StreamSubBlockGuard &) = delete;
  187. StreamSubBlockGuard &operator=(const StreamSubBlockGuard &) = delete;
  188. ~StreamSubBlockGuard() { Stream.ExitBlock(); }
  189. };
  190. // Emission of validation and overview blocks.
  191. void emitHeader();
  192. void emitVersionBlock();
  193. void emitRecordID(RecordId ID);
  194. void emitBlockID(BlockId ID);
  195. void emitBlockInfoBlock();
  196. void emitBlockInfo(BlockId BID, const std::vector<RecordId> &RIDs);
  197. // Emission of individual record types.
  198. void emitRecord(StringRef Str, RecordId ID);
  199. void emitRecord(const SymbolID &Str, RecordId ID);
  200. void emitRecord(const Location &Loc, RecordId ID);
  201. void emitRecord(const Reference &Ref, RecordId ID);
  202. void emitRecord(bool Value, RecordId ID);
  203. void emitRecord(int Value, RecordId ID);
  204. void emitRecord(unsigned Value, RecordId ID);
  205. void emitRecord(const TemplateInfo &Templ);
  206. bool prepRecordData(RecordId ID, bool ShouldEmit = true);
  207. // Emission of appropriate abbreviation type.
  208. void emitAbbrev(RecordId ID, BlockId Block);
  209. // Static size is the maximum length of the block/record names we're pushing
  210. // to this + 1. Longest is currently `MemberTypeBlock` at 15 chars.
  211. SmallVector<uint32_t, BitCodeConstants::RecordSize> Record;
  212. llvm::BitstreamWriter &Stream;
  213. AbbreviationMap Abbrevs;
  214. };
  215. } // namespace doc
  216. } // namespace clang
  217. #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H