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