VTTBuilder.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //===--- VTTBuilder.cpp - C++ VTT layout builder --------------------------===//
  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. // This contains code dealing with generation of the layout of virtual table
  11. // tables (VTT).
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/AST/VTTBuilder.h"
  15. #include "clang/AST/ASTContext.h"
  16. #include "clang/AST/CXXInheritance.h"
  17. #include "clang/AST/RecordLayout.h"
  18. #include "clang/Basic/TargetInfo.h"
  19. #include "llvm/Support/Format.h"
  20. #include <algorithm>
  21. #include <cstdio>
  22. using namespace clang;
  23. #define DUMP_OVERRIDERS 0
  24. VTTBuilder::VTTBuilder(ASTContext &Ctx,
  25. const CXXRecordDecl *MostDerivedClass,
  26. bool GenerateDefinition)
  27. : Ctx(Ctx), MostDerivedClass(MostDerivedClass),
  28. MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)),
  29. GenerateDefinition(GenerateDefinition) {
  30. // Lay out this VTT.
  31. LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()),
  32. /*BaseIsVirtual=*/false);
  33. }
  34. void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
  35. const CXXRecordDecl *VTableClass) {
  36. // Store the vtable pointer index if we're generating the primary VTT.
  37. if (VTableClass == MostDerivedClass) {
  38. assert(!SecondaryVirtualPointerIndices.count(Base) &&
  39. "A virtual pointer index already exists for this base subobject!");
  40. SecondaryVirtualPointerIndices[Base] = VTTComponents.size();
  41. }
  42. if (!GenerateDefinition) {
  43. VTTComponents.push_back(VTTComponent());
  44. return;
  45. }
  46. VTTComponents.push_back(VTTComponent(VTableIndex, Base));
  47. }
  48. void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
  49. const CXXRecordDecl *RD = Base.getBase();
  50. for (const auto &I : RD->bases()) {
  51. // Don't layout virtual bases.
  52. if (I.isVirtual())
  53. continue;
  54. const CXXRecordDecl *BaseDecl =
  55. cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
  56. const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
  57. CharUnits BaseOffset = Base.getBaseOffset() +
  58. Layout.getBaseClassOffset(BaseDecl);
  59. // Layout the VTT for this base.
  60. LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/false);
  61. }
  62. }
  63. void
  64. VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
  65. bool BaseIsMorallyVirtual,
  66. uint64_t VTableIndex,
  67. const CXXRecordDecl *VTableClass,
  68. VisitedVirtualBasesSetTy &VBases) {
  69. const CXXRecordDecl *RD = Base.getBase();
  70. // We're not interested in bases that don't have virtual bases, and not
  71. // morally virtual bases.
  72. if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
  73. return;
  74. for (const auto &I : RD->bases()) {
  75. const CXXRecordDecl *BaseDecl =
  76. cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
  77. // Itanium C++ ABI 2.6.2:
  78. // Secondary virtual pointers are present for all bases with either
  79. // virtual bases or virtual function declarations overridden along a
  80. // virtual path.
  81. //
  82. // If the base class is not dynamic, we don't want to add it, nor any
  83. // of its base classes.
  84. if (!BaseDecl->isDynamicClass())
  85. continue;
  86. bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
  87. bool BaseDeclIsNonVirtualPrimaryBase = false;
  88. CharUnits BaseOffset;
  89. if (I.isVirtual()) {
  90. // Ignore virtual bases that we've already visited.
  91. if (!VBases.insert(BaseDecl).second)
  92. continue;
  93. BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
  94. BaseDeclIsMorallyVirtual = true;
  95. } else {
  96. const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
  97. BaseOffset = Base.getBaseOffset() +
  98. Layout.getBaseClassOffset(BaseDecl);
  99. if (!Layout.isPrimaryBaseVirtual() &&
  100. Layout.getPrimaryBase() == BaseDecl)
  101. BaseDeclIsNonVirtualPrimaryBase = true;
  102. }
  103. // Itanium C++ ABI 2.6.2:
  104. // Secondary virtual pointers: for each base class X which (a) has virtual
  105. // bases or is reachable along a virtual path from D, and (b) is not a
  106. // non-virtual primary base, the address of the virtual table for X-in-D
  107. // or an appropriate construction virtual table.
  108. if (!BaseDeclIsNonVirtualPrimaryBase &&
  109. (BaseDecl->getNumVBases() || BaseDeclIsMorallyVirtual)) {
  110. // Add the vtable pointer.
  111. AddVTablePointer(BaseSubobject(BaseDecl, BaseOffset), VTableIndex,
  112. VTableClass);
  113. }
  114. // And lay out the secondary virtual pointers for the base class.
  115. LayoutSecondaryVirtualPointers(BaseSubobject(BaseDecl, BaseOffset),
  116. BaseDeclIsMorallyVirtual, VTableIndex,
  117. VTableClass, VBases);
  118. }
  119. }
  120. void
  121. VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
  122. uint64_t VTableIndex) {
  123. VisitedVirtualBasesSetTy VBases;
  124. LayoutSecondaryVirtualPointers(Base, /*BaseIsMorallyVirtual=*/false,
  125. VTableIndex, Base.getBase(), VBases);
  126. }
  127. void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
  128. VisitedVirtualBasesSetTy &VBases) {
  129. for (const auto &I : RD->bases()) {
  130. const CXXRecordDecl *BaseDecl =
  131. cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
  132. // Check if this is a virtual base.
  133. if (I.isVirtual()) {
  134. // Check if we've seen this base before.
  135. if (!VBases.insert(BaseDecl).second)
  136. continue;
  137. CharUnits BaseOffset =
  138. MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
  139. LayoutVTT(BaseSubobject(BaseDecl, BaseOffset), /*BaseIsVirtual=*/true);
  140. }
  141. // We only need to layout virtual VTTs for this base if it actually has
  142. // virtual bases.
  143. if (BaseDecl->getNumVBases())
  144. LayoutVirtualVTTs(BaseDecl, VBases);
  145. }
  146. }
  147. void VTTBuilder::LayoutVTT(BaseSubobject Base, bool BaseIsVirtual) {
  148. const CXXRecordDecl *RD = Base.getBase();
  149. // Itanium C++ ABI 2.6.2:
  150. // An array of virtual table addresses, called the VTT, is declared for
  151. // each class type that has indirect or direct virtual base classes.
  152. if (RD->getNumVBases() == 0)
  153. return;
  154. bool IsPrimaryVTT = Base.getBase() == MostDerivedClass;
  155. if (!IsPrimaryVTT) {
  156. // Remember the sub-VTT index.
  157. SubVTTIndicies[Base] = VTTComponents.size();
  158. }
  159. uint64_t VTableIndex = VTTVTables.size();
  160. VTTVTables.push_back(VTTVTable(Base, BaseIsVirtual));
  161. // Add the primary vtable pointer.
  162. AddVTablePointer(Base, VTableIndex, RD);
  163. // Add the secondary VTTs.
  164. LayoutSecondaryVTTs(Base);
  165. // Add the secondary virtual pointers.
  166. LayoutSecondaryVirtualPointers(Base, VTableIndex);
  167. // If this is the primary VTT, we want to lay out virtual VTTs as well.
  168. if (IsPrimaryVTT) {
  169. VisitedVirtualBasesSetTy VBases;
  170. LayoutVirtualVTTs(Base.getBase(), VBases);
  171. }
  172. }