Home | History | Annotate | Download | only in PDB
      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;
     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 
     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 
     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 
    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;
    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 
    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 
    154   const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
    155   bool isVirtualBase() const { return IsVirtualBase; }
    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 
    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