1 //===- UDTLayout.h - UDT layout info ----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_PDB_UDTLAYOUT_H 11 #define LLVM_DEBUGINFO_PDB_UDTLAYOUT_H 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/ADT/BitVector.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/DebugInfo/PDB/PDBSymbol.h" 17 #include "llvm/DebugInfo/PDB/PDBSymbolData.h" 18 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" 19 #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" 20 #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 21 #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" 22 #include "llvm/DebugInfo/PDB/PDBTypes.h" 23 #include <cstdint> 24 #include <memory> 25 #include <string> 26 #include <vector> 27 28 namespace llvm { 29 namespace pdb { 30 31 class BaseClassLayout; 32 class ClassLayout; 33 class UDTLayoutBase; 34 35 class LayoutItemBase { 36 public: 37 LayoutItemBase(const UDTLayoutBase *Parent, const PDBSymbol *Symbol, 38 const std::string &Name, uint32_t OffsetInParent, 39 uint32_t Size, bool IsElided); 40 virtual ~LayoutItemBase() = default; 41 42 uint32_t deepPaddingSize() const; immediatePadding()43 virtual uint32_t immediatePadding() const { return 0; } 44 virtual uint32_t tailPadding() const; 45 getParent()46 const UDTLayoutBase *getParent() const { return Parent; } getName()47 StringRef getName() const { return Name; } getOffsetInParent()48 uint32_t getOffsetInParent() const { return OffsetInParent; } getSize()49 uint32_t getSize() const { return SizeOf; } getLayoutSize()50 uint32_t getLayoutSize() const { return LayoutSize; } getSymbol()51 const PDBSymbol *getSymbol() const { return Symbol; } usedBytes()52 const BitVector &usedBytes() const { return UsedBytes; } isElided()53 bool isElided() const { return IsElided; } isVBPtr()54 virtual bool isVBPtr() const { return false; } 55 containsOffset(uint32_t Off)56 uint32_t containsOffset(uint32_t Off) const { 57 uint32_t Begin = getOffsetInParent(); 58 uint32_t End = Begin + getSize(); 59 return (Off >= Begin && Off < End); 60 } 61 62 protected: 63 const PDBSymbol *Symbol = nullptr; 64 const UDTLayoutBase *Parent = nullptr; 65 BitVector UsedBytes; 66 std::string Name; 67 uint32_t OffsetInParent = 0; 68 uint32_t SizeOf = 0; 69 uint32_t LayoutSize = 0; 70 bool IsElided = false; 71 }; 72 73 class VBPtrLayoutItem : public LayoutItemBase { 74 public: 75 VBPtrLayoutItem(const UDTLayoutBase &Parent, 76 std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset, 77 uint32_t Size); 78 isVBPtr()79 bool isVBPtr() const override { return true; } 80 81 private: 82 std::unique_ptr<PDBSymbolTypeBuiltin> Type; 83 }; 84 85 class DataMemberLayoutItem : public LayoutItemBase { 86 public: 87 DataMemberLayoutItem(const UDTLayoutBase &Parent, 88 std::unique_ptr<PDBSymbolData> DataMember); 89 90 const PDBSymbolData &getDataMember(); 91 bool hasUDTLayout() const; 92 const ClassLayout &getUDTLayout() const; 93 94 private: 95 std::unique_ptr<PDBSymbolData> DataMember; 96 std::unique_ptr<ClassLayout> UdtLayout; 97 }; 98 99 class VTableLayoutItem : public LayoutItemBase { 100 public: 101 VTableLayoutItem(const UDTLayoutBase &Parent, 102 std::unique_ptr<PDBSymbolTypeVTable> VTable); 103 getElementSize()104 uint32_t getElementSize() const { return ElementSize; } 105 106 private: 107 uint32_t ElementSize = 0; 108 std::unique_ptr<PDBSymbolTypeVTable> VTable; 109 }; 110 111 class UDTLayoutBase : public LayoutItemBase { 112 template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>; 113 114 public: 115 UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym, 116 const std::string &Name, uint32_t OffsetInParent, uint32_t Size, 117 bool IsElided); 118 119 uint32_t tailPadding() const override; layout_items()120 ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; } bases()121 ArrayRef<BaseClassLayout *> bases() const { return AllBases; } regular_bases()122 ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; } virtual_bases()123 ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; } directVirtualBaseCount()124 uint32_t directVirtualBaseCount() const { return DirectVBaseCount; } funcs()125 ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; } other_items()126 ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; } 127 128 protected: 129 bool hasVBPtrAtOffset(uint32_t Off) const; 130 void initializeChildren(const PDBSymbol &Sym); 131 132 void addChildToLayout(std::unique_ptr<LayoutItemBase> Child); 133 134 uint32_t DirectVBaseCount = 0; 135 136 UniquePtrVector<PDBSymbol> Other; 137 UniquePtrVector<PDBSymbolFunc> Funcs; 138 UniquePtrVector<LayoutItemBase> ChildStorage; 139 std::vector<LayoutItemBase *> LayoutItems; 140 141 std::vector<BaseClassLayout *> AllBases; 142 ArrayRef<BaseClassLayout *> NonVirtualBases; 143 ArrayRef<BaseClassLayout *> VirtualBases; 144 145 VTableLayoutItem *VTable = nullptr; 146 VBPtrLayoutItem *VBPtr = nullptr; 147 }; 148 149 class BaseClassLayout : public UDTLayoutBase { 150 public: 151 BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent, 152 bool Elide, std::unique_ptr<PDBSymbolTypeBaseClass> Base); 153 getBase()154 const PDBSymbolTypeBaseClass &getBase() const { return *Base; } isVirtualBase()155 bool isVirtualBase() const { return IsVirtualBase; } isEmptyBase()156 bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; } 157 158 private: 159 std::unique_ptr<PDBSymbolTypeBaseClass> Base; 160 bool IsVirtualBase; 161 }; 162 163 class ClassLayout : public UDTLayoutBase { 164 public: 165 explicit ClassLayout(const PDBSymbolTypeUDT &UDT); 166 explicit ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT); 167 168 ClassLayout(ClassLayout &&Other) = default; 169 getClass()170 const PDBSymbolTypeUDT &getClass() const { return UDT; } 171 uint32_t immediatePadding() const override; 172 173 private: 174 BitVector ImmediateUsedBytes; 175 std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage; 176 const PDBSymbolTypeUDT &UDT; 177 }; 178 179 } // end namespace pdb 180 } // end namespace llvm 181 182 #endif // LLVM_DEBUGINFO_PDB_UDTLAYOUT_H 183