clang-tools 23.0.0git
BitcodeWriter.cpp
Go to the documentation of this file.
1//===-- BitcodeWriter.cpp - 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#include "BitcodeWriter.h"
10#include "llvm/ADT/IndexedMap.h"
11#include <initializer_list>
12
13using namespace clang;
14using namespace clang::doc;
15using namespace llvm;
16
17namespace {
18
19// Empty SymbolID for comparison, so we don't have to construct one every time.
20static const SymbolID EmptySID = SymbolID();
21
22// Since id enums are not zero-indexed, we need to transform the given id into
23// its associated index.
24struct BlockIdToIndexFunctor {
25 using argument_type = unsigned;
26 unsigned operator()(unsigned ID) const { return ID - BI_FIRST; }
27};
28
29struct RecordIdToIndexFunctor {
30 using argument_type = unsigned;
31 unsigned operator()(unsigned ID) const { return ID - RI_FIRST; }
32};
33
34using AbbrevDsc = void (*)(std::shared_ptr<BitCodeAbbrev> &Abbrev);
35} // namespace
36
37static void generateAbbrev(std::shared_ptr<BitCodeAbbrev> &Abbrev,
38 const std::initializer_list<BitCodeAbbrevOp> Ops) {
39 for (const auto &Op : Ops)
40 Abbrev->Add(Op);
41}
42
43static void genBoolAbbrev(std::shared_ptr<BitCodeAbbrev> &Abbrev) {
45 Abbrev,
46 {// 0. Boolean
47 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, BitCodeConstants::BoolSize)});
48}
49
50static void genIntAbbrev(std::shared_ptr<BitCodeAbbrev> &Abbrev) {
52 Abbrev,
53 {// 0. Fixed-size integer
54 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, BitCodeConstants::IntSize)});
55}
56
57static void genSymbolIdAbbrev(std::shared_ptr<BitCodeAbbrev> &Abbrev) {
59 Abbrev,
60 {// 0. Fixed-size integer (length of the sha1'd USR)
61 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, BitCodeConstants::USRLengthSize),
62 // 1. Fixed-size array of Char6 (USR)
63 BitCodeAbbrevOp(BitCodeAbbrevOp::Array),
64 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
66}
67
68static void genStringAbbrev(std::shared_ptr<BitCodeAbbrev> &Abbrev) {
69 generateAbbrev(Abbrev,
70 {// 0. Fixed-size integer (length of the following string)
71 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
73 // 1. The string blob
74 BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)});
75}
76
77// Assumes that the file will not have more than 65535 lines.
78static void genLocationAbbrev(std::shared_ptr<BitCodeAbbrev> &Abbrev) {
80 Abbrev,
81 {// 0. Fixed-size integer (line number)
82 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
84 // 1. Fixed-size integer (start line number)
85 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
87 // 2. Boolean (IsFileInRootDir)
88 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, BitCodeConstants::BoolSize),
89 // 3. Fixed-size integer (length of the following string (filename))
90 BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed,
92 // 4. The string blob
93 BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)});
94}
95
96namespace {
97struct RecordIdDsc {
98 RecordIdDsc() = default;
99 constexpr RecordIdDsc(StringRef Name, AbbrevDsc Abbrev)
100 : Name(Name), Abbrev(Abbrev) {}
101
102 // Is this 'description' valid?
103 explicit operator bool() const {
104 return Abbrev != nullptr && Name.data() != nullptr && !Name.empty();
105 }
106
107 StringRef Name;
108 AbbrevDsc Abbrev = nullptr;
109};
110
111static const IndexedMap<StringRef, BlockIdToIndexFunctor> BlockIdNameMap =
112 []() {
113 IndexedMap<StringRef, BlockIdToIndexFunctor> BlockIdNameMap;
114 BlockIdNameMap.resize(BlockIdCount);
115
116 // There is no init-list constructor for the IndexedMap, so have to
117 // improvise
118 static constexpr std::pair<BlockId, StringRef> IdToName[] = {
119 {BI_VERSION_BLOCK_ID, "VersionBlock"},
120 {BI_NAMESPACE_BLOCK_ID, "NamespaceBlock"},
121 {BI_ENUM_BLOCK_ID, "EnumBlock"},
122 {BI_ENUM_VALUE_BLOCK_ID, "EnumValueBlock"},
123 {BI_TYPEDEF_BLOCK_ID, "TypedefBlock"},
124 {BI_TYPE_BLOCK_ID, "TypeBlock"},
125 {BI_FIELD_TYPE_BLOCK_ID, "FieldTypeBlock"},
126 {BI_MEMBER_TYPE_BLOCK_ID, "MemberTypeBlock"},
127 {BI_RECORD_BLOCK_ID, "RecordBlock"},
128 {BI_BASE_RECORD_BLOCK_ID, "BaseRecordBlock"},
129 {BI_FUNCTION_BLOCK_ID, "FunctionBlock"},
130 {BI_COMMENT_BLOCK_ID, "CommentBlock"},
131 {BI_REFERENCE_BLOCK_ID, "ReferenceBlock"},
132 {BI_TEMPLATE_BLOCK_ID, "TemplateBlock"},
133 {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, "TemplateSpecializationBlock"},
134 {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"},
135 {BI_CONSTRAINT_BLOCK_ID, "ConstraintBlock"},
136 {BI_CONCEPT_BLOCK_ID, "ConceptBlock"},
137 {BI_VAR_BLOCK_ID, "VarBlock"},
138 {BI_FRIEND_BLOCK_ID, "FriendBlock"}};
139 ArrayRef<std::pair<BlockId, StringRef>> Inits(IdToName);
140 assert(Inits.size() == BlockIdCount);
141 for (const auto &Init : Inits)
142 BlockIdNameMap[Init.first] = Init.second;
143 assert(BlockIdNameMap.size() == BlockIdCount);
144 return BlockIdNameMap;
145 }();
146
147static const IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> RecordIdNameMap =
148 []() {
149 IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> RecordIdNameMap;
150 RecordIdNameMap.resize(RecordIdCount);
151
152 // There is no init-list constructor for the IndexedMap, so have to
153 // improvise
154 static constexpr std::pair<RecordId, RecordIdDsc> IdToFunc[] = {
155 {VERSION, {"Version", &genIntAbbrev}},
156 {COMMENT_KIND, {"Kind", &genStringAbbrev}},
157 {COMMENT_TEXT, {"Text", &genStringAbbrev}},
158 {COMMENT_NAME, {"Name", &genStringAbbrev}},
159 {COMMENT_DIRECTION, {"Direction", &genStringAbbrev}},
160 {COMMENT_PARAMNAME, {"ParamName", &genStringAbbrev}},
161 {COMMENT_CLOSENAME, {"CloseName", &genStringAbbrev}},
162 {COMMENT_SELFCLOSING, {"SelfClosing", &genBoolAbbrev}},
163 {COMMENT_EXPLICIT, {"Explicit", &genBoolAbbrev}},
164 {COMMENT_ATTRKEY, {"AttrKey", &genStringAbbrev}},
165 {COMMENT_ATTRVAL, {"AttrVal", &genStringAbbrev}},
166 {COMMENT_ARG, {"Arg", &genStringAbbrev}},
167 {FIELD_TYPE_NAME, {"Name", &genStringAbbrev}},
168 {FIELD_DEFAULT_VALUE, {"DefaultValue", &genStringAbbrev}},
169 {FIELD_TYPE_IS_BUILTIN, {"IsBuiltin", &genBoolAbbrev}},
170 {FIELD_TYPE_IS_TEMPLATE, {"IsTemplate", &genBoolAbbrev}},
171 {MEMBER_TYPE_NAME, {"Name", &genStringAbbrev}},
172 {MEMBER_TYPE_ACCESS, {"Access", &genIntAbbrev}},
173 {MEMBER_TYPE_IS_STATIC, {"IsStatic", &genBoolAbbrev}},
174 {MEMBER_TYPE_IS_BUILTIN, {"IsBuiltin", &genBoolAbbrev}},
175 {MEMBER_TYPE_IS_TEMPLATE, {"IsTemplate", &genBoolAbbrev}},
176 {TYPE_IS_BUILTIN, {"IsBuiltin", &genBoolAbbrev}},
177 {TYPE_IS_TEMPLATE, {"IsTemplate", &genBoolAbbrev}},
178 {NAMESPACE_USR, {"USR", &genSymbolIdAbbrev}},
179 {NAMESPACE_NAME, {"Name", &genStringAbbrev}},
180 {NAMESPACE_PATH, {"Path", &genStringAbbrev}},
181 {NAMESPACE_PARENT_USR, {"ParentUSR", &genSymbolIdAbbrev}},
182 {ENUM_USR, {"USR", &genSymbolIdAbbrev}},
183 {ENUM_NAME, {"Name", &genStringAbbrev}},
184 {ENUM_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
185 {ENUM_LOCATION, {"Location", &genLocationAbbrev}},
186 {ENUM_SCOPED, {"Scoped", &genBoolAbbrev}},
187 {ENUM_VALUE_NAME, {"Name", &genStringAbbrev}},
188 {ENUM_VALUE_VALUE, {"Value", &genStringAbbrev}},
189 {ENUM_VALUE_EXPR, {"Expr", &genStringAbbrev}},
190 {RECORD_USR, {"USR", &genSymbolIdAbbrev}},
191 {RECORD_NAME, {"Name", &genStringAbbrev}},
192 {RECORD_PATH, {"Path", &genStringAbbrev}},
193 {RECORD_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
194 {RECORD_LOCATION, {"Location", &genLocationAbbrev}},
195 {RECORD_TAG_TYPE, {"TagType", &genIntAbbrev}},
196 {RECORD_IS_TYPE_DEF, {"IsTypeDef", &genBoolAbbrev}},
197 {RECORD_MANGLED_NAME, {"MangledName", &genStringAbbrev}},
198 {RECORD_PARENT_USR, {"ParentUSR", &genSymbolIdAbbrev}},
200 {BASE_RECORD_NAME, {"Name", &genStringAbbrev}},
201 {BASE_RECORD_PATH, {"Path", &genStringAbbrev}},
202 {BASE_RECORD_TAG_TYPE, {"TagType", &genIntAbbrev}},
203 {BASE_RECORD_IS_VIRTUAL, {"IsVirtual", &genBoolAbbrev}},
204 {BASE_RECORD_ACCESS, {"Access", &genIntAbbrev}},
205 {BASE_RECORD_IS_PARENT, {"IsParent", &genBoolAbbrev}},
206 {FUNCTION_USR, {"USR", &genSymbolIdAbbrev}},
207 {FUNCTION_NAME, {"Name", &genStringAbbrev}},
208 {FUNCTION_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
209 {FUNCTION_LOCATION, {"Location", &genLocationAbbrev}},
210 {FUNCTION_ACCESS, {"Access", &genIntAbbrev}},
211 {FUNCTION_IS_METHOD, {"IsMethod", &genBoolAbbrev}},
212 {FUNCTION_IS_STATIC, {"IsStatic", &genBoolAbbrev}},
213 {REFERENCE_USR, {"USR", &genSymbolIdAbbrev}},
214 {REFERENCE_NAME, {"Name", &genStringAbbrev}},
215 {REFERENCE_QUAL_NAME, {"QualName", &genStringAbbrev}},
216 {REFERENCE_TYPE, {"RefType", &genIntAbbrev}},
217 {REFERENCE_PATH, {"Path", &genStringAbbrev}},
218 {REFERENCE_FIELD, {"Field", &genIntAbbrev}},
219 {REFERENCE_FILE, {"File", &genStringAbbrev}},
222 {"SpecializationOf", &genSymbolIdAbbrev}},
223 {TYPEDEF_USR, {"USR", &genSymbolIdAbbrev}},
224 {TYPEDEF_NAME, {"Name", &genStringAbbrev}},
225 {TYPEDEF_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
226 {TYPEDEF_IS_USING, {"IsUsing", &genBoolAbbrev}},
227 {CONCEPT_USR, {"USR", &genSymbolIdAbbrev}},
228 {CONCEPT_NAME, {"Name", &genStringAbbrev}},
229 {CONCEPT_IS_TYPE, {"IsType", &genBoolAbbrev}},
231 {"ConstraintExpression", &genStringAbbrev}},
232 {CONCEPT_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
233 {CONSTRAINT_EXPRESSION, {"Expression", &genStringAbbrev}},
234 {VAR_USR, {"USR", &genSymbolIdAbbrev}},
235 {VAR_NAME, {"Name", &genStringAbbrev}},
236 {VAR_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
237 {VAR_IS_STATIC, {"IsStatic", &genBoolAbbrev}},
238 {FRIEND_IS_CLASS, {"IsClass", &genBoolAbbrev}}};
239
240 ArrayRef<std::pair<RecordId, RecordIdDsc>> Inits(IdToFunc);
241 assert(Inits.size() == RecordIdCount);
242 for (const auto &Init : Inits) {
243 RecordIdNameMap[Init.first] = Init.second;
244 assert((Init.second.Name.size() + 1) <= BitCodeConstants::RecordSize);
245 }
246 assert(RecordIdNameMap.size() == RecordIdCount);
247 return RecordIdNameMap;
248 }();
249
250struct BlockToIdList {
251 BlockId BID;
252 std::initializer_list<RecordId> RIDs;
253};
254
255static const BlockToIdList RecordsByBlock[] = {
256 // Version Block
258 // Comment Block
263 // Type Block
265 // FieldType Block
269 // MemberType Block
273 // Enum Block
276 // Enum Value Block
279 // Typedef Block
282 // Namespace Block
285 // Record Block
290 // BaseRecord Block
294 // Function Block
298 // Reference Block
302 // Template Blocks.
306 // Concept Block
310 // Constraint Block
314
315} // namespace
316
317namespace clang {
318namespace doc {
319
320// AbbreviationMap
321
322void ClangDocBitcodeWriter::AbbreviationMap::add(RecordId RID,
323 unsigned AbbrevID) {
324 assert(RecordIdNameMap[RID] && "Unknown RecordId.");
325 assert(!Abbrevs.contains(RID) && "Abbreviation already added.");
326 Abbrevs[RID] = AbbrevID;
327}
328
329unsigned ClangDocBitcodeWriter::AbbreviationMap::get(RecordId RID) const {
330 assert(RecordIdNameMap[RID] && "Unknown RecordId.");
331 assert(Abbrevs.contains(RID) && "Unknown abbreviation.");
332 return Abbrevs.lookup(RID);
333}
334
335// Validation and Overview Blocks
336
337/// Emits the magic number header to check that its the right format,
338/// in this case, 'DOCS'.
339void ClangDocBitcodeWriter::emitHeader() {
340 for (char C : BitCodeConstants::Signature)
341 Stream.Emit((unsigned)C, BitCodeConstants::SignatureBitSize);
342}
343
344void ClangDocBitcodeWriter::emitVersionBlock() {
345 StreamSubBlockGuard Block(Stream, BI_VERSION_BLOCK_ID);
346 emitRecord(VersionNumber, VERSION);
347}
348
349/// Emits a block ID and the block name to the BLOCKINFO block.
350void ClangDocBitcodeWriter::emitBlockID(BlockId BID) {
351 const auto &BlockIdName = BlockIdNameMap[BID];
352 assert(BlockIdName.data() && BlockIdName.size() && "Unknown BlockId.");
353
354 Record.clear();
355 Record.push_back(BID);
356 Stream.EmitRecord(bitc::BLOCKINFO_CODE_SETBID, Record);
357 Stream.EmitRecord(bitc::BLOCKINFO_CODE_BLOCKNAME,
358 ArrayRef<unsigned char>(BlockIdName.bytes_begin(),
359 BlockIdName.bytes_end()));
360}
361
362/// Emits a record name to the BLOCKINFO block.
363void ClangDocBitcodeWriter::emitRecordID(RecordId ID) {
364 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
365 prepRecordData(ID);
366 Record.append(RecordIdNameMap[ID].Name.begin(),
367 RecordIdNameMap[ID].Name.end());
368 Stream.EmitRecord(bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
369}
370
371// Abbreviations
372
373void ClangDocBitcodeWriter::emitAbbrev(RecordId ID, BlockId Block) {
374 assert(RecordIdNameMap[ID] && "Unknown abbreviation.");
375 auto Abbrev = std::make_shared<BitCodeAbbrev>();
376 Abbrev->Add(BitCodeAbbrevOp(ID));
377 RecordIdNameMap[ID].Abbrev(Abbrev);
378 Abbrevs.add(ID, Stream.EmitBlockInfoAbbrev(Block, std::move(Abbrev)));
379}
380
381// Records
382
383void ClangDocBitcodeWriter::emitRecord(const SymbolID &Sym, RecordId ID) {
384 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
385 assert(RecordIdNameMap[ID].Abbrev == &genSymbolIdAbbrev &&
386 "Abbrev type mismatch.");
387 if (!prepRecordData(ID, Sym != EmptySID))
388 return;
389 assert(Sym.size() == 20);
390 Record.push_back(Sym.size());
391 Record.append(Sym.begin(), Sym.end());
392 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
393}
394
395void ClangDocBitcodeWriter::emitRecord(StringRef Str, RecordId ID) {
396 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
397 assert(RecordIdNameMap[ID].Abbrev == &genStringAbbrev &&
398 "Abbrev type mismatch.");
399 if (!prepRecordData(ID, !Str.empty()))
400 return;
401 assert(Str.size() < (1U << BitCodeConstants::StringLengthSize));
402 Record.push_back(Str.size());
403 Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Str);
404}
405
406void ClangDocBitcodeWriter::emitRecord(const Location &Loc, RecordId ID) {
407 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
408 assert(RecordIdNameMap[ID].Abbrev == &genLocationAbbrev &&
409 "Abbrev type mismatch.");
410 if (!prepRecordData(ID, true))
411 return;
412 // FIXME: Assert that the line number is of the appropriate size.
413 Record.push_back(Loc.StartLineNumber);
414 Record.push_back(Loc.EndLineNumber);
415 assert(Loc.Filename.size() < (1U << BitCodeConstants::StringLengthSize));
416 Record.push_back(Loc.IsFileInRootDir);
417 Record.push_back(Loc.Filename.size());
418 Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Loc.Filename);
419}
420
421void ClangDocBitcodeWriter::emitRecord(bool Val, RecordId ID) {
422 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
423 assert(RecordIdNameMap[ID].Abbrev == &genBoolAbbrev &&
424 "Abbrev type mismatch.");
425 if (!prepRecordData(ID, Val))
426 return;
427 Record.push_back(Val);
428 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
429}
430
431void ClangDocBitcodeWriter::emitRecord(int Val, RecordId ID) {
432 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
433 assert(RecordIdNameMap[ID].Abbrev == &genIntAbbrev &&
434 "Abbrev type mismatch.");
435 if (!prepRecordData(ID, Val))
436 return;
437 // FIXME: Assert that the integer is of the appropriate size.
438 Record.push_back(Val);
439 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
440}
441
442void ClangDocBitcodeWriter::emitRecord(unsigned Val, RecordId ID) {
443 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
444 assert(RecordIdNameMap[ID].Abbrev == &genIntAbbrev &&
445 "Abbrev type mismatch.");
446 if (!prepRecordData(ID, Val))
447 return;
448 assert(Val < (1U << BitCodeConstants::IntSize));
449 Record.push_back(Val);
450 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
451}
452
453void ClangDocBitcodeWriter::emitRecord(const TemplateInfo &Templ) {}
454
455bool ClangDocBitcodeWriter::prepRecordData(RecordId ID, bool ShouldEmit) {
456 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
457 if (!ShouldEmit)
458 return false;
459 Record.clear();
460 Record.push_back(ID);
461 return true;
462}
463
464// BlockInfo Block
465
466void ClangDocBitcodeWriter::emitBlockInfoBlock() {
467 Stream.EnterBlockInfoBlock();
468 for (const auto &Block : RecordsByBlock) {
469 assert(Block.RIDs.size() < (1U << BitCodeConstants::SubblockIDSize));
470 emitBlockInfo(Block.BID, Block.RIDs);
471 }
472 Stream.ExitBlock();
473}
474
475void ClangDocBitcodeWriter::emitBlockInfo(BlockId BID,
476 ArrayRef<RecordId> RIDs) {
477 assert(RIDs.size() < (1U << BitCodeConstants::SubblockIDSize));
478 emitBlockID(BID);
479 for (RecordId RID : RIDs) {
480 emitRecordID(RID);
481 emitAbbrev(RID, BID);
482 }
483}
484
485// Block emission
486
488 if (R.USR == EmptySID && R.Name.empty())
489 return;
490 StreamSubBlockGuard Block(Stream, BI_REFERENCE_BLOCK_ID);
491 emitRecord(R.USR, REFERENCE_USR);
492 emitRecord(R.Name, REFERENCE_NAME);
493 emitRecord(R.QualName, REFERENCE_QUAL_NAME);
494 emitRecord((unsigned)R.RefType, REFERENCE_TYPE);
495 emitRecord(R.Path, REFERENCE_PATH);
496 emitRecord((unsigned)Field, REFERENCE_FIELD);
498}
499
501 StreamSubBlockGuard Block(Stream, BI_FRIEND_BLOCK_ID);
503 emitRecord(R.IsClass, FRIEND_IS_CLASS);
504 if (R.Template)
506 for (const auto &P : R.Params)
507 emitBlock(P);
508 if (R.ReturnType)
510 for (const auto &CI : R.Description)
511 emitBlock(*CI.Ptr);
512}
513
515 StreamSubBlockGuard Block(Stream, BI_TYPE_BLOCK_ID);
516 emitBlock(T.Type, FieldId::F_type);
517 emitRecord(T.IsBuiltIn, TYPE_IS_BUILTIN);
518 emitRecord(T.IsTemplate, TYPE_IS_TEMPLATE);
519}
520
522 StreamSubBlockGuard Block(Stream, BI_TYPEDEF_BLOCK_ID);
523 emitRecord(T.USR, TYPEDEF_USR);
524 emitRecord(T.Name, TYPEDEF_NAME);
525 for (const auto &N : T.Namespace)
527 for (const auto &CI : T.Description)
528 emitBlock(*CI.Ptr);
529 if (T.DefLoc)
530 emitRecord(*T.DefLoc, TYPEDEF_DEFLOCATION);
531 if (T.Template)
532 emitBlock(*T.Template);
533 emitRecord(T.IsUsing, TYPEDEF_IS_USING);
534 emitBlock(T.Underlying);
535}
536
538 StreamSubBlockGuard Block(Stream, BI_FIELD_TYPE_BLOCK_ID);
539 emitBlock(T.Type, FieldId::F_type);
540 emitRecord(T.Name, FIELD_TYPE_NAME);
541 emitRecord(T.DefaultValue, FIELD_DEFAULT_VALUE);
542 emitRecord(T.IsBuiltIn, FIELD_TYPE_IS_BUILTIN);
543 emitRecord(T.IsTemplate, FIELD_TYPE_IS_TEMPLATE);
544}
545
547 StreamSubBlockGuard Block(Stream, BI_MEMBER_TYPE_BLOCK_ID);
548 emitBlock(T.Type, FieldId::F_type);
549 emitRecord(T.Name, MEMBER_TYPE_NAME);
550 emitRecord(T.Access, MEMBER_TYPE_ACCESS);
551 emitRecord(T.IsStatic, MEMBER_TYPE_IS_STATIC);
552 emitRecord(T.IsBuiltIn, MEMBER_TYPE_IS_BUILTIN);
553 emitRecord(T.IsTemplate, MEMBER_TYPE_IS_TEMPLATE);
554 // emitRecord(T.IsTemplate, MEMBER_TYPE_IS_TEMPLATE);
555 for (const auto &CI : T.Description)
556 emitBlock(*CI.Ptr);
557}
558
560 StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID);
561 // Handle Kind (enum) separately, since it is not a string.
562 emitRecord(commentKindToString(I.Kind), COMMENT_KIND);
563 for (const auto &L : std::vector<std::pair<StringRef, RecordId>>{
564 {I.Text, COMMENT_TEXT},
565 {I.Name, COMMENT_NAME},
569 emitRecord(L.first, L.second);
570 emitRecord(I.SelfClosing, COMMENT_SELFCLOSING);
571 emitRecord(I.Explicit, COMMENT_EXPLICIT);
572 for (const auto &A : I.AttrKeys)
573 emitRecord(A, COMMENT_ATTRKEY);
574 for (const auto &A : I.AttrValues)
575 emitRecord(A, COMMENT_ATTRVAL);
576 for (const auto &A : I.Args)
577 emitRecord(A, COMMENT_ARG);
578 for (const auto &C : I.Children)
579 emitBlock(C);
580}
581
583 StreamSubBlockGuard Block(Stream, BI_NAMESPACE_BLOCK_ID);
584 emitRecord(I.USR, NAMESPACE_USR);
585 emitRecord(I.Name, NAMESPACE_NAME);
586 emitRecord(I.Path, NAMESPACE_PATH);
587 emitRecord(I.ParentUSR, NAMESPACE_PARENT_USR);
588 for (const auto &N : I.Namespace)
590 for (const auto &CI : I.Description)
591 emitBlock(*CI.Ptr);
592 for (const auto &C : I.Children.Namespaces)
594 for (const auto &C : I.Children.Records)
596 for (const auto &C : I.Children.Functions)
597 emitBlock(C);
598 for (const auto &C : I.Children.Enums)
599 emitBlock(C);
600 for (const auto &C : I.Children.Typedefs)
601 emitBlock(C);
602 for (const auto &C : I.Children.Concepts)
603 emitBlock(C);
604 for (const auto &C : I.Children.Variables)
605 emitBlock(C);
606}
607
609 StreamSubBlockGuard Block(Stream, BI_ENUM_BLOCK_ID);
610 emitRecord(I.USR, ENUM_USR);
611 emitRecord(I.Name, ENUM_NAME);
612 for (const auto &N : I.Namespace)
614 for (const auto &CI : I.Description)
615 emitBlock(*CI.Ptr);
616 if (I.DefLoc)
617 emitRecord(*I.DefLoc, ENUM_DEFLOCATION);
618 for (const auto &L : I.Loc)
619 emitRecord(L, ENUM_LOCATION);
620 emitRecord(I.Scoped, ENUM_SCOPED);
621 if (I.BaseType)
623 for (const auto &N : I.Members)
624 emitBlock(N);
625}
626
628 StreamSubBlockGuard Block(Stream, BI_ENUM_VALUE_BLOCK_ID);
629 emitRecord(I.Name, ENUM_VALUE_NAME);
630 emitRecord(I.Value, ENUM_VALUE_VALUE);
631 emitRecord(I.ValueExpr, ENUM_VALUE_EXPR);
632 for (const auto &CI : I.Description)
633 emitBlock(*CI.Ptr);
634}
635
637 StreamSubBlockGuard Block(Stream, BI_RECORD_BLOCK_ID);
638 emitRecord(I.USR, RECORD_USR);
639 emitRecord(I.Name, RECORD_NAME);
640 emitRecord(I.Path, RECORD_PATH);
641 emitRecord(I.MangledName, RECORD_MANGLED_NAME);
642 emitRecord(I.ParentUSR, RECORD_PARENT_USR);
643 for (const auto &N : I.Namespace)
645 for (const auto &CI : I.Description)
646 emitBlock(*CI.Ptr);
647 if (I.DefLoc)
648 emitRecord(*I.DefLoc, RECORD_DEFLOCATION);
649 for (const auto &L : I.Loc)
650 emitRecord(L, RECORD_LOCATION);
651 emitRecord(llvm::to_underlying(I.TagType), RECORD_TAG_TYPE);
652 emitRecord(I.IsTypeDef, RECORD_IS_TYPE_DEF);
653 for (const auto &N : I.Members)
654 emitBlock(N);
655 for (const auto &P : I.Parents)
657 for (const auto &P : I.VirtualParents)
659 for (const auto &PB : I.Bases)
660 emitBlock(PB);
661 for (const auto &C : I.Children.Records)
663 for (const auto &C : I.Children.Functions)
664 emitBlock(C);
665 for (const auto &C : I.Children.Enums)
666 emitBlock(C);
667 for (const auto &C : I.Children.Typedefs)
668 emitBlock(C);
669 if (I.Template)
671 for (const auto &C : I.Friends)
672 emitBlock(C);
673}
674
676 StreamSubBlockGuard Block(Stream, BI_BASE_RECORD_BLOCK_ID);
677 emitRecord(I.USR, BASE_RECORD_USR);
678 emitRecord(I.Name, BASE_RECORD_NAME);
679 emitRecord(I.Path, BASE_RECORD_PATH);
680 emitRecord(llvm::to_underlying(I.TagType), BASE_RECORD_TAG_TYPE);
681 emitRecord(I.IsVirtual, BASE_RECORD_IS_VIRTUAL);
682 emitRecord(I.Access, BASE_RECORD_ACCESS);
683 emitRecord(I.IsParent, BASE_RECORD_IS_PARENT);
684 for (const auto &M : I.Members)
685 emitBlock(M);
686 for (const auto &C : I.Children.Functions)
687 emitBlock(C);
688}
689
691 StreamSubBlockGuard Block(Stream, BI_FUNCTION_BLOCK_ID);
692 emitRecord(I.USR, FUNCTION_USR);
693 emitRecord(I.Name, FUNCTION_NAME);
694 for (const auto &N : I.Namespace)
696 for (const auto &CI : I.Description)
697 emitBlock(*CI.Ptr);
698 emitRecord(I.Access, FUNCTION_ACCESS);
699 emitRecord(I.IsMethod, FUNCTION_IS_METHOD);
700 emitRecord(I.IsStatic, FUNCTION_IS_STATIC);
701 if (I.DefLoc)
702 emitRecord(*I.DefLoc, FUNCTION_DEFLOCATION);
703 for (const auto &L : I.Loc)
704 emitRecord(L, FUNCTION_LOCATION);
707 for (const auto &N : I.Params)
708 emitBlock(N);
709 if (I.Template)
711}
712
714 StreamSubBlockGuard Block(Stream, BI_CONCEPT_BLOCK_ID);
715 emitRecord(I.USR, CONCEPT_USR);
716 emitRecord(I.Name, CONCEPT_NAME);
717 for (const auto &CI : I.Description)
718 emitBlock(*CI.Ptr);
719 emitRecord(I.IsType, CONCEPT_IS_TYPE);
722 if (I.DefLoc)
723 emitRecord(*I.DefLoc, CONCEPT_DEFLOCATION);
724}
725
727 StreamSubBlockGuard Block(Stream, BI_TEMPLATE_BLOCK_ID);
728 for (const auto &P : T.Params)
729 emitBlock(P);
730 if (T.Specialization)
731 emitBlock(*T.Specialization);
732 for (const auto &C : T.Constraints)
733 emitBlock(C);
734}
735
737 StreamSubBlockGuard Block(Stream, BI_TEMPLATE_SPECIALIZATION_BLOCK_ID);
738 emitRecord(T.SpecializationOf, TEMPLATE_SPECIALIZATION_OF);
739 for (const auto &P : T.Params)
740 emitBlock(P);
741}
742
744 StreamSubBlockGuard Block(Stream, BI_TEMPLATE_PARAM_BLOCK_ID);
745 emitRecord(T.Contents, TEMPLATE_PARAM_CONTENTS);
746}
747
749 StreamSubBlockGuard Block(Stream, BI_CONSTRAINT_BLOCK_ID);
750 emitRecord(C.ConstraintExpr, CONSTRAINT_EXPRESSION);
751 emitBlock(C.ConceptRef, FieldId::F_concept);
752}
753
755 StreamSubBlockGuard Block(Stream, BI_VAR_BLOCK_ID);
756 emitRecord(I.USR, VAR_USR);
757 emitRecord(I.Name, VAR_NAME);
758 for (const auto &N : I.Namespace)
760 for (const auto &CI : I.Description)
761 emitBlock(*CI.Ptr);
762 if (I.DefLoc)
763 emitRecord(*I.DefLoc, VAR_DEFLOCATION);
764 emitRecord(I.IsStatic, VAR_IS_STATIC);
765 emitBlock(I.Type);
766}
767
769 switch (I->IT) {
771 emitBlock(*static_cast<NamespaceInfo *>(I));
772 break;
774 emitBlock(*static_cast<RecordInfo *>(I));
775 break;
777 emitBlock(*static_cast<EnumInfo *>(I));
778 break;
780 emitBlock(*static_cast<FunctionInfo *>(I));
781 break;
783 emitBlock(*static_cast<TypedefInfo *>(I));
784 break;
786 emitBlock(*static_cast<ConceptInfo *>(I));
787 break;
789 emitBlock(*static_cast<VarInfo *>(I));
790 break;
792 emitBlock(*static_cast<FriendInfo *>(I));
793 break;
795 unsigned ID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
796 "Unexpected info, unable to write.");
797 Diags.Report(ID);
798 return true;
799 }
800 return false;
801}
802
803} // namespace doc
804} // namespace clang
static void genLocationAbbrev(std::shared_ptr< BitCodeAbbrev > &Abbrev)
static void genBoolAbbrev(std::shared_ptr< BitCodeAbbrev > &Abbrev)
static void genSymbolIdAbbrev(std::shared_ptr< BitCodeAbbrev > &Abbrev)
static void genIntAbbrev(std::shared_ptr< BitCodeAbbrev > &Abbrev)
static void generateAbbrev(std::shared_ptr< BitCodeAbbrev > &Abbrev, const std::initializer_list< BitCodeAbbrevOp > Ops)
static void genStringAbbrev(std::shared_ptr< BitCodeAbbrev > &Abbrev)
void emitBlock(const NamespaceInfo &I)
@ TEMPLATE_SPECIALIZATION_OF
@ MEMBER_TYPE_IS_TEMPLATE
@ TEMPLATE_PARAM_CONTENTS
@ CONCEPT_CONSTRAINT_EXPRESSION
static constexpr unsigned BlockIdCount
static const unsigned VersionNumber
static constexpr unsigned RecordIdCount
std::array< uint8_t, 20 > SymbolID
llvm::StringRef commentKindToString(CommentKind Kind)
@ BI_CONSTRAINT_BLOCK_ID
@ BI_ENUM_VALUE_BLOCK_ID
@ BI_TEMPLATE_SPECIALIZATION_BLOCK_ID
@ BI_NAMESPACE_BLOCK_ID
@ BI_TEMPLATE_PARAM_BLOCK_ID
@ BI_MEMBER_TYPE_BLOCK_ID
@ BI_BASE_RECORD_BLOCK_ID
@ BI_FIELD_TYPE_BLOCK_ID
@ BI_REFERENCE_BLOCK_ID
const SymbolID EmptySID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Some operations such as code completion produce a set of candidates.
Definition Generators.h:152
static constexpr unsigned BoolSize
static constexpr unsigned LineNumberSize
static constexpr unsigned RecordSize
static constexpr unsigned StringLengthSize
static constexpr unsigned USRBitLengthSize
static constexpr unsigned char Signature[4]
static constexpr unsigned IntSize
static constexpr unsigned SignatureBitSize
static constexpr unsigned SubblockIDSize
static constexpr unsigned USRLengthSize
ArrayRef< StringRef > Args
ArrayRef< CommentInfo > Children
ArrayRef< StringRef > AttrKeys
ArrayRef< StringRef > AttrValues
llvm::ArrayRef< EnumValueInfo > Members
std::optional< TypeInfo > BaseType
DocList< CommentInfo > Description
Comment description of this field.
std::optional< TypeInfo > ReturnType
llvm::ArrayRef< FieldTypeInfo > Params
std::optional< TemplateInfo > Template
llvm::ArrayRef< FieldTypeInfo > Params
std::optional< TemplateInfo > Template
A base struct for Infos.
DocList< CommentInfo > Description
llvm::ArrayRef< Reference > Namespace
llvm::ArrayRef< BaseRecordInfo > Bases
llvm::ArrayRef< FriendInfo > Friends
llvm::ArrayRef< Reference > VirtualParents
std::optional< TemplateInfo > Template
llvm::ArrayRef< Reference > Parents
llvm::ArrayRef< MemberTypeInfo > Members
DocList< Reference > Records
DocList< EnumInfo > Enums
DocList< ConceptInfo > Concepts
DocList< VarInfo > Variables
DocList< FunctionInfo > Functions
DocList< Reference > Namespaces
DocList< TypedefInfo > Typedefs
DocList< Location > Loc
std::optional< Location > DefLoc