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