clang-tools 22.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/TimeProfiler.h"
13#include "llvm/Support/raw_ostream.h"
14#include <optional>
15
16namespace clang {
17namespace doc {
18
19using Record = llvm::SmallVector<uint64_t, 1024>;
20
21// This implements decode for SmallString.
22static llvm::Error decodeRecord(const Record &R,
24 llvm::StringRef Blob) {
25 Field.assign(Blob.begin(), Blob.end());
26 return llvm::Error::success();
27}
28
29static llvm::Error decodeRecord(const Record &R, SymbolID &Field,
30 llvm::StringRef Blob) {
32 return llvm::createStringError(llvm::inconvertibleErrorCode(),
33 "incorrect USR size");
34
35 // First position in the record is the length of the following array, so we
36 // copy the following elements to the field.
37 for (int I = 0, E = R[0]; I < E; ++I)
38 Field[I] = R[I + 1];
39 return llvm::Error::success();
40}
41
42static llvm::Error decodeRecord(const Record &R, bool &Field,
43 llvm::StringRef Blob) {
44 Field = R[0] != 0;
45 return llvm::Error::success();
46}
47
48static llvm::Error decodeRecord(const Record &R, AccessSpecifier &Field,
49 llvm::StringRef Blob) {
50 switch (R[0]) {
51 case AS_public:
52 case AS_private:
53 case AS_protected:
54 case AS_none:
55 Field = (AccessSpecifier)R[0];
56 return llvm::Error::success();
57 }
58 llvm_unreachable("invalid value for AccessSpecifier");
59}
60
61static llvm::Error decodeRecord(const Record &R, TagTypeKind &Field,
62 llvm::StringRef Blob) {
63 switch (static_cast<TagTypeKind>(R[0])) {
64 case TagTypeKind::Struct:
65 case TagTypeKind::Interface:
66 case TagTypeKind::Union:
67 case TagTypeKind::Class:
68 case TagTypeKind::Enum:
69 Field = static_cast<TagTypeKind>(R[0]);
70 return llvm::Error::success();
71 }
72 return llvm::createStringError(llvm::inconvertibleErrorCode(),
73 "invalid value for TagTypeKind");
74}
75
76static llvm::Error decodeRecord(const Record &R, std::optional<Location> &Field,
77 llvm::StringRef Blob) {
78 if (R[0] > INT_MAX)
79 return llvm::createStringError(llvm::inconvertibleErrorCode(),
80 "integer too large to parse");
81 Field.emplace(static_cast<int>(R[0]), static_cast<int>(R[1]), Blob,
82 static_cast<bool>(R[2]));
83 return llvm::Error::success();
84}
85
86static llvm::Error decodeRecord(const Record &R, InfoType &Field,
87 llvm::StringRef Blob) {
88 switch (auto IT = static_cast<InfoType>(R[0])) {
98 Field = IT;
99 return llvm::Error::success();
100 }
101 return llvm::createStringError(llvm::inconvertibleErrorCode(),
102 "invalid value for InfoType");
103}
104
105static llvm::Error decodeRecord(const Record &R, FieldId &Field,
106 llvm::StringRef Blob) {
107 switch (auto F = static_cast<FieldId>(R[0])) {
111 case FieldId::F_type:
117 Field = F;
118 return llvm::Error::success();
119 }
120 return llvm::createStringError(llvm::inconvertibleErrorCode(),
121 "invalid value for FieldId");
122}
123
124static llvm::Error
126 llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
127 llvm::StringRef Blob) {
128 Field.push_back(Blob);
129 return llvm::Error::success();
130}
131
132static llvm::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(static_cast<int>(R[0]), static_cast<int>(R[1]), Blob,
139 static_cast<bool>(R[2]));
140 return llvm::Error::success();
141}
142
143static llvm::Error parseRecord(const Record &R, unsigned ID,
144 llvm::StringRef Blob, const unsigned VersionNo) {
145 if (ID == VERSION && R[0] == VersionNo)
146 return llvm::Error::success();
147 return llvm::createStringError(llvm::inconvertibleErrorCode(),
148 "mismatched bitcode version number");
149}
150
151static llvm::Error parseRecord(const Record &R, unsigned ID,
152 llvm::StringRef Blob, NamespaceInfo *I) {
153 switch (ID) {
154 case NAMESPACE_USR:
155 return decodeRecord(R, I->USR, Blob);
156 case NAMESPACE_NAME:
157 return decodeRecord(R, I->Name, Blob);
158 case NAMESPACE_PATH:
159 return decodeRecord(R, I->Path, Blob);
160 default:
161 return llvm::createStringError(llvm::inconvertibleErrorCode(),
162 "invalid field for NamespaceInfo");
163 }
164}
165
166static llvm::Error parseRecord(const Record &R, unsigned ID,
167 llvm::StringRef Blob, RecordInfo *I) {
168 switch (ID) {
169 case RECORD_USR:
170 return decodeRecord(R, I->USR, Blob);
171 case RECORD_NAME:
172 return decodeRecord(R, I->Name, Blob);
173 case RECORD_PATH:
174 return decodeRecord(R, I->Path, Blob);
176 return decodeRecord(R, I->DefLoc, Blob);
177 case RECORD_LOCATION:
178 return decodeRecord(R, I->Loc, Blob);
179 case RECORD_TAG_TYPE:
180 return decodeRecord(R, I->TagType, Blob);
182 return decodeRecord(R, I->IsTypeDef, Blob);
184 return decodeRecord(R, I->MangledName, Blob);
185 default:
186 return llvm::createStringError(llvm::inconvertibleErrorCode(),
187 "invalid field for RecordInfo");
188 }
189}
190
191static llvm::Error parseRecord(const Record &R, unsigned ID,
192 llvm::StringRef Blob, BaseRecordInfo *I) {
193 switch (ID) {
194 case BASE_RECORD_USR:
195 return decodeRecord(R, I->USR, Blob);
196 case BASE_RECORD_NAME:
197 return decodeRecord(R, I->Name, Blob);
198 case BASE_RECORD_PATH:
199 return decodeRecord(R, I->Path, Blob);
201 return decodeRecord(R, I->TagType, Blob);
203 return decodeRecord(R, I->IsVirtual, Blob);
205 return decodeRecord(R, I->Access, Blob);
207 return decodeRecord(R, I->IsParent, Blob);
208 default:
209 return llvm::createStringError(llvm::inconvertibleErrorCode(),
210 "invalid field for BaseRecordInfo");
211 }
212}
213
214static llvm::Error parseRecord(const Record &R, unsigned ID,
215 llvm::StringRef Blob, EnumInfo *I) {
216 switch (ID) {
217 case ENUM_USR:
218 return decodeRecord(R, I->USR, Blob);
219 case ENUM_NAME:
220 return decodeRecord(R, I->Name, Blob);
221 case ENUM_DEFLOCATION:
222 return decodeRecord(R, I->DefLoc, Blob);
223 case ENUM_LOCATION:
224 return decodeRecord(R, I->Loc, Blob);
225 case ENUM_SCOPED:
226 return decodeRecord(R, I->Scoped, Blob);
227 default:
228 return llvm::createStringError(llvm::inconvertibleErrorCode(),
229 "invalid field for EnumInfo");
230 }
231}
232
233static llvm::Error parseRecord(const Record &R, unsigned ID,
234 llvm::StringRef Blob, TypedefInfo *I) {
235 switch (ID) {
236 case TYPEDEF_USR:
237 return decodeRecord(R, I->USR, Blob);
238 case TYPEDEF_NAME:
239 return decodeRecord(R, I->Name, Blob);
241 return decodeRecord(R, I->DefLoc, Blob);
242 case TYPEDEF_IS_USING:
243 return decodeRecord(R, I->IsUsing, Blob);
244 default:
245 return llvm::createStringError(llvm::inconvertibleErrorCode(),
246 "invalid field for TypedefInfo");
247 }
248}
249
250static llvm::Error parseRecord(const Record &R, unsigned ID,
251 llvm::StringRef Blob, EnumValueInfo *I) {
252 switch (ID) {
253 case ENUM_VALUE_NAME:
254 return decodeRecord(R, I->Name, Blob);
255 case ENUM_VALUE_VALUE:
256 return decodeRecord(R, I->Value, Blob);
257 case ENUM_VALUE_EXPR:
258 return decodeRecord(R, I->ValueExpr, Blob);
259 default:
260 return llvm::createStringError(llvm::inconvertibleErrorCode(),
261 "invalid field for EnumValueInfo");
262 }
263}
264
265static llvm::Error parseRecord(const Record &R, unsigned ID,
266 llvm::StringRef Blob, FunctionInfo *I) {
267 switch (ID) {
268 case FUNCTION_USR:
269 return decodeRecord(R, I->USR, Blob);
270 case FUNCTION_NAME:
271 return decodeRecord(R, I->Name, Blob);
273 return decodeRecord(R, I->DefLoc, Blob);
275 return decodeRecord(R, I->Loc, Blob);
276 case FUNCTION_ACCESS:
277 return decodeRecord(R, I->Access, Blob);
279 return decodeRecord(R, I->IsMethod, Blob);
281 return decodeRecord(R, I->IsStatic, Blob);
282 default:
283 return llvm::createStringError(llvm::inconvertibleErrorCode(),
284 "invalid field for FunctionInfo");
285 }
286}
287
288static llvm::Error parseRecord(const Record &R, unsigned ID,
289 llvm::StringRef Blob, TypeInfo *I) {
290 switch (ID) {
291 case TYPE_IS_BUILTIN:
292 return decodeRecord(R, I->IsBuiltIn, Blob);
293 case TYPE_IS_TEMPLATE:
294 return decodeRecord(R, I->IsTemplate, Blob);
295 default:
296 return llvm::createStringError(llvm::inconvertibleErrorCode(),
297 "invalid field for TypeInfo");
298 }
299}
300
301static llvm::Error parseRecord(const Record &R, unsigned ID,
302 llvm::StringRef Blob, FieldTypeInfo *I) {
303 switch (ID) {
304 case FIELD_TYPE_NAME:
305 return decodeRecord(R, I->Name, Blob);
307 return decodeRecord(R, I->DefaultValue, Blob);
309 return decodeRecord(R, I->IsBuiltIn, Blob);
311 return decodeRecord(R, I->IsTemplate, Blob);
312 default:
313 return llvm::createStringError(llvm::inconvertibleErrorCode(),
314 "invalid field for TypeInfo");
315 }
316}
317
318static llvm::Error parseRecord(const Record &R, unsigned ID,
319 llvm::StringRef Blob, MemberTypeInfo *I) {
320 switch (ID) {
321 case MEMBER_TYPE_NAME:
322 return decodeRecord(R, I->Name, Blob);
324 return decodeRecord(R, I->Access, Blob);
326 return decodeRecord(R, I->IsStatic, Blob);
328 return decodeRecord(R, I->IsBuiltIn, Blob);
330 return decodeRecord(R, I->IsTemplate, Blob);
331 default:
332 return llvm::createStringError(llvm::inconvertibleErrorCode(),
333 "invalid field for MemberTypeInfo");
334 }
335}
336
337static llvm::Error parseRecord(const Record &R, unsigned ID,
338 llvm::StringRef Blob, CommentInfo *I) {
339 llvm::SmallString<16> KindStr;
340 switch (ID) {
341 case COMMENT_KIND:
342 if (llvm::Error Err = decodeRecord(R, KindStr, Blob))
343 return Err;
344 I->Kind = stringToCommentKind(KindStr);
345 return llvm::Error::success();
346 case COMMENT_TEXT:
347 return decodeRecord(R, I->Text, Blob);
348 case COMMENT_NAME:
349 return decodeRecord(R, I->Name, Blob);
351 return decodeRecord(R, I->Direction, Blob);
353 return decodeRecord(R, I->ParamName, Blob);
355 return decodeRecord(R, I->CloseName, Blob);
356 case COMMENT_ATTRKEY:
357 return decodeRecord(R, I->AttrKeys, Blob);
358 case COMMENT_ATTRVAL:
359 return decodeRecord(R, I->AttrValues, Blob);
360 case COMMENT_ARG:
361 return decodeRecord(R, I->Args, Blob);
363 return decodeRecord(R, I->SelfClosing, Blob);
364 case COMMENT_EXPLICIT:
365 return decodeRecord(R, I->Explicit, Blob);
366 default:
367 return llvm::createStringError(llvm::inconvertibleErrorCode(),
368 "invalid field for CommentInfo");
369 }
370}
371
372static llvm::Error parseRecord(const Record &R, unsigned ID,
373 llvm::StringRef Blob, Reference *I, FieldId &F) {
374 switch (ID) {
375 case REFERENCE_USR:
376 return decodeRecord(R, I->USR, Blob);
377 case REFERENCE_NAME:
378 return decodeRecord(R, I->Name, Blob);
380 return decodeRecord(R, I->QualName, Blob);
381 case REFERENCE_TYPE:
382 return decodeRecord(R, I->RefType, Blob);
383 case REFERENCE_PATH:
384 return decodeRecord(R, I->Path, Blob);
385 case REFERENCE_FIELD:
386 return decodeRecord(R, F, Blob);
387 case REFERENCE_FILE:
388 return decodeRecord(R, I->DocumentationFileName, Blob);
389 default:
390 return llvm::createStringError(llvm::inconvertibleErrorCode(),
391 "invalid field for Reference");
392 }
393}
394
395static llvm::Error parseRecord(const Record &R, unsigned ID,
396 llvm::StringRef Blob, TemplateInfo *I) {
397 // Currently there are no child records of TemplateInfo (only child blocks).
398 return llvm::createStringError(llvm::inconvertibleErrorCode(),
399 "invalid field for TemplateParamInfo");
400}
401
402static llvm::Error parseRecord(const Record &R, unsigned ID,
403 llvm::StringRef Blob,
406 return decodeRecord(R, I->SpecializationOf, Blob);
407 return llvm::createStringError(llvm::inconvertibleErrorCode(),
408 "invalid field for TemplateParamInfo");
409}
410
411static llvm::Error parseRecord(const Record &R, unsigned ID,
412 llvm::StringRef Blob, TemplateParamInfo *I) {
413 if (ID == TEMPLATE_PARAM_CONTENTS)
414 return decodeRecord(R, I->Contents, Blob);
415 return llvm::createStringError(llvm::inconvertibleErrorCode(),
416 "invalid field for TemplateParamInfo");
417}
418
419static llvm::Error parseRecord(const Record &R, unsigned ID,
420 llvm::StringRef Blob, ConceptInfo *I) {
421 switch (ID) {
422 case CONCEPT_USR:
423 return decodeRecord(R, I->USR, Blob);
424 case CONCEPT_NAME:
425 return decodeRecord(R, I->Name, Blob);
426 case CONCEPT_IS_TYPE:
427 return decodeRecord(R, I->IsType, Blob);
429 return decodeRecord(R, I->ConstraintExpression, Blob);
430 }
431 llvm_unreachable("invalid field for ConceptInfo");
432}
433
434static llvm::Error parseRecord(const Record &R, unsigned ID,
435 llvm::StringRef Blob, ConstraintInfo *I) {
436 if (ID == CONSTRAINT_EXPRESSION)
437 return decodeRecord(R, I->ConstraintExpr, Blob);
438 return llvm::createStringError(llvm::inconvertibleErrorCode(),
439 "invalid field for ConstraintInfo");
440}
441
442static llvm::Error parseRecord(const Record &R, unsigned ID,
443 llvm::StringRef Blob, VarInfo *I) {
444 switch (ID) {
445 case VAR_USR:
446 return decodeRecord(R, I->USR, Blob);
447 case VAR_NAME:
448 return decodeRecord(R, I->Name, Blob);
449 case VAR_DEFLOCATION:
450 return decodeRecord(R, I->DefLoc, Blob);
451 case VAR_IS_STATIC:
452 return decodeRecord(R, I->IsStatic, Blob);
453 default:
454 return llvm::createStringError(llvm::inconvertibleErrorCode(),
455 "invalid field for VarInfo");
456 }
457}
458
459static llvm::Error parseRecord(const Record &R, unsigned ID, StringRef Blob,
460 FriendInfo *F) {
461 if (ID == FRIEND_IS_CLASS) {
462 return decodeRecord(R, F->IsClass, Blob);
463 }
464 return llvm::createStringError(llvm::inconvertibleErrorCode(),
465 "invalid field for Friend");
466}
467
468template <typename T> static llvm::Expected<CommentInfo *> getCommentInfo(T I) {
469 return llvm::createStringError(llvm::inconvertibleErrorCode(),
470 "invalid type cannot contain CommentInfo");
471}
472
473template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
474 return &I->Description.emplace_back();
475}
476
477template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
478 return &I->Description.emplace_back();
479}
480
481template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
482 return &I->Description.emplace_back();
483}
484
485template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) {
486 return &I->Description.emplace_back();
487}
488
489template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
490 return &I->Description.emplace_back();
491}
492
493template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
494 return &I->Description.emplace_back();
495}
496
497template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumValueInfo *I) {
498 return &I->Description.emplace_back();
499}
500
501template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
502 I->Children.emplace_back(std::make_unique<CommentInfo>());
503 return I->Children.back().get();
504}
505
506template <> llvm::Expected<CommentInfo *> getCommentInfo(ConceptInfo *I) {
507 return &I->Description.emplace_back();
508}
509
510template <> Expected<CommentInfo *> getCommentInfo(VarInfo *I) {
511 return &I->Description.emplace_back();
512}
513
514// When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
515// the parent block to set it. The template specializations define what to do
516// for each supported parent block.
517template <typename T, typename TTypeInfo>
518static llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
519 return llvm::createStringError(llvm::inconvertibleErrorCode(),
520 "invalid type cannot contain TypeInfo");
521}
522
523template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
524 I->Members.emplace_back(std::move(T));
525 return llvm::Error::success();
526}
527
528template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) {
529 I->Members.emplace_back(std::move(T));
530 return llvm::Error::success();
531}
532
533template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
534 I->ReturnType = std::move(T);
535 return llvm::Error::success();
536}
537
538template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
539 I->Params.emplace_back(std::move(T));
540 return llvm::Error::success();
541}
542
543template <> llvm::Error addTypeInfo(FriendInfo *I, FieldTypeInfo &&T) {
544 if (!I->Params)
545 I->Params.emplace();
546 I->Params->emplace_back(std::move(T));
547 return llvm::Error::success();
548}
549
550template <> llvm::Error addTypeInfo(FriendInfo *I, TypeInfo &&T) {
551 I->ReturnType.emplace(std::move(T));
552 return llvm::Error::success();
553}
554
555template <> llvm::Error addTypeInfo(EnumInfo *I, TypeInfo &&T) {
556 I->BaseType = std::move(T);
557 return llvm::Error::success();
558}
559
560template <> llvm::Error addTypeInfo(TypedefInfo *I, TypeInfo &&T) {
561 I->Underlying = std::move(T);
562 return llvm::Error::success();
563}
564
565template <> llvm::Error addTypeInfo(VarInfo *I, TypeInfo &&T) {
566 I->Type = std::move(T);
567 return llvm::Error::success();
568}
569
570template <typename T>
571static llvm::Error addReference(T I, Reference &&R, FieldId F) {
572 return llvm::createStringError(llvm::inconvertibleErrorCode(),
573 "invalid type cannot contain Reference");
574}
575
576template <> llvm::Error addReference(VarInfo *I, Reference &&R, FieldId F) {
577 switch (F) {
579 I->Namespace.emplace_back(std::move(R));
580 return llvm::Error::success();
581 default:
582 return llvm::createStringError(llvm::inconvertibleErrorCode(),
583 "VarInfo cannot contain this Reference");
584 }
585}
586
587template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) {
588 switch (F) {
589 case FieldId::F_type:
590 I->Type = std::move(R);
591 return llvm::Error::success();
592 default:
593 return llvm::createStringError(llvm::inconvertibleErrorCode(),
594 "invalid type cannot contain Reference");
595 }
596}
597
598template <>
600 switch (F) {
601 case FieldId::F_type:
602 I->Type = std::move(R);
603 return llvm::Error::success();
604 default:
605 return llvm::createStringError(llvm::inconvertibleErrorCode(),
606 "invalid type cannot contain Reference");
607 }
608}
609
610template <>
612 switch (F) {
613 case FieldId::F_type:
614 I->Type = std::move(R);
615 return llvm::Error::success();
616 default:
617 return llvm::createStringError(llvm::inconvertibleErrorCode(),
618 "invalid type cannot contain Reference");
619 }
620}
621
622template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
623 switch (F) {
625 I->Namespace.emplace_back(std::move(R));
626 return llvm::Error::success();
627 default:
628 return llvm::createStringError(llvm::inconvertibleErrorCode(),
629 "invalid type cannot contain Reference");
630 }
631}
632
633template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F) {
634 switch (F) {
636 I->Namespace.emplace_back(std::move(R));
637 return llvm::Error::success();
638 default:
639 return llvm::createStringError(llvm::inconvertibleErrorCode(),
640 "invalid type cannot contain Reference");
641 }
642}
643
644template <>
646 switch (F) {
648 I->Namespace.emplace_back(std::move(R));
649 return llvm::Error::success();
651 I->Children.Namespaces.emplace_back(std::move(R));
652 return llvm::Error::success();
654 I->Children.Records.emplace_back(std::move(R));
655 return llvm::Error::success();
656 default:
657 return llvm::createStringError(llvm::inconvertibleErrorCode(),
658 "invalid type cannot contain Reference");
659 }
660}
661
662template <>
664 switch (F) {
666 I->Namespace.emplace_back(std::move(R));
667 return llvm::Error::success();
669 I->Parent = std::move(R);
670 return llvm::Error::success();
671 default:
672 return llvm::createStringError(llvm::inconvertibleErrorCode(),
673 "invalid type cannot contain Reference");
674 }
675}
676
677template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
678 switch (F) {
680 I->Namespace.emplace_back(std::move(R));
681 return llvm::Error::success();
683 I->Parents.emplace_back(std::move(R));
684 return llvm::Error::success();
686 I->VirtualParents.emplace_back(std::move(R));
687 return llvm::Error::success();
689 I->Children.Records.emplace_back(std::move(R));
690 return llvm::Error::success();
691 default:
692 return llvm::createStringError(llvm::inconvertibleErrorCode(),
693 "invalid type cannot contain Reference");
694 }
695}
696
697template <>
699 if (F == FieldId::F_concept) {
700 I->ConceptRef = std::move(R);
701 return llvm::Error::success();
702 }
703 return llvm::createStringError(
704 llvm::inconvertibleErrorCode(),
705 "ConstraintInfo cannot contain this Reference");
706}
707
708template <>
709llvm::Error addReference(FriendInfo *Friend, Reference &&R, FieldId F) {
710 if (F == FieldId::F_friend) {
711 Friend->Ref = std::move(R);
712 return llvm::Error::success();
713 }
714 return llvm::createStringError(llvm::inconvertibleErrorCode(),
715 "Friend cannot contain this Reference");
716}
717
718template <typename T, typename ChildInfoType>
719static void addChild(T I, ChildInfoType &&R) {
720 llvm::errs() << "invalid child type for info";
721 exit(1);
722}
723
724// Namespace children:
725template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
726 I->Children.Functions.emplace_back(std::move(R));
727}
728template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
729 I->Children.Enums.emplace_back(std::move(R));
730}
731template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
732 I->Children.Typedefs.emplace_back(std::move(R));
733}
734template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) {
735 I->Children.Concepts.emplace_back(std::move(R));
736}
737template <> void addChild(NamespaceInfo *I, VarInfo &&R) {
738 I->Children.Variables.emplace_back(std::move(R));
739}
740
741// Record children:
742template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
743 I->Children.Functions.emplace_back(std::move(R));
744}
745template <> void addChild(RecordInfo *I, EnumInfo &&R) {
746 I->Children.Enums.emplace_back(std::move(R));
747}
748template <> void addChild(RecordInfo *I, TypedefInfo &&R) {
749 I->Children.Typedefs.emplace_back(std::move(R));
750}
751template <> void addChild(RecordInfo *I, FriendInfo &&R) {
752 I->Friends.emplace_back(std::move(R));
753}
754
755// Other types of children:
756template <> void addChild(EnumInfo *I, EnumValueInfo &&R) {
757 I->Members.emplace_back(std::move(R));
758}
759template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) {
760 I->Bases.emplace_back(std::move(R));
761}
762template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) {
763 I->Children.Functions.emplace_back(std::move(R));
764}
765
766// TemplateParam children. These go into either a TemplateInfo (for template
767// parameters) or TemplateSpecializationInfo (for the specialization's
768// parameters).
769template <typename T> static void addTemplateParam(T I, TemplateParamInfo &&P) {
770 llvm::errs() << "invalid container for template parameter";
771 exit(1);
772}
774 I->Params.emplace_back(std::move(P));
775}
776template <>
778 I->Params.emplace_back(std::move(P));
779}
780
781// Template info. These apply to either records or functions.
782template <typename T> static void addTemplate(T I, TemplateInfo &&P) {
783 llvm::errs() << "invalid container for template info";
784 exit(1);
785}
786template <> void addTemplate(RecordInfo *I, TemplateInfo &&P) {
787 I->Template.emplace(std::move(P));
788}
789template <> void addTemplate(FunctionInfo *I, TemplateInfo &&P) {
790 I->Template.emplace(std::move(P));
791}
792template <> void addTemplate(ConceptInfo *I, TemplateInfo &&P) {
793 I->Template = std::move(P);
794}
795template <> void addTemplate(FriendInfo *I, TemplateInfo &&P) {
796 I->Template.emplace(std::move(P));
797}
798
799// Template specializations go only into template records.
800template <typename T>
802 llvm::errs() << "invalid container for template specialization info";
803 exit(1);
804}
805template <>
808 I->Specialization.emplace(std::move(TSI));
809}
810
811template <typename T> static void addConstraint(T I, ConstraintInfo &&C) {
812 llvm::errs() << "invalid container for constraint info";
813 exit(1);
814}
815template <> void addConstraint(TemplateInfo *I, ConstraintInfo &&C) {
816 I->Constraints.emplace_back(std::move(C));
817}
818
819// Read records from bitcode into a given info.
820template <typename T>
821llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
822 Record R;
823 llvm::StringRef Blob;
824 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
825 if (!MaybeRecID)
826 return MaybeRecID.takeError();
827 return parseRecord(R, MaybeRecID.get(), Blob, I);
828}
829
830template <>
831llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
832 llvm::TimeTraceScope("Reducing infos", "readRecord");
833 Record R;
834 llvm::StringRef Blob;
835 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
836 if (!MaybeRecID)
837 return MaybeRecID.takeError();
838 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
839}
840
841// Read a block of records into a single info.
842template <typename T>
843llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
844 llvm::TimeTraceScope("Reducing infos", "readBlock");
845 if (llvm::Error Err = Stream.EnterSubBlock(ID))
846 return Err;
847
848 while (true) {
849 unsigned BlockOrCode = 0;
850 Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
851
852 switch (Res) {
853 case Cursor::BadBlock:
854 return llvm::createStringError(llvm::inconvertibleErrorCode(),
855 "bad block found");
856 case Cursor::BlockEnd:
857 return llvm::Error::success();
858 case Cursor::BlockBegin:
859 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
860 if (llvm::Error Skipped = Stream.SkipBlock())
861 return joinErrors(std::move(Err), std::move(Skipped));
862 return Err;
863 }
864 continue;
865 case Cursor::Record:
866 break;
867 }
868 if (auto Err = readRecord(BlockOrCode, I))
869 return Err;
870 }
871}
872
873// TODO: fix inconsistentent returning of errors in add callbacks.
874// Once that's fixed, we only need one handleSubBlock.
875template <typename InfoType, typename T, typename Callback>
876llvm::Error ClangDocBitcodeReader::handleSubBlock(unsigned ID, T Parent,
877 Callback Function) {
879 if (auto Err = readBlock(ID, &Info))
880 return Err;
881 Function(Parent, std::move(Info));
882 return llvm::Error::success();
883}
884
885template <typename InfoType, typename T, typename Callback>
886llvm::Error ClangDocBitcodeReader::handleTypeSubBlock(unsigned ID, T Parent,
887 Callback Function) {
889 if (auto Err = readBlock(ID, &Info))
890 return Err;
891 if (auto Err = Function(Parent, std::move(Info)))
892 return Err;
893 return llvm::Error::success();
894}
895
896template <typename T>
897llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
898 llvm::TimeTraceScope("Reducing infos", "readSubBlock");
899
900 static auto CreateAddFunc = [](auto AddFunc) {
901 return [AddFunc](auto Parent, auto Child) {
902 return AddFunc(Parent, std::move(Child));
903 };
904 };
905
906 switch (ID) {
907 // Blocks can only have certain types of sub blocks.
908 case BI_COMMENT_BLOCK_ID: {
909 auto Comment = getCommentInfo(I);
910 if (!Comment)
911 return Comment.takeError();
912 if (auto Err = readBlock(ID, Comment.get()))
913 return Err;
914 return llvm::Error::success();
915 }
916 case BI_TYPE_BLOCK_ID: {
917 return handleTypeSubBlock<TypeInfo>(
918 ID, I, CreateAddFunc(addTypeInfo<T, TypeInfo>));
919 }
921 return handleTypeSubBlock<FieldTypeInfo>(
922 ID, I, CreateAddFunc(addTypeInfo<T, FieldTypeInfo>));
923 }
925 return handleTypeSubBlock<MemberTypeInfo>(
926 ID, I, CreateAddFunc(addTypeInfo<T, MemberTypeInfo>));
927 }
929 Reference R;
930 if (auto Err = readBlock(ID, &R))
931 return Err;
932 if (auto Err = addReference(I, std::move(R), CurrentReferenceField))
933 return Err;
934 return llvm::Error::success();
935 }
937 return handleSubBlock<FunctionInfo>(
938 ID, I, CreateAddFunc(addChild<T, FunctionInfo>));
939 }
941 return handleSubBlock<BaseRecordInfo>(
942 ID, I, CreateAddFunc(addChild<T, BaseRecordInfo>));
943 }
944 case BI_ENUM_BLOCK_ID: {
945 return handleSubBlock<EnumInfo>(ID, I,
946 CreateAddFunc(addChild<T, EnumInfo>));
947 }
949 return handleSubBlock<EnumValueInfo>(
950 ID, I, CreateAddFunc(addChild<T, EnumValueInfo>));
951 }
953 return handleSubBlock<TemplateInfo>(ID, I, CreateAddFunc(addTemplate<T>));
954 }
956 return handleSubBlock<TemplateSpecializationInfo>(
957 ID, I, CreateAddFunc(addTemplateSpecialization<T>));
958 }
960 return handleSubBlock<TemplateParamInfo>(
961 ID, I, CreateAddFunc(addTemplateParam<T>));
962 }
963 case BI_TYPEDEF_BLOCK_ID: {
964 return handleSubBlock<TypedefInfo>(ID, I,
965 CreateAddFunc(addChild<T, TypedefInfo>));
966 }
968 return handleSubBlock<ConstraintInfo>(ID, I,
969 CreateAddFunc(addConstraint<T>));
970 }
971 case BI_CONCEPT_BLOCK_ID: {
972 return handleSubBlock<ConceptInfo>(ID, I,
973 CreateAddFunc(addChild<T, ConceptInfo>));
974 }
975 case BI_VAR_BLOCK_ID: {
976 return handleSubBlock<VarInfo>(ID, I, CreateAddFunc(addChild<T, VarInfo>));
977 }
978 case BI_FRIEND_BLOCK_ID: {
979 return handleSubBlock<FriendInfo>(ID, I,
980 CreateAddFunc(addChild<T, FriendInfo>));
981 }
982 default:
983 return llvm::createStringError(llvm::inconvertibleErrorCode(),
984 "invalid subblock type");
985 }
986}
987
988ClangDocBitcodeReader::Cursor
989ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
990 llvm::TimeTraceScope("Reducing infos", "skipUntilRecordOrBlock");
991 BlockOrRecordID = 0;
992
993 while (!Stream.AtEndOfStream()) {
994 Expected<unsigned> MaybeCode = Stream.ReadCode();
995 if (!MaybeCode) {
996 // FIXME this drops the error on the floor.
997 consumeError(MaybeCode.takeError());
998 return Cursor::BadBlock;
999 }
1000
1001 unsigned Code = MaybeCode.get();
1002 if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
1003 BlockOrRecordID = Code;
1004 return Cursor::Record;
1005 }
1006 switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
1007 case llvm::bitc::ENTER_SUBBLOCK:
1008 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
1009 BlockOrRecordID = MaybeID.get();
1010 else {
1011 // FIXME this drops the error on the floor.
1012 consumeError(MaybeID.takeError());
1013 }
1014 return Cursor::BlockBegin;
1015 case llvm::bitc::END_BLOCK:
1016 if (Stream.ReadBlockEnd())
1017 return Cursor::BadBlock;
1018 return Cursor::BlockEnd;
1019 case llvm::bitc::DEFINE_ABBREV:
1020 if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
1021 // FIXME this drops the error on the floor.
1022 consumeError(std::move(Err));
1023 }
1024 continue;
1025 case llvm::bitc::UNABBREV_RECORD:
1026 return Cursor::BadBlock;
1027 case llvm::bitc::FIRST_APPLICATION_ABBREV:
1028 llvm_unreachable("Unexpected abbrev id.");
1029 }
1030 }
1031 llvm_unreachable("Premature stream end.");
1032}
1033
1034llvm::Error ClangDocBitcodeReader::validateStream() {
1035 if (Stream.AtEndOfStream())
1036 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1037 "premature end of stream");
1038
1039 // Sniff for the signature.
1040 for (int Idx = 0; Idx != 4; ++Idx) {
1041 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
1042 if (!MaybeRead)
1043 return MaybeRead.takeError();
1044 if (MaybeRead.get() != BitCodeConstants::Signature[Idx])
1045 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1046 "invalid bitcode signature");
1047 }
1048 return llvm::Error::success();
1049}
1050
1051llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
1052 llvm::TimeTraceScope("Reducing infos", "readBlockInfoBlock");
1053 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
1054 Stream.ReadBlockInfoBlock();
1055 if (!MaybeBlockInfo)
1056 return MaybeBlockInfo.takeError();
1057 BlockInfo = MaybeBlockInfo.get();
1058 if (!BlockInfo)
1059 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1060 "unable to parse BlockInfoBlock");
1061 Stream.setBlockInfo(&*BlockInfo);
1062 return llvm::Error::success();
1063}
1064
1065template <typename T>
1066llvm::Expected<std::unique_ptr<Info>>
1067ClangDocBitcodeReader::createInfo(unsigned ID) {
1068 llvm::TimeTraceScope("Reducing infos", "createInfo");
1069 std::unique_ptr<Info> I = std::make_unique<T>();
1070 if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
1071 return std::move(Err);
1072 return std::unique_ptr<Info>{std::move(I)};
1073}
1074
1075llvm::Expected<std::unique_ptr<Info>>
1076ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
1077 llvm::TimeTraceScope("Reducing infos", "readBlockToInfo");
1078 switch (ID) {
1080 return createInfo<NamespaceInfo>(ID);
1081 case BI_RECORD_BLOCK_ID:
1082 return createInfo<RecordInfo>(ID);
1083 case BI_ENUM_BLOCK_ID:
1084 return createInfo<EnumInfo>(ID);
1086 return createInfo<TypedefInfo>(ID);
1088 return createInfo<ConceptInfo>(ID);
1090 return createInfo<FunctionInfo>(ID);
1091 case BI_VAR_BLOCK_ID:
1092 return createInfo<VarInfo>(ID);
1093 case BI_FRIEND_BLOCK_ID:
1094 return createInfo<FriendInfo>(ID);
1095 default:
1096 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1097 "cannot create info");
1098 }
1099}
1100
1101// Entry point
1102llvm::Expected<std::vector<std::unique_ptr<Info>>>
1104 std::vector<std::unique_ptr<Info>> Infos;
1105 if (auto Err = validateStream())
1106 return std::move(Err);
1107
1108 // Read the top level blocks.
1109 while (!Stream.AtEndOfStream()) {
1110 Expected<unsigned> MaybeCode = Stream.ReadCode();
1111 if (!MaybeCode)
1112 return MaybeCode.takeError();
1113 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
1114 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1115 "no blocks in input");
1116 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
1117 if (!MaybeID)
1118 return MaybeID.takeError();
1119 unsigned ID = MaybeID.get();
1120 switch (ID) {
1121 // NamedType and Comment blocks should not appear at the top level
1122 case BI_TYPE_BLOCK_ID:
1127 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1128 "invalid top level block");
1130 case BI_RECORD_BLOCK_ID:
1131 case BI_ENUM_BLOCK_ID:
1134 case BI_VAR_BLOCK_ID:
1135 case BI_FRIEND_BLOCK_ID:
1136 case BI_FUNCTION_BLOCK_ID: {
1137 auto InfoOrErr = readBlockToInfo(ID);
1138 if (!InfoOrErr)
1139 return InfoOrErr.takeError();
1140 Infos.emplace_back(std::move(InfoOrErr.get()));
1141 continue;
1142 }
1144 if (auto Err = readBlock(ID, VersionNumber))
1145 return std::move(Err);
1146 continue;
1147 case llvm::bitc::BLOCKINFO_BLOCK_ID:
1148 if (auto Err = readBlockInfoBlock())
1149 return std::move(Err);
1150 continue;
1151 default:
1152 if (llvm::Error Err = Stream.SkipBlock()) {
1153 // FIXME this drops the error on the floor.
1154 consumeError(std::move(Err));
1155 }
1156 continue;
1157 }
1158 }
1159 return std::move(Infos);
1160}
1161
1162} // namespace doc
1163} // namespace clang
llvm::Expected< std::vector< std::unique_ptr< Info > > > readBitcode()
static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
static llvm::Expected< CommentInfo * > getCommentInfo(T I)
@ TEMPLATE_SPECIALIZATION_OF
@ MEMBER_TYPE_IS_TEMPLATE
@ TEMPLATE_PARAM_CONTENTS
@ CONCEPT_CONSTRAINT_EXPRESSION
llvm::SmallVector< uint64_t, 1024 > Record
static llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)
static const unsigned VersionNumber
static void addChild(T I, ChildInfoType &&R)
CommentKind stringToCommentKind(llvm::StringRef KindStr)
static llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
static void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI)
static void addTemplate(T I, TemplateInfo &&P)
static llvm::Error addReference(T I, Reference &&R, FieldId F)
std::array< uint8_t, 20 > SymbolID
static void addTemplateParam(T I, TemplateParamInfo &&P)
@ 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
static void addConstraint(T I, ConstraintInfo &&C)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static constexpr unsigned char Signature[4]
static constexpr int USRHashSize
SmallString< 8 > Direction
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
SmallString< 16 > ConstraintExpression
SmallString< 16 > ConstraintExpr
llvm::SmallVector< EnumValueInfo, 4 > Members
std::optional< TypeInfo > BaseType
std::vector< CommentInfo > Description
Comment description of this field.
SmallString< 16 > ValueExpr
SmallString< 16 > DefaultValue
std::optional< TypeInfo > ReturnType
std::optional< SmallVector< FieldTypeInfo, 4 > > Params
std::optional< TemplateInfo > Template
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
std::vector< CommentInfo > Description
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::optional< TemplateInfo > Template
std::vector< FriendInfo > Friends
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
std::vector< BaseRecordInfo > Bases
SmallString< 16 > QualName
llvm::SmallString< 128 > Path
SmallString< 16 > DocumentationFileName
SmallString< 16 > Name
std::vector< Reference > Records
std::vector< TypedefInfo > Typedefs
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< VarInfo > Variables
std::vector< EnumInfo > Enums
std::vector< ConceptInfo > Concepts
llvm::SmallVector< Location, 2 > Loc
std::optional< Location > DefLoc
SmallString< 16 > MangledName
std::vector< ConstraintInfo > Constraints
std::vector< TemplateParamInfo > Params
std::optional< TemplateSpecializationInfo > Specialization
std::vector< TemplateParamInfo > Params
std::vector< CommentInfo > Description
Comment description for the typedef.