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::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
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::createStringError(llvm::inconvertibleErrorCode(),
46 "integer too large to parse");
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::createStringError(llvm::inconvertibleErrorCode(),
62 "invalid value for AccessSpecifier");
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::createStringError(llvm::inconvertibleErrorCode(),
77 "invalid value for TagTypeKind");
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::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
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::createStringError(llvm::inconvertibleErrorCode(),
101 "invalid value for InfoType");
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::createStringError(llvm::inconvertibleErrorCode(),
117 "invalid value for FieldId");
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::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
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::createStringError(llvm::inconvertibleErrorCode(),
141 "mismatched bitcode version number");
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::createStringError(llvm::inconvertibleErrorCode(),
155 "invalid field for NamespaceInfo");
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::createStringError(llvm::inconvertibleErrorCode(),
178 "invalid field for RecordInfo");
179 }
180 }
181
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,BaseRecordInfo * I)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);
191 case BASE_RECORD_TAG_TYPE:
192 return decodeRecord(R, I->TagType, Blob);
193 case BASE_RECORD_IS_VIRTUAL:
194 return decodeRecord(R, I->IsVirtual, Blob);
195 case BASE_RECORD_ACCESS:
196 return decodeRecord(R, I->Access, Blob);
197 case BASE_RECORD_IS_PARENT:
198 return decodeRecord(R, I->IsParent, Blob);
199 default:
200 return llvm::createStringError(llvm::inconvertibleErrorCode(),
201 "invalid field for BaseRecordInfo");
202 }
203 }
204
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,EnumInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,FunctionInfo * I)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);
233 case FUNCTION_DEFLOCATION:
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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,TypeInfo * I)247 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
248 TypeInfo *I) {
249 return llvm::Error::success();
250 }
251
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,FieldTypeInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,MemberTypeInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,CommentInfo * I)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
parseRecord(Record R,unsigned ID,llvm::StringRef Blob,Reference * I,FieldId & F)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);
318 case REFERENCE_IS_IN_GLOBAL_NAMESPACE:
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
getCommentInfo(T I)328 template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) {
329 return llvm::createStringError(llvm::inconvertibleErrorCode(),
330 "invalid type cannot contain CommentInfo");
331 }
332
getCommentInfo(FunctionInfo * I)333 template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
334 I->Description.emplace_back();
335 return &I->Description.back();
336 }
337
getCommentInfo(NamespaceInfo * I)338 template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
339 I->Description.emplace_back();
340 return &I->Description.back();
341 }
342
getCommentInfo(RecordInfo * I)343 template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
344 I->Description.emplace_back();
345 return &I->Description.back();
346 }
347
getCommentInfo(EnumInfo * I)348 template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
349 I->Description.emplace_back();
350 return &I->Description.back();
351 }
352
getCommentInfo(CommentInfo * I)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 <>
getCommentInfo(std::unique_ptr<CommentInfo> & I)359 llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
360 return getCommentInfo(I.get());
361 }
362
363 template <typename T, typename TTypeInfo>
addTypeInfo(T I,TTypeInfo && TI)364 llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
365 return llvm::createStringError(llvm::inconvertibleErrorCode(),
366 "invalid type cannot contain TypeInfo");
367 }
368
addTypeInfo(RecordInfo * I,MemberTypeInfo && T)369 template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
370 I->Members.emplace_back(std::move(T));
371 return llvm::Error::success();
372 }
373
addTypeInfo(BaseRecordInfo * I,MemberTypeInfo && T)374 template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) {
375 I->Members.emplace_back(std::move(T));
376 return llvm::Error::success();
377 }
378
addTypeInfo(FunctionInfo * I,TypeInfo && T)379 template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
380 I->ReturnType = std::move(T);
381 return llvm::Error::success();
382 }
383
addTypeInfo(FunctionInfo * I,FieldTypeInfo && T)384 template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
385 I->Params.emplace_back(std::move(T));
386 return llvm::Error::success();
387 }
388
addReference(T I,Reference && R,FieldId F)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
addReference(TypeInfo * I,Reference && R,FieldId F)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 <>
addReference(FieldTypeInfo * I,Reference && R,FieldId F)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 <>
addReference(MemberTypeInfo * I,Reference && R,FieldId F)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
addReference(EnumInfo * I,Reference && R,FieldId F)429 template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
430 switch (F) {
431 case FieldId::F_namespace:
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 <>
addReference(NamespaceInfo * I,Reference && R,FieldId F)441 llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
442 switch (F) {
443 case FieldId::F_namespace:
444 I->Namespace.emplace_back(std::move(R));
445 return llvm::Error::success();
446 case FieldId::F_child_namespace:
447 I->ChildNamespaces.emplace_back(std::move(R));
448 return llvm::Error::success();
449 case FieldId::F_child_record:
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 <>
addReference(FunctionInfo * I,Reference && R,FieldId F)459 llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
460 switch (F) {
461 case FieldId::F_namespace:
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
addReference(RecordInfo * I,Reference && R,FieldId F)473 template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
474 switch (F) {
475 case FieldId::F_namespace:
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();
484 case FieldId::F_child_record:
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>
addChild(T I,ChildInfoType && R)494 void addChild(T I, ChildInfoType &&R) {
495 llvm::errs() << "invalid child type for info";
496 exit(1);
497 }
498
addChild(NamespaceInfo * I,FunctionInfo && R)499 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
500 I->ChildFunctions.emplace_back(std::move(R));
501 }
502
addChild(NamespaceInfo * I,EnumInfo && R)503 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
504 I->ChildEnums.emplace_back(std::move(R));
505 }
506
addChild(RecordInfo * I,FunctionInfo && R)507 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
508 I->ChildFunctions.emplace_back(std::move(R));
509 }
510
addChild(RecordInfo * I,EnumInfo && R)511 template <> void addChild(RecordInfo *I, EnumInfo &&R) {
512 I->ChildEnums.emplace_back(std::move(R));
513 }
514
addChild(RecordInfo * I,BaseRecordInfo && R)515 template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) {
516 I->Bases.emplace_back(std::move(R));
517 }
518
addChild(BaseRecordInfo * I,FunctionInfo && R)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>
readRecord(unsigned ID,T I)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 <>
readRecord(unsigned ID,Reference * I)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>
readBlock(unsigned ID,T I)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>
readSubBlock(unsigned ID,T I)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 }
604 case BI_MEMBER_TYPE_BLOCK_ID: {
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 }
627 case BI_BASE_RECORD_BLOCK_ID: {
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
skipUntilRecordOrBlock(unsigned & BlockOrRecordID)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
validateStream()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
readBlockInfoBlock()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>>
createInfo(unsigned ID)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>>
readBlockToInfo(unsigned ID)733 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
734 switch (ID) {
735 case BI_NAMESPACE_BLOCK_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);
741 case BI_FUNCTION_BLOCK_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>>>
readBitcode()751 ClangDocBitcodeReader::readBitcode() {
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:
771 case BI_FIELD_TYPE_BLOCK_ID:
772 case BI_MEMBER_TYPE_BLOCK_ID:
773 case BI_COMMENT_BLOCK_ID:
774 case BI_REFERENCE_BLOCK_ID:
775 return llvm::createStringError(llvm::inconvertibleErrorCode(),
776 "invalid top level block");
777 case BI_NAMESPACE_BLOCK_ID:
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
808