clang-tools  8.0.0
BitcodeReader.cpp
Go to the documentation of this file.
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 
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 
27 llvm::Error decodeRecord(Record R, SymbolID &Field, llvm::StringRef Blob) {
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 
39 llvm::Error decodeRecord(Record R, bool &Field, llvm::StringRef Blob) {
40  Field = R[0] != 0;
41  return llvm::Error::success();
42 }
43 
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 
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 
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 
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 
91 llvm::Error decodeRecord(Record R, InfoType &Field, llvm::StringRef Blob) {
92  switch (auto IT = static_cast<InfoType>(R[0])) {
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 
105 llvm::Error decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) {
106  switch (auto F = static_cast<FieldId>(R[0])) {
108  case FieldId::F_parent:
109  case FieldId::F_vparent:
110  case FieldId::F_type:
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 
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 
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 
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 
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 
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 
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 
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);
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 
219 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
220  TypeInfo *I) {
221  return llvm::Error::success();
222 }
223 
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 
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 
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 
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 
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 
302 template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
303  I->Description.emplace_back();
304  return &I->Description.back();
305 }
306 
307 template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
308  I->Description.emplace_back();
309  return &I->Description.back();
310 }
311 
312 template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
313  I->Description.emplace_back();
314  return &I->Description.back();
315 }
316 
317 template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
318  I->Description.emplace_back();
319  return &I->Description.back();
320 }
321 
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 <>
328 llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
329  return getCommentInfo(I.get());
330 }
331 
332 template <typename T, typename TTypeInfo>
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 
339 template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
340  I->Members.emplace_back(std::move(T));
341  return llvm::Error::success();
342 }
343 
344 template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
345  I->ReturnType = std::move(T);
346  return llvm::Error::success();
347 }
348 
349 template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
350  I->Params.emplace_back(std::move(T));
351  return llvm::Error::success();
352 }
353 
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 
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 <>
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 <>
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 
398 template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
399  switch (F) {
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 <>
411 llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
412  switch (F) {
414  I->Namespace.emplace_back(std::move(R));
415  return llvm::Error::success();
417  I->ChildNamespaces.emplace_back(std::move(R));
418  return llvm::Error::success();
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 <>
430 llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
431  switch (F) {
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 
445 template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
446  switch (F) {
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();
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>
467 void addChild(T I, ChildInfoType &&R) {
468  llvm::errs() << "Invalid child type for info.\n";
469  exit(1);
470 }
471 
472 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
473  I->ChildFunctions.emplace_back(std::move(R));
474 }
475 
476 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
477  I->ChildEnums.emplace_back(std::move(R));
478 }
479 
480 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
481  I->ChildFunctions.emplace_back(std::move(R));
482 }
483 
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>
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 <>
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>
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>
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  }
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
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 
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 
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>>
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>>
664 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
665  switch (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);
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>>>
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:
699  case BI_COMMENT_BLOCK_ID:
701  return llvm::make_error<llvm::StringError>(
702  "Invalid top level block.\n", llvm::inconvertibleErrorCode());
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
llvm::SmallVector< Reference, 4 > Namespace
static const unsigned VersionNumber
Definition: BitcodeWriter.h:34
llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
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
static constexpr char Signature[4]
Definition: BitcodeWriter.h:48
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:49
SmallString< 16 > Name
llvm::Expected< std::vector< std::unique_ptr< Info > > > readBitcode()
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::Error addReference(T I, Reference &&R, FieldId F)
llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)