[CodeView] Simplify the use of visiting type records & streams.
There is often a lot of boilerplate code required to visit a type
record or type stream. The #1 use case is that you have a sequence
of bytes that represent one or more records, and you want to
deserialize each one, switch on it, and call a callback with the
deserialized record that the user can examine. Currently this
requires at least 6 lines of code:
codeview::TypeVisitorCallbackPipeline Pipeline;
Pipeline.addCallbackToPipeline(Deserializer);
Pipeline.addCallbackToPipeline(MyCallbacks);
codeview::CVTypeVisitor Visitor(Pipeline);
consumeError(Visitor.visitTypeRecord(Record));
With this patch, it becomes one line of code:
consumeError(codeview::visitTypeRecord(Record, MyCallbacks));
This is done by having the deserialization happen internally inside
of the visitTypeRecord function. Since this is occasionally not
desirable, the function provides a 3rd parameter that can be used
to change this behavior.
Hopefully this can significantly reduce the barrier to entry
to using the visitation infrastructure.
Differential Revision: https://reviews.llvm.org/D33245
llvm-svn: 303271
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index e975a52..c4fecb8 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -178,11 +178,10 @@
private:
Error dumpTypeRecord(StringRef Label, TypeDatabase &DB, TypeIndex Index) {
CompactTypeDumpVisitor CTDV(DB, Index, &P);
- CVTypeVisitor Visitor(CTDV);
DictScope D(P, Label);
if (DB.contains(Index)) {
CVType &Type = DB.getTypeRecord(Index);
- if (auto EC = Visitor.visitTypeRecord(Type))
+ if (auto EC = codeview::visitTypeRecord(Type, CTDV))
return EC;
} else {
P.printString(
@@ -629,7 +628,6 @@
std::vector<std::unique_ptr<TypeVisitorCallbacks>> Visitors;
- Visitors.push_back(make_unique<TypeDeserializer>());
if (!StreamDB.hasValue()) {
StreamDB.emplace(Tpi->getNumTypeRecords());
Visitors.push_back(make_unique<TypeDatabaseVisitor>(*StreamDB));
@@ -659,8 +657,6 @@
for (const auto &V : Visitors)
Pipeline.addCallbackToPipeline(*V);
- CVTypeVisitor Visitor(Pipeline);
-
if (DumpRecords || DumpRecordBytes)
RecordScope = llvm::make_unique<ListScope>(P, "Records");
@@ -673,9 +669,10 @@
if ((DumpRecords || DumpRecordBytes) && !opts::raw::CompactRecords)
OneRecordScope = llvm::make_unique<DictScope>(P, "");
- if (auto EC = Visitor.visitTypeRecord(Type))
+ if (auto EC = codeview::visitTypeRecord(Type, Pipeline))
return EC;
- T.setIndex(T.getIndex() + 1);
+
+ ++T;
}
if (HadError)
return make_error<RawError>(raw_error_code::corrupt_file,
@@ -730,22 +727,19 @@
DB.emplace(Tpi->getNumTypeRecords());
- TypeVisitorCallbackPipeline Pipeline;
- TypeDeserializer Deserializer;
TypeDatabaseVisitor DBV(*DB);
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(DBV);
auto HashValues = Tpi->getHashValues();
- std::unique_ptr<TpiHashVerifier> HashVerifier;
- if (!HashValues.empty()) {
- HashVerifier =
- make_unique<TpiHashVerifier>(HashValues, Tpi->getNumHashBuckets());
- Pipeline.addCallbackToPipeline(*HashVerifier);
- }
+ if (HashValues.empty())
+ return codeview::visitTypeStream(Tpi->typeArray(), DBV);
- CVTypeVisitor Visitor(Pipeline);
- return Visitor.visitTypeStream(Tpi->types(nullptr));
+ TypeVisitorCallbackPipeline Pipeline;
+ Pipeline.addCallbackToPipeline(DBV);
+
+ TpiHashVerifier HashVerifier(HashValues, Tpi->getNumHashBuckets());
+ Pipeline.addCallbackToPipeline(HashVerifier);
+
+ return codeview::visitTypeStream(Tpi->typeArray(), Pipeline);
}
Error LLVMOutputStyle::dumpDbiStream() {