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

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