1317017Sdim//===- UDTLayout.h - UDT layout info ----------------------------*- C++ -*-===// 2317017Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6317017Sdim// 7317017Sdim//===----------------------------------------------------------------------===// 8317017Sdim 9317017Sdim#ifndef LLVM_DEBUGINFO_PDB_UDTLAYOUT_H 10317017Sdim#define LLVM_DEBUGINFO_PDB_UDTLAYOUT_H 11317017Sdim 12317017Sdim#include "llvm/ADT/ArrayRef.h" 13317017Sdim#include "llvm/ADT/BitVector.h" 14320572Sdim#include "llvm/ADT/StringRef.h" 15320572Sdim#include "llvm/DebugInfo/PDB/PDBSymbol.h" 16320572Sdim#include "llvm/DebugInfo/PDB/PDBSymbolData.h" 17320572Sdim#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" 18320572Sdim#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" 19320572Sdim#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" 20320572Sdim#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h" 21320572Sdim#include "llvm/DebugInfo/PDB/PDBTypes.h" 22320572Sdim#include <cstdint> 23317017Sdim#include <memory> 24320572Sdim#include <string> 25320572Sdim#include <vector> 26317017Sdim 27317017Sdimnamespace llvm { 28317017Sdimnamespace pdb { 29317017Sdim 30320572Sdimclass BaseClassLayout; 31317017Sdimclass ClassLayout; 32317017Sdimclass UDTLayoutBase; 33317017Sdim 34317472Sdimclass LayoutItemBase { 35317017Sdimpublic: 36317472Sdim LayoutItemBase(const UDTLayoutBase *Parent, const PDBSymbol *Symbol, 37317472Sdim const std::string &Name, uint32_t OffsetInParent, 38317472Sdim uint32_t Size, bool IsElided); 39320572Sdim virtual ~LayoutItemBase() = default; 40317017Sdim 41317472Sdim uint32_t deepPaddingSize() const; 42317472Sdim virtual uint32_t immediatePadding() const { return 0; } 43317472Sdim virtual uint32_t tailPadding() const; 44317017Sdim 45317472Sdim const UDTLayoutBase *getParent() const { return Parent; } 46317017Sdim StringRef getName() const { return Name; } 47317017Sdim uint32_t getOffsetInParent() const { return OffsetInParent; } 48317017Sdim uint32_t getSize() const { return SizeOf; } 49317472Sdim uint32_t getLayoutSize() const { return LayoutSize; } 50317472Sdim const PDBSymbol *getSymbol() const { return Symbol; } 51317472Sdim const BitVector &usedBytes() const { return UsedBytes; } 52317472Sdim bool isElided() const { return IsElided; } 53317472Sdim virtual bool isVBPtr() const { return false; } 54317017Sdim 55317472Sdim uint32_t containsOffset(uint32_t Off) const { 56317472Sdim uint32_t Begin = getOffsetInParent(); 57317472Sdim uint32_t End = Begin + getSize(); 58317472Sdim return (Off >= Begin && Off < End); 59317472Sdim } 60317472Sdim 61317017Sdimprotected: 62317472Sdim const PDBSymbol *Symbol = nullptr; 63317472Sdim const UDTLayoutBase *Parent = nullptr; 64317017Sdim BitVector UsedBytes; 65317017Sdim std::string Name; 66317017Sdim uint32_t OffsetInParent = 0; 67317017Sdim uint32_t SizeOf = 0; 68317472Sdim uint32_t LayoutSize = 0; 69317472Sdim bool IsElided = false; 70317017Sdim}; 71317017Sdim 72317472Sdimclass VBPtrLayoutItem : public LayoutItemBase { 73317017Sdimpublic: 74317472Sdim VBPtrLayoutItem(const UDTLayoutBase &Parent, 75317472Sdim std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset, 76317472Sdim uint32_t Size); 77317472Sdim 78320572Sdim bool isVBPtr() const override { return true; } 79320572Sdim 80317472Sdimprivate: 81317472Sdim std::unique_ptr<PDBSymbolTypeBuiltin> Type; 82317472Sdim}; 83317472Sdim 84317472Sdimclass DataMemberLayoutItem : public LayoutItemBase { 85317472Sdimpublic: 86317017Sdim DataMemberLayoutItem(const UDTLayoutBase &Parent, 87317017Sdim std::unique_ptr<PDBSymbolData> DataMember); 88317017Sdim 89317017Sdim const PDBSymbolData &getDataMember(); 90317017Sdim bool hasUDTLayout() const; 91317017Sdim const ClassLayout &getUDTLayout() const; 92317017Sdim 93317017Sdimprivate: 94317017Sdim std::unique_ptr<PDBSymbolData> DataMember; 95317017Sdim std::unique_ptr<ClassLayout> UdtLayout; 96317017Sdim}; 97317017Sdim 98317472Sdimclass VTableLayoutItem : public LayoutItemBase { 99317017Sdimpublic: 100317017Sdim VTableLayoutItem(const UDTLayoutBase &Parent, 101317017Sdim std::unique_ptr<PDBSymbolTypeVTable> VTable); 102317017Sdim 103317017Sdim uint32_t getElementSize() const { return ElementSize; } 104317017Sdim 105317017Sdimprivate: 106317017Sdim uint32_t ElementSize = 0; 107317017Sdim std::unique_ptr<PDBSymbolTypeVTable> VTable; 108317017Sdim}; 109317017Sdim 110317472Sdimclass UDTLayoutBase : public LayoutItemBase { 111317017Sdim template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>; 112317017Sdim 113317017Sdimpublic: 114317472Sdim UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym, 115317472Sdim const std::string &Name, uint32_t OffsetInParent, uint32_t Size, 116317472Sdim bool IsElided); 117317017Sdim 118317472Sdim uint32_t tailPadding() const override; 119317472Sdim ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; } 120317472Sdim ArrayRef<BaseClassLayout *> bases() const { return AllBases; } 121317472Sdim ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; } 122317472Sdim ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; } 123317472Sdim uint32_t directVirtualBaseCount() const { return DirectVBaseCount; } 124317017Sdim ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; } 125317017Sdim ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; } 126317017Sdim 127317017Sdimprotected: 128317472Sdim bool hasVBPtrAtOffset(uint32_t Off) const; 129317017Sdim void initializeChildren(const PDBSymbol &Sym); 130317017Sdim 131317472Sdim void addChildToLayout(std::unique_ptr<LayoutItemBase> Child); 132317017Sdim 133317472Sdim uint32_t DirectVBaseCount = 0; 134317017Sdim 135317017Sdim UniquePtrVector<PDBSymbol> Other; 136317017Sdim UniquePtrVector<PDBSymbolFunc> Funcs; 137317472Sdim UniquePtrVector<LayoutItemBase> ChildStorage; 138317472Sdim std::vector<LayoutItemBase *> LayoutItems; 139317472Sdim 140317472Sdim std::vector<BaseClassLayout *> AllBases; 141317472Sdim ArrayRef<BaseClassLayout *> NonVirtualBases; 142317472Sdim ArrayRef<BaseClassLayout *> VirtualBases; 143317472Sdim 144317017Sdim VTableLayoutItem *VTable = nullptr; 145317472Sdim VBPtrLayoutItem *VBPtr = nullptr; 146317017Sdim}; 147317017Sdim 148317472Sdimclass BaseClassLayout : public UDTLayoutBase { 149317472Sdimpublic: 150317472Sdim BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent, 151317472Sdim bool Elide, std::unique_ptr<PDBSymbolTypeBaseClass> Base); 152317472Sdim 153317472Sdim const PDBSymbolTypeBaseClass &getBase() const { return *Base; } 154317472Sdim bool isVirtualBase() const { return IsVirtualBase; } 155317472Sdim bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; } 156317472Sdim 157317472Sdimprivate: 158317472Sdim std::unique_ptr<PDBSymbolTypeBaseClass> Base; 159317472Sdim bool IsVirtualBase; 160317472Sdim}; 161317472Sdim 162317017Sdimclass ClassLayout : public UDTLayoutBase { 163317017Sdimpublic: 164317017Sdim explicit ClassLayout(const PDBSymbolTypeUDT &UDT); 165317017Sdim explicit ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT); 166317017Sdim 167317017Sdim ClassLayout(ClassLayout &&Other) = default; 168317017Sdim 169317017Sdim const PDBSymbolTypeUDT &getClass() const { return UDT; } 170317472Sdim uint32_t immediatePadding() const override; 171317017Sdim 172317017Sdimprivate: 173317472Sdim BitVector ImmediateUsedBytes; 174317017Sdim std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage; 175317017Sdim const PDBSymbolTypeUDT &UDT; 176317017Sdim}; 177317017Sdim 178320572Sdim} // end namespace pdb 179320572Sdim} // end namespace llvm 180320572Sdim 181317017Sdim#endif // LLVM_DEBUGINFO_PDB_UDTLAYOUT_H 182