summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-pdbdump
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-05-18 23:03:06 +0000
committerZachary Turner <zturner@google.com>2017-05-18 23:03:06 +0000
commit0c60f269fcbb9b6ebba0897ed5fc9ea6ac271038 (patch)
tree73c17db87837f286a112f7415481ff60b45c94d9 /llvm/tools/llvm-pdbdump
parent86bf0a874c0b2cf56bd8c1493e98ef6c11a0ebd4 (diff)
downloadbcm5719-llvm-0c60f269fcbb9b6ebba0897ed5fc9ea6ac271038.tar.gz
bcm5719-llvm-0c60f269fcbb9b6ebba0897ed5fc9ea6ac271038.zip
[CodeView] Provide a common interface for type collections.
Right now we have multiple notions of things that represent collections of types. Most commonly used are TypeDatabase, which is supposed to keep mappings from TypeIndex to type name when reading a type stream, which happens when reading PDBs. And also TypeTableBuilder, which is used to build up a collection of types dynamically which we will later serialize (i.e. when writing PDBs). But often you just want to do some operation on a collection of types, and you may want to do the same operation on any kind of collection. For example, you might want to merge two TypeTableBuilders or you might want to merge two type streams that you loaded from various files. This dichotomy between reading and writing is responsible for a lot of the existing code duplication and overlapping responsibilities in the existing CodeView library classes. For example, after building up a TypeTableBuilder with a bunch of type records, if we want to dump it we have to re-invent a bunch of extra glue because our dumper takes a TypeDatabase or a CVTypeArray, which are both incompatible with TypeTableBuilder. This patch introduces an abstract base class called TypeCollection which is shared between the various type collection like things. Wherever we previously stored a TypeDatabase& in some common class, we now store a TypeCollection&. The advantage of this is that all the details of how the collection are implemented, such as lazy deserialization of partial type streams, is completely transparent and you can just treat any collection of types the same regardless of where it came from. Differential Revision: https://reviews.llvm.org/D33293 llvm-svn: 303388
Diffstat (limited to 'llvm/tools/llvm-pdbdump')
-rw-r--r--llvm/tools/llvm-pdbdump/Analyze.cpp1
-rw-r--r--llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp10
-rw-r--r--llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.h8
-rw-r--r--llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp120
-rw-r--r--llvm/tools/llvm-pdbdump/LLVMOutputStyle.h12
-rw-r--r--llvm/tools/llvm-pdbdump/PdbYaml.cpp2
-rw-r--r--llvm/tools/llvm-pdbdump/YAMLOutputStyle.h1
-rw-r--r--llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp1
8 files changed, 72 insertions, 83 deletions
diff --git a/llvm/tools/llvm-pdbdump/Analyze.cpp b/llvm/tools/llvm-pdbdump/Analyze.cpp
index ab4477ed7ba..3a026e5d245 100644
--- a/llvm/tools/llvm-pdbdump/Analyze.cpp
+++ b/llvm/tools/llvm-pdbdump/Analyze.cpp
@@ -14,7 +14,6 @@
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeDatabase.h"
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
diff --git a/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp b/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
index 5ad0bfad26c..3b609ae50c1 100644
--- a/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
+++ b/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.cpp
@@ -29,15 +29,15 @@ static StringRef getLeafName(TypeLeafKind K) {
return StringRef();
}
-CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB,
+CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types,
ScopedPrinter *W)
- : CompactTypeDumpVisitor(TypeDB, TypeIndex(TypeIndex::FirstNonSimpleIndex),
+ : CompactTypeDumpVisitor(Types, TypeIndex(TypeIndex::FirstNonSimpleIndex),
W) {}
-CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeDatabase &TypeDB,
+CompactTypeDumpVisitor::CompactTypeDumpVisitor(TypeCollection &Types,
TypeIndex FirstTI,
ScopedPrinter *W)
- : W(W), TI(FirstTI), Offset(0), TypeDB(TypeDB) {}
+ : W(W), TI(FirstTI), Offset(0), Types(Types) {}
Error CompactTypeDumpVisitor::visitTypeBegin(CVType &Record) {
return Error::success();
@@ -46,7 +46,7 @@ Error CompactTypeDumpVisitor::visitTypeBegin(CVType &Record) {
Error CompactTypeDumpVisitor::visitTypeEnd(CVType &Record) {
uint32_t I = TI.getIndex();
StringRef Leaf = getLeafName(Record.Type);
- StringRef Name = TypeDB.getTypeName(TI);
+ StringRef Name = Types.getTypeName(TI);
W->printString(
llvm::formatv("Index: {0:x} ({1:N} bytes, offset {2:N}) {3} \"{4}\"", I,
Record.length(), Offset, Leaf, Name)
diff --git a/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.h b/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
index 76fafc93e03..41ccea0c2e9 100644
--- a/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
+++ b/llvm/tools/llvm-pdbdump/CompactTypeDumpVisitor.h
@@ -17,7 +17,7 @@
namespace llvm {
class ScopedPrinter;
namespace codeview {
-class TypeDatabase;
+class TypeCollection;
}
namespace pdb {
@@ -26,8 +26,8 @@ namespace pdb {
/// Dumps records on a single line, and ignores member records.
class CompactTypeDumpVisitor : public codeview::TypeVisitorCallbacks {
public:
- CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB, ScopedPrinter *W);
- CompactTypeDumpVisitor(codeview::TypeDatabase &TypeDB,
+ CompactTypeDumpVisitor(codeview::TypeCollection &Types, ScopedPrinter *W);
+ CompactTypeDumpVisitor(codeview::TypeCollection &Types,
codeview::TypeIndex FirstTI, ScopedPrinter *W);
/// Paired begin/end actions for all types. Receives all record data,
@@ -40,7 +40,7 @@ private:
codeview::TypeIndex TI;
uint32_t Offset;
- codeview::TypeDatabase &TypeDB;
+ codeview::TypeCollection &Types;
};
} // end namespace pdb
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index c4fecb80ea5..4b94f8b7006 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -14,9 +14,9 @@
#include "StreamUtil.h"
#include "llvm-pdbdump.h"
-#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFileChecksumFragment.h"
#include "llvm/DebugInfo/CodeView/ModuleDebugFragmentVisitor.h"
@@ -25,7 +25,6 @@
#include "llvm/DebugInfo/CodeView/ModuleDebugUnknownFragment.h"
#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
#include "llvm/DebugInfo/CodeView/TypeDatabaseVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
@@ -84,7 +83,7 @@ struct PageStats {
class C13RawVisitor : public C13DebugFragmentVisitor {
public:
- C13RawVisitor(ScopedPrinter &P, PDBFile &F, TypeDatabase &IPI)
+ C13RawVisitor(ScopedPrinter &P, PDBFile &F, LazyRandomTypeCollection &IPI)
: C13DebugFragmentVisitor(F), P(P), IPI(IPI) {}
Error handleLines() override {
@@ -160,7 +159,7 @@ public:
if (auto EC = printFileName("FileName", L.Header->FileID))
return EC;
- if (auto EC = dumpTypeRecord("Function", IPI, L.Header->Inlinee))
+ if (auto EC = dumpTypeRecord("Function", L.Header->Inlinee))
return EC;
P.printNumber("SourceLine", L.Header->SourceLineNum);
if (IL.hasExtraFiles()) {
@@ -176,11 +175,11 @@ public:
}
private:
- Error dumpTypeRecord(StringRef Label, TypeDatabase &DB, TypeIndex Index) {
- CompactTypeDumpVisitor CTDV(DB, Index, &P);
+ Error dumpTypeRecord(StringRef Label, TypeIndex Index) {
+ CompactTypeDumpVisitor CTDV(IPI, Index, &P);
DictScope D(P, Label);
- if (DB.contains(Index)) {
- CVType &Type = DB.getTypeRecord(Index);
+ if (IPI.contains(Index)) {
+ CVType Type = IPI.getType(Index);
if (auto EC = codeview::visitTypeRecord(Type, CTDV))
return EC;
} else {
@@ -199,7 +198,7 @@ private:
}
ScopedPrinter &P;
- TypeDatabase &IPI;
+ LazyRandomTypeCollection &IPI;
};
}
@@ -609,14 +608,19 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
VerLabel = "IPI Version";
}
- if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash)
- return Error::success();
-
auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
: File.getPDBIpiStream();
if (!Tpi)
return Tpi.takeError();
+ auto ExpectedTypes = initializeTypeDatabase(StreamIdx);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &Types = *ExpectedTypes;
+
+ if (!DumpRecordBytes && !DumpRecords && !DumpTpiHash)
+ return Error::success();
+
std::unique_ptr<DictScope> StreamScope;
std::unique_ptr<ListScope> RecordScope;
@@ -624,25 +628,19 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
P.printNumber(VerLabel, Tpi->getTpiVersion());
P.printNumber("Record count", Tpi->getNumTypeRecords());
- Optional<TypeDatabase> &StreamDB = (StreamIdx == StreamTPI) ? TypeDB : ItemDB;
-
std::vector<std::unique_ptr<TypeVisitorCallbacks>> Visitors;
- if (!StreamDB.hasValue()) {
- StreamDB.emplace(Tpi->getNumTypeRecords());
- Visitors.push_back(make_unique<TypeDatabaseVisitor>(*StreamDB));
- }
// If we're in dump mode, add a dumper with the appropriate detail level.
if (DumpRecords) {
std::unique_ptr<TypeVisitorCallbacks> Dumper;
if (opts::raw::CompactRecords)
- Dumper = make_unique<CompactTypeDumpVisitor>(*StreamDB, &P);
+ Dumper = make_unique<CompactTypeDumpVisitor>(Types, &P);
else {
- assert(TypeDB.hasValue());
+ assert(TpiTypes);
- auto X = make_unique<TypeDumpVisitor>(*TypeDB, &P, false);
+ auto X = make_unique<TypeDumpVisitor>(*TpiTypes, &P, false);
if (StreamIdx == StreamIPI)
- X->setItemDB(*ItemDB);
+ X->setIpiTypes(*IpiTypes);
Dumper = std::move(X);
}
Visitors.push_back(std::move(Dumper));
@@ -660,23 +658,17 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
if (DumpRecords || DumpRecordBytes)
RecordScope = llvm::make_unique<ListScope>(P, "Records");
- bool HadError = false;
-
- TypeIndex T(TypeIndex::FirstNonSimpleIndex);
- for (auto Type : Tpi->types(&HadError)) {
+ Optional<TypeIndex> I = Types.getFirst();
+ do {
std::unique_ptr<DictScope> OneRecordScope;
if ((DumpRecords || DumpRecordBytes) && !opts::raw::CompactRecords)
OneRecordScope = llvm::make_unique<DictScope>(P, "");
- if (auto EC = codeview::visitTypeRecord(Type, Pipeline))
+ auto T = Types.getType(*I);
+ if (auto EC = codeview::visitTypeRecord(T, *I, Pipeline))
return EC;
-
- ++T;
- }
- if (HadError)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "TPI stream contained corrupt record");
+ } while (I = Types.getNext(*I));
if (DumpTpiHash) {
DictScope DD(P, "Hash");
@@ -711,35 +703,26 @@ Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
return Error::success();
}
-Error LLVMOutputStyle::buildTypeDatabase(uint32_t SN) {
- assert(SN == StreamIPI || SN == StreamTPI);
-
- auto &DB = (SN == StreamIPI) ? ItemDB : TypeDB;
-
- if (DB.hasValue())
- return Error::success();
-
+Expected<codeview::LazyRandomTypeCollection &>
+LLVMOutputStyle::initializeTypeDatabase(uint32_t SN) {
+ auto &TypeCollection = (SN == StreamTPI) ? TpiTypes : IpiTypes;
auto Tpi =
(SN == StreamTPI) ? File.getPDBTpiStream() : File.getPDBIpiStream();
-
if (!Tpi)
return Tpi.takeError();
- DB.emplace(Tpi->getNumTypeRecords());
-
- TypeDatabaseVisitor DBV(*DB);
-
- auto HashValues = Tpi->getHashValues();
- if (HashValues.empty())
- return codeview::visitTypeStream(Tpi->typeArray(), DBV);
-
- TypeVisitorCallbackPipeline Pipeline;
- Pipeline.addCallbackToPipeline(DBV);
-
- TpiHashVerifier HashVerifier(HashValues, Tpi->getNumHashBuckets());
- Pipeline.addCallbackToPipeline(HashVerifier);
+ if (!TypeCollection) {
+ // Initialize the type collection, even if we're not going to dump it. This
+ // way if some other part of the dumper decides it wants to use some or all
+ // of the records for whatever purposes, it can still access them lazily.
+ auto &Types = Tpi->typeArray();
+ uint32_t Count = Tpi->getNumTypeRecords();
+ auto Offsets = Tpi->getTypeIndexOffsets();
+ TypeCollection =
+ llvm::make_unique<LazyRandomTypeCollection>(Types, Count, Offsets);
+ }
- return codeview::visitTypeStream(Tpi->typeArray(), Pipeline);
+ return *TypeCollection;
}
Error LLVMOutputStyle::dumpDbiStream() {
@@ -814,11 +797,13 @@ Error LLVMOutputStyle::dumpDbiStream() {
return EC;
if (ShouldDumpSymbols) {
- if (auto EC = buildTypeDatabase(StreamTPI))
- return EC;
+ auto ExpectedTypes = initializeTypeDatabase(StreamTPI);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &Types = *ExpectedTypes;
ListScope SS(P, "Symbols");
- codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
+ codeview::CVSymbolDumper SD(P, Types, nullptr, false);
bool HadError = false;
for (auto S : ModS.symbols(&HadError)) {
DictScope LL(P, "");
@@ -839,10 +824,11 @@ Error LLVMOutputStyle::dumpDbiStream() {
}
if (opts::raw::DumpLineInfo) {
ListScope SS(P, "LineInfo");
- if (auto EC = buildTypeDatabase(StreamIPI))
- return EC;
-
- C13RawVisitor V(P, File, *ItemDB);
+ auto ExpectedTypes = initializeTypeDatabase(StreamIPI);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &IpiItems = *ExpectedTypes;
+ C13RawVisitor V(P, File, IpiItems);
if (auto EC = codeview::visitModuleDebugFragments(
ModS.linesAndChecksums(), V))
return EC;
@@ -960,10 +946,12 @@ Error LLVMOutputStyle::dumpPublicsStream() {
P.printList("Section Offsets", Publics->getSectionOffsets(),
printSectionOffset);
ListScope L(P, "Symbols");
- if (auto EC = buildTypeDatabase(StreamTPI))
- return EC;
+ auto ExpectedTypes = initializeTypeDatabase(StreamTPI);
+ if (!ExpectedTypes)
+ return ExpectedTypes.takeError();
+ auto &Tpi = *ExpectedTypes;
- codeview::CVSymbolDumper SD(P, *TypeDB, nullptr, false);
+ codeview::CVSymbolDumper SD(P, Tpi, nullptr, false);
bool HadError = false;
for (auto S : Publics->getSymbols(&HadError)) {
DictScope DD(P, "");
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h
index b0e7e3406b3..184dc4e1f44 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.h
@@ -21,6 +21,11 @@
namespace llvm {
class BitVector;
+
+namespace codeview {
+class LazyRandomTypeCollection;
+}
+
namespace pdb {
class LLVMOutputStyle : public OutputStyle {
public:
@@ -29,7 +34,8 @@ public:
Error dump() override;
private:
- Error buildTypeDatabase(uint32_t SN);
+ Expected<codeview::LazyRandomTypeCollection &>
+ initializeTypeDatabase(uint32_t SN);
Error dumpFileHeaders();
Error dumpStreamSummary();
@@ -54,8 +60,8 @@ private:
PDBFile &File;
ScopedPrinter P;
- Optional<codeview::TypeDatabase> TypeDB;
- Optional<codeview::TypeDatabase> ItemDB;
+ std::unique_ptr<codeview::LazyRandomTypeCollection> TpiTypes;
+ std::unique_ptr<codeview::LazyRandomTypeCollection> IpiTypes;
SmallVector<std::string, 32> StreamPurposes;
};
}
diff --git a/llvm/tools/llvm-pdbdump/PdbYaml.cpp b/llvm/tools/llvm-pdbdump/PdbYaml.cpp
index 6527bec31a7..dd32eca14c1 100644
--- a/llvm/tools/llvm-pdbdump/PdbYaml.cpp
+++ b/llvm/tools/llvm-pdbdump/PdbYaml.cpp
@@ -19,7 +19,6 @@
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -371,7 +370,6 @@ void MappingContextTraits<PdbInlineeInfo, SerializationContext>::mapping(
void MappingContextTraits<PdbTpiRecord, pdb::yaml::SerializationContext>::
mapping(IO &IO, pdb::yaml::PdbTpiRecord &Obj,
pdb::yaml::SerializationContext &Context) {
-
if (IO.outputting()) {
// For PDB to Yaml, deserialize into a high level record type, then dump it.
consumeError(codeview::visitTypeRecord(Obj.Record, Context.Dumper));
diff --git a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
index 517c7d86d7a..068312aec45 100644
--- a/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
+++ b/llvm/tools/llvm-pdbdump/YAMLOutputStyle.h
@@ -13,7 +13,6 @@
#include "OutputStyle.h"
#include "PdbYaml.h"
-#include "llvm/DebugInfo/CodeView/CVTypeDumper.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/YAMLTraits.h"
diff --git a/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp b/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp
index 3e447ca60b6..beb70072095 100644
--- a/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp
@@ -13,7 +13,6 @@
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeSerializer.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
OpenPOWER on IntegriCloud