summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp')
-rw-r--r--llvm/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp135
1 files changed, 124 insertions, 11 deletions
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;
}
OpenPOWER on IntegriCloud