mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 13:11:39 +01:00
[llvm-pdbdump] Minor prepatory refactor of Class Def Dumper.
In a followup patch I intend to introduce an additional dumping mode which dumps a graphical representation of a class's layout. In preparation for this, the text-based layout printer needs to be split out from the graphical layout printer, and both need to be able to use the same code for printing the intro and outro of a class's definition (e.g. base class list, etc). This patch does so, and in the process introduces a skeleton definition for the graphical printer, while currently making the graphical printer just print nothing. NFC llvm-svn: 300134
This commit is contained in:
parent
8a8f84f312
commit
89377d6ac2
@ -95,16 +95,18 @@ public:
|
||||
|
||||
uint32_t getClassSize() const { return SizeOf; }
|
||||
|
||||
const PDBSymbol &getSymbol() const { return Symbol; }
|
||||
|
||||
ArrayRef<std::unique_ptr<StorageItemBase>> layout_items() const {
|
||||
return ChildStorage;
|
||||
}
|
||||
|
||||
ArrayRef<BaseClassLayout *> base_classes() const { return BaseClasses; }
|
||||
|
||||
ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const {
|
||||
return NonStorageItems;
|
||||
}
|
||||
|
||||
const PDBSymbol &getSymbolBase() const { return SymbolBase; }
|
||||
|
||||
protected:
|
||||
void initializeChildren(const PDBSymbol &Sym);
|
||||
|
||||
@ -113,7 +115,7 @@ protected:
|
||||
uint32_t SizeOf = 0;
|
||||
std::string Name;
|
||||
|
||||
const PDBSymbol &Symbol;
|
||||
const PDBSymbol &SymbolBase;
|
||||
BitVector UsedBytes;
|
||||
std::vector<std::unique_ptr<PDBSymbol>> NonStorageItems;
|
||||
std::vector<std::unique_ptr<StorageItemBase>> ChildStorage;
|
||||
@ -124,10 +126,14 @@ protected:
|
||||
|
||||
class ClassLayout : public UDTLayoutBase {
|
||||
public:
|
||||
explicit ClassLayout(const PDBSymbolTypeUDT &UDT);
|
||||
explicit ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT);
|
||||
|
||||
const PDBSymbolTypeUDT &getClass() const { return UDT; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<PDBSymbolTypeUDT> Type;
|
||||
std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage;
|
||||
const PDBSymbolTypeUDT &UDT;
|
||||
};
|
||||
|
||||
class BaseClassLayout : public UDTLayoutBase, public StorageItemBase {
|
||||
@ -135,6 +141,8 @@ public:
|
||||
BaseClassLayout(const UDTLayoutBase &Parent,
|
||||
std::unique_ptr<PDBSymbolTypeBaseClass> Base);
|
||||
|
||||
const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<PDBSymbolTypeBaseClass> Base;
|
||||
bool IsVirtualBase;
|
||||
|
@ -89,7 +89,8 @@ VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
|
||||
VTableType->getPointeeType())) {
|
||||
VTableFuncs.resize(Shape->getCount());
|
||||
|
||||
auto ParentFunctions = Parent.getSymbol().findAllChildren<PDBSymbolFunc>();
|
||||
auto ParentFunctions =
|
||||
Parent.getSymbolBase().findAllChildren<PDBSymbolFunc>();
|
||||
while (auto Func = ParentFunctions->getNext()) {
|
||||
if (Func->isVirtual()) {
|
||||
uint32_t Index = Func->getVirtualBaseOffset();
|
||||
@ -109,15 +110,19 @@ VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
|
||||
|
||||
UDTLayoutBase::UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name,
|
||||
uint32_t Size)
|
||||
: Symbol(Symbol), Name(Name), SizeOf(Size) {
|
||||
: SymbolBase(Symbol), Name(Name), SizeOf(Size) {
|
||||
UsedBytes.resize(Size);
|
||||
ChildrenPerByte.resize(Size);
|
||||
initializeChildren(Symbol);
|
||||
}
|
||||
|
||||
ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
|
||||
: UDTLayoutBase(UDT, UDT.getName(), UDT.getLength()), UDT(UDT) {}
|
||||
|
||||
ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
|
||||
: UDTLayoutBase(*UDT, UDT->getName(), UDT->getLength()),
|
||||
Type(std::move(UDT)) {}
|
||||
: ClassLayout(*UDT) {
|
||||
OwnedStorage = std::move(UDT);
|
||||
}
|
||||
|
||||
BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
|
||||
std::unique_ptr<PDBSymbolTypeBaseClass> Base)
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llvm-pdbdump pretty -classes -class-definitions=layout \
|
||||
; RUN: llvm-pdbdump pretty -classes -class-definitions=layout-members \
|
||||
; RUN: -include-types=SimplePad %p/Inputs/SimplePaddingTest.pdb > %t
|
||||
|
||||
; RUN: FileCheck -input-file=%t %s -check-prefix=NO_PADDING
|
||||
|
@ -18,6 +18,8 @@ add_llvm_tool(llvm-pdbdump
|
||||
PdbYaml.cpp
|
||||
PrettyBuiltinDumper.cpp
|
||||
PrettyClassDefinitionDumper.cpp
|
||||
PrettyClassLayoutTextDumper.cpp
|
||||
PrettyClassLayoutGraphicalDumper.cpp
|
||||
PrettyCompilandDumper.cpp
|
||||
PrettyEnumDumper.cpp
|
||||
PrettyExternalSymbolDumper.cpp
|
||||
|
@ -10,24 +10,14 @@
|
||||
#include "PrettyClassDefinitionDumper.h"
|
||||
|
||||
#include "LinePrinter.h"
|
||||
#include "PrettyEnumDumper.h"
|
||||
#include "PrettyFunctionDumper.h"
|
||||
#include "PrettyTypedefDumper.h"
|
||||
#include "PrettyVariableDumper.h"
|
||||
#include "PrettyClassLayoutGraphicalDumper.h"
|
||||
#include "PrettyClassLayoutTextDumper.h"
|
||||
#include "llvm-pdbdump.h"
|
||||
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/DebugInfo/PDB/IPDBSession.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBExtras.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
|
||||
#include "llvm/DebugInfo/PDB/UDTLayout.h"
|
||||
|
||||
#include "llvm/Support/Format.h"
|
||||
@ -42,33 +32,57 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
|
||||
assert(opts::pretty::ClassFormat !=
|
||||
opts::pretty::ClassDefinitionFormat::None);
|
||||
|
||||
uint32_t Size = Class.getLength();
|
||||
|
||||
ClassLayout Layout(Class.clone());
|
||||
ClassLayout Layout(Class);
|
||||
|
||||
if (opts::pretty::OnlyPaddingClasses && (Layout.shallowPaddingSize() == 0))
|
||||
return;
|
||||
|
||||
prettyPrintClassIntro(Layout);
|
||||
|
||||
switch (opts::pretty::ClassFormat) {
|
||||
case opts::pretty::ClassDefinitionFormat::Graphical: {
|
||||
PrettyClassLayoutGraphicalDumper Dumper(Printer);
|
||||
DumpedAnything = Dumper.start(Layout);
|
||||
break;
|
||||
}
|
||||
case opts::pretty::ClassDefinitionFormat::Standard:
|
||||
case opts::pretty::ClassDefinitionFormat::Layout: {
|
||||
PrettyClassLayoutTextDumper Dumper(Printer);
|
||||
DumpedAnything |= Dumper.start(Layout);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("Unreachable!");
|
||||
}
|
||||
|
||||
prettyPrintClassOutro(Layout);
|
||||
}
|
||||
|
||||
void ClassDefinitionDumper::prettyPrintClassIntro(const ClassLayout &Layout) {
|
||||
DumpedAnything = false;
|
||||
Printer.NewLine();
|
||||
|
||||
uint32_t Size = Layout.getClassSize();
|
||||
const PDBSymbolTypeUDT &Class = Layout.getClass();
|
||||
|
||||
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) {
|
||||
uint32_t BaseCount = Layout.base_classes().size();
|
||||
if (BaseCount > 0) {
|
||||
Printer.Indent();
|
||||
Printer.NewLine();
|
||||
Printer << ":";
|
||||
uint32_t BaseIndex = 0;
|
||||
while (auto Base = Bases->getNext()) {
|
||||
for (auto BC : Layout.base_classes()) {
|
||||
const auto &Base = BC->getBase();
|
||||
Printer << " ";
|
||||
WithColor(Printer, PDB_ColorItem::Keyword).get() << Base->getAccess();
|
||||
if (Base->isVirtualBaseClass())
|
||||
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 < Bases->getChildCount()) {
|
||||
WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName();
|
||||
if (++BaseIndex < BaseCount) {
|
||||
Printer.NewLine();
|
||||
Printer << ",";
|
||||
}
|
||||
@ -78,49 +92,17 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
|
||||
|
||||
Printer << " {";
|
||||
Printer.Indent();
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
LayoutItem->getSymbol().dump(*this);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void ClassDefinitionDumper::prettyPrintClassOutro(const ClassLayout &Layout) {
|
||||
Printer.Unindent();
|
||||
if (DumpedAnything)
|
||||
Printer.NewLine();
|
||||
Printer << "}";
|
||||
Printer.NewLine();
|
||||
if (Layout.deepPaddingSize() > 0) {
|
||||
APFloat Pct(100.0 * (double)Layout.deepPaddingSize() / (double)Size);
|
||||
APFloat Pct(100.0 * (double)Layout.deepPaddingSize() /
|
||||
(double)Layout.getClassSize());
|
||||
SmallString<8> PctStr;
|
||||
Pct.toString(PctStr, 4);
|
||||
WithColor(Printer, PDB_ColorItem::Padding).get()
|
||||
@ -129,54 +111,3 @@ void ClassDefinitionDumper::start(const PDBSymbolTypeUDT &Class) {
|
||||
Printer.NewLine();
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
void ClassDefinitionDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
|
||||
if (Printer.IsTypeExcluded(Symbol.getName()))
|
||||
return;
|
||||
|
||||
DumpedAnything = true;
|
||||
Printer.NewLine();
|
||||
TypedefDumper Dumper(Printer);
|
||||
Dumper.start(Symbol);
|
||||
}
|
||||
|
||||
void ClassDefinitionDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
|
||||
|
@ -25,6 +25,7 @@ class BitVector;
|
||||
|
||||
namespace pdb {
|
||||
|
||||
class ClassLayout;
|
||||
class LinePrinter;
|
||||
|
||||
class ClassDefinitionDumper : public PDBSymDumper {
|
||||
@ -33,18 +34,10 @@ public:
|
||||
|
||||
void start(const PDBSymbolTypeUDT &Exe);
|
||||
|
||||
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:
|
||||
bool maybeDumpSymbol(std::unique_ptr<PDBSymbolData> Data,
|
||||
const BitVector &Padding, int &NextUnusedByte);
|
||||
bool maybeDumpSymbol(std::unique_ptr<PDBSymbolFunc> Data);
|
||||
void prettyPrintClassIntro(const ClassLayout &Class);
|
||||
void prettyPrintClassOutro(const ClassLayout &Class);
|
||||
|
||||
bool DumpedAnything = false;
|
||||
LinePrinter &Printer;
|
||||
};
|
||||
|
38
tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
Normal file
38
tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
//===- PrettyClassLayoutGraphicalDumper.h -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PrettyClassLayoutGraphicalDumper.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
PrettyClassLayoutGraphicalDumper::PrettyClassLayoutGraphicalDumper(
|
||||
LinePrinter &P)
|
||||
: PDBSymDumper(true), Printer(P) {}
|
||||
|
||||
bool PrettyClassLayoutGraphicalDumper::start(const ClassLayout &Layout) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void PrettyClassLayoutGraphicalDumper::dump(
|
||||
const PDBSymbolTypeBaseClass &Symbol) {}
|
||||
|
||||
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolData &Symbol) {}
|
||||
|
||||
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeEnum &Symbol) {}
|
||||
|
||||
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolFunc &Symbol) {}
|
||||
|
||||
void PrettyClassLayoutGraphicalDumper::dump(
|
||||
const PDBSymbolTypeTypedef &Symbol) {}
|
||||
|
||||
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
|
||||
|
||||
void PrettyClassLayoutGraphicalDumper::dump(const PDBSymbolTypeVTable &Symbol) {
|
||||
}
|
44
tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h
Normal file
44
tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h
Normal file
@ -0,0 +1,44 @@
|
||||
//===- PrettyClassLayoutGraphicalDumper.h -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TOOLS_LLVMPDBDUMP_PRETTYCLASSLAYOUTGRAPHICALDUMPER_H
|
||||
#define LLVM_TOOLS_LLVMPDBDUMP_PRETTYCLASSLAYOUTGRAPHICALDUMPER_H
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
|
||||
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace pdb {
|
||||
|
||||
class ClassLayout;
|
||||
class LinePrinter;
|
||||
|
||||
class PrettyClassLayoutGraphicalDumper : public PDBSymDumper {
|
||||
public:
|
||||
explicit PrettyClassLayoutGraphicalDumper(LinePrinter &P);
|
||||
|
||||
bool start(const ClassLayout &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:
|
||||
bool DumpedAnything = false;
|
||||
LinePrinter &Printer;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
123
tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp
Normal file
123
tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
//===- PrettyClassLayoutTextDumper.cpp --------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PrettyClassLayoutTextDumper.h"
|
||||
|
||||
#include "LinePrinter.h"
|
||||
#include "PrettyEnumDumper.h"
|
||||
#include "PrettyFunctionDumper.h"
|
||||
#include "PrettyTypedefDumper.h"
|
||||
#include "PrettyVariableDumper.h"
|
||||
#include "llvm-pdbdump.h"
|
||||
|
||||
#include "llvm/DebugInfo/PDB/IPDBSession.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBExtras.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
|
||||
#include "llvm/DebugInfo/PDB/UDTLayout.h"
|
||||
|
||||
#include "llvm/Support/Format.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::pdb;
|
||||
|
||||
PrettyClassLayoutTextDumper::PrettyClassLayoutTextDumper(LinePrinter &P)
|
||||
: PDBSymDumper(true), Printer(P) {}
|
||||
|
||||
bool PrettyClassLayoutTextDumper::start(const ClassLayout &Layout) {
|
||||
if (opts::pretty::ClassFormat ==
|
||||
opts::pretty::ClassDefinitionFormat::Standard) {
|
||||
for (auto &Other : Layout.other_items())
|
||||
Other->dump(*this);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
LayoutItem->getSymbol().dump(*this);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return DumpedAnything;
|
||||
}
|
||||
|
||||
void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {}
|
||||
|
||||
void PrettyClassLayoutTextDumper::dump(const PDBSymbolData &Symbol) {
|
||||
VariableDumper Dumper(Printer);
|
||||
Dumper.start(Symbol);
|
||||
DumpedAnything = true;
|
||||
}
|
||||
|
||||
void PrettyClassLayoutTextDumper::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 PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeVTable &Symbol) {
|
||||
VariableDumper Dumper(Printer);
|
||||
Dumper.start(Symbol);
|
||||
DumpedAnything = true;
|
||||
}
|
||||
|
||||
void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeEnum &Symbol) {
|
||||
if (Printer.IsTypeExcluded(Symbol.getName()))
|
||||
return;
|
||||
|
||||
DumpedAnything = true;
|
||||
Printer.NewLine();
|
||||
EnumDumper Dumper(Printer);
|
||||
Dumper.start(Symbol);
|
||||
}
|
||||
|
||||
void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
|
||||
if (Printer.IsTypeExcluded(Symbol.getName()))
|
||||
return;
|
||||
|
||||
DumpedAnything = true;
|
||||
Printer.NewLine();
|
||||
TypedefDumper Dumper(Printer);
|
||||
Dumper.start(Symbol);
|
||||
}
|
||||
|
||||
void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
|
44
tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h
Normal file
44
tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h
Normal file
@ -0,0 +1,44 @@
|
||||
//===- PrettyClassLayoutTextDumper.h ----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_TOOLS_LLVMPDBDUMP_PRETTYCLASSLAYOUTTEXTDUMPER_H
|
||||
#define LLVM_TOOLS_LLVMPDBDUMP_PRETTYCLASSLAYOUTTEXTDUMPER_H
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
|
||||
#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace pdb {
|
||||
|
||||
class ClassLayout;
|
||||
class LinePrinter;
|
||||
|
||||
class PrettyClassLayoutTextDumper : public PDBSymDumper {
|
||||
public:
|
||||
PrettyClassLayoutTextDumper(LinePrinter &P);
|
||||
|
||||
bool start(const ClassLayout &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:
|
||||
bool DumpedAnything = false;
|
||||
LinePrinter &Printer;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
@ -126,9 +126,10 @@ 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",
|
||||
clEnumValN(ClassDefinitionFormat::Standard, "all-members",
|
||||
"Display all class members including data, constants, "
|
||||
"typedefs, etc"),
|
||||
clEnumValN(ClassDefinitionFormat::Layout, "layout-members",
|
||||
"Only display members that contribute to class size."),
|
||||
clEnumValN(ClassDefinitionFormat::None, "none",
|
||||
"Don't display class definitions")),
|
||||
|
@ -18,7 +18,7 @@ namespace opts {
|
||||
|
||||
namespace pretty {
|
||||
|
||||
enum class ClassDefinitionFormat { None, Layout, Standard };
|
||||
enum class ClassDefinitionFormat { None, Layout, Graphical, Standard };
|
||||
|
||||
extern llvm::cl::opt<bool> Compilands;
|
||||
extern llvm::cl::opt<bool> Symbols;
|
||||
|
Loading…
x
Reference in New Issue
Block a user