VTTBuilder.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- VTTBuilder.h - C++ VTT layout builder --------------------*- 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. //
  14. // This contains code dealing with generation of the layout of virtual table
  15. // tables (VTT).
  16. //
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_AST_VTTBUILDER_H
  19. #define LLVM_CLANG_AST_VTTBUILDER_H
  20. #include "clang/AST/BaseSubobject.h"
  21. #include "clang/AST/CharUnits.h"
  22. #include "clang/Basic/LLVM.h"
  23. #include "llvm/ADT/DenseMap.h"
  24. #include "llvm/ADT/PointerIntPair.h"
  25. #include "llvm/ADT/SmallPtrSet.h"
  26. #include "llvm/ADT/SmallVector.h"
  27. #include <cstdint>
  28. namespace clang {
  29. class ASTContext;
  30. class ASTRecordLayout;
  31. class CXXRecordDecl;
  32. class VTTVTable {
  33. llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> BaseAndIsVirtual;
  34. CharUnits BaseOffset;
  35. public:
  36. VTTVTable() = default;
  37. VTTVTable(const CXXRecordDecl *Base, CharUnits BaseOffset, bool BaseIsVirtual)
  38. : BaseAndIsVirtual(Base, BaseIsVirtual), BaseOffset(BaseOffset) {}
  39. VTTVTable(BaseSubobject Base, bool BaseIsVirtual)
  40. : BaseAndIsVirtual(Base.getBase(), BaseIsVirtual),
  41. BaseOffset(Base.getBaseOffset()) {}
  42. const CXXRecordDecl *getBase() const {
  43. return BaseAndIsVirtual.getPointer();
  44. }
  45. CharUnits getBaseOffset() const {
  46. return BaseOffset;
  47. }
  48. bool isVirtual() const {
  49. return BaseAndIsVirtual.getInt();
  50. }
  51. BaseSubobject getBaseSubobject() const {
  52. return BaseSubobject(getBase(), getBaseOffset());
  53. }
  54. };
  55. struct VTTComponent {
  56. uint64_t VTableIndex;
  57. BaseSubobject VTableBase;
  58. VTTComponent() = default;
  59. VTTComponent(uint64_t VTableIndex, BaseSubobject VTableBase)
  60. : VTableIndex(VTableIndex), VTableBase(VTableBase) {}
  61. };
  62. /// Class for building VTT layout information.
  63. class VTTBuilder {
  64. ASTContext &Ctx;
  65. /// The most derived class for which we're building this vtable.
  66. const CXXRecordDecl *MostDerivedClass;
  67. using VTTVTablesVectorTy = SmallVector<VTTVTable, 64>;
  68. /// The VTT vtables.
  69. VTTVTablesVectorTy VTTVTables;
  70. using VTTComponentsVectorTy = SmallVector<VTTComponent, 64>;
  71. /// The VTT components.
  72. VTTComponentsVectorTy VTTComponents;
  73. /// The AST record layout of the most derived class.
  74. const ASTRecordLayout &MostDerivedClassLayout;
  75. using VisitedVirtualBasesSetTy = llvm::SmallPtrSet<const CXXRecordDecl *, 4>;
  76. using AddressPointsMapTy = llvm::DenseMap<BaseSubobject, uint64_t>;
  77. /// The sub-VTT indices for the bases of the most derived class.
  78. llvm::DenseMap<BaseSubobject, uint64_t> SubVTTIndicies;
  79. /// The secondary virtual pointer indices of all subobjects of
  80. /// the most derived class.
  81. llvm::DenseMap<BaseSubobject, uint64_t> SecondaryVirtualPointerIndices;
  82. /// Whether the VTT builder should generate LLVM IR for the VTT.
  83. bool GenerateDefinition;
  84. /// Add a vtable pointer to the VTT currently being built.
  85. void AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
  86. const CXXRecordDecl *VTableClass);
  87. /// Lay out the secondary VTTs of the given base subobject.
  88. void LayoutSecondaryVTTs(BaseSubobject Base);
  89. /// Lay out the secondary virtual pointers for the given base
  90. /// subobject.
  91. ///
  92. /// \param BaseIsMorallyVirtual whether the base subobject is a virtual base
  93. /// or a direct or indirect base of a virtual base.
  94. void LayoutSecondaryVirtualPointers(BaseSubobject Base,
  95. bool BaseIsMorallyVirtual,
  96. uint64_t VTableIndex,
  97. const CXXRecordDecl *VTableClass,
  98. VisitedVirtualBasesSetTy &VBases);
  99. /// Lay out the secondary virtual pointers for the given base
  100. /// subobject.
  101. void LayoutSecondaryVirtualPointers(BaseSubobject Base,
  102. uint64_t VTableIndex);
  103. /// Lay out the VTTs for the virtual base classes of the given
  104. /// record declaration.
  105. void LayoutVirtualVTTs(const CXXRecordDecl *RD,
  106. VisitedVirtualBasesSetTy &VBases);
  107. /// Lay out the VTT for the given subobject, including any
  108. /// secondary VTTs, secondary virtual pointers and virtual VTTs.
  109. void LayoutVTT(BaseSubobject Base, bool BaseIsVirtual);
  110. public:
  111. VTTBuilder(ASTContext &Ctx, const CXXRecordDecl *MostDerivedClass,
  112. bool GenerateDefinition);
  113. // Returns a reference to the VTT components.
  114. const VTTComponentsVectorTy &getVTTComponents() const {
  115. return VTTComponents;
  116. }
  117. // Returns a reference to the VTT vtables.
  118. const VTTVTablesVectorTy &getVTTVTables() const {
  119. return VTTVTables;
  120. }
  121. /// Returns a reference to the sub-VTT indices.
  122. const llvm::DenseMap<BaseSubobject, uint64_t> &getSubVTTIndicies() const {
  123. return SubVTTIndicies;
  124. }
  125. /// Returns a reference to the secondary virtual pointer indices.
  126. const llvm::DenseMap<BaseSubobject, uint64_t> &
  127. getSecondaryVirtualPointerIndices() const {
  128. return SecondaryVirtualPointerIndices;
  129. }
  130. };
  131. } // namespace clang
  132. #endif // LLVM_CLANG_AST_VTTBUILDER_H
  133. #ifdef __GNUC__
  134. #pragma GCC diagnostic pop
  135. #endif