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 | |
15 | #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H |
16 | #define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H |
17 | |
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> |
26 | |
27 | namespace clang { |
28 | namespace doc { |
29 | |
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; |
34 | |
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; |
49 | }; |
50 | |
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_ENUM_VALUE_BLOCK_ID, |
58 | BI_TYPE_BLOCK_ID, |
59 | BI_FIELD_TYPE_BLOCK_ID, |
60 | BI_MEMBER_TYPE_BLOCK_ID, |
61 | BI_RECORD_BLOCK_ID, |
62 | BI_BASE_RECORD_BLOCK_ID, |
63 | BI_FUNCTION_BLOCK_ID, |
64 | BI_COMMENT_BLOCK_ID, |
65 | BI_REFERENCE_BLOCK_ID, |
66 | BI_TEMPLATE_BLOCK_ID, |
67 | BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, |
68 | BI_TEMPLATE_PARAM_BLOCK_ID, |
69 | BI_TYPEDEF_BLOCK_ID, |
70 | BI_LAST, |
71 | BI_FIRST = BI_VERSION_BLOCK_ID |
72 | }; |
73 | |
74 | // New Ids need to be added to the enum here, and to the relevant IdNameMap and |
75 | // initialization list in the implementation file. |
76 | enum RecordId { |
77 | VERSION = 1, |
78 | FUNCTION_USR, |
79 | FUNCTION_NAME, |
80 | FUNCTION_DEFLOCATION, |
81 | FUNCTION_LOCATION, |
82 | FUNCTION_ACCESS, |
83 | FUNCTION_IS_METHOD, |
84 | FUNCTION_IS_STATIC, |
85 | COMMENT_KIND, |
86 | COMMENT_TEXT, |
87 | COMMENT_NAME, |
88 | COMMENT_DIRECTION, |
89 | COMMENT_PARAMNAME, |
90 | COMMENT_CLOSENAME, |
91 | COMMENT_SELFCLOSING, |
92 | COMMENT_EXPLICIT, |
93 | COMMENT_ATTRKEY, |
94 | COMMENT_ATTRVAL, |
95 | COMMENT_ARG, |
96 | FIELD_TYPE_NAME, |
97 | FIELD_DEFAULT_VALUE, |
98 | MEMBER_TYPE_NAME, |
99 | MEMBER_TYPE_ACCESS, |
100 | MEMBER_TYPE_IS_STATIC, |
101 | NAMESPACE_USR, |
102 | NAMESPACE_NAME, |
103 | NAMESPACE_PATH, |
104 | ENUM_USR, |
105 | ENUM_NAME, |
106 | ENUM_DEFLOCATION, |
107 | ENUM_LOCATION, |
108 | ENUM_SCOPED, |
109 | ENUM_VALUE_NAME, |
110 | ENUM_VALUE_VALUE, |
111 | ENUM_VALUE_EXPR, |
112 | RECORD_USR, |
113 | RECORD_NAME, |
114 | RECORD_PATH, |
115 | RECORD_DEFLOCATION, |
116 | RECORD_LOCATION, |
117 | RECORD_TAG_TYPE, |
118 | RECORD_IS_TYPE_DEF, |
119 | BASE_RECORD_USR, |
120 | BASE_RECORD_NAME, |
121 | BASE_RECORD_PATH, |
122 | BASE_RECORD_TAG_TYPE, |
123 | BASE_RECORD_IS_VIRTUAL, |
124 | BASE_RECORD_ACCESS, |
125 | BASE_RECORD_IS_PARENT, |
126 | REFERENCE_USR, |
127 | REFERENCE_NAME, |
128 | REFERENCE_QUAL_NAME, |
129 | REFERENCE_TYPE, |
130 | REFERENCE_PATH, |
131 | REFERENCE_FIELD, |
132 | TEMPLATE_PARAM_CONTENTS, |
133 | TEMPLATE_SPECIALIZATION_OF, |
134 | TYPEDEF_USR, |
135 | TYPEDEF_NAME, |
136 | TYPEDEF_DEFLOCATION, |
137 | TYPEDEF_IS_USING, |
138 | RI_LAST, |
139 | RI_FIRST = VERSION |
140 | }; |
141 | |
142 | static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST; |
143 | static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST; |
144 | |
145 | // Identifiers for differentiating between subblocks |
146 | enum class FieldId { |
147 | F_default, |
148 | F_namespace, |
149 | F_parent, |
150 | F_vparent, |
151 | F_type, |
152 | F_child_namespace, |
153 | F_child_record |
154 | }; |
155 | |
156 | class ClangDocBitcodeWriter { |
157 | public: |
158 | ClangDocBitcodeWriter(llvm::BitstreamWriter &Stream) : Stream(Stream) { |
159 | emitHeader(); |
160 | emitBlockInfoBlock(); |
161 | emitVersionBlock(); |
162 | } |
163 | |
164 | // Write a specific info to a bitcode stream. |
165 | bool dispatchInfoForWrite(Info *I); |
166 | |
167 | // Block emission of different info types. |
168 | void emitBlock(const NamespaceInfo &I); |
169 | void emitBlock(const RecordInfo &I); |
170 | void emitBlock(const BaseRecordInfo &I); |
171 | void emitBlock(const FunctionInfo &I); |
172 | void emitBlock(const EnumInfo &I); |
173 | void emitBlock(const EnumValueInfo &I); |
174 | void emitBlock(const TypeInfo &B); |
175 | void emitBlock(const TypedefInfo &B); |
176 | void emitBlock(const FieldTypeInfo &B); |
177 | void emitBlock(const MemberTypeInfo &T); |
178 | void emitBlock(const CommentInfo &B); |
179 | void emitBlock(const TemplateInfo &T); |
180 | void emitBlock(const TemplateSpecializationInfo &T); |
181 | void emitBlock(const TemplateParamInfo &T); |
182 | void emitBlock(const Reference &B, FieldId F); |
183 | |
184 | private: |
185 | class AbbreviationMap { |
186 | llvm::DenseMap<unsigned, unsigned> Abbrevs; |
187 | |
188 | public: |
189 | AbbreviationMap() : Abbrevs(RecordIdCount) {} |
190 | |
191 | void add(RecordId RID, unsigned AbbrevID); |
192 | unsigned get(RecordId RID) const; |
193 | }; |
194 | |
195 | class StreamSubBlockGuard { |
196 | llvm::BitstreamWriter &Stream; |
197 | |
198 | public: |
199 | StreamSubBlockGuard(llvm::BitstreamWriter &Stream_, BlockId ID) |
200 | : Stream(Stream_) { |
201 | // NOTE: SubBlockIDSize could theoretically be calculated on the fly, |
202 | // based on the initialization list of records in each block. |
203 | Stream.EnterSubblock(BlockID: ID, CodeLen: BitCodeConstants::SubblockIDSize); |
204 | } |
205 | |
206 | StreamSubBlockGuard(const StreamSubBlockGuard &) = delete; |
207 | StreamSubBlockGuard &operator=(const StreamSubBlockGuard &) = delete; |
208 | |
209 | ~StreamSubBlockGuard() { Stream.ExitBlock(); } |
210 | }; |
211 | |
212 | // Emission of validation and overview blocks. |
213 | void emitHeader(); |
214 | void emitVersionBlock(); |
215 | void emitRecordID(RecordId ID); |
216 | void emitBlockID(BlockId ID); |
217 | void emitBlockInfoBlock(); |
218 | void emitBlockInfo(BlockId BID, const std::vector<RecordId> &RIDs); |
219 | |
220 | // Emission of individual record types. |
221 | void emitRecord(StringRef Str, RecordId ID); |
222 | void emitRecord(const SymbolID &Str, RecordId ID); |
223 | void emitRecord(const Location &Loc, RecordId ID); |
224 | void emitRecord(const Reference &Ref, RecordId ID); |
225 | void emitRecord(bool Value, RecordId ID); |
226 | void emitRecord(int Value, RecordId ID); |
227 | void emitRecord(unsigned Value, RecordId ID); |
228 | void emitRecord(const TemplateInfo &Templ); |
229 | bool prepRecordData(RecordId ID, bool ShouldEmit = true); |
230 | |
231 | // Emission of appropriate abbreviation type. |
232 | void emitAbbrev(RecordId ID, BlockId Block); |
233 | |
234 | // Static size is the maximum length of the block/record names we're pushing |
235 | // to this + 1. Longest is currently `MemberTypeBlock` at 15 chars. |
236 | SmallVector<uint32_t, BitCodeConstants::RecordSize> Record; |
237 | llvm::BitstreamWriter &Stream; |
238 | AbbreviationMap Abbrevs; |
239 | }; |
240 | |
241 | } // namespace doc |
242 | } // namespace clang |
243 | |
244 | #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H |
245 |
Definitions
- VersionNumber
- BitCodeConstants
- RecordSize
- SignatureBitSize
- SubblockIDSize
- BoolSize
- IntSize
- StringLengthSize
- FilenameLengthSize
- LineNumberSize
- ReferenceTypeSize
- USRLengthSize
- USRBitLengthSize
- Signature
- USRHashSize
- BlockId
- RecordId
- BlockIdCount
- RecordIdCount
- FieldId
- ClangDocBitcodeWriter
- ClangDocBitcodeWriter
- AbbreviationMap
- AbbreviationMap
- StreamSubBlockGuard
- StreamSubBlockGuard
- StreamSubBlockGuard
- operator=
Improve your Profiling and Debugging skills
Find out more