UDTLayout.h 5.8 KB

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