diff options
Diffstat (limited to 'clang-tools-extra/clang-doc/BitcodeReader.cpp')
-rw-r--r-- | clang-tools-extra/clang-doc/BitcodeReader.cpp | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index fa51d01355c..70e92c7a646 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -100,6 +100,8 @@ bool decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) { case FieldId::F_parent: case FieldId::F_vparent: case FieldId::F_type: + case FieldId::F_child_namespace: + case FieldId::F_child_record: case FieldId::F_default: Field = F; return true; @@ -372,6 +374,12 @@ template <> void addReference(NamespaceInfo *I, Reference &&R, FieldId F) { case FieldId::F_namespace: I->Namespace.emplace_back(std::move(R)); break; + case FieldId::F_child_namespace: + I->ChildNamespaces.emplace_back(std::move(R)); + break; + case FieldId::F_child_record: + I->ChildRecords.emplace_back(std::move(R)); + break; default: llvm::errs() << "Invalid field type for info.\n"; exit(1); @@ -403,12 +411,37 @@ template <> void addReference(RecordInfo *I, Reference &&R, FieldId F) { case FieldId::F_vparent: I->VirtualParents.emplace_back(std::move(R)); break; + case FieldId::F_child_record: + I->ChildRecords.emplace_back(std::move(R)); + break; default: llvm::errs() << "Invalid field type for info.\n"; exit(1); } } +template <typename T, typename ChildInfoType> +void addChild(T I, ChildInfoType &&R) { + llvm::errs() << "Invalid child type for info.\n"; + exit(1); +} + +template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) { + I->ChildFunctions.emplace_back(std::move(R)); +} + +template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { + I->ChildEnums.emplace_back(std::move(R)); +} + +template <> void addChild(RecordInfo *I, FunctionInfo &&R) { + I->ChildFunctions.emplace_back(std::move(R)); +} + +template <> void addChild(RecordInfo *I, EnumInfo &&R) { + I->ChildEnums.emplace_back(std::move(R)); +} + // Read records from bitcode into a given info. template <typename T> bool ClangDocBitcodeReader::readRecord(unsigned ID, T I) { Record R; @@ -455,7 +488,8 @@ template <typename T> bool ClangDocBitcodeReader::readBlock(unsigned ID, T I) { template <typename T> bool ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { switch (ID) { - // Blocks can only have Comment, Reference, or TypeInfo subblocks + // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or + // EnumInfo subblocks case BI_COMMENT_BLOCK_ID: if (readBlock(ID, getCommentInfo(I))) return true; @@ -492,6 +526,22 @@ bool ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { } return false; } + case BI_FUNCTION_BLOCK_ID: { + FunctionInfo F; + if (readBlock(ID, &F)) { + addChild(I, std::move(F)); + return true; + } + return false; + } + case BI_ENUM_BLOCK_ID: { + EnumInfo E; + if (readBlock(ID, &E)) { + addChild(I, std::move(E)); + return true; + } + return false; + } default: llvm::errs() << "Invalid subblock type.\n"; return false; @@ -573,16 +623,21 @@ std::unique_ptr<Info> ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { } // Entry point -std::vector<std::unique_ptr<Info>> ClangDocBitcodeReader::readBitcode() { +llvm::Expected<std::vector<std::unique_ptr<Info>>> +ClangDocBitcodeReader::readBitcode() { std::vector<std::unique_ptr<Info>> Infos; if (!validateStream()) - return Infos; + return llvm::make_error<llvm::StringError>("Invalid bitcode stream.\n", + llvm::inconvertibleErrorCode()); + ; // Read the top level blocks. while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); if (Code != llvm::bitc::ENTER_SUBBLOCK) - return Infos; + return llvm::make_error<llvm::StringError>( + "Missing subblock in bitcode.\n", llvm::inconvertibleErrorCode()); + ; unsigned ID = Stream.ReadSubBlockID(); switch (ID) { @@ -592,24 +647,30 @@ std::vector<std::unique_ptr<Info>> ClangDocBitcodeReader::readBitcode() { case BI_MEMBER_TYPE_BLOCK_ID: case BI_COMMENT_BLOCK_ID: case BI_REFERENCE_BLOCK_ID: - llvm::errs() << "Invalid top level block.\n"; - return Infos; + return llvm::make_error<llvm::StringError>( + "Invalid top level block in bitcode.\n", + llvm::inconvertibleErrorCode()); + ; case BI_NAMESPACE_BLOCK_ID: case BI_RECORD_BLOCK_ID: case BI_ENUM_BLOCK_ID: case BI_FUNCTION_BLOCK_ID: - if (std::unique_ptr<Info> I = readBlockToInfo(ID)) { + if (std::unique_ptr<Info> I = readBlockToInfo(ID)) Infos.emplace_back(std::move(I)); - } return Infos; case BI_VERSION_BLOCK_ID: if (readBlock(ID, VersionNumber)) continue; - return Infos; + return llvm::make_error<llvm::StringError>( + "Invalid bitcode version in bitcode.\n", + llvm::inconvertibleErrorCode()); + ; case llvm::bitc::BLOCKINFO_BLOCK_ID: if (readBlockInfoBlock()) continue; - return Infos; + return llvm::make_error<llvm::StringError>( + "Invalid BlockInfo in bitcode.\n", llvm::inconvertibleErrorCode()); + ; default: if (!Stream.SkipBlock()) continue; |