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