106f32e7eSjoerg //===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This contains code dealing with C++ code generation of virtual tables.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg
1306f32e7eSjoerg #include "CGCXXABI.h"
1406f32e7eSjoerg #include "CodeGenFunction.h"
1506f32e7eSjoerg #include "CodeGenModule.h"
16*13fbcb42Sjoerg #include "clang/AST/Attr.h"
1706f32e7eSjoerg #include "clang/AST/CXXInheritance.h"
1806f32e7eSjoerg #include "clang/AST/RecordLayout.h"
1906f32e7eSjoerg #include "clang/Basic/CodeGenOptions.h"
2006f32e7eSjoerg #include "clang/CodeGen/CGFunctionInfo.h"
2106f32e7eSjoerg #include "clang/CodeGen/ConstantInitBuilder.h"
2206f32e7eSjoerg #include "llvm/IR/IntrinsicInst.h"
2306f32e7eSjoerg #include "llvm/Support/Format.h"
2406f32e7eSjoerg #include "llvm/Transforms/Utils/Cloning.h"
2506f32e7eSjoerg #include <algorithm>
2606f32e7eSjoerg #include <cstdio>
2706f32e7eSjoerg
2806f32e7eSjoerg using namespace clang;
2906f32e7eSjoerg using namespace CodeGen;
3006f32e7eSjoerg
CodeGenVTables(CodeGenModule & CGM)3106f32e7eSjoerg CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
3206f32e7eSjoerg : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
3306f32e7eSjoerg
GetAddrOfThunk(StringRef Name,llvm::Type * FnTy,GlobalDecl GD)3406f32e7eSjoerg llvm::Constant *CodeGenModule::GetAddrOfThunk(StringRef Name, llvm::Type *FnTy,
3506f32e7eSjoerg GlobalDecl GD) {
3606f32e7eSjoerg return GetOrCreateLLVMFunction(Name, FnTy, GD, /*ForVTable=*/true,
3706f32e7eSjoerg /*DontDefer=*/true, /*IsThunk=*/true);
3806f32e7eSjoerg }
3906f32e7eSjoerg
setThunkProperties(CodeGenModule & CGM,const ThunkInfo & Thunk,llvm::Function * ThunkFn,bool ForVTable,GlobalDecl GD)4006f32e7eSjoerg static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
4106f32e7eSjoerg llvm::Function *ThunkFn, bool ForVTable,
4206f32e7eSjoerg GlobalDecl GD) {
4306f32e7eSjoerg CGM.setFunctionLinkage(GD, ThunkFn);
4406f32e7eSjoerg CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
4506f32e7eSjoerg !Thunk.Return.isEmpty());
4606f32e7eSjoerg
4706f32e7eSjoerg // Set the right visibility.
4806f32e7eSjoerg CGM.setGVProperties(ThunkFn, GD);
4906f32e7eSjoerg
5006f32e7eSjoerg if (!CGM.getCXXABI().exportThunk()) {
5106f32e7eSjoerg ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
5206f32e7eSjoerg ThunkFn->setDSOLocal(true);
5306f32e7eSjoerg }
5406f32e7eSjoerg
5506f32e7eSjoerg if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
5606f32e7eSjoerg ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
5706f32e7eSjoerg }
5806f32e7eSjoerg
5906f32e7eSjoerg #ifndef NDEBUG
similar(const ABIArgInfo & infoL,CanQualType typeL,const ABIArgInfo & infoR,CanQualType typeR)6006f32e7eSjoerg static bool similar(const ABIArgInfo &infoL, CanQualType typeL,
6106f32e7eSjoerg const ABIArgInfo &infoR, CanQualType typeR) {
6206f32e7eSjoerg return (infoL.getKind() == infoR.getKind() &&
6306f32e7eSjoerg (typeL == typeR ||
6406f32e7eSjoerg (isa<PointerType>(typeL) && isa<PointerType>(typeR)) ||
6506f32e7eSjoerg (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR))));
6606f32e7eSjoerg }
6706f32e7eSjoerg #endif
6806f32e7eSjoerg
PerformReturnAdjustment(CodeGenFunction & CGF,QualType ResultType,RValue RV,const ThunkInfo & Thunk)6906f32e7eSjoerg static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
7006f32e7eSjoerg QualType ResultType, RValue RV,
7106f32e7eSjoerg const ThunkInfo &Thunk) {
7206f32e7eSjoerg // Emit the return adjustment.
7306f32e7eSjoerg bool NullCheckValue = !ResultType->isReferenceType();
7406f32e7eSjoerg
7506f32e7eSjoerg llvm::BasicBlock *AdjustNull = nullptr;
7606f32e7eSjoerg llvm::BasicBlock *AdjustNotNull = nullptr;
7706f32e7eSjoerg llvm::BasicBlock *AdjustEnd = nullptr;
7806f32e7eSjoerg
7906f32e7eSjoerg llvm::Value *ReturnValue = RV.getScalarVal();
8006f32e7eSjoerg
8106f32e7eSjoerg if (NullCheckValue) {
8206f32e7eSjoerg AdjustNull = CGF.createBasicBlock("adjust.null");
8306f32e7eSjoerg AdjustNotNull = CGF.createBasicBlock("adjust.notnull");
8406f32e7eSjoerg AdjustEnd = CGF.createBasicBlock("adjust.end");
8506f32e7eSjoerg
8606f32e7eSjoerg llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue);
8706f32e7eSjoerg CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
8806f32e7eSjoerg CGF.EmitBlock(AdjustNotNull);
8906f32e7eSjoerg }
9006f32e7eSjoerg
9106f32e7eSjoerg auto ClassDecl = ResultType->getPointeeType()->getAsCXXRecordDecl();
9206f32e7eSjoerg auto ClassAlign = CGF.CGM.getClassPointerAlignment(ClassDecl);
9306f32e7eSjoerg ReturnValue = CGF.CGM.getCXXABI().performReturnAdjustment(CGF,
9406f32e7eSjoerg Address(ReturnValue, ClassAlign),
9506f32e7eSjoerg Thunk.Return);
9606f32e7eSjoerg
9706f32e7eSjoerg if (NullCheckValue) {
9806f32e7eSjoerg CGF.Builder.CreateBr(AdjustEnd);
9906f32e7eSjoerg CGF.EmitBlock(AdjustNull);
10006f32e7eSjoerg CGF.Builder.CreateBr(AdjustEnd);
10106f32e7eSjoerg CGF.EmitBlock(AdjustEnd);
10206f32e7eSjoerg
10306f32e7eSjoerg llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2);
10406f32e7eSjoerg PHI->addIncoming(ReturnValue, AdjustNotNull);
10506f32e7eSjoerg PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
10606f32e7eSjoerg AdjustNull);
10706f32e7eSjoerg ReturnValue = PHI;
10806f32e7eSjoerg }
10906f32e7eSjoerg
11006f32e7eSjoerg return RValue::get(ReturnValue);
11106f32e7eSjoerg }
11206f32e7eSjoerg
11306f32e7eSjoerg /// This function clones a function's DISubprogram node and enters it into
11406f32e7eSjoerg /// a value map with the intent that the map can be utilized by the cloner
11506f32e7eSjoerg /// to short-circuit Metadata node mapping.
11606f32e7eSjoerg /// Furthermore, the function resolves any DILocalVariable nodes referenced
11706f32e7eSjoerg /// by dbg.value intrinsics so they can be properly mapped during cloning.
resolveTopLevelMetadata(llvm::Function * Fn,llvm::ValueToValueMapTy & VMap)11806f32e7eSjoerg static void resolveTopLevelMetadata(llvm::Function *Fn,
11906f32e7eSjoerg llvm::ValueToValueMapTy &VMap) {
12006f32e7eSjoerg // Clone the DISubprogram node and put it into the Value map.
12106f32e7eSjoerg auto *DIS = Fn->getSubprogram();
12206f32e7eSjoerg if (!DIS)
12306f32e7eSjoerg return;
12406f32e7eSjoerg auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
12506f32e7eSjoerg VMap.MD()[DIS].reset(NewDIS);
12606f32e7eSjoerg
12706f32e7eSjoerg // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes
12806f32e7eSjoerg // they are referencing.
12906f32e7eSjoerg for (auto &BB : Fn->getBasicBlockList()) {
13006f32e7eSjoerg for (auto &I : BB) {
13106f32e7eSjoerg if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
13206f32e7eSjoerg auto *DILocal = DII->getVariable();
13306f32e7eSjoerg if (!DILocal->isResolved())
13406f32e7eSjoerg DILocal->resolve();
13506f32e7eSjoerg }
13606f32e7eSjoerg }
13706f32e7eSjoerg }
13806f32e7eSjoerg }
13906f32e7eSjoerg
14006f32e7eSjoerg // This function does roughly the same thing as GenerateThunk, but in a
14106f32e7eSjoerg // very different way, so that va_start and va_end work correctly.
14206f32e7eSjoerg // FIXME: This function assumes "this" is the first non-sret LLVM argument of
14306f32e7eSjoerg // a function, and that there is an alloca built in the entry block
14406f32e7eSjoerg // for all accesses to "this".
14506f32e7eSjoerg // FIXME: This function assumes there is only one "ret" statement per function.
14606f32e7eSjoerg // FIXME: Cloning isn't correct in the presence of indirect goto!
14706f32e7eSjoerg // FIXME: This implementation of thunks bloats codesize by duplicating the
14806f32e7eSjoerg // function definition. There are alternatives:
14906f32e7eSjoerg // 1. Add some sort of stub support to LLVM for cases where we can
15006f32e7eSjoerg // do a this adjustment, then a sibcall.
15106f32e7eSjoerg // 2. We could transform the definition to take a va_list instead of an
15206f32e7eSjoerg // actual variable argument list, then have the thunks (including a
15306f32e7eSjoerg // no-op thunk for the regular definition) call va_start/va_end.
15406f32e7eSjoerg // There's a bit of per-call overhead for this solution, but it's
15506f32e7eSjoerg // better for codesize if the definition is long.
15606f32e7eSjoerg llvm::Function *
GenerateVarArgsThunk(llvm::Function * Fn,const CGFunctionInfo & FnInfo,GlobalDecl GD,const ThunkInfo & Thunk)15706f32e7eSjoerg CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn,
15806f32e7eSjoerg const CGFunctionInfo &FnInfo,
15906f32e7eSjoerg GlobalDecl GD, const ThunkInfo &Thunk) {
16006f32e7eSjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
16106f32e7eSjoerg const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
16206f32e7eSjoerg QualType ResultType = FPT->getReturnType();
16306f32e7eSjoerg
16406f32e7eSjoerg // Get the original function
16506f32e7eSjoerg assert(FnInfo.isVariadic());
16606f32e7eSjoerg llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo);
16706f32e7eSjoerg llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
16806f32e7eSjoerg llvm::Function *BaseFn = cast<llvm::Function>(Callee);
16906f32e7eSjoerg
17006f32e7eSjoerg // Cloning can't work if we don't have a definition. The Microsoft ABI may
17106f32e7eSjoerg // require thunks when a definition is not available. Emit an error in these
17206f32e7eSjoerg // cases.
17306f32e7eSjoerg if (!MD->isDefined()) {
17406f32e7eSjoerg CGM.ErrorUnsupported(MD, "return-adjusting thunk with variadic arguments");
17506f32e7eSjoerg return Fn;
17606f32e7eSjoerg }
17706f32e7eSjoerg assert(!BaseFn->isDeclaration() && "cannot clone undefined variadic method");
17806f32e7eSjoerg
17906f32e7eSjoerg // Clone to thunk.
18006f32e7eSjoerg llvm::ValueToValueMapTy VMap;
18106f32e7eSjoerg
18206f32e7eSjoerg // We are cloning a function while some Metadata nodes are still unresolved.
18306f32e7eSjoerg // Ensure that the value mapper does not encounter any of them.
18406f32e7eSjoerg resolveTopLevelMetadata(BaseFn, VMap);
18506f32e7eSjoerg llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);
18606f32e7eSjoerg Fn->replaceAllUsesWith(NewFn);
18706f32e7eSjoerg NewFn->takeName(Fn);
18806f32e7eSjoerg Fn->eraseFromParent();
18906f32e7eSjoerg Fn = NewFn;
19006f32e7eSjoerg
19106f32e7eSjoerg // "Initialize" CGF (minimally).
19206f32e7eSjoerg CurFn = Fn;
19306f32e7eSjoerg
19406f32e7eSjoerg // Get the "this" value
19506f32e7eSjoerg llvm::Function::arg_iterator AI = Fn->arg_begin();
19606f32e7eSjoerg if (CGM.ReturnTypeUsesSRet(FnInfo))
19706f32e7eSjoerg ++AI;
19806f32e7eSjoerg
19906f32e7eSjoerg // Find the first store of "this", which will be to the alloca associated
20006f32e7eSjoerg // with "this".
20106f32e7eSjoerg Address ThisPtr(&*AI, CGM.getClassPointerAlignment(MD->getParent()));
20206f32e7eSjoerg llvm::BasicBlock *EntryBB = &Fn->front();
20306f32e7eSjoerg llvm::BasicBlock::iterator ThisStore =
20406f32e7eSjoerg std::find_if(EntryBB->begin(), EntryBB->end(), [&](llvm::Instruction &I) {
20506f32e7eSjoerg return isa<llvm::StoreInst>(I) &&
20606f32e7eSjoerg I.getOperand(0) == ThisPtr.getPointer();
20706f32e7eSjoerg });
20806f32e7eSjoerg assert(ThisStore != EntryBB->end() &&
20906f32e7eSjoerg "Store of this should be in entry block?");
21006f32e7eSjoerg // Adjust "this", if necessary.
21106f32e7eSjoerg Builder.SetInsertPoint(&*ThisStore);
21206f32e7eSjoerg llvm::Value *AdjustedThisPtr =
21306f32e7eSjoerg CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This);
21406f32e7eSjoerg AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,
21506f32e7eSjoerg ThisStore->getOperand(0)->getType());
21606f32e7eSjoerg ThisStore->setOperand(0, AdjustedThisPtr);
21706f32e7eSjoerg
21806f32e7eSjoerg if (!Thunk.Return.isEmpty()) {
21906f32e7eSjoerg // Fix up the returned value, if necessary.
22006f32e7eSjoerg for (llvm::BasicBlock &BB : *Fn) {
22106f32e7eSjoerg llvm::Instruction *T = BB.getTerminator();
22206f32e7eSjoerg if (isa<llvm::ReturnInst>(T)) {
22306f32e7eSjoerg RValue RV = RValue::get(T->getOperand(0));
22406f32e7eSjoerg T->eraseFromParent();
22506f32e7eSjoerg Builder.SetInsertPoint(&BB);
22606f32e7eSjoerg RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk);
22706f32e7eSjoerg Builder.CreateRet(RV.getScalarVal());
22806f32e7eSjoerg break;
22906f32e7eSjoerg }
23006f32e7eSjoerg }
23106f32e7eSjoerg }
23206f32e7eSjoerg
23306f32e7eSjoerg return Fn;
23406f32e7eSjoerg }
23506f32e7eSjoerg
StartThunk(llvm::Function * Fn,GlobalDecl GD,const CGFunctionInfo & FnInfo,bool IsUnprototyped)23606f32e7eSjoerg void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
23706f32e7eSjoerg const CGFunctionInfo &FnInfo,
23806f32e7eSjoerg bool IsUnprototyped) {
23906f32e7eSjoerg assert(!CurGD.getDecl() && "CurGD was already set!");
24006f32e7eSjoerg CurGD = GD;
24106f32e7eSjoerg CurFuncIsThunk = true;
24206f32e7eSjoerg
24306f32e7eSjoerg // Build FunctionArgs.
24406f32e7eSjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
24506f32e7eSjoerg QualType ThisType = MD->getThisType();
24606f32e7eSjoerg QualType ResultType;
24706f32e7eSjoerg if (IsUnprototyped)
24806f32e7eSjoerg ResultType = CGM.getContext().VoidTy;
24906f32e7eSjoerg else if (CGM.getCXXABI().HasThisReturn(GD))
25006f32e7eSjoerg ResultType = ThisType;
25106f32e7eSjoerg else if (CGM.getCXXABI().hasMostDerivedReturn(GD))
25206f32e7eSjoerg ResultType = CGM.getContext().VoidPtrTy;
25306f32e7eSjoerg else
25406f32e7eSjoerg ResultType = MD->getType()->castAs<FunctionProtoType>()->getReturnType();
25506f32e7eSjoerg FunctionArgList FunctionArgs;
25606f32e7eSjoerg
25706f32e7eSjoerg // Create the implicit 'this' parameter declaration.
25806f32e7eSjoerg CGM.getCXXABI().buildThisParam(*this, FunctionArgs);
25906f32e7eSjoerg
26006f32e7eSjoerg // Add the rest of the parameters, if we have a prototype to work with.
26106f32e7eSjoerg if (!IsUnprototyped) {
26206f32e7eSjoerg FunctionArgs.append(MD->param_begin(), MD->param_end());
26306f32e7eSjoerg
26406f32e7eSjoerg if (isa<CXXDestructorDecl>(MD))
26506f32e7eSjoerg CGM.getCXXABI().addImplicitStructorParams(*this, ResultType,
26606f32e7eSjoerg FunctionArgs);
26706f32e7eSjoerg }
26806f32e7eSjoerg
26906f32e7eSjoerg // Start defining the function.
27006f32e7eSjoerg auto NL = ApplyDebugLocation::CreateEmpty(*this);
27106f32e7eSjoerg StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
27206f32e7eSjoerg MD->getLocation());
27306f32e7eSjoerg // Create a scope with an artificial location for the body of this function.
27406f32e7eSjoerg auto AL = ApplyDebugLocation::CreateArtificial(*this);
27506f32e7eSjoerg
27606f32e7eSjoerg // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves.
27706f32e7eSjoerg CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
27806f32e7eSjoerg CXXThisValue = CXXABIThisValue;
27906f32e7eSjoerg CurCodeDecl = MD;
28006f32e7eSjoerg CurFuncDecl = MD;
28106f32e7eSjoerg }
28206f32e7eSjoerg
FinishThunk()28306f32e7eSjoerg void CodeGenFunction::FinishThunk() {
28406f32e7eSjoerg // Clear these to restore the invariants expected by
28506f32e7eSjoerg // StartFunction/FinishFunction.
28606f32e7eSjoerg CurCodeDecl = nullptr;
28706f32e7eSjoerg CurFuncDecl = nullptr;
28806f32e7eSjoerg
28906f32e7eSjoerg FinishFunction();
29006f32e7eSjoerg }
29106f32e7eSjoerg
EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,const ThunkInfo * Thunk,bool IsUnprototyped)29206f32e7eSjoerg void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
29306f32e7eSjoerg const ThunkInfo *Thunk,
29406f32e7eSjoerg bool IsUnprototyped) {
29506f32e7eSjoerg assert(isa<CXXMethodDecl>(CurGD.getDecl()) &&
29606f32e7eSjoerg "Please use a new CGF for this thunk");
29706f32e7eSjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl());
29806f32e7eSjoerg
29906f32e7eSjoerg // Adjust the 'this' pointer if necessary
30006f32e7eSjoerg llvm::Value *AdjustedThisPtr =
30106f32e7eSjoerg Thunk ? CGM.getCXXABI().performThisAdjustment(
30206f32e7eSjoerg *this, LoadCXXThisAddress(), Thunk->This)
30306f32e7eSjoerg : LoadCXXThis();
30406f32e7eSjoerg
30506f32e7eSjoerg // If perfect forwarding is required a variadic method, a method using
30606f32e7eSjoerg // inalloca, or an unprototyped thunk, use musttail. Emit an error if this
30706f32e7eSjoerg // thunk requires a return adjustment, since that is impossible with musttail.
30806f32e7eSjoerg if (CurFnInfo->usesInAlloca() || CurFnInfo->isVariadic() || IsUnprototyped) {
30906f32e7eSjoerg if (Thunk && !Thunk->Return.isEmpty()) {
31006f32e7eSjoerg if (IsUnprototyped)
31106f32e7eSjoerg CGM.ErrorUnsupported(
31206f32e7eSjoerg MD, "return-adjusting thunk with incomplete parameter type");
31306f32e7eSjoerg else if (CurFnInfo->isVariadic())
31406f32e7eSjoerg llvm_unreachable("shouldn't try to emit musttail return-adjusting "
31506f32e7eSjoerg "thunks for variadic functions");
31606f32e7eSjoerg else
31706f32e7eSjoerg CGM.ErrorUnsupported(
31806f32e7eSjoerg MD, "non-trivial argument copy for return-adjusting thunk");
31906f32e7eSjoerg }
32006f32e7eSjoerg EmitMustTailThunk(CurGD, AdjustedThisPtr, Callee);
32106f32e7eSjoerg return;
32206f32e7eSjoerg }
32306f32e7eSjoerg
32406f32e7eSjoerg // Start building CallArgs.
32506f32e7eSjoerg CallArgList CallArgs;
32606f32e7eSjoerg QualType ThisType = MD->getThisType();
32706f32e7eSjoerg CallArgs.add(RValue::get(AdjustedThisPtr), ThisType);
32806f32e7eSjoerg
32906f32e7eSjoerg if (isa<CXXDestructorDecl>(MD))
33006f32e7eSjoerg CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, CurGD, CallArgs);
33106f32e7eSjoerg
33206f32e7eSjoerg #ifndef NDEBUG
33306f32e7eSjoerg unsigned PrefixArgs = CallArgs.size() - 1;
33406f32e7eSjoerg #endif
33506f32e7eSjoerg // Add the rest of the arguments.
33606f32e7eSjoerg for (const ParmVarDecl *PD : MD->parameters())
33706f32e7eSjoerg EmitDelegateCallArg(CallArgs, PD, SourceLocation());
33806f32e7eSjoerg
339*13fbcb42Sjoerg const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
34006f32e7eSjoerg
34106f32e7eSjoerg #ifndef NDEBUG
34206f32e7eSjoerg const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(
34306f32e7eSjoerg CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1), PrefixArgs);
34406f32e7eSjoerg assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
34506f32e7eSjoerg CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
34606f32e7eSjoerg CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());
34706f32e7eSjoerg assert(isa<CXXDestructorDecl>(MD) || // ignore dtor return types
34806f32e7eSjoerg similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
34906f32e7eSjoerg CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType()));
35006f32e7eSjoerg assert(CallFnInfo.arg_size() == CurFnInfo->arg_size());
35106f32e7eSjoerg for (unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i)
35206f32e7eSjoerg assert(similar(CallFnInfo.arg_begin()[i].info,
35306f32e7eSjoerg CallFnInfo.arg_begin()[i].type,
35406f32e7eSjoerg CurFnInfo->arg_begin()[i].info,
35506f32e7eSjoerg CurFnInfo->arg_begin()[i].type));
35606f32e7eSjoerg #endif
35706f32e7eSjoerg
35806f32e7eSjoerg // Determine whether we have a return value slot to use.
35906f32e7eSjoerg QualType ResultType = CGM.getCXXABI().HasThisReturn(CurGD)
36006f32e7eSjoerg ? ThisType
36106f32e7eSjoerg : CGM.getCXXABI().hasMostDerivedReturn(CurGD)
36206f32e7eSjoerg ? CGM.getContext().VoidPtrTy
36306f32e7eSjoerg : FPT->getReturnType();
36406f32e7eSjoerg ReturnValueSlot Slot;
36506f32e7eSjoerg if (!ResultType->isVoidType() &&
366*13fbcb42Sjoerg (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect ||
367*13fbcb42Sjoerg hasAggregateEvaluationKind(ResultType)))
368*13fbcb42Sjoerg Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified(),
369*13fbcb42Sjoerg /*IsUnused=*/false, /*IsExternallyDestructed=*/true);
37006f32e7eSjoerg
37106f32e7eSjoerg // Now emit our call.
37206f32e7eSjoerg llvm::CallBase *CallOrInvoke;
37306f32e7eSjoerg RValue RV = EmitCall(*CurFnInfo, CGCallee::forDirect(Callee, CurGD), Slot,
37406f32e7eSjoerg CallArgs, &CallOrInvoke);
37506f32e7eSjoerg
37606f32e7eSjoerg // Consider return adjustment if we have ThunkInfo.
37706f32e7eSjoerg if (Thunk && !Thunk->Return.isEmpty())
37806f32e7eSjoerg RV = PerformReturnAdjustment(*this, ResultType, RV, *Thunk);
37906f32e7eSjoerg else if (llvm::CallInst* Call = dyn_cast<llvm::CallInst>(CallOrInvoke))
38006f32e7eSjoerg Call->setTailCallKind(llvm::CallInst::TCK_Tail);
38106f32e7eSjoerg
38206f32e7eSjoerg // Emit return.
38306f32e7eSjoerg if (!ResultType->isVoidType() && Slot.isNull())
38406f32e7eSjoerg CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType);
38506f32e7eSjoerg
38606f32e7eSjoerg // Disable the final ARC autorelease.
38706f32e7eSjoerg AutoreleaseResult = false;
38806f32e7eSjoerg
38906f32e7eSjoerg FinishThunk();
39006f32e7eSjoerg }
39106f32e7eSjoerg
EmitMustTailThunk(GlobalDecl GD,llvm::Value * AdjustedThisPtr,llvm::FunctionCallee Callee)39206f32e7eSjoerg void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
39306f32e7eSjoerg llvm::Value *AdjustedThisPtr,
39406f32e7eSjoerg llvm::FunctionCallee Callee) {
39506f32e7eSjoerg // Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery
39606f32e7eSjoerg // to translate AST arguments into LLVM IR arguments. For thunks, we know
39706f32e7eSjoerg // that the caller prototype more or less matches the callee prototype with
39806f32e7eSjoerg // the exception of 'this'.
39906f32e7eSjoerg SmallVector<llvm::Value *, 8> Args;
40006f32e7eSjoerg for (llvm::Argument &A : CurFn->args())
40106f32e7eSjoerg Args.push_back(&A);
40206f32e7eSjoerg
40306f32e7eSjoerg // Set the adjusted 'this' pointer.
40406f32e7eSjoerg const ABIArgInfo &ThisAI = CurFnInfo->arg_begin()->info;
40506f32e7eSjoerg if (ThisAI.isDirect()) {
40606f32e7eSjoerg const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo();
40706f32e7eSjoerg int ThisArgNo = RetAI.isIndirect() && !RetAI.isSRetAfterThis() ? 1 : 0;
40806f32e7eSjoerg llvm::Type *ThisType = Args[ThisArgNo]->getType();
40906f32e7eSjoerg if (ThisType != AdjustedThisPtr->getType())
41006f32e7eSjoerg AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
41106f32e7eSjoerg Args[ThisArgNo] = AdjustedThisPtr;
41206f32e7eSjoerg } else {
41306f32e7eSjoerg assert(ThisAI.isInAlloca() && "this is passed directly or inalloca");
41406f32e7eSjoerg Address ThisAddr = GetAddrOfLocalVar(CXXABIThisDecl);
41506f32e7eSjoerg llvm::Type *ThisType = ThisAddr.getElementType();
41606f32e7eSjoerg if (ThisType != AdjustedThisPtr->getType())
41706f32e7eSjoerg AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
41806f32e7eSjoerg Builder.CreateStore(AdjustedThisPtr, ThisAddr);
41906f32e7eSjoerg }
42006f32e7eSjoerg
42106f32e7eSjoerg // Emit the musttail call manually. Even if the prologue pushed cleanups, we
42206f32e7eSjoerg // don't actually want to run them.
42306f32e7eSjoerg llvm::CallInst *Call = Builder.CreateCall(Callee, Args);
42406f32e7eSjoerg Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
42506f32e7eSjoerg
42606f32e7eSjoerg // Apply the standard set of call attributes.
42706f32e7eSjoerg unsigned CallingConv;
42806f32e7eSjoerg llvm::AttributeList Attrs;
42906f32e7eSjoerg CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD,
430*13fbcb42Sjoerg Attrs, CallingConv, /*AttrOnCallSite=*/true,
431*13fbcb42Sjoerg /*IsThunk=*/false);
43206f32e7eSjoerg Call->setAttributes(Attrs);
43306f32e7eSjoerg Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
43406f32e7eSjoerg
43506f32e7eSjoerg if (Call->getType()->isVoidTy())
43606f32e7eSjoerg Builder.CreateRetVoid();
43706f32e7eSjoerg else
43806f32e7eSjoerg Builder.CreateRet(Call);
43906f32e7eSjoerg
44006f32e7eSjoerg // Finish the function to maintain CodeGenFunction invariants.
44106f32e7eSjoerg // FIXME: Don't emit unreachable code.
44206f32e7eSjoerg EmitBlock(createBasicBlock());
443*13fbcb42Sjoerg
444*13fbcb42Sjoerg FinishThunk();
44506f32e7eSjoerg }
44606f32e7eSjoerg
generateThunk(llvm::Function * Fn,const CGFunctionInfo & FnInfo,GlobalDecl GD,const ThunkInfo & Thunk,bool IsUnprototyped)44706f32e7eSjoerg void CodeGenFunction::generateThunk(llvm::Function *Fn,
44806f32e7eSjoerg const CGFunctionInfo &FnInfo, GlobalDecl GD,
44906f32e7eSjoerg const ThunkInfo &Thunk,
45006f32e7eSjoerg bool IsUnprototyped) {
45106f32e7eSjoerg StartThunk(Fn, GD, FnInfo, IsUnprototyped);
45206f32e7eSjoerg // Create a scope with an artificial location for the body of this function.
45306f32e7eSjoerg auto AL = ApplyDebugLocation::CreateArtificial(*this);
45406f32e7eSjoerg
45506f32e7eSjoerg // Get our callee. Use a placeholder type if this method is unprototyped so
45606f32e7eSjoerg // that CodeGenModule doesn't try to set attributes.
45706f32e7eSjoerg llvm::Type *Ty;
45806f32e7eSjoerg if (IsUnprototyped)
45906f32e7eSjoerg Ty = llvm::StructType::get(getLLVMContext());
46006f32e7eSjoerg else
46106f32e7eSjoerg Ty = CGM.getTypes().GetFunctionType(FnInfo);
46206f32e7eSjoerg
46306f32e7eSjoerg llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
46406f32e7eSjoerg
46506f32e7eSjoerg // Fix up the function type for an unprototyped musttail call.
46606f32e7eSjoerg if (IsUnprototyped)
46706f32e7eSjoerg Callee = llvm::ConstantExpr::getBitCast(Callee, Fn->getType());
46806f32e7eSjoerg
46906f32e7eSjoerg // Make the call and return the result.
47006f32e7eSjoerg EmitCallAndReturnForThunk(llvm::FunctionCallee(Fn->getFunctionType(), Callee),
47106f32e7eSjoerg &Thunk, IsUnprototyped);
47206f32e7eSjoerg }
47306f32e7eSjoerg
shouldEmitVTableThunk(CodeGenModule & CGM,const CXXMethodDecl * MD,bool IsUnprototyped,bool ForVTable)47406f32e7eSjoerg static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD,
47506f32e7eSjoerg bool IsUnprototyped, bool ForVTable) {
47606f32e7eSjoerg // Always emit thunks in the MS C++ ABI. We cannot rely on other TUs to
47706f32e7eSjoerg // provide thunks for us.
47806f32e7eSjoerg if (CGM.getTarget().getCXXABI().isMicrosoft())
47906f32e7eSjoerg return true;
48006f32e7eSjoerg
48106f32e7eSjoerg // In the Itanium C++ ABI, vtable thunks are provided by TUs that provide
48206f32e7eSjoerg // definitions of the main method. Therefore, emitting thunks with the vtable
48306f32e7eSjoerg // is purely an optimization. Emit the thunk if optimizations are enabled and
48406f32e7eSjoerg // all of the parameter types are complete.
48506f32e7eSjoerg if (ForVTable)
48606f32e7eSjoerg return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped;
48706f32e7eSjoerg
48806f32e7eSjoerg // Always emit thunks along with the method definition.
48906f32e7eSjoerg return true;
49006f32e7eSjoerg }
49106f32e7eSjoerg
maybeEmitThunk(GlobalDecl GD,const ThunkInfo & TI,bool ForVTable)49206f32e7eSjoerg llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
49306f32e7eSjoerg const ThunkInfo &TI,
49406f32e7eSjoerg bool ForVTable) {
49506f32e7eSjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
49606f32e7eSjoerg
49706f32e7eSjoerg // First, get a declaration. Compute the mangled name. Don't worry about
49806f32e7eSjoerg // getting the function prototype right, since we may only need this
49906f32e7eSjoerg // declaration to fill in a vtable slot.
50006f32e7eSjoerg SmallString<256> Name;
50106f32e7eSjoerg MangleContext &MCtx = CGM.getCXXABI().getMangleContext();
50206f32e7eSjoerg llvm::raw_svector_ostream Out(Name);
50306f32e7eSjoerg if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
50406f32e7eSjoerg MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI.This, Out);
50506f32e7eSjoerg else
50606f32e7eSjoerg MCtx.mangleThunk(MD, TI, Out);
50706f32e7eSjoerg llvm::Type *ThunkVTableTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
50806f32e7eSjoerg llvm::Constant *Thunk = CGM.GetAddrOfThunk(Name, ThunkVTableTy, GD);
50906f32e7eSjoerg
51006f32e7eSjoerg // If we don't need to emit a definition, return this declaration as is.
51106f32e7eSjoerg bool IsUnprototyped = !CGM.getTypes().isFuncTypeConvertible(
51206f32e7eSjoerg MD->getType()->castAs<FunctionType>());
51306f32e7eSjoerg if (!shouldEmitVTableThunk(CGM, MD, IsUnprototyped, ForVTable))
51406f32e7eSjoerg return Thunk;
51506f32e7eSjoerg
51606f32e7eSjoerg // Arrange a function prototype appropriate for a function definition. In some
51706f32e7eSjoerg // cases in the MS ABI, we may need to build an unprototyped musttail thunk.
51806f32e7eSjoerg const CGFunctionInfo &FnInfo =
51906f32e7eSjoerg IsUnprototyped ? CGM.getTypes().arrangeUnprototypedMustTailThunk(MD)
52006f32e7eSjoerg : CGM.getTypes().arrangeGlobalDeclaration(GD);
52106f32e7eSjoerg llvm::FunctionType *ThunkFnTy = CGM.getTypes().GetFunctionType(FnInfo);
52206f32e7eSjoerg
52306f32e7eSjoerg // If the type of the underlying GlobalValue is wrong, we'll have to replace
52406f32e7eSjoerg // it. It should be a declaration.
52506f32e7eSjoerg llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts());
52606f32e7eSjoerg if (ThunkFn->getFunctionType() != ThunkFnTy) {
52706f32e7eSjoerg llvm::GlobalValue *OldThunkFn = ThunkFn;
52806f32e7eSjoerg
52906f32e7eSjoerg assert(OldThunkFn->isDeclaration() && "Shouldn't replace non-declaration");
53006f32e7eSjoerg
53106f32e7eSjoerg // Remove the name from the old thunk function and get a new thunk.
53206f32e7eSjoerg OldThunkFn->setName(StringRef());
53306f32e7eSjoerg ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,
53406f32e7eSjoerg Name.str(), &CGM.getModule());
535*13fbcb42Sjoerg CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false);
53606f32e7eSjoerg
53706f32e7eSjoerg // If needed, replace the old thunk with a bitcast.
53806f32e7eSjoerg if (!OldThunkFn->use_empty()) {
53906f32e7eSjoerg llvm::Constant *NewPtrForOldDecl =
54006f32e7eSjoerg llvm::ConstantExpr::getBitCast(ThunkFn, OldThunkFn->getType());
54106f32e7eSjoerg OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl);
54206f32e7eSjoerg }
54306f32e7eSjoerg
54406f32e7eSjoerg // Remove the old thunk.
54506f32e7eSjoerg OldThunkFn->eraseFromParent();
54606f32e7eSjoerg }
54706f32e7eSjoerg
54806f32e7eSjoerg bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();
54906f32e7eSjoerg bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
55006f32e7eSjoerg
55106f32e7eSjoerg if (!ThunkFn->isDeclaration()) {
55206f32e7eSjoerg if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
55306f32e7eSjoerg // There is already a thunk emitted for this function, do nothing.
55406f32e7eSjoerg return ThunkFn;
55506f32e7eSjoerg }
55606f32e7eSjoerg
55706f32e7eSjoerg setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
55806f32e7eSjoerg return ThunkFn;
55906f32e7eSjoerg }
56006f32e7eSjoerg
56106f32e7eSjoerg // If this will be unprototyped, add the "thunk" attribute so that LLVM knows
56206f32e7eSjoerg // that the return type is meaningless. These thunks can be used to call
56306f32e7eSjoerg // functions with differing return types, and the caller is required to cast
56406f32e7eSjoerg // the prototype appropriately to extract the correct value.
56506f32e7eSjoerg if (IsUnprototyped)
56606f32e7eSjoerg ThunkFn->addFnAttr("thunk");
56706f32e7eSjoerg
56806f32e7eSjoerg CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);
56906f32e7eSjoerg
57006f32e7eSjoerg // Thunks for variadic methods are special because in general variadic
571*13fbcb42Sjoerg // arguments cannot be perfectly forwarded. In the general case, clang
57206f32e7eSjoerg // implements such thunks by cloning the original function body. However, for
57306f32e7eSjoerg // thunks with no return adjustment on targets that support musttail, we can
57406f32e7eSjoerg // use musttail to perfectly forward the variadic arguments.
57506f32e7eSjoerg bool ShouldCloneVarArgs = false;
57606f32e7eSjoerg if (!IsUnprototyped && ThunkFn->isVarArg()) {
57706f32e7eSjoerg ShouldCloneVarArgs = true;
57806f32e7eSjoerg if (TI.Return.isEmpty()) {
57906f32e7eSjoerg switch (CGM.getTriple().getArch()) {
58006f32e7eSjoerg case llvm::Triple::x86_64:
58106f32e7eSjoerg case llvm::Triple::x86:
58206f32e7eSjoerg case llvm::Triple::aarch64:
58306f32e7eSjoerg ShouldCloneVarArgs = false;
58406f32e7eSjoerg break;
58506f32e7eSjoerg default:
58606f32e7eSjoerg break;
58706f32e7eSjoerg }
58806f32e7eSjoerg }
58906f32e7eSjoerg }
59006f32e7eSjoerg
59106f32e7eSjoerg if (ShouldCloneVarArgs) {
59206f32e7eSjoerg if (UseAvailableExternallyLinkage)
59306f32e7eSjoerg return ThunkFn;
59406f32e7eSjoerg ThunkFn =
59506f32e7eSjoerg CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, TI);
59606f32e7eSjoerg } else {
59706f32e7eSjoerg // Normal thunk body generation.
59806f32e7eSjoerg CodeGenFunction(CGM).generateThunk(ThunkFn, FnInfo, GD, TI, IsUnprototyped);
59906f32e7eSjoerg }
60006f32e7eSjoerg
60106f32e7eSjoerg setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
60206f32e7eSjoerg return ThunkFn;
60306f32e7eSjoerg }
60406f32e7eSjoerg
EmitThunks(GlobalDecl GD)60506f32e7eSjoerg void CodeGenVTables::EmitThunks(GlobalDecl GD) {
60606f32e7eSjoerg const CXXMethodDecl *MD =
60706f32e7eSjoerg cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
60806f32e7eSjoerg
60906f32e7eSjoerg // We don't need to generate thunks for the base destructor.
61006f32e7eSjoerg if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
61106f32e7eSjoerg return;
61206f32e7eSjoerg
61306f32e7eSjoerg const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector =
61406f32e7eSjoerg VTContext->getThunkInfo(GD);
61506f32e7eSjoerg
61606f32e7eSjoerg if (!ThunkInfoVector)
61706f32e7eSjoerg return;
61806f32e7eSjoerg
61906f32e7eSjoerg for (const ThunkInfo& Thunk : *ThunkInfoVector)
62006f32e7eSjoerg maybeEmitThunk(GD, Thunk, /*ForVTable=*/false);
62106f32e7eSjoerg }
62206f32e7eSjoerg
addRelativeComponent(ConstantArrayBuilder & builder,llvm::Constant * component,unsigned vtableAddressPoint,bool vtableHasLocalLinkage,bool isCompleteDtor) const623*13fbcb42Sjoerg void CodeGenVTables::addRelativeComponent(ConstantArrayBuilder &builder,
624*13fbcb42Sjoerg llvm::Constant *component,
625*13fbcb42Sjoerg unsigned vtableAddressPoint,
626*13fbcb42Sjoerg bool vtableHasLocalLinkage,
627*13fbcb42Sjoerg bool isCompleteDtor) const {
628*13fbcb42Sjoerg // No need to get the offset of a nullptr.
629*13fbcb42Sjoerg if (component->isNullValue())
630*13fbcb42Sjoerg return builder.add(llvm::ConstantInt::get(CGM.Int32Ty, 0));
63106f32e7eSjoerg
632*13fbcb42Sjoerg auto *globalVal =
633*13fbcb42Sjoerg cast<llvm::GlobalValue>(component->stripPointerCastsAndAliases());
634*13fbcb42Sjoerg llvm::Module &module = CGM.getModule();
635*13fbcb42Sjoerg
636*13fbcb42Sjoerg // We don't want to copy the linkage of the vtable exactly because we still
637*13fbcb42Sjoerg // want the stub/proxy to be emitted for properly calculating the offset.
638*13fbcb42Sjoerg // Examples where there would be no symbol emitted are available_externally
639*13fbcb42Sjoerg // and private linkages.
640*13fbcb42Sjoerg auto stubLinkage = vtableHasLocalLinkage ? llvm::GlobalValue::InternalLinkage
641*13fbcb42Sjoerg : llvm::GlobalValue::ExternalLinkage;
642*13fbcb42Sjoerg
643*13fbcb42Sjoerg llvm::Constant *target;
644*13fbcb42Sjoerg if (auto *func = dyn_cast<llvm::Function>(globalVal)) {
645*13fbcb42Sjoerg target = llvm::DSOLocalEquivalent::get(func);
646*13fbcb42Sjoerg } else {
647*13fbcb42Sjoerg llvm::SmallString<16> rttiProxyName(globalVal->getName());
648*13fbcb42Sjoerg rttiProxyName.append(".rtti_proxy");
649*13fbcb42Sjoerg
650*13fbcb42Sjoerg // The RTTI component may not always be emitted in the same linkage unit as
651*13fbcb42Sjoerg // the vtable. As a general case, we can make a dso_local proxy to the RTTI
652*13fbcb42Sjoerg // that points to the actual RTTI struct somewhere. This will result in a
653*13fbcb42Sjoerg // GOTPCREL relocation when taking the relative offset to the proxy.
654*13fbcb42Sjoerg llvm::GlobalVariable *proxy = module.getNamedGlobal(rttiProxyName);
655*13fbcb42Sjoerg if (!proxy) {
656*13fbcb42Sjoerg proxy = new llvm::GlobalVariable(module, globalVal->getType(),
657*13fbcb42Sjoerg /*isConstant=*/true, stubLinkage,
658*13fbcb42Sjoerg globalVal, rttiProxyName);
659*13fbcb42Sjoerg proxy->setDSOLocal(true);
660*13fbcb42Sjoerg proxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
661*13fbcb42Sjoerg if (!proxy->hasLocalLinkage()) {
662*13fbcb42Sjoerg proxy->setVisibility(llvm::GlobalValue::HiddenVisibility);
663*13fbcb42Sjoerg proxy->setComdat(module.getOrInsertComdat(rttiProxyName));
664*13fbcb42Sjoerg }
665*13fbcb42Sjoerg }
666*13fbcb42Sjoerg target = proxy;
667*13fbcb42Sjoerg }
668*13fbcb42Sjoerg
669*13fbcb42Sjoerg builder.addRelativeOffsetToPosition(CGM.Int32Ty, target,
670*13fbcb42Sjoerg /*position=*/vtableAddressPoint);
671*13fbcb42Sjoerg }
672*13fbcb42Sjoerg
useRelativeLayout() const673*13fbcb42Sjoerg bool CodeGenVTables::useRelativeLayout() const {
674*13fbcb42Sjoerg return CGM.getTarget().getCXXABI().isItaniumFamily() &&
675*13fbcb42Sjoerg CGM.getItaniumVTableContext().isRelativeLayout();
676*13fbcb42Sjoerg }
677*13fbcb42Sjoerg
getVTableComponentType() const678*13fbcb42Sjoerg llvm::Type *CodeGenVTables::getVTableComponentType() const {
679*13fbcb42Sjoerg if (useRelativeLayout())
680*13fbcb42Sjoerg return CGM.Int32Ty;
681*13fbcb42Sjoerg return CGM.Int8PtrTy;
682*13fbcb42Sjoerg }
683*13fbcb42Sjoerg
AddPointerLayoutOffset(const CodeGenModule & CGM,ConstantArrayBuilder & builder,CharUnits offset)684*13fbcb42Sjoerg static void AddPointerLayoutOffset(const CodeGenModule &CGM,
685*13fbcb42Sjoerg ConstantArrayBuilder &builder,
686*13fbcb42Sjoerg CharUnits offset) {
68706f32e7eSjoerg builder.add(llvm::ConstantExpr::getIntToPtr(
68806f32e7eSjoerg llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()),
68906f32e7eSjoerg CGM.Int8PtrTy));
690*13fbcb42Sjoerg }
691*13fbcb42Sjoerg
AddRelativeLayoutOffset(const CodeGenModule & CGM,ConstantArrayBuilder & builder,CharUnits offset)692*13fbcb42Sjoerg static void AddRelativeLayoutOffset(const CodeGenModule &CGM,
693*13fbcb42Sjoerg ConstantArrayBuilder &builder,
694*13fbcb42Sjoerg CharUnits offset) {
695*13fbcb42Sjoerg builder.add(llvm::ConstantInt::get(CGM.Int32Ty, offset.getQuantity()));
696*13fbcb42Sjoerg }
697*13fbcb42Sjoerg
addVTableComponent(ConstantArrayBuilder & builder,const VTableLayout & layout,unsigned componentIndex,llvm::Constant * rtti,unsigned & nextVTableThunkIndex,unsigned vtableAddressPoint,bool vtableHasLocalLinkage)698*13fbcb42Sjoerg void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
699*13fbcb42Sjoerg const VTableLayout &layout,
700*13fbcb42Sjoerg unsigned componentIndex,
701*13fbcb42Sjoerg llvm::Constant *rtti,
702*13fbcb42Sjoerg unsigned &nextVTableThunkIndex,
703*13fbcb42Sjoerg unsigned vtableAddressPoint,
704*13fbcb42Sjoerg bool vtableHasLocalLinkage) {
705*13fbcb42Sjoerg auto &component = layout.vtable_components()[componentIndex];
706*13fbcb42Sjoerg
707*13fbcb42Sjoerg auto addOffsetConstant =
708*13fbcb42Sjoerg useRelativeLayout() ? AddRelativeLayoutOffset : AddPointerLayoutOffset;
70906f32e7eSjoerg
71006f32e7eSjoerg switch (component.getKind()) {
71106f32e7eSjoerg case VTableComponent::CK_VCallOffset:
712*13fbcb42Sjoerg return addOffsetConstant(CGM, builder, component.getVCallOffset());
71306f32e7eSjoerg
71406f32e7eSjoerg case VTableComponent::CK_VBaseOffset:
715*13fbcb42Sjoerg return addOffsetConstant(CGM, builder, component.getVBaseOffset());
71606f32e7eSjoerg
71706f32e7eSjoerg case VTableComponent::CK_OffsetToTop:
718*13fbcb42Sjoerg return addOffsetConstant(CGM, builder, component.getOffsetToTop());
71906f32e7eSjoerg
72006f32e7eSjoerg case VTableComponent::CK_RTTI:
721*13fbcb42Sjoerg if (useRelativeLayout())
722*13fbcb42Sjoerg return addRelativeComponent(builder, rtti, vtableAddressPoint,
723*13fbcb42Sjoerg vtableHasLocalLinkage,
724*13fbcb42Sjoerg /*isCompleteDtor=*/false);
725*13fbcb42Sjoerg else
72606f32e7eSjoerg return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.Int8PtrTy));
72706f32e7eSjoerg
72806f32e7eSjoerg case VTableComponent::CK_FunctionPointer:
72906f32e7eSjoerg case VTableComponent::CK_CompleteDtorPointer:
73006f32e7eSjoerg case VTableComponent::CK_DeletingDtorPointer: {
731*13fbcb42Sjoerg GlobalDecl GD = component.getGlobalDecl();
73206f32e7eSjoerg
73306f32e7eSjoerg if (CGM.getLangOpts().CUDA) {
73406f32e7eSjoerg // Emit NULL for methods we can't codegen on this
73506f32e7eSjoerg // side. Otherwise we'd end up with vtable with unresolved
73606f32e7eSjoerg // references.
73706f32e7eSjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
73806f32e7eSjoerg // OK on device side: functions w/ __device__ attribute
73906f32e7eSjoerg // OK on host side: anything except __device__-only functions.
74006f32e7eSjoerg bool CanEmitMethod =
74106f32e7eSjoerg CGM.getLangOpts().CUDAIsDevice
74206f32e7eSjoerg ? MD->hasAttr<CUDADeviceAttr>()
74306f32e7eSjoerg : (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
74406f32e7eSjoerg if (!CanEmitMethod)
745*13fbcb42Sjoerg return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy));
74606f32e7eSjoerg // Method is acceptable, continue processing as usual.
74706f32e7eSjoerg }
74806f32e7eSjoerg
749*13fbcb42Sjoerg auto getSpecialVirtualFn = [&](StringRef name) -> llvm::Constant * {
750*13fbcb42Sjoerg // FIXME(PR43094): When merging comdat groups, lld can select a local
751*13fbcb42Sjoerg // symbol as the signature symbol even though it cannot be accessed
752*13fbcb42Sjoerg // outside that symbol's TU. The relative vtables ABI would make
753*13fbcb42Sjoerg // __cxa_pure_virtual and __cxa_deleted_virtual local symbols, and
754*13fbcb42Sjoerg // depending on link order, the comdat groups could resolve to the one
755*13fbcb42Sjoerg // with the local symbol. As a temporary solution, fill these components
756*13fbcb42Sjoerg // with zero. We shouldn't be calling these in the first place anyway.
757*13fbcb42Sjoerg if (useRelativeLayout())
758*13fbcb42Sjoerg return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
759*13fbcb42Sjoerg
760*13fbcb42Sjoerg // For NVPTX devices in OpenMP emit special functon as null pointers,
761*13fbcb42Sjoerg // otherwise linking ends up with unresolved references.
762*13fbcb42Sjoerg if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPIsDevice &&
763*13fbcb42Sjoerg CGM.getTriple().isNVPTX())
764*13fbcb42Sjoerg return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
76506f32e7eSjoerg llvm::FunctionType *fnTy =
76606f32e7eSjoerg llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
76706f32e7eSjoerg llvm::Constant *fn = cast<llvm::Constant>(
76806f32e7eSjoerg CGM.CreateRuntimeFunction(fnTy, name).getCallee());
76906f32e7eSjoerg if (auto f = dyn_cast<llvm::Function>(fn))
77006f32e7eSjoerg f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
77106f32e7eSjoerg return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy);
77206f32e7eSjoerg };
77306f32e7eSjoerg
77406f32e7eSjoerg llvm::Constant *fnPtr;
77506f32e7eSjoerg
77606f32e7eSjoerg // Pure virtual member functions.
77706f32e7eSjoerg if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) {
77806f32e7eSjoerg if (!PureVirtualFn)
77906f32e7eSjoerg PureVirtualFn =
78006f32e7eSjoerg getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
78106f32e7eSjoerg fnPtr = PureVirtualFn;
78206f32e7eSjoerg
78306f32e7eSjoerg // Deleted virtual member functions.
78406f32e7eSjoerg } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
78506f32e7eSjoerg if (!DeletedVirtualFn)
78606f32e7eSjoerg DeletedVirtualFn =
78706f32e7eSjoerg getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName());
78806f32e7eSjoerg fnPtr = DeletedVirtualFn;
78906f32e7eSjoerg
79006f32e7eSjoerg // Thunks.
79106f32e7eSjoerg } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
792*13fbcb42Sjoerg layout.vtable_thunks()[nextVTableThunkIndex].first ==
793*13fbcb42Sjoerg componentIndex) {
79406f32e7eSjoerg auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;
79506f32e7eSjoerg
79606f32e7eSjoerg nextVTableThunkIndex++;
79706f32e7eSjoerg fnPtr = maybeEmitThunk(GD, thunkInfo, /*ForVTable=*/true);
79806f32e7eSjoerg
79906f32e7eSjoerg // Otherwise we can use the method definition directly.
80006f32e7eSjoerg } else {
80106f32e7eSjoerg llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
80206f32e7eSjoerg fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true);
80306f32e7eSjoerg }
80406f32e7eSjoerg
805*13fbcb42Sjoerg if (useRelativeLayout()) {
806*13fbcb42Sjoerg return addRelativeComponent(
807*13fbcb42Sjoerg builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,
808*13fbcb42Sjoerg component.getKind() == VTableComponent::CK_CompleteDtorPointer);
809*13fbcb42Sjoerg } else
810*13fbcb42Sjoerg return builder.add(llvm::ConstantExpr::getBitCast(fnPtr, CGM.Int8PtrTy));
81106f32e7eSjoerg }
81206f32e7eSjoerg
81306f32e7eSjoerg case VTableComponent::CK_UnusedFunctionPointer:
814*13fbcb42Sjoerg if (useRelativeLayout())
815*13fbcb42Sjoerg return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int32Ty));
816*13fbcb42Sjoerg else
81706f32e7eSjoerg return builder.addNullPointer(CGM.Int8PtrTy);
81806f32e7eSjoerg }
81906f32e7eSjoerg
82006f32e7eSjoerg llvm_unreachable("Unexpected vtable component kind");
82106f32e7eSjoerg }
82206f32e7eSjoerg
getVTableType(const VTableLayout & layout)82306f32e7eSjoerg llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) {
82406f32e7eSjoerg SmallVector<llvm::Type *, 4> tys;
825*13fbcb42Sjoerg llvm::Type *componentType = getVTableComponentType();
826*13fbcb42Sjoerg for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i)
827*13fbcb42Sjoerg tys.push_back(llvm::ArrayType::get(componentType, layout.getVTableSize(i)));
82806f32e7eSjoerg
82906f32e7eSjoerg return llvm::StructType::get(CGM.getLLVMContext(), tys);
83006f32e7eSjoerg }
83106f32e7eSjoerg
createVTableInitializer(ConstantStructBuilder & builder,const VTableLayout & layout,llvm::Constant * rtti,bool vtableHasLocalLinkage)83206f32e7eSjoerg void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder,
83306f32e7eSjoerg const VTableLayout &layout,
834*13fbcb42Sjoerg llvm::Constant *rtti,
835*13fbcb42Sjoerg bool vtableHasLocalLinkage) {
836*13fbcb42Sjoerg llvm::Type *componentType = getVTableComponentType();
837*13fbcb42Sjoerg
838*13fbcb42Sjoerg const auto &addressPoints = layout.getAddressPointIndices();
83906f32e7eSjoerg unsigned nextVTableThunkIndex = 0;
840*13fbcb42Sjoerg for (unsigned vtableIndex = 0, endIndex = layout.getNumVTables();
841*13fbcb42Sjoerg vtableIndex != endIndex; ++vtableIndex) {
842*13fbcb42Sjoerg auto vtableElem = builder.beginArray(componentType);
843*13fbcb42Sjoerg
844*13fbcb42Sjoerg size_t vtableStart = layout.getVTableOffset(vtableIndex);
845*13fbcb42Sjoerg size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex);
846*13fbcb42Sjoerg for (size_t componentIndex = vtableStart; componentIndex < vtableEnd;
847*13fbcb42Sjoerg ++componentIndex) {
848*13fbcb42Sjoerg addVTableComponent(vtableElem, layout, componentIndex, rtti,
849*13fbcb42Sjoerg nextVTableThunkIndex, addressPoints[vtableIndex],
850*13fbcb42Sjoerg vtableHasLocalLinkage);
85106f32e7eSjoerg }
85206f32e7eSjoerg vtableElem.finishAndAddTo(builder);
85306f32e7eSjoerg }
85406f32e7eSjoerg }
85506f32e7eSjoerg
GenerateConstructionVTable(const CXXRecordDecl * RD,const BaseSubobject & Base,bool BaseIsVirtual,llvm::GlobalVariable::LinkageTypes Linkage,VTableAddressPointsMapTy & AddressPoints)856*13fbcb42Sjoerg llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable(
857*13fbcb42Sjoerg const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual,
85806f32e7eSjoerg llvm::GlobalVariable::LinkageTypes Linkage,
85906f32e7eSjoerg VTableAddressPointsMapTy &AddressPoints) {
86006f32e7eSjoerg if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
86106f32e7eSjoerg DI->completeClassData(Base.getBase());
86206f32e7eSjoerg
86306f32e7eSjoerg std::unique_ptr<VTableLayout> VTLayout(
86406f32e7eSjoerg getItaniumVTableContext().createConstructionVTableLayout(
86506f32e7eSjoerg Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));
86606f32e7eSjoerg
86706f32e7eSjoerg // Add the address points.
86806f32e7eSjoerg AddressPoints = VTLayout->getAddressPoints();
86906f32e7eSjoerg
87006f32e7eSjoerg // Get the mangled construction vtable name.
87106f32e7eSjoerg SmallString<256> OutName;
87206f32e7eSjoerg llvm::raw_svector_ostream Out(OutName);
87306f32e7eSjoerg cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext())
87406f32e7eSjoerg .mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(),
87506f32e7eSjoerg Base.getBase(), Out);
876*13fbcb42Sjoerg SmallString<256> Name(OutName);
877*13fbcb42Sjoerg
878*13fbcb42Sjoerg bool UsingRelativeLayout = getItaniumVTableContext().isRelativeLayout();
879*13fbcb42Sjoerg bool VTableAliasExists =
880*13fbcb42Sjoerg UsingRelativeLayout && CGM.getModule().getNamedAlias(Name);
881*13fbcb42Sjoerg if (VTableAliasExists) {
882*13fbcb42Sjoerg // We previously made the vtable hidden and changed its name.
883*13fbcb42Sjoerg Name.append(".local");
884*13fbcb42Sjoerg }
88506f32e7eSjoerg
88606f32e7eSjoerg llvm::Type *VTType = getVTableType(*VTLayout);
88706f32e7eSjoerg
88806f32e7eSjoerg // Construction vtable symbols are not part of the Itanium ABI, so we cannot
88906f32e7eSjoerg // guarantee that they actually will be available externally. Instead, when
89006f32e7eSjoerg // emitting an available_externally VTT, we provide references to an internal
89106f32e7eSjoerg // linkage construction vtable. The ABI only requires complete-object vtables
89206f32e7eSjoerg // to be the same for all instances of a type, not construction vtables.
89306f32e7eSjoerg if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
89406f32e7eSjoerg Linkage = llvm::GlobalVariable::InternalLinkage;
89506f32e7eSjoerg
89606f32e7eSjoerg unsigned Align = CGM.getDataLayout().getABITypeAlignment(VTType);
89706f32e7eSjoerg
89806f32e7eSjoerg // Create the variable that will hold the construction vtable.
89906f32e7eSjoerg llvm::GlobalVariable *VTable =
90006f32e7eSjoerg CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align);
90106f32e7eSjoerg
90206f32e7eSjoerg // V-tables are always unnamed_addr.
90306f32e7eSjoerg VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
90406f32e7eSjoerg
90506f32e7eSjoerg llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
90606f32e7eSjoerg CGM.getContext().getTagDeclType(Base.getBase()));
90706f32e7eSjoerg
90806f32e7eSjoerg // Create and set the initializer.
90906f32e7eSjoerg ConstantInitBuilder builder(CGM);
91006f32e7eSjoerg auto components = builder.beginStruct();
911*13fbcb42Sjoerg createVTableInitializer(components, *VTLayout, RTTI,
912*13fbcb42Sjoerg VTable->hasLocalLinkage());
91306f32e7eSjoerg components.finishAndSetAsInitializer(VTable);
91406f32e7eSjoerg
91506f32e7eSjoerg // Set properties only after the initializer has been set to ensure that the
91606f32e7eSjoerg // GV is treated as definition and not declaration.
91706f32e7eSjoerg assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration");
91806f32e7eSjoerg CGM.setGVProperties(VTable, RD);
91906f32e7eSjoerg
92006f32e7eSjoerg CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout.get());
92106f32e7eSjoerg
922*13fbcb42Sjoerg if (UsingRelativeLayout && !VTable->isDSOLocal())
923*13fbcb42Sjoerg GenerateRelativeVTableAlias(VTable, OutName);
924*13fbcb42Sjoerg
92506f32e7eSjoerg return VTable;
92606f32e7eSjoerg }
92706f32e7eSjoerg
928*13fbcb42Sjoerg // If the VTable is not dso_local, then we will not be able to indicate that
929*13fbcb42Sjoerg // the VTable does not need a relocation and move into rodata. A frequent
930*13fbcb42Sjoerg // time this can occur is for classes that should be made public from a DSO
931*13fbcb42Sjoerg // (like in libc++). For cases like these, we can make the vtable hidden or
932*13fbcb42Sjoerg // private and create a public alias with the same visibility and linkage as
933*13fbcb42Sjoerg // the original vtable type.
GenerateRelativeVTableAlias(llvm::GlobalVariable * VTable,llvm::StringRef AliasNameRef)934*13fbcb42Sjoerg void CodeGenVTables::GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
935*13fbcb42Sjoerg llvm::StringRef AliasNameRef) {
936*13fbcb42Sjoerg assert(getItaniumVTableContext().isRelativeLayout() &&
937*13fbcb42Sjoerg "Can only use this if the relative vtable ABI is used");
938*13fbcb42Sjoerg assert(!VTable->isDSOLocal() && "This should be called only if the vtable is "
939*13fbcb42Sjoerg "not guaranteed to be dso_local");
940*13fbcb42Sjoerg
941*13fbcb42Sjoerg // If the vtable is available_externally, we shouldn't (or need to) generate
942*13fbcb42Sjoerg // an alias for it in the first place since the vtable won't actually by
943*13fbcb42Sjoerg // emitted in this compilation unit.
944*13fbcb42Sjoerg if (VTable->hasAvailableExternallyLinkage())
945*13fbcb42Sjoerg return;
946*13fbcb42Sjoerg
947*13fbcb42Sjoerg // Create a new string in the event the alias is already the name of the
948*13fbcb42Sjoerg // vtable. Using the reference directly could lead to use of an inititialized
949*13fbcb42Sjoerg // value in the module's StringMap.
950*13fbcb42Sjoerg llvm::SmallString<256> AliasName(AliasNameRef);
951*13fbcb42Sjoerg VTable->setName(AliasName + ".local");
952*13fbcb42Sjoerg
953*13fbcb42Sjoerg auto Linkage = VTable->getLinkage();
954*13fbcb42Sjoerg assert(llvm::GlobalAlias::isValidLinkage(Linkage) &&
955*13fbcb42Sjoerg "Invalid vtable alias linkage");
956*13fbcb42Sjoerg
957*13fbcb42Sjoerg llvm::GlobalAlias *VTableAlias = CGM.getModule().getNamedAlias(AliasName);
958*13fbcb42Sjoerg if (!VTableAlias) {
959*13fbcb42Sjoerg VTableAlias = llvm::GlobalAlias::create(VTable->getValueType(),
960*13fbcb42Sjoerg VTable->getAddressSpace(), Linkage,
961*13fbcb42Sjoerg AliasName, &CGM.getModule());
962*13fbcb42Sjoerg } else {
963*13fbcb42Sjoerg assert(VTableAlias->getValueType() == VTable->getValueType());
964*13fbcb42Sjoerg assert(VTableAlias->getLinkage() == Linkage);
965*13fbcb42Sjoerg }
966*13fbcb42Sjoerg VTableAlias->setVisibility(VTable->getVisibility());
967*13fbcb42Sjoerg VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());
968*13fbcb42Sjoerg
969*13fbcb42Sjoerg // Both of these imply dso_local for the vtable.
970*13fbcb42Sjoerg if (!VTable->hasComdat()) {
971*13fbcb42Sjoerg // If this is in a comdat, then we shouldn't make the linkage private due to
972*13fbcb42Sjoerg // an issue in lld where private symbols can be used as the key symbol when
973*13fbcb42Sjoerg // choosing the prevelant group. This leads to "relocation refers to a
974*13fbcb42Sjoerg // symbol in a discarded section".
975*13fbcb42Sjoerg VTable->setLinkage(llvm::GlobalValue::PrivateLinkage);
976*13fbcb42Sjoerg } else {
977*13fbcb42Sjoerg // We should at least make this hidden since we don't want to expose it.
978*13fbcb42Sjoerg VTable->setVisibility(llvm::GlobalValue::HiddenVisibility);
979*13fbcb42Sjoerg }
980*13fbcb42Sjoerg
981*13fbcb42Sjoerg VTableAlias->setAliasee(VTable);
982*13fbcb42Sjoerg }
983*13fbcb42Sjoerg
shouldEmitAvailableExternallyVTable(const CodeGenModule & CGM,const CXXRecordDecl * RD)98406f32e7eSjoerg static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM,
98506f32e7eSjoerg const CXXRecordDecl *RD) {
98606f32e7eSjoerg return CGM.getCodeGenOpts().OptimizationLevel > 0 &&
98706f32e7eSjoerg CGM.getCXXABI().canSpeculativelyEmitVTable(RD);
98806f32e7eSjoerg }
98906f32e7eSjoerg
99006f32e7eSjoerg /// Compute the required linkage of the vtable for the given class.
99106f32e7eSjoerg ///
99206f32e7eSjoerg /// Note that we only call this at the end of the translation unit.
99306f32e7eSjoerg llvm::GlobalVariable::LinkageTypes
getVTableLinkage(const CXXRecordDecl * RD)99406f32e7eSjoerg CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
99506f32e7eSjoerg if (!RD->isExternallyVisible())
99606f32e7eSjoerg return llvm::GlobalVariable::InternalLinkage;
99706f32e7eSjoerg
99806f32e7eSjoerg // We're at the end of the translation unit, so the current key
99906f32e7eSjoerg // function is fully correct.
100006f32e7eSjoerg const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD);
100106f32e7eSjoerg if (keyFunction && !RD->hasAttr<DLLImportAttr>()) {
100206f32e7eSjoerg // If this class has a key function, use that to determine the
100306f32e7eSjoerg // linkage of the vtable.
100406f32e7eSjoerg const FunctionDecl *def = nullptr;
100506f32e7eSjoerg if (keyFunction->hasBody(def))
100606f32e7eSjoerg keyFunction = cast<CXXMethodDecl>(def);
100706f32e7eSjoerg
100806f32e7eSjoerg switch (keyFunction->getTemplateSpecializationKind()) {
100906f32e7eSjoerg case TSK_Undeclared:
101006f32e7eSjoerg case TSK_ExplicitSpecialization:
101106f32e7eSjoerg assert((def || CodeGenOpts.OptimizationLevel > 0 ||
101206f32e7eSjoerg CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) &&
101306f32e7eSjoerg "Shouldn't query vtable linkage without key function, "
101406f32e7eSjoerg "optimizations, or debug info");
101506f32e7eSjoerg if (!def && CodeGenOpts.OptimizationLevel > 0)
101606f32e7eSjoerg return llvm::GlobalVariable::AvailableExternallyLinkage;
101706f32e7eSjoerg
101806f32e7eSjoerg if (keyFunction->isInlined())
101906f32e7eSjoerg return !Context.getLangOpts().AppleKext ?
102006f32e7eSjoerg llvm::GlobalVariable::LinkOnceODRLinkage :
102106f32e7eSjoerg llvm::Function::InternalLinkage;
102206f32e7eSjoerg
102306f32e7eSjoerg return llvm::GlobalVariable::ExternalLinkage;
102406f32e7eSjoerg
102506f32e7eSjoerg case TSK_ImplicitInstantiation:
102606f32e7eSjoerg return !Context.getLangOpts().AppleKext ?
102706f32e7eSjoerg llvm::GlobalVariable::LinkOnceODRLinkage :
102806f32e7eSjoerg llvm::Function::InternalLinkage;
102906f32e7eSjoerg
103006f32e7eSjoerg case TSK_ExplicitInstantiationDefinition:
103106f32e7eSjoerg return !Context.getLangOpts().AppleKext ?
103206f32e7eSjoerg llvm::GlobalVariable::WeakODRLinkage :
103306f32e7eSjoerg llvm::Function::InternalLinkage;
103406f32e7eSjoerg
103506f32e7eSjoerg case TSK_ExplicitInstantiationDeclaration:
103606f32e7eSjoerg llvm_unreachable("Should not have been asked to emit this");
103706f32e7eSjoerg }
103806f32e7eSjoerg }
103906f32e7eSjoerg
104006f32e7eSjoerg // -fapple-kext mode does not support weak linkage, so we must use
104106f32e7eSjoerg // internal linkage.
104206f32e7eSjoerg if (Context.getLangOpts().AppleKext)
104306f32e7eSjoerg return llvm::Function::InternalLinkage;
104406f32e7eSjoerg
104506f32e7eSjoerg llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
104606f32e7eSjoerg llvm::GlobalValue::LinkOnceODRLinkage;
104706f32e7eSjoerg llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
104806f32e7eSjoerg llvm::GlobalValue::WeakODRLinkage;
104906f32e7eSjoerg if (RD->hasAttr<DLLExportAttr>()) {
105006f32e7eSjoerg // Cannot discard exported vtables.
105106f32e7eSjoerg DiscardableODRLinkage = NonDiscardableODRLinkage;
105206f32e7eSjoerg } else if (RD->hasAttr<DLLImportAttr>()) {
105306f32e7eSjoerg // Imported vtables are available externally.
105406f32e7eSjoerg DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
105506f32e7eSjoerg NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
105606f32e7eSjoerg }
105706f32e7eSjoerg
105806f32e7eSjoerg switch (RD->getTemplateSpecializationKind()) {
105906f32e7eSjoerg case TSK_Undeclared:
106006f32e7eSjoerg case TSK_ExplicitSpecialization:
106106f32e7eSjoerg case TSK_ImplicitInstantiation:
106206f32e7eSjoerg return DiscardableODRLinkage;
106306f32e7eSjoerg
106406f32e7eSjoerg case TSK_ExplicitInstantiationDeclaration:
106506f32e7eSjoerg // Explicit instantiations in MSVC do not provide vtables, so we must emit
106606f32e7eSjoerg // our own.
106706f32e7eSjoerg if (getTarget().getCXXABI().isMicrosoft())
106806f32e7eSjoerg return DiscardableODRLinkage;
106906f32e7eSjoerg return shouldEmitAvailableExternallyVTable(*this, RD)
107006f32e7eSjoerg ? llvm::GlobalVariable::AvailableExternallyLinkage
107106f32e7eSjoerg : llvm::GlobalVariable::ExternalLinkage;
107206f32e7eSjoerg
107306f32e7eSjoerg case TSK_ExplicitInstantiationDefinition:
107406f32e7eSjoerg return NonDiscardableODRLinkage;
107506f32e7eSjoerg }
107606f32e7eSjoerg
107706f32e7eSjoerg llvm_unreachable("Invalid TemplateSpecializationKind!");
107806f32e7eSjoerg }
107906f32e7eSjoerg
108006f32e7eSjoerg /// This is a callback from Sema to tell us that a particular vtable is
108106f32e7eSjoerg /// required to be emitted in this translation unit.
108206f32e7eSjoerg ///
108306f32e7eSjoerg /// This is only called for vtables that _must_ be emitted (mainly due to key
108406f32e7eSjoerg /// functions). For weak vtables, CodeGen tracks when they are needed and
108506f32e7eSjoerg /// emits them as-needed.
EmitVTable(CXXRecordDecl * theClass)108606f32e7eSjoerg void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) {
108706f32e7eSjoerg VTables.GenerateClassData(theClass);
108806f32e7eSjoerg }
108906f32e7eSjoerg
109006f32e7eSjoerg void
GenerateClassData(const CXXRecordDecl * RD)109106f32e7eSjoerg CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
109206f32e7eSjoerg if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
109306f32e7eSjoerg DI->completeClassData(RD);
109406f32e7eSjoerg
109506f32e7eSjoerg if (RD->getNumVBases())
109606f32e7eSjoerg CGM.getCXXABI().emitVirtualInheritanceTables(RD);
109706f32e7eSjoerg
109806f32e7eSjoerg CGM.getCXXABI().emitVTableDefinitions(*this, RD);
109906f32e7eSjoerg }
110006f32e7eSjoerg
110106f32e7eSjoerg /// At this point in the translation unit, does it appear that can we
110206f32e7eSjoerg /// rely on the vtable being defined elsewhere in the program?
110306f32e7eSjoerg ///
110406f32e7eSjoerg /// The response is really only definitive when called at the end of
110506f32e7eSjoerg /// the translation unit.
110606f32e7eSjoerg ///
110706f32e7eSjoerg /// The only semantic restriction here is that the object file should
110806f32e7eSjoerg /// not contain a vtable definition when that vtable is defined
110906f32e7eSjoerg /// strongly elsewhere. Otherwise, we'd just like to avoid emitting
111006f32e7eSjoerg /// vtables when unnecessary.
isVTableExternal(const CXXRecordDecl * RD)111106f32e7eSjoerg bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
111206f32e7eSjoerg assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
111306f32e7eSjoerg
111406f32e7eSjoerg // We always synthesize vtables if they are needed in the MS ABI. MSVC doesn't
111506f32e7eSjoerg // emit them even if there is an explicit template instantiation.
111606f32e7eSjoerg if (CGM.getTarget().getCXXABI().isMicrosoft())
111706f32e7eSjoerg return false;
111806f32e7eSjoerg
111906f32e7eSjoerg // If we have an explicit instantiation declaration (and not a
112006f32e7eSjoerg // definition), the vtable is defined elsewhere.
112106f32e7eSjoerg TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
112206f32e7eSjoerg if (TSK == TSK_ExplicitInstantiationDeclaration)
112306f32e7eSjoerg return true;
112406f32e7eSjoerg
112506f32e7eSjoerg // Otherwise, if the class is an instantiated template, the
112606f32e7eSjoerg // vtable must be defined here.
112706f32e7eSjoerg if (TSK == TSK_ImplicitInstantiation ||
112806f32e7eSjoerg TSK == TSK_ExplicitInstantiationDefinition)
112906f32e7eSjoerg return false;
113006f32e7eSjoerg
113106f32e7eSjoerg // Otherwise, if the class doesn't have a key function (possibly
113206f32e7eSjoerg // anymore), the vtable must be defined here.
113306f32e7eSjoerg const CXXMethodDecl *keyFunction = CGM.getContext().getCurrentKeyFunction(RD);
113406f32e7eSjoerg if (!keyFunction)
113506f32e7eSjoerg return false;
113606f32e7eSjoerg
113706f32e7eSjoerg // Otherwise, if we don't have a definition of the key function, the
113806f32e7eSjoerg // vtable must be defined somewhere else.
113906f32e7eSjoerg return !keyFunction->hasBody();
114006f32e7eSjoerg }
114106f32e7eSjoerg
114206f32e7eSjoerg /// Given that we're currently at the end of the translation unit, and
114306f32e7eSjoerg /// we've emitted a reference to the vtable for this class, should
114406f32e7eSjoerg /// we define that vtable?
shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule & CGM,const CXXRecordDecl * RD)114506f32e7eSjoerg static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
114606f32e7eSjoerg const CXXRecordDecl *RD) {
114706f32e7eSjoerg // If vtable is internal then it has to be done.
114806f32e7eSjoerg if (!CGM.getVTables().isVTableExternal(RD))
114906f32e7eSjoerg return true;
115006f32e7eSjoerg
115106f32e7eSjoerg // If it's external then maybe we will need it as available_externally.
115206f32e7eSjoerg return shouldEmitAvailableExternallyVTable(CGM, RD);
115306f32e7eSjoerg }
115406f32e7eSjoerg
115506f32e7eSjoerg /// Given that at some point we emitted a reference to one or more
115606f32e7eSjoerg /// vtables, and that we are now at the end of the translation unit,
115706f32e7eSjoerg /// decide whether we should emit them.
EmitDeferredVTables()115806f32e7eSjoerg void CodeGenModule::EmitDeferredVTables() {
115906f32e7eSjoerg #ifndef NDEBUG
116006f32e7eSjoerg // Remember the size of DeferredVTables, because we're going to assume
116106f32e7eSjoerg // that this entire operation doesn't modify it.
116206f32e7eSjoerg size_t savedSize = DeferredVTables.size();
116306f32e7eSjoerg #endif
116406f32e7eSjoerg
116506f32e7eSjoerg for (const CXXRecordDecl *RD : DeferredVTables)
116606f32e7eSjoerg if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD))
116706f32e7eSjoerg VTables.GenerateClassData(RD);
116806f32e7eSjoerg else if (shouldOpportunisticallyEmitVTables())
116906f32e7eSjoerg OpportunisticVTables.push_back(RD);
117006f32e7eSjoerg
117106f32e7eSjoerg assert(savedSize == DeferredVTables.size() &&
117206f32e7eSjoerg "deferred extra vtables during vtable emission?");
117306f32e7eSjoerg DeferredVTables.clear();
117406f32e7eSjoerg }
117506f32e7eSjoerg
HasLTOVisibilityPublicStd(const CXXRecordDecl * RD)1176*13fbcb42Sjoerg bool CodeGenModule::HasLTOVisibilityPublicStd(const CXXRecordDecl *RD) {
1177*13fbcb42Sjoerg if (!getCodeGenOpts().LTOVisibilityPublicStd)
1178*13fbcb42Sjoerg return false;
1179*13fbcb42Sjoerg
1180*13fbcb42Sjoerg const DeclContext *DC = RD;
1181*13fbcb42Sjoerg while (1) {
1182*13fbcb42Sjoerg auto *D = cast<Decl>(DC);
1183*13fbcb42Sjoerg DC = DC->getParent();
1184*13fbcb42Sjoerg if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
1185*13fbcb42Sjoerg if (auto *ND = dyn_cast<NamespaceDecl>(D))
1186*13fbcb42Sjoerg if (const IdentifierInfo *II = ND->getIdentifier())
1187*13fbcb42Sjoerg if (II->isStr("std") || II->isStr("stdext"))
1188*13fbcb42Sjoerg return true;
1189*13fbcb42Sjoerg break;
1190*13fbcb42Sjoerg }
1191*13fbcb42Sjoerg }
1192*13fbcb42Sjoerg
1193*13fbcb42Sjoerg return false;
1194*13fbcb42Sjoerg }
1195*13fbcb42Sjoerg
HasHiddenLTOVisibility(const CXXRecordDecl * RD)119606f32e7eSjoerg bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
119706f32e7eSjoerg LinkageInfo LV = RD->getLinkageAndVisibility();
119806f32e7eSjoerg if (!isExternallyVisible(LV.getLinkage()))
119906f32e7eSjoerg return true;
120006f32e7eSjoerg
120106f32e7eSjoerg if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
120206f32e7eSjoerg return false;
120306f32e7eSjoerg
120406f32e7eSjoerg if (getTriple().isOSBinFormatCOFF()) {
120506f32e7eSjoerg if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
120606f32e7eSjoerg return false;
120706f32e7eSjoerg } else {
120806f32e7eSjoerg if (LV.getVisibility() != HiddenVisibility)
120906f32e7eSjoerg return false;
121006f32e7eSjoerg }
121106f32e7eSjoerg
1212*13fbcb42Sjoerg return !HasLTOVisibilityPublicStd(RD);
121306f32e7eSjoerg }
121406f32e7eSjoerg
GetVCallVisibilityLevel(const CXXRecordDecl * RD,llvm::DenseSet<const CXXRecordDecl * > & Visited)1215*13fbcb42Sjoerg llvm::GlobalObject::VCallVisibility CodeGenModule::GetVCallVisibilityLevel(
1216*13fbcb42Sjoerg const CXXRecordDecl *RD, llvm::DenseSet<const CXXRecordDecl *> &Visited) {
1217*13fbcb42Sjoerg // If we have already visited this RD (which means this is a recursive call
1218*13fbcb42Sjoerg // since the initial call should have an empty Visited set), return the max
1219*13fbcb42Sjoerg // visibility. The recursive calls below compute the min between the result
1220*13fbcb42Sjoerg // of the recursive call and the current TypeVis, so returning the max here
1221*13fbcb42Sjoerg // ensures that it will have no effect on the current TypeVis.
1222*13fbcb42Sjoerg if (!Visited.insert(RD).second)
1223*13fbcb42Sjoerg return llvm::GlobalObject::VCallVisibilityTranslationUnit;
122406f32e7eSjoerg
122506f32e7eSjoerg LinkageInfo LV = RD->getLinkageAndVisibility();
122606f32e7eSjoerg llvm::GlobalObject::VCallVisibility TypeVis;
122706f32e7eSjoerg if (!isExternallyVisible(LV.getLinkage()))
122806f32e7eSjoerg TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
122906f32e7eSjoerg else if (HasHiddenLTOVisibility(RD))
123006f32e7eSjoerg TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
123106f32e7eSjoerg else
123206f32e7eSjoerg TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
123306f32e7eSjoerg
123406f32e7eSjoerg for (auto B : RD->bases())
123506f32e7eSjoerg if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1236*13fbcb42Sjoerg TypeVis = std::min(
1237*13fbcb42Sjoerg TypeVis,
1238*13fbcb42Sjoerg GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited));
123906f32e7eSjoerg
124006f32e7eSjoerg for (auto B : RD->vbases())
124106f32e7eSjoerg if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1242*13fbcb42Sjoerg TypeVis = std::min(
1243*13fbcb42Sjoerg TypeVis,
1244*13fbcb42Sjoerg GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited));
124506f32e7eSjoerg
124606f32e7eSjoerg return TypeVis;
124706f32e7eSjoerg }
124806f32e7eSjoerg
EmitVTableTypeMetadata(const CXXRecordDecl * RD,llvm::GlobalVariable * VTable,const VTableLayout & VTLayout)124906f32e7eSjoerg void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
125006f32e7eSjoerg llvm::GlobalVariable *VTable,
125106f32e7eSjoerg const VTableLayout &VTLayout) {
125206f32e7eSjoerg if (!getCodeGenOpts().LTOUnit)
125306f32e7eSjoerg return;
125406f32e7eSjoerg
125506f32e7eSjoerg CharUnits PointerWidth =
125606f32e7eSjoerg Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
125706f32e7eSjoerg
125806f32e7eSjoerg typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
125906f32e7eSjoerg std::vector<AddressPoint> AddressPoints;
126006f32e7eSjoerg for (auto &&AP : VTLayout.getAddressPoints())
126106f32e7eSjoerg AddressPoints.push_back(std::make_pair(
126206f32e7eSjoerg AP.first.getBase(), VTLayout.getVTableOffset(AP.second.VTableIndex) +
126306f32e7eSjoerg AP.second.AddressPointIndex));
126406f32e7eSjoerg
126506f32e7eSjoerg // Sort the address points for determinism.
126606f32e7eSjoerg llvm::sort(AddressPoints, [this](const AddressPoint &AP1,
126706f32e7eSjoerg const AddressPoint &AP2) {
126806f32e7eSjoerg if (&AP1 == &AP2)
126906f32e7eSjoerg return false;
127006f32e7eSjoerg
127106f32e7eSjoerg std::string S1;
127206f32e7eSjoerg llvm::raw_string_ostream O1(S1);
127306f32e7eSjoerg getCXXABI().getMangleContext().mangleTypeName(
127406f32e7eSjoerg QualType(AP1.first->getTypeForDecl(), 0), O1);
127506f32e7eSjoerg O1.flush();
127606f32e7eSjoerg
127706f32e7eSjoerg std::string S2;
127806f32e7eSjoerg llvm::raw_string_ostream O2(S2);
127906f32e7eSjoerg getCXXABI().getMangleContext().mangleTypeName(
128006f32e7eSjoerg QualType(AP2.first->getTypeForDecl(), 0), O2);
128106f32e7eSjoerg O2.flush();
128206f32e7eSjoerg
128306f32e7eSjoerg if (S1 < S2)
128406f32e7eSjoerg return true;
128506f32e7eSjoerg if (S1 != S2)
128606f32e7eSjoerg return false;
128706f32e7eSjoerg
128806f32e7eSjoerg return AP1.second < AP2.second;
128906f32e7eSjoerg });
129006f32e7eSjoerg
129106f32e7eSjoerg ArrayRef<VTableComponent> Comps = VTLayout.vtable_components();
129206f32e7eSjoerg for (auto AP : AddressPoints) {
129306f32e7eSjoerg // Create type metadata for the address point.
129406f32e7eSjoerg AddVTableTypeMetadata(VTable, PointerWidth * AP.second, AP.first);
129506f32e7eSjoerg
129606f32e7eSjoerg // The class associated with each address point could also potentially be
129706f32e7eSjoerg // used for indirect calls via a member function pointer, so we need to
129806f32e7eSjoerg // annotate the address of each function pointer with the appropriate member
129906f32e7eSjoerg // function pointer type.
130006f32e7eSjoerg for (unsigned I = 0; I != Comps.size(); ++I) {
130106f32e7eSjoerg if (Comps[I].getKind() != VTableComponent::CK_FunctionPointer)
130206f32e7eSjoerg continue;
130306f32e7eSjoerg llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
130406f32e7eSjoerg Context.getMemberPointerType(
130506f32e7eSjoerg Comps[I].getFunctionDecl()->getType(),
130606f32e7eSjoerg Context.getRecordType(AP.first).getTypePtr()));
130706f32e7eSjoerg VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD);
130806f32e7eSjoerg }
130906f32e7eSjoerg }
131006f32e7eSjoerg
1311*13fbcb42Sjoerg if (getCodeGenOpts().VirtualFunctionElimination ||
1312*13fbcb42Sjoerg getCodeGenOpts().WholeProgramVTables) {
1313*13fbcb42Sjoerg llvm::DenseSet<const CXXRecordDecl *> Visited;
1314*13fbcb42Sjoerg llvm::GlobalObject::VCallVisibility TypeVis =
1315*13fbcb42Sjoerg GetVCallVisibilityLevel(RD, Visited);
131606f32e7eSjoerg if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1317*13fbcb42Sjoerg VTable->setVCallVisibilityMetadata(TypeVis);
131806f32e7eSjoerg }
131906f32e7eSjoerg }
1320