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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

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