[llvm] r301203 - [llvm-pdbdump] Re-write the record layout code to be more resilient.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 24 10:47:25 PDT 2017
Author: zturner
Date: Mon Apr 24 12:47:24 2017
New Revision: 301203
URL: http://llvm.org/viewvc/llvm-project?rev=301203&view=rev
Log:
[llvm-pdbdump] Re-write the record layout code to be more resilient.
This reworks the way virtual bases are handled, and also the way
padding is detected across multiple levels of aggregates, producing
a much more accurate result.
Added:
llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.cpp
llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.pdb (with props)
llvm/trunk/test/tools/llvm-pdbdump/complex-padding-graphical.test
Removed:
llvm/trunk/test/tools/llvm-pdbdump/simple-padding-text.test
Modified:
llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
llvm/trunk/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
llvm/trunk/include/llvm/DebugInfo/PDB/UDTLayout.h
llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp
llvm/trunk/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
llvm/trunk/lib/DebugInfo/PDB/UDTLayout.cpp
llvm/trunk/test/tools/llvm-pdbdump/class-layout.test
llvm/trunk/test/tools/llvm-pdbdump/simple-padding-graphical.test
llvm/trunk/tools/llvm-pdbdump/LinePrinter.cpp
llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h
llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp
llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h
llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp
llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp
llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h
llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h Mon Apr 24 12:47:24 2017
@@ -102,7 +102,8 @@ public:
uint32_t getVirtualBaseDispIndex() const override;
uint32_t getVirtualBaseOffset() const override;
uint32_t getVirtualTableShapeId() const override;
- std::unique_ptr<PDBSymbolTypeVTable> getVirtualBaseTableType() const override;
+ std::unique_ptr<PDBSymbolTypeBuiltin>
+ getVirtualBaseTableType() const override;
PDB_DataKind getDataKind() const override;
PDB_SymType getSymTag() const override;
PDB_UniqueId getGuid() const override;
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h Mon Apr 24 12:47:24 2017
@@ -113,7 +113,7 @@ public:
virtual Variant getValue() const = 0;
virtual uint32_t getVirtualBaseDispIndex() const = 0;
virtual uint32_t getVirtualBaseOffset() const = 0;
- virtual std::unique_ptr<PDBSymbolTypeVTable>
+ virtual std::unique_ptr<PDBSymbolTypeBuiltin>
getVirtualBaseTableType() const = 0;
virtual uint32_t getVirtualTableShapeId() const = 0;
virtual PDB_DataKind getDataKind() const = 0;
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/NativeRawSymbol.h Mon Apr 24 12:47:24 2017
@@ -101,7 +101,8 @@ public:
uint32_t getVirtualBaseDispIndex() const override;
uint32_t getVirtualBaseOffset() const override;
uint32_t getVirtualTableShapeId() const override;
- std::unique_ptr<PDBSymbolTypeVTable> getVirtualBaseTableType() const override;
+ std::unique_ptr<PDBSymbolTypeBuiltin>
+ getVirtualBaseTableType() const override;
PDB_DataKind getDataKind() const override;
PDB_SymType getSymTag() const override;
PDB_UniqueId getGuid() const override;
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/UDTLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/UDTLayout.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/UDTLayout.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/UDTLayout.h Mon Apr 24 12:47:24 2017
@@ -15,6 +15,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
#include <list>
#include <memory>
@@ -32,40 +33,62 @@ class PDBSymbolTypeVTable;
class ClassLayout;
class BaseClassLayout;
-class StorageItemBase;
+class LayoutItemBase;
class UDTLayoutBase;
-class StorageItemBase {
+class LayoutItemBase {
public:
- StorageItemBase(const UDTLayoutBase &Parent, const PDBSymbol &Symbol,
- const std::string &Name, uint32_t OffsetInParent,
- uint32_t Size);
- virtual ~StorageItemBase() {}
+ LayoutItemBase(const UDTLayoutBase *Parent, const PDBSymbol *Symbol,
+ const std::string &Name, uint32_t OffsetInParent,
+ uint32_t Size, bool IsElided);
+ virtual ~LayoutItemBase() {}
- virtual uint32_t deepPaddingSize() const;
+ uint32_t deepPaddingSize() const;
+ virtual uint32_t tailPadding() const;
- const UDTLayoutBase &getParent() const { return Parent; }
+ const UDTLayoutBase *getParent() const { return Parent; }
StringRef getName() const { return Name; }
uint32_t getOffsetInParent() const { return OffsetInParent; }
uint32_t getSize() const { return SizeOf; }
- const PDBSymbol &getSymbol() const { return Symbol; }
+ uint32_t getLayoutSize() const { return LayoutSize; }
+ const PDBSymbol *getSymbol() const { return Symbol; }
+ const BitVector &usedBytes() const { return UsedBytes; }
+ bool isElided() const { return IsElided; }
+ virtual bool isVBPtr() const { return false; }
+
+ uint32_t containsOffset(uint32_t Off) const {
+ uint32_t Begin = getOffsetInParent();
+ uint32_t End = Begin + getSize();
+ return (Off >= Begin && Off < End);
+ }
protected:
- const UDTLayoutBase &Parent;
- const PDBSymbol &Symbol;
+ const PDBSymbol *Symbol = nullptr;
+ const UDTLayoutBase *Parent = nullptr;
BitVector UsedBytes;
std::string Name;
uint32_t OffsetInParent = 0;
uint32_t SizeOf = 0;
+ uint32_t LayoutSize = 0;
+ bool IsElided = false;
+};
+
+class VBPtrLayoutItem : public LayoutItemBase {
+public:
+ VBPtrLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset,
+ uint32_t Size);
+ virtual bool isVBPtr() const { return true; }
+
+private:
+ std::unique_ptr<PDBSymbolTypeBuiltin> Type;
};
-class DataMemberLayoutItem : public StorageItemBase {
+class DataMemberLayoutItem : public LayoutItemBase {
public:
DataMemberLayoutItem(const UDTLayoutBase &Parent,
std::unique_ptr<PDBSymbolData> DataMember);
- virtual uint32_t deepPaddingSize() const;
-
const PDBSymbolData &getDataMember();
bool hasUDTLayout() const;
const ClassLayout &getUDTLayout() const;
@@ -75,77 +98,73 @@ private:
std::unique_ptr<ClassLayout> UdtLayout;
};
-class VTableLayoutItem : public StorageItemBase {
+class VTableLayoutItem : public LayoutItemBase {
public:
VTableLayoutItem(const UDTLayoutBase &Parent,
std::unique_ptr<PDBSymbolTypeVTable> VTable);
- ArrayRef<PDBSymbolFunc *> funcs() const { return VTableFuncs; }
uint32_t getElementSize() const { return ElementSize; }
- void setFunction(uint32_t Index, PDBSymbolFunc &Func) {
- VTableFuncs[Index] = &Func;
- }
-
private:
uint32_t ElementSize = 0;
- std::unique_ptr<PDBSymbolTypeVTableShape> Shape;
std::unique_ptr<PDBSymbolTypeVTable> VTable;
- std::vector<PDBSymbolFunc *> VTableFuncs;
};
-class UDTLayoutBase {
+class UDTLayoutBase : public LayoutItemBase {
template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>;
public:
- UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name,
- uint32_t Size);
-
- uint32_t shallowPaddingSize() const;
- uint32_t deepPaddingSize() const;
-
- const BitVector &usedBytes() const { return UsedBytes; }
+ UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
+ const std::string &Name, uint32_t OffsetInParent, uint32_t Size,
+ bool IsElided);
- uint32_t getClassSize() const { return SizeOf; }
+ uint32_t tailPadding() const override;
- ArrayRef<std::unique_ptr<StorageItemBase>> layout_items() const {
- return ChildStorage;
- }
-
- VTableLayoutItem *findVTableAtOffset(uint32_t RelativeOffset);
+ ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; }
- StringRef getUDTName() const { return Name; }
+ ArrayRef<BaseClassLayout *> bases() const { return AllBases; }
+ ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; }
+ ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; }
- ArrayRef<BaseClassLayout *> bases() const { return BaseClasses; }
- ArrayRef<std::unique_ptr<PDBSymbolTypeBaseClass>> vbases() const {
- return VirtualBases;
- }
+ uint32_t directVirtualBaseCount() const { return DirectVBaseCount; }
ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; }
ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; }
- const PDBSymbol &getSymbolBase() const { return SymbolBase; }
-
protected:
+ bool hasVBPtrAtOffset(uint32_t Off) const;
void initializeChildren(const PDBSymbol &Sym);
- void addChildToLayout(std::unique_ptr<StorageItemBase> Child);
- void addVirtualOverride(PDBSymbolFunc &Func);
- void addVirtualIntro(PDBSymbolFunc &Func);
+ void addChildToLayout(std::unique_ptr<LayoutItemBase> Child);
- const PDBSymbol &SymbolBase;
- std::string Name;
- uint32_t SizeOf = 0;
+ uint32_t DirectVBaseCount = 0;
- BitVector UsedBytes;
UniquePtrVector<PDBSymbol> Other;
UniquePtrVector<PDBSymbolFunc> Funcs;
- UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBases;
- UniquePtrVector<StorageItemBase> ChildStorage;
- std::vector<std::list<StorageItemBase *>> ChildrenPerByte;
- std::vector<BaseClassLayout *> BaseClasses;
+ UniquePtrVector<LayoutItemBase> ChildStorage;
+ std::vector<LayoutItemBase *> LayoutItems;
+
+ std::vector<BaseClassLayout *> AllBases;
+ ArrayRef<BaseClassLayout *> NonVirtualBases;
+ ArrayRef<BaseClassLayout *> VirtualBases;
+
VTableLayoutItem *VTable = nullptr;
+ VBPtrLayoutItem *VBPtr = nullptr;
+};
+
+class BaseClassLayout : public UDTLayoutBase {
+public:
+ BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent,
+ bool Elide, std::unique_ptr<PDBSymbolTypeBaseClass> Base);
+
+ const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
+ bool isVirtualBase() const { return IsVirtualBase; }
+ bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; }
+
+private:
+ std::unique_ptr<PDBSymbolTypeBaseClass> Base;
+ bool IsVirtualBase;
};
class ClassLayout : public UDTLayoutBase {
@@ -161,19 +180,6 @@ private:
std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage;
const PDBSymbolTypeUDT &UDT;
};
-
-class BaseClassLayout : public UDTLayoutBase, public StorageItemBase {
-public:
- BaseClassLayout(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeBaseClass> Base);
-
- const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
- bool isVirtualBase() const { return IsVirtualBase; }
-
-private:
- std::unique_ptr<PDBSymbolTypeBaseClass> Base;
- bool IsVirtualBase;
-};
}
} // namespace llvm
Modified: llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp Mon Apr 24 12:47:24 2017
@@ -14,6 +14,7 @@
#include "llvm/DebugInfo/PDB/DIA/DIAEnumSymbols.h"
#include "llvm/DebugInfo/PDB/DIA/DIASession.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
@@ -720,7 +721,7 @@ uint32_t DIARawSymbol::getVirtualTableSh
return PrivateGetDIAValue(Symbol, &IDiaSymbol::get_virtualTableShapeId);
}
-std::unique_ptr<PDBSymbolTypeVTable>
+std::unique_ptr<PDBSymbolTypeBuiltin>
DIARawSymbol::getVirtualBaseTableType() const {
CComPtr<IDiaSymbol> TableType;
if (FAILED(Symbol->get_virtualBaseTableType(&TableType)) || !TableType)
@@ -729,7 +730,7 @@ DIARawSymbol::getVirtualBaseTableType()
auto RawVT = llvm::make_unique<DIARawSymbol>(Session, TableType);
auto Pointer =
llvm::make_unique<PDBSymbolTypePointer>(Session, std::move(RawVT));
- return unique_dyn_cast<PDBSymbolTypeVTable>(Pointer->getPointeeType());
+ return unique_dyn_cast<PDBSymbolTypeBuiltin>(Pointer->getPointeeType());
}
PDB_DataKind DIARawSymbol::getDataKind() const {
Modified: llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/DIA/DIASession.cpp Mon Apr 24 12:47:24 2017
@@ -21,12 +21,22 @@
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace llvm::pdb;
-static Error ErrorFromHResult(HRESULT Result, StringRef Context) {
+template <typename... Ts>
+static Error ErrorFromHResult(HRESULT Result, const char *Str, Ts &&... Args) {
+ SmallString<64> MessageStorage;
+ StringRef Context;
+ if (sizeof...(Args) > 0) {
+ MessageStorage = formatv(Str, std::forward<Ts>(Args)...).str();
+ Context = MessageStorage;
+ } else
+ Context = Str;
+
switch (Result) {
case E_PDB_NOT_FOUND:
return make_error<GenericError>(generic_error_code::invalid_path, Context);
@@ -95,8 +105,9 @@ Error DIASession::createFromPdb(StringRe
const wchar_t *Path16Str = reinterpret_cast<const wchar_t*>(Path16.data());
HRESULT HR;
- if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str)))
- return ErrorFromHResult(HR, "Calling loadDataFromPdb");
+ if (FAILED(HR = DiaDataSource->loadDataFromPdb(Path16Str))) {
+ return ErrorFromHResult(HR, "Calling loadDataFromPdb {0}", Path);
+ }
if (FAILED(HR = DiaDataSource->openSession(&DiaSession)))
return ErrorFromHResult(HR, "Calling openSession");
Modified: llvm/trunk/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp Mon Apr 24 12:47:24 2017
@@ -13,6 +13,7 @@
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
#include "llvm/Support/ConvertUTF.h"
@@ -320,7 +321,7 @@ uint32_t NativeRawSymbol::getVirtualTabl
return 0;
}
-std::unique_ptr<PDBSymbolTypeVTable>
+std::unique_ptr<PDBSymbolTypeBuiltin>
NativeRawSymbol::getVirtualBaseTableType() const {
return nullptr;
}
Modified: llvm/trunk/lib/DebugInfo/PDB/UDTLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/UDTLayout.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/UDTLayout.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/UDTLayout.cpp Mon Apr 24 12:47:24 2017
@@ -16,6 +16,7 @@
#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
@@ -39,36 +40,48 @@ static uint32_t getTypeLength(const PDBS
return RawType.getLength();
}
-StorageItemBase::StorageItemBase(const UDTLayoutBase &Parent,
- const PDBSymbol &Symbol,
- const std::string &Name,
- uint32_t OffsetInParent, uint32_t Size)
- : Parent(Parent), Symbol(Symbol), Name(Name),
- OffsetInParent(OffsetInParent), SizeOf(Size) {
+LayoutItemBase::LayoutItemBase(const UDTLayoutBase *Parent,
+ const PDBSymbol *Symbol, const std::string &Name,
+ uint32_t OffsetInParent, uint32_t Size,
+ bool IsElided)
+ : Symbol(Symbol), Parent(Parent), Name(Name),
+ OffsetInParent(OffsetInParent), SizeOf(Size), LayoutSize(Size),
+ IsElided(IsElided) {
UsedBytes.resize(SizeOf, true);
}
-uint32_t StorageItemBase::deepPaddingSize() const {
- // sizeof(Field) - sizeof(typeof(Field)) is trailing padding.
- return SizeOf - getTypeLength(Symbol);
+uint32_t LayoutItemBase::deepPaddingSize() const {
+ return UsedBytes.size() - UsedBytes.count();
+}
+
+uint32_t LayoutItemBase::tailPadding() const {
+ int Last = UsedBytes.find_last();
+
+ return UsedBytes.size() - (Last + 1);
}
+
DataMemberLayoutItem::DataMemberLayoutItem(
- const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> DataMember)
- : StorageItemBase(Parent, *DataMember, DataMember->getName(),
- DataMember->getOffset(), getTypeLength(*DataMember)),
- DataMember(std::move(DataMember)) {
- auto Type = this->DataMember->getType();
+ const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> Member)
+ : LayoutItemBase(&Parent, Member.get(), Member->getName(),
+ Member->getOffset(), getTypeLength(*Member), false),
+ DataMember(std::move(Member)) {
+ auto Type = DataMember->getType();
if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
- // UDT data members might have padding in between fields, but otherwise
- // a member should occupy its entire storage.
- UsedBytes.resize(SizeOf, false);
UdtLayout = llvm::make_unique<ClassLayout>(std::move(UDT));
+ UsedBytes = UdtLayout->usedBytes();
}
}
+VBPtrLayoutItem::VBPtrLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeBuiltin> Sym,
+ uint32_t Offset, uint32_t Size)
+ : LayoutItemBase(&Parent, Sym.get(), "<vbptr>", Offset, Size, false),
+ Type(std::move(Sym)) {
+}
+
const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
- return *dyn_cast<PDBSymbolData>(&Symbol);
+ return *dyn_cast<PDBSymbolData>(Symbol);
}
bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
@@ -77,36 +90,43 @@ const ClassLayout &DataMemberLayoutItem:
return *UdtLayout;
}
-uint32_t DataMemberLayoutItem::deepPaddingSize() const {
- uint32_t Result = StorageItemBase::deepPaddingSize();
- if (UdtLayout)
- Result += UdtLayout->deepPaddingSize();
- return Result;
-}
-
VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeVTable> VTable)
- : StorageItemBase(Parent, *VTable, "<vtbl>", 0, getTypeLength(*VTable)),
- VTable(std::move(VTable)) {
- auto VTableType = cast<PDBSymbolTypePointer>(this->VTable->getType());
+ std::unique_ptr<PDBSymbolTypeVTable> VT)
+ : LayoutItemBase(&Parent, VT.get(), "<vtbl>", 0, getTypeLength(*VT), false),
+ VTable(std::move(VT)) {
+ auto VTableType = cast<PDBSymbolTypePointer>(VTable->getType());
ElementSize = VTableType->getLength();
-
- Shape =
- unique_dyn_cast<PDBSymbolTypeVTableShape>(VTableType->getPointeeType());
- if (Shape)
- VTableFuncs.resize(Shape->getCount());
}
-UDTLayoutBase::UDTLayoutBase(const PDBSymbol &Symbol, const std::string &Name,
- uint32_t Size)
- : SymbolBase(Symbol), Name(Name), SizeOf(Size) {
- UsedBytes.resize(Size);
- ChildrenPerByte.resize(Size);
- initializeChildren(Symbol);
+UDTLayoutBase::UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
+ const std::string &Name, uint32_t OffsetInParent,
+ uint32_t Size, bool IsElided)
+ : LayoutItemBase(Parent, &Sym, Name, OffsetInParent, Size, IsElided) {
+ // UDT storage comes from a union of all the children's storage, so start out
+ // uninitialized.
+ UsedBytes.reset(0, Size);
+
+ initializeChildren(Sym);
+ if (LayoutSize < Size)
+ UsedBytes.resize(LayoutSize);
+}
+
+uint32_t UDTLayoutBase::tailPadding() const {
+ uint32_t Abs = LayoutItemBase::tailPadding();
+ if (!LayoutItems.empty()) {
+ const LayoutItemBase *Back = LayoutItems.back();
+ uint32_t ChildPadding = Back->LayoutItemBase::tailPadding();
+ if (Abs < ChildPadding)
+ Abs = 0;
+ else
+ Abs -= ChildPadding;
+ }
+ return Abs;
}
ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
- : UDTLayoutBase(UDT, UDT.getName(), UDT.getLength()), UDT(UDT) {}
+ : UDTLayoutBase(nullptr, UDT, UDT.getName(), 0, UDT.getLength(), false),
+ UDT(UDT) {}
ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
: ClassLayout(*UDT) {
@@ -114,23 +134,17 @@ ClassLayout::ClassLayout(std::unique_ptr
}
BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeBaseClass> Base)
- : UDTLayoutBase(*Base, Base->getName(), Base->getLength()),
- StorageItemBase(Parent, *Base, Base->getName(), Base->getOffset(),
- Base->getLength()),
- Base(std::move(Base)) {
- IsVirtualBase = this->Base->isVirtualBaseClass();
-}
-
-uint32_t UDTLayoutBase::shallowPaddingSize() const {
- return UsedBytes.size() - UsedBytes.count();
-}
-
-uint32_t UDTLayoutBase::deepPaddingSize() const {
- uint32_t Result = shallowPaddingSize();
- for (auto &Child : ChildStorage)
- Result += Child->deepPaddingSize();
- return Result;
+ uint32_t OffsetInParent, bool Elide,
+ std::unique_ptr<PDBSymbolTypeBaseClass> B)
+ : UDTLayoutBase(&Parent, *B, B->getName(), OffsetInParent, B->getLength(),
+ Elide),
+ Base(std::move(B)) {
+ if (isEmptyBase()) {
+ // Special case an empty base so that it doesn't get treated as padding.
+ UsedBytes.resize(1);
+ UsedBytes.set(0);
+ }
+ IsVirtualBase = Base->isVirtualBaseClass();
}
void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
@@ -138,15 +152,16 @@ void UDTLayoutBase::initializeChildren(c
// followed by functions, followed by other. This ordering is necessary
// so that bases and vtables get initialized before any functions which
// may override them.
-
UniquePtrVector<PDBSymbolTypeBaseClass> Bases;
UniquePtrVector<PDBSymbolTypeVTable> VTables;
UniquePtrVector<PDBSymbolData> Members;
+ UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBaseSyms;
+
auto Children = Sym.findAllChildren();
while (auto Child = Children->getNext()) {
if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) {
if (Base->isVirtualBaseClass())
- VirtualBases.push_back(std::move(Base));
+ VirtualBaseSyms.push_back(std::move(Base));
else
Bases.push_back(std::move(Base));
}
@@ -164,20 +179,33 @@ void UDTLayoutBase::initializeChildren(c
Other.push_back(std::move(Child));
}
+ // We don't want to have any re-allocations in the list of bases, so make
+ // sure to reserve enough space so that our ArrayRefs don't get invalidated.
+ AllBases.reserve(Bases.size() + VirtualBaseSyms.size());
+
+ // Only add non-virtual bases to the class first. Only at the end of the
+ // class, after all non-virtual bases and data members have been added do we
+ // add virtual bases. This way the offsets are correctly aligned when we go
+ // to lay out virtual bases.
for (auto &Base : Bases) {
- auto BL = llvm::make_unique<BaseClassLayout>(*this, std::move(Base));
- BaseClasses.push_back(BL.get());
+ uint32_t Offset = Base->getOffset();
+ // Non-virtual bases never get elided.
+ auto BL = llvm::make_unique<BaseClassLayout>(*this, Offset, false,
+ std::move(Base));
+ AllBases.push_back(BL.get());
addChildToLayout(std::move(BL));
}
+ NonVirtualBases = AllBases;
- for (auto &VT : VTables) {
- auto VTLayout = llvm::make_unique<VTableLayoutItem>(*this, std::move(VT));
+ assert(VTables.size() <= 1);
+ if (!VTables.empty()) {
+ auto VTLayout =
+ llvm::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
VTable = VTLayout.get();
addChildToLayout(std::move(VTLayout));
- continue;
}
for (auto &Data : Members) {
@@ -186,150 +214,74 @@ void UDTLayoutBase::initializeChildren(c
addChildToLayout(std::move(DM));
}
- for (auto &Func : Funcs) {
- if (!Func->isVirtual())
- continue;
+ // Make sure add virtual bases before adding functions, since functions may be
+ // overrides of virtual functions declared in a virtual base, so the VTables
+ // and virtual intros need to be correctly initialized.
+ for (auto &VB : VirtualBaseSyms) {
+ int VBPO = VB->getVirtualBasePointerOffset();
+ if (!hasVBPtrAtOffset(VBPO)) {
+ if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
+ auto VBPL = llvm::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
+ VBPO, VBP->getLength());
+ VBPtr = VBPL.get();
+ addChildToLayout(std::move(VBPL));
+ }
+ }
- if (Func->isIntroVirtualFunction())
- addVirtualIntro(*Func);
- else
- addVirtualOverride(*Func);
+ // Virtual bases always go at the end. So just look for the last place we
+ // ended when writing something, and put our virtual base there.
+ // Note that virtual bases get elided unless this is a top-most derived
+ // class.
+ uint32_t Offset = UsedBytes.find_last() + 1;
+ bool Elide = (Parent != nullptr);
+ auto BL =
+ llvm::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
+ AllBases.push_back(BL.get());
+
+ // Only lay this virtual base out directly inside of *this* class if this
+ // is a top-most derived class. Keep track of it regardless, but only
+ // physically lay it out if it's a topmost derived class.
+ addChildToLayout(std::move(BL));
}
+ VirtualBases = makeArrayRef(AllBases).drop_front(NonVirtualBases.size());
+
+ if (Parent != nullptr)
+ LayoutSize = UsedBytes.find_last() + 1;
}
-void UDTLayoutBase::addVirtualIntro(PDBSymbolFunc &Func) {
- // Kind of a hack, but we prefer the more common destructor name that people
- // are familiar with, e.g. ~ClassName. It seems there are always both and
- // the vector deleting destructor overwrites the nice destructor, so just
- // ignore the vector deleting destructor.
- if (Func.getName() == "__vecDelDtor")
- return;
-
- if (!VTable) {
- // FIXME: Handle this. What's most likely happening is we have an intro
- // virtual in a derived class where the base also has an intro virtual.
- // In this case the vtable lives in the base. What we really need is
- // for each UDTLayoutBase to contain a list of all its vtables, and
- // then propagate this list up the hierarchy so that derived classes have
- // direct access to their bases' vtables.
- return;
+bool UDTLayoutBase::hasVBPtrAtOffset(uint32_t Off) const {
+ if (VBPtr && VBPtr->getOffsetInParent() == Off)
+ return true;
+ for (BaseClassLayout *BL : AllBases) {
+ if (BL->hasVBPtrAtOffset(Off - BL->getOffsetInParent()))
+ return true;
}
-
- uint32_t Stride = VTable->getElementSize();
-
- uint32_t Index = Func.getVirtualBaseOffset();
- assert(Index % Stride == 0);
- Index /= Stride;
-
- VTable->setFunction(Index, Func);
+ return false;
}
-VTableLayoutItem *UDTLayoutBase::findVTableAtOffset(uint32_t RelativeOffset) {
- if (VTable && VTable->getOffsetInParent() == RelativeOffset)
- return VTable;
- for (auto Base : BaseClasses) {
- uint32_t Begin = Base->getOffsetInParent();
- uint32_t End = Begin + Base->getSize();
- if (RelativeOffset < Begin || RelativeOffset >= End)
- continue;
+void UDTLayoutBase::addChildToLayout(std::unique_ptr<LayoutItemBase> Child) {
+ uint32_t Begin = Child->getOffsetInParent();
- return Base->findVTableAtOffset(RelativeOffset - Begin);
- }
+ if (!Child->isElided()) {
+ BitVector ChildBytes = Child->usedBytes();
- return nullptr;
-}
+ // Suppose the child occupies 4 bytes starting at offset 12 in a 32 byte
+ // class. When we call ChildBytes.resize(32), the Child's storage will
+ // still begin at offset 0, so we need to shift it left by offset bytes
+ // to get it into the right position.
+ ChildBytes.resize(UsedBytes.size());
+ ChildBytes <<= Child->getOffsetInParent();
+ UsedBytes |= ChildBytes;
+
+ if (ChildBytes.count() > 0) {
+ auto Loc = std::upper_bound(LayoutItems.begin(), LayoutItems.end(), Begin,
+ [](uint32_t Off, const LayoutItemBase *Item) {
+ return (Off < Item->getOffsetInParent());
+ });
-void UDTLayoutBase::addVirtualOverride(PDBSymbolFunc &Func) {
- auto Signature = Func.getSignature();
- auto ThisAdjust = Signature->getThisAdjust();
- // ThisAdjust tells us which VTable we're looking for. Specifically, it's
- // the offset into the current class of the VTable we're looking for. So
- // look through the base hierarchy until we find one such that
- // AbsoluteOffset(VT) == ThisAdjust
- VTableLayoutItem *VT = findVTableAtOffset(ThisAdjust);
- if (!VT) {
- // FIXME: There really should be a vtable here. If there's not it probably
- // means that the vtable is in a virtual base, which we don't yet support.
- assert(!VirtualBases.empty());
- return;
- }
- int32_t OverrideIndex = -1;
- // Now we've found the VTable. Func will not have a virtual base offset set,
- // so instead we need to compare names and signatures. We iterate each item
- // in the VTable. All items should already have non null entries because they
- // were initialized by the intro virtual, which was guaranteed to come before.
- for (auto ItemAndIndex : enumerate(VT->funcs())) {
- auto Item = ItemAndIndex.value();
- assert(Item);
- // If the name doesn't match, this isn't an override. Note that it's ok
- // for the return type to not match (e.g. co-variant return).
- if (Item->getName() != Func.getName()) {
- if (Item->isDestructor() && Func.isDestructor()) {
- OverrideIndex = ItemAndIndex.index();
- break;
- }
- continue;
- }
- // Now make sure it's the right overload. Get the signature of the existing
- // vtable method and make sure it has the same arglist and the same cv-ness.
- auto ExistingSig = Item->getSignature();
- if (ExistingSig->isConstType() != Signature->isConstType())
- continue;
- if (ExistingSig->isVolatileType() != Signature->isVolatileType())
- continue;
-
- // Now compare arguments. Using the raw bytes of the PDB this would be
- // trivial
- // because there is an ArgListId and they should be identical. But DIA
- // doesn't
- // expose this, so the best we can do is iterate each argument and confirm
- // that
- // each one is identical.
- if (ExistingSig->getCount() != Signature->getCount())
- continue;
- bool IsMatch = true;
- auto ExistingEnumerator = ExistingSig->getArguments();
- auto NewEnumerator = Signature->getArguments();
- for (uint32_t I = 0; I < ExistingEnumerator->getChildCount(); ++I) {
- auto ExistingArg = ExistingEnumerator->getNext();
- auto NewArg = NewEnumerator->getNext();
- if (ExistingArg->getSymIndexId() != NewArg->getSymIndexId()) {
- IsMatch = false;
- break;
- }
+ LayoutItems.insert(Loc, Child.get());
}
- if (!IsMatch)
- continue;
-
- // It's a match! Stick the new function into the VTable.
- OverrideIndex = ItemAndIndex.index();
- break;
- }
- if (OverrideIndex == -1) {
- // FIXME: This is probably due to one of the other FIXMEs in this file.
- return;
}
- VT->setFunction(OverrideIndex, Func);
-}
-
-void UDTLayoutBase::addChildToLayout(std::unique_ptr<StorageItemBase> Child) {
- uint32_t Begin = Child->getOffsetInParent();
- uint32_t End = Begin + Child->getSize();
- // Due to the empty base optimization, End might point outside the bounds of
- // the parent class. If that happens, just clamp the value.
- End = std::min(End, getClassSize());
-
- UsedBytes.set(Begin, End);
- while (Begin != End) {
- ChildrenPerByte[Begin].push_back(Child.get());
- ++Begin;
- }
-
- auto Loc = std::upper_bound(
- ChildStorage.begin(), ChildStorage.end(), Begin,
- [](uint32_t Off, const std::unique_ptr<StorageItemBase> &Item) {
- return Off < Item->getOffsetInParent();
- });
- ChildStorage.insert(Loc, std::move(Child));
+ ChildStorage.push_back(std::move(Child));
}
\ No newline at end of file
Added: llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.cpp?rev=301203&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.cpp (added)
+++ llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.cpp Mon Apr 24 12:47:24 2017
@@ -0,0 +1,48 @@
+// Compile with "cl /c /Zi /GR- ComplexPaddingTest.cpp"
+// Link with "link ComplexPaddingTest.obj /debug /nodefaultlib /entry:main"
+
+#include <stdint.h>
+
+extern "C" using at_exit_handler = void();
+
+int atexit(at_exit_handler handler) { return 0; }
+
+struct TestVB {
+ static void operator delete(void *ptr, size_t sz) {}
+ virtual ~TestVB() {}
+ virtual void IntroFunction1() {}
+ int X;
+} A;
+
+struct TestNVB {
+ static void operator delete(void *ptr, size_t sz) {}
+ virtual ~TestNVB() {}
+ virtual void IntroFunction2() {}
+ int Y;
+} B;
+
+struct TestVBLayout
+ : public virtual TestVB,
+ public TestNVB {
+ static void operator delete(void *ptr, size_t sz) {}
+ int Z;
+} C;
+
+struct TestIVBBase : public virtual TestVB {
+ int A;
+} D;
+
+struct TestIVBDerived : public TestIVBBase {
+ int B;
+} E;
+
+struct TestIVBMergedDerived
+ : public virtual TestVB,
+ public TestIVBBase {
+ int B;
+} F;
+
+int main(int argc, char **argv) {
+
+ return 0;
+}
Added: llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.pdb
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.pdb?rev=301203&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-pdbdump/Inputs/ComplexPaddingTest.pdb
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Modified: llvm/trunk/test/tools/llvm-pdbdump/class-layout.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/class-layout.test?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/class-layout.test (original)
+++ llvm/trunk/test/tools/llvm-pdbdump/class-layout.test Mon Apr 24 12:47:24 2017
@@ -36,9 +36,8 @@
; BASE_CLASS_D: ---TYPES---
; BASE_CLASS_D: class BaseClassTest::D [sizeof = 8]
-; BASE_CLASS_D-DAG: protected BaseClassTest::B
-; BASE_CLASS_D-DAG: private BaseClassTest::C
-; BASE_CLASS_D-DAG: protected virtual BaseClassTest::A
+; BASE_CLASS_D-NEXT: protected BaseClassTest::B
+; BASE_CLASS_D-NEXT: private BaseClassTest::C
; UDT_KIND_TEST: ---TYPES---
; UDT_KIND_TEST-DAG: union UdtKindTest::C [sizeof = 1] {}
Added: llvm/trunk/test/tools/llvm-pdbdump/complex-padding-graphical.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/complex-padding-graphical.test?rev=301203&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/complex-padding-graphical.test (added)
+++ llvm/trunk/test/tools/llvm-pdbdump/complex-padding-graphical.test Mon Apr 24 12:47:24 2017
@@ -0,0 +1,53 @@
+; RUN: llvm-pdbdump pretty -classes -class-definitions=graphical \
+; RUN: -include-types=Test %p/Inputs/ComplexPaddingTest.pdb > %t
+
+; RUN: FileCheck -input-file=%t %s -check-prefix=DIRECT_VB_ONLY
+; RUN: FileCheck -input-file=%t %s -check-prefix=DIRECT_VB_AND_NON_VB
+; RUN: FileCheck -input-file=%t %s -check-prefix=INDIRECT_VB
+; RUN: FileCheck -input-file=%t %s -check-prefix=INDIRECT_AND_DIRECT_VB
+
+
+; DIRECT_VB_ONLY: struct TestIVBBase [sizeof = 16]
+; DIRECT_VB_ONLY-NEXT: : public virtual TestVB {
+; DIRECT_VB_ONLY-NEXT: vbptr +0x00 [sizeof=4]
+; DIRECT_VB_ONLY-NEXT: data +0x04 [sizeof=4] int A
+; DIRECT_VB_ONLY-NEXT: vbase +0x08 [sizeof=8] TestVB
+; DIRECT_VB_ONLY-NEXT: vfptr +0x08 [sizeof=4]
+; DIRECT_VB_ONLY-NEXT: data +0x0c [sizeof=4] int X
+; DIRECT_VB_ONLY-NEXT: }
+
+DIRECT_VB_AND_NON_VB: struct TestVBLayout [sizeof = 24]
+DIRECT_VB_AND_NON_VB-NEXT: : public TestNVB
+DIRECT_VB_AND_NON_VB-NEXT: , public virtual TestVB {
+DIRECT_VB_AND_NON_VB-NEXT: base +0x00 [sizeof=8] TestNVB
+DIRECT_VB_AND_NON_VB-NEXT: vfptr +0x00 [sizeof=4]
+DIRECT_VB_AND_NON_VB-NEXT: data +0x04 [sizeof=4] int Y
+DIRECT_VB_AND_NON_VB-NEXT: vbptr +0x08 [sizeof=4]
+DIRECT_VB_AND_NON_VB-NEXT: data +0x0c [sizeof=4] int Z
+DIRECT_VB_AND_NON_VB-NEXT: vbase +0x10 [sizeof=8] TestVB
+DIRECT_VB_AND_NON_VB-NEXT: vfptr +0x10 [sizeof=4]
+DIRECT_VB_AND_NON_VB-NEXT: data +0x14 [sizeof=4] int X
+DIRECT_VB_AND_NON_VB-NEXT: }
+
+INDIRECT_VB: struct TestIVBDerived [sizeof = 20]
+INDIRECT_VB-NEXT: : public TestIVBBase {
+INDIRECT_VB-NEXT: base +0x00 [sizeof=8] TestIVBBase
+INDIRECT_VB-NEXT: vbptr +0x00 [sizeof=4]
+INDIRECT_VB-NEXT: data +0x04 [sizeof=4] int A
+INDIRECT_VB-NEXT: data +0x08 [sizeof=4] int B
+INDIRECT_VB-NEXT: ivbase +0x0c [sizeof=8] TestVB
+INDIRECT_VB-NEXT: vfptr +0x0c [sizeof=4]
+INDIRECT_VB-NEXT: data +0x10 [sizeof=4] int X
+INDIRECT_VB-NEXT: }
+
+INDIRECT_AND_DIRECT_VB: struct TestIVBMergedDerived [sizeof = 20]
+INDIRECT_AND_DIRECT_VB-NEXT: : public TestIVBBase
+INDIRECT_AND_DIRECT_VB-NEXT: , public virtual TestVB {
+INDIRECT_AND_DIRECT_VB-NEXT: base +0x00 [sizeof=8] TestIVBBase
+INDIRECT_AND_DIRECT_VB-NEXT: vbptr +0x00 [sizeof=4]
+INDIRECT_AND_DIRECT_VB-NEXT: data +0x04 [sizeof=4] int A
+INDIRECT_AND_DIRECT_VB-NEXT: data +0x08 [sizeof=4] int B
+INDIRECT_AND_DIRECT_VB-NEXT: vbase +0x0c [sizeof=8] TestVB
+INDIRECT_AND_DIRECT_VB-NEXT: vfptr +0x0c [sizeof=4]
+INDIRECT_AND_DIRECT_VB-NEXT: data +0x10 [sizeof=4] int X
+INDIRECT_AND_DIRECT_VB-NEXT: }
Modified: llvm/trunk/test/tools/llvm-pdbdump/simple-padding-graphical.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/simple-padding-graphical.test?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/simple-padding-graphical.test (original)
+++ llvm/trunk/test/tools/llvm-pdbdump/simple-padding-graphical.test Mon Apr 24 12:47:24 2017
@@ -71,7 +71,6 @@
; VFPTR: struct SimplePadVfptr [sizeof = 8] {
; VFPTR-NEXT: vfptr +0x00 [sizeof=4]
-; VFPTR-NEXT: [0] &SimplePadVfptr::~SimplePadVfptr
; VFPTR-NEXT: data +0x04 [sizeof=4] int X
; VFPTR-NEXT: }
@@ -89,15 +88,15 @@
; MULTIPLE_INHERIT2: SimplePadMultiInherit2 [sizeof = 16]
; MULTIPLE_INHERIT2-NEXT: : public SimplePadFields1
; MULTIPLE_INHERIT2-NEXT: , public SimplePadFields2 {
-; MULTIPLE_INHERIT2-NEXT: base +0x00 [sizeof=4] SimplePadFields1
+; MULTIPLE_INHERIT2-NEXT: base +0x00 [sizeof=3] SimplePadFields1
; MULTIPLE_INHERIT2-NEXT: data +0x00 [sizeof=1] char A
; MULTIPLE_INHERIT2-NEXT: data +0x01 [sizeof=1] char B
; MULTIPLE_INHERIT2-NEXT: data +0x02 [sizeof=1] char C
-; MULTIPLE_INHERIT2-NEXT: <padding> (1 bytes)
-; MULTIPLE_INHERIT2-NEXT: base +0x04 [sizeof=8] SimplePadFields2
+; MULTIPLE_INHERIT2-NEXT: <padding> (1 bytes)
+; MULTIPLE_INHERIT2-NEXT: base +0x04 [sizeof=5] SimplePadFields2
; MULTIPLE_INHERIT2-NEXT: data +0x04 [sizeof=4] int Y
; MULTIPLE_INHERIT2-NEXT: data +0x08 [sizeof=1] char X
-; MULTIPLE_INHERIT2-NEXT: <padding> (3 bytes)
+; MULTIPLE_INHERIT2-NEXT: <padding> (3 bytes)
; MULTIPLE_INHERIT2-NEXT: data +0x0c [sizeof=4] int X
; MULTIPLE_INHERIT2-NEXT: }
Removed: llvm/trunk/test/tools/llvm-pdbdump/simple-padding-text.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/simple-padding-text.test?rev=301202&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/simple-padding-text.test (original)
+++ llvm/trunk/test/tools/llvm-pdbdump/simple-padding-text.test (removed)
@@ -1,94 +0,0 @@
-; 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
-; RUN: FileCheck -input-file=%t %s -check-prefix=UNION
-; RUN: FileCheck -input-file=%t %s -check-prefix=NESTED_UNION
-; RUN: FileCheck -input-file=%t %s -check-prefix=PAD_FROM_FIELDS1
-; RUN: FileCheck -input-file=%t %s -check-prefix=PAD_FROM_FIELDS2
-; RUN: FileCheck -input-file=%t %s -check-prefix=NO_PAD_IN_BASE
-; RUN: FileCheck -input-file=%t %s -check-prefix=PAD_IN_DERIVED
-; RUN: FileCheck -input-file=%t %s -check-prefix=EMPTY_BASE
-; RUN: FileCheck -input-file=%t %s -check-prefix=VFPTR
-; RUN: FileCheck -input-file=%t %s -check-prefix=MULTIPLE_INHERIT
-; RUN: FileCheck -input-file=%t %s -check-prefix=MULTIPLE_INHERIT2
-; RUN: FileCheck -input-file=%t %s -check-prefix=DEEP_INHERIT
-; RUN: FileCheck -input-file=%t %s -check-prefix=AGGREGATE
-
-; NO_PADDING: struct SimplePadNoPadding [sizeof = 8] {
-; NO_PADDING-NEXT: data +0x00 [sizeof=4] int X
-; NO_PADDING-NEXT: data +0x04 [sizeof=4] int Y
-; NO_PADDING-NEXT: }
-
-; UNION: struct SimplePadUnion [sizeof = 16] {
-; UNION-NEXT: data +0x00 [sizeof=4] int X
-; UNION-NEXT: data +0x00 [sizeof=8] __int64 Y
-; UNION-NEXT: data +0x00 [sizeof=16] SimplePadUnion::
-; UNION-NEXT: }
-
-; NESTED_UNION: struct {{SimplePadUnion::.*}} [sizeof = 16] {
-; NESTED_UNION-NEXT: data +0x00 [sizeof=4] int X
-; NESTED_UNION-NEXT: <padding> (4 bytes)
-; NESTED_UNION-NEXT: data +0x08 [sizeof=8] __int64 Y
-; NESTED_UNION-NEXT: }
-
-; PAD_FROM_FIELDS1: struct SimplePadFields1 [sizeof = 4] {
-; PAD_FROM_FIELDS1-NEXT: data +0x00 [sizeof=1] char A
-; PAD_FROM_FIELDS1-NEXT: data +0x01 [sizeof=1] char B
-; PAD_FROM_FIELDS1-NEXT: data +0x02 [sizeof=1] char C
-; PAD_FROM_FIELDS1-NEXT: <padding> (1 bytes)
-; PAD_FROM_FIELDS1-NEXT: }
-
-; PAD_FROM_FIELDS2: struct SimplePadFields2 [sizeof = 8] {
-; PAD_FROM_FIELDS2-NEXT: data +0x00 [sizeof=4] int Y
-; PAD_FROM_FIELDS2-NEXT: data +0x04 [sizeof=1] char X
-; PAD_FROM_FIELDS2-NEXT: <padding> (3 bytes)
-; PAD_FROM_FIELDS2-NEXT: }
-
-; NO_PAD_IN_BASE: struct SimplePadBase [sizeof = 4] {
-; NO_PAD_IN_BASE-NEXT: data +0x00 [sizeof=4] int X
-; NO_PAD_IN_BASE-NEXT: }
-
-; PAD_IN_DERIVED: struct SimplePadDerived [sizeof = 16]
-; PAD_IN_DERIVED-NEXT: public SimplePadBase {
-; PAD_IN_DERIVED-NEXT: <padding> (4 bytes)
-; PAD_IN_DERIVED-NEXT: data +0x08 [sizeof=8] __int64 Y
-; PAD_IN_DERIVED-NEXT: }
-
-; EMPTY_BASE: struct SimplePadEmpty [sizeof = 8]
-; EMPTY_BASE-NEXT: : public SimplePadEmptyBase1
-; EMPTY_BASE-NEXT: , public SimplePadEmptyBase2 {
-; EMPTY_BASE-NEXT: <padding> (2 bytes)
-; EMPTY_BASE-NEXT: data +0x04 [sizeof=4] int X
-; EMPTY_BASE-NEXT: }
-
-; VFPTR: struct SimplePadVfptr [sizeof = 8] {
-; VFPTR-NEXT: vfptr +0x00 [sizeof=4]
-; VFPTR-NEXT: data +0x04 [sizeof=4] int X
-; VFPTR-NEXT: }
-
-; MULTIPLE_INHERIT: struct SimplePadMultiInherit [sizeof = 8]
-; MULTIPLE_INHERIT-NEXT: : public NonEmptyBase1
-; MULTIPLE_INHERIT-NEXT: , public NonEmptyBase2 {
-; MULTIPLE_INHERIT-NEXT: <padding> (2 bytes)
-; MULTIPLE_INHERIT-NEXT: data +0x04 [sizeof=4] int X
-; MULTIPLE_INHERIT-NEXT: }
-
-; MULTIPLE_INHERIT2: SimplePadMultiInherit2 [sizeof = 16]
-; MULTIPLE_INHERIT2-NEXT: : public SimplePadFields1
-; MULTIPLE_INHERIT2-NEXT: , public SimplePadFields2 {
-; MULTIPLE_INHERIT2-NEXT: data +0x0c [sizeof=4] int X
-; MULTIPLE_INHERIT2-NEXT: }
-
-; DEEP_INHERIT: struct SimplePadTwoLevelInherit [sizeof = 16]
-; DEEP_INHERIT-NEXT: : public OneLevelInherit {
-; DEEP_INHERIT-NEXT: <padding> (4 bytes)
-; DEEP_INHERIT-NEXT: data +0x08 [sizeof=8] __int64 Z
-; DEEP_INHERIT-NEXT: }
-
-
-; AGGREGATE: struct SimplePadAggregate [sizeof = 8] {
-; AGGREGATE-NEXT: data +0x00 [sizeof=1] NonEmptyBase1 X
-; AGGREGATE-NEXT: <padding> (3 bytes)
-; AGGREGATE-NEXT: data +0x04 [sizeof=4] int Y
-; AGGREGATE-NEXT: }
Modified: llvm/trunk/tools/llvm-pdbdump/LinePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LinePrinter.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LinePrinter.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LinePrinter.cpp Mon Apr 24 12:47:24 2017
@@ -72,7 +72,7 @@ void LinePrinter::NewLine() {
}
bool LinePrinter::IsClassExcluded(const ClassLayout &Class) {
- if (IsTypeExcluded(Class.getUDTName(), Class.getClassSize()))
+ if (IsTypeExcluded(Class.getName(), Class.getSize()))
return true;
if (Class.deepPaddingSize() < opts::pretty::PaddingThreshold)
return true;
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyClassDefinitionDumper.cpp Mon Apr 24 12:47:24 2017
@@ -58,25 +58,11 @@ void ClassDefinitionDumper::start(const
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();
- uint32_t Size = Layout.getClassSize();
+ uint32_t Size = Layout.getSize();
const PDBSymbolTypeUDT &Class = Layout.getClass();
WithColor(Printer, PDB_ColorItem::Keyword).get() << Class.getUdtKind() << " ";
@@ -84,19 +70,22 @@ void ClassDefinitionDumper::prettyPrintC
WithColor(Printer, PDB_ColorItem::Comment).get() << " [sizeof = " << Size
<< "]";
uint32_t BaseCount = Layout.bases().size();
- uint32_t VBaseCount = Layout.vbases().size();
- uint32_t TotalBaseCount = BaseCount + VBaseCount;
- if (TotalBaseCount > 0) {
+ if (BaseCount > 0) {
Printer.Indent();
- Printer.NewLine();
- Printer << ":";
- uint32_t BaseIndex = 0;
+ char NextSeparator = ':';
for (auto BC : Layout.bases()) {
const auto &Base = BC->getBase();
- printBase(Printer, Base, BaseIndex, TotalBaseCount, false);
- }
- for (auto &BC : Layout.vbases()) {
- printBase(Printer, *BC, BaseIndex, TotalBaseCount, true);
+ if (Base.isIndirectVirtualBaseClass())
+ continue;
+
+ Printer.NewLine();
+ Printer << NextSeparator << " ";
+ WithColor(Printer, PDB_ColorItem::Keyword).get() << Base.getAccess();
+ if (BC->isVirtualBase())
+ WithColor(Printer, PDB_ColorItem::Keyword).get() << " virtual";
+
+ WithColor(Printer, PDB_ColorItem::Type).get() << " " << Base.getName();
+ NextSeparator = ',';
}
Printer.Unindent();
@@ -114,7 +103,7 @@ void ClassDefinitionDumper::prettyPrintC
Printer.NewLine();
if (Layout.deepPaddingSize() > 0) {
APFloat Pct(100.0 * (double)Layout.deepPaddingSize() /
- (double)Layout.getClassSize());
+ (double)Layout.getSize());
SmallString<8> PctStr;
Pct.toString(PctStr, 4);
WithColor(Printer, PDB_ColorItem::Padding).get()
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.cpp Mon Apr 24 12:47:24 2017
@@ -53,15 +53,28 @@ bool PrettyClassLayoutGraphicalDumper::s
}
}
- CurrentItem = Item.get();
- Item->getSymbol().dump(*this);
+ CurrentItem = Item;
+ if (Item->isVBPtr()) {
+ VTableLayoutItem &Layout = static_cast<VTableLayoutItem &>(*CurrentItem);
+
+ VariableDumper VarDumper(Printer);
+ VarDumper.startVbptr(CurrentAbsoluteOffset, Layout.getSize());
+ } else {
+ if (auto Sym = Item->getSymbol())
+ Sym->dump(*this);
+ }
+
+ if (Item->getLayoutSize() > 0) {
+ uint32_t Prev = RelativeOffset + Item->getLayoutSize() - 1;
+ NextPaddingByte = UseMap.find_next_unset(Prev);
+ }
}
- if (NextPaddingByte >= 0 && Layout.getClassSize() > 1) {
- uint32_t Amount = Layout.getClassSize() - NextPaddingByte;
+ auto TailPadding = Layout.tailPadding();
+ if (TailPadding > 0) {
Printer.NewLine();
- WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> (" << Amount
- << " bytes)";
+ WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> ("
+ << TailPadding << " bytes)";
DumpedAnything = true;
}
@@ -85,12 +98,19 @@ void PrettyClassLayoutGraphicalDumper::d
Printer.NewLine();
BaseClassLayout &Layout = static_cast<BaseClassLayout &>(*CurrentItem);
- std::string Label = Layout.isVirtualBase() ? "vbase" : "base";
+ std::string Label = "base";
+ if (Layout.isVirtualBase()) {
+ Label.insert(Label.begin(), 'v');
+ if (Layout.getBase().isIndirectVirtualBaseClass())
+ Label.insert(Label.begin(), 'i');
+ }
Printer << Label << " ";
+ uint32_t Size = Layout.isEmptyBase() ? 1 : Layout.getLayoutSize();
+
WithColor(Printer, PDB_ColorItem::Offset).get()
- << "+" << format_hex(CurrentAbsoluteOffset, 4)
- << " [sizeof=" << Layout.getSize() << "] ";
+ << "+" << format_hex(CurrentAbsoluteOffset, 4) << " [sizeof=" << Size
+ << "] ";
WithColor(Printer, PDB_ColorItem::Identifier).get() << Layout.getName();
@@ -125,27 +145,8 @@ void PrettyClassLayoutGraphicalDumper::d
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;
}
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutGraphicalDumper.h Mon Apr 24 12:47:24 2017
@@ -19,7 +19,7 @@ namespace llvm {
namespace pdb {
class UDTLayoutBase;
-class StorageItemBase;
+class LayoutItemBase;
class LinePrinter;
class PrettyClassLayoutGraphicalDumper : public PDBSymDumper {
@@ -37,7 +37,7 @@ private:
LinePrinter &Printer;
- StorageItemBase *CurrentItem = nullptr;
+ LayoutItemBase *CurrentItem = nullptr;
uint32_t ClassOffsetZero = 0;
uint32_t CurrentAbsoluteOffset = 0;
bool DumpedAnything = false;
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.cpp Mon Apr 24 12:47:24 2017
@@ -59,14 +59,17 @@ bool PrettyClassLayoutTextDumper::start(
NextUnusedByte = UseMap.find_next_unset(Off);
}
}
- LayoutItem->getSymbol().dump(*this);
+ if (auto Sym = LayoutItem->getSymbol())
+ Sym->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)";
+ if (NextUnusedByte >= 0 && Layout.getSize() > 1) {
+ uint32_t Amount = Layout.getSize() - NextUnusedByte;
+ if (Amount > 0) {
+ Printer.NewLine();
+ WithColor(Printer, PDB_ColorItem::Padding).get() << "<padding> ("
+ << Amount << " bytes)";
+ }
DumpedAnything = true;
}
@@ -116,4 +119,6 @@ void PrettyClassLayoutTextDumper::dump(c
Dumper.start(Symbol);
}
+void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {}
+
void PrettyClassLayoutTextDumper::dump(const PDBSymbolTypeUDT &Symbol) {}
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyClassLayoutTextDumper.h Mon Apr 24 12:47:24 2017
@@ -34,6 +34,7 @@ public:
void dump(const PDBSymbolTypeTypedef &Symbol) override;
void dump(const PDBSymbolTypeUDT &Symbol) override;
void dump(const PDBSymbolTypeVTable &Symbol) override;
+ void dump(const PDBSymbolTypeBuiltin &Symbol) override;
private:
bool DumpedAnything = false;
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyTypeDumper.cpp Mon Apr 24 12:47:24 2017
@@ -34,17 +34,23 @@ using LayoutPtr = std::unique_ptr<ClassL
typedef bool (*CompareFunc)(const LayoutPtr &S1, const LayoutPtr &S2);
static bool CompareNames(const LayoutPtr &S1, const LayoutPtr &S2) {
- return S1->getUDTName() < S2->getUDTName();
+ return S1->getName() < S2->getName();
}
static bool CompareSizes(const LayoutPtr &S1, const LayoutPtr &S2) {
- return S1->getClassSize() < S2->getClassSize();
+ return S1->getSize() < S2->getSize();
}
static bool ComparePadding(const LayoutPtr &S1, const LayoutPtr &S2) {
return S1->deepPaddingSize() < S2->deepPaddingSize();
}
+static bool ComparePaddingPct(const LayoutPtr &S1, const LayoutPtr &S2) {
+ double Pct1 = (double)S1->deepPaddingSize() / (double)S1->getSize();
+ double Pct2 = (double)S2->deepPaddingSize() / (double)S2->getSize();
+ return Pct1 < Pct2;
+}
+
static CompareFunc getComparisonFunc(opts::pretty::ClassSortMode Mode) {
switch (Mode) {
case opts::pretty::ClassSortMode::Name:
@@ -53,6 +59,8 @@ static CompareFunc getComparisonFunc(opt
return CompareSizes;
case opts::pretty::ClassSortMode::Padding:
return ComparePadding;
+ case opts::pretty::ClassSortMode::PaddingPct:
+ return ComparePaddingPct;
default:
return nullptr;
}
@@ -67,14 +75,18 @@ filterAndSortClassDefs(LinePrinter &Prin
Filtered.reserve(UnfilteredCount);
CompareFunc Comp = getComparisonFunc(opts::pretty::ClassOrder);
+ if (UnfilteredCount > 10000) {
+ errs() << formatv("Filtering and sorting {0} types", UnfilteredCount);
+ errs().flush();
+ }
uint32_t Examined = 0;
uint32_t Discarded = 0;
while (auto Class = E.getNext()) {
++Examined;
if (Examined % 10000 == 0) {
- outs() << formatv("Examined {0}/{1} items. {2} items discarded\n",
+ errs() << formatv("Examined {0}/{1} items. {2} items discarded\n",
Examined, UnfilteredCount, Discarded);
- outs().flush();
+ errs().flush();
}
if (Class->getUnmodifiedTypeId() != 0) {
@@ -163,6 +175,9 @@ void TypeDumper::start(const PDBSymbolEx
dumpClassLayout(*Class);
} else {
while (auto Class = Classes->getNext()) {
+ if (Class->getUnmodifiedTypeId() != 0)
+ continue;
+
if (Printer.IsTypeExcluded(Class->getName(), Class->getLength()))
continue;
@@ -209,7 +224,7 @@ void TypeDumper::dumpClassLayout(const C
if (opts::pretty::ClassFormat == opts::pretty::ClassDefinitionFormat::None) {
Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Keyword).get() << "class ";
- WithColor(Printer, PDB_ColorItem::Identifier).get() << Class.getUDTName();
+ WithColor(Printer, PDB_ColorItem::Identifier).get() << Class.getName();
} else {
ClassDefinitionDumper Dumper(Printer);
Dumper.start(Class);
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.cpp Mon Apr 24 12:47:24 2017
@@ -91,6 +91,14 @@ void VariableDumper::start(const PDBSymb
}
}
+void VariableDumper::startVbptr(uint32_t Offset, uint32_t Size) {
+ Printer.NewLine();
+ Printer << "vbptr ";
+
+ WithColor(Printer, PDB_ColorItem::Offset).get()
+ << "+" << format_hex(Offset, 4) << " [sizeof=" << Size << "] ";
+}
+
void VariableDumper::start(const PDBSymbolTypeVTable &Var, uint32_t Offset) {
Printer.NewLine();
Printer << "vfptr ";
Modified: llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/PrettyVariableDumper.h Mon Apr 24 12:47:24 2017
@@ -26,6 +26,7 @@ public:
void start(const PDBSymbolData &Var, uint32_t Offset = 0);
void start(const PDBSymbolTypeVTable &Var, uint32_t Offset = 0);
+ void startVbptr(uint32_t Offset, uint32_t Size);
void dump(const PDBSymbolTypeArray &Symbol) override;
void dump(const PDBSymbolTypeBuiltin &Symbol) override;
Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Mon Apr 24 12:47:24 2017
@@ -124,12 +124,15 @@ cl::opt<bool> Typedefs("typedefs", cl::d
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::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"),
+ clEnumValN(ClassSortMode::PaddingPct, "padding-pct",
+ "Sort classes by percentage of space consumed by padding")),
cl::cat(TypeCategory), cl::sub(PrettySubcommand));
cl::opt<ClassDefinitionFormat> ClassFormat(
Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h?rev=301203&r1=301202&r2=301203&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h Mon Apr 24 12:47:24 2017
@@ -19,7 +19,7 @@ namespace opts {
namespace pretty {
enum class ClassDefinitionFormat { None, Layout, Graphical, Standard };
-enum class ClassSortMode { None, Name, Size, Padding };
+enum class ClassSortMode { None, Name, Size, Padding, PaddingPct };
extern llvm::cl::opt<bool> Compilands;
extern llvm::cl::opt<bool> Symbols;
More information about the llvm-commits
mailing list