[llvm] r306852 - [llvm-pdbutil] Add the ability to dump the dependency tree for a type

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 30 11:15:47 PDT 2017


Author: zturner
Date: Fri Jun 30 11:15:47 2017
New Revision: 306852

URL: http://llvm.org/viewvc/llvm-project?rev=306852&view=rev
Log:
[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

Added:
    llvm/trunk/test/tools/llvm-pdbdump/partial-type-stream.test
Modified:
    llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
    llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
    llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h
    llvm/trunk/tools/llvm-pdbutil/MinimalTypeDumper.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h

Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h?rev=306852&r1=306851&r2=306852&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndexDiscovery.h Fri Jun 30 11:15:47 2017
@@ -28,6 +28,8 @@ void discoverTypeIndices(ArrayRef<uint8_
                          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.

Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp?rev=306852&r1=306851&r2=306852&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp Fri Jun 30 11:15:47 2017
@@ -438,6 +438,25 @@ void llvm::codeview::discoverTypeIndices
   ::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 =

Added: llvm/trunk/test/tools/llvm-pdbdump/partial-type-stream.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/partial-type-stream.test?rev=306852&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/partial-type-stream.test (added)
+++ llvm/trunk/test/tools/llvm-pdbdump/partial-type-stream.test Fri Jun 30 11:15:47 2017
@@ -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 at 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

Modified: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp?rev=306852&r1=306851&r2=306852&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp Fri Jun 30 11:15:47 2017
@@ -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(uin
 
   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);
     }
   }
 

Modified: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h?rev=306852&r1=306851&r2=306852&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.h Fri Jun 30 11:15:47 2017
@@ -37,8 +37,6 @@ private:
 
   Error dumpFileSummary();
   Error dumpStreamSummary();
-  Error dumpBlockRanges();
-  Error dumpStreamBytes();
   Error dumpStringTable();
   Error dumpLines();
   Error dumpInlineeLines();

Modified: llvm/trunk/tools/llvm-pdbutil/MinimalTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/MinimalTypeDumper.cpp?rev=306852&r1=306851&r2=306852&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/MinimalTypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/MinimalTypeDumper.cpp Fri Jun 30 11:15:47 2017
@@ -377,7 +377,7 @@ Error MinimalTypeDumpVisitor::visitKnown
 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}",

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=306852&r1=306851&r2=306852&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Fri Jun 30 11:15:47 2017
@@ -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));

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h?rev=306852&r1=306851&r2=306852&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Fri Jun 30 11:15:47 2017
@@ -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;




More information about the llvm-commits mailing list