summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp131
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h6
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyFunctionDumper.cpp2
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp34
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyTypedefDumper.cpp2
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp23
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyVariableDumper.h1
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp21
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.h2
9 files changed, 119 insertions, 103 deletions
diff --git a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
index b48ed23c1c7..2e1e54e4db1 100644
--- a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
@@ -28,7 +28,8 @@
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
-#include "llvm/Support/Compiler.h"
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
+
#include "llvm/Support/Format.h"
using namespace llvm;
@@ -37,58 +38,23 @@ using namespace llvm::pdb;
ClassDefinitionDumper::ClassDefinitionDumper(LinePrinter &P)
: PDBSymDumper(true), Printer(P) {}
-static void analyzePadding(const PDBSymbolTypeUDT &Class, BitVector &Padding,
- uint32_t &FirstFieldOffset) {
- Padding.resize(Class.getLength(), true);
- auto Children = Class.findAllChildren<PDBSymbolData>();
- bool IsFirst = true;
- FirstFieldOffset = Class.getLength();
-
- while (auto Data = Children->getNext()) {
- // Ignore data members which are not relative to this. Usually these are
- // static data members or constexpr and occupy no space. We also need to
- // handle BitFields since the PDB doesn't consider them ThisRel, but they
- // still occupy space in the record layout.
- auto LocType = Data->getLocationType();
- if (LocType != PDB_LocType::ThisRel && LocType != PDB_LocType::BitField)
- continue;
-
- uint64_t Start = Data->getOffset();
- if (IsFirst) {
- FirstFieldOffset = Start;
- IsFirst = false;
- }
-
- auto VarType = Data->getType();
- uint64_t Size = VarType->getRawSymbol().getLength();
- Padding.reset(Start, Start + Size);
- }
-
- // Unmark anything that comes before the first field so it doesn't get
- // counted as padding. In reality this is going to be vptrs or base class
- // members, but we don't correctly handle that yet.
- // FIXME: Handle it.
- Padding.reset(0, FirstFieldOffset);
-}
-
void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
assert(opts::pretty::ClassFormat !=
opts::pretty::ClassDefinitionFormat::None);
uint32_t Size = Class.getLength();
- uint32_t FirstFieldOffset = 0;
- BitVector Padding;
- analyzePadding(Class, Padding, FirstFieldOffset);
- if (opts::pretty::OnlyPaddingClasses && (Padding.count() == 0))
+ ClassLayout Layout(Class.clone());
+
+ if (opts::pretty::OnlyPaddingClasses && (Layout.shallowPaddingSize() == 0))
return;
Printer.NewLine();
- WithColor(Printer, PDB_ColorItem::Comment).get() << "// sizeof = " << Size;
- Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
WithColor(Printer, PDB_ColorItem::Type).get() << Class.getName();
+ WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size
+ << "]";
auto Bases = Class.findAllChildren<PDBSymbolTypeBaseClass>();
if (Bases->getChildCount() > 0) {
@@ -111,60 +77,54 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
}
Printer << " {";
- auto Children = Class.findAllChildren();
Printer.Indent();
- int DumpedCount = 0;
-
- int NextPaddingByte = Padding.find_first();
- while (auto Child = Children->getNext()) {
- if (auto Data = llvm::dyn_cast<PDBSymbolData>(Child.get())) {
- if (Data->getDataKind() == PDB_DataKind::Member && NextPaddingByte >= 0) {
- // If there are padding bytes remaining, see if this field is the first
- // to cross a padding boundary, and print a padding field indicator if
- // so.
- int Off = Data->getOffset();
- if (Off > NextPaddingByte) {
- uint32_t Amount = Off - NextPaddingByte;
- Printer.NewLine();
- WithColor(Printer, PDB_ColorItem::Padding).get()
- << "<padding> (" << Amount << " bytes)";
- assert(Padding.find_next_unset(NextPaddingByte) == Off);
- NextPaddingByte = Padding.find_next(Off);
- }
- }
- }
- if (auto Func = Child->cast<PDBSymbolFunc>()) {
- if (Func->isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
- continue;
+ // Dump non-layout items first, but only if we're not in layout-only mode.
+ if (opts::pretty::ClassFormat !=
+ opts::pretty::ClassDefinitionFormat::Layout) {
+ for (auto &Other : Layout.other_items())
+ Other->dump(*this);
+ }
- if (Func->getLength() == 0 && !Func->isPureVirtual() &&
- !Func->isIntroVirtualFunction())
- continue;
+ const BitVector &UseMap = Layout.usedBytes();
+ int NextUnusedByte = Layout.usedBytes().find_first_unset();
+ // Next dump items which affect class layout.
+ for (auto &LayoutItem : Layout.layout_items()) {
+ if (NextUnusedByte >= 0) {
+ // If there are padding bytes remaining, see if this field is the first to
+ // cross a padding boundary, and print a padding field indicator if so.
+ int Off = LayoutItem->getOffsetInParent();
+ if (Off > NextUnusedByte) {
+ uint32_t Amount = Off - NextUnusedByte;
+ Printer.NewLine();
+ WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> ("
+ << Amount << " bytes)";
+ assert(UseMap.find_next(NextUnusedByte) == Off);
+ NextUnusedByte = UseMap.find_next_unset(Off);
+ }
}
-
- ++DumpedCount;
- Child->dump(*this);
+ LayoutItem->getSymbol().dump(*this);
}
- if (NextPaddingByte >= 0) {
- uint32_t Amount = Size - NextPaddingByte;
+ if (NextUnusedByte >= 0 && Layout.getClassSize() > 1) {
+ uint32_t Amount = Layout.getClassSize() - NextUnusedByte;
Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
<< " bytes)";
+ DumpedAnything = true;
}
+
Printer.Unindent();
- if (DumpedCount > 0)
+ if (DumpedAnything)
Printer.NewLine();
Printer << "}";
Printer.NewLine();
- if (Padding.count() > 0) {
- APFloat Pct(100.0 * (double)Padding.count() /
- (double)(Size - FirstFieldOffset));
+ if (Layout.deepPaddingSize() > 0) {
+ APFloat Pct(100.0 * (double)Layout.deepPaddingSize() / (double)Size);
SmallString<8> PctStr;
Pct.toString(PctStr, 4);
WithColor(Printer, PDB_ColorItem::Padding).get()
- << "Total padding " << Padding.count() << " bytes (" << PctStr
+ << "Total padding " << Layout.deepPaddingSize() << " bytes (" << PctStr
<< "% of class size)";
Printer.NewLine();
}
@@ -175,23 +135,35 @@ void ClassDefinitionDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {}
void ClassDefinitionDumper::dump(const PDBSymbolData &Symbol) {
VariableDumper Dumper(Printer);
Dumper.start(Symbol);
+ DumpedAnything = true;
}
void ClassDefinitionDumper::dump(const PDBSymbolFunc &Symbol) {
if (Printer.IsSymbolExcluded(Symbol.getName()))
return;
+ if (Symbol.isCompilerGenerated() && opts::pretty::ExcludeCompilerGenerated)
+ return;
+ if (Symbol.getLength() == 0 && !Symbol.isPureVirtual() &&
+ !Symbol.isIntroVirtualFunction())
+ return;
+ DumpedAnything = true;
Printer.NewLine();
FunctionDumper Dumper(Printer);
Dumper.start(Symbol, FunctionDumper::PointerType::None);
}
-void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol) {}
+void ClassDefinitionDumper::dump(const PDBSymbolTypeVTable &Symbol) {
+ VariableDumper Dumper(Printer);
+ Dumper.start(Symbol);
+ DumpedAnything = true;
+}
void ClassDefinitionDumper::dump(const PDBSymbolTypeEnum &Symbol) {
if (Printer.IsTypeExcluded(Symbol.getName()))
return;
+ DumpedAnything = true;
Printer.NewLine();
EnumDumper Dumper(Printer);
Dumper.start(Symbol);
@@ -201,6 +173,7 @@ void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
if (Printer.IsTypeExcluded(Symbol.getName()))
return;
+ DumpedAnything = true;
Printer.NewLine();
TypedefDumper Dumper(Printer);
Dumper.start(Symbol);
diff --git a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
index 8f0c35cba81..94ae07d345d 100644
--- a/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
+++ b/llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h
@@ -21,6 +21,8 @@
#include <unordered_map>
namespace llvm {
+class BitVector;
+
namespace pdb {
class LinePrinter;
@@ -40,6 +42,10 @@ public:
void dump(const PDBSymbolTypeVTable &Symbol) override;
private:
+ bool maybeDumpSymbol(std::unique_ptr<PDBSymbolData> Data,
+ const BitVector &Padding, int &NextUnusedByte);
+ bool maybeDumpSymbol(std::unique_ptr<PDBSymbolFunc> Data);
+ bool DumpedAnything = false;
LinePrinter &Printer;
};
}
diff --git a/llvm/tools/llvm-pdbdump/PrettyFunctionDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyFunctionDumper.cpp
index 0e0da026e56..b0be33c157c 100644
--- a/llvm/tools/llvm-pdbdump/PrettyFunctionDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyFunctionDumper.cpp
@@ -233,7 +233,7 @@ void FunctionDumper::dump(const PDBSymbolTypePointer &Symbol) {
if (!PointeeType)
return;
- if (auto FuncSig = PointeeType->cast<PDBSymbolTypeFunctionSig>()) {
+ if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {
FunctionDumper NestedDumper(Printer);
PointerType Pointer =
Symbol.isReference() ? PointerType::Reference : PointerType::Pointer;
diff --git a/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp
index 12a47d24f79..2857b07078c 100644
--- a/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp
@@ -26,6 +26,23 @@
using namespace llvm;
using namespace llvm::pdb;
+template <typename Enumerator>
+static std::vector<std::unique_ptr<PDBSymbolTypeUDT>>
+filterClassDefs(LinePrinter &Printer, Enumerator &E) {
+ std::vector<std::unique_ptr<PDBSymbolTypeUDT>> Filtered;
+ while (auto Class = E.getNext()) {
+ if (Class->getUnmodifiedTypeId() != 0)
+ continue;
+
+ if (Printer.IsTypeExcluded(Class->getName()))
+ continue;
+
+ Filtered.push_back(std::move(Class));
+ }
+
+ return Filtered;
+}
+
TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {}
void TypeDumper::start(const PDBSymbolExe &Exe) {
@@ -53,11 +70,19 @@ 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();
+
WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes";
- Printer << ": (" << Classes->getChildCount() << " items)";
+ Printer << ": (Showing " << Shown << " items";
+ if (Shown < All)
+ Printer << ", " << (All - Shown) << " filtered";
+ Printer << ")";
Printer.Indent();
- while (auto Class = Classes->getNext())
+ for (auto &Class : Filtered)
Class->dump(*this);
Printer.Unindent();
}
@@ -91,11 +116,6 @@ void TypeDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
void TypeDumper::dump(const PDBSymbolTypeUDT &Symbol) {
assert(opts::pretty::Classes);
- if (Symbol.getUnmodifiedTypeId() != 0)
- return;
- if (Printer.IsTypeExcluded(Symbol.getName()))
- return;
-
if (opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::None) {
Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Keyword).get() << "class ";
diff --git a/llvm/tools/llvm-pdbdump/PrettyTypedefDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyTypedefDumper.cpp
index 861f7e28b38..2d8e915d760 100644
--- a/llvm/tools/llvm-pdbdump/PrettyTypedefDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyTypedefDumper.cpp
@@ -54,7 +54,7 @@ void TypedefDumper::dump(const PDBSymbolTypePointer &Symbol) {
if (Symbol.isVolatileType())
WithColor(Printer, PDB_ColorItem::Keyword).get() << "volatile ";
auto PointeeType = Symbol.getPointeeType();
- if (auto FuncSig = PointeeType->cast<PDBSymbolTypeFunctionSig>()) {
+ if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {
FunctionDumper::PointerType Pointer = FunctionDumper::PointerType::Pointer;
if (Symbol.isReference())
Pointer = FunctionDumper::PointerType::Reference;
diff --git a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp
index 65f0139dfbc..ef9a9b51bd0 100644
--- a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp
+++ b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp
@@ -91,6 +91,19 @@ void VariableDumper::start(const PDBSymbolData &Var) {
}
}
+void VariableDumper::start(const PDBSymbolTypeVTable &Var) {
+ Printer.NewLine();
+ Printer << "data ";
+ 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";
+}
+
void VariableDumper::dump(const PDBSymbolTypeArray &Symbol) {
auto ElementType = Symbol.getElementType();
assert(ElementType);
@@ -157,12 +170,12 @@ void VariableDumper::dump(const PDBSymbolTypePointer &Symbol) {
if (!PointeeType)
return;
PointeeType->dump(*this);
- if (auto Func = PointeeType->cast<PDBSymbolTypeFunctionSig>()) {
+ if (auto FuncSig = unique_dyn_cast<PDBSymbolTypeFunctionSig>(PointeeType)) {
// A hack to get the calling convention in the right spot.
Printer << " (";
- PDB_CallingConv CC = Func->getCallingConvention();
+ PDB_CallingConv CC = FuncSig->getCallingConvention();
WithColor(Printer, PDB_ColorItem::Keyword).get() << CC << " ";
- } else if (isa<PDBSymbolTypeArray>(PointeeType.get())) {
+ } else if (isa<PDBSymbolTypeArray>(PointeeType)) {
Printer << " (";
}
Printer << (Symbol.isReference() ? "&" : "*");
@@ -177,8 +190,8 @@ void VariableDumper::dumpRight(const PDBSymbolTypePointer &Symbol) {
assert(PointeeType);
if (!PointeeType)
return;
- if (isa<PDBSymbolTypeFunctionSig>(PointeeType.get()) ||
- isa<PDBSymbolTypeArray>(PointeeType.get())) {
+ if (isa<PDBSymbolTypeFunctionSig>(PointeeType) ||
+ isa<PDBSymbolTypeArray>(PointeeType)) {
Printer << ")";
}
PointeeType->dumpRight(*this);
diff --git a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h
index eec389b1707..ba9fdb17655 100644
--- a/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h
+++ b/llvm/tools/llvm-pdbdump/PrettyVariableDumper.h
@@ -25,6 +25,7 @@ public:
VariableDumper(LinePrinter &P);
void start(const PDBSymbolData &Var);
+ void start(const PDBSymbolTypeVTable &Var);
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 8a749bab98e..a486c8a0730 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -96,7 +96,7 @@ cl::SubCommand
"Analyze various aspects of a PDB's structure");
cl::OptionCategory TypeCategory("Symbol Type Options");
-cl::OptionCategory FilterCategory("Filtering Options");
+cl::OptionCategory FilterCategory("Filtering and Sorting Options");
cl::OptionCategory OtherOptions("Other Options");
namespace pretty {
@@ -122,14 +122,17 @@ 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<ClassDefinitionFormat>
- ClassFormat("class-definitions", cl::desc("Class definition format"),
- cl::init(ClassDefinitionFormat::Standard),
- cl::values(clEnumValN(ClassDefinitionFormat::Standard, "full",
- "Display complete class definition"),
- clEnumValN(ClassDefinitionFormat::None, "none",
- "Don't display class definitions")),
- 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, "full",
+ "Display complete class definition"),
+ clEnumValN(ClassDefinitionFormat::Layout, "layout",
+ "Only display members that contribute to class size."),
+ clEnumValN(ClassDefinitionFormat::None, "none",
+ "Don't display class definitions")),
+ cl::cat(TypeCategory), cl::sub(PrettySubcommand));
cl::opt<bool> Lines("lines", cl::desc("Line tables"), cl::cat(TypeCategory),
cl::sub(PrettySubcommand));
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
index a335d30c4cf..c572176f76d 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
@@ -18,7 +18,7 @@ namespace opts {
namespace pretty {
-enum class ClassDefinitionFormat { None, Standard };
+enum class ClassDefinitionFormat { None, Layout, Standard };
extern llvm::cl::opt<bool> Compilands;
extern llvm::cl::opt<bool> Symbols;
OpenPOWER on IntegriCloud