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
,
58 BI_FIELD_TYPE_BLOCK_ID
,
59 BI_MEMBER_TYPE_BLOCK_ID
,
61 BI_BASE_RECORD_BLOCK_ID
,
64 BI_REFERENCE_BLOCK_ID
,
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.
112 BASE_RECORD_TAG_TYPE
,
113 BASE_RECORD_IS_VIRTUAL
,
115 BASE_RECORD_IS_PARENT
,
120 REFERENCE_IS_IN_GLOBAL_NAMESPACE
,
126 static constexpr unsigned BlockIdCount
= BI_LAST
- BI_FIRST
;
127 static constexpr unsigned RecordIdCount
= RI_LAST
- RI_FIRST
;
129 // Identifiers for differentiating between subblocks
140 class ClangDocBitcodeWriter
{
142 ClangDocBitcodeWriter(llvm::BitstreamWriter
&Stream
) : Stream(Stream
) {
144 emitBlockInfoBlock();
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
);
164 class AbbreviationMap
{
165 llvm::DenseMap
<unsigned, unsigned> Abbrevs
;
168 AbbreviationMap() : Abbrevs(RecordIdCount
) {}
170 void add(RecordId RID
, unsigned AbbrevID
);
171 unsigned get(RecordId RID
) const;
174 class StreamSubBlockGuard
{
175 llvm::BitstreamWriter
&Stream
;
178 StreamSubBlockGuard(llvm::BitstreamWriter
&Stream_
, BlockId ID
)
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.
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
;
222 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_BITCODEWRITER_H