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" 18 using Record = llvm::SmallVector<uint64_t, 1024>;
21 llvm::StringRef Blob) {
22 Field.assign(Blob.begin(), Blob.end());
23 return llvm::Error::success();
28 return llvm::make_error<llvm::StringError>(
"Incorrect USR size.\n",
29 llvm::inconvertibleErrorCode());
33 for (
int I = 0, E = R[0]; I < E; ++I)
35 return llvm::Error::success();
40 return llvm::Error::success();
45 return llvm::make_error<llvm::StringError>(
"Integer too large to parse.\n",
46 llvm::inconvertibleErrorCode());
48 return llvm::Error::success();
52 llvm::StringRef Blob) {
58 Field = (AccessSpecifier)R[0];
59 return llvm::Error::success();
61 return llvm::make_error<llvm::StringError>(
62 "Invalid value for AccessSpecifier.\n", llvm::inconvertibleErrorCode());
73 Field = (TagTypeKind)R[0];
74 return llvm::Error::success();
76 return llvm::make_error<llvm::StringError>(
77 "Invalid value for TagTypeKind.\n", llvm::inconvertibleErrorCode());
82 llvm::StringRef Blob) {
84 return llvm::make_error<llvm::StringError>(
"Integer too large to parse.\n",
85 llvm::inconvertibleErrorCode());
86 Field.emplace((
int)R[0], Blob);
87 return llvm::Error::success();
91 switch (
auto IT = static_cast<InfoType>(R[0])) {
98 return llvm::Error::success();
100 return llvm::make_error<llvm::StringError>(
"Invalid value for InfoType.\n",
101 llvm::inconvertibleErrorCode());
105 switch (
auto F = static_cast<FieldId>(R[0])) {
114 return llvm::Error::success();
116 return llvm::make_error<llvm::StringError>(
"Invalid value for FieldId.\n",
117 llvm::inconvertibleErrorCode());
121 llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
122 llvm::StringRef Blob) {
123 Field.push_back(Blob);
124 return llvm::Error::success();
128 llvm::StringRef Blob) {
130 return llvm::make_error<llvm::StringError>(
"Integer too large to parse.\n",
131 llvm::inconvertibleErrorCode());
132 Field.emplace_back((
int)R[0], Blob);
133 return llvm::Error::success();
137 const unsigned VersionNo) {
138 if (ID ==
VERSION && R[0] == VersionNo)
139 return llvm::Error::success();
140 return llvm::make_error<llvm::StringError>(
141 "Mismatched bitcode version number.\n", llvm::inconvertibleErrorCode());
154 return llvm::make_error<llvm::StringError>(
155 "Invalid field for NamespaceInfo.\n", llvm::inconvertibleErrorCode());
177 return llvm::make_error<llvm::StringError>(
178 "Invalid field for RecordInfo.\n", llvm::inconvertibleErrorCode());
198 return llvm::make_error<llvm::StringError>(
"Invalid field for EnumInfo.\n",
199 llvm::inconvertibleErrorCode());
219 return llvm::make_error<llvm::StringError>(
220 "Invalid field for FunctionInfo.\n", llvm::inconvertibleErrorCode());
226 return llvm::Error::success();
235 return llvm::make_error<llvm::StringError>(
"Invalid field for TypeInfo.\n",
236 llvm::inconvertibleErrorCode());
248 return llvm::make_error<llvm::StringError>(
249 "Invalid field for MemberTypeInfo.\n", llvm::inconvertibleErrorCode());
279 return llvm::make_error<llvm::StringError>(
280 "Invalid field for CommentInfo.\n", llvm::inconvertibleErrorCode());
298 return llvm::make_error<llvm::StringError>(
"Invalid field for Reference.\n",
299 llvm::inconvertibleErrorCode());
304 return llvm::make_error<llvm::StringError>(
305 "Invalid type cannot contain CommentInfo.\n",
306 llvm::inconvertibleErrorCode());
330 I->
Children.emplace_back(llvm::make_unique<CommentInfo>());
339 template <
typename T,
typename TTypeInfo>
341 return llvm::make_error<llvm::StringError>(
342 "Invalid type cannot contain TypeInfo.\n",
343 llvm::inconvertibleErrorCode());
347 I->
Members.emplace_back(std::move(T));
348 return llvm::Error::success();
353 return llvm::Error::success();
357 I->
Params.emplace_back(std::move(T));
358 return llvm::Error::success();
362 return llvm::make_error<llvm::StringError>(
363 "Invalid type cannot contain Reference\n",
364 llvm::inconvertibleErrorCode());
370 I->
Type = std::move(R);
371 return llvm::Error::success();
373 return llvm::make_error<llvm::StringError>(
374 "Invalid type cannot contain Reference.\n",
375 llvm::inconvertibleErrorCode());
383 I->
Type = std::move(R);
384 return llvm::Error::success();
386 return llvm::make_error<llvm::StringError>(
387 "Invalid type cannot contain Reference.\n",
388 llvm::inconvertibleErrorCode());
396 I->
Type = std::move(R);
397 return llvm::Error::success();
399 return llvm::make_error<llvm::StringError>(
400 "Invalid type cannot contain Reference.\n",
401 llvm::inconvertibleErrorCode());
409 return llvm::Error::success();
411 return llvm::make_error<llvm::StringError>(
412 "Invalid type cannot contain Reference.\n",
413 llvm::inconvertibleErrorCode());
422 return llvm::Error::success();
425 return llvm::Error::success();
428 return llvm::Error::success();
430 return llvm::make_error<llvm::StringError>(
431 "Invalid type cannot contain Reference.\n",
432 llvm::inconvertibleErrorCode());
441 return llvm::Error::success();
444 return llvm::Error::success();
446 return llvm::make_error<llvm::StringError>(
447 "Invalid type cannot contain Reference.\n",
448 llvm::inconvertibleErrorCode());
456 return llvm::Error::success();
458 I->
Parents.emplace_back(std::move(R));
459 return llvm::Error::success();
462 return llvm::Error::success();
465 return llvm::Error::success();
467 return llvm::make_error<llvm::StringError>(
468 "Invalid type cannot contain Reference.\n",
469 llvm::inconvertibleErrorCode());
473 template <
typename T,
typename ChildInfoType>
475 llvm::errs() <<
"Invalid child type for info.\n";
496 template <
typename T>
497 llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID, T I) {
499 llvm::StringRef Blob;
500 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
502 return MaybeRecID.takeError();
507 llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID,
Reference *I) {
509 llvm::StringRef Blob;
510 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
512 return MaybeRecID.takeError();
513 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
517 template <
typename T>
518 llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID, T I) {
519 if (llvm::Error Err = Stream.EnterSubBlock(ID))
523 unsigned BlockOrCode = 0;
524 Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
527 case Cursor::BadBlock:
528 return llvm::make_error<llvm::StringError>(
529 "Bad block found.\n", llvm::inconvertibleErrorCode());
530 case Cursor::BlockEnd:
531 return llvm::Error::success();
532 case Cursor::BlockBegin:
533 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
534 if (llvm::Error Skipped = Stream.SkipBlock())
535 return joinErrors(std::move(Err), std::move(Skipped));
542 if (
auto Err = readRecord(BlockOrCode, I))
547 template <
typename T>
548 llvm::Error ClangDocBitcodeReader::readSubBlock(
unsigned ID, T I) {
555 return Comment.takeError();
556 if (
auto Err = readBlock(ID, Comment.get()))
558 return llvm::Error::success();
562 if (
auto Err = readBlock(ID, &TI))
566 return llvm::Error::success();
570 if (
auto Err = readBlock(ID, &TI))
574 return llvm::Error::success();
578 if (
auto Err = readBlock(ID, &TI))
582 return llvm::Error::success();
586 if (
auto Err = readBlock(ID, &R))
588 if (
auto Err =
addReference(I, std::move(R), CurrentReferenceField))
590 return llvm::Error::success();
594 if (
auto Err = readBlock(ID, &F))
597 return llvm::Error::success();
601 if (
auto Err = readBlock(ID, &E))
604 return llvm::Error::success();
607 return llvm::make_error<llvm::StringError>(
"Invalid subblock type.\n",
608 llvm::inconvertibleErrorCode());
612 ClangDocBitcodeReader::Cursor
613 ClangDocBitcodeReader::skipUntilRecordOrBlock(
unsigned &BlockOrRecordID) {
616 while (!Stream.AtEndOfStream()) {
617 Expected<unsigned> MaybeCode = Stream.ReadCode();
620 consumeError(MaybeCode.takeError());
621 return Cursor::BadBlock;
624 unsigned Code = MaybeCode.get();
625 if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
626 BlockOrRecordID = Code;
627 return Cursor::Record;
629 switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
630 case llvm::bitc::ENTER_SUBBLOCK:
631 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
632 BlockOrRecordID = MaybeID.get();
635 consumeError(MaybeID.takeError());
637 return Cursor::BlockBegin;
638 case llvm::bitc::END_BLOCK:
639 if (Stream.ReadBlockEnd())
640 return Cursor::BadBlock;
641 return Cursor::BlockEnd;
642 case llvm::bitc::DEFINE_ABBREV:
643 if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
645 consumeError(std::move(Err));
648 case llvm::bitc::UNABBREV_RECORD:
649 return Cursor::BadBlock;
650 case llvm::bitc::FIRST_APPLICATION_ABBREV:
651 llvm_unreachable(
"Unexpected abbrev id.");
654 llvm_unreachable(
"Premature stream end.");
657 llvm::Error ClangDocBitcodeReader::validateStream() {
658 if (Stream.AtEndOfStream())
659 return llvm::make_error<llvm::StringError>(
"Premature end of stream.\n",
660 llvm::inconvertibleErrorCode());
663 for (
int Idx = 0; Idx != 4; ++Idx) {
664 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
666 return MaybeRead.takeError();
668 return llvm::make_error<llvm::StringError>(
669 "Invalid bitcode signature.\n", llvm::inconvertibleErrorCode());
671 return llvm::Error::success();
674 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
675 Expected<Optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
676 Stream.ReadBlockInfoBlock();
678 return MaybeBlockInfo.takeError();
680 BlockInfo = MaybeBlockInfo.get();
682 return llvm::make_error<llvm::StringError>(
683 "Unable to parse BlockInfoBlock.\n", llvm::inconvertibleErrorCode());
684 Stream.setBlockInfo(&*BlockInfo);
685 return llvm::Error::success();
688 template <
typename T>
689 llvm::Expected<std::unique_ptr<Info>>
690 ClangDocBitcodeReader::createInfo(
unsigned ID) {
691 std::unique_ptr<Info> I = llvm::make_unique<T>();
692 if (
auto Err = readBlock(ID, static_cast<T *>(I.get())))
693 return std::move(Err);
694 return std::unique_ptr<Info>{std::move(I)};
697 llvm::Expected<std::unique_ptr<Info>>
698 ClangDocBitcodeReader::readBlockToInfo(
unsigned ID) {
701 return createInfo<NamespaceInfo>(ID);
703 return createInfo<RecordInfo>(ID);
705 return createInfo<EnumInfo>(ID);
707 return createInfo<FunctionInfo>(ID);
709 return llvm::make_error<llvm::StringError>(
"Cannot create info.\n",
710 llvm::inconvertibleErrorCode());
715 llvm::Expected<std::vector<std::unique_ptr<Info>>>
717 std::vector<std::unique_ptr<Info>> Infos;
718 if (
auto Err = validateStream())
719 return std::move(Err);
722 while (!Stream.AtEndOfStream()) {
723 Expected<unsigned> MaybeCode = Stream.ReadCode();
725 return MaybeCode.takeError();
726 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
727 return llvm::make_error<llvm::StringError>(
728 "No blocks in input.\n", llvm::inconvertibleErrorCode());
729 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
731 return MaybeID.takeError();
732 unsigned ID = MaybeID.get();
740 return llvm::make_error<llvm::StringError>(
741 "Invalid top level block.\n", llvm::inconvertibleErrorCode());
746 auto InfoOrErr = readBlockToInfo(ID);
748 return InfoOrErr.takeError();
749 Infos.emplace_back(std::move(InfoOrErr.get()));
754 return std::move(Err);
756 case llvm::bitc::BLOCKINFO_BLOCK_ID:
757 if (
auto Err = readBlockInfoBlock())
758 return std::move(Err);
761 if (llvm::Error Err = Stream.SkipBlock()) {
763 consumeError(std::move(Err));
768 return std::move(Infos);
llvm::SmallVector< Reference, 4 > Namespace
static const unsigned VersionNumber
llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
static constexpr unsigned char Signature[4]
llvm::SmallVector< uint64_t, 1024 > Record
llvm::Optional< Location > DefLoc
std::vector< FunctionInfo > ChildFunctions
llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
llvm::SmallVector< Location, 2 > Loc
std::vector< FunctionInfo > ChildFunctions
std::vector< EnumInfo > ChildEnums
std::vector< Reference > ChildRecords
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< FieldTypeInfo, 4 > Params
llvm::SmallVector< SmallString< 16 >, 4 > Members
std::vector< CommentInfo > Description
static constexpr int USRHashSize
llvm::Expected< std::vector< std::unique_ptr< Info > > > readBitcode()
llvm::SmallString< 128 > Path
llvm::SmallVector< Reference, 4 > Parents
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< Reference > ChildNamespaces
std::vector< Reference > ChildRecords
std::vector< EnumInfo > ChildEnums
llvm::Expected< CommentInfo * > getCommentInfo(T I)
llvm::SmallVector< MemberTypeInfo, 4 > Members
void addChild(T I, ChildInfoType &&R)
std::array< uint8_t, 20 > SymbolID
llvm::SmallString< 128 > Path
llvm::Error addReference(T I, Reference &&R, FieldId F)
llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)