UDTLayout.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- UDTLayout.h - UDT layout info ----------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DEBUGINFO_PDB_UDTLAYOUT_H
  14. #define LLVM_DEBUGINFO_PDB_UDTLAYOUT_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/BitVector.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/DebugInfo/PDB/PDBSymbol.h"
  19. #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
  20. #include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
  21. #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
  22. #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
  23. #include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
  24. #include "llvm/DebugInfo/PDB/PDBTypes.h"
  25. #include <cstdint>
  26. #include <memory>
  27. #include <string>
  28. #include <vector>
  29. namespace llvm {
  30. namespace pdb {
  31. class BaseClassLayout;
  32. class ClassLayout;
  33. class UDTLayoutBase;
  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. uint32_t deepPaddingSize() const;
  41. virtual uint32_t immediatePadding() const { return 0; }
  42. virtual uint32_t tailPadding() const;
  43. const UDTLayoutBase *getParent() const { return Parent; }
  44. StringRef getName() const { return Name; }
  45. uint32_t getOffsetInParent() const { return OffsetInParent; }
  46. uint32_t getSize() const { return SizeOf; }
  47. uint32_t getLayoutSize() const { return LayoutSize; }
  48. const PDBSymbol *getSymbol() const { return Symbol; }
  49. const BitVector &usedBytes() const { return UsedBytes; }
  50. bool isElided() const { return IsElided; }
  51. virtual bool isVBPtr() const { return false; }
  52. uint32_t containsOffset(uint32_t Off) const {
  53. uint32_t Begin = getOffsetInParent();
  54. uint32_t End = Begin + getSize();
  55. return (Off >= Begin && Off < End);
  56. }
  57. protected:
  58. const PDBSymbol *Symbol = nullptr;
  59. const UDTLayoutBase *Parent = nullptr;
  60. BitVector UsedBytes;
  61. std::string Name;
  62. uint32_t OffsetInParent = 0;
  63. uint32_t SizeOf = 0;
  64. uint32_t LayoutSize = 0;
  65. bool IsElided = false;
  66. };
  67. class VBPtrLayoutItem : public LayoutItemBase {
  68. public:
  69. VBPtrLayoutItem(const UDTLayoutBase &Parent,
  70. std::unique_ptr<PDBSymbolTypeBuiltin> Sym, uint32_t Offset,
  71. uint32_t Size);
  72. bool isVBPtr() const override { return true; }
  73. private:
  74. std::unique_ptr<PDBSymbolTypeBuiltin> Type;
  75. };
  76. class DataMemberLayoutItem : public LayoutItemBase {
  77. public:
  78. DataMemberLayoutItem(const UDTLayoutBase &Parent,
  79. std::unique_ptr<PDBSymbolData> DataMember);
  80. const PDBSymbolData &getDataMember();
  81. bool hasUDTLayout() const;
  82. const ClassLayout &getUDTLayout() const;
  83. private:
  84. std::unique_ptr<PDBSymbolData> DataMember;
  85. std::unique_ptr<ClassLayout> UdtLayout;
  86. };
  87. class VTableLayoutItem : public LayoutItemBase {
  88. public:
  89. VTableLayoutItem(const UDTLayoutBase &Parent,
  90. std::unique_ptr<PDBSymbolTypeVTable> VTable);
  91. uint32_t getElementSize() const { return ElementSize; }
  92. private:
  93. uint32_t ElementSize = 0;
  94. std::unique_ptr<PDBSymbolTypeVTable> VTable;
  95. };
  96. class UDTLayoutBase : public LayoutItemBase {
  97. template <typename T> using UniquePtrVector = std::vector<std::unique_ptr<T>>;
  98. public:
  99. UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
  100. const std::string &Name, uint32_t OffsetInParent, uint32_t Size,
  101. bool IsElided);
  102. uint32_t tailPadding() const override;
  103. ArrayRef<LayoutItemBase *> layout_items() const { return LayoutItems; }
  104. ArrayRef<BaseClassLayout *> bases() const { return AllBases; }
  105. ArrayRef<BaseClassLayout *> regular_bases() const { return NonVirtualBases; }
  106. ArrayRef<BaseClassLayout *> virtual_bases() const { return VirtualBases; }
  107. uint32_t directVirtualBaseCount() const { return DirectVBaseCount; }
  108. ArrayRef<std::unique_ptr<PDBSymbolFunc>> funcs() const { return Funcs; }
  109. ArrayRef<std::unique_ptr<PDBSymbol>> other_items() const { return Other; }
  110. protected:
  111. bool hasVBPtrAtOffset(uint32_t Off) const;
  112. void initializeChildren(const PDBSymbol &Sym);
  113. void addChildToLayout(std::unique_ptr<LayoutItemBase> Child);
  114. uint32_t DirectVBaseCount = 0;
  115. UniquePtrVector<PDBSymbol> Other;
  116. UniquePtrVector<PDBSymbolFunc> Funcs;
  117. UniquePtrVector<LayoutItemBase> ChildStorage;
  118. std::vector<LayoutItemBase *> LayoutItems;
  119. std::vector<BaseClassLayout *> AllBases;
  120. ArrayRef<BaseClassLayout *> NonVirtualBases;
  121. ArrayRef<BaseClassLayout *> VirtualBases;
  122. VTableLayoutItem *VTable = nullptr;
  123. VBPtrLayoutItem *VBPtr = nullptr;
  124. };
  125. class BaseClassLayout : public UDTLayoutBase {
  126. public:
  127. BaseClassLayout(const UDTLayoutBase &Parent, uint32_t OffsetInParent,
  128. bool Elide, std::unique_ptr<PDBSymbolTypeBaseClass> Base);
  129. const PDBSymbolTypeBaseClass &getBase() const { return *Base; }
  130. bool isVirtualBase() const { return IsVirtualBase; }
  131. bool isEmptyBase() { return SizeOf == 1 && LayoutSize == 0; }
  132. private:
  133. std::unique_ptr<PDBSymbolTypeBaseClass> Base;
  134. bool IsVirtualBase;
  135. };
  136. class ClassLayout : public UDTLayoutBase {
  137. public:
  138. explicit ClassLayout(const PDBSymbolTypeUDT &UDT);
  139. explicit ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT);
  140. ClassLayout(ClassLayout &&Other) = default;
  141. const PDBSymbolTypeUDT &getClass() const { return UDT; }
  142. uint32_t immediatePadding() const override;
  143. private:
  144. BitVector ImmediateUsedBytes;
  145. std::unique_ptr<PDBSymbolTypeUDT> OwnedStorage;
  146. const PDBSymbolTypeUDT &UDT;
  147. };
  148. } // end namespace pdb
  149. } // end namespace llvm
  150. #endif // LLVM_DEBUGINFO_PDB_UDTLAYOUT_H
  151. #ifdef __GNUC__
  152. #pragma GCC diagnostic pop
  153. #endif