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