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
decodeRecord(Record R,llvm::SmallVectorImpl<char> & Field,llvm::StringRef Blob)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
decodeRecord(Record R,SymbolID & Field,llvm::StringRef Blob)26 llvm::Error decodeRecord(Record R, SymbolID &Field, llvm::StringRef Blob) {
27 if (R[0] != BitCodeConstants::USRHashSize)
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
decodeRecord(Record R,bool & Field,llvm::StringRef Blob)38 llvm::Error decodeRecord(Record R, bool &Field, llvm::StringRef Blob) {
39 Field = R[0] != 0;
40 return llvm::Error::success();
41 }
42
decodeRecord(Record R,int & Field,llvm::StringRef Blob)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
decodeRecord(Record R,AccessSpecifier & Field,llvm::StringRef Blob)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
decodeRecord(Record R,TagTypeKind & Field,llvm::StringRef Blob)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
decodeRecord(Record R,llvm::Optional<Location> & Field,llvm::StringRef Blob)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
decodeRecord(Record R,InfoType & Field,llvm::StringRef Blob)90 llvm::Error decodeRecord(Record R, InfoType &Field, llvm::StringRef Blob) {
91 switch (auto IT = static_cast<InfoType>(R[0])) {
92 case InfoType::IT_namespace:
93 case InfoType::IT_record:
94 case InfoType::IT_function:
95 case InfoType::IT_default:
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
decodeRecord(Record R,FieldId & Field,llvm::StringRef Blob)104 llvm::Error decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) {
105 switch (auto F = static_cast<FieldId>(R[0])) {
106 case FieldId::F_namespace:
107 case FieldId::F_parent:
108 case FieldId::F_vparent:
109 case FieldId::F_type:
110 case FieldId::F_child_namespace:
111 case FieldId::F_child_record:
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
decodeRecord(Record R,llvm::SmallVectorImpl<llvm::SmallString<16>> & Field,llvm::StringRef Blob)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
decodeRecord(Record R,llvm::SmallVectorImpl<Location> & Field,llvm::StringRef Blob)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,const unsigned VersionNo)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,NamespaceInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,RecordInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,EnumInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,FunctionInfo * I)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);
210 case FUNCTION_DEFLOCATION:
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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,TypeInfo * I)224 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
225 TypeInfo *I) {
226 return llvm::Error::success();
227 }
228
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,FieldTypeInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,MemberTypeInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,CommentInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,Reference * I,FieldId & F)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
getCommentInfo(T I)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
getCommentInfo(FunctionInfo * I)309 template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
310 I->Description.emplace_back();
311 return &I->Description.back();
312 }
313
getCommentInfo(NamespaceInfo * I)314 template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
315 I->Description.emplace_back();
316 return &I->Description.back();
317 }
318
getCommentInfo(RecordInfo * I)319 template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
320 I->Description.emplace_back();
321 return &I->Description.back();
322 }
323
getCommentInfo(EnumInfo * I)324 template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
325 I->Description.emplace_back();
326 return &I->Description.back();
327 }
328
getCommentInfo(CommentInfo * I)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 <>
getCommentInfo(std::unique_ptr<CommentInfo> & I)335 llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
336 return getCommentInfo(I.get());
337 }
338
339 template <typename T, typename TTypeInfo>
addTypeInfo(T I,TTypeInfo && TI)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
addTypeInfo(RecordInfo * I,MemberTypeInfo && T)346 template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
347 I->Members.emplace_back(std::move(T));
348 return llvm::Error::success();
349 }
350
addTypeInfo(FunctionInfo * I,TypeInfo && T)351 template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
352 I->ReturnType = std::move(T);
353 return llvm::Error::success();
354 }
355
addTypeInfo(FunctionInfo * I,FieldTypeInfo && T)356 template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
357 I->Params.emplace_back(std::move(T));
358 return llvm::Error::success();
359 }
360
addReference(T I,Reference && R,FieldId F)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
addReference(TypeInfo * I,Reference && R,FieldId F)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 <>
addReference(FieldTypeInfo * I,Reference && R,FieldId F)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 <>
addReference(MemberTypeInfo * I,Reference && R,FieldId F)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
addReference(EnumInfo * I,Reference && R,FieldId F)405 template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
406 switch (F) {
407 case FieldId::F_namespace:
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 <>
addReference(NamespaceInfo * I,Reference && R,FieldId F)418 llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
419 switch (F) {
420 case FieldId::F_namespace:
421 I->Namespace.emplace_back(std::move(R));
422 return llvm::Error::success();
423 case FieldId::F_child_namespace:
424 I->ChildNamespaces.emplace_back(std::move(R));
425 return llvm::Error::success();
426 case FieldId::F_child_record:
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 <>
addReference(FunctionInfo * I,Reference && R,FieldId F)437 llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
438 switch (F) {
439 case FieldId::F_namespace:
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
addReference(RecordInfo * I,Reference && R,FieldId F)452 template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
453 switch (F) {
454 case FieldId::F_namespace:
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();
463 case FieldId::F_child_record:
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>
addChild(T I,ChildInfoType && R)474 void addChild(T I, ChildInfoType &&R) {
475 llvm::errs() << "Invalid child type for info.\n";
476 exit(1);
477 }
478
addChild(NamespaceInfo * I,FunctionInfo && R)479 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
480 I->ChildFunctions.emplace_back(std::move(R));
481 }
482
addChild(NamespaceInfo * I,EnumInfo && R)483 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
484 I->ChildEnums.emplace_back(std::move(R));
485 }
486
addChild(RecordInfo * I,FunctionInfo && R)487 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
488 I->ChildFunctions.emplace_back(std::move(R));
489 }
490
addChild(RecordInfo * I,EnumInfo && R)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>
readRecord(unsigned ID,T I)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 <>
readRecord(unsigned ID,Reference * I)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>
readBlock(unsigned ID,T I)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>
readSubBlock(unsigned ID,T I)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 }
576 case BI_MEMBER_TYPE_BLOCK_ID: {
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
skipUntilRecordOrBlock(unsigned & BlockOrRecordID)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
validateStream()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
readBlockInfoBlock()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>>
createInfo(unsigned ID)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>>
readBlockToInfo(unsigned ID)698 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
699 switch (ID) {
700 case BI_NAMESPACE_BLOCK_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);
706 case BI_FUNCTION_BLOCK_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>>>
readBitcode()716 ClangDocBitcodeReader::readBitcode() {
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:
736 case BI_FIELD_TYPE_BLOCK_ID:
737 case BI_MEMBER_TYPE_BLOCK_ID:
738 case BI_COMMENT_BLOCK_ID:
739 case BI_REFERENCE_BLOCK_ID:
740 return llvm::make_error<llvm::StringError>(
741 "Invalid top level block.\n", llvm::inconvertibleErrorCode());
742 case BI_NAMESPACE_BLOCK_ID:
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
773