summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-doc/BitcodeReader.cpp
diff options
context:
space:
mode:
authorJulie Hockett <juliehockett@google.com>2018-08-02 20:10:17 +0000
committerJulie Hockett <juliehockett@google.com>2018-08-02 20:10:17 +0000
commit8899c29b1e0835f06972b03adab2e8fd91339c8d (patch)
tree51f122d564bd08a833ce38a9954852516b40f849 /clang-tools-extra/clang-doc/BitcodeReader.cpp
parent31da130e4dcce5a4fe72eb187db3e169cba4ec23 (diff)
Reland "[clang-doc] Refactoring mapper to map by scope"
Relanding with a minor change to prevent an assertion on release bots. The result of this adjusted mapper pass is that all Function and Enum infos are absorbed into the info of their enclosing scope (i.e. the class or namespace in which they are defined). Namespace and Record infos are passed along to the final output, but the second pass creates a reference to each in its parent scope. As a result, the top-level final outputs are Namespaces and Records. Differential Revision: https://reviews.llvm.org/D48341 llvm-svn: 338763
Diffstat (limited to 'clang-tools-extra/clang-doc/BitcodeReader.cpp')
-rw-r--r--clang-tools-extra/clang-doc/BitcodeReader.cpp85
1 files changed, 73 insertions, 12 deletions
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index fa51d01355ca..7acf107db07e 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,30 +647,36 @@ 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;
+ continue;
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;
}
}
- return Infos;
+ return std::move(Infos);
}
} // namespace doc