xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/UDTLayout.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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