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