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 28namespace llvm { 29namespace pdb { 30 31class BaseClassLayout; 32class ClassLayout; 33class UDTLayoutBase; 34 35class LayoutItemBase { 36public: 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; 43 virtual uint32_t immediatePadding() const { return 0; } 44 virtual uint32_t tailPadding() const; 45 46 const UDTLayoutBase *getParent() const { return Parent; } 47 StringRef getName() const { return Name; } 48 uint32_t getOffsetInParent() const { return OffsetInParent; } 49 uint32_t getSize() const { return SizeOf; } 50 uint32_t getLayoutSize() const { return LayoutSize; } 51 const PDBSymbol *getSymbol() const { return Symbol; } 52 const BitVector &usedBytes() const { return UsedBytes; } 53 bool isElided() const { return IsElided; } 54 virtual bool isVBPtr() const { return false; } 55 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 62protected: 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 73class VBPtrLayoutItem : public LayoutItemBase { 74public: 75 VBPtrLayoutItem(const UDTLayoutBase &Parent, 76 std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset, 77 uint32_t Size); 78 79 bool isVBPtr() const override { return true; } 80 81private: 82 std::unique_ptr<PDBSymbolTypeBuiltin> Type; 83}; 84 85class DataMemberLayoutItem : public LayoutItemBase { 86public: 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 94private: 95 std::unique_ptr<PDBSymbolData> DataMember; 96 std::unique_ptr<ClassLayout> UdtLayout; 97}; 98 99class VTableLayoutItem : public LayoutItemBase { 100public: 101 VTableLayoutItem(const UDTLayoutBase &Parent, 102 std::unique_ptr<PDBSymbolTypeVTable> VTable); 103 104 uint32_t getElementSize() const { return ElementSize; } 105 106private: 107 uint32_t ElementSize = 0; 108 std::unique_ptr<PDBSymbolTypeVTable> VTable; 109}; 110 111class UDTLayoutBase : public LayoutItemBase { 112 template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>; 113 114public: 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; 120 ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; } 121 ArrayRef<BaseClassLayout *> bases() const { return AllBases; } 122 ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; } 123 ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; } 124 uint32_t directVirtualBaseCount() const { return DirectVBaseCount; } 125 ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; } 126 ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; } 127 128protected: 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 149class BaseClassLayout : public UDTLayoutBase { 150public: 151 BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent, 152 bool Elide, std::unique_ptr<PDBSymbolTypeBaseClass> Base); 153 154 const PDBSymbolTypeBaseClass &getBase() const { return *Base; } 155 bool isVirtualBase() const { return IsVirtualBase; } 156 bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; } 157 158private: 159 std::unique_ptr<PDBSymbolTypeBaseClass> Base; 160 bool IsVirtualBase; 161}; 162 163class ClassLayout : public UDTLayoutBase { 164public: 165 explicit ClassLayout(const PDBSymbolTypeUDT &UDT); 166 explicit ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT); 167 168 ClassLayout(ClassLayout &&Other) = default; 169 170 const PDBSymbolTypeUDT &getClass() const { return UDT; } 171 uint32_t immediatePadding() const override; 172 173private: 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