clang-tools 20.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
13namespace clang {
14namespace doc {
15
16// Empty SymbolID for comparison, so we don't have to construct one every time.
17static const SymbolID EmptySID = SymbolID();
18
19// Since id enums are not zero-indexed, we need to transform the given id into
20// its associated index.
22 using argument_type = unsigned;
23 unsigned operator()(unsigned ID) const { return ID - BI_FIRST; }
24};
25
27 using argument_type = unsigned;
28 unsigned operator()(unsigned ID) const { return ID - RI_FIRST; }
29};
30
31using AbbrevDsc = void (*)(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev);
32
33static void AbbrevGen(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev,
34 const std::initializer_list<llvm::BitCodeAbbrevOp> Ops) {
35 for (const auto &Op : Ops)
36 Abbrev->Add(Op);
37}
38
39static void BoolAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
40 AbbrevGen(Abbrev,
41 {// 0. Boolean
42 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
44}
45
46static void IntAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
47 AbbrevGen(Abbrev,
48 {// 0. Fixed-size integer
49 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
51}
52
53static void SymbolIDAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
54 AbbrevGen(Abbrev,
55 {// 0. Fixed-size integer (length of the sha1'd USR)
56 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
58 // 1. Fixed-size array of Char6 (USR)
59 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array),
60 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
62}
63
64static void StringAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
65 AbbrevGen(Abbrev,
66 {// 0. Fixed-size integer (length of the following string)
67 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
69 // 1. The string blob
70 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
71}
72
73// Assumes that the file will not have more than 65535 lines.
74static void LocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
76 Abbrev,
77 {// 0. Fixed-size integer (line number)
78 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
80 // 1. Boolean (IsFileInRootDir)
81 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
83 // 2. Fixed-size integer (length of the following string (filename))
84 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
86 // 3. The string blob
87 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
88}
89
91 llvm::StringRef Name;
92 AbbrevDsc Abbrev = nullptr;
93
94 RecordIdDsc() = default;
95 RecordIdDsc(llvm::StringRef Name, AbbrevDsc Abbrev)
96 : Name(Name), Abbrev(Abbrev) {}
97
98 // Is this 'description' valid?
99 operator bool() const {
100 return Abbrev != nullptr && Name.data() != nullptr && !Name.empty();
101 }
102};
103
104static const llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor>
106 llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor> BlockIdNameMap;
108
109 // There is no init-list constructor for the IndexedMap, so have to
110 // improvise
111 static const std::vector<std::pair<BlockId, const char *const>> Inits = {
112 {BI_VERSION_BLOCK_ID, "VersionBlock"},
113 {BI_NAMESPACE_BLOCK_ID, "NamespaceBlock"},
114 {BI_ENUM_BLOCK_ID, "EnumBlock"},
115 {BI_ENUM_VALUE_BLOCK_ID, "EnumValueBlock"},
116 {BI_TYPEDEF_BLOCK_ID, "TypedefBlock"},
117 {BI_TYPE_BLOCK_ID, "TypeBlock"},
118 {BI_FIELD_TYPE_BLOCK_ID, "FieldTypeBlock"},
119 {BI_MEMBER_TYPE_BLOCK_ID, "MemberTypeBlock"},
120 {BI_RECORD_BLOCK_ID, "RecordBlock"},
121 {BI_BASE_RECORD_BLOCK_ID, "BaseRecordBlock"},
122 {BI_FUNCTION_BLOCK_ID, "FunctionBlock"},
123 {BI_COMMENT_BLOCK_ID, "CommentBlock"},
124 {BI_REFERENCE_BLOCK_ID, "ReferenceBlock"},
125 {BI_TEMPLATE_BLOCK_ID, "TemplateBlock"},
126 {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, "TemplateSpecializationBlock"},
127 {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"}};
128 assert(Inits.size() == BlockIdCount);
129 for (const auto &Init : Inits)
130 BlockIdNameMap[Init.first] = Init.second;
131 assert(BlockIdNameMap.size() == BlockIdCount);
132 return BlockIdNameMap;
133 }();
134
135static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
137 llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> RecordIdNameMap;
139
140 // There is no init-list constructor for the IndexedMap, so have to
141 // improvise
142 static const std::vector<std::pair<RecordId, RecordIdDsc>> Inits = {
143 {VERSION, {"Version", &IntAbbrev}},
144 {COMMENT_KIND, {"Kind", &StringAbbrev}},
145 {COMMENT_TEXT, {"Text", &StringAbbrev}},
146 {COMMENT_NAME, {"Name", &StringAbbrev}},
147 {COMMENT_DIRECTION, {"Direction", &StringAbbrev}},
148 {COMMENT_PARAMNAME, {"ParamName", &StringAbbrev}},
149 {COMMENT_CLOSENAME, {"CloseName", &StringAbbrev}},
150 {COMMENT_SELFCLOSING, {"SelfClosing", &BoolAbbrev}},
151 {COMMENT_EXPLICIT, {"Explicit", &BoolAbbrev}},
152 {COMMENT_ATTRKEY, {"AttrKey", &StringAbbrev}},
153 {COMMENT_ATTRVAL, {"AttrVal", &StringAbbrev}},
154 {COMMENT_ARG, {"Arg", &StringAbbrev}},
155 {FIELD_TYPE_NAME, {"Name", &StringAbbrev}},
156 {FIELD_DEFAULT_VALUE, {"DefaultValue", &StringAbbrev}},
157 {MEMBER_TYPE_NAME, {"Name", &StringAbbrev}},
158 {MEMBER_TYPE_ACCESS, {"Access", &IntAbbrev}},
159 {NAMESPACE_USR, {"USR", &SymbolIDAbbrev}},
160 {NAMESPACE_NAME, {"Name", &StringAbbrev}},
161 {NAMESPACE_PATH, {"Path", &StringAbbrev}},
162 {ENUM_USR, {"USR", &SymbolIDAbbrev}},
163 {ENUM_NAME, {"Name", &StringAbbrev}},
164 {ENUM_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
165 {ENUM_LOCATION, {"Location", &LocationAbbrev}},
166 {ENUM_SCOPED, {"Scoped", &BoolAbbrev}},
167 {ENUM_VALUE_NAME, {"Name", &StringAbbrev}},
168 {ENUM_VALUE_VALUE, {"Value", &StringAbbrev}},
169 {ENUM_VALUE_EXPR, {"Expr", &StringAbbrev}},
170 {RECORD_USR, {"USR", &SymbolIDAbbrev}},
171 {RECORD_NAME, {"Name", &StringAbbrev}},
172 {RECORD_PATH, {"Path", &StringAbbrev}},
173 {RECORD_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
174 {RECORD_LOCATION, {"Location", &LocationAbbrev}},
175 {RECORD_TAG_TYPE, {"TagType", &IntAbbrev}},
176 {RECORD_IS_TYPE_DEF, {"IsTypeDef", &BoolAbbrev}},
177 {BASE_RECORD_USR, {"USR", &SymbolIDAbbrev}},
178 {BASE_RECORD_NAME, {"Name", &StringAbbrev}},
179 {BASE_RECORD_PATH, {"Path", &StringAbbrev}},
180 {BASE_RECORD_TAG_TYPE, {"TagType", &IntAbbrev}},
181 {BASE_RECORD_IS_VIRTUAL, {"IsVirtual", &BoolAbbrev}},
182 {BASE_RECORD_ACCESS, {"Access", &IntAbbrev}},
183 {BASE_RECORD_IS_PARENT, {"IsParent", &BoolAbbrev}},
184 {FUNCTION_USR, {"USR", &SymbolIDAbbrev}},
185 {FUNCTION_NAME, {"Name", &StringAbbrev}},
186 {FUNCTION_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
187 {FUNCTION_LOCATION, {"Location", &LocationAbbrev}},
188 {FUNCTION_ACCESS, {"Access", &IntAbbrev}},
189 {FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}},
190 {REFERENCE_USR, {"USR", &SymbolIDAbbrev}},
191 {REFERENCE_NAME, {"Name", &StringAbbrev}},
192 {REFERENCE_QUAL_NAME, {"QualName", &StringAbbrev}},
193 {REFERENCE_TYPE, {"RefType", &IntAbbrev}},
194 {REFERENCE_PATH, {"Path", &StringAbbrev}},
195 {REFERENCE_FIELD, {"Field", &IntAbbrev}},
196 {TEMPLATE_PARAM_CONTENTS, {"Contents", &StringAbbrev}},
197 {TEMPLATE_SPECIALIZATION_OF, {"SpecializationOf", &SymbolIDAbbrev}},
198 {TYPEDEF_USR, {"USR", &SymbolIDAbbrev}},
199 {TYPEDEF_NAME, {"Name", &StringAbbrev}},
200 {TYPEDEF_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
201 {TYPEDEF_IS_USING, {"IsUsing", &BoolAbbrev}}};
202 assert(Inits.size() == RecordIdCount);
203 for (const auto &Init : Inits) {
204 RecordIdNameMap[Init.first] = Init.second;
205 assert((Init.second.Name.size() + 1) <= BitCodeConstants::RecordSize);
206 }
207 assert(RecordIdNameMap.size() == RecordIdCount);
208 return RecordIdNameMap;
209 }();
210
211static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
213 // Version Block
215 // Comment Block
220 // Type Block
221 {BI_TYPE_BLOCK_ID, {}},
222 // FieldType Block
224 // MemberType Block
226 // Enum Block
229 // Enum Value Block
232 // Typedef Block
235 // Namespace Block
238 // Record Block
242 // BaseRecord Block
247 // Function Block
251 // Reference Block
255 // Template Blocks.
259
260// AbbreviationMap
261
262constexpr unsigned char BitCodeConstants::Signature[];
263
264void ClangDocBitcodeWriter::AbbreviationMap::add(RecordId RID,
265 unsigned AbbrevID) {
266 assert(RecordIdNameMap[RID] && "Unknown RecordId.");
267 assert(!Abbrevs.contains(RID) && "Abbreviation already added.");
268 Abbrevs[RID] = AbbrevID;
269}
270
271unsigned ClangDocBitcodeWriter::AbbreviationMap::get(RecordId RID) const {
272 assert(RecordIdNameMap[RID] && "Unknown RecordId.");
273 assert(Abbrevs.contains(RID) && "Unknown abbreviation.");
274 return Abbrevs.lookup(RID);
275}
276
277// Validation and Overview Blocks
278
279/// Emits the magic number header to check that its the right format,
280/// in this case, 'DOCS'.
281void ClangDocBitcodeWriter::emitHeader() {
282 for (char C : BitCodeConstants::Signature)
283 Stream.Emit((unsigned)C, BitCodeConstants::SignatureBitSize);
284}
285
286void ClangDocBitcodeWriter::emitVersionBlock() {
287 StreamSubBlockGuard Block(Stream, BI_VERSION_BLOCK_ID);
288 emitRecord(VersionNumber, VERSION);
289}
290
291/// Emits a block ID and the block name to the BLOCKINFO block.
292void ClangDocBitcodeWriter::emitBlockID(BlockId BID) {
293 const auto &BlockIdName = BlockIdNameMap[BID];
294 assert(BlockIdName.data() && BlockIdName.size() && "Unknown BlockId.");
295
296 Record.clear();
297 Record.push_back(BID);
298 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
299 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME,
300 ArrayRef<unsigned char>(BlockIdName.bytes_begin(),
301 BlockIdName.bytes_end()));
302}
303
304/// Emits a record name to the BLOCKINFO block.
305void ClangDocBitcodeWriter::emitRecordID(RecordId ID) {
306 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
307 prepRecordData(ID);
308 Record.append(RecordIdNameMap[ID].Name.begin(),
309 RecordIdNameMap[ID].Name.end());
310 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
311}
312
313// Abbreviations
314
315void ClangDocBitcodeWriter::emitAbbrev(RecordId ID, BlockId Block) {
316 assert(RecordIdNameMap[ID] && "Unknown abbreviation.");
317 auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>();
318 Abbrev->Add(llvm::BitCodeAbbrevOp(ID));
319 RecordIdNameMap[ID].Abbrev(Abbrev);
320 Abbrevs.add(ID, Stream.EmitBlockInfoAbbrev(Block, std::move(Abbrev)));
321}
322
323// Records
324
325void ClangDocBitcodeWriter::emitRecord(const SymbolID &Sym, RecordId ID) {
326 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
327 assert(RecordIdNameMap[ID].Abbrev == &SymbolIDAbbrev &&
328 "Abbrev type mismatch.");
329 if (!prepRecordData(ID, Sym != EmptySID))
330 return;
331 assert(Sym.size() == 20);
332 Record.push_back(Sym.size());
333 Record.append(Sym.begin(), Sym.end());
334 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
335}
336
337void ClangDocBitcodeWriter::emitRecord(llvm::StringRef Str, RecordId ID) {
338 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
339 assert(RecordIdNameMap[ID].Abbrev == &StringAbbrev &&
340 "Abbrev type mismatch.");
341 if (!prepRecordData(ID, !Str.empty()))
342 return;
343 assert(Str.size() < (1U << BitCodeConstants::StringLengthSize));
344 Record.push_back(Str.size());
345 Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Str);
346}
347
348void ClangDocBitcodeWriter::emitRecord(const Location &Loc, RecordId ID) {
349 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
350 assert(RecordIdNameMap[ID].Abbrev == &LocationAbbrev &&
351 "Abbrev type mismatch.");
352 if (!prepRecordData(ID, true))
353 return;
354 // FIXME: Assert that the line number is of the appropriate size.
355 Record.push_back(Loc.LineNumber);
356 assert(Loc.Filename.size() < (1U << BitCodeConstants::StringLengthSize));
357 Record.push_back(Loc.IsFileInRootDir);
358 Record.push_back(Loc.Filename.size());
359 Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Loc.Filename);
360}
361
362void ClangDocBitcodeWriter::emitRecord(bool Val, RecordId ID) {
363 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
364 assert(RecordIdNameMap[ID].Abbrev == &BoolAbbrev && "Abbrev type mismatch.");
365 if (!prepRecordData(ID, Val))
366 return;
367 Record.push_back(Val);
368 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
369}
370
371void ClangDocBitcodeWriter::emitRecord(int Val, RecordId ID) {
372 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
373 assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch.");
374 if (!prepRecordData(ID, Val))
375 return;
376 // FIXME: Assert that the integer is of the appropriate size.
377 Record.push_back(Val);
378 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
379}
380
381void ClangDocBitcodeWriter::emitRecord(unsigned Val, RecordId ID) {
382 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
383 assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch.");
384 if (!prepRecordData(ID, Val))
385 return;
386 assert(Val < (1U << BitCodeConstants::IntSize));
387 Record.push_back(Val);
388 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
389}
390
391void ClangDocBitcodeWriter::emitRecord(const TemplateInfo &Templ) {}
392
393bool ClangDocBitcodeWriter::prepRecordData(RecordId ID, bool ShouldEmit) {
394 assert(RecordIdNameMap[ID] && "Unknown RecordId.");
395 if (!ShouldEmit)
396 return false;
397 Record.clear();
398 Record.push_back(ID);
399 return true;
400}
401
402// BlockInfo Block
403
404void ClangDocBitcodeWriter::emitBlockInfoBlock() {
405 Stream.EnterBlockInfoBlock();
406 for (const auto &Block : RecordsByBlock) {
407 assert(Block.second.size() < (1U << BitCodeConstants::SubblockIDSize));
408 emitBlockInfo(Block.first, Block.second);
409 }
410 Stream.ExitBlock();
411}
412
413void ClangDocBitcodeWriter::emitBlockInfo(BlockId BID,
414 const std::vector<RecordId> &RIDs) {
415 assert(RIDs.size() < (1U << BitCodeConstants::SubblockIDSize));
416 emitBlockID(BID);
417 for (RecordId RID : RIDs) {
418 emitRecordID(RID);
419 emitAbbrev(RID, BID);
420 }
421}
422
423// Block emission
424
426 if (R.USR == EmptySID && R.Name.empty())
427 return;
428 StreamSubBlockGuard Block(Stream, BI_REFERENCE_BLOCK_ID);
429 emitRecord(R.USR, REFERENCE_USR);
430 emitRecord(R.Name, REFERENCE_NAME);
431 emitRecord(R.QualName, REFERENCE_QUAL_NAME);
432 emitRecord((unsigned)R.RefType, REFERENCE_TYPE);
433 emitRecord(R.Path, REFERENCE_PATH);
434 emitRecord((unsigned)Field, REFERENCE_FIELD);
435}
436
438 StreamSubBlockGuard Block(Stream, BI_TYPE_BLOCK_ID);
439 emitBlock(T.Type, FieldId::F_type);
440}
441
443 StreamSubBlockGuard Block(Stream, BI_TYPEDEF_BLOCK_ID);
444 emitRecord(T.USR, TYPEDEF_USR);
445 emitRecord(T.Name, TYPEDEF_NAME);
446 for (const auto &N : T.Namespace)
448 for (const auto &CI : T.Description)
449 emitBlock(CI);
450 if (T.DefLoc)
451 emitRecord(*T.DefLoc, TYPEDEF_DEFLOCATION);
452 emitRecord(T.IsUsing, TYPEDEF_IS_USING);
453 emitBlock(T.Underlying);
454}
455
457 StreamSubBlockGuard Block(Stream, BI_FIELD_TYPE_BLOCK_ID);
458 emitBlock(T.Type, FieldId::F_type);
459 emitRecord(T.Name, FIELD_TYPE_NAME);
460 emitRecord(T.DefaultValue, FIELD_DEFAULT_VALUE);
461}
462
464 StreamSubBlockGuard Block(Stream, BI_MEMBER_TYPE_BLOCK_ID);
465 emitBlock(T.Type, FieldId::F_type);
466 emitRecord(T.Name, MEMBER_TYPE_NAME);
467 emitRecord(T.Access, MEMBER_TYPE_ACCESS);
468 for (const auto &CI : T.Description)
469 emitBlock(CI);
470}
471
473 StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID);
474 for (const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{
475 {I.Kind, COMMENT_KIND},
476 {I.Text, COMMENT_TEXT},
477 {I.Name, COMMENT_NAME},
481 emitRecord(L.first, L.second);
482 emitRecord(I.SelfClosing, COMMENT_SELFCLOSING);
483 emitRecord(I.Explicit, COMMENT_EXPLICIT);
484 for (const auto &A : I.AttrKeys)
485 emitRecord(A, COMMENT_ATTRKEY);
486 for (const auto &A : I.AttrValues)
487 emitRecord(A, COMMENT_ATTRVAL);
488 for (const auto &A : I.Args)
489 emitRecord(A, COMMENT_ARG);
490 for (const auto &C : I.Children)
491 emitBlock(*C);
492}
493
495 StreamSubBlockGuard Block(Stream, BI_NAMESPACE_BLOCK_ID);
496 emitRecord(I.USR, NAMESPACE_USR);
497 emitRecord(I.Name, NAMESPACE_NAME);
498 emitRecord(I.Path, NAMESPACE_PATH);
499 for (const auto &N : I.Namespace)
501 for (const auto &CI : I.Description)
502 emitBlock(CI);
503 for (const auto &C : I.Children.Namespaces)
505 for (const auto &C : I.Children.Records)
507 for (const auto &C : I.Children.Functions)
508 emitBlock(C);
509 for (const auto &C : I.Children.Enums)
510 emitBlock(C);
511 for (const auto &C : I.Children.Typedefs)
512 emitBlock(C);
513}
514
516 StreamSubBlockGuard Block(Stream, BI_ENUM_BLOCK_ID);
517 emitRecord(I.USR, ENUM_USR);
518 emitRecord(I.Name, ENUM_NAME);
519 for (const auto &N : I.Namespace)
521 for (const auto &CI : I.Description)
522 emitBlock(CI);
523 if (I.DefLoc)
524 emitRecord(*I.DefLoc, ENUM_DEFLOCATION);
525 for (const auto &L : I.Loc)
526 emitRecord(L, ENUM_LOCATION);
527 emitRecord(I.Scoped, ENUM_SCOPED);
528 if (I.BaseType)
530 for (const auto &N : I.Members)
531 emitBlock(N);
532}
533
535 StreamSubBlockGuard Block(Stream, BI_ENUM_VALUE_BLOCK_ID);
536 emitRecord(I.Name, ENUM_VALUE_NAME);
537 emitRecord(I.Value, ENUM_VALUE_VALUE);
538 emitRecord(I.ValueExpr, ENUM_VALUE_EXPR);
539 for (const auto &CI : I.Description)
540 emitBlock(CI);
541}
542
544 StreamSubBlockGuard Block(Stream, BI_RECORD_BLOCK_ID);
545 emitRecord(I.USR, RECORD_USR);
546 emitRecord(I.Name, RECORD_NAME);
547 emitRecord(I.Path, RECORD_PATH);
548 for (const auto &N : I.Namespace)
550 for (const auto &CI : I.Description)
551 emitBlock(CI);
552 if (I.DefLoc)
553 emitRecord(*I.DefLoc, RECORD_DEFLOCATION);
554 for (const auto &L : I.Loc)
555 emitRecord(L, RECORD_LOCATION);
556 emitRecord(llvm::to_underlying(I.TagType), RECORD_TAG_TYPE);
557 emitRecord(I.IsTypeDef, RECORD_IS_TYPE_DEF);
558 for (const auto &N : I.Members)
559 emitBlock(N);
560 for (const auto &P : I.Parents)
562 for (const auto &P : I.VirtualParents)
564 for (const auto &PB : I.Bases)
565 emitBlock(PB);
566 for (const auto &C : I.Children.Records)
568 for (const auto &C : I.Children.Functions)
569 emitBlock(C);
570 for (const auto &C : I.Children.Enums)
571 emitBlock(C);
572 for (const auto &C : I.Children.Typedefs)
573 emitBlock(C);
574 if (I.Template)
576}
577
579 StreamSubBlockGuard Block(Stream, BI_BASE_RECORD_BLOCK_ID);
580 emitRecord(I.USR, BASE_RECORD_USR);
581 emitRecord(I.Name, BASE_RECORD_NAME);
582 emitRecord(I.Path, BASE_RECORD_PATH);
583 emitRecord(llvm::to_underlying(I.TagType), BASE_RECORD_TAG_TYPE);
584 emitRecord(I.IsVirtual, BASE_RECORD_IS_VIRTUAL);
585 emitRecord(I.Access, BASE_RECORD_ACCESS);
586 emitRecord(I.IsParent, BASE_RECORD_IS_PARENT);
587 for (const auto &M : I.Members)
588 emitBlock(M);
589 for (const auto &C : I.Children.Functions)
590 emitBlock(C);
591}
592
594 StreamSubBlockGuard Block(Stream, BI_FUNCTION_BLOCK_ID);
595 emitRecord(I.USR, FUNCTION_USR);
596 emitRecord(I.Name, FUNCTION_NAME);
597 for (const auto &N : I.Namespace)
599 for (const auto &CI : I.Description)
600 emitBlock(CI);
601 emitRecord(I.Access, FUNCTION_ACCESS);
602 emitRecord(I.IsMethod, FUNCTION_IS_METHOD);
603 if (I.DefLoc)
604 emitRecord(*I.DefLoc, FUNCTION_DEFLOCATION);
605 for (const auto &L : I.Loc)
606 emitRecord(L, FUNCTION_LOCATION);
609 for (const auto &N : I.Params)
610 emitBlock(N);
611 if (I.Template)
613}
614
616 StreamSubBlockGuard Block(Stream, BI_TEMPLATE_BLOCK_ID);
617 for (const auto &P : T.Params)
618 emitBlock(P);
619 if (T.Specialization)
620 emitBlock(*T.Specialization);
621}
622
624 StreamSubBlockGuard Block(Stream, BI_TEMPLATE_SPECIALIZATION_BLOCK_ID);
625 emitRecord(T.SpecializationOf, TEMPLATE_SPECIALIZATION_OF);
626 for (const auto &P : T.Params)
627 emitBlock(P);
628}
629
631 StreamSubBlockGuard Block(Stream, BI_TEMPLATE_PARAM_BLOCK_ID);
632 emitRecord(T.Contents, TEMPLATE_PARAM_CONTENTS);
633}
634
636 switch (I->IT) {
638 emitBlock(*static_cast<clang::doc::NamespaceInfo *>(I));
639 break;
641 emitBlock(*static_cast<clang::doc::RecordInfo *>(I));
642 break;
644 emitBlock(*static_cast<clang::doc::EnumInfo *>(I));
645 break;
647 emitBlock(*static_cast<clang::doc::FunctionInfo *>(I));
648 break;
650 emitBlock(*static_cast<clang::doc::TypedefInfo *>(I));
651 break;
652 default:
653 llvm::errs() << "Unexpected info, unable to write.\n";
654 return true;
655 }
656 return false;
657}
658
659} // namespace doc
660} // namespace clang
llvm::SmallString< 256U > Name
const Criteria C
SourceLocation Loc
const FieldDecl * Field
const google::protobuf::Message & M
Definition: Server.cpp:309
std::unique_ptr< CompilerInvocation > CI
void emitBlock(const NamespaceInfo &I)
static const llvm::IndexedMap< RecordIdDsc, RecordIdToIndexFunctor > RecordIdNameMap
static void SymbolIDAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
static const llvm::IndexedMap< llvm::StringRef, BlockIdToIndexFunctor > BlockIdNameMap
@ FIELD_DEFAULT_VALUE
Definition: BitcodeWriter.h:96
@ TEMPLATE_SPECIALIZATION_OF
@ BASE_RECORD_TAG_TYPE
@ COMMENT_SELFCLOSING
Definition: BitcodeWriter.h:90
@ FUNCTION_DEFLOCATION
Definition: BitcodeWriter.h:80
@ FUNCTION_IS_METHOD
Definition: BitcodeWriter.h:83
@ MEMBER_TYPE_ACCESS
Definition: BitcodeWriter.h:98
@ BASE_RECORD_IS_PARENT
@ TEMPLATE_PARAM_CONTENTS
@ BASE_RECORD_IS_VIRTUAL
static void AbbrevGen(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev, const std::initializer_list< llvm::BitCodeAbbrevOp > Ops)
static constexpr unsigned BlockIdCount
static const std::vector< std::pair< BlockId, std::vector< RecordId > > > RecordsByBlock
static const unsigned VersionNumber
Definition: BitcodeWriter.h:33
static void StringAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
static constexpr unsigned RecordIdCount
static void LocationAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
static void IntAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
std::array< uint8_t, 20 > SymbolID
static void BoolAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
void(*)(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev) AbbrevDsc
@ BI_RECORD_BLOCK_ID
Definition: BitcodeWriter.h:61
@ BI_FUNCTION_BLOCK_ID
Definition: BitcodeWriter.h:63
@ BI_ENUM_VALUE_BLOCK_ID
Definition: BitcodeWriter.h:57
@ BI_TEMPLATE_SPECIALIZATION_BLOCK_ID
Definition: BitcodeWriter.h:67
@ BI_VERSION_BLOCK_ID
Definition: BitcodeWriter.h:54
@ BI_COMMENT_BLOCK_ID
Definition: BitcodeWriter.h:64
@ BI_TEMPLATE_BLOCK_ID
Definition: BitcodeWriter.h:66
@ BI_TYPEDEF_BLOCK_ID
Definition: BitcodeWriter.h:69
@ BI_NAMESPACE_BLOCK_ID
Definition: BitcodeWriter.h:55
@ BI_TEMPLATE_PARAM_BLOCK_ID
Definition: BitcodeWriter.h:68
@ BI_MEMBER_TYPE_BLOCK_ID
Definition: BitcodeWriter.h:60
@ BI_BASE_RECORD_BLOCK_ID
Definition: BitcodeWriter.h:62
@ BI_FIELD_TYPE_BLOCK_ID
Definition: BitcodeWriter.h:59
@ BI_REFERENCE_BLOCK_ID
Definition: BitcodeWriter.h:65
static const SymbolID EmptySID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static constexpr unsigned BoolSize
Definition: BitcodeWriter.h:39
static constexpr unsigned LineNumberSize
Definition: BitcodeWriter.h:43
static constexpr unsigned char Signature[4]
Definition: BitcodeWriter.h:47
static constexpr unsigned RecordSize
Definition: BitcodeWriter.h:36
static constexpr unsigned StringLengthSize
Definition: BitcodeWriter.h:41
static constexpr unsigned USRBitLengthSize
Definition: BitcodeWriter.h:46
static constexpr unsigned IntSize
Definition: BitcodeWriter.h:40
static constexpr unsigned SignatureBitSize
Definition: BitcodeWriter.h:37
static constexpr unsigned SubblockIDSize
Definition: BitcodeWriter.h:38
static constexpr unsigned USRLengthSize
Definition: BitcodeWriter.h:45
unsigned operator()(unsigned ID) const
SmallString< 8 > Direction
SmallString< 16 > Kind
std::vector< std::unique_ptr< CommentInfo > > Children
llvm::SmallVector< SmallString< 16 >, 4 > AttrValues
SmallString< 16 > CloseName
SmallString< 16 > Name
SmallString< 64 > Text
llvm::SmallVector< SmallString< 16 >, 4 > AttrKeys
llvm::SmallVector< SmallString< 16 >, 4 > Args
SmallString< 16 > ParamName
llvm::SmallVector< EnumValueInfo, 4 > Members
std::optional< TypeInfo > BaseType
std::vector< CommentInfo > Description
SmallString< 16 > Value
SmallString< 16 > Name
SmallString< 16 > ValueExpr
llvm::SmallVector< FieldTypeInfo, 4 > Params
std::optional< TemplateInfo > Template
A base struct for Infos.
SmallString< 16 > Name
std::vector< CommentInfo > Description
llvm::SmallString< 128 > Path
llvm::SmallVector< Reference, 4 > Namespace
RecordIdDsc(llvm::StringRef Name, AbbrevDsc Abbrev)
unsigned operator()(unsigned ID) const
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::optional< TemplateInfo > Template
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
std::vector< BaseRecordInfo > Bases
SmallString< 16 > QualName
llvm::SmallString< 128 > Path
SmallString< 16 > Name
std::vector< Reference > Records
std::vector< TypedefInfo > Typedefs
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< EnumInfo > Enums
llvm::SmallVector< Location, 2 > Loc
std::optional< Location > DefLoc