summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-pdbdump
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-04-13 21:11:00 +0000
committerZachary Turner <zturner@google.com>2017-04-13 21:11:00 +0000
commit4dc4f01a86569977ad6fc2a0bb605731055f0a92 (patch)
tree86e89154bab5ec96eaa55ad9d395c46f6612640c /llvm/tools/llvm-pdbdump
parent60f54ac8c5d46fb73d23fe45ae326d492474e57c (diff)
downloadbcm5719-llvm-4dc4f01a86569977ad6fc2a0bb605731055f0a92.tar.gz
bcm5719-llvm-4dc4f01a86569977ad6fc2a0bb605731055f0a92.zip
[llvm-pdbdump] Recursively dump class layout.
llvm-svn: 300258
Diffstat (limited to 'llvm/tools/llvm-pdbdump')
-rw-r--r--llvm/tools/llvm-pdbdump/LinePrinter.cpp17
-rw-r--r--llvm/tools/llvm-pdbdump/LinePrinter.h5
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp44
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h3
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp135
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h21
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp8
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp124
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyTypeDumper.h4
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp20
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyVariableDumper.h4
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp26
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.h5
13 files changed, 335 insertions, 81 deletions
diff --git a/llvm/tools/llvm-pdbdump/LinePrinter.cpp b/llvm/tools/llvm-pdbdump/LinePrinter.cpp
index e5dd66fd9aa..d4a5a8d859e 100644
--- a/llvm/tools/llvm-pdbdump/LinePrinter.cpp
+++ b/llvm/tools/llvm-pdbdump/LinePrinter.cpp
@@ -12,6 +12,7 @@
#include "llvm-pdbdump.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
#include "llvm/Support/Regex.h"
#include <algorithm>
@@ -70,8 +71,20 @@ void LinePrinter::NewLine() {
OS.indent(CurrentIndent);
}
-bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName) {
- return IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters);
+bool LinePrinter::IsClassExcluded(const ClassLayout &Class) {
+ if (IsTypeExcluded(Class.getUDTName(), Class.getClassSize()))
+ return true;
+ if (Class.deepPaddingSize() < opts::pretty::PaddingThreshold)
+ return true;
+ return false;
+}
+
+bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size) {
+ if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters))
+ return true;
+ if (Size < opts::pretty::SizeThreshold)
+ return true;
+ return false;
}
bool LinePrinter::IsSymbolExcluded(llvm::StringRef SymbolName) {
diff --git a/llvm/tools/llvm-pdbdump/LinePrinter.h b/llvm/tools/llvm-pdbdump/LinePrinter.h
index 8b3d8755ad8..1a922feb1e6 100644
--- a/llvm/tools/llvm-pdbdump/LinePrinter.h
+++ b/llvm/tools/llvm-pdbdump/LinePrinter.h
@@ -20,6 +20,8 @@
namespace llvm {
namespace pdb {
+class ClassLayout;
+
class LinePrinter {
friend class WithColor;
@@ -34,7 +36,8 @@ public:
raw_ostream &getStream() { return OS; }
int getIndentLevel() const { return CurrentIndent; }
- bool IsTypeExcluded(llvm::StringRef TypeName);
+ bool IsClassExcluded(const ClassLayout &Class);
+ bool IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size);
bool IsSymbolExcluded(llvm::StringRef SymbolName);
bool IsCompilandExcluded(llvm::StringRef CompilandName);
diff --git a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
index ba829e794ea..9f213a4b4d9 100644
--- a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
@@ -33,15 +33,15 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
opts::pretty::ClassDefinitionFormat::None);
ClassLayout Layout(Class);
+ start(Layout);
+}
- if (opts::pretty::OnlyPaddingClasses && (Layout.shallowPaddingSize() == 0))
- return;
-
+void ClassDefinitionDumper::start(const ClassLayout &Layout) {
prettyPrintClassIntro(Layout);
switch (opts::pretty::ClassFormat) {
case opts::pretty::ClassDefinitionFormat::Graphical: {
- PrettyClassLayoutGraphicalDumper Dumper(Printer);
+ PrettyClassLayoutGraphicalDumper Dumper(Printer, 0);
DumpedAnything = Dumper.start(Layout);
break;
}
@@ -58,6 +58,20 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
prettyPrintClassOutro(Layout);
}
+static void printBase(LinePrinter &Printer, const PDBSymbolTypeBaseClass &Base,
+ uint32_t &CurIndex, uint32_t TotalBaseCount,
+ bool IsVirtual) {
+ Printer << " ";
+ WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess();
+ if (IsVirtual)
+ WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";
+ WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName();
+ if (++CurIndex < TotalBaseCount) {
+ Printer.NewLine();
+ Printer << ",";
+ }
+}
+
void ClassDefinitionDumper::prettyPrintClassIntro(const ClassLayout &Layout) {
DumpedAnything = false;
Printer.NewLine();
@@ -69,24 +83,22 @@ void ClassDefinitionDumper::prettyPrintClassIntro(const ClassLayout &Layout) {
WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size
<< "]";
- uint32_t BaseCount = Layout.base_classes().size();
- if (BaseCount > 0) {
+ uint32_t BaseCount = Layout.bases().size();
+ uint32_t VBaseCount = Layout.vbases().size();
+ uint32_t TotalBaseCount = BaseCount + VBaseCount;
+ if (TotalBaseCount > 0) {
Printer.Indent();
Printer.NewLine();
Printer << ":";
uint32_t BaseIndex = 0;
- for (auto BC : Layout.base_classes()) {
+ for (auto BC : Layout.bases()) {
const auto &Base = BC->getBase();
- Printer << " ";
- WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess();
- if (Base.isVirtualBaseClass())
- WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";
- WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName();
- if (++BaseIndex < BaseCount) {
- Printer.NewLine();
- Printer << ",";
- }
+ printBase(Printer, Base, BaseIndex, TotalBaseCount, false);
}
+ for (auto &BC : Layout.vbases()) {
+ printBase(Printer, *BC, BaseIndex, TotalBaseCount, true);
+ }
+
Printer.Unindent();
}
diff --git a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
index 6b24c7c8398..0e27733b3cc 100644
--- a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
+++ b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
@@ -32,7 +32,8 @@ class ClassDefinitionDumper : public PDBSymDumper {
public:
ClassDefinitionDumper(LinePrinter &P);
- void start(const PDBSymbolTypeUDT &Exe);
+ void start(const PDBSymbolTypeUDT &Class);
+ void start(const ClassLayout &Class);
private:
void prettyPrintClassIntro(const ClassLayout &Class);
diff --git a/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
index 13368934ed8..d146ca9d471 100644
--- a/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
@@ -9,30 +9,143 @@
#include "PrettyClassLayoutGraphicalDumper.h"
+#include "LinePrinter.h"
+#include "PrettyClassDefinitionDumper.h"
+#include "PrettyVariableDumper.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
+#include "llvm/Support/Format.h"
+
using namespace llvm;
using namespace llvm::pdb;
PrettyClassLayoutGraphicalDumper::PrettyClassLayoutGraphicalDumper(
- LinePrinter &P)
- : PDBSymDumper(true) {}
+ LinePrinter &P, uint32_t InitialOffset)
+ : PDBSymDumper(true), Printer(P), ClassOffsetZero(InitialOffset),
+ CurrentAbsoluteOffset(InitialOffset) {}
+
+bool PrettyClassLayoutGraphicalDumper::start(const UDTLayoutBase &Layout) {
+ const BitVector &UseMap = Layout.usedBytes();
+ int NextPaddingByte = UseMap.find_first_unset();
+
+ for (auto &Item : Layout.layout_items()) {
+ // Calculate the absolute offset of the first byte of the next field.
+ uint32_t RelativeOffset = Item->getOffsetInParent();
+ CurrentAbsoluteOffset = ClassOffsetZero + RelativeOffset;
+
+ // Since there is storage there, it should be set! However, this might
+ // be an empty base, in which case it could extend outside the bounds of
+ // the parent class.
+ if (RelativeOffset < UseMap.size() && (Item->getSize() > 0)) {
+ assert(UseMap.test(RelativeOffset));
+
+ // If there is any remaining padding in this class, and the offset of the
+ // new item is after the padding, then we must have just jumped over some
+ // padding. Print a padding row and then look for where the next block
+ // of padding begins.
+ if ((NextPaddingByte >= 0) &&
+ (RelativeOffset > uint32_t(NextPaddingByte))) {
+ printPaddingRow(RelativeOffset - NextPaddingByte);
+ NextPaddingByte = UseMap.find_next_unset(RelativeOffset);
+ }
+ }
-bool PrettyClassLayoutGraphicalDumper::start(const ClassLayout &Layout) {
- return false;
+ CurrentItem = Item.get();
+ Item->getSymbol().dump(*this);
+ }
+
+ if (NextPaddingByte >= 0 && Layout.getClassSize() > 1) {
+ uint32_t Amount = Layout.getClassSize() - NextPaddingByte;
+ Printer.NewLine();
+ WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
+ << " bytes)";
+ DumpedAnything = true;
+ }
+
+ return DumpedAnything;
+}
+
+void PrettyClassLayoutGraphicalDumper::printPaddingRow(uint32_t Amount) {
+ if (Amount == 0)
+ return;
+
+ Printer.NewLine();
+ WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
+ << " bytes)";
+ DumpedAnything = true;
}
void PrettyClassLayoutGraphicalDumper::dump(
- const PDBSymbolTypeBaseClass &Symbol) {}
+ const PDBSymbolTypeBaseClass &Symbol) {
+ assert(CurrentItem != nullptr);
-void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {}
+ Printer.NewLine();
+ BaseClassLayout &Layout = static_cast<BaseClassLayout &>(*CurrentItem);
-void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeEnum &Symbol) {}
+ std::string Label = Layout.isVirtualBase() ? "vbase" : "base";
+ Printer << Label << " ";
-void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolFunc &Symbol) {}
+ WithColor(Printer, PDB_ColorItem::Offset).get()
+ << "+" << format_hex(CurrentAbsoluteOffset, 4)
+ << " [sizeof=" << Layout.getSize() << "] ";
-void PrettyClassLayoutGraphicalDumper::dump(
- const PDBSymbolTypeTypedef &Symbol) {}
+ WithColor(Printer, PDB_ColorItem::Identifier).get() << Layout.getName();
-void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
+ Printer.Indent();
+ uint32_t ChildOffsetZero = ClassOffsetZero + Layout.getOffsetInParent();
+ PrettyClassLayoutGraphicalDumper BaseDumper(Printer, ChildOffsetZero);
+ BaseDumper.start(Layout);
+ Printer.Unindent();
+
+ DumpedAnything = true;
+}
+
+void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {
+ assert(CurrentItem != nullptr);
+
+ DataMemberLayoutItem &Layout =
+ static_cast<DataMemberLayoutItem &>(*CurrentItem);
+
+ VariableDumper VarDumper(Printer);
+ VarDumper.start(Symbol, ClassOffsetZero);
+
+ if (Layout.hasUDTLayout()) {
+ Printer.Indent();
+ PrettyClassLayoutGraphicalDumper TypeDumper(Printer, ClassOffsetZero);
+ TypeDumper.start(Layout.getUDTLayout());
+ Printer.Unindent();
+ }
+
+ DumpedAnything = true;
+}
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeVTable &Symbol) {
+ assert(CurrentItem != nullptr);
+
+ VTableLayoutItem &Layout = static_cast<VTableLayoutItem &>(*CurrentItem);
+
+ VariableDumper VarDumper(Printer);
+ VarDumper.start(Symbol, ClassOffsetZero);
+
+ Printer.Indent();
+ uint32_t Index = 0;
+ for (auto &Func : Layout.funcs()) {
+ Printer.NewLine();
+ std::string Name = Func->getName();
+ auto ParentClass =
+ unique_dyn_cast<PDBSymbolTypeUDT>(Func->getClassParent());
+ assert(ParentClass);
+ WithColor(Printer, PDB_ColorItem::Address).get() << " [" << Index << "] ";
+ WithColor(Printer, PDB_ColorItem::Identifier).get()
+ << "&" << ParentClass->getName();
+ Printer << "::";
+ WithColor(Printer, PDB_ColorItem::Identifier).get() << Name;
+ ++Index;
+ }
+ Printer.Unindent();
+
+ DumpedAnything = true;
}
diff --git a/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h b/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h
index 6b35b23a855..7dfb74c4e14 100644
--- a/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h
+++ b/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h
@@ -18,22 +18,29 @@ namespace llvm {
namespace pdb {
-class ClassLayout;
+class UDTLayoutBase;
+class StorageItemBase;
class LinePrinter;
class PrettyClassLayoutGraphicalDumper : public PDBSymDumper {
public:
- explicit PrettyClassLayoutGraphicalDumper(LinePrinter &P);
+ PrettyClassLayoutGraphicalDumper(LinePrinter &P, uint32_t InitialOffset);
- bool start(const ClassLayout &Layout);
+ bool start(const UDTLayoutBase &Layout);
void dump(const PDBSymbolTypeBaseClass &Symbol) override;
void dump(const PDBSymbolData &Symbol) override;
- void dump(const PDBSymbolTypeEnum &Symbol) override;
- void dump(const PDBSymbolFunc &Symbol) override;
- void dump(const PDBSymbolTypeTypedef &Symbol) override;
- void dump(const PDBSymbolTypeUDT &Symbol) override;
void dump(const PDBSymbolTypeVTable &Symbol) override;
+
+private:
+ void printPaddingRow(uint32_t Amount);
+
+ LinePrinter &Printer;
+
+ StorageItemBase *CurrentItem = nullptr;
+ uint32_t ClassOffsetZero = 0;
+ uint32_t CurrentAbsoluteOffset = 0;
+ bool DumpedAnything = false;
};
}
}
diff --git a/llvm/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp
index de654d3f81d..02f31108b0d 100644
--- a/llvm/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp
@@ -38,6 +38,8 @@ bool PrettyClassLayoutTextDumper::start(const ClassLayout &Layout) {
opts::pretty::ClassDefinitionFormat::Standard) {
for (auto &Other : Layout.other_items())
Other->dump(*this);
+ for (auto &Func : Layout.funcs())
+ Func->dump(*this);
}
const BitVector &UseMap = Layout.usedBytes();
@@ -101,9 +103,6 @@ void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeVTable &Symbol) {
}
void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeEnum &Symbol) {
- if (Printer.IsTypeExcluded(Symbol.getName()))
- return;
-
DumpedAnything = true;
Printer.NewLine();
EnumDumper Dumper(Printer);
@@ -111,9 +110,6 @@ void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeEnum &Symbol) {
}
void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
- if (Printer.IsTypeExcluded(Symbol.getName()))
- return;
-
DumpedAnything = true;
Printer.NewLine();
TypedefDumper Dumper(Printer);
diff --git a/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp
index 2857b07078c..ffeef72150d 100644
--- a/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp
@@ -22,24 +22,82 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
using namespace llvm::pdb;
+using LayoutPtr = std::unique_ptr<ClassLayout>;
+
+typedef bool (*CompareFunc)(const LayoutPtr &S1, const LayoutPtr &S2);
+
+static bool CompareNames(const LayoutPtr &S1, const LayoutPtr &S2) {
+ return S1->getUDTName() < S2->getUDTName();
+}
+
+static bool CompareSizes(const LayoutPtr &S1, const LayoutPtr &S2) {
+ return S1->getClassSize() < S2->getClassSize();
+}
+
+static bool ComparePadding(const LayoutPtr &S1, const LayoutPtr &S2) {
+ return S1->deepPaddingSize() < S2->deepPaddingSize();
+}
+
+static CompareFunc getComparisonFunc(opts::pretty::ClassSortMode Mode) {
+ switch (Mode) {
+ case opts::pretty::ClassSortMode::Name:
+ return CompareNames;
+ case opts::pretty::ClassSortMode::Size:
+ return CompareSizes;
+ case opts::pretty::ClassSortMode::Padding:
+ return ComparePadding;
+ default:
+ return nullptr;
+ }
+}
+
template <typename Enumerator>
-static std::vector<std::unique_ptr<PDBSymbolTypeUDT>>
-filterClassDefs(LinePrinter &Printer, Enumerator &E) {
- std::vector<std::unique_ptr<PDBSymbolTypeUDT>> Filtered;
+static std::vector<std::unique_ptr<ClassLayout>>
+filterAndSortClassDefs(LinePrinter &Printer, Enumerator &E,
+ uint32_t UnfilteredCount) {
+ std::vector<std::unique_ptr<ClassLayout>> Filtered;
+
+ Filtered.reserve(UnfilteredCount);
+ CompareFunc Comp = getComparisonFunc(opts::pretty::ClassOrder);
+
+ uint32_t Examined = 0;
+ uint32_t Discarded = 0;
while (auto Class = E.getNext()) {
- if (Class->getUnmodifiedTypeId() != 0)
+ ++Examined;
+ if (Examined % 10000 == 0) {
+ outs() << formatv("Examined {0}/{1} items. {2} items discarded\n",
+ Examined, UnfilteredCount, Discarded);
+ outs().flush();
+ }
+
+ if (Class->getUnmodifiedTypeId() != 0) {
+ ++Discarded;
continue;
+ }
- if (Printer.IsTypeExcluded(Class->getName()))
+ if (Printer.IsTypeExcluded(Class->getName(), Class->getLength())) {
+ ++Discarded;
continue;
+ }
- Filtered.push_back(std::move(Class));
+ auto Layout = llvm::make_unique<ClassLayout>(std::move(Class));
+ if (Layout->deepPaddingSize() < opts::pretty::PaddingThreshold) {
+ ++Discarded;
+ continue;
+ }
+
+ Filtered.push_back(std::move(Layout));
}
+ if (Comp)
+ std::sort(Filtered.begin(), Filtered.end(), Comp);
return Filtered;
}
@@ -70,20 +128,52 @@ void TypeDumper::start(const PDBSymbolExe &Exe) {
if (opts::pretty::Classes) {
auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>();
- auto Filtered = filterClassDefs(Printer, *Classes);
-
- Printer.NewLine();
- uint32_t Shown = Filtered.size();
uint32_t All = Classes->getChildCount();
+ Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes";
+
+ bool Precompute = false;
+ Precompute =
+ (opts::pretty::ClassOrder != opts::pretty::ClassSortMode::None);
+
+ // If we're using no sort mode, then we can start getting immediate output
+ // from the tool by just filtering as we go, rather than processing
+ // everything up front so that we can sort it. This makes the tool more
+ // responsive. So only precompute the filtered/sorted set of classes if
+ // necessary due to the specified options.
+ std::vector<LayoutPtr> Filtered;
+ uint32_t Shown = All;
+ if (Precompute) {
+ Filtered = filterAndSortClassDefs(Printer, *Classes, All);
+
+ Shown = Filtered.size();
+ }
+
Printer << ": (Showing " << Shown << " items";
if (Shown < All)
Printer << ", " << (All - Shown) << " filtered";
Printer << ")";
Printer.Indent();
- for (auto &Class : Filtered)
- Class->dump(*this);
+
+ // If we pre-computed, iterate the filtered/sorted list, otherwise iterate
+ // the DIA enumerator and filter on the fly.
+ if (Precompute) {
+ for (auto &Class : Filtered)
+ dumpClassLayout(*Class);
+ } else {
+ while (auto Class = Classes->getNext()) {
+ if (Printer.IsTypeExcluded(Class->getName(), Class->getLength()))
+ continue;
+
+ auto Layout = llvm::make_unique<ClassLayout>(std::move(Class));
+ if (Layout->deepPaddingSize() < opts::pretty::PaddingThreshold)
+ continue;
+
+ dumpClassLayout(*Layout);
+ }
+ }
+
Printer.Unindent();
}
}
@@ -91,7 +181,7 @@ void TypeDumper::start(const PDBSymbolExe &Exe) {
void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol) {
assert(opts::pretty::Enums);
- if (Printer.IsTypeExcluded(Symbol.getName()))
+ if (Printer.IsTypeExcluded(Symbol.getName(), Symbol.getLength()))
return;
// Dump member enums when dumping their class definition.
if (nullptr != Symbol.getClassParent())
@@ -105,7 +195,7 @@ void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol) {
void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
assert(opts::pretty::Typedefs);
- if (Printer.IsTypeExcluded(Symbol.getName()))
+ if (Printer.IsTypeExcluded(Symbol.getName(), Symbol.getLength()))
return;
Printer.NewLine();
@@ -113,15 +203,15 @@ void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
Dumper.start(Symbol);
}
-void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) {
+void TypeDumper::dumpClassLayout(const ClassLayout &Class) {
assert(opts::pretty::Classes);
if (opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::None) {
Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Keyword).get() << "class ";
- WithColor(Printer, PDB_ColorItem::Identifier).get() << Symbol.getName();
+ WithColor(Printer, PDB_ColorItem::Identifier).get() << Class.getUDTName();
} else {
ClassDefinitionDumper Dumper(Printer);
- Dumper.start(Symbol);
+ Dumper.start(Class);
}
}
diff --git a/llvm/tools/llvm-pdbdump/PrettyTypeDumper.h b/llvm/tools/llvm-pdbdump/PrettyTypeDumper.h
index f9d8304c320..68a2f0246eb 100644
--- a/llvm/tools/llvm-pdbdump/PrettyTypeDumper.h
+++ b/llvm/tools/llvm-pdbdump/PrettyTypeDumper.h
@@ -15,6 +15,7 @@
namespace llvm {
namespace pdb {
class LinePrinter;
+class ClassLayout;
class TypeDumper : public PDBSymDumper {
public:
@@ -24,7 +25,8 @@ public:
void dump(const PDBSymbolTypeEnum &Symbol) override;
void dump(const PDBSymbolTypeTypedef &Symbol) override;
- void dump(const PDBSymbolTypeUDT &Symbol) override;
+
+ void dumpClassLayout(const ClassLayout &Class);
private:
LinePrinter &Printer;
diff --git a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp
index ef9a9b51bd0..76a0d23bf87 100644
--- a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp
@@ -35,7 +35,7 @@ using namespace llvm::pdb;
VariableDumper::VariableDumper(LinePrinter &P)
: PDBSymDumper(true), Printer(P) {}
-void VariableDumper::start(const PDBSymbolData &Var) {
+void VariableDumper::start(const PDBSymbolData &Var, uint32_t Offset) {
if (Var.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
return;
if (Printer.IsSymbolExcluded(Var.getName()))
@@ -68,16 +68,16 @@ void VariableDumper::start(const PDBSymbolData &Var) {
Printer.NewLine();
Printer << "data ";
WithColor(Printer, PDB_ColorItem::Offset).get()
- << "+" << format_hex(Var.getOffset(), 4) << " [sizeof=" << Length
- << "] ";
+ << "+" << format_hex(Offset + Var.getOffset(), 4)
+ << " [sizeof=" << Length << "] ";
dumpSymbolTypeAndName(*VarType, Var.getName());
break;
case PDB_LocType::BitField:
Printer.NewLine();
Printer << "data ";
WithColor(Printer, PDB_ColorItem::Offset).get()
- << "+" << format_hex(Var.getOffset(), 4) << " [sizeof=" << Length
- << "] ";
+ << "+" << format_hex(Offset + Var.getOffset(), 4)
+ << " [sizeof=" << Length << "] ";
dumpSymbolTypeAndName(*VarType, Var.getName());
Printer << " : ";
WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Var.getLength();
@@ -91,17 +91,15 @@ void VariableDumper::start(const PDBSymbolData &Var) {
}
}
-void VariableDumper::start(const PDBSymbolTypeVTable &Var) {
+void VariableDumper::start(const PDBSymbolTypeVTable &Var, uint32_t Offset) {
Printer.NewLine();
- Printer << "data ";
+ Printer << "vfptr ";
auto VTableType = cast<PDBSymbolTypePointer>(Var.getType());
uint32_t PointerSize = VTableType->getLength();
WithColor(Printer, PDB_ColorItem::Offset).get()
- << "+" << format_hex(Var.getOffset(), 4) << " [sizeof=" << PointerSize
- << "] ";
-
- WithColor(Printer, PDB_ColorItem::Identifier).get() << " __vfptr";
+ << "+" << format_hex(Offset + Var.getOffset(), 4)
+ << " [sizeof=" << PointerSize << "] ";
}
void VariableDumper::dump(const PDBSymbolTypeArray &Symbol) {
diff --git a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h
index ba9fdb17655..4ba3bc97d85 100644
--- a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h
+++ b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h
@@ -24,8 +24,8 @@ class VariableDumper : public PDBSymDumper {
public:
VariableDumper(LinePrinter &P);
- void start(const PDBSymbolData &Var);
- void start(const PDBSymbolTypeVTable &Var);
+ void start(const PDBSymbolData &Var, uint32_t Offset = 0);
+ void start(const PDBSymbolTypeVTable &Var, uint32_t Offset = 0);
void dump(const PDBSymbolTypeArray &Symbol) override;
void dump(const PDBSymbolTypeBuiltin &Symbol) override;
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index 6d39871699b..06c2afc0bc7 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -122,15 +122,27 @@ cl::opt<bool> Enums("enums", cl::desc("Display enum types"),
cl::cat(TypeCategory), cl::sub(PrettySubcommand));
cl::opt<bool> Typedefs("typedefs", cl::desc("Display typedef types"),
cl::cat(TypeCategory), cl::sub(PrettySubcommand));
+cl::opt<ClassSortMode> ClassOrder(
+ "class-order", cl::desc("Class sort order"), cl::init(ClassSortMode::None),
+ cl::values(clEnumValN(ClassSortMode::None, "none",
+ "Undefined / no particular sort order"),
+ clEnumValN(ClassSortMode::Name, "name", "Sort classes by name"),
+ clEnumValN(ClassSortMode::Size, "size", "Sort classes by size"),
+ clEnumValN(ClassSortMode::Padding, "padding",
+ "Sort classes by amount of padding")),
+ cl::cat(TypeCategory), cl::sub(PrettySubcommand));
+
cl::opt<ClassDefinitionFormat> ClassFormat(
"class-definitions", cl::desc("Class definition format"),
cl::init(ClassDefinitionFormat::Standard),
cl::values(
clEnumValN(ClassDefinitionFormat::Standard, "all-members",
"Display all class members including data, constants, "
- "typedefs, etc"),
+ "typedefs, functions, etc"),
clEnumValN(ClassDefinitionFormat::Layout, "layout-members",
"Only display members that contribute to class size."),
+ clEnumValN(ClassDefinitionFormat::Graphical, "graphical",
+ "Display graphical representation of each class's layout."),
clEnumValN(ClassDefinitionFormat::None, "none",
"Don't display class definitions")),
cl::cat(TypeCategory), cl::sub(PrettySubcommand));
@@ -173,10 +185,14 @@ cl::list<std::string> IncludeCompilands(
"include-compilands",
cl::desc("Include only compilands those which match a regular expression"),
cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand));
-cl::opt<bool> OnlyPaddingClasses(
- "only-padding-classes", cl::desc("When dumping classes, only display those "
- "with non-zero amounts of padding bytes"),
- cl::ZeroOrMore, cl::cat(FilterCategory), cl::sub(PrettySubcommand));
+cl::opt<uint32_t> SizeThreshold(
+ "min-type-size", cl::desc("Displays only those types which are greater "
+ "than or equal to the specified size."),
+ cl::init(0), cl::cat(FilterCategory), cl::sub(PrettySubcommand));
+cl::opt<uint32_t> PaddingThreshold(
+ "min-class-padding", cl::desc("Displays only those classes which have at "
+ "least the specified amount of padding."),
+ cl::init(0), cl::cat(FilterCategory), cl::sub(PrettySubcommand));
cl::opt<bool> ExcludeCompilerGenerated(
"no-compiler-generated",
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
index 36a296087ab..a5429a253df 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
@@ -19,6 +19,7 @@ namespace opts {
namespace pretty {
enum class ClassDefinitionFormat { None, Layout, Graphical, Standard };
+enum class ClassSortMode { None, Name, Size, Padding };
extern llvm::cl::opt<bool> Compilands;
extern llvm::cl::opt<bool> Symbols;
@@ -36,7 +37,9 @@ extern llvm::cl::list<std::string> ExcludeCompilands;
extern llvm::cl::list<std::string> IncludeTypes;
extern llvm::cl::list<std::string> IncludeSymbols;
extern llvm::cl::list<std::string> IncludeCompilands;
-extern llvm::cl::opt<bool> OnlyPaddingClasses;
+extern llvm::cl::opt<ClassSortMode> ClassOrder;
+extern llvm::cl::opt<uint32_t> SizeThreshold;
+extern llvm::cl::opt<uint32_t> PaddingThreshold;
extern llvm::cl::opt<ClassDefinitionFormat> ClassFormat;
}
OpenPOWER on IntegriCloud