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