summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-06-30 18:15:47 +0000
committerZachary Turner <zturner@google.com>2017-06-30 18:15:47 +0000
commit02a267758e0f2fb0b1475e8c68cdfae8411f2483 (patch)
treecfdeee091483b19acc22cd28420249c0ef5c4296
parent9dd7e808b31f2a5370802ce94305ca822679418f (diff)
downloadbcm5719-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
-rw-r--r--llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h2
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp19
-rw-r--r--llvm/test/tools/llvm-pdbdump/partial-type-stream.test30
-rw-r--r--llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp105
-rw-r--r--llvm/tools/llvm-pdbutil/DumpOutputStyle.h2
-rw-r--r--llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp2
-rw-r--r--llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp7
-rw-r--r--llvm/tools/llvm-pdbutil/llvm-pdbutil.h1
8 files changed, 142 insertions, 26 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h b/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
index c393b42cd27..afe8942159e 100644
--- a/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
+++ b/llvm/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
@@ -28,6 +28,8 @@ void discoverTypeIndices(ArrayRef<uint8_t> RecordData,
SmallVectorImpl<TiReference> &Refs);
void discoverTypeIndices(const CVType &Type,
SmallVectorImpl<TiReference> &Refs);
+void discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TypeIndex> &Indices);
/// Discover type indices in symbol records. Returns false if this is an unknown
/// record.
diff --git a/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
index 1226d5be3f3..72cb9e2e354 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
@@ -438,6 +438,25 @@ void llvm::codeview::discoverTypeIndices(const CVType &Type,
::discoverTypeIndices(Type.content(), Type.kind(), Refs);
}
+void llvm::codeview::discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TypeIndex> &Indices) {
+
+ Indices.clear();
+
+ SmallVector<TiReference, 4> Refs;
+ discoverTypeIndices(Type, Refs);
+ if (Refs.empty())
+ return;
+
+ BinaryStreamReader Reader(Type.content(), support::little);
+ for (const auto &Ref : Refs) {
+ Reader.setOffset(Ref.Offset);
+ FixedStreamArray<TypeIndex> Run;
+ cantFail(Reader.readArray(Run, Ref.Count));
+ Indices.append(Run.begin(), Run.end());
+ }
+}
+
void llvm::codeview::discoverTypeIndices(ArrayRef<uint8_t> RecordData,
SmallVectorImpl<TiReference> &Refs) {
const RecordPrefix *P =
diff --git a/llvm/test/tools/llvm-pdbdump/partial-type-stream.test b/llvm/test/tools/llvm-pdbdump/partial-type-stream.test
new file mode 100644
index 00000000000..3a853c39145
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbdump/partial-type-stream.test
@@ -0,0 +1,30 @@
+; RUN: llvm-pdbutil dump -type-index=0x1019 %p/Inputs/ClassLayoutTest.pdb \
+; RUN: | FileCheck --check-prefix=NODEPS %s
+; RUN: llvm-pdbutil dump -type-index=0x1019 -dependents %p/Inputs/ClassLayoutTest.pdb \
+; RUN: | FileCheck --check-prefix=DEPS %s
+
+
+NODEPS: Types (TPI Stream)
+NODEPS-NEXT: ============================================================
+NODEPS-NEXT: Showing 1 records.
+NODEPS-NEXT: 0x1019 | LF_MFUNCTION [size = 28]
+NODEPS-NEXT: return type = 0x0003 (void), # args = 0, param list = 0x100E
+NODEPS-NEXT: class type = 0x1017, this type = 0x1018, this adjust = 0
+NODEPS-NEXT: calling conv = thiscall, options = None
+
+
+DEPS: Types (TPI Stream)
+DEPS-NEXT: ============================================================
+DEPS-NEXT: Showing 1 records and their dependents (4 records total)
+DEPS-NEXT: 0x100E | LF_ARGLIST [size = 8]
+DEPS-NEXT: 0x1017 | LF_CLASS [size = 60]
+DEPS-NEXT: class name: `MembersTest::A`
+DEPS-NEXT: unique name: `.?AVA@MembersTest@@`
+DEPS-NEXT: vtable: <no type>, base list: <no type>, field list: <no type>
+DEPS-NEXT: options: forward ref | has unique name
+DEPS-NEXT: 0x1018 | LF_POINTER [size = 12]
+DEPS-NEXT: referent = 0x1017, mode = pointer, opts = const, kind = ptr32
+DEPS-NEXT: 0x1019 | LF_MFUNCTION [size = 28]
+DEPS-NEXT: return type = 0x0003 (void), # args = 0, param list = 0x100E
+DEPS-NEXT: class type = 0x1017, this type = 0x1018, this adjust = 0
+DEPS-NEXT: calling conv = thiscall, options = None
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);
}
}
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.h b/llvm/tools/llvm-pdbutil/DumpOutputStyle.h
index 296a6c14942..4c52289f052 100644
--- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.h
+++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.h
@@ -37,8 +37,6 @@ private:
Error dumpFileSummary();
Error dumpStreamSummary();
- Error dumpBlockRanges();
- Error dumpStreamBytes();
Error dumpStringTable();
Error dumpLines();
Error dumpInlineeLines();
diff --git a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
index 22d3a4557c5..1af53e35ed1 100644
--- a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
@@ -377,7 +377,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
MemberFunctionRecord &MF) {
P.formatLine("return type = {0}, # args = {1}, param list = {2}",
- MF.ParameterCount, MF.ArgumentList, MF.ReturnType);
+ MF.ReturnType, MF.ParameterCount, MF.ArgumentList);
P.formatLine("class type = {0}, this type = {1}, this adjust = {2}",
MF.ClassType, MF.ThisType, MF.ThisPointerAdjustment);
P.formatLine("calling conv = {0}, options = {1}",
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
index 4a176fb1359..ad11ad49800 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -419,6 +419,13 @@ cl::list<uint32_t> DumpIdIndex(
cl::desc("only dump ids with the specified hexadecimal type index"),
cl::cat(TypeOptions), cl::sub(DumpSubcommand));
+cl::opt<bool> DumpTypeDependents(
+ "dependents",
+ cl::desc("In conjunection with -type-index and -id-index, dumps the entire "
+ "dependency graph for the specified index instead of "
+ "just the single record with the specified index"),
+ cl::cat(TypeOptions), cl::sub(DumpSubcommand));
+
// SYMBOL OPTIONS
cl::opt<bool> DumpPublics("publics", cl::desc("dump Publics stream data"),
cl::cat(SymbolOptions), cl::sub(DumpSubcommand));
diff --git a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
index 837d8ebbaf9..9ee5866bbef 100644
--- a/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
+++ b/llvm/tools/llvm-pdbutil/llvm-pdbutil.h
@@ -135,6 +135,7 @@ extern llvm::cl::opt<bool> DumpTypes;
extern llvm::cl::opt<bool> DumpTypeData;
extern llvm::cl::opt<bool> DumpTypeExtras;
extern llvm::cl::list<uint32_t> DumpTypeIndex;
+extern llvm::cl::opt<bool> DumpTypeDependents;
extern llvm::cl::opt<bool> DumpIds;
extern llvm::cl::opt<bool> DumpIdData;
OpenPOWER on IntegriCloud