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