[llvm-pdbdump] Add a compact dump mode.
Differential Revision: https://reviews.llvm.org/D28545
llvm-svn: 291849
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index 629ba40..f3508d6 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -9,7 +9,9 @@
#include "LLVMOutputStyle.h"
+#include "CompactTypeDumpVisitor.h"
#include "llvm-pdbdump.h"
+
#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
@@ -34,6 +36,7 @@
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Support/FormatVariadic.h"
#include <unordered_map>
@@ -524,22 +527,40 @@
if (!Tpi)
return Tpi.takeError();
- CVTypeDumper Dumper(TypeDB);
+ // Even if the user doesn't want to dump type records, we still need to
+ // iterate them in order to build the type database. So when they want to
+ // dump symbols but not types, don't stick a dumper on the end, just build
+ // the type database.
+ TypeDatabaseVisitor DBV(TypeDB);
+ CompactTypeDumpVisitor CTDV(TypeDB, &P);
+ TypeDumpVisitor TDV(TypeDB, &P, false);
+ TypeDeserializer Deserializer;
+ TypeVisitorCallbackPipeline Pipeline;
+ Pipeline.addCallbackToPipeline(Deserializer);
+ Pipeline.addCallbackToPipeline(DBV);
+
+ CVTypeVisitor Visitor(Pipeline);
+
if (DumpRecords || DumpRecordBytes) {
DictScope D(P, Label);
P.printNumber(VerLabel, Tpi->getTpiVersion());
P.printNumber("Record count", Tpi->NumTypeRecords());
-
ListScope L(P, "Records");
bool HadError = false;
- for (auto &Type : Tpi->types(&HadError)) {
- DictScope DD(P, "");
+ if (opts::raw::CompactRecords)
+ Pipeline.addCallbackToPipeline(CTDV);
+ else
+ Pipeline.addCallbackToPipeline(TDV);
+
+ for (auto Type : Tpi->types(&HadError)) {
+ std::unique_ptr<DictScope> Scope;
+ if (!opts::raw::CompactRecords)
+ Scope.reset(new DictScope(P, ""));
if (DumpRecords) {
- TypeDumpVisitor TDV(TypeDB, &P, false);
- if (auto EC = Dumper.dump(Type, TDV))
+ if (auto EC = Visitor.visitTypeRecord(Type))
return EC;
}
@@ -550,18 +571,16 @@
if (HadError)
return make_error<RawError>(raw_error_code::corrupt_file,
"TPI stream contained corrupt record");
- } else if (opts::raw::DumpModuleSyms) {
- // Even if the user doesn't want to dump type records, we still need to
- // iterate them in order to build the type database. So when they want to
- // dump symbols but not types, don't stick a dumper on the end, just build
- // the type database.
- TypeDatabaseVisitor DBV(TypeDB);
- TypeDeserializer Deserializer;
- TypeVisitorCallbackPipeline Pipeline;
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(DBV);
+ {
+ ListScope L(P, "TypeIndexOffsets");
+ for (const auto &IO : Tpi->getTypeIndexOffsets()) {
+ P.printString(formatv("Index: {0:x}, Offset: {1:N}", IO.Type.getIndex(),
+ (uint32_t)IO.Offset)
+ .str());
+ }
+ }
- CVTypeVisitor Visitor(Pipeline);
+ } else if (opts::raw::DumpModuleSyms) {
bool HadError = false;
for (auto Type : Tpi->types(&HadError)) {