diff options
| author | Zachary Turner <zturner@google.com> | 2017-04-13 21:11:00 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2017-04-13 21:11:00 +0000 |
| commit | 4dc4f01a86569977ad6fc2a0bb605731055f0a92 (patch) | |
| tree | 86e89154bab5ec96eaa55ad9d395c46f6612640c /llvm/tools/llvm-pdbdump | |
| parent | 60f54ac8c5d46fb73d23fe45ae326d492474e57c (diff) | |
| download | bcm5719-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.cpp | 17 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/LinePrinter.h | 5 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp | 44 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h | 3 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp | 135 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h | 21 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp | 8 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp | 124 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyTypeDumper.h | 4 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp | 20 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyVariableDumper.h | 4 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 26 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.h | 5 |
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; } |

