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
27namespace clang {
28namespace 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.
33static const unsigned VersionNumber = 3;
34
35struct 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.
53enum 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.
76enum 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
142static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST;
143static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST;
144
145// Identifiers for differentiating between subblocks
146enum 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
156class ClangDocBitcodeWriter {
157public:
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
184private:
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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang-tools-extra/clang-doc/BitcodeWriter.h