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