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,
23 llvm::SmallVectorImpl<char> &Field,
24 llvm::StringRef Blob) {
25 Field.assign(in_start: Blob.begin(), in_end: Blob.end());
26 return llvm::Error::success();
27}
28
29static llvm::Error decodeRecord(const Record &R, SymbolID &Field,
30 llvm::StringRef Blob) {
31 if (R[0] != BitCodeConstants::USRHashSize)
32 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
33 S: "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(EC: llvm::inconvertibleErrorCode(),
73 S: "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(EC: llvm::inconvertibleErrorCode(),
80 S: "integer too large to parse");
81 Field.emplace(args: static_cast<int>(R[0]), args: static_cast<int>(R[1]), args&: Blob,
82 args: 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])) {
89 case InfoType::IT_namespace:
90 case InfoType::IT_record:
91 case InfoType::IT_function:
92 case InfoType::IT_default:
93 case InfoType::IT_enum:
94 case InfoType::IT_typedef:
95 case InfoType::IT_concept:
96 case InfoType::IT_variable:
97 case InfoType::IT_friend:
98 Field = IT;
99 return llvm::Error::success();
100 }
101 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
102 S: "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])) {
108 case FieldId::F_namespace:
109 case FieldId::F_parent:
110 case FieldId::F_vparent:
111 case FieldId::F_type:
112 case FieldId::F_child_namespace:
113 case FieldId::F_child_record:
114 case FieldId::F_concept:
115 case FieldId::F_friend:
116 case FieldId::F_default:
117 Field = F;
118 return llvm::Error::success();
119 }
120 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
121 S: "invalid value for FieldId");
122}
123
124static llvm::Error
125decodeRecord(const Record &R,
126 llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
127 llvm::StringRef Blob) {
128 Field.push_back(Elt: Blob);
129 return llvm::Error::success();
130}
131
132static llvm::Error decodeRecord(const Record &R,
133 llvm::SmallVectorImpl<Location> &Field,
134 llvm::StringRef Blob) {
135 if (R[0] > INT_MAX)
136 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
137 S: "integer too large to parse");
138 Field.emplace_back(Args: static_cast<int>(R[0]), Args: static_cast<int>(R[1]), Args&: Blob,
139 Args: 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(EC: llvm::inconvertibleErrorCode(),
148 S: "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, Field&: I->USR, Blob);
156 case NAMESPACE_NAME:
157 return decodeRecord(R, Field&: I->Name, Blob);
158 case NAMESPACE_PATH:
159 return decodeRecord(R, Field&: I->Path, Blob);
160 default:
161 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
162 S: "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, Field&: I->USR, Blob);
171 case RECORD_NAME:
172 return decodeRecord(R, Field&: I->Name, Blob);
173 case RECORD_PATH:
174 return decodeRecord(R, Field&: I->Path, Blob);
175 case RECORD_DEFLOCATION:
176 return decodeRecord(R, Field&: I->DefLoc, Blob);
177 case RECORD_LOCATION:
178 return decodeRecord(R, Field&: I->Loc, Blob);
179 case RECORD_TAG_TYPE:
180 return decodeRecord(R, Field&: I->TagType, Blob);
181 case RECORD_IS_TYPE_DEF:
182 return decodeRecord(R, Field&: I->IsTypeDef, Blob);
183 case RECORD_MANGLED_NAME:
184 return decodeRecord(R, Field&: I->MangledName, Blob);
185 default:
186 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
187 S: "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, Field&: I->USR, Blob);
196 case BASE_RECORD_NAME:
197 return decodeRecord(R, Field&: I->Name, Blob);
198 case BASE_RECORD_PATH:
199 return decodeRecord(R, Field&: I->Path, Blob);
200 case BASE_RECORD_TAG_TYPE:
201 return decodeRecord(R, Field&: I->TagType, Blob);
202 case BASE_RECORD_IS_VIRTUAL:
203 return decodeRecord(R, Field&: I->IsVirtual, Blob);
204 case BASE_RECORD_ACCESS:
205 return decodeRecord(R, Field&: I->Access, Blob);
206 case BASE_RECORD_IS_PARENT:
207 return decodeRecord(R, Field&: I->IsParent, Blob);
208 default:
209 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
210 S: "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, Field&: I->USR, Blob);
219 case ENUM_NAME:
220 return decodeRecord(R, Field&: I->Name, Blob);
221 case ENUM_DEFLOCATION:
222 return decodeRecord(R, Field&: I->DefLoc, Blob);
223 case ENUM_LOCATION:
224 return decodeRecord(R, Field&: I->Loc, Blob);
225 case ENUM_SCOPED:
226 return decodeRecord(R, Field&: I->Scoped, Blob);
227 default:
228 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
229 S: "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, Field&: I->USR, Blob);
238 case TYPEDEF_NAME:
239 return decodeRecord(R, Field&: I->Name, Blob);
240 case TYPEDEF_DEFLOCATION:
241 return decodeRecord(R, Field&: I->DefLoc, Blob);
242 case TYPEDEF_IS_USING:
243 return decodeRecord(R, Field&: I->IsUsing, Blob);
244 default:
245 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
246 S: "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, Field&: I->Name, Blob);
255 case ENUM_VALUE_VALUE:
256 return decodeRecord(R, Field&: I->Value, Blob);
257 case ENUM_VALUE_EXPR:
258 return decodeRecord(R, Field&: I->ValueExpr, Blob);
259 default:
260 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
261 S: "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, Field&: I->USR, Blob);
270 case FUNCTION_NAME:
271 return decodeRecord(R, Field&: I->Name, Blob);
272 case FUNCTION_DEFLOCATION:
273 return decodeRecord(R, Field&: I->DefLoc, Blob);
274 case FUNCTION_LOCATION:
275 return decodeRecord(R, Field&: I->Loc, Blob);
276 case FUNCTION_ACCESS:
277 return decodeRecord(R, Field&: I->Access, Blob);
278 case FUNCTION_IS_METHOD:
279 return decodeRecord(R, Field&: I->IsMethod, Blob);
280 case FUNCTION_IS_STATIC:
281 return decodeRecord(R, Field&: I->IsStatic, Blob);
282 default:
283 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
284 S: "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, Field&: I->IsBuiltIn, Blob);
293 case TYPE_IS_TEMPLATE:
294 return decodeRecord(R, Field&: I->IsTemplate, Blob);
295 default:
296 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
297 S: "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, Field&: I->Name, Blob);
306 case FIELD_DEFAULT_VALUE:
307 return decodeRecord(R, Field&: I->DefaultValue, Blob);
308 case FIELD_TYPE_IS_BUILTIN:
309 return decodeRecord(R, Field&: I->IsBuiltIn, Blob);
310 case FIELD_TYPE_IS_TEMPLATE:
311 return decodeRecord(R, Field&: I->IsTemplate, Blob);
312 default:
313 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
314 S: "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, Field&: I->Name, Blob);
323 case MEMBER_TYPE_ACCESS:
324 return decodeRecord(R, Field&: I->Access, Blob);
325 case MEMBER_TYPE_IS_STATIC:
326 return decodeRecord(R, Field&: I->IsStatic, Blob);
327 case MEMBER_TYPE_IS_BUILTIN:
328 return decodeRecord(R, Field&: I->IsBuiltIn, Blob);
329 case MEMBER_TYPE_IS_TEMPLATE:
330 return decodeRecord(R, Field&: I->IsTemplate, Blob);
331 default:
332 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
333 S: "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, Field&: KindStr, Blob))
343 return Err;
344 I->Kind = stringToCommentKind(KindStr);
345 return llvm::Error::success();
346 case COMMENT_TEXT:
347 return decodeRecord(R, Field&: I->Text, Blob);
348 case COMMENT_NAME:
349 return decodeRecord(R, Field&: I->Name, Blob);
350 case COMMENT_DIRECTION:
351 return decodeRecord(R, Field&: I->Direction, Blob);
352 case COMMENT_PARAMNAME:
353 return decodeRecord(R, Field&: I->ParamName, Blob);
354 case COMMENT_CLOSENAME:
355 return decodeRecord(R, Field&: I->CloseName, Blob);
356 case COMMENT_ATTRKEY:
357 return decodeRecord(R, Field&: I->AttrKeys, Blob);
358 case COMMENT_ATTRVAL:
359 return decodeRecord(R, Field&: I->AttrValues, Blob);
360 case COMMENT_ARG:
361 return decodeRecord(R, Field&: I->Args, Blob);
362 case COMMENT_SELFCLOSING:
363 return decodeRecord(R, Field&: I->SelfClosing, Blob);
364 case COMMENT_EXPLICIT:
365 return decodeRecord(R, Field&: I->Explicit, Blob);
366 default:
367 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
368 S: "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, Field&: I->USR, Blob);
377 case REFERENCE_NAME:
378 return decodeRecord(R, Field&: I->Name, Blob);
379 case REFERENCE_QUAL_NAME:
380 return decodeRecord(R, Field&: I->QualName, Blob);
381 case REFERENCE_TYPE:
382 return decodeRecord(R, Field&: I->RefType, Blob);
383 case REFERENCE_PATH:
384 return decodeRecord(R, Field&: I->Path, Blob);
385 case REFERENCE_FIELD:
386 return decodeRecord(R, Field&: F, Blob);
387 default:
388 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
389 S: "invalid field for Reference");
390 }
391}
392
393static llvm::Error parseRecord(const Record &R, unsigned ID,
394 llvm::StringRef Blob, TemplateInfo *I) {
395 // Currently there are no child records of TemplateInfo (only child blocks).
396 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
397 S: "invalid field for TemplateParamInfo");
398}
399
400static llvm::Error parseRecord(const Record &R, unsigned ID,
401 llvm::StringRef Blob,
402 TemplateSpecializationInfo *I) {
403 if (ID == TEMPLATE_SPECIALIZATION_OF)
404 return decodeRecord(R, Field&: I->SpecializationOf, Blob);
405 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
406 S: "invalid field for TemplateParamInfo");
407}
408
409static llvm::Error parseRecord(const Record &R, unsigned ID,
410 llvm::StringRef Blob, TemplateParamInfo *I) {
411 if (ID == TEMPLATE_PARAM_CONTENTS)
412 return decodeRecord(R, Field&: I->Contents, Blob);
413 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
414 S: "invalid field for TemplateParamInfo");
415}
416
417static llvm::Error parseRecord(const Record &R, unsigned ID,
418 llvm::StringRef Blob, ConceptInfo *I) {
419 switch (ID) {
420 case CONCEPT_USR:
421 return decodeRecord(R, Field&: I->USR, Blob);
422 case CONCEPT_NAME:
423 return decodeRecord(R, Field&: I->Name, Blob);
424 case CONCEPT_IS_TYPE:
425 return decodeRecord(R, Field&: I->IsType, Blob);
426 case CONCEPT_CONSTRAINT_EXPRESSION:
427 return decodeRecord(R, Field&: I->ConstraintExpression, Blob);
428 }
429 llvm_unreachable("invalid field for ConceptInfo");
430}
431
432static llvm::Error parseRecord(const Record &R, unsigned ID,
433 llvm::StringRef Blob, ConstraintInfo *I) {
434 if (ID == CONSTRAINT_EXPRESSION)
435 return decodeRecord(R, Field&: I->ConstraintExpr, Blob);
436 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
437 S: "invalid field for ConstraintInfo");
438}
439
440static llvm::Error parseRecord(const Record &R, unsigned ID,
441 llvm::StringRef Blob, VarInfo *I) {
442 switch (ID) {
443 case VAR_USR:
444 return decodeRecord(R, Field&: I->USR, Blob);
445 case VAR_NAME:
446 return decodeRecord(R, Field&: I->Name, Blob);
447 case VAR_DEFLOCATION:
448 return decodeRecord(R, Field&: I->DefLoc, Blob);
449 case VAR_IS_STATIC:
450 return decodeRecord(R, Field&: I->IsStatic, Blob);
451 default:
452 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
453 S: "invalid field for VarInfo");
454 }
455}
456
457static llvm::Error parseRecord(const Record &R, unsigned ID, StringRef Blob,
458 FriendInfo *F) {
459 if (ID == FRIEND_IS_CLASS) {
460 return decodeRecord(R, Field&: F->IsClass, Blob);
461 }
462 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
463 S: "invalid field for Friend");
464}
465
466template <typename T> static llvm::Expected<CommentInfo *> getCommentInfo(T I) {
467 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
468 S: "invalid type cannot contain CommentInfo");
469}
470
471template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
472 return &I->Description.emplace_back();
473}
474
475template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
476 return &I->Description.emplace_back();
477}
478
479template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
480 return &I->Description.emplace_back();
481}
482
483template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) {
484 return &I->Description.emplace_back();
485}
486
487template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
488 return &I->Description.emplace_back();
489}
490
491template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
492 return &I->Description.emplace_back();
493}
494
495template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumValueInfo *I) {
496 return &I->Description.emplace_back();
497}
498
499template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
500 I->Children.emplace_back(args: std::make_unique<CommentInfo>());
501 return I->Children.back().get();
502}
503
504template <> llvm::Expected<CommentInfo *> getCommentInfo(ConceptInfo *I) {
505 return &I->Description.emplace_back();
506}
507
508template <> Expected<CommentInfo *> getCommentInfo(VarInfo *I) {
509 return &I->Description.emplace_back();
510}
511
512// When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
513// the parent block to set it. The template specializations define what to do
514// for each supported parent block.
515template <typename T, typename TTypeInfo>
516static llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
517 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
518 S: "invalid type cannot contain TypeInfo");
519}
520
521template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
522 I->Members.emplace_back(Args: std::move(T));
523 return llvm::Error::success();
524}
525
526template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) {
527 I->Members.emplace_back(Args: std::move(T));
528 return llvm::Error::success();
529}
530
531template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
532 I->ReturnType = std::move(T);
533 return llvm::Error::success();
534}
535
536template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
537 I->Params.emplace_back(Args: std::move(T));
538 return llvm::Error::success();
539}
540
541template <> llvm::Error addTypeInfo(FriendInfo *I, FieldTypeInfo &&T) {
542 if (!I->Params)
543 I->Params.emplace();
544 I->Params->emplace_back(Args: std::move(T));
545 return llvm::Error::success();
546}
547
548template <> llvm::Error addTypeInfo(FriendInfo *I, TypeInfo &&T) {
549 I->ReturnType.emplace(args: std::move(T));
550 return llvm::Error::success();
551}
552
553template <> llvm::Error addTypeInfo(EnumInfo *I, TypeInfo &&T) {
554 I->BaseType = std::move(T);
555 return llvm::Error::success();
556}
557
558template <> llvm::Error addTypeInfo(TypedefInfo *I, TypeInfo &&T) {
559 I->Underlying = std::move(T);
560 return llvm::Error::success();
561}
562
563template <> llvm::Error addTypeInfo(VarInfo *I, TypeInfo &&T) {
564 I->Type = std::move(T);
565 return llvm::Error::success();
566}
567
568template <typename T>
569static llvm::Error addReference(T I, Reference &&R, FieldId F) {
570 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
571 S: "invalid type cannot contain Reference");
572}
573
574template <> llvm::Error addReference(VarInfo *I, Reference &&R, FieldId F) {
575 switch (F) {
576 case FieldId::F_namespace:
577 I->Namespace.emplace_back(Args: std::move(R));
578 return llvm::Error::success();
579 default:
580 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
581 S: "VarInfo cannot contain this Reference");
582 }
583}
584
585template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) {
586 switch (F) {
587 case FieldId::F_type:
588 I->Type = std::move(R);
589 return llvm::Error::success();
590 default:
591 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
592 S: "invalid type cannot contain Reference");
593 }
594}
595
596template <>
597llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F) {
598 switch (F) {
599 case FieldId::F_type:
600 I->Type = std::move(R);
601 return llvm::Error::success();
602 default:
603 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
604 S: "invalid type cannot contain Reference");
605 }
606}
607
608template <>
609llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F) {
610 switch (F) {
611 case FieldId::F_type:
612 I->Type = std::move(R);
613 return llvm::Error::success();
614 default:
615 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
616 S: "invalid type cannot contain Reference");
617 }
618}
619
620template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
621 switch (F) {
622 case FieldId::F_namespace:
623 I->Namespace.emplace_back(Args: std::move(R));
624 return llvm::Error::success();
625 default:
626 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
627 S: "invalid type cannot contain Reference");
628 }
629}
630
631template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F) {
632 switch (F) {
633 case FieldId::F_namespace:
634 I->Namespace.emplace_back(Args: std::move(R));
635 return llvm::Error::success();
636 default:
637 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
638 S: "invalid type cannot contain Reference");
639 }
640}
641
642template <>
643llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
644 switch (F) {
645 case FieldId::F_namespace:
646 I->Namespace.emplace_back(Args: std::move(R));
647 return llvm::Error::success();
648 case FieldId::F_child_namespace:
649 I->Children.Namespaces.emplace_back(args: std::move(R));
650 return llvm::Error::success();
651 case FieldId::F_child_record:
652 I->Children.Records.emplace_back(args: std::move(R));
653 return llvm::Error::success();
654 default:
655 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
656 S: "invalid type cannot contain Reference");
657 }
658}
659
660template <>
661llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
662 switch (F) {
663 case FieldId::F_namespace:
664 I->Namespace.emplace_back(Args: std::move(R));
665 return llvm::Error::success();
666 case FieldId::F_parent:
667 I->Parent = std::move(R);
668 return llvm::Error::success();
669 default:
670 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
671 S: "invalid type cannot contain Reference");
672 }
673}
674
675template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
676 switch (F) {
677 case FieldId::F_namespace:
678 I->Namespace.emplace_back(Args: std::move(R));
679 return llvm::Error::success();
680 case FieldId::F_parent:
681 I->Parents.emplace_back(Args: std::move(R));
682 return llvm::Error::success();
683 case FieldId::F_vparent:
684 I->VirtualParents.emplace_back(Args: std::move(R));
685 return llvm::Error::success();
686 case FieldId::F_child_record:
687 I->Children.Records.emplace_back(args: std::move(R));
688 return llvm::Error::success();
689 default:
690 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
691 S: "invalid type cannot contain Reference");
692 }
693}
694
695template <>
696llvm::Error addReference(ConstraintInfo *I, Reference &&R, FieldId F) {
697 if (F == FieldId::F_concept) {
698 I->ConceptRef = std::move(R);
699 return llvm::Error::success();
700 }
701 return llvm::createStringError(
702 EC: llvm::inconvertibleErrorCode(),
703 S: "ConstraintInfo cannot contain this Reference");
704}
705
706template <>
707llvm::Error addReference(FriendInfo *Friend, Reference &&R, FieldId F) {
708 if (F == FieldId::F_friend) {
709 Friend->Ref = std::move(R);
710 return llvm::Error::success();
711 }
712 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
713 S: "Friend cannot contain this Reference");
714}
715
716template <typename T, typename ChildInfoType>
717static void addChild(T I, ChildInfoType &&R) {
718 llvm::errs() << "invalid child type for info";
719 exit(status: 1);
720}
721
722// Namespace children:
723template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
724 I->Children.Functions.emplace_back(args: std::move(R));
725}
726template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
727 I->Children.Enums.emplace_back(args: std::move(R));
728}
729template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
730 I->Children.Typedefs.emplace_back(args: std::move(R));
731}
732template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) {
733 I->Children.Concepts.emplace_back(args: std::move(R));
734}
735template <> void addChild(NamespaceInfo *I, VarInfo &&R) {
736 I->Children.Variables.emplace_back(args: std::move(R));
737}
738
739// Record children:
740template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
741 I->Children.Functions.emplace_back(args: std::move(R));
742}
743template <> void addChild(RecordInfo *I, EnumInfo &&R) {
744 I->Children.Enums.emplace_back(args: std::move(R));
745}
746template <> void addChild(RecordInfo *I, TypedefInfo &&R) {
747 I->Children.Typedefs.emplace_back(args: std::move(R));
748}
749template <> void addChild(RecordInfo *I, FriendInfo &&R) {
750 I->Friends.emplace_back(args: std::move(R));
751}
752
753// Other types of children:
754template <> void addChild(EnumInfo *I, EnumValueInfo &&R) {
755 I->Members.emplace_back(Args: std::move(R));
756}
757template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) {
758 I->Bases.emplace_back(args: std::move(R));
759}
760template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) {
761 I->Children.Functions.emplace_back(args: std::move(R));
762}
763
764// TemplateParam children. These go into either a TemplateInfo (for template
765// parameters) or TemplateSpecializationInfo (for the specialization's
766// parameters).
767template <typename T> static void addTemplateParam(T I, TemplateParamInfo &&P) {
768 llvm::errs() << "invalid container for template parameter";
769 exit(status: 1);
770}
771template <> void addTemplateParam(TemplateInfo *I, TemplateParamInfo &&P) {
772 I->Params.emplace_back(args: std::move(P));
773}
774template <>
775void addTemplateParam(TemplateSpecializationInfo *I, TemplateParamInfo &&P) {
776 I->Params.emplace_back(args: std::move(P));
777}
778
779// Template info. These apply to either records or functions.
780template <typename T> static void addTemplate(T I, TemplateInfo &&P) {
781 llvm::errs() << "invalid container for template info";
782 exit(status: 1);
783}
784template <> void addTemplate(RecordInfo *I, TemplateInfo &&P) {
785 I->Template.emplace(args: std::move(P));
786}
787template <> void addTemplate(FunctionInfo *I, TemplateInfo &&P) {
788 I->Template.emplace(args: std::move(P));
789}
790template <> void addTemplate(ConceptInfo *I, TemplateInfo &&P) {
791 I->Template = std::move(P);
792}
793template <> void addTemplate(FriendInfo *I, TemplateInfo &&P) {
794 I->Template.emplace(args: std::move(P));
795}
796
797// Template specializations go only into template records.
798template <typename T>
799static void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI) {
800 llvm::errs() << "invalid container for template specialization info";
801 exit(status: 1);
802}
803template <>
804void addTemplateSpecialization(TemplateInfo *I,
805 TemplateSpecializationInfo &&TSI) {
806 I->Specialization.emplace(args: std::move(TSI));
807}
808
809template <typename T> static void addConstraint(T I, ConstraintInfo &&C) {
810 llvm::errs() << "invalid container for constraint info";
811 exit(status: 1);
812}
813template <> void addConstraint(TemplateInfo *I, ConstraintInfo &&C) {
814 I->Constraints.emplace_back(args: std::move(C));
815}
816
817// Read records from bitcode into a given info.
818template <typename T>
819llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
820 Record R;
821 llvm::StringRef Blob;
822 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(AbbrevID: ID, Vals&: R, Blob: &Blob);
823 if (!MaybeRecID)
824 return MaybeRecID.takeError();
825 return parseRecord(R, MaybeRecID.get(), Blob, I);
826}
827
828template <>
829llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
830 llvm::TimeTraceScope("Reducing infos", "readRecord");
831 Record R;
832 llvm::StringRef Blob;
833 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(AbbrevID: ID, Vals&: R, Blob: &Blob);
834 if (!MaybeRecID)
835 return MaybeRecID.takeError();
836 return parseRecord(R, ID: MaybeRecID.get(), Blob, I, F&: CurrentReferenceField);
837}
838
839// Read a block of records into a single info.
840template <typename T>
841llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
842 llvm::TimeTraceScope("Reducing infos", "readBlock");
843 if (llvm::Error Err = Stream.EnterSubBlock(BlockID: ID))
844 return Err;
845
846 while (true) {
847 unsigned BlockOrCode = 0;
848 Cursor Res = skipUntilRecordOrBlock(BlockOrRecordID&: BlockOrCode);
849
850 switch (Res) {
851 case Cursor::BadBlock:
852 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
853 S: "bad block found");
854 case Cursor::BlockEnd:
855 return llvm::Error::success();
856 case Cursor::BlockBegin:
857 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
858 if (llvm::Error Skipped = Stream.SkipBlock())
859 return joinErrors(E1: std::move(Err), E2: std::move(Skipped));
860 return Err;
861 }
862 continue;
863 case Cursor::Record:
864 break;
865 }
866 if (auto Err = readRecord(BlockOrCode, I))
867 return Err;
868 }
869}
870
871// TODO: fix inconsistentent returning of errors in add callbacks.
872// Once that's fixed, we only need one handleSubBlock.
873template <typename InfoType, typename T, typename Callback>
874llvm::Error ClangDocBitcodeReader::handleSubBlock(unsigned ID, T Parent,
875 Callback Function) {
876 InfoType Info;
877 if (auto Err = readBlock(ID, &Info))
878 return Err;
879 Function(Parent, std::move(Info));
880 return llvm::Error::success();
881}
882
883template <typename InfoType, typename T, typename Callback>
884llvm::Error ClangDocBitcodeReader::handleTypeSubBlock(unsigned ID, T Parent,
885 Callback Function) {
886 InfoType Info;
887 if (auto Err = readBlock(ID, &Info))
888 return Err;
889 if (auto Err = Function(Parent, std::move(Info)))
890 return Err;
891 return llvm::Error::success();
892}
893
894template <typename T>
895llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
896 llvm::TimeTraceScope("Reducing infos", "readSubBlock");
897
898 static auto CreateAddFunc = [](auto AddFunc) {
899 return [AddFunc](auto Parent, auto Child) {
900 return AddFunc(Parent, std::move(Child));
901 };
902 };
903
904 switch (ID) {
905 // Blocks can only have certain types of sub blocks.
906 case BI_COMMENT_BLOCK_ID: {
907 auto Comment = getCommentInfo(I);
908 if (!Comment)
909 return Comment.takeError();
910 if (auto Err = readBlock(ID, Comment.get()))
911 return Err;
912 return llvm::Error::success();
913 }
914 case BI_TYPE_BLOCK_ID: {
915 return handleTypeSubBlock<TypeInfo>(
916 ID, I, CreateAddFunc(addTypeInfo<T, TypeInfo>));
917 }
918 case BI_FIELD_TYPE_BLOCK_ID: {
919 return handleTypeSubBlock<FieldTypeInfo>(
920 ID, I, CreateAddFunc(addTypeInfo<T, FieldTypeInfo>));
921 }
922 case BI_MEMBER_TYPE_BLOCK_ID: {
923 return handleTypeSubBlock<MemberTypeInfo>(
924 ID, I, CreateAddFunc(addTypeInfo<T, MemberTypeInfo>));
925 }
926 case BI_REFERENCE_BLOCK_ID: {
927 Reference R;
928 if (auto Err = readBlock(ID, I: &R))
929 return Err;
930 if (auto Err = addReference(I, std::move(R), CurrentReferenceField))
931 return Err;
932 return llvm::Error::success();
933 }
934 case BI_FUNCTION_BLOCK_ID: {
935 return handleSubBlock<FunctionInfo>(
936 ID, I, CreateAddFunc(addChild<T, FunctionInfo>));
937 }
938 case BI_BASE_RECORD_BLOCK_ID: {
939 return handleSubBlock<BaseRecordInfo>(
940 ID, I, CreateAddFunc(addChild<T, BaseRecordInfo>));
941 }
942 case BI_ENUM_BLOCK_ID: {
943 return handleSubBlock<EnumInfo>(ID, I,
944 CreateAddFunc(addChild<T, EnumInfo>));
945 }
946 case BI_ENUM_VALUE_BLOCK_ID: {
947 return handleSubBlock<EnumValueInfo>(
948 ID, I, CreateAddFunc(addChild<T, EnumValueInfo>));
949 }
950 case BI_TEMPLATE_BLOCK_ID: {
951 return handleSubBlock<TemplateInfo>(ID, I, CreateAddFunc(addTemplate<T>));
952 }
953 case BI_TEMPLATE_SPECIALIZATION_BLOCK_ID: {
954 return handleSubBlock<TemplateSpecializationInfo>(
955 ID, I, CreateAddFunc(addTemplateSpecialization<T>));
956 }
957 case BI_TEMPLATE_PARAM_BLOCK_ID: {
958 return handleSubBlock<TemplateParamInfo>(
959 ID, I, CreateAddFunc(addTemplateParam<T>));
960 }
961 case BI_TYPEDEF_BLOCK_ID: {
962 return handleSubBlock<TypedefInfo>(ID, I,
963 CreateAddFunc(addChild<T, TypedefInfo>));
964 }
965 case BI_CONSTRAINT_BLOCK_ID: {
966 return handleSubBlock<ConstraintInfo>(ID, I,
967 CreateAddFunc(addConstraint<T>));
968 }
969 case BI_CONCEPT_BLOCK_ID: {
970 return handleSubBlock<ConceptInfo>(ID, I,
971 CreateAddFunc(addChild<T, ConceptInfo>));
972 }
973 case BI_VAR_BLOCK_ID: {
974 return handleSubBlock<VarInfo>(ID, I, CreateAddFunc(addChild<T, VarInfo>));
975 }
976 case BI_FRIEND_BLOCK_ID: {
977 return handleSubBlock<FriendInfo>(ID, I,
978 CreateAddFunc(addChild<T, FriendInfo>));
979 }
980 default:
981 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
982 S: "invalid subblock type");
983 }
984}
985
986ClangDocBitcodeReader::Cursor
987ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
988 llvm::TimeTraceScope("Reducing infos", "skipUntilRecordOrBlock");
989 BlockOrRecordID = 0;
990
991 while (!Stream.AtEndOfStream()) {
992 Expected<unsigned> MaybeCode = Stream.ReadCode();
993 if (!MaybeCode) {
994 // FIXME this drops the error on the floor.
995 consumeError(Err: MaybeCode.takeError());
996 return Cursor::BadBlock;
997 }
998
999 unsigned Code = MaybeCode.get();
1000 if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
1001 BlockOrRecordID = Code;
1002 return Cursor::Record;
1003 }
1004 switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
1005 case llvm::bitc::ENTER_SUBBLOCK:
1006 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
1007 BlockOrRecordID = MaybeID.get();
1008 else {
1009 // FIXME this drops the error on the floor.
1010 consumeError(Err: MaybeID.takeError());
1011 }
1012 return Cursor::BlockBegin;
1013 case llvm::bitc::END_BLOCK:
1014 if (Stream.ReadBlockEnd())
1015 return Cursor::BadBlock;
1016 return Cursor::BlockEnd;
1017 case llvm::bitc::DEFINE_ABBREV:
1018 if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
1019 // FIXME this drops the error on the floor.
1020 consumeError(Err: std::move(Err));
1021 }
1022 continue;
1023 case llvm::bitc::UNABBREV_RECORD:
1024 return Cursor::BadBlock;
1025 case llvm::bitc::FIRST_APPLICATION_ABBREV:
1026 llvm_unreachable("Unexpected abbrev id.");
1027 }
1028 }
1029 llvm_unreachable("Premature stream end.");
1030}
1031
1032llvm::Error ClangDocBitcodeReader::validateStream() {
1033 if (Stream.AtEndOfStream())
1034 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1035 S: "premature end of stream");
1036
1037 // Sniff for the signature.
1038 for (int Idx = 0; Idx != 4; ++Idx) {
1039 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(NumBits: 8);
1040 if (!MaybeRead)
1041 return MaybeRead.takeError();
1042 if (MaybeRead.get() != BitCodeConstants::Signature[Idx])
1043 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1044 S: "invalid bitcode signature");
1045 }
1046 return llvm::Error::success();
1047}
1048
1049llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
1050 llvm::TimeTraceScope("Reducing infos", "readBlockInfoBlock");
1051 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
1052 Stream.ReadBlockInfoBlock();
1053 if (!MaybeBlockInfo)
1054 return MaybeBlockInfo.takeError();
1055 BlockInfo = MaybeBlockInfo.get();
1056 if (!BlockInfo)
1057 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1058 S: "unable to parse BlockInfoBlock");
1059 Stream.setBlockInfo(&*BlockInfo);
1060 return llvm::Error::success();
1061}
1062
1063template <typename T>
1064llvm::Expected<std::unique_ptr<Info>>
1065ClangDocBitcodeReader::createInfo(unsigned ID) {
1066 llvm::TimeTraceScope("Reducing infos", "createInfo");
1067 std::unique_ptr<Info> I = std::make_unique<T>();
1068 if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
1069 return std::move(Err);
1070 return std::unique_ptr<Info>{std::move(I)};
1071}
1072
1073llvm::Expected<std::unique_ptr<Info>>
1074ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
1075 llvm::TimeTraceScope("Reducing infos", "readBlockToInfo");
1076 switch (ID) {
1077 case BI_NAMESPACE_BLOCK_ID:
1078 return createInfo<NamespaceInfo>(ID);
1079 case BI_RECORD_BLOCK_ID:
1080 return createInfo<RecordInfo>(ID);
1081 case BI_ENUM_BLOCK_ID:
1082 return createInfo<EnumInfo>(ID);
1083 case BI_TYPEDEF_BLOCK_ID:
1084 return createInfo<TypedefInfo>(ID);
1085 case BI_CONCEPT_BLOCK_ID:
1086 return createInfo<ConceptInfo>(ID);
1087 case BI_FUNCTION_BLOCK_ID:
1088 return createInfo<FunctionInfo>(ID);
1089 case BI_VAR_BLOCK_ID:
1090 return createInfo<VarInfo>(ID);
1091 case BI_FRIEND_BLOCK_ID:
1092 return createInfo<FriendInfo>(ID);
1093 default:
1094 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1095 S: "cannot create info");
1096 }
1097}
1098
1099// Entry point
1100llvm::Expected<std::vector<std::unique_ptr<Info>>>
1101ClangDocBitcodeReader::readBitcode() {
1102 std::vector<std::unique_ptr<Info>> Infos;
1103 if (auto Err = validateStream())
1104 return std::move(Err);
1105
1106 // Read the top level blocks.
1107 while (!Stream.AtEndOfStream()) {
1108 Expected<unsigned> MaybeCode = Stream.ReadCode();
1109 if (!MaybeCode)
1110 return MaybeCode.takeError();
1111 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
1112 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1113 S: "no blocks in input");
1114 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
1115 if (!MaybeID)
1116 return MaybeID.takeError();
1117 unsigned ID = MaybeID.get();
1118 switch (ID) {
1119 // NamedType and Comment blocks should not appear at the top level
1120 case BI_TYPE_BLOCK_ID:
1121 case BI_FIELD_TYPE_BLOCK_ID:
1122 case BI_MEMBER_TYPE_BLOCK_ID:
1123 case BI_COMMENT_BLOCK_ID:
1124 case BI_REFERENCE_BLOCK_ID:
1125 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
1126 S: "invalid top level block");
1127 case BI_NAMESPACE_BLOCK_ID:
1128 case BI_RECORD_BLOCK_ID:
1129 case BI_ENUM_BLOCK_ID:
1130 case BI_TYPEDEF_BLOCK_ID:
1131 case BI_CONCEPT_BLOCK_ID:
1132 case BI_VAR_BLOCK_ID:
1133 case BI_FRIEND_BLOCK_ID:
1134 case BI_FUNCTION_BLOCK_ID: {
1135 auto InfoOrErr = readBlockToInfo(ID);
1136 if (!InfoOrErr)
1137 return InfoOrErr.takeError();
1138 Infos.emplace_back(args: std::move(InfoOrErr.get()));
1139 continue;
1140 }
1141 case BI_VERSION_BLOCK_ID:
1142 if (auto Err = readBlock(ID, I: VersionNumber))
1143 return std::move(Err);
1144 continue;
1145 case llvm::bitc::BLOCKINFO_BLOCK_ID:
1146 if (auto Err = readBlockInfoBlock())
1147 return std::move(Err);
1148 continue;
1149 default:
1150 if (llvm::Error Err = Stream.SkipBlock()) {
1151 // FIXME this drops the error on the floor.
1152 consumeError(Err: std::move(Err));
1153 }
1154 continue;
1155 }
1156 }
1157 return std::move(Infos);
1158}
1159
1160} // namespace doc
1161} // namespace clang
1162

source code of clang-tools-extra/clang-doc/BitcodeReader.cpp