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