xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CGVTables.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- CGVTables.h - Emit LLVM Code for C++ vtables -----------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This contains code dealing with C++ code generation of virtual tables.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H
14e5dd7070Spatrick #define LLVM_CLANG_LIB_CODEGEN_CGVTABLES_H
15e5dd7070Spatrick 
16e5dd7070Spatrick #include "clang/AST/BaseSubobject.h"
17e5dd7070Spatrick #include "clang/AST/CharUnits.h"
18e5dd7070Spatrick #include "clang/AST/GlobalDecl.h"
19e5dd7070Spatrick #include "clang/AST/VTableBuilder.h"
20e5dd7070Spatrick #include "clang/Basic/ABI.h"
21e5dd7070Spatrick #include "llvm/ADT/DenseMap.h"
22e5dd7070Spatrick #include "llvm/IR/GlobalVariable.h"
23e5dd7070Spatrick 
24e5dd7070Spatrick namespace clang {
25e5dd7070Spatrick   class CXXRecordDecl;
26e5dd7070Spatrick 
27e5dd7070Spatrick namespace CodeGen {
28e5dd7070Spatrick   class CodeGenModule;
29e5dd7070Spatrick   class ConstantArrayBuilder;
30e5dd7070Spatrick   class ConstantStructBuilder;
31e5dd7070Spatrick 
32e5dd7070Spatrick class CodeGenVTables {
33e5dd7070Spatrick   CodeGenModule &CGM;
34e5dd7070Spatrick 
35e5dd7070Spatrick   VTableContextBase *VTContext;
36e5dd7070Spatrick 
37e5dd7070Spatrick   /// VTableAddressPointsMapTy - Address points for a single vtable.
38e5dd7070Spatrick   typedef VTableLayout::AddressPointsMapTy VTableAddressPointsMapTy;
39e5dd7070Spatrick 
40e5dd7070Spatrick   typedef std::pair<const CXXRecordDecl *, BaseSubobject> BaseSubobjectPairTy;
41e5dd7070Spatrick   typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t> SubVTTIndiciesMapTy;
42e5dd7070Spatrick 
43e5dd7070Spatrick   /// SubVTTIndicies - Contains indices into the various sub-VTTs.
44e5dd7070Spatrick   SubVTTIndiciesMapTy SubVTTIndicies;
45e5dd7070Spatrick 
46e5dd7070Spatrick   typedef llvm::DenseMap<BaseSubobjectPairTy, uint64_t>
47e5dd7070Spatrick     SecondaryVirtualPointerIndicesMapTy;
48e5dd7070Spatrick 
49e5dd7070Spatrick   /// SecondaryVirtualPointerIndices - Contains the secondary virtual pointer
50e5dd7070Spatrick   /// indices.
51e5dd7070Spatrick   SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
52e5dd7070Spatrick 
53e5dd7070Spatrick   /// Cache for the pure virtual member call function.
54e5dd7070Spatrick   llvm::Constant *PureVirtualFn = nullptr;
55e5dd7070Spatrick 
56e5dd7070Spatrick   /// Cache for the deleted virtual member call function.
57e5dd7070Spatrick   llvm::Constant *DeletedVirtualFn = nullptr;
58e5dd7070Spatrick 
59e5dd7070Spatrick   /// Get the address of a thunk and emit it if necessary.
60e5dd7070Spatrick   llvm::Constant *maybeEmitThunk(GlobalDecl GD,
61e5dd7070Spatrick                                  const ThunkInfo &ThunkAdjustments,
62e5dd7070Spatrick                                  bool ForVTable);
63e5dd7070Spatrick 
64e5dd7070Spatrick   void addVTableComponent(ConstantArrayBuilder &builder,
65ec727ea7Spatrick                           const VTableLayout &layout, unsigned componentIndex,
66ec727ea7Spatrick                           llvm::Constant *rtti, unsigned &nextVTableThunkIndex,
67ec727ea7Spatrick                           unsigned vtableAddressPoint,
68ec727ea7Spatrick                           bool vtableHasLocalLinkage);
69ec727ea7Spatrick 
70ec727ea7Spatrick   /// Add a 32-bit offset to a component relative to the vtable when using the
71ec727ea7Spatrick   /// relative vtables ABI. The array builder points to the start of the vtable.
72ec727ea7Spatrick   void addRelativeComponent(ConstantArrayBuilder &builder,
73ec727ea7Spatrick                             llvm::Constant *component,
74ec727ea7Spatrick                             unsigned vtableAddressPoint,
75ec727ea7Spatrick                             bool vtableHasLocalLinkage,
76ec727ea7Spatrick                             bool isCompleteDtor) const;
77ec727ea7Spatrick 
78ec727ea7Spatrick   /// Create a dso_local stub that will be used for a relative reference in the
79ec727ea7Spatrick   /// relative vtable layout. This stub will just be a tail call to the original
80ec727ea7Spatrick   /// function and propagate any function attributes from the original. If the
81ec727ea7Spatrick   /// original function is already dso_local, the original is returned instead
82ec727ea7Spatrick   /// and a stub is not created.
83ec727ea7Spatrick   llvm::Function *
84ec727ea7Spatrick   getOrCreateRelativeStub(llvm::Function *func,
85ec727ea7Spatrick                           llvm::GlobalValue::LinkageTypes stubLinkage,
86ec727ea7Spatrick                           bool isCompleteDtor) const;
87ec727ea7Spatrick 
88ec727ea7Spatrick   bool useRelativeLayout() const;
89ec727ea7Spatrick 
90ec727ea7Spatrick   llvm::Type *getVTableComponentType() const;
91e5dd7070Spatrick 
92e5dd7070Spatrick public:
93e5dd7070Spatrick   /// Add vtable components for the given vtable layout to the given
94e5dd7070Spatrick   /// global initializer.
95e5dd7070Spatrick   void createVTableInitializer(ConstantStructBuilder &builder,
96ec727ea7Spatrick                                const VTableLayout &layout, llvm::Constant *rtti,
97ec727ea7Spatrick                                bool vtableHasLocalLinkage);
98e5dd7070Spatrick 
99e5dd7070Spatrick   CodeGenVTables(CodeGenModule &CGM);
100e5dd7070Spatrick 
getItaniumVTableContext()101e5dd7070Spatrick   ItaniumVTableContext &getItaniumVTableContext() {
102e5dd7070Spatrick     return *cast<ItaniumVTableContext>(VTContext);
103e5dd7070Spatrick   }
104e5dd7070Spatrick 
getItaniumVTableContext()105*12c85518Srobert   const ItaniumVTableContext &getItaniumVTableContext() const {
106*12c85518Srobert     return *cast<ItaniumVTableContext>(VTContext);
107*12c85518Srobert   }
108*12c85518Srobert 
getMicrosoftVTableContext()109e5dd7070Spatrick   MicrosoftVTableContext &getMicrosoftVTableContext() {
110e5dd7070Spatrick     return *cast<MicrosoftVTableContext>(VTContext);
111e5dd7070Spatrick   }
112e5dd7070Spatrick 
113e5dd7070Spatrick   /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
114e5dd7070Spatrick   /// given record decl.
115e5dd7070Spatrick   uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base);
116e5dd7070Spatrick 
117e5dd7070Spatrick   /// getSecondaryVirtualPointerIndex - Return the index in the VTT where the
118e5dd7070Spatrick   /// virtual pointer for the given subobject is located.
119e5dd7070Spatrick   uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *RD,
120e5dd7070Spatrick                                            BaseSubobject Base);
121e5dd7070Spatrick 
122e5dd7070Spatrick   /// GenerateConstructionVTable - Generate a construction vtable for the given
123e5dd7070Spatrick   /// base subobject.
124e5dd7070Spatrick   llvm::GlobalVariable *
125e5dd7070Spatrick   GenerateConstructionVTable(const CXXRecordDecl *RD, const BaseSubobject &Base,
126e5dd7070Spatrick                              bool BaseIsVirtual,
127e5dd7070Spatrick                              llvm::GlobalVariable::LinkageTypes Linkage,
128e5dd7070Spatrick                              VTableAddressPointsMapTy& AddressPoints);
129e5dd7070Spatrick 
130e5dd7070Spatrick 
131e5dd7070Spatrick   /// GetAddrOfVTT - Get the address of the VTT for the given record decl.
132e5dd7070Spatrick   llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
133e5dd7070Spatrick 
134e5dd7070Spatrick   /// EmitVTTDefinition - Emit the definition of the given vtable.
135e5dd7070Spatrick   void EmitVTTDefinition(llvm::GlobalVariable *VTT,
136e5dd7070Spatrick                          llvm::GlobalVariable::LinkageTypes Linkage,
137e5dd7070Spatrick                          const CXXRecordDecl *RD);
138e5dd7070Spatrick 
139e5dd7070Spatrick   /// EmitThunks - Emit the associated thunks for the given global decl.
140e5dd7070Spatrick   void EmitThunks(GlobalDecl GD);
141e5dd7070Spatrick 
142e5dd7070Spatrick   /// GenerateClassData - Generate all the class data required to be
143e5dd7070Spatrick   /// generated upon definition of a KeyFunction.  This includes the
144e5dd7070Spatrick   /// vtable, the RTTI data structure (if RTTI is enabled) and the VTT
145e5dd7070Spatrick   /// (if the class has virtual bases).
146e5dd7070Spatrick   void GenerateClassData(const CXXRecordDecl *RD);
147e5dd7070Spatrick 
148e5dd7070Spatrick   bool isVTableExternal(const CXXRecordDecl *RD);
149e5dd7070Spatrick 
150e5dd7070Spatrick   /// Returns the type of a vtable with the given layout. Normally a struct of
151e5dd7070Spatrick   /// arrays of pointers, with one struct element for each vtable in the vtable
152e5dd7070Spatrick   /// group.
153e5dd7070Spatrick   llvm::Type *getVTableType(const VTableLayout &layout);
154ec727ea7Spatrick 
155ec727ea7Spatrick   /// Generate a public facing alias for the vtable and make the vtable either
156ec727ea7Spatrick   /// hidden or private. The alias will have the original linkage and visibility
157ec727ea7Spatrick   /// of the vtable. This is used for cases under the relative vtables ABI
158ec727ea7Spatrick   /// when a vtable may not be dso_local.
159ec727ea7Spatrick   void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
160ec727ea7Spatrick                                    llvm::StringRef AliasNameRef);
161*12c85518Srobert 
162*12c85518Srobert   /// Specify a global should not be instrumented with hwasan.
163*12c85518Srobert   void RemoveHwasanMetadata(llvm::GlobalValue *GV) const;
164e5dd7070Spatrick };
165e5dd7070Spatrick 
166e5dd7070Spatrick } // end namespace CodeGen
167e5dd7070Spatrick } // end namespace clang
168e5dd7070Spatrick #endif
169