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