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