xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/CGVTables.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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