xref: /llvm-project/clang-tools-extra/clang-doc/BitcodeReader.cpp (revision 15e468e0d5b7c7ac64a387513c9c9115d8875ef8)
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/ADT/Optional.h"
12 #include "llvm/Support/Error.h"
13 #include "llvm/Support/raw_ostream.h"
14 
15 namespace clang {
16 namespace doc {
17 
18 using Record = llvm::SmallVector<uint64_t, 1024>;
19 
20 llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<char> &Field,
21                          llvm::StringRef Blob) {
22   Field.assign(Blob.begin(), Blob.end());
23   return llvm::Error::success();
24 }
25 
26 llvm::Error decodeRecord(Record R, SymbolID &Field, llvm::StringRef Blob) {
27   if (R[0] != BitCodeConstants::USRHashSize)
28     return llvm::make_error<llvm::StringError>("Incorrect USR size.\n",
29                                                llvm::inconvertibleErrorCode());
30 
31   // First position in the record is the length of the following array, so we
32   // copy the following elements to the field.
33   for (int I = 0, E = R[0]; I < E; ++I)
34     Field[I] = R[I + 1];
35   return llvm::Error::success();
36 }
37 
38 llvm::Error decodeRecord(Record R, bool &Field, llvm::StringRef Blob) {
39   Field = R[0] != 0;
40   return llvm::Error::success();
41 }
42 
43 llvm::Error decodeRecord(Record R, int &Field, llvm::StringRef Blob) {
44   if (R[0] > INT_MAX)
45     return llvm::make_error<llvm::StringError>("Integer too large to parse.\n",
46                                                llvm::inconvertibleErrorCode());
47   Field = (int)R[0];
48   return llvm::Error::success();
49 }
50 
51 llvm::Error decodeRecord(Record R, AccessSpecifier &Field,
52                          llvm::StringRef Blob) {
53   switch (R[0]) {
54   case AS_public:
55   case AS_private:
56   case AS_protected:
57   case AS_none:
58     Field = (AccessSpecifier)R[0];
59     return llvm::Error::success();
60   default:
61     return llvm::make_error<llvm::StringError>(
62         "Invalid value for AccessSpecifier.\n", llvm::inconvertibleErrorCode());
63   }
64 }
65 
66 llvm::Error decodeRecord(Record R, TagTypeKind &Field, llvm::StringRef Blob) {
67   switch (R[0]) {
68   case TTK_Struct:
69   case TTK_Interface:
70   case TTK_Union:
71   case TTK_Class:
72   case TTK_Enum:
73     Field = (TagTypeKind)R[0];
74     return llvm::Error::success();
75   default:
76     return llvm::make_error<llvm::StringError>(
77         "Invalid value for TagTypeKind.\n", llvm::inconvertibleErrorCode());
78   }
79 }
80 
81 llvm::Error decodeRecord(Record R, llvm::Optional<Location> &Field,
82                          llvm::StringRef Blob) {
83   if (R[0] > INT_MAX)
84     return llvm::make_error<llvm::StringError>("Integer too large to parse.\n",
85                                                llvm::inconvertibleErrorCode());
86   Field.emplace((int)R[0], Blob);
87   return llvm::Error::success();
88 }
89 
90 llvm::Error decodeRecord(Record R, InfoType &Field, llvm::StringRef Blob) {
91   switch (auto IT = static_cast<InfoType>(R[0])) {
92   case InfoType::IT_namespace:
93   case InfoType::IT_record:
94   case InfoType::IT_function:
95   case InfoType::IT_default:
96   case InfoType::IT_enum:
97     Field = IT;
98     return llvm::Error::success();
99   }
100   return llvm::make_error<llvm::StringError>("Invalid value for InfoType.\n",
101                                              llvm::inconvertibleErrorCode());
102 }
103 
104 llvm::Error decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) {
105   switch (auto F = static_cast<FieldId>(R[0])) {
106   case FieldId::F_namespace:
107   case FieldId::F_parent:
108   case FieldId::F_vparent:
109   case FieldId::F_type:
110   case FieldId::F_child_namespace:
111   case FieldId::F_child_record:
112   case FieldId::F_default:
113     Field = F;
114     return llvm::Error::success();
115   }
116   return llvm::make_error<llvm::StringError>("Invalid value for FieldId.\n",
117                                              llvm::inconvertibleErrorCode());
118 }
119 
120 llvm::Error decodeRecord(Record R,
121                          llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
122                          llvm::StringRef Blob) {
123   Field.push_back(Blob);
124   return llvm::Error::success();
125 }
126 
127 llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<Location> &Field,
128                          llvm::StringRef Blob) {
129   if (R[0] > INT_MAX)
130     return llvm::make_error<llvm::StringError>("Integer too large to parse.\n",
131                                                llvm::inconvertibleErrorCode());
132   Field.emplace_back((int)R[0], Blob);
133   return llvm::Error::success();
134 }
135 
136 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
137                         const unsigned VersionNo) {
138   if (ID == VERSION && R[0] == VersionNo)
139     return llvm::Error::success();
140   return llvm::make_error<llvm::StringError>(
141       "Mismatched bitcode version number.\n", llvm::inconvertibleErrorCode());
142 }
143 
144 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
145                         NamespaceInfo *I) {
146   switch (ID) {
147   case NAMESPACE_USR:
148     return decodeRecord(R, I->USR, Blob);
149   case NAMESPACE_NAME:
150     return decodeRecord(R, I->Name, Blob);
151   case NAMESPACE_PATH:
152     return decodeRecord(R, I->Path, Blob);
153   default:
154     return llvm::make_error<llvm::StringError>(
155         "Invalid field for NamespaceInfo.\n", llvm::inconvertibleErrorCode());
156   }
157 }
158 
159 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
160                         RecordInfo *I) {
161   switch (ID) {
162   case RECORD_USR:
163     return decodeRecord(R, I->USR, Blob);
164   case RECORD_NAME:
165     return decodeRecord(R, I->Name, Blob);
166   case RECORD_PATH:
167     return decodeRecord(R, I->Path, Blob);
168   case RECORD_DEFLOCATION:
169     return decodeRecord(R, I->DefLoc, Blob);
170   case RECORD_LOCATION:
171     return decodeRecord(R, I->Loc, Blob);
172   case RECORD_TAG_TYPE:
173     return decodeRecord(R, I->TagType, Blob);
174   case RECORD_IS_TYPE_DEF:
175     return decodeRecord(R, I->IsTypeDef, Blob);
176   default:
177     return llvm::make_error<llvm::StringError>(
178         "Invalid field for RecordInfo.\n", llvm::inconvertibleErrorCode());
179   }
180 }
181 
182 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
183                         EnumInfo *I) {
184   switch (ID) {
185   case ENUM_USR:
186     return decodeRecord(R, I->USR, Blob);
187   case ENUM_NAME:
188     return decodeRecord(R, I->Name, Blob);
189   case ENUM_DEFLOCATION:
190     return decodeRecord(R, I->DefLoc, Blob);
191   case ENUM_LOCATION:
192     return decodeRecord(R, I->Loc, Blob);
193   case ENUM_MEMBER:
194     return decodeRecord(R, I->Members, Blob);
195   case ENUM_SCOPED:
196     return decodeRecord(R, I->Scoped, Blob);
197   default:
198     return llvm::make_error<llvm::StringError>("Invalid field for EnumInfo.\n",
199                                                llvm::inconvertibleErrorCode());
200   }
201 }
202 
203 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
204                         FunctionInfo *I) {
205   switch (ID) {
206   case FUNCTION_USR:
207     return decodeRecord(R, I->USR, Blob);
208   case FUNCTION_NAME:
209     return decodeRecord(R, I->Name, Blob);
210   case FUNCTION_DEFLOCATION:
211     return decodeRecord(R, I->DefLoc, Blob);
212   case FUNCTION_LOCATION:
213     return decodeRecord(R, I->Loc, Blob);
214   case FUNCTION_ACCESS:
215     return decodeRecord(R, I->Access, Blob);
216   case FUNCTION_IS_METHOD:
217     return decodeRecord(R, I->IsMethod, Blob);
218   default:
219     return llvm::make_error<llvm::StringError>(
220         "Invalid field for FunctionInfo.\n", llvm::inconvertibleErrorCode());
221   }
222 }
223 
224 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
225                         TypeInfo *I) {
226   return llvm::Error::success();
227 }
228 
229 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
230                         FieldTypeInfo *I) {
231   switch (ID) {
232   case FIELD_TYPE_NAME:
233     return decodeRecord(R, I->Name, Blob);
234   default:
235     return llvm::make_error<llvm::StringError>("Invalid field for TypeInfo.\n",
236                                                llvm::inconvertibleErrorCode());
237   }
238 }
239 
240 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
241                         MemberTypeInfo *I) {
242   switch (ID) {
243   case MEMBER_TYPE_NAME:
244     return decodeRecord(R, I->Name, Blob);
245   case MEMBER_TYPE_ACCESS:
246     return decodeRecord(R, I->Access, Blob);
247   default:
248     return llvm::make_error<llvm::StringError>(
249         "Invalid field for MemberTypeInfo.\n", llvm::inconvertibleErrorCode());
250   }
251 }
252 
253 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
254                         CommentInfo *I) {
255   switch (ID) {
256   case COMMENT_KIND:
257     return decodeRecord(R, I->Kind, Blob);
258   case COMMENT_TEXT:
259     return decodeRecord(R, I->Text, Blob);
260   case COMMENT_NAME:
261     return decodeRecord(R, I->Name, Blob);
262   case COMMENT_DIRECTION:
263     return decodeRecord(R, I->Direction, Blob);
264   case COMMENT_PARAMNAME:
265     return decodeRecord(R, I->ParamName, Blob);
266   case COMMENT_CLOSENAME:
267     return decodeRecord(R, I->CloseName, Blob);
268   case COMMENT_ATTRKEY:
269     return decodeRecord(R, I->AttrKeys, Blob);
270   case COMMENT_ATTRVAL:
271     return decodeRecord(R, I->AttrValues, Blob);
272   case COMMENT_ARG:
273     return decodeRecord(R, I->Args, Blob);
274   case COMMENT_SELFCLOSING:
275     return decodeRecord(R, I->SelfClosing, Blob);
276   case COMMENT_EXPLICIT:
277     return decodeRecord(R, I->Explicit, Blob);
278   default:
279     return llvm::make_error<llvm::StringError>(
280         "Invalid field for CommentInfo.\n", llvm::inconvertibleErrorCode());
281   }
282 }
283 
284 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
285                         Reference *I, FieldId &F) {
286   switch (ID) {
287   case REFERENCE_USR:
288     return decodeRecord(R, I->USR, Blob);
289   case REFERENCE_NAME:
290     return decodeRecord(R, I->Name, Blob);
291   case REFERENCE_TYPE:
292     return decodeRecord(R, I->RefType, Blob);
293   case REFERENCE_PATH:
294     return decodeRecord(R, I->Path, Blob);
295   case REFERENCE_IS_IN_GLOBAL_NAMESPACE:
296     return decodeRecord(R, I->IsInGlobalNamespace, Blob);
297   case REFERENCE_FIELD:
298     return decodeRecord(R, F, Blob);
299   default:
300     return llvm::make_error<llvm::StringError>("Invalid field for Reference.\n",
301                                                llvm::inconvertibleErrorCode());
302   }
303 }
304 
305 template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) {
306   return llvm::make_error<llvm::StringError>(
307       "Invalid type cannot contain CommentInfo.\n",
308       llvm::inconvertibleErrorCode());
309 }
310 
311 template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
312   I->Description.emplace_back();
313   return &I->Description.back();
314 }
315 
316 template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
317   I->Description.emplace_back();
318   return &I->Description.back();
319 }
320 
321 template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
322   I->Description.emplace_back();
323   return &I->Description.back();
324 }
325 
326 template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
327   I->Description.emplace_back();
328   return &I->Description.back();
329 }
330 
331 template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
332   I->Children.emplace_back(llvm::make_unique<CommentInfo>());
333   return I->Children.back().get();
334 }
335 
336 template <>
337 llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
338   return getCommentInfo(I.get());
339 }
340 
341 template <typename T, typename TTypeInfo>
342 llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
343   return llvm::make_error<llvm::StringError>(
344       "Invalid type cannot contain TypeInfo.\n",
345       llvm::inconvertibleErrorCode());
346 }
347 
348 template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
349   I->Members.emplace_back(std::move(T));
350   return llvm::Error::success();
351 }
352 
353 template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
354   I->ReturnType = std::move(T);
355   return llvm::Error::success();
356 }
357 
358 template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
359   I->Params.emplace_back(std::move(T));
360   return llvm::Error::success();
361 }
362 
363 template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) {
364   return llvm::make_error<llvm::StringError>(
365       "Invalid type cannot contain Reference\n",
366       llvm::inconvertibleErrorCode());
367 }
368 
369 template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) {
370   switch (F) {
371   case FieldId::F_type:
372     I->Type = std::move(R);
373     return llvm::Error::success();
374   default:
375     return llvm::make_error<llvm::StringError>(
376         "Invalid type cannot contain Reference.\n",
377         llvm::inconvertibleErrorCode());
378   }
379 }
380 
381 template <>
382 llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F) {
383   switch (F) {
384   case FieldId::F_type:
385     I->Type = std::move(R);
386     return llvm::Error::success();
387   default:
388     return llvm::make_error<llvm::StringError>(
389         "Invalid type cannot contain Reference.\n",
390         llvm::inconvertibleErrorCode());
391   }
392 }
393 
394 template <>
395 llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F) {
396   switch (F) {
397   case FieldId::F_type:
398     I->Type = std::move(R);
399     return llvm::Error::success();
400   default:
401     return llvm::make_error<llvm::StringError>(
402         "Invalid type cannot contain Reference.\n",
403         llvm::inconvertibleErrorCode());
404   }
405 }
406 
407 template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
408   switch (F) {
409   case FieldId::F_namespace:
410     I->Namespace.emplace_back(std::move(R));
411     return llvm::Error::success();
412   default:
413     return llvm::make_error<llvm::StringError>(
414         "Invalid type cannot contain Reference.\n",
415         llvm::inconvertibleErrorCode());
416   }
417 }
418 
419 template <>
420 llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
421   switch (F) {
422   case FieldId::F_namespace:
423     I->Namespace.emplace_back(std::move(R));
424     return llvm::Error::success();
425   case FieldId::F_child_namespace:
426     I->ChildNamespaces.emplace_back(std::move(R));
427     return llvm::Error::success();
428   case FieldId::F_child_record:
429     I->ChildRecords.emplace_back(std::move(R));
430     return llvm::Error::success();
431   default:
432     return llvm::make_error<llvm::StringError>(
433         "Invalid type cannot contain Reference.\n",
434         llvm::inconvertibleErrorCode());
435   }
436 }
437 
438 template <>
439 llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
440   switch (F) {
441   case FieldId::F_namespace:
442     I->Namespace.emplace_back(std::move(R));
443     return llvm::Error::success();
444   case FieldId::F_parent:
445     I->Parent = std::move(R);
446     return llvm::Error::success();
447   default:
448     return llvm::make_error<llvm::StringError>(
449         "Invalid type cannot contain Reference.\n",
450         llvm::inconvertibleErrorCode());
451   }
452 }
453 
454 template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
455   switch (F) {
456   case FieldId::F_namespace:
457     I->Namespace.emplace_back(std::move(R));
458     return llvm::Error::success();
459   case FieldId::F_parent:
460     I->Parents.emplace_back(std::move(R));
461     return llvm::Error::success();
462   case FieldId::F_vparent:
463     I->VirtualParents.emplace_back(std::move(R));
464     return llvm::Error::success();
465   case FieldId::F_child_record:
466     I->ChildRecords.emplace_back(std::move(R));
467     return llvm::Error::success();
468   default:
469     return llvm::make_error<llvm::StringError>(
470         "Invalid type cannot contain Reference.\n",
471         llvm::inconvertibleErrorCode());
472   }
473 }
474 
475 template <typename T, typename ChildInfoType>
476 void addChild(T I, ChildInfoType &&R) {
477   llvm::errs() << "Invalid child type for info.\n";
478   exit(1);
479 }
480 
481 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
482   I->ChildFunctions.emplace_back(std::move(R));
483 }
484 
485 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
486   I->ChildEnums.emplace_back(std::move(R));
487 }
488 
489 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
490   I->ChildFunctions.emplace_back(std::move(R));
491 }
492 
493 template <> void addChild(RecordInfo *I, EnumInfo &&R) {
494   I->ChildEnums.emplace_back(std::move(R));
495 }
496 
497 // Read records from bitcode into a given info.
498 template <typename T>
499 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
500   Record R;
501   llvm::StringRef Blob;
502   llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
503   if (!MaybeRecID)
504     return MaybeRecID.takeError();
505   return parseRecord(R, MaybeRecID.get(), Blob, I);
506 }
507 
508 template <>
509 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
510   Record R;
511   llvm::StringRef Blob;
512   llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
513   if (!MaybeRecID)
514     return MaybeRecID.takeError();
515   return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
516 }
517 
518 // Read a block of records into a single info.
519 template <typename T>
520 llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
521   if (llvm::Error Err = Stream.EnterSubBlock(ID))
522     return Err;
523 
524   while (true) {
525     unsigned BlockOrCode = 0;
526     Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
527 
528     switch (Res) {
529     case Cursor::BadBlock:
530       return llvm::make_error<llvm::StringError>(
531           "Bad block found.\n", llvm::inconvertibleErrorCode());
532     case Cursor::BlockEnd:
533       return llvm::Error::success();
534     case Cursor::BlockBegin:
535       if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
536         if (llvm::Error Skipped = Stream.SkipBlock())
537           return joinErrors(std::move(Err), std::move(Skipped));
538         return Err;
539       }
540       continue;
541     case Cursor::Record:
542       break;
543     }
544     if (auto Err = readRecord(BlockOrCode, I))
545       return Err;
546   }
547 }
548 
549 template <typename T>
550 llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
551   switch (ID) {
552   // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or
553   // EnumInfo subblocks
554   case BI_COMMENT_BLOCK_ID: {
555     auto Comment = getCommentInfo(I);
556     if (!Comment)
557       return Comment.takeError();
558     if (auto Err = readBlock(ID, Comment.get()))
559       return Err;
560     return llvm::Error::success();
561   }
562   case BI_TYPE_BLOCK_ID: {
563     TypeInfo TI;
564     if (auto Err = readBlock(ID, &TI))
565       return Err;
566     if (auto Err = addTypeInfo(I, std::move(TI)))
567       return Err;
568     return llvm::Error::success();
569   }
570   case BI_FIELD_TYPE_BLOCK_ID: {
571     FieldTypeInfo TI;
572     if (auto Err = readBlock(ID, &TI))
573       return Err;
574     if (auto Err = addTypeInfo(I, std::move(TI)))
575       return Err;
576     return llvm::Error::success();
577   }
578   case BI_MEMBER_TYPE_BLOCK_ID: {
579     MemberTypeInfo TI;
580     if (auto Err = readBlock(ID, &TI))
581       return Err;
582     if (auto Err = addTypeInfo(I, std::move(TI)))
583       return Err;
584     return llvm::Error::success();
585   }
586   case BI_REFERENCE_BLOCK_ID: {
587     Reference R;
588     if (auto Err = readBlock(ID, &R))
589       return Err;
590     if (auto Err = addReference(I, std::move(R), CurrentReferenceField))
591       return Err;
592     return llvm::Error::success();
593   }
594   case BI_FUNCTION_BLOCK_ID: {
595     FunctionInfo F;
596     if (auto Err = readBlock(ID, &F))
597       return Err;
598     addChild(I, std::move(F));
599     return llvm::Error::success();
600   }
601   case BI_ENUM_BLOCK_ID: {
602     EnumInfo E;
603     if (auto Err = readBlock(ID, &E))
604       return Err;
605     addChild(I, std::move(E));
606     return llvm::Error::success();
607   }
608   default:
609     return llvm::make_error<llvm::StringError>("Invalid subblock type.\n",
610                                                llvm::inconvertibleErrorCode());
611   }
612 }
613 
614 ClangDocBitcodeReader::Cursor
615 ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
616   BlockOrRecordID = 0;
617 
618   while (!Stream.AtEndOfStream()) {
619     Expected<unsigned> MaybeCode = Stream.ReadCode();
620     if (!MaybeCode) {
621       // FIXME this drops the error on the floor.
622       consumeError(MaybeCode.takeError());
623       return Cursor::BadBlock;
624     }
625 
626     unsigned Code = MaybeCode.get();
627     if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
628       BlockOrRecordID = Code;
629       return Cursor::Record;
630     }
631     switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
632     case llvm::bitc::ENTER_SUBBLOCK:
633       if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
634         BlockOrRecordID = MaybeID.get();
635       else {
636         // FIXME this drops the error on the floor.
637         consumeError(MaybeID.takeError());
638       }
639       return Cursor::BlockBegin;
640     case llvm::bitc::END_BLOCK:
641       if (Stream.ReadBlockEnd())
642         return Cursor::BadBlock;
643       return Cursor::BlockEnd;
644     case llvm::bitc::DEFINE_ABBREV:
645       if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
646         // FIXME this drops the error on the floor.
647         consumeError(std::move(Err));
648       }
649       continue;
650     case llvm::bitc::UNABBREV_RECORD:
651       return Cursor::BadBlock;
652     case llvm::bitc::FIRST_APPLICATION_ABBREV:
653       llvm_unreachable("Unexpected abbrev id.");
654     }
655   }
656   llvm_unreachable("Premature stream end.");
657 }
658 
659 llvm::Error ClangDocBitcodeReader::validateStream() {
660   if (Stream.AtEndOfStream())
661     return llvm::make_error<llvm::StringError>("Premature end of stream.\n",
662                                                llvm::inconvertibleErrorCode());
663 
664   // Sniff for the signature.
665   for (int Idx = 0; Idx != 4; ++Idx) {
666     Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
667     if (!MaybeRead)
668       return MaybeRead.takeError();
669     else if (MaybeRead.get() != BitCodeConstants::Signature[Idx])
670       return llvm::make_error<llvm::StringError>(
671           "Invalid bitcode signature.\n", llvm::inconvertibleErrorCode());
672   }
673   return llvm::Error::success();
674 }
675 
676 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
677   Expected<Optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
678       Stream.ReadBlockInfoBlock();
679   if (!MaybeBlockInfo)
680     return MaybeBlockInfo.takeError();
681   else
682     BlockInfo = MaybeBlockInfo.get();
683   if (!BlockInfo)
684     return llvm::make_error<llvm::StringError>(
685         "Unable to parse BlockInfoBlock.\n", llvm::inconvertibleErrorCode());
686   Stream.setBlockInfo(&*BlockInfo);
687   return llvm::Error::success();
688 }
689 
690 template <typename T>
691 llvm::Expected<std::unique_ptr<Info>>
692 ClangDocBitcodeReader::createInfo(unsigned ID) {
693   std::unique_ptr<Info> I = llvm::make_unique<T>();
694   if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
695     return std::move(Err);
696   return std::unique_ptr<Info>{std::move(I)};
697 }
698 
699 llvm::Expected<std::unique_ptr<Info>>
700 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
701   switch (ID) {
702   case BI_NAMESPACE_BLOCK_ID:
703     return createInfo<NamespaceInfo>(ID);
704   case BI_RECORD_BLOCK_ID:
705     return createInfo<RecordInfo>(ID);
706   case BI_ENUM_BLOCK_ID:
707     return createInfo<EnumInfo>(ID);
708   case BI_FUNCTION_BLOCK_ID:
709     return createInfo<FunctionInfo>(ID);
710   default:
711     return llvm::make_error<llvm::StringError>("Cannot create info.\n",
712                                                llvm::inconvertibleErrorCode());
713   }
714 }
715 
716 // Entry point
717 llvm::Expected<std::vector<std::unique_ptr<Info>>>
718 ClangDocBitcodeReader::readBitcode() {
719   std::vector<std::unique_ptr<Info>> Infos;
720   if (auto Err = validateStream())
721     return std::move(Err);
722 
723   // Read the top level blocks.
724   while (!Stream.AtEndOfStream()) {
725     Expected<unsigned> MaybeCode = Stream.ReadCode();
726     if (!MaybeCode)
727       return MaybeCode.takeError();
728     if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
729       return llvm::make_error<llvm::StringError>(
730           "No blocks in input.\n", llvm::inconvertibleErrorCode());
731     Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
732     if (!MaybeID)
733       return MaybeID.takeError();
734     unsigned ID = MaybeID.get();
735     switch (ID) {
736     // NamedType and Comment blocks should not appear at the top level
737     case BI_TYPE_BLOCK_ID:
738     case BI_FIELD_TYPE_BLOCK_ID:
739     case BI_MEMBER_TYPE_BLOCK_ID:
740     case BI_COMMENT_BLOCK_ID:
741     case BI_REFERENCE_BLOCK_ID:
742       return llvm::make_error<llvm::StringError>(
743           "Invalid top level block.\n", llvm::inconvertibleErrorCode());
744     case BI_NAMESPACE_BLOCK_ID:
745     case BI_RECORD_BLOCK_ID:
746     case BI_ENUM_BLOCK_ID:
747     case BI_FUNCTION_BLOCK_ID: {
748       auto InfoOrErr = readBlockToInfo(ID);
749       if (!InfoOrErr)
750         return InfoOrErr.takeError();
751       Infos.emplace_back(std::move(InfoOrErr.get()));
752       continue;
753     }
754     case BI_VERSION_BLOCK_ID:
755       if (auto Err = readBlock(ID, VersionNumber))
756         return std::move(Err);
757       continue;
758     case llvm::bitc::BLOCKINFO_BLOCK_ID:
759       if (auto Err = readBlockInfoBlock())
760         return std::move(Err);
761       continue;
762     default:
763       if (llvm::Error Err = Stream.SkipBlock()) {
764         // FIXME this drops the error on the floor.
765         consumeError(std::move(Err));
766       }
767       continue;
768     }
769   }
770   return std::move(Infos);
771 }
772 
773 } // namespace doc
774 } // namespace clang
775