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