clang-tools 20.0.0git
BitcodeReader.cpp
Go to the documentation of this file.
1//===-- BitcodeReader.cpp - ClangDoc Bitcode Reader ------------*- 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 "BitcodeReader.h"
10#include "llvm/ADT/IndexedMap.h"
11#include "llvm/Support/Error.h"
12#include "llvm/Support/raw_ostream.h"
13#include <optional>
14
15namespace clang {
16namespace doc {
17
18using Record = llvm::SmallVector<uint64_t, 1024>;
19
20// This implements decode for SmallString.
21llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl<char> &Field,
22 llvm::StringRef Blob) {
23 Field.assign(Blob.begin(), Blob.end());
24 return llvm::Error::success();
25}
26
27llvm::Error decodeRecord(const Record &R, SymbolID &Field,
28 llvm::StringRef Blob) {
30 return llvm::createStringError(llvm::inconvertibleErrorCode(),
31 "incorrect USR size");
32
33 // First position in the record is the length of the following array, so we
34 // copy the following elements to the field.
35 for (int I = 0, E = R[0]; I < E; ++I)
36 Field[I] = R[I + 1];
37 return llvm::Error::success();
38}
39
40llvm::Error decodeRecord(const Record &R, bool &Field, llvm::StringRef Blob) {
41 Field = R[0] != 0;
42 return llvm::Error::success();
43}
44
45llvm::Error decodeRecord(const Record &R, int &Field, llvm::StringRef Blob) {
46 if (R[0] > INT_MAX)
47 return llvm::createStringError(llvm::inconvertibleErrorCode(),
48 "integer too large to parse");
49 Field = (int)R[0];
50 return llvm::Error::success();
51}
52
53llvm::Error decodeRecord(const Record &R, AccessSpecifier &Field,
54 llvm::StringRef Blob) {
55 switch (R[0]) {
56 case AS_public:
57 case AS_private:
58 case AS_protected:
59 case AS_none:
60 Field = (AccessSpecifier)R[0];
61 return llvm::Error::success();
62 default:
63 return llvm::createStringError(llvm::inconvertibleErrorCode(),
64 "invalid value for AccessSpecifier");
65 }
66}
67
68llvm::Error decodeRecord(const Record &R, TagTypeKind &Field,
69 llvm::StringRef Blob) {
70 switch (static_cast<TagTypeKind>(R[0])) {
71 case TagTypeKind::Struct:
72 case TagTypeKind::Interface:
73 case TagTypeKind::Union:
74 case TagTypeKind::Class:
75 case TagTypeKind::Enum:
76 Field = static_cast<TagTypeKind>(R[0]);
77 return llvm::Error::success();
78 }
79 return llvm::createStringError(llvm::inconvertibleErrorCode(),
80 "invalid value for TagTypeKind");
81}
82
83llvm::Error decodeRecord(const Record &R, std::optional<Location> &Field,
84 llvm::StringRef Blob) {
85 if (R[0] > INT_MAX)
86 return llvm::createStringError(llvm::inconvertibleErrorCode(),
87 "integer too large to parse");
88 Field.emplace((int)R[0], Blob, (bool)R[1]);
89 return llvm::Error::success();
90}
91
92llvm::Error decodeRecord(const Record &R, InfoType &Field,
93 llvm::StringRef Blob) {
94 switch (auto IT = static_cast<InfoType>(R[0])) {
101 Field = IT;
102 return llvm::Error::success();
103 }
104 return llvm::createStringError(llvm::inconvertibleErrorCode(),
105 "invalid value for InfoType");
106}
107
108llvm::Error decodeRecord(const Record &R, FieldId &Field,
109 llvm::StringRef Blob) {
110 switch (auto F = static_cast<FieldId>(R[0])) {
114 case FieldId::F_type:
118 Field = F;
119 return llvm::Error::success();
120 }
121 return llvm::createStringError(llvm::inconvertibleErrorCode(),
122 "invalid value for FieldId");
123}
124
125llvm::Error decodeRecord(const Record &R,
126 llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
127 llvm::StringRef Blob) {
128 Field.push_back(Blob);
129 return llvm::Error::success();
130}
131
132llvm::Error decodeRecord(const Record &R,
134 llvm::StringRef Blob) {
135 if (R[0] > INT_MAX)
136 return llvm::createStringError(llvm::inconvertibleErrorCode(),
137 "integer too large to parse");
138 Field.emplace_back((int)R[0], Blob, (bool)R[1]);
139 return llvm::Error::success();
140}
141
142llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
143 const unsigned VersionNo) {
144 if (ID == VERSION && R[0] == VersionNo)
145 return llvm::Error::success();
146 return llvm::createStringError(llvm::inconvertibleErrorCode(),
147 "mismatched bitcode version number");
148}
149
150llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
151 NamespaceInfo *I) {
152 switch (ID) {
153 case NAMESPACE_USR:
154 return decodeRecord(R, I->USR, Blob);
155 case NAMESPACE_NAME:
156 return decodeRecord(R, I->Name, Blob);
157 case NAMESPACE_PATH:
158 return decodeRecord(R, I->Path, Blob);
159 default:
160 return llvm::createStringError(llvm::inconvertibleErrorCode(),
161 "invalid field for NamespaceInfo");
162 }
163}
164
165llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
166 RecordInfo *I) {
167 switch (ID) {
168 case RECORD_USR:
169 return decodeRecord(R, I->USR, Blob);
170 case RECORD_NAME:
171 return decodeRecord(R, I->Name, Blob);
172 case RECORD_PATH:
173 return decodeRecord(R, I->Path, Blob);
175 return decodeRecord(R, I->DefLoc, Blob);
176 case RECORD_LOCATION:
177 return decodeRecord(R, I->Loc, Blob);
178 case RECORD_TAG_TYPE:
179 return decodeRecord(R, I->TagType, Blob);
181 return decodeRecord(R, I->IsTypeDef, Blob);
182 default:
183 return llvm::createStringError(llvm::inconvertibleErrorCode(),
184 "invalid field for RecordInfo");
185 }
186}
187
188llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
189 BaseRecordInfo *I) {
190 switch (ID) {
191 case BASE_RECORD_USR:
192 return decodeRecord(R, I->USR, Blob);
193 case BASE_RECORD_NAME:
194 return decodeRecord(R, I->Name, Blob);
195 case BASE_RECORD_PATH:
196 return decodeRecord(R, I->Path, Blob);
198 return decodeRecord(R, I->TagType, Blob);
200 return decodeRecord(R, I->IsVirtual, Blob);
202 return decodeRecord(R, I->Access, Blob);
204 return decodeRecord(R, I->IsParent, Blob);
205 default:
206 return llvm::createStringError(llvm::inconvertibleErrorCode(),
207 "invalid field for BaseRecordInfo");
208 }
209}
210
211llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
212 EnumInfo *I) {
213 switch (ID) {
214 case ENUM_USR:
215 return decodeRecord(R, I->USR, Blob);
216 case ENUM_NAME:
217 return decodeRecord(R, I->Name, Blob);
218 case ENUM_DEFLOCATION:
219 return decodeRecord(R, I->DefLoc, Blob);
220 case ENUM_LOCATION:
221 return decodeRecord(R, I->Loc, Blob);
222 case ENUM_SCOPED:
223 return decodeRecord(R, I->Scoped, Blob);
224 default:
225 return llvm::createStringError(llvm::inconvertibleErrorCode(),
226 "invalid field for EnumInfo");
227 }
228}
229
230llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
231 TypedefInfo *I) {
232 switch (ID) {
233 case TYPEDEF_USR:
234 return decodeRecord(R, I->USR, Blob);
235 case TYPEDEF_NAME:
236 return decodeRecord(R, I->Name, Blob);
238 return decodeRecord(R, I->DefLoc, Blob);
239 case TYPEDEF_IS_USING:
240 return decodeRecord(R, I->IsUsing, Blob);
241 default:
242 return llvm::createStringError(llvm::inconvertibleErrorCode(),
243 "invalid field for TypedefInfo");
244 }
245}
246
247llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
248 EnumValueInfo *I) {
249 switch (ID) {
250 case ENUM_VALUE_NAME:
251 return decodeRecord(R, I->Name, Blob);
252 case ENUM_VALUE_VALUE:
253 return decodeRecord(R, I->Value, Blob);
254 case ENUM_VALUE_EXPR:
255 return decodeRecord(R, I->ValueExpr, Blob);
256 default:
257 return llvm::createStringError(llvm::inconvertibleErrorCode(),
258 "invalid field for EnumValueInfo");
259 }
260}
261
262llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
263 FunctionInfo *I) {
264 switch (ID) {
265 case FUNCTION_USR:
266 return decodeRecord(R, I->USR, Blob);
267 case FUNCTION_NAME:
268 return decodeRecord(R, I->Name, Blob);
270 return decodeRecord(R, I->DefLoc, Blob);
272 return decodeRecord(R, I->Loc, Blob);
273 case FUNCTION_ACCESS:
274 return decodeRecord(R, I->Access, Blob);
276 return decodeRecord(R, I->IsMethod, Blob);
277 default:
278 return llvm::createStringError(llvm::inconvertibleErrorCode(),
279 "invalid field for FunctionInfo");
280 }
281}
282
283llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
284 TypeInfo *I) {
285 return llvm::Error::success();
286}
287
288llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
289 FieldTypeInfo *I) {
290 switch (ID) {
291 case FIELD_TYPE_NAME:
292 return decodeRecord(R, I->Name, Blob);
294 return decodeRecord(R, I->DefaultValue, Blob);
295 default:
296 return llvm::createStringError(llvm::inconvertibleErrorCode(),
297 "invalid field for TypeInfo");
298 }
299}
300
301llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
302 MemberTypeInfo *I) {
303 switch (ID) {
304 case MEMBER_TYPE_NAME:
305 return decodeRecord(R, I->Name, Blob);
307 return decodeRecord(R, I->Access, Blob);
308 default:
309 return llvm::createStringError(llvm::inconvertibleErrorCode(),
310 "invalid field for MemberTypeInfo");
311 }
312}
313
314llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
315 CommentInfo *I) {
316 switch (ID) {
317 case COMMENT_KIND:
318 return decodeRecord(R, I->Kind, Blob);
319 case COMMENT_TEXT:
320 return decodeRecord(R, I->Text, Blob);
321 case COMMENT_NAME:
322 return decodeRecord(R, I->Name, Blob);
324 return decodeRecord(R, I->Direction, Blob);
326 return decodeRecord(R, I->ParamName, Blob);
328 return decodeRecord(R, I->CloseName, Blob);
329 case COMMENT_ATTRKEY:
330 return decodeRecord(R, I->AttrKeys, Blob);
331 case COMMENT_ATTRVAL:
332 return decodeRecord(R, I->AttrValues, Blob);
333 case COMMENT_ARG:
334 return decodeRecord(R, I->Args, Blob);
336 return decodeRecord(R, I->SelfClosing, Blob);
337 case COMMENT_EXPLICIT:
338 return decodeRecord(R, I->Explicit, Blob);
339 default:
340 return llvm::createStringError(llvm::inconvertibleErrorCode(),
341 "invalid field for CommentInfo");
342 }
343}
344
345llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
346 Reference *I, FieldId &F) {
347 switch (ID) {
348 case REFERENCE_USR:
349 return decodeRecord(R, I->USR, Blob);
350 case REFERENCE_NAME:
351 return decodeRecord(R, I->Name, Blob);
353 return decodeRecord(R, I->QualName, Blob);
354 case REFERENCE_TYPE:
355 return decodeRecord(R, I->RefType, Blob);
356 case REFERENCE_PATH:
357 return decodeRecord(R, I->Path, Blob);
358 case REFERENCE_FIELD:
359 return decodeRecord(R, F, Blob);
360 default:
361 return llvm::createStringError(llvm::inconvertibleErrorCode(),
362 "invalid field for Reference");
363 }
364}
365
366llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
367 TemplateInfo *I) {
368 // Currently there are no child records of TemplateInfo (only child blocks).
369 return llvm::createStringError(llvm::inconvertibleErrorCode(),
370 "invalid field for TemplateParamInfo");
371}
372
373llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
376 return decodeRecord(R, I->SpecializationOf, Blob);
377 return llvm::createStringError(llvm::inconvertibleErrorCode(),
378 "invalid field for TemplateParamInfo");
379}
380
381llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
384 return decodeRecord(R, I->Contents, Blob);
385 return llvm::createStringError(llvm::inconvertibleErrorCode(),
386 "invalid field for TemplateParamInfo");
387}
388
389template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) {
390 return llvm::createStringError(llvm::inconvertibleErrorCode(),
391 "invalid type cannot contain CommentInfo");
392}
393
394template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
395 return &I->Description.emplace_back();
396}
397
398template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
399 return &I->Description.emplace_back();
400}
401
402template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
403 return &I->Description.emplace_back();
404}
405
406template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) {
407 return &I->Description.emplace_back();
408}
409
410template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
411 return &I->Description.emplace_back();
412}
413
414template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
415 return &I->Description.emplace_back();
416}
417
418template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumValueInfo *I) {
419 return &I->Description.emplace_back();
420}
421
422template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
423 I->Children.emplace_back(std::make_unique<CommentInfo>());
424 return I->Children.back().get();
425}
426
427template <>
428llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
429 return getCommentInfo(I.get());
430}
431
432// When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
433// the parent block to set it. The template specializations define what to do
434// for each supported parent block.
435template <typename T, typename TTypeInfo>
436llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
437 return llvm::createStringError(llvm::inconvertibleErrorCode(),
438 "invalid type cannot contain TypeInfo");
439}
440
441template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
442 I->Members.emplace_back(std::move(T));
443 return llvm::Error::success();
444}
445
446template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) {
447 I->Members.emplace_back(std::move(T));
448 return llvm::Error::success();
449}
450
451template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
452 I->ReturnType = std::move(T);
453 return llvm::Error::success();
454}
455
456template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
457 I->Params.emplace_back(std::move(T));
458 return llvm::Error::success();
459}
460
461template <> llvm::Error addTypeInfo(EnumInfo *I, TypeInfo &&T) {
462 I->BaseType = std::move(T);
463 return llvm::Error::success();
464}
465
466template <> llvm::Error addTypeInfo(TypedefInfo *I, TypeInfo &&T) {
467 I->Underlying = std::move(T);
468 return llvm::Error::success();
469}
470
471template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) {
472 return llvm::createStringError(llvm::inconvertibleErrorCode(),
473 "invalid type cannot contain Reference");
474}
475
476template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) {
477 switch (F) {
478 case FieldId::F_type:
479 I->Type = std::move(R);
480 return llvm::Error::success();
481 default:
482 return llvm::createStringError(llvm::inconvertibleErrorCode(),
483 "invalid type cannot contain Reference");
484 }
485}
486
487template <>
489 switch (F) {
490 case FieldId::F_type:
491 I->Type = std::move(R);
492 return llvm::Error::success();
493 default:
494 return llvm::createStringError(llvm::inconvertibleErrorCode(),
495 "invalid type cannot contain Reference");
496 }
497}
498
499template <>
501 switch (F) {
502 case FieldId::F_type:
503 I->Type = std::move(R);
504 return llvm::Error::success();
505 default:
506 return llvm::createStringError(llvm::inconvertibleErrorCode(),
507 "invalid type cannot contain Reference");
508 }
509}
510
511template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
512 switch (F) {
514 I->Namespace.emplace_back(std::move(R));
515 return llvm::Error::success();
516 default:
517 return llvm::createStringError(llvm::inconvertibleErrorCode(),
518 "invalid type cannot contain Reference");
519 }
520}
521
522template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F) {
523 switch (F) {
525 I->Namespace.emplace_back(std::move(R));
526 return llvm::Error::success();
527 default:
528 return llvm::createStringError(llvm::inconvertibleErrorCode(),
529 "invalid type cannot contain Reference");
530 }
531}
532
533template <>
535 switch (F) {
537 I->Namespace.emplace_back(std::move(R));
538 return llvm::Error::success();
540 I->Children.Namespaces.emplace_back(std::move(R));
541 return llvm::Error::success();
543 I->Children.Records.emplace_back(std::move(R));
544 return llvm::Error::success();
545 default:
546 return llvm::createStringError(llvm::inconvertibleErrorCode(),
547 "invalid type cannot contain Reference");
548 }
549}
550
551template <>
553 switch (F) {
555 I->Namespace.emplace_back(std::move(R));
556 return llvm::Error::success();
558 I->Parent = std::move(R);
559 return llvm::Error::success();
560 default:
561 return llvm::createStringError(llvm::inconvertibleErrorCode(),
562 "invalid type cannot contain Reference");
563 }
564}
565
566template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
567 switch (F) {
569 I->Namespace.emplace_back(std::move(R));
570 return llvm::Error::success();
572 I->Parents.emplace_back(std::move(R));
573 return llvm::Error::success();
575 I->VirtualParents.emplace_back(std::move(R));
576 return llvm::Error::success();
578 I->Children.Records.emplace_back(std::move(R));
579 return llvm::Error::success();
580 default:
581 return llvm::createStringError(llvm::inconvertibleErrorCode(),
582 "invalid type cannot contain Reference");
583 }
584}
585
586template <typename T, typename ChildInfoType>
587void addChild(T I, ChildInfoType &&R) {
588 llvm::errs() << "invalid child type for info";
589 exit(1);
590}
591
592// Namespace children:
593template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
594 I->Children.Functions.emplace_back(std::move(R));
595}
596template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
597 I->Children.Enums.emplace_back(std::move(R));
598}
599template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
600 I->Children.Typedefs.emplace_back(std::move(R));
601}
602
603// Record children:
604template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
605 I->Children.Functions.emplace_back(std::move(R));
606}
607template <> void addChild(RecordInfo *I, EnumInfo &&R) {
608 I->Children.Enums.emplace_back(std::move(R));
609}
610template <> void addChild(RecordInfo *I, TypedefInfo &&R) {
611 I->Children.Typedefs.emplace_back(std::move(R));
612}
613
614// Other types of children:
615template <> void addChild(EnumInfo *I, EnumValueInfo &&R) {
616 I->Members.emplace_back(std::move(R));
617}
618template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) {
619 I->Bases.emplace_back(std::move(R));
620}
621template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) {
622 I->Children.Functions.emplace_back(std::move(R));
623}
624
625// TemplateParam children. These go into either a TemplateInfo (for template
626// parameters) or TemplateSpecializationInfo (for the specialization's
627// parameters).
628template <typename T> void addTemplateParam(T I, TemplateParamInfo &&P) {
629 llvm::errs() << "invalid container for template parameter";
630 exit(1);
631}
633 I->Params.emplace_back(std::move(P));
634}
635template <>
637 I->Params.emplace_back(std::move(P));
638}
639
640// Template info. These apply to either records or functions.
641template <typename T> void addTemplate(T I, TemplateInfo &&P) {
642 llvm::errs() << "invalid container for template info";
643 exit(1);
644}
645template <> void addTemplate(RecordInfo *I, TemplateInfo &&P) {
646 I->Template.emplace(std::move(P));
647}
648template <> void addTemplate(FunctionInfo *I, TemplateInfo &&P) {
649 I->Template.emplace(std::move(P));
650}
651
652// Template specializations go only into template records.
653template <typename T>
655 llvm::errs() << "invalid container for template specialization info";
656 exit(1);
657}
658template <>
661 I->Specialization.emplace(std::move(TSI));
662}
663
664// Read records from bitcode into a given info.
665template <typename T>
666llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
667 Record R;
668 llvm::StringRef Blob;
669 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
670 if (!MaybeRecID)
671 return MaybeRecID.takeError();
672 return parseRecord(R, MaybeRecID.get(), Blob, I);
673}
674
675template <>
676llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
677 Record R;
678 llvm::StringRef Blob;
679 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
680 if (!MaybeRecID)
681 return MaybeRecID.takeError();
682 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
683}
684
685// Read a block of records into a single info.
686template <typename T>
687llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
688 if (llvm::Error Err = Stream.EnterSubBlock(ID))
689 return Err;
690
691 while (true) {
692 unsigned BlockOrCode = 0;
693 Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
694
695 switch (Res) {
696 case Cursor::BadBlock:
697 return llvm::createStringError(llvm::inconvertibleErrorCode(),
698 "bad block found");
699 case Cursor::BlockEnd:
700 return llvm::Error::success();
701 case Cursor::BlockBegin:
702 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
703 if (llvm::Error Skipped = Stream.SkipBlock())
704 return joinErrors(std::move(Err), std::move(Skipped));
705 return Err;
706 }
707 continue;
708 case Cursor::Record:
709 break;
710 }
711 if (auto Err = readRecord(BlockOrCode, I))
712 return Err;
713 }
714}
715
716template <typename T>
717llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
718 switch (ID) {
719 // Blocks can only have certain types of sub blocks.
720 case BI_COMMENT_BLOCK_ID: {
721 auto Comment = getCommentInfo(I);
722 if (!Comment)
723 return Comment.takeError();
724 if (auto Err = readBlock(ID, Comment.get()))
725 return Err;
726 return llvm::Error::success();
727 }
728 case BI_TYPE_BLOCK_ID: {
729 TypeInfo TI;
730 if (auto Err = readBlock(ID, &TI))
731 return Err;
732 if (auto Err = addTypeInfo(I, std::move(TI)))
733 return Err;
734 return llvm::Error::success();
735 }
737 FieldTypeInfo TI;
738 if (auto Err = readBlock(ID, &TI))
739 return Err;
740 if (auto Err = addTypeInfo(I, std::move(TI)))
741 return Err;
742 return llvm::Error::success();
743 }
745 MemberTypeInfo TI;
746 if (auto Err = readBlock(ID, &TI))
747 return Err;
748 if (auto Err = addTypeInfo(I, std::move(TI)))
749 return Err;
750 return llvm::Error::success();
751 }
753 Reference R;
754 if (auto Err = readBlock(ID, &R))
755 return Err;
756 if (auto Err = addReference(I, std::move(R), CurrentReferenceField))
757 return Err;
758 return llvm::Error::success();
759 }
761 FunctionInfo F;
762 if (auto Err = readBlock(ID, &F))
763 return Err;
764 addChild(I, std::move(F));
765 return llvm::Error::success();
766 }
768 BaseRecordInfo BR;
769 if (auto Err = readBlock(ID, &BR))
770 return Err;
771 addChild(I, std::move(BR));
772 return llvm::Error::success();
773 }
774 case BI_ENUM_BLOCK_ID: {
775 EnumInfo E;
776 if (auto Err = readBlock(ID, &E))
777 return Err;
778 addChild(I, std::move(E));
779 return llvm::Error::success();
780 }
782 EnumValueInfo EV;
783 if (auto Err = readBlock(ID, &EV))
784 return Err;
785 addChild(I, std::move(EV));
786 return llvm::Error::success();
787 }
789 TemplateInfo TI;
790 if (auto Err = readBlock(ID, &TI))
791 return Err;
792 addTemplate(I, std::move(TI));
793 return llvm::Error::success();
794 }
796 TemplateSpecializationInfo TSI;
797 if (auto Err = readBlock(ID, &TSI))
798 return Err;
799 addTemplateSpecialization(I, std::move(TSI));
800 return llvm::Error::success();
801 }
803 TemplateParamInfo TPI;
804 if (auto Err = readBlock(ID, &TPI))
805 return Err;
806 addTemplateParam(I, std::move(TPI));
807 return llvm::Error::success();
808 }
809 case BI_TYPEDEF_BLOCK_ID: {
810 TypedefInfo TI;
811 if (auto Err = readBlock(ID, &TI))
812 return Err;
813 addChild(I, std::move(TI));
814 return llvm::Error::success();
815 }
816 default:
817 return llvm::createStringError(llvm::inconvertibleErrorCode(),
818 "invalid subblock type");
819 }
820}
821
822ClangDocBitcodeReader::Cursor
823ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
824 BlockOrRecordID = 0;
825
826 while (!Stream.AtEndOfStream()) {
827 Expected<unsigned> MaybeCode = Stream.ReadCode();
828 if (!MaybeCode) {
829 // FIXME this drops the error on the floor.
830 consumeError(MaybeCode.takeError());
831 return Cursor::BadBlock;
832 }
833
834 unsigned Code = MaybeCode.get();
835 if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
836 BlockOrRecordID = Code;
837 return Cursor::Record;
838 }
839 switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
840 case llvm::bitc::ENTER_SUBBLOCK:
841 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
842 BlockOrRecordID = MaybeID.get();
843 else {
844 // FIXME this drops the error on the floor.
845 consumeError(MaybeID.takeError());
846 }
847 return Cursor::BlockBegin;
848 case llvm::bitc::END_BLOCK:
849 if (Stream.ReadBlockEnd())
850 return Cursor::BadBlock;
851 return Cursor::BlockEnd;
852 case llvm::bitc::DEFINE_ABBREV:
853 if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
854 // FIXME this drops the error on the floor.
855 consumeError(std::move(Err));
856 }
857 continue;
858 case llvm::bitc::UNABBREV_RECORD:
859 return Cursor::BadBlock;
860 case llvm::bitc::FIRST_APPLICATION_ABBREV:
861 llvm_unreachable("Unexpected abbrev id.");
862 }
863 }
864 llvm_unreachable("Premature stream end.");
865}
866
867llvm::Error ClangDocBitcodeReader::validateStream() {
868 if (Stream.AtEndOfStream())
869 return llvm::createStringError(llvm::inconvertibleErrorCode(),
870 "premature end of stream");
871
872 // Sniff for the signature.
873 for (int Idx = 0; Idx != 4; ++Idx) {
874 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
875 if (!MaybeRead)
876 return MaybeRead.takeError();
877 else if (MaybeRead.get() != BitCodeConstants::Signature[Idx])
878 return llvm::createStringError(llvm::inconvertibleErrorCode(),
879 "invalid bitcode signature");
880 }
881 return llvm::Error::success();
882}
883
884llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
885 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
886 Stream.ReadBlockInfoBlock();
887 if (!MaybeBlockInfo)
888 return MaybeBlockInfo.takeError();
889 else
890 BlockInfo = MaybeBlockInfo.get();
891 if (!BlockInfo)
892 return llvm::createStringError(llvm::inconvertibleErrorCode(),
893 "unable to parse BlockInfoBlock");
894 Stream.setBlockInfo(&*BlockInfo);
895 return llvm::Error::success();
896}
897
898template <typename T>
899llvm::Expected<std::unique_ptr<Info>>
900ClangDocBitcodeReader::createInfo(unsigned ID) {
901 std::unique_ptr<Info> I = std::make_unique<T>();
902 if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
903 return std::move(Err);
904 return std::unique_ptr<Info>{std::move(I)};
905}
906
907llvm::Expected<std::unique_ptr<Info>>
908ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
909 switch (ID) {
911 return createInfo<NamespaceInfo>(ID);
913 return createInfo<RecordInfo>(ID);
914 case BI_ENUM_BLOCK_ID:
915 return createInfo<EnumInfo>(ID);
917 return createInfo<TypedefInfo>(ID);
919 return createInfo<FunctionInfo>(ID);
920 default:
921 return llvm::createStringError(llvm::inconvertibleErrorCode(),
922 "cannot create info");
923 }
924}
925
926// Entry point
927llvm::Expected<std::vector<std::unique_ptr<Info>>>
929 std::vector<std::unique_ptr<Info>> Infos;
930 if (auto Err = validateStream())
931 return std::move(Err);
932
933 // Read the top level blocks.
934 while (!Stream.AtEndOfStream()) {
935 Expected<unsigned> MaybeCode = Stream.ReadCode();
936 if (!MaybeCode)
937 return MaybeCode.takeError();
938 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
939 return llvm::createStringError(llvm::inconvertibleErrorCode(),
940 "no blocks in input");
941 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
942 if (!MaybeID)
943 return MaybeID.takeError();
944 unsigned ID = MaybeID.get();
945 switch (ID) {
946 // NamedType and Comment blocks should not appear at the top level
947 case BI_TYPE_BLOCK_ID:
952 return llvm::createStringError(llvm::inconvertibleErrorCode(),
953 "invalid top level block");
956 case BI_ENUM_BLOCK_ID:
959 auto InfoOrErr = readBlockToInfo(ID);
960 if (!InfoOrErr)
961 return InfoOrErr.takeError();
962 Infos.emplace_back(std::move(InfoOrErr.get()));
963 continue;
964 }
966 if (auto Err = readBlock(ID, VersionNumber))
967 return std::move(Err);
968 continue;
969 case llvm::bitc::BLOCKINFO_BLOCK_ID:
970 if (auto Err = readBlockInfoBlock())
971 return std::move(Err);
972 continue;
973 default:
974 if (llvm::Error Err = Stream.SkipBlock()) {
975 // FIXME this drops the error on the floor.
976 consumeError(std::move(Err));
977 }
978 continue;
979 }
980 }
981 return std::move(Infos);
982}
983
984} // namespace doc
985} // namespace clang
const Expr * E
QualType TypeInfo
const FieldDecl * Field
llvm::Expected< std::vector< std::unique_ptr< Info > > > readBitcode()
llvm::SmallVector< uint64_t, 1024 > Record
llvm::Error addReference(T I, Reference &&R, FieldId F)
void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI)
void addTemplateParam(T I, TemplateParamInfo &&P)
@ 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
void addTemplate(T I, TemplateInfo &&P)
llvm::Expected< CommentInfo * > getCommentInfo(T I)
static const unsigned VersionNumber
Definition: BitcodeWriter.h:33
llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)
void addChild(T I, ChildInfoType &&R)
llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
std::array< uint8_t, 20 > SymbolID
@ 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
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static constexpr unsigned char Signature[4]
Definition: BitcodeWriter.h:47
static constexpr int USRHashSize
Definition: BitcodeWriter.h:48
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
SmallString< 16 > Name
SmallString< 16 > DefaultValue
llvm::SmallVector< FieldTypeInfo, 4 > Params
std::optional< TemplateInfo > Template
SmallString< 16 > Name
std::vector< CommentInfo > Description
llvm::SmallString< 128 > Path
llvm::SmallVector< Reference, 4 > Namespace
std::vector< CommentInfo > Description
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
std::vector< TemplateParamInfo > Params
std::optional< TemplateSpecializationInfo > Specialization
std::vector< TemplateParamInfo > Params