1 //===--- CGVTT.cpp - Emit LLVM Code for C++ VTTs --------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This contains code dealing with C++ code generation of VTTs (vtable tables).
11 //===----------------------------------------------------------------------===//
13 #include "CodeGenModule.h"
15 #include "clang/AST/RecordLayout.h"
16 #include "clang/AST/VTTBuilder.h"
17 using namespace clang
;
18 using namespace CodeGen
;
20 static llvm::GlobalVariable
*
21 GetAddrOfVTTVTable(CodeGenVTables
&CGVT
, CodeGenModule
&CGM
,
22 const CXXRecordDecl
*MostDerivedClass
,
23 const VTTVTable
&VTable
,
24 llvm::GlobalVariable::LinkageTypes Linkage
,
25 VTableLayout::AddressPointsMapTy
&AddressPoints
) {
26 if (VTable
.getBase() == MostDerivedClass
) {
27 assert(VTable
.getBaseOffset().isZero() &&
28 "Most derived class vtable must have a zero offset!");
29 // This is a regular vtable.
30 return CGM
.getCXXABI().getAddrOfVTable(MostDerivedClass
, CharUnits());
33 return CGVT
.GenerateConstructionVTable(MostDerivedClass
,
34 VTable
.getBaseSubobject(),
41 CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable
*VTT
,
42 llvm::GlobalVariable::LinkageTypes Linkage
,
43 const CXXRecordDecl
*RD
) {
44 VTTBuilder
Builder(CGM
.getContext(), RD
, /*GenerateDefinition=*/true);
45 llvm::ArrayType
*ArrayType
= llvm::ArrayType::get(
46 CGM
.GlobalsInt8PtrTy
, Builder
.getVTTComponents().size());
48 SmallVector
<llvm::GlobalVariable
*, 8> VTables
;
49 SmallVector
<VTableAddressPointsMapTy
, 8> VTableAddressPoints
;
50 for (const VTTVTable
*i
= Builder
.getVTTVTables().begin(),
51 *e
= Builder
.getVTTVTables().end(); i
!= e
; ++i
) {
52 VTableAddressPoints
.push_back(VTableAddressPointsMapTy());
53 VTables
.push_back(GetAddrOfVTTVTable(*this, CGM
, RD
, *i
, Linkage
,
54 VTableAddressPoints
.back()));
57 SmallVector
<llvm::Constant
*, 8> VTTComponents
;
58 for (const VTTComponent
*i
= Builder
.getVTTComponents().begin(),
59 *e
= Builder
.getVTTComponents().end(); i
!= e
; ++i
) {
60 const VTTVTable
&VTTVT
= Builder
.getVTTVTables()[i
->VTableIndex
];
61 llvm::GlobalVariable
*VTable
= VTables
[i
->VTableIndex
];
62 VTableLayout::AddressPointLocation AddressPoint
;
63 if (VTTVT
.getBase() == RD
) {
64 // Just get the address point for the regular vtable.
66 getItaniumVTableContext().getVTableLayout(RD
).getAddressPoint(
69 AddressPoint
= VTableAddressPoints
[i
->VTableIndex
].lookup(i
->VTableBase
);
70 assert(AddressPoint
.AddressPointIndex
!= 0 &&
71 "Did not find ctor vtable address point!");
74 llvm::Value
*Idxs
[] = {
75 llvm::ConstantInt::get(CGM
.Int32Ty
, 0),
76 llvm::ConstantInt::get(CGM
.Int32Ty
, AddressPoint
.VTableIndex
),
77 llvm::ConstantInt::get(CGM
.Int32Ty
, AddressPoint
.AddressPointIndex
),
80 llvm::Constant
*Init
= llvm::ConstantExpr::getGetElementPtr(
81 VTable
->getValueType(), VTable
, Idxs
, /*InBounds=*/true,
84 VTTComponents
.push_back(Init
);
87 llvm::Constant
*Init
= llvm::ConstantArray::get(ArrayType
, VTTComponents
);
89 VTT
->setInitializer(Init
);
91 // Set the correct linkage.
92 VTT
->setLinkage(Linkage
);
94 if (CGM
.supportsCOMDAT() && VTT
->isWeakForLinker())
95 VTT
->setComdat(CGM
.getModule().getOrInsertComdat(VTT
->getName()));
97 // Set the visibility. This will already have been set on the VTT declaration.
98 // Set it again, now that we have a definition, as the implicit visibility can
99 // apply differently to definitions.
100 CGM
.setGVProperties(VTT
, RD
);
103 llvm::GlobalVariable
*CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl
*RD
) {
104 assert(RD
->getNumVBases() && "Only classes with virtual bases need a VTT");
106 SmallString
<256> OutName
;
107 llvm::raw_svector_ostream
Out(OutName
);
108 cast
<ItaniumMangleContext
>(CGM
.getCXXABI().getMangleContext())
109 .mangleCXXVTT(RD
, Out
);
110 StringRef Name
= OutName
.str();
112 // This will also defer the definition of the VTT.
113 (void) CGM
.getCXXABI().getAddrOfVTable(RD
, CharUnits());
115 VTTBuilder
Builder(CGM
.getContext(), RD
, /*GenerateDefinition=*/false);
117 llvm::ArrayType
*ArrayType
= llvm::ArrayType::get(
118 CGM
.GlobalsInt8PtrTy
, Builder
.getVTTComponents().size());
119 llvm::Align Align
= CGM
.getDataLayout().getABITypeAlign(CGM
.GlobalsInt8PtrTy
);
121 llvm::GlobalVariable
*GV
= CGM
.CreateOrReplaceCXXRuntimeVariable(
122 Name
, ArrayType
, llvm::GlobalValue::ExternalLinkage
, Align
);
123 GV
->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global
);
124 CGM
.setGVProperties(GV
, RD
);
128 uint64_t CodeGenVTables::getSubVTTIndex(const CXXRecordDecl
*RD
,
129 BaseSubobject Base
) {
130 BaseSubobjectPairTy
ClassSubobjectPair(RD
, Base
);
132 SubVTTIndiciesMapTy::iterator I
= SubVTTIndicies
.find(ClassSubobjectPair
);
133 if (I
!= SubVTTIndicies
.end())
136 VTTBuilder
Builder(CGM
.getContext(), RD
, /*GenerateDefinition=*/false);
138 for (llvm::DenseMap
<BaseSubobject
, uint64_t>::const_iterator I
=
139 Builder
.getSubVTTIndicies().begin(),
140 E
= Builder
.getSubVTTIndicies().end(); I
!= E
; ++I
) {
141 // Insert all indices.
142 BaseSubobjectPairTy
ClassSubobjectPair(RD
, I
->first
);
144 SubVTTIndicies
.insert(std::make_pair(ClassSubobjectPair
, I
->second
));
147 I
= SubVTTIndicies
.find(ClassSubobjectPair
);
148 assert(I
!= SubVTTIndicies
.end() && "Did not find index!");
154 CodeGenVTables::getSecondaryVirtualPointerIndex(const CXXRecordDecl
*RD
,
155 BaseSubobject Base
) {
156 SecondaryVirtualPointerIndicesMapTy::iterator I
=
157 SecondaryVirtualPointerIndices
.find(std::make_pair(RD
, Base
));
159 if (I
!= SecondaryVirtualPointerIndices
.end())
162 VTTBuilder
Builder(CGM
.getContext(), RD
, /*GenerateDefinition=*/false);
164 // Insert all secondary vpointer indices.
165 for (llvm::DenseMap
<BaseSubobject
, uint64_t>::const_iterator I
=
166 Builder
.getSecondaryVirtualPointerIndices().begin(),
167 E
= Builder
.getSecondaryVirtualPointerIndices().end(); I
!= E
; ++I
) {
168 std::pair
<const CXXRecordDecl
*, BaseSubobject
> Pair
=
169 std::make_pair(RD
, I
->first
);
171 SecondaryVirtualPointerIndices
.insert(std::make_pair(Pair
, I
->second
));
174 I
= SecondaryVirtualPointerIndices
.find(std::make_pair(RD
, Base
));
175 assert(I
!= SecondaryVirtualPointerIndices
.end() && "Did not find index!");