1 //===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- 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 C++ code generation of virtual tables. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef CLANG_CODEGEN_CGVTABLE_H 15 #define CLANG_CODEGEN_CGVTABLE_H 16 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/GlobalVariable.h" 19 #include "clang/Basic/ABI.h" 20 #include "clang/AST/CharUnits.h" 21 #include "clang/AST/GlobalDecl.h" 22 23 namespace clang { 24 class CXXRecordDecl; 25 26 namespace CodeGen { 27 class CodeGenModule; 28 29 // BaseSubobject - Uniquely identifies a direct or indirect base class. 30 // Stores both the base class decl and the offset from the most derived class to 31 // the base class. 32 class BaseSubobject { 33 /// Base - The base class declaration. 34 const CXXRecordDecl *Base; 35 36 /// BaseOffset - The offset from the most derived class to the base class. 37 CharUnits BaseOffset; 38 39 public: 40 BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset) 41 : Base(Base), BaseOffset(BaseOffset) { } 42 43 /// getBase - Returns the base class declaration. 44 const CXXRecordDecl *getBase() const { return Base; } 45 46 /// getBaseOffset - Returns the base class offset. 47 CharUnits getBaseOffset() const { return BaseOffset; } 48 49 friend bool operator==(const BaseSubobject &LHS, const BaseSubobject &RHS) { 50 return LHS.Base == RHS.Base && LHS.BaseOffset == RHS.BaseOffset; 51 } 52 }; 53 54 } // end namespace CodeGen 55 } // end namespace clang 56 57 namespace llvm { 58 59 template<> struct DenseMapInfo<clang::CodeGen::BaseSubobject> { 60 static clang::CodeGen::BaseSubobject getEmptyKey() { 61 return clang::CodeGen::BaseSubobject( 62 DenseMapInfo<const clang::CXXRecordDecl *>::getEmptyKey(), 63 clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getEmptyKey())); 64 } 65 66 static clang::CodeGen::BaseSubobject getTombstoneKey() { 67 return clang::CodeGen::BaseSubobject( 68 DenseMapInfo<const clang::CXXRecordDecl *>::getTombstoneKey(), 69 clang::CharUnits::fromQuantity(DenseMapInfo<int64_t>::getTombstoneKey())); 70 } 71 72 static unsigned getHashValue(const clang::CodeGen::BaseSubobject &Base) { 73 return 74 DenseMapInfo<const clang::CXXRecordDecl *>::getHashValue(Base.getBase()) ^ 75 DenseMapInfo<int64_t>::getHashValue(Base.getBaseOffset().getQuantity()); 76 } 77 78 static bool isEqual(const clang::CodeGen::BaseSubobject &LHS, 79 const clang::CodeGen::BaseSubobject &RHS) { 80 return LHS == RHS; 81 } 82 }; 83 84 // It's OK to treat BaseSubobject as a POD type. 85 template <> struct isPodLike<clang::CodeGen::BaseSubobject> { 86 static const bool value = true; 87 }; 88 89 } 90 91 namespace clang { 92 namespace CodeGen { 93 94 class CodeGenVTables { 95 CodeGenModule &CGM; 96 97 /// MethodVTableIndices - Contains the index (relative to the vtable address 98 /// point) where the function pointer for a virtual function is stored. 99 typedef llvm::DenseMap<GlobalDecl, int64_t> MethodVTableIndicesTy; 100 MethodVTableIndicesTy MethodVTableIndices; 101 102 typedef std::pair<const CXXRecordDecl *, 103 const CXXRecordDecl *> ClassPairTy; 104 105 /// VirtualBaseClassOffsetOffsets - Contains the vtable offset (relative to 106 /// the address point) in chars where the offsets for virtual bases of a class 107 /// are stored. 108 typedef llvm::DenseMap<ClassPairTy, CharUnits> 109 VirtualBaseClassOffsetOffsetsMapTy; 110 VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets; 111 112 /// VTables - All the vtables which have been defined. 113 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables; 114 115 /// NumVirtualFunctionPointers - Contains the number of virtual function 116 /// pointers in the vtable for a given record decl. 117 llvm::DenseMap<const CXXRecordDecl *, uint64_t> NumVirtualFunctionPointers; 118 119 typedef llvm::SmallVector<ThunkInfo, 1> ThunkInfoVectorTy; 120 typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy; 121 122 /// Thunks - Contains all thunks that a given method decl will need. 123 ThunksMapTy Thunks; 124 125 // The layout entry and a bool indicating whether we've actually emitted 126 // the vtable. 127 typedef llvm::PointerIntPair<uint64_t *, 1, bool> VTableLayoutData; 128 typedef llvm::DenseMap<const CXXRecordDecl *, VTableLayoutData> 129 VTableLayoutMapTy; 130 131 /// VTableLayoutMap - Stores the vtable layout for all record decls. 132 /// The layout is stored as an array of 64-bit integers, where the first 133 /// integer is the number of vtable entries in the layout, and the subsequent 134 /// integers are the vtable components. 135 VTableLayoutMapTy VTableLayoutMap; 136 137 typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy; 138 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> AddressPointsMapTy; 139 140 /// Address points - Address points for all vtables. 141 AddressPointsMapTy AddressPoints; 142 143 /// VTableAddressPointsMapTy - Address points for a single vtable. 144 typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy; 145 146 typedef llvm::SmallVector<std::pair<uint64_t, ThunkInfo>, 1> 147 VTableThunksTy; 148 149 typedef llvm::DenseMap<const CXXRecordDecl *, VTableThunksTy> 150 VTableThunksMapTy; 151 152 /// VTableThunksMap - Contains thunks needed by vtables. 153 VTableThunksMapTy VTableThunksMap; 154 155 uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const { 156 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!"); 157 158 return VTableLayoutMap.lookup(RD).getPointer()[0]; 159 } 160 161 const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const { 162 assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!"); 163 164 uint64_t *Components = VTableLayoutMap.lookup(RD).getPointer(); 165 return &Components[1]; 166 } 167 168 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy; 169 170 /// SubVTTIndicies - Contains indices into the various sub-VTTs. 171 SubVTTIndiciesMapTy SubVTTIndicies; 172 173 typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> 174 SecondaryVirtualPointerIndicesMapTy; 175 176 /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer 177 /// indices. 178 SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices; 179 180 /// getNumVirtualFunctionPointers - Return the number of virtual function 181 /// pointers in the vtable for a given record decl. 182 uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); 183 184 void ComputeMethodVTableIndices(const CXXRecordDecl *RD); 185 186 /// EmitThunk - Emit a single thunk. 187 void EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk, 188 bool UseAvailableExternallyLinkage); 189 190 /// MaybeEmitThunkAvailableExternally - Try to emit the given thunk with 191 /// available_externally linkage to allow for inlining of thunks. 192 /// This will be done iff optimizations are enabled and the member function 193 /// doesn't contain any incomplete types. 194 void MaybeEmitThunkAvailableExternally(GlobalDecl GD, const ThunkInfo &Thunk); 195 196 /// ComputeVTableRelatedInformation - Compute and store all vtable related 197 /// information (vtable layout, vbase offset offsets, thunks etc) for the 198 /// given record decl. 199 void ComputeVTableRelatedInformation(const CXXRecordDecl *RD, 200 bool VTableRequired); 201 202 /// CreateVTableInitializer - Create a vtable initializer for the given record 203 /// decl. 204 /// \param Components - The vtable components; this is really an array of 205 /// VTableComponents. 206 llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD, 207 const uint64_t *Components, 208 unsigned NumComponents, 209 const VTableThunksTy &VTableThunks); 210 211 public: 212 CodeGenVTables(CodeGenModule &CGM) 213 : CGM(CGM) { } 214 215 /// \brief True if the VTable of this record must be emitted in the 216 /// translation unit. 217 bool ShouldEmitVTableInThisTU(const CXXRecordDecl *RD); 218 219 /// needsVTTParameter - Return whether the given global decl needs a VTT 220 /// parameter, which it does if it's a base constructor or destructor with 221 /// virtual bases. 222 static bool needsVTTParameter(GlobalDecl GD); 223 224 /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the 225 /// given record decl. 226 uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base); 227 228 /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the 229 /// virtual pointer for the given subobject is located. 230 uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD, 231 BaseSubobject Base); 232 233 /// getMethodVTableIndex - Return the index (relative to the vtable address 234 /// point) where the function pointer for the given virtual function is 235 /// stored. 236 uint64_t getMethodVTableIndex(GlobalDecl GD); 237 238 /// getVirtualBaseOffsetOffset - Return the offset in chars (relative to the 239 /// vtable address point) where the offset of the virtual base that contains 240 /// the given base is stored, otherwise, if no virtual base contains the given 241 /// class, return 0. Base must be a virtual base class or an unambigious 242 /// base. 243 CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, 244 const CXXRecordDecl *VBase); 245 246 /// getAddressPoint - Get the address point of the given subobject in the 247 /// class decl. 248 uint64_t getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD); 249 250 /// GetAddrOfVTable - Get the address of the vtable for the given record decl. 251 llvm::GlobalVariable *GetAddrOfVTable(const CXXRecordDecl *RD); 252 253 /// EmitVTableDefinition - Emit the definition of the given vtable. 254 void EmitVTableDefinition(llvm::GlobalVariable *VTable, 255 llvm::GlobalVariable::LinkageTypes Linkage, 256 const CXXRecordDecl *RD); 257 258 /// GenerateConstructionVTable - Generate a construction vtable for the given 259 /// base subobject. 260 llvm::GlobalVariable * 261 GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, 262 bool BaseIsVirtual, 263 llvm::GlobalVariable::LinkageTypes Linkage, 264 VTableAddressPointsMapTy& AddressPoints); 265 266 267 /// GetAddrOfVTable - Get the address of the VTT for the given record decl. 268 llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD); 269 270 /// EmitVTTDefinition - Emit the definition of the given vtable. 271 void EmitVTTDefinition(llvm::GlobalVariable *VTT, 272 llvm::GlobalVariable::LinkageTypes Linkage, 273 const CXXRecordDecl *RD); 274 275 /// EmitThunks - Emit the associated thunks for the given global decl. 276 void EmitThunks(GlobalDecl GD); 277 278 /// GenerateClassData - Generate all the class data required to be generated 279 /// upon definition of a KeyFunction. This includes the vtable, the 280 /// rtti data structure and the VTT. 281 /// 282 /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT. 283 void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, 284 const CXXRecordDecl *RD); 285 }; 286 287 } // end namespace CodeGen 288 } // end namespace clang 289 #endif 290