diff options
author | Zachary Turner <zturner@google.com> | 2017-06-30 18:15:47 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2017-06-30 18:15:47 +0000 |
commit | 02a267758e0f2fb0b1475e8c68cdfae8411f2483 (patch) | |
tree | cfdeee091483b19acc22cd28420249c0ef5c4296 /llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp | |
parent | 9dd7e808b31f2a5370802ce94305ca822679418f (diff) | |
download | bcm5719-llvm-02a267758e0f2fb0b1475e8c68cdfae8411f2483.tar.gz bcm5719-llvm-02a267758e0f2fb0b1475e8c68cdfae8411f2483.zip |
[llvm-pdbutil] Add the ability to dump the dependency tree for a type
Previously we had the -type-index option which would dump the record of
a single, but we had no way to follow the dependency graph backwards and
also dump all dependent types.
Having this option makes test-writing better, because we can limit the
test to only those records that are of importance for the thing we're
trying to test, which allows us to use things like CHECK-NEXT to reduce
fragility.
Differential Revision: https://reviews.llvm.org/D34899
llvm-svn: 306852
Diffstat (limited to 'llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp')
-rw-r--r-- | llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp | 105 |
1 files changed, 82 insertions, 23 deletions
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp index f76635f9e51..3a956c9f64f 100644 --- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp @@ -37,6 +37,7 @@ #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h" #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" +#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h" #include "llvm/DebugInfo/MSF/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" @@ -116,12 +117,14 @@ Error DumpOutputStyle::dump() { return EC; } - if (opts::dump::DumpTypes || opts::dump::DumpTypeExtras) { + if (opts::dump::DumpTypes || !opts::dump::DumpTypeIndex.empty() || + opts::dump::DumpTypeExtras) { if (auto EC = dumpTpiStream(StreamTPI)) return EC; } - if (opts::dump::DumpIds || opts::dump::DumpIdExtras) { + if (opts::dump::DumpIds || !opts::dump::DumpIdIndex.empty() || + opts::dump::DumpIdExtras) { if (auto EC = dumpTpiStream(StreamIPI)) return EC; } @@ -620,6 +623,76 @@ Error DumpOutputStyle::dumpStringTable() { return Error::success(); } +static void buildDepSet(LazyRandomTypeCollection &Types, + ArrayRef<TypeIndex> Indices, + std::map<TypeIndex, CVType> &DepSet) { + SmallVector<TypeIndex, 4> DepList; + for (const auto &I : Indices) { + TypeIndex TI(I); + if (DepSet.find(TI) != DepSet.end() || TI.isSimple() || TI.isNoneType()) + continue; + + CVType Type = Types.getType(TI); + DepSet[TI] = Type; + codeview::discoverTypeIndices(Type, DepList); + buildDepSet(Types, DepList, DepSet); + } +} + +static void dumpFullTypeStream(LinePrinter &Printer, + LazyRandomTypeCollection &Types, + TpiStream &Stream, bool Bytes, bool Extras) { + Printer.formatLine("Showing {0:N} records", Stream.getNumTypeRecords()); + uint32_t Width = + NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords()); + + MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types, + Stream.getHashValues()); + + if (auto EC = codeview::visitTypeStream(Types, V)) { + Printer.formatLine("An error occurred dumping type records: {0}", + toString(std::move(EC))); + } +} + +static void dumpPartialTypeStream(LinePrinter &Printer, + LazyRandomTypeCollection &Types, + TpiStream &Stream, ArrayRef<TypeIndex> TiList, + bool Bytes, bool Extras, bool Deps) { + uint32_t Width = + NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords()); + + MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types, + Stream.getHashValues()); + + if (opts::dump::DumpTypeDependents) { + // If we need to dump all dependents, then iterate each index and find + // all dependents, adding them to a map ordered by TypeIndex. + std::map<TypeIndex, CVType> DepSet; + buildDepSet(Types, TiList, DepSet); + + Printer.formatLine( + "Showing {0:N} records and their dependents ({1:N} records total)", + TiList.size(), DepSet.size()); + + for (auto &Dep : DepSet) { + if (auto EC = codeview::visitTypeRecord(Dep.second, Dep.first, V)) + Printer.formatLine("An error occurred dumping type record {0}: {1}", + Dep.first, toString(std::move(EC))); + } + } else { + Printer.formatLine("Showing {0:N} records.", TiList.size()); + + for (const auto &I : TiList) { + TypeIndex TI(I); + CVType Type = Types.getType(TI); + if (auto EC = codeview::visitTypeRecord(Type, TI, V)) + Printer.formatLine("An error occurred dumping type record {0}: {1}", TI, + toString(std::move(EC))); + } + } +} + Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) { assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI); @@ -659,27 +732,13 @@ Error DumpOutputStyle::dumpTpiStream(uint32_t StreamIdx) { auto &Types = Err(initializeTypes(StreamIdx)); - if (DumpTypes) { - P.formatLine("Showing {0:N} records", Stream.getNumTypeRecords()); - uint32_t Width = - NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords()); - - MinimalTypeDumpVisitor V(P, Width + 2, DumpBytes, DumpExtras, Types, - Stream.getHashValues()); - - if (Indices.empty()) { - if (auto EC = codeview::visitTypeStream(Types, V)) { - P.formatLine("An error occurred dumping type records: {0}", - toString(std::move(EC))); - } - } else { - for (const auto &I : Indices) { - TypeIndex TI(I); - CVType Type = Types.getType(TI); - if (auto EC = codeview::visitTypeRecord(Type, TI, V)) - P.formatLine("An error occurred dumping type record {0}: {1}", TI, - toString(std::move(EC))); - } + if (DumpTypes || !Indices.empty()) { + if (Indices.empty()) + dumpFullTypeStream(P, Types, Stream, DumpBytes, DumpExtras); + else { + std::vector<TypeIndex> TiList(Indices.begin(), Indices.end()); + dumpPartialTypeStream(P, Types, Stream, TiList, DumpBytes, DumpExtras, + opts::dump::DumpTypeDependents); } } |