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