1 //===-- BitcodeWriter.h - ClangDoc Bitcode Writer --------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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>
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.
54 BI_VERSION_BLOCK_ID
= llvm::bitc::FIRST_APPLICATION_BLOCKID
,
55 BI_NAMESPACE_BLOCK_ID
,
57 BI_ENUM_VALUE_BLOCK_ID
,
59 BI_FIELD_TYPE_BLOCK_ID
,
60 BI_MEMBER_TYPE_BLOCK_ID
,
62 BI_BASE_RECORD_BLOCK_ID
,
65 BI_REFERENCE_BLOCK_ID
,
67 BI_TEMPLATE_SPECIALIZATION_BLOCK_ID
,
68 BI_TEMPLATE_PARAM_BLOCK_ID
,
71 BI_FIRST
= BI_VERSION_BLOCK_ID
74 // New Ids need to be added to the enum here, and to the relevant IdNameMap and
75 // initialization list in the implementation file.
120 BASE_RECORD_TAG_TYPE
,
121 BASE_RECORD_IS_VIRTUAL
,
123 BASE_RECORD_IS_PARENT
,
130 TEMPLATE_PARAM_CONTENTS
,
131 TEMPLATE_SPECIALIZATION_OF
,
140 static constexpr unsigned BlockIdCount
= BI_LAST
- BI_FIRST
;
141 static constexpr unsigned RecordIdCount
= RI_LAST
- RI_FIRST
;
143 // Identifiers for differentiating between subblocks
154 class ClangDocBitcodeWriter
{
156 ClangDocBitcodeWriter(llvm::BitstreamWriter
&Stream
) : Stream(Stream
) {
158 emitBlockInfoBlock();
162 // Write a specific info to a bitcode stream.
163 bool dispatchInfoForWrite(Info
*I
);
165 // Block emission of different info types.
166 void emitBlock(const NamespaceInfo
&I
);
167 void emitBlock(const RecordInfo
&I
);
168 void emitBlock(const BaseRecordInfo
&I
);
169 void emitBlock(const FunctionInfo
&I
);
170 void emitBlock(const EnumInfo
&I
);
171 void emitBlock(const EnumValueInfo
&I
);
172 void emitBlock(const TypeInfo
&B
);
173 void emitBlock(const TypedefInfo
&B
);
174 void emitBlock(const FieldTypeInfo
&B
);
175 void emitBlock(const MemberTypeInfo
&T
);
176 void emitBlock(const CommentInfo
&B
);
177 void emitBlock(const TemplateInfo
&T
);
178 void emitBlock(const TemplateSpecializationInfo
&T
);
179 void emitBlock(const TemplateParamInfo
&T
);
180 void emitBlock(const Reference
&B
, FieldId F
);
183 class AbbreviationMap
{
184 llvm::DenseMap
<unsigned, unsigned> Abbrevs
;
187 AbbreviationMap() : Abbrevs(RecordIdCount
) {}
189 void add(RecordId RID
, unsigned AbbrevID
);
190 unsigned get(RecordId RID
) const;
193 class StreamSubBlockGuard
{
194 llvm::BitstreamWriter
&Stream
;
197 StreamSubBlockGuard(llvm::BitstreamWriter
&Stream_
, BlockId ID
)
199 // NOTE: SubBlockIDSize could theoretically be calculated on the fly,
200 // based on the initialization list of records in each block.
201 Stream
.EnterSubblock(ID
, BitCodeConstants::SubblockIDSize
);
204 StreamSubBlockGuard(const StreamSubBlockGuard
&) = delete;
205 StreamSubBlockGuard
&operator=(const StreamSubBlockGuard
&) = delete;
207 ~StreamSubBlockGuard() { Stream
.ExitBlock(); }
210 // Emission of validation and overview blocks.
212 void emitVersionBlock();
213 void emitRecordID(RecordId ID
);
214 void emitBlockID(BlockId ID
);
215 void emitBlockInfoBlock();
216 void emitBlockInfo(BlockId BID
, const std::vector
<RecordId
> &RIDs
);
218 // Emission of individual record types.
219 void emitRecord(StringRef Str
, RecordId ID
);
220 void emitRecord(const SymbolID
&Str
, RecordId ID
);
221 void emitRecord(const Location
&Loc
, RecordId ID
);
222 void emitRecord(const Reference
&Ref
, RecordId ID
);
223 void emitRecord(bool Value
, RecordId ID
);
224 void emitRecord(int Value
, RecordId ID
);
225 void emitRecord(unsigned Value
, RecordId ID
);
226 void emitRecord(const TemplateInfo
&Templ
);
227 bool prepRecordData(RecordId ID
, bool ShouldEmit
= true);
229 // Emission of appropriate abbreviation type.
230 void emitAbbrev(RecordId ID
, BlockId Block
);
232 // Static size is the maximum length of the block/record names we're pushing
233 // to this + 1. Longest is currently `MemberTypeBlock` at 15 chars.
234 SmallVector
<uint32_t, BitCodeConstants::RecordSize
> Record
;
235 llvm::BitstreamWriter
&Stream
;
236 AbbreviationMap Abbrevs
;
242 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H