summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-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