10b57cec5SDimitry Andric //===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This contains code dealing with C++ code generation of virtual tables. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/AST/BaseSubobject.h" 170b57cec5SDimitry Andric #include "clang/AST/CharUnits.h" 180b57cec5SDimitry Andric #include "clang/AST/GlobalDecl.h" 190b57cec5SDimitry Andric #include "clang/AST/VTableBuilder.h" 200b57cec5SDimitry Andric #include "clang/Basic/ABI.h" 210b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 220b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace clang { 250b57cec5SDimitry Andric class CXXRecordDecl; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace CodeGen { 280b57cec5SDimitry Andric class CodeGenModule; 290b57cec5SDimitry Andric class ConstantArrayBuilder; 300b57cec5SDimitry Andric class ConstantStructBuilder; 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric class CodeGenVTables { 330b57cec5SDimitry Andric CodeGenModule &CGM; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric VTableContextBase *VTContext; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// VTableAddressPointsMapTy - Address points for a single vtable. 380b57cec5SDimitry Andric typedef VTableLayout::AddressPointsMapTy VTableAddressPointsMapTy; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy; 41*0fca6ea1SDimitry Andric typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndicesMapTy; 420b57cec5SDimitry Andric 43*0fca6ea1SDimitry Andric /// SubVTTIndices - Contains indices into the various sub-VTTs. 44*0fca6ea1SDimitry Andric SubVTTIndicesMapTy SubVTTIndices; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> 470b57cec5SDimitry Andric SecondaryVirtualPointerIndicesMapTy; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer 500b57cec5SDimitry Andric /// indices. 510b57cec5SDimitry Andric SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric /// Cache for the pure virtual member call function. 540b57cec5SDimitry Andric llvm::Constant *PureVirtualFn = nullptr; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric /// Cache for the deleted virtual member call function. 570b57cec5SDimitry Andric llvm::Constant *DeletedVirtualFn = nullptr; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric /// Get the address of a thunk and emit it if necessary. 600b57cec5SDimitry Andric llvm::Constant *maybeEmitThunk(GlobalDecl GD, 610b57cec5SDimitry Andric const ThunkInfo &ThunkAdjustments, 620b57cec5SDimitry Andric bool ForVTable); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric void addVTableComponent(ConstantArrayBuilder &builder, 655ffd83dbSDimitry Andric const VTableLayout &layout, unsigned componentIndex, 665ffd83dbSDimitry Andric llvm::Constant *rtti, unsigned &nextVTableThunkIndex, 675ffd83dbSDimitry Andric unsigned vtableAddressPoint, 685ffd83dbSDimitry Andric bool vtableHasLocalLinkage); 695ffd83dbSDimitry Andric 705ffd83dbSDimitry Andric /// Add a 32-bit offset to a component relative to the vtable when using the 715ffd83dbSDimitry Andric /// relative vtables ABI. The array builder points to the start of the vtable. 725ffd83dbSDimitry Andric void addRelativeComponent(ConstantArrayBuilder &builder, 735ffd83dbSDimitry Andric llvm::Constant *component, 745ffd83dbSDimitry Andric unsigned vtableAddressPoint, 755ffd83dbSDimitry Andric bool vtableHasLocalLinkage, 765ffd83dbSDimitry Andric bool isCompleteDtor) const; 775ffd83dbSDimitry Andric 785ffd83dbSDimitry Andric bool useRelativeLayout() const; 795ffd83dbSDimitry Andric 805ffd83dbSDimitry Andric llvm::Type *getVTableComponentType() const; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric public: 830b57cec5SDimitry Andric /// Add vtable components for the given vtable layout to the given 840b57cec5SDimitry Andric /// global initializer. 850b57cec5SDimitry Andric void createVTableInitializer(ConstantStructBuilder &builder, 865ffd83dbSDimitry Andric const VTableLayout &layout, llvm::Constant *rtti, 875ffd83dbSDimitry Andric bool vtableHasLocalLinkage); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric CodeGenVTables(CodeGenModule &CGM); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric ItaniumVTableContext &getItaniumVTableContext() { 920b57cec5SDimitry Andric return *cast<ItaniumVTableContext>(VTContext); 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric 95bdd1243dSDimitry Andric const ItaniumVTableContext &getItaniumVTableContext() const { 96bdd1243dSDimitry Andric return *cast<ItaniumVTableContext>(VTContext); 97bdd1243dSDimitry Andric } 98bdd1243dSDimitry Andric 990b57cec5SDimitry Andric MicrosoftVTableContext &getMicrosoftVTableContext() { 1000b57cec5SDimitry Andric return *cast<MicrosoftVTableContext>(VTContext); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the 1040b57cec5SDimitry Andric /// given record decl. 1050b57cec5SDimitry Andric uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base); 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the 1080b57cec5SDimitry Andric /// virtual pointer for the given subobject is located. 1090b57cec5SDimitry Andric uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD, 1100b57cec5SDimitry Andric BaseSubobject Base); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /// GenerateConstructionVTable - Generate a construction vtable for the given 1130b57cec5SDimitry Andric /// base subobject. 1140b57cec5SDimitry Andric llvm::GlobalVariable * 1150b57cec5SDimitry Andric GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base, 1160b57cec5SDimitry Andric bool BaseIsVirtual, 1170b57cec5SDimitry Andric llvm::GlobalVariable::LinkageTypes Linkage, 1180b57cec5SDimitry Andric VTableAddressPointsMapTy& AddressPoints); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// GetAddrOfVTT - Get the address of the VTT for the given record decl. 1220b57cec5SDimitry Andric llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric /// EmitVTTDefinition - Emit the definition of the given vtable. 1250b57cec5SDimitry Andric void EmitVTTDefinition(llvm::GlobalVariable *VTT, 1260b57cec5SDimitry Andric llvm::GlobalVariable::LinkageTypes Linkage, 1270b57cec5SDimitry Andric const CXXRecordDecl *RD); 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric /// EmitThunks - Emit the associated thunks for the given global decl. 1300b57cec5SDimitry Andric void EmitThunks(GlobalDecl GD); 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric /// GenerateClassData - Generate all the class data required to be 1330b57cec5SDimitry Andric /// generated upon definition of a KeyFunction. This includes the 1340b57cec5SDimitry Andric /// vtable, the RTTI data structure (if RTTI is enabled) and the VTT 1350b57cec5SDimitry Andric /// (if the class has virtual bases). 1360b57cec5SDimitry Andric void GenerateClassData(const CXXRecordDecl *RD); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric bool isVTableExternal(const CXXRecordDecl *RD); 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric /// Returns the type of a vtable with the given layout. Normally a struct of 1410b57cec5SDimitry Andric /// arrays of pointers, with one struct element for each vtable in the vtable 1420b57cec5SDimitry Andric /// group. 1430b57cec5SDimitry Andric llvm::Type *getVTableType(const VTableLayout &layout); 1445ffd83dbSDimitry Andric 1455ffd83dbSDimitry Andric /// Generate a public facing alias for the vtable and make the vtable either 1465ffd83dbSDimitry Andric /// hidden or private. The alias will have the original linkage and visibility 1475ffd83dbSDimitry Andric /// of the vtable. This is used for cases under the relative vtables ABI 1485ffd83dbSDimitry Andric /// when a vtable may not be dso_local. 1495ffd83dbSDimitry Andric void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable, 1505ffd83dbSDimitry Andric llvm::StringRef AliasNameRef); 151bdd1243dSDimitry Andric 152bdd1243dSDimitry Andric /// Specify a global should not be instrumented with hwasan. 153bdd1243dSDimitry Andric void RemoveHwasanMetadata(llvm::GlobalValue *GV) const; 1540b57cec5SDimitry Andric }; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric } // end namespace CodeGen 1570b57cec5SDimitry Andric } // end namespace clang 1580b57cec5SDimitry Andric #endif 159