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