clang-tools 10.0.0

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) {
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
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])) {
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
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
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);
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
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);
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
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);
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
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) {
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 <>
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 <>
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
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>
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 }
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
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) {
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>>>
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
clang::doc::VERSION
Definition: BitcodeWriter.h:72
clang::doc::Info::Namespace
llvm::SmallVector< Reference, 4 > Namespace
Definition: Representation.h:255
Code
std::string Code
Definition: FindTargetTests.cpp:67
clang::doc::InfoType::IT_default
clang::doc::COMMENT_NAME
Definition: BitcodeWriter.h:81
clang::doc::COMMENT_ATTRVAL
Definition: BitcodeWriter.h:88
clang::doc::BaseRecordInfo::Access
AccessSpecifier Access
Definition: Representation.h:372
clang::doc::RecordInfo::Bases
std::vector< BaseRecordInfo > Bases
Definition: Representation.h:350
clang::doc::REFERENCE_USR
Definition: BitcodeWriter.h:116
clang::doc::COMMENT_CLOSENAME
Definition: BitcodeWriter.h:84
clang::doc::BI_MEMBER_TYPE_BLOCK_ID
Definition: BitcodeWriter.h:59
clang::doc::FieldId::F_child_namespace
clang::doc::FUNCTION_IS_METHOD
Definition: BitcodeWriter.h:78
clang::doc::ENUM_LOCATION
Definition: BitcodeWriter.h:99
clang::doc::VersionNumber
static const unsigned VersionNumber
Definition: BitcodeWriter.h:33
clang::doc::addTypeInfo
llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
Definition: BitcodeReader.cpp:364
clang::doc::InfoType::IT_function
clang::doc::FUNCTION_USR
Definition: BitcodeWriter.h:73
clang::doc::BaseRecordInfo::IsParent
bool IsParent
Definition: Representation.h:373
clang::doc::Reference
Definition: Representation.h:115
clang::doc::BASE_RECORD_ACCESS
Definition: BitcodeWriter.h:114
clang::doc::NAMESPACE_NAME
Definition: BitcodeWriter.h:94
clang::doc::BitCodeConstants::Signature
static constexpr unsigned char Signature[4]
Definition: BitcodeWriter.h:47
clang::doc::Record
llvm::SmallVector< uint64_t, 1024 > Record
Definition: BitcodeReader.cpp:18
clang::doc::TypeInfo::Type
Reference Type
Definition: Representation.h:163
clang::doc::RecordInfo::IsTypeDef
bool IsTypeDef
Definition: Representation.h:340
clang::doc::Reference::Name
SmallString< 16 > Name
Definition: Representation.h:139
clang::doc::SymbolInfo::DefLoc
llvm::Optional< Location > DefLoc
Definition: Representation.h:301
clang::doc::FIELD_TYPE_NAME
Definition: BitcodeWriter.h:90
clang::doc::ENUM_DEFLOCATION
Definition: BitcodeWriter.h:98
clang::doc::RecordInfo::ChildFunctions
std::vector< FunctionInfo > ChildFunctions
Definition: Representation.h:357
clang::doc::FunctionInfo::Parent
Reference Parent
Definition: Representation.h:314
clang::doc::parseRecord
llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
Definition: BitcodeReader.cpp:136
clang::doc::InfoType::IT_enum
clang::doc::InfoType::IT_record
clang::doc::InfoType::IT_namespace
clang::doc::SymbolInfo::Loc
llvm::SmallVector< Location, 2 > Loc
Definition: Representation.h:302
clang::doc::REFERENCE_PATH
Definition: BitcodeWriter.h:119
clang::doc::REFERENCE_FIELD
Definition: BitcodeWriter.h:121
clang::doc::REFERENCE_NAME
Definition: BitcodeWriter.h:117
BitcodeReader.h
clang::doc::MEMBER_TYPE_NAME
Definition: BitcodeWriter.h:91
clang::doc::ENUM_NAME
Definition: BitcodeWriter.h:97
clang::doc::COMMENT_TEXT
Definition: BitcodeWriter.h:80
clang::doc::NamespaceInfo::ChildFunctions
std::vector< FunctionInfo > ChildFunctions
Definition: Representation.h:287
clang::doc::RECORD_TAG_TYPE
Definition: BitcodeWriter.h:107
clang::doc::FUNCTION_ACCESS
Definition: BitcodeWriter.h:77
clang::doc::NamespaceInfo::ChildEnums
std::vector< EnumInfo > ChildEnums
Definition: Representation.h:288
clang::doc::EnumInfo::Scoped
bool Scoped
Definition: Representation.h:384
clang::doc::NAMESPACE_PATH
Definition: BitcodeWriter.h:95
clang::doc::RecordInfo::ChildRecords
std::vector< Reference > ChildRecords
Definition: Representation.h:356
clang::doc::BI_RECORD_BLOCK_ID
Definition: BitcodeWriter.h:60
clang::doc::FieldId
FieldId
Definition: BitcodeWriter.h:130
clang::doc::RECORD_DEFLOCATION
Definition: BitcodeWriter.h:105
clang::doc::RecordInfo::VirtualParents
llvm::SmallVector< Reference, 4 > VirtualParents
Definition: Representation.h:347
clang::doc::RECORD_PATH
Definition: BitcodeWriter.h:104
clang::doc::BaseRecordInfo::IsVirtual
bool IsVirtual
Definition: Representation.h:369
clang::doc::FunctionInfo
Definition: Representation.h:307
clang::doc::CommentInfo::SelfClosing
bool SelfClosing
Definition: Representation.h:102
clang::doc::FunctionInfo::Params
llvm::SmallVector< FieldTypeInfo, 4 > Params
Definition: Representation.h:316
clang::doc::BaseRecordInfo
Definition: Representation.h:361
clang::doc::RECORD_IS_TYPE_DEF
Definition: BitcodeWriter.h:108
clang::doc::Reference::USR
SymbolID USR
Definition: Representation.h:138
clang::doc::RECORD_NAME
Definition: BitcodeWriter.h:103
clang::doc::Reference::RefType
InfoType RefType
Definition: Representation.h:140
clang::doc::EnumInfo::Members
llvm::SmallVector< SmallString< 16 >, 4 > Members
Definition: Representation.h:386
clang::doc::FieldId::F_parent
clang::doc::CommentInfo::AttrValues
llvm::SmallVector< SmallString< 16 >, 4 > AttrValues
Definition: Representation.h:108
clang::doc::BI_BASE_RECORD_BLOCK_ID
Definition: BitcodeWriter.h:61
clang::doc::COMMENT_PARAMNAME
Definition: BitcodeWriter.h:83
clang::doc::BI_ENUM_BLOCK_ID
Definition: BitcodeWriter.h:56
clang::doc::BASE_RECORD_IS_VIRTUAL
Definition: BitcodeWriter.h:113
clang::doc::BASE_RECORD_TAG_TYPE
Definition: BitcodeWriter.h:112
clang::doc::COMMENT_ATTRKEY
Definition: BitcodeWriter.h:87
clang::doc::Info::Description
std::vector< CommentInfo > Description
Definition: Representation.h:256
clang::doc::NamespaceInfo
Definition: Representation.h:271
clang::doc::BI_VERSION_BLOCK_ID
Definition: BitcodeWriter.h:54
clang::doc::InfoType
InfoType
Definition: Representation.h:37
clang::doc::FieldId::F_default
clang::doc::BASE_RECORD_IS_PARENT
Definition: BitcodeWriter.h:115
clang::doc::ENUM_USR
Definition: BitcodeWriter.h:96
clang::doc::RecordInfo
Definition: Representation.h:327
clang::doc::MemberTypeInfo::Access
AccessSpecifier Access
Definition: Representation.h:206
clang::doc::CommentInfo::Args
llvm::SmallVector< SmallString< 16 >, 4 > Args
Definition: Representation.h:110
clang::doc::BI_REFERENCE_BLOCK_ID
Definition: BitcodeWriter.h:64
clang::doc::BitCodeConstants::USRHashSize
static constexpr int USRHashSize
Definition: BitcodeWriter.h:48
clang::doc::BI_COMMENT_BLOCK_ID
Definition: BitcodeWriter.h:63
clang::doc::Info::Name
SmallString< 16 > Name
Definition: Representation.h:253
clang::doc::ClangDocBitcodeReader::readBitcode
llvm::Expected< std::vector< std::unique_ptr< Info > > > readBitcode()
Definition: BitcodeReader.cpp:751
clang::doc::FUNCTION_DEFLOCATION
Definition: BitcodeWriter.h:75
clang::doc::CommentInfo::Explicit
bool Explicit
Definition: Representation.h:103
clang::doc::COMMENT_DIRECTION
Definition: BitcodeWriter.h:82
clang::doc::FunctionInfo::Access
AccessSpecifier Access
Definition: Representation.h:321
clang::doc::Info::Path
llvm::SmallString< 128 > Path
Definition: Representation.h:257
clang::doc::COMMENT_ARG
Definition: BitcodeWriter.h:89
clang::doc::BI_FIELD_TYPE_BLOCK_ID
Definition: BitcodeWriter.h:58
clang::doc::RecordInfo::Parents
llvm::SmallVector< Reference, 4 > Parents
Definition: Representation.h:343
clang::doc::BI_TYPE_BLOCK_ID
Definition: BitcodeWriter.h:57
clang::doc::Reference::IsInGlobalNamespace
bool IsInGlobalNamespace
Definition: Representation.h:148
clang::doc::MEMBER_TYPE_ACCESS
Definition: BitcodeWriter.h:92
clang::doc::FUNCTION_NAME
Definition: BitcodeWriter.h:74
clang::doc::CommentInfo::ParamName
SmallString< 16 > ParamName
Definition: Representation.h:100
clang::doc::FieldId::F_type
clang::doc::COMMENT_EXPLICIT
Definition: BitcodeWriter.h:86
clang::doc::RECORD_LOCATION
Definition: BitcodeWriter.h:106
clang::doc::RecordInfo::TagType
TagTypeKind TagType
Definition: Representation.h:337
clang::doc::EnumInfo
Definition: Representation.h:378
clang::doc::BASE_RECORD_NAME
Definition: BitcodeWriter.h:110
clang::doc::CommentInfo::AttrKeys
llvm::SmallVector< SmallString< 16 >, 4 > AttrKeys
Definition: Representation.h:106
clang::doc::REFERENCE_IS_IN_GLOBAL_NAMESPACE
Definition: BitcodeWriter.h:120
clang::doc::CommentInfo::Name
SmallString< 16 > Name
Definition: Representation.h:98
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::doc::FieldTypeInfo::Name
SmallString< 16 > Name
Definition: Representation.h:181
clang::doc::BI_NAMESPACE_BLOCK_ID
Definition: BitcodeWriter.h:55
clang::doc::BASE_RECORD_PATH
Definition: BitcodeWriter.h:111
clang::doc::NAMESPACE_USR
Definition: BitcodeWriter.h:93
clang::doc::TypeInfo
Definition: Representation.h:152
clang::doc::MemberTypeInfo
Definition: Representation.h:185
clang::doc::NamespaceInfo::ChildNamespaces
std::vector< Reference > ChildNamespaces
Definition: Representation.h:285
clang::doc::CommentInfo::CloseName
SmallString< 16 > CloseName
Definition: Representation.h:101
clang::doc::BI_FUNCTION_BLOCK_ID
Definition: BitcodeWriter.h:62
clang::doc::NamespaceInfo::ChildRecords
std::vector< Reference > ChildRecords
Definition: Representation.h:286
clang::doc::COMMENT_KIND
Definition: BitcodeWriter.h:79
clang::doc::REFERENCE_TYPE
Definition: BitcodeWriter.h:118
clang::doc::CommentInfo::Direction
SmallString< 8 > Direction
Definition: Representation.h:99
clang::doc::FUNCTION_LOCATION
Definition: BitcodeWriter.h:76
clang::doc::RecordInfo::ChildEnums
std::vector< EnumInfo > ChildEnums
Definition: Representation.h:358
clang::doc::FieldId::F_namespace
clang::doc::FunctionInfo::ReturnType
TypeInfo ReturnType
Definition: Representation.h:315
clang::doc::ENUM_SCOPED
Definition: BitcodeWriter.h:101
E
const Expr * E
Definition: AvoidBindCheck.cpp:82
clang::doc::FieldTypeInfo
Definition: Representation.h:167
clang::doc::getCommentInfo
llvm::Expected< CommentInfo * > getCommentInfo(T I)
Definition: BitcodeReader.cpp:328
clang::doc::RECORD_USR
Definition: BitcodeWriter.h:102
clang::doc::RecordInfo::Members
llvm::SmallVector< MemberTypeInfo, 4 > Members
Definition: Representation.h:342
clang::doc::Info::USR
SymbolID USR
Definition: Representation.h:250
clang::doc::CommentInfo::Kind
SmallString< 16 > Kind
Definition: Representation.h:92
clang::doc::addChild
void addChild(T I, ChildInfoType &&R)
Definition: BitcodeReader.cpp:494
clang::doc::CommentInfo::Children
std::vector< std::unique_ptr< CommentInfo > > Children
Definition: Representation.h:112
clang::doc::CommentInfo::Text
SmallString< 64 > Text
Definition: Representation.h:97
clang::doc::FieldId::F_vparent
clang::doc::SymbolID
std::array< uint8_t, 20 > SymbolID
Definition: Representation.h:30
clang::doc::FunctionInfo::IsMethod
bool IsMethod
Definition: Representation.h:313
clang::doc::ENUM_MEMBER
Definition: BitcodeWriter.h:100
clang::doc::Reference::Path
llvm::SmallString< 128 > Path
Definition: Representation.h:145
clang::doc::BASE_RECORD_USR
Definition: BitcodeWriter.h:109
clang::doc::FieldId::F_child_record
clang::doc::addReference
llvm::Error addReference(T I, Reference &&R, FieldId F)
Definition: BitcodeReader.cpp:389
clang::doc::CommentInfo
Definition: Representation.h:46
clang::doc::COMMENT_SELFCLOSING
Definition: BitcodeWriter.h:85
clang::doc::decodeRecord
llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)
Definition: BitcodeReader.cpp:20