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