/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/CodeGen/CGVTables.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===// |
2 | | // |
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 |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This contains code dealing with C++ code generation of virtual tables. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "CGCXXABI.h" |
14 | | #include "CodeGenFunction.h" |
15 | | #include "CodeGenModule.h" |
16 | | #include "clang/AST/Attr.h" |
17 | | #include "clang/AST/CXXInheritance.h" |
18 | | #include "clang/AST/RecordLayout.h" |
19 | | #include "clang/Basic/CodeGenOptions.h" |
20 | | #include "clang/CodeGen/CGFunctionInfo.h" |
21 | | #include "clang/CodeGen/ConstantInitBuilder.h" |
22 | | #include "llvm/IR/IntrinsicInst.h" |
23 | | #include "llvm/Support/Format.h" |
24 | | #include "llvm/Transforms/Utils/Cloning.h" |
25 | | #include <algorithm> |
26 | | #include <cstdio> |
27 | | |
28 | | using namespace clang; |
29 | | using namespace CodeGen; |
30 | | |
31 | | CodeGenVTables::CodeGenVTables(CodeGenModule &CGM) |
32 | 36.4k | : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {} |
33 | | |
34 | | llvm::Constant *CodeGenModule::GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, |
35 | 1.08k | GlobalDecl GD) { |
36 | 1.08k | return GetOrCreateLLVMFunction(Name, FnTy, GD, /*ForVTable=*/true, |
37 | 1.08k | /*DontDefer=*/true, /*IsThunk=*/true); |
38 | 1.08k | } |
39 | | |
40 | | static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk, |
41 | | llvm::Function *ThunkFn, bool ForVTable, |
42 | 635 | GlobalDecl GD) { |
43 | 635 | CGM.setFunctionLinkage(GD, ThunkFn); |
44 | 635 | CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD, |
45 | 635 | !Thunk.Return.isEmpty()); |
46 | | |
47 | | // Set the right visibility. |
48 | 635 | CGM.setGVProperties(ThunkFn, GD); |
49 | | |
50 | 635 | if (!CGM.getCXXABI().exportThunk()) { |
51 | 269 | ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); |
52 | 269 | ThunkFn->setDSOLocal(true); |
53 | 269 | } |
54 | | |
55 | 635 | if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker()441 ) |
56 | 319 | ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName())); |
57 | 635 | } |
58 | | |
59 | | #ifndef NDEBUG |
60 | | static bool similar(const ABIArgInfo &infoL, CanQualType typeL, |
61 | 1.06k | const ABIArgInfo &infoR, CanQualType typeR) { |
62 | 1.06k | return (infoL.getKind() == infoR.getKind() && |
63 | 1.06k | (typeL == typeR || |
64 | 1.06k | (100 isa<PointerType>(typeL)100 && isa<PointerType>(typeR)100 ) || |
65 | 1.06k | (0 isa<ReferenceType>(typeL)0 && isa<ReferenceType>(typeR)0 ))); |
66 | 1.06k | } |
67 | | #endif |
68 | | |
69 | | static RValue PerformReturnAdjustment(CodeGenFunction &CGF, |
70 | | QualType ResultType, RValue RV, |
71 | 64 | const ThunkInfo &Thunk) { |
72 | | // Emit the return adjustment. |
73 | 64 | bool NullCheckValue = !ResultType->isReferenceType(); |
74 | | |
75 | 64 | llvm::BasicBlock *AdjustNull = nullptr; |
76 | 64 | llvm::BasicBlock *AdjustNotNull = nullptr; |
77 | 64 | llvm::BasicBlock *AdjustEnd = nullptr; |
78 | | |
79 | 64 | llvm::Value *ReturnValue = RV.getScalarVal(); |
80 | | |
81 | 64 | if (NullCheckValue) { |
82 | 57 | AdjustNull = CGF.createBasicBlock("adjust.null"); |
83 | 57 | AdjustNotNull = CGF.createBasicBlock("adjust.notnull"); |
84 | 57 | AdjustEnd = CGF.createBasicBlock("adjust.end"); |
85 | | |
86 | 57 | llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue); |
87 | 57 | CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull); |
88 | 57 | CGF.EmitBlock(AdjustNotNull); |
89 | 57 | } |
90 | | |
91 | 64 | auto ClassDecl = ResultType->getPointeeType()->getAsCXXRecordDecl(); |
92 | 64 | auto ClassAlign = CGF.CGM.getClassPointerAlignment(ClassDecl); |
93 | 64 | ReturnValue = CGF.CGM.getCXXABI().performReturnAdjustment( |
94 | 64 | CGF, |
95 | 64 | Address(ReturnValue, CGF.ConvertTypeForMem(ResultType->getPointeeType()), |
96 | 64 | ClassAlign), |
97 | 64 | Thunk.Return); |
98 | | |
99 | 64 | if (NullCheckValue) { |
100 | 57 | CGF.Builder.CreateBr(AdjustEnd); |
101 | 57 | CGF.EmitBlock(AdjustNull); |
102 | 57 | CGF.Builder.CreateBr(AdjustEnd); |
103 | 57 | CGF.EmitBlock(AdjustEnd); |
104 | | |
105 | 57 | llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2); |
106 | 57 | PHI->addIncoming(ReturnValue, AdjustNotNull); |
107 | 57 | PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()), |
108 | 57 | AdjustNull); |
109 | 57 | ReturnValue = PHI; |
110 | 57 | } |
111 | | |
112 | 64 | return RValue::get(ReturnValue); |
113 | 64 | } |
114 | | |
115 | | /// This function clones a function's DISubprogram node and enters it into |
116 | | /// a value map with the intent that the map can be utilized by the cloner |
117 | | /// to short-circuit Metadata node mapping. |
118 | | /// Furthermore, the function resolves any DILocalVariable nodes referenced |
119 | | /// by dbg.value intrinsics so they can be properly mapped during cloning. |
120 | | static void resolveTopLevelMetadata(llvm::Function *Fn, |
121 | 7 | llvm::ValueToValueMapTy &VMap) { |
122 | | // Clone the DISubprogram node and put it into the Value map. |
123 | 7 | auto *DIS = Fn->getSubprogram(); |
124 | 7 | if (!DIS) |
125 | 4 | return; |
126 | 3 | auto *NewDIS = DIS->replaceWithDistinct(DIS->clone()); |
127 | 3 | VMap.MD()[DIS].reset(NewDIS); |
128 | | |
129 | | // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes |
130 | | // they are referencing. |
131 | 3 | for (auto &BB : Fn->getBasicBlockList()) { |
132 | 17 | for (auto &I : BB) { |
133 | 17 | if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) { |
134 | 2 | auto *DILocal = DII->getVariable(); |
135 | 2 | if (!DILocal->isResolved()) |
136 | 0 | DILocal->resolve(); |
137 | 2 | } |
138 | 17 | } |
139 | 3 | } |
140 | 3 | } |
141 | | |
142 | | // This function does roughly the same thing as GenerateThunk, but in a |
143 | | // very different way, so that va_start and va_end work correctly. |
144 | | // FIXME: This function assumes "this" is the first non-sret LLVM argument of |
145 | | // a function, and that there is an alloca built in the entry block |
146 | | // for all accesses to "this". |
147 | | // FIXME: This function assumes there is only one "ret" statement per function. |
148 | | // FIXME: Cloning isn't correct in the presence of indirect goto! |
149 | | // FIXME: This implementation of thunks bloats codesize by duplicating the |
150 | | // function definition. There are alternatives: |
151 | | // 1. Add some sort of stub support to LLVM for cases where we can |
152 | | // do a this adjustment, then a sibcall. |
153 | | // 2. We could transform the definition to take a va_list instead of an |
154 | | // actual variable argument list, then have the thunks (including a |
155 | | // no-op thunk for the regular definition) call va_start/va_end. |
156 | | // There's a bit of per-call overhead for this solution, but it's |
157 | | // better for codesize if the definition is long. |
158 | | llvm::Function * |
159 | | CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn, |
160 | | const CGFunctionInfo &FnInfo, |
161 | 9 | GlobalDecl GD, const ThunkInfo &Thunk) { |
162 | 9 | const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); |
163 | 9 | const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); |
164 | 9 | QualType ResultType = FPT->getReturnType(); |
165 | | |
166 | | // Get the original function |
167 | 9 | assert(FnInfo.isVariadic()); |
168 | 0 | llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo); |
169 | 9 | llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); |
170 | 9 | llvm::Function *BaseFn = cast<llvm::Function>(Callee); |
171 | | |
172 | | // Cloning can't work if we don't have a definition. The Microsoft ABI may |
173 | | // require thunks when a definition is not available. Emit an error in these |
174 | | // cases. |
175 | 9 | if (!MD->isDefined()) { |
176 | 2 | CGM.ErrorUnsupported(MD, "return-adjusting thunk with variadic arguments"); |
177 | 2 | return Fn; |
178 | 2 | } |
179 | 7 | assert(!BaseFn->isDeclaration() && "cannot clone undefined variadic method"); |
180 | | |
181 | | // Clone to thunk. |
182 | 0 | llvm::ValueToValueMapTy VMap; |
183 | | |
184 | | // We are cloning a function while some Metadata nodes are still unresolved. |
185 | | // Ensure that the value mapper does not encounter any of them. |
186 | 7 | resolveTopLevelMetadata(BaseFn, VMap); |
187 | 7 | llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap); |
188 | 7 | Fn->replaceAllUsesWith(NewFn); |
189 | 7 | NewFn->takeName(Fn); |
190 | 7 | Fn->eraseFromParent(); |
191 | 7 | Fn = NewFn; |
192 | | |
193 | | // "Initialize" CGF (minimally). |
194 | 7 | CurFn = Fn; |
195 | | |
196 | | // Get the "this" value |
197 | 7 | llvm::Function::arg_iterator AI = Fn->arg_begin(); |
198 | 7 | if (CGM.ReturnTypeUsesSRet(FnInfo)) |
199 | 0 | ++AI; |
200 | | |
201 | | // Find the first store of "this", which will be to the alloca associated |
202 | | // with "this". |
203 | 7 | Address ThisPtr = |
204 | 7 | Address(&*AI, ConvertTypeForMem(MD->getThisType()->getPointeeType()), |
205 | 7 | CGM.getClassPointerAlignment(MD->getParent())); |
206 | 7 | llvm::BasicBlock *EntryBB = &Fn->front(); |
207 | 7 | llvm::BasicBlock::iterator ThisStore = |
208 | 20 | llvm::find_if(*EntryBB, [&](llvm::Instruction &I) { |
209 | 20 | return isa<llvm::StoreInst>(I) && |
210 | 20 | I.getOperand(0) == ThisPtr.getPointer()8 ; |
211 | 20 | }); |
212 | 7 | assert(ThisStore != EntryBB->end() && |
213 | 7 | "Store of this should be in entry block?"); |
214 | | // Adjust "this", if necessary. |
215 | 0 | Builder.SetInsertPoint(&*ThisStore); |
216 | 7 | llvm::Value *AdjustedThisPtr = |
217 | 7 | CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This); |
218 | 7 | AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, |
219 | 7 | ThisStore->getOperand(0)->getType()); |
220 | 7 | ThisStore->setOperand(0, AdjustedThisPtr); |
221 | | |
222 | 7 | if (!Thunk.Return.isEmpty()) { |
223 | | // Fix up the returned value, if necessary. |
224 | 5 | for (llvm::BasicBlock &BB : *Fn) { |
225 | 5 | llvm::Instruction *T = BB.getTerminator(); |
226 | 5 | if (isa<llvm::ReturnInst>(T)) { |
227 | 5 | RValue RV = RValue::get(T->getOperand(0)); |
228 | 5 | T->eraseFromParent(); |
229 | 5 | Builder.SetInsertPoint(&BB); |
230 | 5 | RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk); |
231 | 5 | Builder.CreateRet(RV.getScalarVal()); |
232 | 5 | break; |
233 | 5 | } |
234 | 5 | } |
235 | 5 | } |
236 | | |
237 | 7 | return Fn; |
238 | 9 | } |
239 | | |
240 | | void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD, |
241 | | const CGFunctionInfo &FnInfo, |
242 | 598 | bool IsUnprototyped) { |
243 | 598 | assert(!CurGD.getDecl() && "CurGD was already set!"); |
244 | 0 | CurGD = GD; |
245 | 598 | CurFuncIsThunk = true; |
246 | | |
247 | | // Build FunctionArgs. |
248 | 598 | const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); |
249 | 598 | QualType ThisType = MD->getThisType(); |
250 | 598 | QualType ResultType; |
251 | 598 | if (IsUnprototyped) |
252 | 6 | ResultType = CGM.getContext().VoidTy; |
253 | 592 | else if (CGM.getCXXABI().HasThisReturn(GD)) |
254 | 12 | ResultType = ThisType; |
255 | 580 | else if (CGM.getCXXABI().hasMostDerivedReturn(GD)) |
256 | 94 | ResultType = CGM.getContext().VoidPtrTy; |
257 | 486 | else |
258 | 486 | ResultType = MD->getType()->castAs<FunctionProtoType>()->getReturnType(); |
259 | 598 | FunctionArgList FunctionArgs; |
260 | | |
261 | | // Create the implicit 'this' parameter declaration. |
262 | 598 | CGM.getCXXABI().buildThisParam(*this, FunctionArgs); |
263 | | |
264 | | // Add the rest of the parameters, if we have a prototype to work with. |
265 | 598 | if (!IsUnprototyped) { |
266 | 592 | FunctionArgs.append(MD->param_begin(), MD->param_end()); |
267 | | |
268 | 592 | if (isa<CXXDestructorDecl>(MD)) |
269 | 241 | CGM.getCXXABI().addImplicitStructorParams(*this, ResultType, |
270 | 241 | FunctionArgs); |
271 | 592 | } |
272 | | |
273 | | // Start defining the function. |
274 | 598 | auto NL = ApplyDebugLocation::CreateEmpty(*this); |
275 | 598 | StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs, |
276 | 598 | MD->getLocation()); |
277 | | // Create a scope with an artificial location for the body of this function. |
278 | 598 | auto AL = ApplyDebugLocation::CreateArtificial(*this); |
279 | | |
280 | | // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves. |
281 | 598 | CGM.getCXXABI().EmitInstanceFunctionProlog(*this); |
282 | 598 | CXXThisValue = CXXABIThisValue; |
283 | 598 | CurCodeDecl = MD; |
284 | 598 | CurFuncDecl = MD; |
285 | 598 | } |
286 | | |
287 | 647 | void CodeGenFunction::FinishThunk() { |
288 | | // Clear these to restore the invariants expected by |
289 | | // StartFunction/FinishFunction. |
290 | 647 | CurCodeDecl = nullptr; |
291 | 647 | CurFuncDecl = nullptr; |
292 | | |
293 | 647 | FinishFunction(); |
294 | 647 | } |
295 | | |
296 | | void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee, |
297 | | const ThunkInfo *Thunk, |
298 | 598 | bool IsUnprototyped) { |
299 | 598 | assert(isa<CXXMethodDecl>(CurGD.getDecl()) && |
300 | 598 | "Please use a new CGF for this thunk"); |
301 | 0 | const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl()); |
302 | | |
303 | | // Adjust the 'this' pointer if necessary |
304 | 598 | llvm::Value *AdjustedThisPtr = |
305 | 598 | Thunk ? CGM.getCXXABI().performThisAdjustment( |
306 | 598 | *this, LoadCXXThisAddress(), Thunk->This) |
307 | 598 | : LoadCXXThis()0 ; |
308 | | |
309 | | // If perfect forwarding is required a variadic method, a method using |
310 | | // inalloca, or an unprototyped thunk, use musttail. Emit an error if this |
311 | | // thunk requires a return adjustment, since that is impossible with musttail. |
312 | 598 | if (CurFnInfo->usesInAlloca() || CurFnInfo->isVariadic()593 || IsUnprototyped579 ) { |
313 | 19 | if (Thunk && !Thunk->Return.isEmpty()) { |
314 | 3 | if (IsUnprototyped) |
315 | 2 | CGM.ErrorUnsupported( |
316 | 2 | MD, "return-adjusting thunk with incomplete parameter type"); |
317 | 1 | else if (CurFnInfo->isVariadic()) |
318 | 0 | llvm_unreachable("shouldn't try to emit musttail return-adjusting " |
319 | 1 | "thunks for variadic functions"); |
320 | 1 | else |
321 | 1 | CGM.ErrorUnsupported( |
322 | 1 | MD, "non-trivial argument copy for return-adjusting thunk"); |
323 | 3 | } |
324 | 19 | EmitMustTailThunk(CurGD, AdjustedThisPtr, Callee); |
325 | 19 | return; |
326 | 19 | } |
327 | | |
328 | | // Start building CallArgs. |
329 | 579 | CallArgList CallArgs; |
330 | 579 | QualType ThisType = MD->getThisType(); |
331 | 579 | CallArgs.add(RValue::get(AdjustedThisPtr), ThisType); |
332 | | |
333 | 579 | if (isa<CXXDestructorDecl>(MD)) |
334 | 241 | CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, CurGD, CallArgs); |
335 | | |
336 | 579 | #ifndef NDEBUG |
337 | 579 | unsigned PrefixArgs = CallArgs.size() - 1; |
338 | 579 | #endif |
339 | | // Add the rest of the arguments. |
340 | 579 | for (const ParmVarDecl *PD : MD->parameters()) |
341 | 49 | EmitDelegateCallArg(CallArgs, PD, SourceLocation()); |
342 | | |
343 | 579 | const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); |
344 | | |
345 | 579 | #ifndef NDEBUG |
346 | 579 | const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall( |
347 | 579 | CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1), PrefixArgs); |
348 | 579 | assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() && |
349 | 579 | CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() && |
350 | 579 | CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention()); |
351 | 0 | assert(isa<CXXDestructorDecl>(MD) || // ignore dtor return types |
352 | 579 | similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(), |
353 | 579 | CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType())); |
354 | 0 | assert(CallFnInfo.arg_size() == CurFnInfo->arg_size()); |
355 | 1.30k | for (unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i722 ) |
356 | 722 | assert(similar(CallFnInfo.arg_begin()[i].info, |
357 | 579 | CallFnInfo.arg_begin()[i].type, |
358 | 579 | CurFnInfo->arg_begin()[i].info, |
359 | 579 | CurFnInfo->arg_begin()[i].type)); |
360 | 579 | #endif |
361 | | |
362 | | // Determine whether we have a return value slot to use. |
363 | 579 | QualType ResultType = CGM.getCXXABI().HasThisReturn(CurGD) |
364 | 579 | ? ThisType12 |
365 | 579 | : CGM.getCXXABI().hasMostDerivedReturn(CurGD)567 |
366 | 567 | ? CGM.getContext().VoidPtrTy94 |
367 | 567 | : FPT->getReturnType()473 ; |
368 | 579 | ReturnValueSlot Slot; |
369 | 579 | if (!ResultType->isVoidType() && |
370 | 579 | (211 CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect211 || |
371 | 211 | hasAggregateEvaluationKind(ResultType)202 )) |
372 | 15 | Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified(), |
373 | 15 | /*IsUnused=*/false, /*IsExternallyDestructed=*/true); |
374 | | |
375 | | // Now emit our call. |
376 | 579 | llvm::CallBase *CallOrInvoke; |
377 | 579 | RValue RV = EmitCall(*CurFnInfo, CGCallee::forDirect(Callee, CurGD), Slot, |
378 | 579 | CallArgs, &CallOrInvoke); |
379 | | |
380 | | // Consider return adjustment if we have ThunkInfo. |
381 | 579 | if (Thunk && !Thunk->Return.isEmpty()) |
382 | 59 | RV = PerformReturnAdjustment(*this, ResultType, RV, *Thunk); |
383 | 520 | else if (llvm::CallInst* Call = dyn_cast<llvm::CallInst>(CallOrInvoke)) |
384 | 520 | Call->setTailCallKind(llvm::CallInst::TCK_Tail); |
385 | | |
386 | | // Emit return. |
387 | 579 | if (!ResultType->isVoidType() && Slot.isNull()211 ) |
388 | 196 | CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType); |
389 | | |
390 | | // Disable the final ARC autorelease. |
391 | 579 | AutoreleaseResult = false; |
392 | | |
393 | 579 | FinishThunk(); |
394 | 579 | } |
395 | | |
396 | | void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD, |
397 | | llvm::Value *AdjustedThisPtr, |
398 | 68 | llvm::FunctionCallee Callee) { |
399 | | // Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery |
400 | | // to translate AST arguments into LLVM IR arguments. For thunks, we know |
401 | | // that the caller prototype more or less matches the callee prototype with |
402 | | // the exception of 'this'. |
403 | 68 | SmallVector<llvm::Value *, 8> Args(llvm::make_pointer_range(CurFn->args())); |
404 | | |
405 | | // Set the adjusted 'this' pointer. |
406 | 68 | const ABIArgInfo &ThisAI = CurFnInfo->arg_begin()->info; |
407 | 68 | if (ThisAI.isDirect()) { |
408 | 66 | const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo(); |
409 | 66 | int ThisArgNo = RetAI.isIndirect() && !RetAI.isSRetAfterThis()0 ? 10 : 0; |
410 | 66 | llvm::Type *ThisType = Args[ThisArgNo]->getType(); |
411 | 66 | if (ThisType != AdjustedThisPtr->getType()) |
412 | 7 | AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType); |
413 | 66 | Args[ThisArgNo] = AdjustedThisPtr; |
414 | 66 | } else { |
415 | 2 | assert(ThisAI.isInAlloca() && "this is passed directly or inalloca"); |
416 | 0 | Address ThisAddr = GetAddrOfLocalVar(CXXABIThisDecl); |
417 | 2 | llvm::Type *ThisType = ThisAddr.getElementType(); |
418 | 2 | if (ThisType != AdjustedThisPtr->getType()) |
419 | 2 | AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType); |
420 | 2 | Builder.CreateStore(AdjustedThisPtr, ThisAddr); |
421 | 2 | } |
422 | | |
423 | | // Emit the musttail call manually. Even if the prologue pushed cleanups, we |
424 | | // don't actually want to run them. |
425 | 0 | llvm::CallInst *Call = Builder.CreateCall(Callee, Args); |
426 | 68 | Call->setTailCallKind(llvm::CallInst::TCK_MustTail); |
427 | | |
428 | | // Apply the standard set of call attributes. |
429 | 68 | unsigned CallingConv; |
430 | 68 | llvm::AttributeList Attrs; |
431 | 68 | CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD, |
432 | 68 | Attrs, CallingConv, /*AttrOnCallSite=*/true, |
433 | 68 | /*IsThunk=*/false); |
434 | 68 | Call->setAttributes(Attrs); |
435 | 68 | Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv)); |
436 | | |
437 | 68 | if (Call->getType()->isVoidTy()) |
438 | 63 | Builder.CreateRetVoid(); |
439 | 5 | else |
440 | 5 | Builder.CreateRet(Call); |
441 | | |
442 | | // Finish the function to maintain CodeGenFunction invariants. |
443 | | // FIXME: Don't emit unreachable code. |
444 | 68 | EmitBlock(createBasicBlock()); |
445 | | |
446 | 68 | FinishThunk(); |
447 | 68 | } |
448 | | |
449 | | void CodeGenFunction::generateThunk(llvm::Function *Fn, |
450 | | const CGFunctionInfo &FnInfo, GlobalDecl GD, |
451 | | const ThunkInfo &Thunk, |
452 | 598 | bool IsUnprototyped) { |
453 | 598 | StartThunk(Fn, GD, FnInfo, IsUnprototyped); |
454 | | // Create a scope with an artificial location for the body of this function. |
455 | 598 | auto AL = ApplyDebugLocation::CreateArtificial(*this); |
456 | | |
457 | | // Get our callee. Use a placeholder type if this method is unprototyped so |
458 | | // that CodeGenModule doesn't try to set attributes. |
459 | 598 | llvm::Type *Ty; |
460 | 598 | if (IsUnprototyped) |
461 | 6 | Ty = llvm::StructType::get(getLLVMContext()); |
462 | 592 | else |
463 | 592 | Ty = CGM.getTypes().GetFunctionType(FnInfo); |
464 | | |
465 | 598 | llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true); |
466 | | |
467 | | // Fix up the function type for an unprototyped musttail call. |
468 | 598 | if (IsUnprototyped) |
469 | 6 | Callee = llvm::ConstantExpr::getBitCast(Callee, Fn->getType()); |
470 | | |
471 | | // Make the call and return the result. |
472 | 598 | EmitCallAndReturnForThunk(llvm::FunctionCallee(Fn->getFunctionType(), Callee), |
473 | 598 | &Thunk, IsUnprototyped); |
474 | 598 | } |
475 | | |
476 | | static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD, |
477 | 1.08k | bool IsUnprototyped, bool ForVTable) { |
478 | | // Always emit thunks in the MS C++ ABI. We cannot rely on other TUs to |
479 | | // provide thunks for us. |
480 | 1.08k | if (CGM.getTarget().getCXXABI().isMicrosoft()) |
481 | 384 | return true; |
482 | | |
483 | | // In the Itanium C++ ABI, vtable thunks are provided by TUs that provide |
484 | | // definitions of the main method. Therefore, emitting thunks with the vtable |
485 | | // is purely an optimization. Emit the thunk if optimizations are enabled and |
486 | | // all of the parameter types are complete. |
487 | 697 | if (ForVTable) |
488 | 370 | return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped63 ; |
489 | | |
490 | | // Always emit thunks along with the method definition. |
491 | 327 | return true; |
492 | 697 | } |
493 | | |
494 | | llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD, |
495 | | const ThunkInfo &TI, |
496 | 1.08k | bool ForVTable) { |
497 | 1.08k | const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); |
498 | | |
499 | | // First, get a declaration. Compute the mangled name. Don't worry about |
500 | | // getting the function prototype right, since we may only need this |
501 | | // declaration to fill in a vtable slot. |
502 | 1.08k | SmallString<256> Name; |
503 | 1.08k | MangleContext &MCtx = CGM.getCXXABI().getMangleContext(); |
504 | 1.08k | llvm::raw_svector_ostream Out(Name); |
505 | 1.08k | if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) |
506 | 491 | MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI.This, Out); |
507 | 590 | else |
508 | 590 | MCtx.mangleThunk(MD, TI, Out); |
509 | 1.08k | llvm::Type *ThunkVTableTy = CGM.getTypes().GetFunctionTypeForVTable(GD); |
510 | 1.08k | llvm::Constant *Thunk = CGM.GetAddrOfThunk(Name, ThunkVTableTy, GD); |
511 | | |
512 | | // If we don't need to emit a definition, return this declaration as is. |
513 | 1.08k | bool IsUnprototyped = !CGM.getTypes().isFuncTypeConvertible( |
514 | 1.08k | MD->getType()->castAs<FunctionType>()); |
515 | 1.08k | if (!shouldEmitVTableThunk(CGM, MD, IsUnprototyped, ForVTable)) |
516 | 311 | return Thunk; |
517 | | |
518 | | // Arrange a function prototype appropriate for a function definition. In some |
519 | | // cases in the MS ABI, we may need to build an unprototyped musttail thunk. |
520 | 770 | const CGFunctionInfo &FnInfo = |
521 | 770 | IsUnprototyped ? CGM.getTypes().arrangeUnprototypedMustTailThunk(MD)6 |
522 | 770 | : CGM.getTypes().arrangeGlobalDeclaration(GD)764 ; |
523 | 770 | llvm::FunctionType *ThunkFnTy = CGM.getTypes().GetFunctionType(FnInfo); |
524 | | |
525 | | // If the type of the underlying GlobalValue is wrong, we'll have to replace |
526 | | // it. It should be a declaration. |
527 | 770 | llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts()); |
528 | 770 | if (ThunkFn->getFunctionType() != ThunkFnTy) { |
529 | 7 | llvm::GlobalValue *OldThunkFn = ThunkFn; |
530 | | |
531 | 7 | assert(OldThunkFn->isDeclaration() && "Shouldn't replace non-declaration"); |
532 | | |
533 | | // Remove the name from the old thunk function and get a new thunk. |
534 | 0 | OldThunkFn->setName(StringRef()); |
535 | 7 | ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage, |
536 | 7 | Name.str(), &CGM.getModule()); |
537 | 7 | CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false); |
538 | | |
539 | | // If needed, replace the old thunk with a bitcast. |
540 | 7 | if (!OldThunkFn->use_empty()) { |
541 | 4 | llvm::Constant *NewPtrForOldDecl = |
542 | 4 | llvm::ConstantExpr::getBitCast(ThunkFn, OldThunkFn->getType()); |
543 | 4 | OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl); |
544 | 4 | } |
545 | | |
546 | | // Remove the old thunk. |
547 | 7 | OldThunkFn->eraseFromParent(); |
548 | 7 | } |
549 | | |
550 | 0 | bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions(); |
551 | 770 | bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions329 ; |
552 | | |
553 | 770 | if (!ThunkFn->isDeclaration()) { |
554 | 161 | if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage46 ) { |
555 | | // There is already a thunk emitted for this function, do nothing. |
556 | 133 | return ThunkFn; |
557 | 133 | } |
558 | | |
559 | 28 | setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD); |
560 | 28 | return ThunkFn; |
561 | 161 | } |
562 | | |
563 | | // If this will be unprototyped, add the "thunk" attribute so that LLVM knows |
564 | | // that the return type is meaningless. These thunks can be used to call |
565 | | // functions with differing return types, and the caller is required to cast |
566 | | // the prototype appropriately to extract the correct value. |
567 | 609 | if (IsUnprototyped) |
568 | 6 | ThunkFn->addFnAttr("thunk"); |
569 | | |
570 | 609 | CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn); |
571 | | |
572 | | // Thunks for variadic methods are special because in general variadic |
573 | | // arguments cannot be perfectly forwarded. In the general case, clang |
574 | | // implements such thunks by cloning the original function body. However, for |
575 | | // thunks with no return adjustment on targets that support musttail, we can |
576 | | // use musttail to perfectly forward the variadic arguments. |
577 | 609 | bool ShouldCloneVarArgs = false; |
578 | 609 | if (!IsUnprototyped && ThunkFn->isVarArg()603 ) { |
579 | 19 | ShouldCloneVarArgs = true; |
580 | 19 | if (TI.Return.isEmpty()) { |
581 | 12 | switch (CGM.getTriple().getArch()) { |
582 | 8 | case llvm::Triple::x86_64: |
583 | 8 | case llvm::Triple::x86: |
584 | 8 | case llvm::Triple::aarch64: |
585 | 8 | ShouldCloneVarArgs = false; |
586 | 8 | break; |
587 | 4 | default: |
588 | 4 | break; |
589 | 12 | } |
590 | 12 | } |
591 | 19 | } |
592 | | |
593 | 609 | if (ShouldCloneVarArgs) { |
594 | 11 | if (UseAvailableExternallyLinkage) |
595 | 2 | return ThunkFn; |
596 | 9 | ThunkFn = |
597 | 9 | CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, TI); |
598 | 598 | } else { |
599 | | // Normal thunk body generation. |
600 | 598 | CodeGenFunction(CGM).generateThunk(ThunkFn, FnInfo, GD, TI, IsUnprototyped); |
601 | 598 | } |
602 | | |
603 | 607 | setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD); |
604 | 607 | return ThunkFn; |
605 | 609 | } |
606 | | |
607 | 4.18k | void CodeGenVTables::EmitThunks(GlobalDecl GD) { |
608 | 4.18k | const CXXMethodDecl *MD = |
609 | 4.18k | cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl(); |
610 | | |
611 | | // We don't need to generate thunks for the base destructor. |
612 | 4.18k | if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base2.50k ) |
613 | 854 | return; |
614 | | |
615 | 3.33k | const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector = |
616 | 3.33k | VTContext->getThunkInfo(GD); |
617 | | |
618 | 3.33k | if (!ThunkInfoVector) |
619 | 2.91k | return; |
620 | | |
621 | 418 | for (const ThunkInfo& Thunk : *ThunkInfoVector) |
622 | 441 | maybeEmitThunk(GD, Thunk, /*ForVTable=*/false); |
623 | 418 | } |
624 | | |
625 | | void CodeGenVTables::addRelativeComponent(ConstantArrayBuilder &builder, |
626 | | llvm::Constant *component, |
627 | | unsigned vtableAddressPoint, |
628 | | bool vtableHasLocalLinkage, |
629 | 167 | bool isCompleteDtor) const { |
630 | | // No need to get the offset of a nullptr. |
631 | 167 | if (component->isNullValue()) |
632 | 1 | return builder.add(llvm::ConstantInt::get(CGM.Int32Ty, 0)); |
633 | | |
634 | 166 | auto *globalVal = |
635 | 166 | cast<llvm::GlobalValue>(component->stripPointerCastsAndAliases()); |
636 | 166 | llvm::Module &module = CGM.getModule(); |
637 | | |
638 | | // We don't want to copy the linkage of the vtable exactly because we still |
639 | | // want the stub/proxy to be emitted for properly calculating the offset. |
640 | | // Examples where there would be no symbol emitted are available_externally |
641 | | // and private linkages. |
642 | 166 | auto stubLinkage = vtableHasLocalLinkage ? llvm::GlobalValue::InternalLinkage8 |
643 | 166 | : llvm::GlobalValue::ExternalLinkage158 ; |
644 | | |
645 | 166 | llvm::Constant *target; |
646 | 166 | if (auto *func = dyn_cast<llvm::Function>(globalVal)) { |
647 | 96 | target = llvm::DSOLocalEquivalent::get(func); |
648 | 96 | } else { |
649 | 70 | llvm::SmallString<16> rttiProxyName(globalVal->getName()); |
650 | 70 | rttiProxyName.append(".rtti_proxy"); |
651 | | |
652 | | // The RTTI component may not always be emitted in the same linkage unit as |
653 | | // the vtable. As a general case, we can make a dso_local proxy to the RTTI |
654 | | // that points to the actual RTTI struct somewhere. This will result in a |
655 | | // GOTPCREL relocation when taking the relative offset to the proxy. |
656 | 70 | llvm::GlobalVariable *proxy = module.getNamedGlobal(rttiProxyName); |
657 | 70 | if (!proxy) { |
658 | 50 | proxy = new llvm::GlobalVariable(module, globalVal->getType(), |
659 | 50 | /*isConstant=*/true, stubLinkage, |
660 | 50 | globalVal, rttiProxyName); |
661 | 50 | proxy->setDSOLocal(true); |
662 | 50 | proxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); |
663 | 50 | if (!proxy->hasLocalLinkage()) { |
664 | 50 | proxy->setVisibility(llvm::GlobalValue::HiddenVisibility); |
665 | 50 | proxy->setComdat(module.getOrInsertComdat(rttiProxyName)); |
666 | 50 | } |
667 | 50 | } |
668 | 70 | target = proxy; |
669 | 70 | } |
670 | | |
671 | 166 | builder.addRelativeOffsetToPosition(CGM.Int32Ty, target, |
672 | 166 | /*position=*/vtableAddressPoint); |
673 | 166 | } |
674 | | |
675 | 26.8k | bool CodeGenVTables::useRelativeLayout() const { |
676 | 26.8k | return CGM.getTarget().getCXXABI().isItaniumFamily() && |
677 | 26.8k | CGM.getItaniumVTableContext().isRelativeLayout()22.2k ; |
678 | 26.8k | } |
679 | | |
680 | 6.03k | llvm::Type *CodeGenVTables::getVTableComponentType() const { |
681 | 6.03k | if (useRelativeLayout()) |
682 | 110 | return CGM.Int32Ty; |
683 | 5.92k | return CGM.Int8PtrTy; |
684 | 6.03k | } |
685 | | |
686 | | static void AddPointerLayoutOffset(const CodeGenModule &CGM, |
687 | | ConstantArrayBuilder &builder, |
688 | 4.14k | CharUnits offset) { |
689 | 4.14k | builder.add(llvm::ConstantExpr::getIntToPtr( |
690 | 4.14k | llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()), |
691 | 4.14k | CGM.Int8PtrTy)); |
692 | 4.14k | } |
693 | | |
694 | | static void AddRelativeLayoutOffset(const CodeGenModule &CGM, |
695 | | ConstantArrayBuilder &builder, |
696 | 93 | CharUnits offset) { |
697 | 93 | builder.add(llvm::ConstantInt::get(CGM.Int32Ty, offset.getQuantity())); |
698 | 93 | } |
699 | | |
700 | | void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder, |
701 | | const VTableLayout &layout, |
702 | | unsigned componentIndex, |
703 | | llvm::Constant *rtti, |
704 | | unsigned &nextVTableThunkIndex, |
705 | | unsigned vtableAddressPoint, |
706 | 12.4k | bool vtableHasLocalLinkage) { |
707 | 12.4k | auto &component = layout.vtable_components()[componentIndex]; |
708 | | |
709 | 12.4k | auto addOffsetConstant = |
710 | 12.4k | useRelativeLayout() ? AddRelativeLayoutOffset260 : AddPointerLayoutOffset12.2k ; |
711 | | |
712 | 12.4k | switch (component.getKind()) { |
713 | 567 | case VTableComponent::CK_VCallOffset: |
714 | 567 | return addOffsetConstant(CGM, builder, component.getVCallOffset()); |
715 | | |
716 | 1.18k | case VTableComponent::CK_VBaseOffset: |
717 | 1.18k | return addOffsetConstant(CGM, builder, component.getVBaseOffset()); |
718 | | |
719 | 2.48k | case VTableComponent::CK_OffsetToTop: |
720 | 2.48k | return addOffsetConstant(CGM, builder, component.getOffsetToTop()); |
721 | | |
722 | 2.74k | case VTableComponent::CK_RTTI: |
723 | 2.74k | if (useRelativeLayout()) |
724 | 70 | return addRelativeComponent(builder, rtti, vtableAddressPoint, |
725 | 70 | vtableHasLocalLinkage, |
726 | 70 | /*isCompleteDtor=*/false); |
727 | 2.67k | else |
728 | 2.67k | return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.Int8PtrTy)); |
729 | | |
730 | 3.55k | case VTableComponent::CK_FunctionPointer: |
731 | 4.37k | case VTableComponent::CK_CompleteDtorPointer: |
732 | 5.45k | case VTableComponent::CK_DeletingDtorPointer: { |
733 | 5.45k | GlobalDecl GD = component.getGlobalDecl(); |
734 | | |
735 | 5.45k | if (CGM.getLangOpts().CUDA) { |
736 | | // Emit NULL for methods we can't codegen on this |
737 | | // side. Otherwise we'd end up with vtable with unresolved |
738 | | // references. |
739 | 21 | const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); |
740 | | // OK on device side: functions w/ __device__ attribute |
741 | | // OK on host side: anything except __device__-only functions. |
742 | 21 | bool CanEmitMethod = |
743 | 21 | CGM.getLangOpts().CUDAIsDevice |
744 | 21 | ? MD->hasAttr<CUDADeviceAttr>() |
745 | 21 | : (0 MD->hasAttr<CUDAHostAttr>()0 || !MD->hasAttr<CUDADeviceAttr>()0 ); |
746 | 21 | if (!CanEmitMethod) |
747 | 0 | return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy)); |
748 | | // Method is acceptable, continue processing as usual. |
749 | 21 | } |
750 | | |
751 | 5.45k | auto getSpecialVirtualFn = [&](StringRef name) -> llvm::Constant * { |
752 | | // FIXME(PR43094): When merging comdat groups, lld can select a local |
753 | | // symbol as the signature symbol even though it cannot be accessed |
754 | | // outside that symbol's TU. The relative vtables ABI would make |
755 | | // __cxa_pure_virtual and __cxa_deleted_virtual local symbols, and |
756 | | // depending on link order, the comdat groups could resolve to the one |
757 | | // with the local symbol. As a temporary solution, fill these components |
758 | | // with zero. We shouldn't be calling these in the first place anyway. |
759 | 80 | if (useRelativeLayout()) |
760 | 1 | return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); |
761 | | |
762 | | // For NVPTX devices in OpenMP emit special functon as null pointers, |
763 | | // otherwise linking ends up with unresolved references. |
764 | 79 | if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPIsDevice5 && |
765 | 79 | CGM.getTriple().isNVPTX()3 ) |
766 | 3 | return llvm::ConstantPointerNull::get(CGM.Int8PtrTy); |
767 | 76 | llvm::FunctionType *fnTy = |
768 | 76 | llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); |
769 | 76 | llvm::Constant *fn = cast<llvm::Constant>( |
770 | 76 | CGM.CreateRuntimeFunction(fnTy, name).getCallee()); |
771 | 76 | if (auto f = dyn_cast<llvm::Function>(fn)) |
772 | 76 | f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); |
773 | 76 | return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy); |
774 | 79 | }; |
775 | | |
776 | 5.45k | llvm::Constant *fnPtr; |
777 | | |
778 | | // Pure virtual member functions. |
779 | 5.45k | if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) { |
780 | 243 | if (!PureVirtualFn) |
781 | 71 | PureVirtualFn = |
782 | 71 | getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName()); |
783 | 243 | fnPtr = PureVirtualFn; |
784 | | |
785 | | // Deleted virtual member functions. |
786 | 5.21k | } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) { |
787 | 15 | if (!DeletedVirtualFn) |
788 | 9 | DeletedVirtualFn = |
789 | 9 | getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName()); |
790 | 15 | fnPtr = DeletedVirtualFn; |
791 | | |
792 | | // Thunks. |
793 | 5.19k | } else if (nextVTableThunkIndex < layout.vtable_thunks().size() && |
794 | 5.19k | layout.vtable_thunks()[nextVTableThunkIndex].first == |
795 | 1.11k | componentIndex) { |
796 | 640 | auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second; |
797 | | |
798 | 640 | nextVTableThunkIndex++; |
799 | 640 | fnPtr = maybeEmitThunk(GD, thunkInfo, /*ForVTable=*/true); |
800 | | |
801 | | // Otherwise we can use the method definition directly. |
802 | 4.55k | } else { |
803 | 4.55k | llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD); |
804 | 4.55k | fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true); |
805 | 4.55k | } |
806 | | |
807 | 5.45k | if (useRelativeLayout()) { |
808 | 97 | return addRelativeComponent( |
809 | 97 | builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage, |
810 | 97 | component.getKind() == VTableComponent::CK_CompleteDtorPointer); |
811 | 97 | } else |
812 | 5.35k | return builder.add(llvm::ConstantExpr::getBitCast(fnPtr, CGM.Int8PtrTy)); |
813 | 5.45k | } |
814 | | |
815 | 44 | case VTableComponent::CK_UnusedFunctionPointer: |
816 | 44 | if (useRelativeLayout()) |
817 | 0 | return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int32Ty)); |
818 | 44 | else |
819 | 44 | return builder.addNullPointer(CGM.Int8PtrTy); |
820 | 12.4k | } |
821 | | |
822 | 0 | llvm_unreachable("Unexpected vtable component kind"); |
823 | 0 | } |
824 | | |
825 | 3.28k | llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) { |
826 | 3.28k | SmallVector<llvm::Type *, 4> tys; |
827 | 3.28k | llvm::Type *componentType = getVTableComponentType(); |
828 | 7.11k | for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i3.83k ) |
829 | 3.83k | tys.push_back(llvm::ArrayType::get(componentType, layout.getVTableSize(i))); |
830 | | |
831 | 3.28k | return llvm::StructType::get(CGM.getLLVMContext(), tys); |
832 | 3.28k | } |
833 | | |
834 | | void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder, |
835 | | const VTableLayout &layout, |
836 | | llvm::Constant *rtti, |
837 | 2.75k | bool vtableHasLocalLinkage) { |
838 | 2.75k | llvm::Type *componentType = getVTableComponentType(); |
839 | | |
840 | 2.75k | const auto &addressPoints = layout.getAddressPointIndices(); |
841 | 2.75k | unsigned nextVTableThunkIndex = 0; |
842 | 2.75k | for (unsigned vtableIndex = 0, endIndex = layout.getNumVTables(); |
843 | 6.05k | vtableIndex != endIndex; ++vtableIndex3.30k ) { |
844 | 3.30k | auto vtableElem = builder.beginArray(componentType); |
845 | | |
846 | 3.30k | size_t vtableStart = layout.getVTableOffset(vtableIndex); |
847 | 3.30k | size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex); |
848 | 15.7k | for (size_t componentIndex = vtableStart; componentIndex < vtableEnd; |
849 | 12.4k | ++componentIndex) { |
850 | 12.4k | addVTableComponent(vtableElem, layout, componentIndex, rtti, |
851 | 12.4k | nextVTableThunkIndex, addressPoints[vtableIndex], |
852 | 12.4k | vtableHasLocalLinkage); |
853 | 12.4k | } |
854 | 3.30k | vtableElem.finishAndAddTo(builder); |
855 | 3.30k | } |
856 | 2.75k | } |
857 | | |
858 | | llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable( |
859 | | const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual, |
860 | | llvm::GlobalVariable::LinkageTypes Linkage, |
861 | 311 | VTableAddressPointsMapTy &AddressPoints) { |
862 | 311 | if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) |
863 | 42 | DI->completeClassData(Base.getBase()); |
864 | | |
865 | 311 | std::unique_ptr<VTableLayout> VTLayout( |
866 | 311 | getItaniumVTableContext().createConstructionVTableLayout( |
867 | 311 | Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD)); |
868 | | |
869 | | // Add the address points. |
870 | 311 | AddressPoints = VTLayout->getAddressPoints(); |
871 | | |
872 | | // Get the mangled construction vtable name. |
873 | 311 | SmallString<256> OutName; |
874 | 311 | llvm::raw_svector_ostream Out(OutName); |
875 | 311 | cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext()) |
876 | 311 | .mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(), |
877 | 311 | Base.getBase(), Out); |
878 | 311 | SmallString<256> Name(OutName); |
879 | | |
880 | 311 | bool UsingRelativeLayout = getItaniumVTableContext().isRelativeLayout(); |
881 | 311 | bool VTableAliasExists = |
882 | 311 | UsingRelativeLayout && CGM.getModule().getNamedAlias(Name)4 ; |
883 | 311 | if (VTableAliasExists) { |
884 | | // We previously made the vtable hidden and changed its name. |
885 | 2 | Name.append(".local"); |
886 | 2 | } |
887 | | |
888 | 311 | llvm::Type *VTType = getVTableType(*VTLayout); |
889 | | |
890 | | // Construction vtable symbols are not part of the Itanium ABI, so we cannot |
891 | | // guarantee that they actually will be available externally. Instead, when |
892 | | // emitting an available_externally VTT, we provide references to an internal |
893 | | // linkage construction vtable. The ABI only requires complete-object vtables |
894 | | // to be the same for all instances of a type, not construction vtables. |
895 | 311 | if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage) |
896 | 6 | Linkage = llvm::GlobalVariable::InternalLinkage; |
897 | | |
898 | 311 | unsigned Align = CGM.getDataLayout().getABITypeAlignment(VTType); |
899 | | |
900 | | // Create the variable that will hold the construction vtable. |
901 | 311 | llvm::GlobalVariable *VTable = |
902 | 311 | CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align); |
903 | | |
904 | | // V-tables are always unnamed_addr. |
905 | 311 | VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); |
906 | | |
907 | 311 | llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor( |
908 | 311 | CGM.getContext().getTagDeclType(Base.getBase())); |
909 | | |
910 | | // Create and set the initializer. |
911 | 311 | ConstantInitBuilder builder(CGM); |
912 | 311 | auto components = builder.beginStruct(); |
913 | 311 | createVTableInitializer(components, *VTLayout, RTTI, |
914 | 311 | VTable->hasLocalLinkage()); |
915 | 311 | components.finishAndSetAsInitializer(VTable); |
916 | | |
917 | | // Set properties only after the initializer has been set to ensure that the |
918 | | // GV is treated as definition and not declaration. |
919 | 311 | assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration"); |
920 | 0 | CGM.setGVProperties(VTable, RD); |
921 | | |
922 | 311 | CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout.get()); |
923 | | |
924 | 311 | if (UsingRelativeLayout && !VTable->isDSOLocal()4 ) |
925 | 2 | GenerateRelativeVTableAlias(VTable, OutName); |
926 | | |
927 | 311 | return VTable; |
928 | 311 | } |
929 | | |
930 | | // If the VTable is not dso_local, then we will not be able to indicate that |
931 | | // the VTable does not need a relocation and move into rodata. A frequent |
932 | | // time this can occur is for classes that should be made public from a DSO |
933 | | // (like in libc++). For cases like these, we can make the vtable hidden or |
934 | | // private and create a public alias with the same visibility and linkage as |
935 | | // the original vtable type. |
936 | | void CodeGenVTables::GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable, |
937 | 51 | llvm::StringRef AliasNameRef) { |
938 | 51 | assert(getItaniumVTableContext().isRelativeLayout() && |
939 | 51 | "Can only use this if the relative vtable ABI is used"); |
940 | 0 | assert(!VTable->isDSOLocal() && "This should be called only if the vtable is " |
941 | 51 | "not guaranteed to be dso_local"); |
942 | | |
943 | | // If the vtable is available_externally, we shouldn't (or need to) generate |
944 | | // an alias for it in the first place since the vtable won't actually by |
945 | | // emitted in this compilation unit. |
946 | 51 | if (VTable->hasAvailableExternallyLinkage()) |
947 | 2 | return; |
948 | | |
949 | | // Create a new string in the event the alias is already the name of the |
950 | | // vtable. Using the reference directly could lead to use of an inititialized |
951 | | // value in the module's StringMap. |
952 | 49 | llvm::SmallString<256> AliasName(AliasNameRef); |
953 | 49 | VTable->setName(AliasName + ".local"); |
954 | | |
955 | 49 | auto Linkage = VTable->getLinkage(); |
956 | 49 | assert(llvm::GlobalAlias::isValidLinkage(Linkage) && |
957 | 49 | "Invalid vtable alias linkage"); |
958 | | |
959 | 0 | llvm::GlobalAlias *VTableAlias = CGM.getModule().getNamedAlias(AliasName); |
960 | 49 | if (!VTableAlias) { |
961 | 49 | VTableAlias = llvm::GlobalAlias::create(VTable->getValueType(), |
962 | 49 | VTable->getAddressSpace(), Linkage, |
963 | 49 | AliasName, &CGM.getModule()); |
964 | 49 | } else { |
965 | 0 | assert(VTableAlias->getValueType() == VTable->getValueType()); |
966 | 0 | assert(VTableAlias->getLinkage() == Linkage); |
967 | 0 | } |
968 | 0 | VTableAlias->setVisibility(VTable->getVisibility()); |
969 | 49 | VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr()); |
970 | | |
971 | | // Both of these imply dso_local for the vtable. |
972 | 49 | if (!VTable->hasComdat()) { |
973 | | // If this is in a comdat, then we shouldn't make the linkage private due to |
974 | | // an issue in lld where private symbols can be used as the key symbol when |
975 | | // choosing the prevelant group. This leads to "relocation refers to a |
976 | | // symbol in a discarded section". |
977 | 39 | VTable->setLinkage(llvm::GlobalValue::PrivateLinkage); |
978 | 39 | } else { |
979 | | // We should at least make this hidden since we don't want to expose it. |
980 | 10 | VTable->setVisibility(llvm::GlobalValue::HiddenVisibility); |
981 | 10 | } |
982 | | |
983 | 49 | VTableAlias->setAliasee(VTable); |
984 | 49 | } |
985 | | |
986 | | static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM, |
987 | 1.26k | const CXXRecordDecl *RD) { |
988 | 1.26k | return CGM.getCodeGenOpts().OptimizationLevel > 0 && |
989 | 1.26k | CGM.getCXXABI().canSpeculativelyEmitVTable(RD)136 ; |
990 | 1.26k | } |
991 | | |
992 | | /// Compute the required linkage of the vtable for the given class. |
993 | | /// |
994 | | /// Note that we only call this at the end of the translation unit. |
995 | | llvm::GlobalVariable::LinkageTypes |
996 | 8.80k | CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { |
997 | 8.80k | if (!RD->isExternallyVisible()) |
998 | 129 | return llvm::GlobalVariable::InternalLinkage; |
999 | | |
1000 | | // We're at the end of the translation unit, so the current key |
1001 | | // function is fully correct. |
1002 | 8.67k | const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD); |
1003 | 8.67k | if (keyFunction && !RD->hasAttr<DLLImportAttr>()3.49k ) { |
1004 | | // If this class has a key function, use that to determine the |
1005 | | // linkage of the vtable. |
1006 | 3.48k | const FunctionDecl *def = nullptr; |
1007 | 3.48k | if (keyFunction->hasBody(def)) |
1008 | 1.45k | keyFunction = cast<CXXMethodDecl>(def); |
1009 | | |
1010 | 3.48k | switch (keyFunction->getTemplateSpecializationKind()) { |
1011 | 3.48k | case TSK_Undeclared: |
1012 | 3.48k | case TSK_ExplicitSpecialization: |
1013 | 3.48k | assert((def || CodeGenOpts.OptimizationLevel > 0 || |
1014 | 3.48k | CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) && |
1015 | 3.48k | "Shouldn't query vtable linkage without key function, " |
1016 | 3.48k | "optimizations, or debug info"); |
1017 | 3.48k | if (!def && CodeGenOpts.OptimizationLevel > 02.03k ) |
1018 | 111 | return llvm::GlobalVariable::AvailableExternallyLinkage; |
1019 | | |
1020 | 3.37k | if (keyFunction->isInlined()) |
1021 | 73 | return !Context.getLangOpts().AppleKext ? |
1022 | 73 | llvm::GlobalVariable::LinkOnceODRLinkage : |
1023 | 73 | llvm::Function::InternalLinkage0 ; |
1024 | | |
1025 | 3.30k | return llvm::GlobalVariable::ExternalLinkage; |
1026 | | |
1027 | 0 | case TSK_ImplicitInstantiation: |
1028 | 0 | return !Context.getLangOpts().AppleKext ? |
1029 | 0 | llvm::GlobalVariable::LinkOnceODRLinkage : |
1030 | 0 | llvm::Function::InternalLinkage; |
1031 | | |
1032 | 0 | case TSK_ExplicitInstantiationDefinition: |
1033 | 0 | return !Context.getLangOpts().AppleKext ? |
1034 | 0 | llvm::GlobalVariable::WeakODRLinkage : |
1035 | 0 | llvm::Function::InternalLinkage; |
1036 | | |
1037 | 0 | case TSK_ExplicitInstantiationDeclaration: |
1038 | 0 | llvm_unreachable("Should not have been asked to emit this"); |
1039 | 3.48k | } |
1040 | 3.48k | } |
1041 | | |
1042 | | // -fapple-kext mode does not support weak linkage, so we must use |
1043 | | // internal linkage. |
1044 | 5.18k | if (Context.getLangOpts().AppleKext) |
1045 | 5 | return llvm::Function::InternalLinkage; |
1046 | | |
1047 | 5.18k | llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage = |
1048 | 5.18k | llvm::GlobalValue::LinkOnceODRLinkage; |
1049 | 5.18k | llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage = |
1050 | 5.18k | llvm::GlobalValue::WeakODRLinkage; |
1051 | 5.18k | if (RD->hasAttr<DLLExportAttr>()) { |
1052 | | // Cannot discard exported vtables. |
1053 | 94 | DiscardableODRLinkage = NonDiscardableODRLinkage; |
1054 | 5.08k | } else if (RD->hasAttr<DLLImportAttr>()) { |
1055 | | // Imported vtables are available externally. |
1056 | 48 | DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage; |
1057 | 48 | NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage; |
1058 | 48 | } |
1059 | | |
1060 | 5.18k | switch (RD->getTemplateSpecializationKind()) { |
1061 | 3.62k | case TSK_Undeclared: |
1062 | 3.63k | case TSK_ExplicitSpecialization: |
1063 | 4.39k | case TSK_ImplicitInstantiation: |
1064 | 4.39k | return DiscardableODRLinkage; |
1065 | | |
1066 | 647 | case TSK_ExplicitInstantiationDeclaration: |
1067 | | // Explicit instantiations in MSVC do not provide vtables, so we must emit |
1068 | | // our own. |
1069 | 647 | if (getTarget().getCXXABI().isMicrosoft()) |
1070 | 7 | return DiscardableODRLinkage; |
1071 | 640 | return shouldEmitAvailableExternallyVTable(*this, RD) |
1072 | 640 | ? llvm::GlobalVariable::AvailableExternallyLinkage9 |
1073 | 640 | : llvm::GlobalVariable::ExternalLinkage631 ; |
1074 | | |
1075 | 139 | case TSK_ExplicitInstantiationDefinition: |
1076 | 139 | return NonDiscardableODRLinkage; |
1077 | 5.18k | } |
1078 | | |
1079 | 0 | llvm_unreachable("Invalid TemplateSpecializationKind!"); |
1080 | 0 | } |
1081 | | |
1082 | | /// This is a callback from Sema to tell us that a particular vtable is |
1083 | | /// required to be emitted in this translation unit. |
1084 | | /// |
1085 | | /// This is only called for vtables that _must_ be emitted (mainly due to key |
1086 | | /// functions). For weak vtables, CodeGen tracks when they are needed and |
1087 | | /// emits them as-needed. |
1088 | 827 | void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) { |
1089 | 827 | VTables.GenerateClassData(theClass); |
1090 | 827 | } |
1091 | | |
1092 | | void |
1093 | 3.26k | CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) { |
1094 | 3.26k | if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) |
1095 | 633 | DI->completeClassData(RD); |
1096 | | |
1097 | 3.26k | if (RD->getNumVBases()) |
1098 | 740 | CGM.getCXXABI().emitVirtualInheritanceTables(RD); |
1099 | | |
1100 | 3.26k | CGM.getCXXABI().emitVTableDefinitions(*this, RD); |
1101 | 3.26k | } |
1102 | | |
1103 | | /// At this point in the translation unit, does it appear that can we |
1104 | | /// rely on the vtable being defined elsewhere in the program? |
1105 | | /// |
1106 | | /// The response is really only definitive when called at the end of |
1107 | | /// the translation unit. |
1108 | | /// |
1109 | | /// The only semantic restriction here is that the object file should |
1110 | | /// not contain a vtable definition when that vtable is defined |
1111 | | /// strongly elsewhere. Otherwise, we'd just like to avoid emitting |
1112 | | /// vtables when unnecessary. |
1113 | 5.72k | bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) { |
1114 | 5.72k | assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable."); |
1115 | | |
1116 | | // We always synthesize vtables if they are needed in the MS ABI. MSVC doesn't |
1117 | | // emit them even if there is an explicit template instantiation. |
1118 | 5.72k | if (CGM.getTarget().getCXXABI().isMicrosoft()) |
1119 | 803 | return false; |
1120 | | |
1121 | | // If we have an explicit instantiation declaration (and not a |
1122 | | // definition), the vtable is defined elsewhere. |
1123 | 4.92k | TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); |
1124 | 4.92k | if (TSK == TSK_ExplicitInstantiationDeclaration) |
1125 | 98 | return true; |
1126 | | |
1127 | | // Otherwise, if the class is an instantiated template, the |
1128 | | // vtable must be defined here. |
1129 | 4.82k | if (TSK == TSK_ImplicitInstantiation || |
1130 | 4.82k | TSK == TSK_ExplicitInstantiationDefinition4.47k ) |
1131 | 483 | return false; |
1132 | | |
1133 | | // Otherwise, if the class doesn't have a key function (possibly |
1134 | | // anymore), the vtable must be defined here. |
1135 | 4.34k | const CXXMethodDecl *keyFunction = CGM.getContext().getCurrentKeyFunction(RD); |
1136 | 4.34k | if (!keyFunction) |
1137 | 1.70k | return false; |
1138 | | |
1139 | | // Otherwise, if we don't have a definition of the key function, the |
1140 | | // vtable must be defined somewhere else. |
1141 | 2.63k | return !keyFunction->hasBody(); |
1142 | 4.34k | } |
1143 | | |
1144 | | /// Given that we're currently at the end of the translation unit, and |
1145 | | /// we've emitted a reference to the vtable for this class, should |
1146 | | /// we define that vtable? |
1147 | | static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM, |
1148 | 2.95k | const CXXRecordDecl *RD) { |
1149 | | // If vtable is internal then it has to be done. |
1150 | 2.95k | if (!CGM.getVTables().isVTableExternal(RD)) |
1151 | 2.32k | return true; |
1152 | | |
1153 | | // If it's external then maybe we will need it as available_externally. |
1154 | 629 | return shouldEmitAvailableExternallyVTable(CGM, RD); |
1155 | 2.95k | } |
1156 | | |
1157 | | /// Given that at some point we emitted a reference to one or more |
1158 | | /// vtables, and that we are now at the end of the translation unit, |
1159 | | /// decide whether we should emit them. |
1160 | 2.24k | void CodeGenModule::EmitDeferredVTables() { |
1161 | 2.24k | #ifndef NDEBUG |
1162 | | // Remember the size of DeferredVTables, because we're going to assume |
1163 | | // that this entire operation doesn't modify it. |
1164 | 2.24k | size_t savedSize = DeferredVTables.size(); |
1165 | 2.24k | #endif |
1166 | | |
1167 | 2.24k | for (const CXXRecordDecl *RD : DeferredVTables) |
1168 | 2.95k | if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD)) |
1169 | 2.43k | VTables.GenerateClassData(RD); |
1170 | 527 | else if (shouldOpportunisticallyEmitVTables()) |
1171 | 25 | OpportunisticVTables.push_back(RD); |
1172 | | |
1173 | 2.24k | assert(savedSize == DeferredVTables.size() && |
1174 | 2.24k | "deferred extra vtables during vtable emission?"); |
1175 | 0 | DeferredVTables.clear(); |
1176 | 2.24k | } |
1177 | | |
1178 | 387 | bool CodeGenModule::AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD) { |
1179 | 387 | if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>()361 ) |
1180 | 32 | return true; |
1181 | | |
1182 | 355 | if (!getCodeGenOpts().LTOVisibilityPublicStd) |
1183 | 340 | return false; |
1184 | | |
1185 | 15 | const DeclContext *DC = RD; |
1186 | 26 | while (true) { |
1187 | 26 | auto *D = cast<Decl>(DC); |
1188 | 26 | DC = DC->getParent(); |
1189 | 26 | if (isa<TranslationUnitDecl>(DC->getRedeclContext())) { |
1190 | 15 | if (auto *ND = dyn_cast<NamespaceDecl>(D)) |
1191 | 9 | if (const IdentifierInfo *II = ND->getIdentifier()) |
1192 | 8 | if (II->isStr("std") || II->isStr("stdext")4 ) |
1193 | 6 | return true; |
1194 | 9 | break; |
1195 | 15 | } |
1196 | 26 | } |
1197 | | |
1198 | 9 | return false; |
1199 | 15 | } |
1200 | | |
1201 | 543 | bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) { |
1202 | 543 | LinkageInfo LV = RD->getLinkageAndVisibility(); |
1203 | 543 | if (!isExternallyVisible(LV.getLinkage())) |
1204 | 134 | return true; |
1205 | | |
1206 | 409 | if (getTriple().isOSBinFormatCOFF()) { |
1207 | 112 | if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>()110 ) |
1208 | 4 | return false; |
1209 | 297 | } else { |
1210 | 297 | if (LV.getVisibility() != HiddenVisibility) |
1211 | 94 | return false; |
1212 | 297 | } |
1213 | | |
1214 | 311 | return !AlwaysHasLTOVisibilityPublic(RD); |
1215 | 409 | } |
1216 | | |
1217 | | llvm::GlobalObject::VCallVisibility CodeGenModule::GetVCallVisibilityLevel( |
1218 | 235 | const CXXRecordDecl *RD, llvm::DenseSet<const CXXRecordDecl *> &Visited) { |
1219 | | // If we have already visited this RD (which means this is a recursive call |
1220 | | // since the initial call should have an empty Visited set), return the max |
1221 | | // visibility. The recursive calls below compute the min between the result |
1222 | | // of the recursive call and the current TypeVis, so returning the max here |
1223 | | // ensures that it will have no effect on the current TypeVis. |
1224 | 235 | if (!Visited.insert(RD).second) |
1225 | 79 | return llvm::GlobalObject::VCallVisibilityTranslationUnit; |
1226 | | |
1227 | 156 | LinkageInfo LV = RD->getLinkageAndVisibility(); |
1228 | 156 | llvm::GlobalObject::VCallVisibility TypeVis; |
1229 | 156 | if (!isExternallyVisible(LV.getLinkage())) |
1230 | 34 | TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit; |
1231 | 122 | else if (HasHiddenLTOVisibility(RD)) |
1232 | 75 | TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit; |
1233 | 47 | else |
1234 | 47 | TypeVis = llvm::GlobalObject::VCallVisibilityPublic; |
1235 | | |
1236 | 156 | for (auto B : RD->bases()) |
1237 | 97 | if (B.getType()->getAsCXXRecordDecl()->isDynamicClass()) |
1238 | 97 | TypeVis = std::min( |
1239 | 97 | TypeVis, |
1240 | 97 | GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited)); |
1241 | | |
1242 | 156 | for (auto B : RD->vbases()) |
1243 | 63 | if (B.getType()->getAsCXXRecordDecl()->isDynamicClass()) |
1244 | 63 | TypeVis = std::min( |
1245 | 63 | TypeVis, |
1246 | 63 | GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited)); |
1247 | | |
1248 | 156 | return TypeVis; |
1249 | 235 | } |
1250 | | |
1251 | | void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD, |
1252 | | llvm::GlobalVariable *VTable, |
1253 | 1.80k | const VTableLayout &VTLayout) { |
1254 | 1.80k | if (!getCodeGenOpts().LTOUnit) |
1255 | 1.73k | return; |
1256 | | |
1257 | 77 | CharUnits PointerWidth = |
1258 | 77 | Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); |
1259 | | |
1260 | 77 | typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint; |
1261 | 77 | std::vector<AddressPoint> AddressPoints; |
1262 | 77 | for (auto &&AP : VTLayout.getAddressPoints()) |
1263 | 143 | AddressPoints.push_back(std::make_pair( |
1264 | 143 | AP.first.getBase(), VTLayout.getVTableOffset(AP.second.VTableIndex) + |
1265 | 143 | AP.second.AddressPointIndex)); |
1266 | | |
1267 | | // Sort the address points for determinism. |
1268 | 77 | llvm::sort(AddressPoints, [this](const AddressPoint &AP1, |
1269 | 80 | const AddressPoint &AP2) { |
1270 | 80 | if (&AP1 == &AP2) |
1271 | 0 | return false; |
1272 | | |
1273 | 80 | std::string S1; |
1274 | 80 | llvm::raw_string_ostream O1(S1); |
1275 | 80 | getCXXABI().getMangleContext().mangleTypeName( |
1276 | 80 | QualType(AP1.first->getTypeForDecl(), 0), O1); |
1277 | 80 | O1.flush(); |
1278 | | |
1279 | 80 | std::string S2; |
1280 | 80 | llvm::raw_string_ostream O2(S2); |
1281 | 80 | getCXXABI().getMangleContext().mangleTypeName( |
1282 | 80 | QualType(AP2.first->getTypeForDecl(), 0), O2); |
1283 | 80 | O2.flush(); |
1284 | | |
1285 | 80 | if (S1 < S2) |
1286 | 43 | return true; |
1287 | 37 | if (S1 != S2) |
1288 | 37 | return false; |
1289 | | |
1290 | 0 | return AP1.second < AP2.second; |
1291 | 37 | }); |
1292 | | |
1293 | 77 | ArrayRef<VTableComponent> Comps = VTLayout.vtable_components(); |
1294 | 143 | for (auto AP : AddressPoints) { |
1295 | | // Create type metadata for the address point. |
1296 | 143 | AddVTableTypeMetadata(VTable, PointerWidth * AP.second, AP.first); |
1297 | | |
1298 | | // The class associated with each address point could also potentially be |
1299 | | // used for indirect calls via a member function pointer, so we need to |
1300 | | // annotate the address of each function pointer with the appropriate member |
1301 | | // function pointer type. |
1302 | 1.05k | for (unsigned I = 0; I != Comps.size(); ++I912 ) { |
1303 | 912 | if (Comps[I].getKind() != VTableComponent::CK_FunctionPointer) |
1304 | 659 | continue; |
1305 | 253 | llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType( |
1306 | 253 | Context.getMemberPointerType( |
1307 | 253 | Comps[I].getFunctionDecl()->getType(), |
1308 | 253 | Context.getRecordType(AP.first).getTypePtr())); |
1309 | 253 | VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD); |
1310 | 253 | } |
1311 | 143 | } |
1312 | | |
1313 | 77 | if (getCodeGenOpts().VirtualFunctionElimination || |
1314 | 77 | getCodeGenOpts().WholeProgramVTables70 ) { |
1315 | 52 | llvm::DenseSet<const CXXRecordDecl *> Visited; |
1316 | 52 | llvm::GlobalObject::VCallVisibility TypeVis = |
1317 | 52 | GetVCallVisibilityLevel(RD, Visited); |
1318 | 52 | if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic) |
1319 | 23 | VTable->setVCallVisibilityMetadata(TypeVis); |
1320 | 52 | } |
1321 | 77 | } |