clang-tools 8.0.0

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