diff options
Diffstat (limited to 'llvm/tools')
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp | 131 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyClassDefinitionDumper.h | 6 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyFunctionDumper.cpp | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyTypeDumper.cpp | 34 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyTypedefDumper.cpp | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyVariableDumper.cpp | 23 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/PrettyVariableDumper.h | 1 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp | 21 | ||||
| -rw-r--r-- | llvm/tools/llvm-pdbdump/llvm-pdbdump.h | 2 |
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; |

