17330f729Sjoerg //===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This contains code dealing with C++ code generation of virtual tables.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #include "CGCXXABI.h"
147330f729Sjoerg #include "CodeGenFunction.h"
157330f729Sjoerg #include "CodeGenModule.h"
16*e038c9c4Sjoerg #include "clang/AST/Attr.h"
177330f729Sjoerg #include "clang/AST/CXXInheritance.h"
187330f729Sjoerg #include "clang/AST/RecordLayout.h"
197330f729Sjoerg #include "clang/Basic/CodeGenOptions.h"
207330f729Sjoerg #include "clang/CodeGen/CGFunctionInfo.h"
217330f729Sjoerg #include "clang/CodeGen/ConstantInitBuilder.h"
227330f729Sjoerg #include "llvm/IR/IntrinsicInst.h"
237330f729Sjoerg #include "llvm/Support/Format.h"
247330f729Sjoerg #include "llvm/Transforms/Utils/Cloning.h"
257330f729Sjoerg #include <algorithm>
267330f729Sjoerg #include <cstdio>
277330f729Sjoerg
287330f729Sjoerg using namespace clang;
297330f729Sjoerg using namespace CodeGen;
307330f729Sjoerg
CodeGenVTables(CodeGenModule & CGM)317330f729Sjoerg CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
327330f729Sjoerg : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
337330f729Sjoerg
GetAddrOfThunk(StringRef Name,llvm::Type * FnTy,GlobalDecl GD)347330f729Sjoerg llvm::Constant *CodeGenModule::GetAddrOfThunk(StringRef Name, llvm::Type *FnTy,
357330f729Sjoerg GlobalDecl GD) {
367330f729Sjoerg return GetOrCreateLLVMFunction(Name, FnTy, GD, /*ForVTable=*/true,
377330f729Sjoerg /*DontDefer=*/true, /*IsThunk=*/true);
387330f729Sjoerg }
397330f729Sjoerg
setThunkProperties(CodeGenModule & CGM,const ThunkInfo & Thunk,llvm::Function * ThunkFn,bool ForVTable,GlobalDecl GD)407330f729Sjoerg static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
417330f729Sjoerg llvm::Function *ThunkFn, bool ForVTable,
427330f729Sjoerg GlobalDecl GD) {
437330f729Sjoerg CGM.setFunctionLinkage(GD, ThunkFn);
447330f729Sjoerg CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
457330f729Sjoerg !Thunk.Return.isEmpty());
467330f729Sjoerg
477330f729Sjoerg // Set the right visibility.
487330f729Sjoerg CGM.setGVProperties(ThunkFn, GD);
497330f729Sjoerg
507330f729Sjoerg if (!CGM.getCXXABI().exportThunk()) {
517330f729Sjoerg ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
527330f729Sjoerg ThunkFn->setDSOLocal(true);
537330f729Sjoerg }
547330f729Sjoerg
557330f729Sjoerg if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
567330f729Sjoerg ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
577330f729Sjoerg }
587330f729Sjoerg
597330f729Sjoerg #ifndef NDEBUG
similar(const ABIArgInfo & infoL,CanQualType typeL,const ABIArgInfo & infoR,CanQualType typeR)607330f729Sjoerg static bool similar(const ABIArgInfo &infoL, CanQualType typeL,
617330f729Sjoerg const ABIArgInfo &infoR, CanQualType typeR) {
627330f729Sjoerg return (infoL.getKind() == infoR.getKind() &&
637330f729Sjoerg (typeL == typeR ||
647330f729Sjoerg (isa<PointerType>(typeL) && isa<PointerType>(typeR)) ||
657330f729Sjoerg (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR))));
667330f729Sjoerg }
677330f729Sjoerg #endif
687330f729Sjoerg
PerformReturnAdjustment(CodeGenFunction & CGF,QualType ResultType,RValue RV,const ThunkInfo & Thunk)697330f729Sjoerg static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
707330f729Sjoerg QualType ResultType, RValue RV,
717330f729Sjoerg const ThunkInfo &Thunk) {
727330f729Sjoerg // Emit the return adjustment.
737330f729Sjoerg bool NullCheckValue = !ResultType->isReferenceType();
747330f729Sjoerg
757330f729Sjoerg llvm::BasicBlock *AdjustNull = nullptr;
767330f729Sjoerg llvm::BasicBlock *AdjustNotNull = nullptr;
777330f729Sjoerg llvm::BasicBlock *AdjustEnd = nullptr;
787330f729Sjoerg
797330f729Sjoerg llvm::Value *ReturnValue = RV.getScalarVal();
807330f729Sjoerg
817330f729Sjoerg if (NullCheckValue) {
827330f729Sjoerg AdjustNull = CGF.createBasicBlock("adjust.null");
837330f729Sjoerg AdjustNotNull = CGF.createBasicBlock("adjust.notnull");
847330f729Sjoerg AdjustEnd = CGF.createBasicBlock("adjust.end");
857330f729Sjoerg
867330f729Sjoerg llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue);
877330f729Sjoerg CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
887330f729Sjoerg CGF.EmitBlock(AdjustNotNull);
897330f729Sjoerg }
907330f729Sjoerg
917330f729Sjoerg auto ClassDecl = ResultType->getPointeeType()->getAsCXXRecordDecl();
927330f729Sjoerg auto ClassAlign = CGF.CGM.getClassPointerAlignment(ClassDecl);
937330f729Sjoerg ReturnValue = CGF.CGM.getCXXABI().performReturnAdjustment(CGF,
947330f729Sjoerg Address(ReturnValue, ClassAlign),
957330f729Sjoerg Thunk.Return);
967330f729Sjoerg
977330f729Sjoerg if (NullCheckValue) {
987330f729Sjoerg CGF.Builder.CreateBr(AdjustEnd);
997330f729Sjoerg CGF.EmitBlock(AdjustNull);
1007330f729Sjoerg CGF.Builder.CreateBr(AdjustEnd);
1017330f729Sjoerg CGF.EmitBlock(AdjustEnd);
1027330f729Sjoerg
1037330f729Sjoerg llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2);
1047330f729Sjoerg PHI->addIncoming(ReturnValue, AdjustNotNull);
1057330f729Sjoerg PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
1067330f729Sjoerg AdjustNull);
1077330f729Sjoerg ReturnValue = PHI;
1087330f729Sjoerg }
1097330f729Sjoerg
1107330f729Sjoerg return RValue::get(ReturnValue);
1117330f729Sjoerg }
1127330f729Sjoerg
1137330f729Sjoerg /// This function clones a function's DISubprogram node and enters it into
1147330f729Sjoerg /// a value map with the intent that the map can be utilized by the cloner
1157330f729Sjoerg /// to short-circuit Metadata node mapping.
1167330f729Sjoerg /// Furthermore, the function resolves any DILocalVariable nodes referenced
1177330f729Sjoerg /// by dbg.value intrinsics so they can be properly mapped during cloning.
resolveTopLevelMetadata(llvm::Function * Fn,llvm::ValueToValueMapTy & VMap)1187330f729Sjoerg static void resolveTopLevelMetadata(llvm::Function *Fn,
1197330f729Sjoerg llvm::ValueToValueMapTy &VMap) {
1207330f729Sjoerg // Clone the DISubprogram node and put it into the Value map.
1217330f729Sjoerg auto *DIS = Fn->getSubprogram();
1227330f729Sjoerg if (!DIS)
1237330f729Sjoerg return;
1247330f729Sjoerg auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
1257330f729Sjoerg VMap.MD()[DIS].reset(NewDIS);
1267330f729Sjoerg
1277330f729Sjoerg // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes
1287330f729Sjoerg // they are referencing.
1297330f729Sjoerg for (auto &BB : Fn->getBasicBlockList()) {
1307330f729Sjoerg for (auto &I : BB) {
1317330f729Sjoerg if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
1327330f729Sjoerg auto *DILocal = DII->getVariable();
1337330f729Sjoerg if (!DILocal->isResolved())
1347330f729Sjoerg DILocal->resolve();
1357330f729Sjoerg }
1367330f729Sjoerg }
1377330f729Sjoerg }
1387330f729Sjoerg }
1397330f729Sjoerg
1407330f729Sjoerg // This function does roughly the same thing as GenerateThunk, but in a
1417330f729Sjoerg // very different way, so that va_start and va_end work correctly.
1427330f729Sjoerg // FIXME: This function assumes "this" is the first non-sret LLVM argument of
1437330f729Sjoerg // a function, and that there is an alloca built in the entry block
1447330f729Sjoerg // for all accesses to "this".
1457330f729Sjoerg // FIXME: This function assumes there is only one "ret" statement per function.
1467330f729Sjoerg // FIXME: Cloning isn't correct in the presence of indirect goto!
1477330f729Sjoerg // FIXME: This implementation of thunks bloats codesize by duplicating the
1487330f729Sjoerg // function definition. There are alternatives:
1497330f729Sjoerg // 1. Add some sort of stub support to LLVM for cases where we can
1507330f729Sjoerg // do a this adjustment, then a sibcall.
1517330f729Sjoerg // 2. We could transform the definition to take a va_list instead of an
1527330f729Sjoerg // actual variable argument list, then have the thunks (including a
1537330f729Sjoerg // no-op thunk for the regular definition) call va_start/va_end.
1547330f729Sjoerg // There's a bit of per-call overhead for this solution, but it's
1557330f729Sjoerg // better for codesize if the definition is long.
1567330f729Sjoerg llvm::Function *
GenerateVarArgsThunk(llvm::Function * Fn,const CGFunctionInfo & FnInfo,GlobalDecl GD,const ThunkInfo & Thunk)1577330f729Sjoerg CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn,
1587330f729Sjoerg const CGFunctionInfo &FnInfo,
1597330f729Sjoerg GlobalDecl GD, const ThunkInfo &Thunk) {
1607330f729Sjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
1617330f729Sjoerg const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
1627330f729Sjoerg QualType ResultType = FPT->getReturnType();
1637330f729Sjoerg
1647330f729Sjoerg // Get the original function
1657330f729Sjoerg assert(FnInfo.isVariadic());
1667330f729Sjoerg llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo);
1677330f729Sjoerg llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
1687330f729Sjoerg llvm::Function *BaseFn = cast<llvm::Function>(Callee);
1697330f729Sjoerg
1707330f729Sjoerg // Cloning can't work if we don't have a definition. The Microsoft ABI may
1717330f729Sjoerg // require thunks when a definition is not available. Emit an error in these
1727330f729Sjoerg // cases.
1737330f729Sjoerg if (!MD->isDefined()) {
1747330f729Sjoerg CGM.ErrorUnsupported(MD, "return-adjusting thunk with variadic arguments");
1757330f729Sjoerg return Fn;
1767330f729Sjoerg }
1777330f729Sjoerg assert(!BaseFn->isDeclaration() && "cannot clone undefined variadic method");
1787330f729Sjoerg
1797330f729Sjoerg // Clone to thunk.
1807330f729Sjoerg llvm::ValueToValueMapTy VMap;
1817330f729Sjoerg
1827330f729Sjoerg // We are cloning a function while some Metadata nodes are still unresolved.
1837330f729Sjoerg // Ensure that the value mapper does not encounter any of them.
1847330f729Sjoerg resolveTopLevelMetadata(BaseFn, VMap);
1857330f729Sjoerg llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);
1867330f729Sjoerg Fn->replaceAllUsesWith(NewFn);
1877330f729Sjoerg NewFn->takeName(Fn);
1887330f729Sjoerg Fn->eraseFromParent();
1897330f729Sjoerg Fn = NewFn;
1907330f729Sjoerg
1917330f729Sjoerg // "Initialize" CGF (minimally).
1927330f729Sjoerg CurFn = Fn;
1937330f729Sjoerg
1947330f729Sjoerg // Get the "this" value
1957330f729Sjoerg llvm::Function::arg_iterator AI = Fn->arg_begin();
1967330f729Sjoerg if (CGM.ReturnTypeUsesSRet(FnInfo))
1977330f729Sjoerg ++AI;
1987330f729Sjoerg
1997330f729Sjoerg // Find the first store of "this", which will be to the alloca associated
2007330f729Sjoerg // with "this".
2017330f729Sjoerg Address ThisPtr(&*AI, CGM.getClassPointerAlignment(MD->getParent()));
2027330f729Sjoerg llvm::BasicBlock *EntryBB = &Fn->front();
2037330f729Sjoerg llvm::BasicBlock::iterator ThisStore =
2047330f729Sjoerg std::find_if(EntryBB->begin(), EntryBB->end(), [&](llvm::Instruction &I) {
2057330f729Sjoerg return isa<llvm::StoreInst>(I) &&
2067330f729Sjoerg I.getOperand(0) == ThisPtr.getPointer();
2077330f729Sjoerg });
2087330f729Sjoerg assert(ThisStore != EntryBB->end() &&
2097330f729Sjoerg "Store of this should be in entry block?");
2107330f729Sjoerg // Adjust "this", if necessary.
2117330f729Sjoerg Builder.SetInsertPoint(&*ThisStore);
2127330f729Sjoerg llvm::Value *AdjustedThisPtr =
2137330f729Sjoerg CGM.getCXXABI().performThisAdjustment(*this, ThisPtr, Thunk.This);
2147330f729Sjoerg AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,
2157330f729Sjoerg ThisStore->getOperand(0)->getType());
2167330f729Sjoerg ThisStore->setOperand(0, AdjustedThisPtr);
2177330f729Sjoerg
2187330f729Sjoerg if (!Thunk.Return.isEmpty()) {
2197330f729Sjoerg // Fix up the returned value, if necessary.
2207330f729Sjoerg for (llvm::BasicBlock &BB : *Fn) {
2217330f729Sjoerg llvm::Instruction *T = BB.getTerminator();
2227330f729Sjoerg if (isa<llvm::ReturnInst>(T)) {
2237330f729Sjoerg RValue RV = RValue::get(T->getOperand(0));
2247330f729Sjoerg T->eraseFromParent();
2257330f729Sjoerg Builder.SetInsertPoint(&BB);
2267330f729Sjoerg RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk);
2277330f729Sjoerg Builder.CreateRet(RV.getScalarVal());
2287330f729Sjoerg break;
2297330f729Sjoerg }
2307330f729Sjoerg }
2317330f729Sjoerg }
2327330f729Sjoerg
2337330f729Sjoerg return Fn;
2347330f729Sjoerg }
2357330f729Sjoerg
StartThunk(llvm::Function * Fn,GlobalDecl GD,const CGFunctionInfo & FnInfo,bool IsUnprototyped)2367330f729Sjoerg void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
2377330f729Sjoerg const CGFunctionInfo &FnInfo,
2387330f729Sjoerg bool IsUnprototyped) {
2397330f729Sjoerg assert(!CurGD.getDecl() && "CurGD was already set!");
2407330f729Sjoerg CurGD = GD;
2417330f729Sjoerg CurFuncIsThunk = true;
2427330f729Sjoerg
2437330f729Sjoerg // Build FunctionArgs.
2447330f729Sjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
2457330f729Sjoerg QualType ThisType = MD->getThisType();
2467330f729Sjoerg QualType ResultType;
2477330f729Sjoerg if (IsUnprototyped)
2487330f729Sjoerg ResultType = CGM.getContext().VoidTy;
2497330f729Sjoerg else if (CGM.getCXXABI().HasThisReturn(GD))
2507330f729Sjoerg ResultType = ThisType;
2517330f729Sjoerg else if (CGM.getCXXABI().hasMostDerivedReturn(GD))
2527330f729Sjoerg ResultType = CGM.getContext().VoidPtrTy;
2537330f729Sjoerg else
2547330f729Sjoerg ResultType = MD->getType()->castAs<FunctionProtoType>()->getReturnType();
2557330f729Sjoerg FunctionArgList FunctionArgs;
2567330f729Sjoerg
2577330f729Sjoerg // Create the implicit 'this' parameter declaration.
2587330f729Sjoerg CGM.getCXXABI().buildThisParam(*this, FunctionArgs);
2597330f729Sjoerg
2607330f729Sjoerg // Add the rest of the parameters, if we have a prototype to work with.
2617330f729Sjoerg if (!IsUnprototyped) {
2627330f729Sjoerg FunctionArgs.append(MD->param_begin(), MD->param_end());
2637330f729Sjoerg
2647330f729Sjoerg if (isa<CXXDestructorDecl>(MD))
2657330f729Sjoerg CGM.getCXXABI().addImplicitStructorParams(*this, ResultType,
2667330f729Sjoerg FunctionArgs);
2677330f729Sjoerg }
2687330f729Sjoerg
2697330f729Sjoerg // Start defining the function.
2707330f729Sjoerg auto NL = ApplyDebugLocation::CreateEmpty(*this);
2717330f729Sjoerg StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
2727330f729Sjoerg MD->getLocation());
2737330f729Sjoerg // Create a scope with an artificial location for the body of this function.
2747330f729Sjoerg auto AL = ApplyDebugLocation::CreateArtificial(*this);
2757330f729Sjoerg
2767330f729Sjoerg // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves.
2777330f729Sjoerg CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
2787330f729Sjoerg CXXThisValue = CXXABIThisValue;
2797330f729Sjoerg CurCodeDecl = MD;
2807330f729Sjoerg CurFuncDecl = MD;
2817330f729Sjoerg }
2827330f729Sjoerg
FinishThunk()2837330f729Sjoerg void CodeGenFunction::FinishThunk() {
2847330f729Sjoerg // Clear these to restore the invariants expected by
2857330f729Sjoerg // StartFunction/FinishFunction.
2867330f729Sjoerg CurCodeDecl = nullptr;
2877330f729Sjoerg CurFuncDecl = nullptr;
2887330f729Sjoerg
2897330f729Sjoerg FinishFunction();
2907330f729Sjoerg }
2917330f729Sjoerg
EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,const ThunkInfo * Thunk,bool IsUnprototyped)2927330f729Sjoerg void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
2937330f729Sjoerg const ThunkInfo *Thunk,
2947330f729Sjoerg bool IsUnprototyped) {
2957330f729Sjoerg assert(isa<CXXMethodDecl>(CurGD.getDecl()) &&
2967330f729Sjoerg "Please use a new CGF for this thunk");
2977330f729Sjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl());
2987330f729Sjoerg
2997330f729Sjoerg // Adjust the 'this' pointer if necessary
3007330f729Sjoerg llvm::Value *AdjustedThisPtr =
3017330f729Sjoerg Thunk ? CGM.getCXXABI().performThisAdjustment(
3027330f729Sjoerg *this, LoadCXXThisAddress(), Thunk->This)
3037330f729Sjoerg : LoadCXXThis();
3047330f729Sjoerg
3057330f729Sjoerg // If perfect forwarding is required a variadic method, a method using
3067330f729Sjoerg // inalloca, or an unprototyped thunk, use musttail. Emit an error if this
3077330f729Sjoerg // thunk requires a return adjustment, since that is impossible with musttail.
3087330f729Sjoerg if (CurFnInfo->usesInAlloca() || CurFnInfo->isVariadic() || IsUnprototyped) {
3097330f729Sjoerg if (Thunk && !Thunk->Return.isEmpty()) {
3107330f729Sjoerg if (IsUnprototyped)
3117330f729Sjoerg CGM.ErrorUnsupported(
3127330f729Sjoerg MD, "return-adjusting thunk with incomplete parameter type");
3137330f729Sjoerg else if (CurFnInfo->isVariadic())
3147330f729Sjoerg llvm_unreachable("shouldn't try to emit musttail return-adjusting "
3157330f729Sjoerg "thunks for variadic functions");
3167330f729Sjoerg else
3177330f729Sjoerg CGM.ErrorUnsupported(
3187330f729Sjoerg MD, "non-trivial argument copy for return-adjusting thunk");
3197330f729Sjoerg }
3207330f729Sjoerg EmitMustTailThunk(CurGD, AdjustedThisPtr, Callee);
3217330f729Sjoerg return;
3227330f729Sjoerg }
3237330f729Sjoerg
3247330f729Sjoerg // Start building CallArgs.
3257330f729Sjoerg CallArgList CallArgs;
3267330f729Sjoerg QualType ThisType = MD->getThisType();
3277330f729Sjoerg CallArgs.add(RValue::get(AdjustedThisPtr), ThisType);
3287330f729Sjoerg
3297330f729Sjoerg if (isa<CXXDestructorDecl>(MD))
3307330f729Sjoerg CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, CurGD, CallArgs);
3317330f729Sjoerg
3327330f729Sjoerg #ifndef NDEBUG
3337330f729Sjoerg unsigned PrefixArgs = CallArgs.size() - 1;
3347330f729Sjoerg #endif
3357330f729Sjoerg // Add the rest of the arguments.
3367330f729Sjoerg for (const ParmVarDecl *PD : MD->parameters())
3377330f729Sjoerg EmitDelegateCallArg(CallArgs, PD, SourceLocation());
3387330f729Sjoerg
339*e038c9c4Sjoerg const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
3407330f729Sjoerg
3417330f729Sjoerg #ifndef NDEBUG
3427330f729Sjoerg const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(
3437330f729Sjoerg CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1), PrefixArgs);
3447330f729Sjoerg assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
3457330f729Sjoerg CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
3467330f729Sjoerg CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());
3477330f729Sjoerg assert(isa<CXXDestructorDecl>(MD) || // ignore dtor return types
3487330f729Sjoerg similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
3497330f729Sjoerg CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType()));
3507330f729Sjoerg assert(CallFnInfo.arg_size() == CurFnInfo->arg_size());
3517330f729Sjoerg for (unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i)
3527330f729Sjoerg assert(similar(CallFnInfo.arg_begin()[i].info,
3537330f729Sjoerg CallFnInfo.arg_begin()[i].type,
3547330f729Sjoerg CurFnInfo->arg_begin()[i].info,
3557330f729Sjoerg CurFnInfo->arg_begin()[i].type));
3567330f729Sjoerg #endif
3577330f729Sjoerg
3587330f729Sjoerg // Determine whether we have a return value slot to use.
3597330f729Sjoerg QualType ResultType = CGM.getCXXABI().HasThisReturn(CurGD)
3607330f729Sjoerg ? ThisType
3617330f729Sjoerg : CGM.getCXXABI().hasMostDerivedReturn(CurGD)
3627330f729Sjoerg ? CGM.getContext().VoidPtrTy
3637330f729Sjoerg : FPT->getReturnType();
3647330f729Sjoerg ReturnValueSlot Slot;
3657330f729Sjoerg if (!ResultType->isVoidType() &&
366*e038c9c4Sjoerg (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect ||
367*e038c9c4Sjoerg hasAggregateEvaluationKind(ResultType)))
368*e038c9c4Sjoerg Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified(),
369*e038c9c4Sjoerg /*IsUnused=*/false, /*IsExternallyDestructed=*/true);
3707330f729Sjoerg
3717330f729Sjoerg // Now emit our call.
3727330f729Sjoerg llvm::CallBase *CallOrInvoke;
3737330f729Sjoerg RValue RV = EmitCall(*CurFnInfo, CGCallee::forDirect(Callee, CurGD), Slot,
3747330f729Sjoerg CallArgs, &CallOrInvoke);
3757330f729Sjoerg
3767330f729Sjoerg // Consider return adjustment if we have ThunkInfo.
3777330f729Sjoerg if (Thunk && !Thunk->Return.isEmpty())
3787330f729Sjoerg RV = PerformReturnAdjustment(*this, ResultType, RV, *Thunk);
3797330f729Sjoerg else if (llvm::CallInst* Call = dyn_cast<llvm::CallInst>(CallOrInvoke))
3807330f729Sjoerg Call->setTailCallKind(llvm::CallInst::TCK_Tail);
3817330f729Sjoerg
3827330f729Sjoerg // Emit return.
3837330f729Sjoerg if (!ResultType->isVoidType() && Slot.isNull())
3847330f729Sjoerg CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType);
3857330f729Sjoerg
3867330f729Sjoerg // Disable the final ARC autorelease.
3877330f729Sjoerg AutoreleaseResult = false;
3887330f729Sjoerg
3897330f729Sjoerg FinishThunk();
3907330f729Sjoerg }
3917330f729Sjoerg
EmitMustTailThunk(GlobalDecl GD,llvm::Value * AdjustedThisPtr,llvm::FunctionCallee Callee)3927330f729Sjoerg void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
3937330f729Sjoerg llvm::Value *AdjustedThisPtr,
3947330f729Sjoerg llvm::FunctionCallee Callee) {
3957330f729Sjoerg // Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery
3967330f729Sjoerg // to translate AST arguments into LLVM IR arguments. For thunks, we know
3977330f729Sjoerg // that the caller prototype more or less matches the callee prototype with
3987330f729Sjoerg // the exception of 'this'.
3997330f729Sjoerg SmallVector<llvm::Value *, 8> Args;
4007330f729Sjoerg for (llvm::Argument &A : CurFn->args())
4017330f729Sjoerg Args.push_back(&A);
4027330f729Sjoerg
4037330f729Sjoerg // Set the adjusted 'this' pointer.
4047330f729Sjoerg const ABIArgInfo &ThisAI = CurFnInfo->arg_begin()->info;
4057330f729Sjoerg if (ThisAI.isDirect()) {
4067330f729Sjoerg const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo();
4077330f729Sjoerg int ThisArgNo = RetAI.isIndirect() && !RetAI.isSRetAfterThis() ? 1 : 0;
4087330f729Sjoerg llvm::Type *ThisType = Args[ThisArgNo]->getType();
4097330f729Sjoerg if (ThisType != AdjustedThisPtr->getType())
4107330f729Sjoerg AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
4117330f729Sjoerg Args[ThisArgNo] = AdjustedThisPtr;
4127330f729Sjoerg } else {
4137330f729Sjoerg assert(ThisAI.isInAlloca() && "this is passed directly or inalloca");
4147330f729Sjoerg Address ThisAddr = GetAddrOfLocalVar(CXXABIThisDecl);
4157330f729Sjoerg llvm::Type *ThisType = ThisAddr.getElementType();
4167330f729Sjoerg if (ThisType != AdjustedThisPtr->getType())
4177330f729Sjoerg AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
4187330f729Sjoerg Builder.CreateStore(AdjustedThisPtr, ThisAddr);
4197330f729Sjoerg }
4207330f729Sjoerg
4217330f729Sjoerg // Emit the musttail call manually. Even if the prologue pushed cleanups, we
4227330f729Sjoerg // don't actually want to run them.
4237330f729Sjoerg llvm::CallInst *Call = Builder.CreateCall(Callee, Args);
4247330f729Sjoerg Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4257330f729Sjoerg
4267330f729Sjoerg // Apply the standard set of call attributes.
4277330f729Sjoerg unsigned CallingConv;
4287330f729Sjoerg llvm::AttributeList Attrs;
4297330f729Sjoerg CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD,
430*e038c9c4Sjoerg Attrs, CallingConv, /*AttrOnCallSite=*/true,
431*e038c9c4Sjoerg /*IsThunk=*/false);
4327330f729Sjoerg Call->setAttributes(Attrs);
4337330f729Sjoerg Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
4347330f729Sjoerg
4357330f729Sjoerg if (Call->getType()->isVoidTy())
4367330f729Sjoerg Builder.CreateRetVoid();
4377330f729Sjoerg else
4387330f729Sjoerg Builder.CreateRet(Call);
4397330f729Sjoerg
4407330f729Sjoerg // Finish the function to maintain CodeGenFunction invariants.
4417330f729Sjoerg // FIXME: Don't emit unreachable code.
4427330f729Sjoerg EmitBlock(createBasicBlock());
443*e038c9c4Sjoerg
444*e038c9c4Sjoerg FinishThunk();
4457330f729Sjoerg }
4467330f729Sjoerg
generateThunk(llvm::Function * Fn,const CGFunctionInfo & FnInfo,GlobalDecl GD,const ThunkInfo & Thunk,bool IsUnprototyped)4477330f729Sjoerg void CodeGenFunction::generateThunk(llvm::Function *Fn,
4487330f729Sjoerg const CGFunctionInfo &FnInfo, GlobalDecl GD,
4497330f729Sjoerg const ThunkInfo &Thunk,
4507330f729Sjoerg bool IsUnprototyped) {
4517330f729Sjoerg StartThunk(Fn, GD, FnInfo, IsUnprototyped);
4527330f729Sjoerg // Create a scope with an artificial location for the body of this function.
4537330f729Sjoerg auto AL = ApplyDebugLocation::CreateArtificial(*this);
4547330f729Sjoerg
4557330f729Sjoerg // Get our callee. Use a placeholder type if this method is unprototyped so
4567330f729Sjoerg // that CodeGenModule doesn't try to set attributes.
4577330f729Sjoerg llvm::Type *Ty;
4587330f729Sjoerg if (IsUnprototyped)
4597330f729Sjoerg Ty = llvm::StructType::get(getLLVMContext());
4607330f729Sjoerg else
4617330f729Sjoerg Ty = CGM.getTypes().GetFunctionType(FnInfo);
4627330f729Sjoerg
4637330f729Sjoerg llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
4647330f729Sjoerg
4657330f729Sjoerg // Fix up the function type for an unprototyped musttail call.
4667330f729Sjoerg if (IsUnprototyped)
4677330f729Sjoerg Callee = llvm::ConstantExpr::getBitCast(Callee, Fn->getType());
4687330f729Sjoerg
4697330f729Sjoerg // Make the call and return the result.
4707330f729Sjoerg EmitCallAndReturnForThunk(llvm::FunctionCallee(Fn->getFunctionType(), Callee),
4717330f729Sjoerg &Thunk, IsUnprototyped);
4727330f729Sjoerg }
4737330f729Sjoerg
shouldEmitVTableThunk(CodeGenModule & CGM,const CXXMethodDecl * MD,bool IsUnprototyped,bool ForVTable)4747330f729Sjoerg static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD,
4757330f729Sjoerg bool IsUnprototyped, bool ForVTable) {
4767330f729Sjoerg // Always emit thunks in the MS C++ ABI. We cannot rely on other TUs to
4777330f729Sjoerg // provide thunks for us.
4787330f729Sjoerg if (CGM.getTarget().getCXXABI().isMicrosoft())
4797330f729Sjoerg return true;
4807330f729Sjoerg
4817330f729Sjoerg // In the Itanium C++ ABI, vtable thunks are provided by TUs that provide
4827330f729Sjoerg // definitions of the main method. Therefore, emitting thunks with the vtable
4837330f729Sjoerg // is purely an optimization. Emit the thunk if optimizations are enabled and
4847330f729Sjoerg // all of the parameter types are complete.
4857330f729Sjoerg if (ForVTable)
4867330f729Sjoerg return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped;
4877330f729Sjoerg
4887330f729Sjoerg // Always emit thunks along with the method definition.
4897330f729Sjoerg return true;
4907330f729Sjoerg }
4917330f729Sjoerg
maybeEmitThunk(GlobalDecl GD,const ThunkInfo & TI,bool ForVTable)4927330f729Sjoerg llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
4937330f729Sjoerg const ThunkInfo &TI,
4947330f729Sjoerg bool ForVTable) {
4957330f729Sjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
4967330f729Sjoerg
4977330f729Sjoerg // First, get a declaration. Compute the mangled name. Don't worry about
4987330f729Sjoerg // getting the function prototype right, since we may only need this
4997330f729Sjoerg // declaration to fill in a vtable slot.
5007330f729Sjoerg SmallString<256> Name;
5017330f729Sjoerg MangleContext &MCtx = CGM.getCXXABI().getMangleContext();
5027330f729Sjoerg llvm::raw_svector_ostream Out(Name);
5037330f729Sjoerg if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
5047330f729Sjoerg MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI.This, Out);
5057330f729Sjoerg else
5067330f729Sjoerg MCtx.mangleThunk(MD, TI, Out);
5077330f729Sjoerg llvm::Type *ThunkVTableTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
5087330f729Sjoerg llvm::Constant *Thunk = CGM.GetAddrOfThunk(Name, ThunkVTableTy, GD);
5097330f729Sjoerg
5107330f729Sjoerg // If we don't need to emit a definition, return this declaration as is.
5117330f729Sjoerg bool IsUnprototyped = !CGM.getTypes().isFuncTypeConvertible(
5127330f729Sjoerg MD->getType()->castAs<FunctionType>());
5137330f729Sjoerg if (!shouldEmitVTableThunk(CGM, MD, IsUnprototyped, ForVTable))
5147330f729Sjoerg return Thunk;
5157330f729Sjoerg
5167330f729Sjoerg // Arrange a function prototype appropriate for a function definition. In some
5177330f729Sjoerg // cases in the MS ABI, we may need to build an unprototyped musttail thunk.
5187330f729Sjoerg const CGFunctionInfo &FnInfo =
5197330f729Sjoerg IsUnprototyped ? CGM.getTypes().arrangeUnprototypedMustTailThunk(MD)
5207330f729Sjoerg : CGM.getTypes().arrangeGlobalDeclaration(GD);
5217330f729Sjoerg llvm::FunctionType *ThunkFnTy = CGM.getTypes().GetFunctionType(FnInfo);
5227330f729Sjoerg
5237330f729Sjoerg // If the type of the underlying GlobalValue is wrong, we'll have to replace
5247330f729Sjoerg // it. It should be a declaration.
5257330f729Sjoerg llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts());
5267330f729Sjoerg if (ThunkFn->getFunctionType() != ThunkFnTy) {
5277330f729Sjoerg llvm::GlobalValue *OldThunkFn = ThunkFn;
5287330f729Sjoerg
5297330f729Sjoerg assert(OldThunkFn->isDeclaration() && "Shouldn't replace non-declaration");
5307330f729Sjoerg
5317330f729Sjoerg // Remove the name from the old thunk function and get a new thunk.
5327330f729Sjoerg OldThunkFn->setName(StringRef());
5337330f729Sjoerg ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,
5347330f729Sjoerg Name.str(), &CGM.getModule());
535*e038c9c4Sjoerg CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false);
5367330f729Sjoerg
5377330f729Sjoerg // If needed, replace the old thunk with a bitcast.
5387330f729Sjoerg if (!OldThunkFn->use_empty()) {
5397330f729Sjoerg llvm::Constant *NewPtrForOldDecl =
5407330f729Sjoerg llvm::ConstantExpr::getBitCast(ThunkFn, OldThunkFn->getType());
5417330f729Sjoerg OldThunkFn->replaceAllUsesWith(NewPtrForOldDecl);
5427330f729Sjoerg }
5437330f729Sjoerg
5447330f729Sjoerg // Remove the old thunk.
5457330f729Sjoerg OldThunkFn->eraseFromParent();
5467330f729Sjoerg }
5477330f729Sjoerg
5487330f729Sjoerg bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();
5497330f729Sjoerg bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
5507330f729Sjoerg
5517330f729Sjoerg if (!ThunkFn->isDeclaration()) {
5527330f729Sjoerg if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
5537330f729Sjoerg // There is already a thunk emitted for this function, do nothing.
5547330f729Sjoerg return ThunkFn;
5557330f729Sjoerg }
5567330f729Sjoerg
5577330f729Sjoerg setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
5587330f729Sjoerg return ThunkFn;
5597330f729Sjoerg }
5607330f729Sjoerg
5617330f729Sjoerg // If this will be unprototyped, add the "thunk" attribute so that LLVM knows
5627330f729Sjoerg // that the return type is meaningless. These thunks can be used to call
5637330f729Sjoerg // functions with differing return types, and the caller is required to cast
5647330f729Sjoerg // the prototype appropriately to extract the correct value.
5657330f729Sjoerg if (IsUnprototyped)
5667330f729Sjoerg ThunkFn->addFnAttr("thunk");
5677330f729Sjoerg
5687330f729Sjoerg CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);
5697330f729Sjoerg
5707330f729Sjoerg // Thunks for variadic methods are special because in general variadic
571*e038c9c4Sjoerg // arguments cannot be perfectly forwarded. In the general case, clang
5727330f729Sjoerg // implements such thunks by cloning the original function body. However, for
5737330f729Sjoerg // thunks with no return adjustment on targets that support musttail, we can
5747330f729Sjoerg // use musttail to perfectly forward the variadic arguments.
5757330f729Sjoerg bool ShouldCloneVarArgs = false;
5767330f729Sjoerg if (!IsUnprototyped && ThunkFn->isVarArg()) {
5777330f729Sjoerg ShouldCloneVarArgs = true;
5787330f729Sjoerg if (TI.Return.isEmpty()) {
5797330f729Sjoerg switch (CGM.getTriple().getArch()) {
5807330f729Sjoerg case llvm::Triple::x86_64:
5817330f729Sjoerg case llvm::Triple::x86:
5827330f729Sjoerg case llvm::Triple::aarch64:
5837330f729Sjoerg ShouldCloneVarArgs = false;
5847330f729Sjoerg break;
5857330f729Sjoerg default:
5867330f729Sjoerg break;
5877330f729Sjoerg }
5887330f729Sjoerg }
5897330f729Sjoerg }
5907330f729Sjoerg
5917330f729Sjoerg if (ShouldCloneVarArgs) {
5927330f729Sjoerg if (UseAvailableExternallyLinkage)
5937330f729Sjoerg return ThunkFn;
5947330f729Sjoerg ThunkFn =
5957330f729Sjoerg CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, TI);
5967330f729Sjoerg } else {
5977330f729Sjoerg // Normal thunk body generation.
5987330f729Sjoerg CodeGenFunction(CGM).generateThunk(ThunkFn, FnInfo, GD, TI, IsUnprototyped);
5997330f729Sjoerg }
6007330f729Sjoerg
6017330f729Sjoerg setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
6027330f729Sjoerg return ThunkFn;
6037330f729Sjoerg }
6047330f729Sjoerg
EmitThunks(GlobalDecl GD)6057330f729Sjoerg void CodeGenVTables::EmitThunks(GlobalDecl GD) {
6067330f729Sjoerg const CXXMethodDecl *MD =
6077330f729Sjoerg cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
6087330f729Sjoerg
6097330f729Sjoerg // We don't need to generate thunks for the base destructor.
6107330f729Sjoerg if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
6117330f729Sjoerg return;
6127330f729Sjoerg
6137330f729Sjoerg const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector =
6147330f729Sjoerg VTContext->getThunkInfo(GD);
6157330f729Sjoerg
6167330f729Sjoerg if (!ThunkInfoVector)
6177330f729Sjoerg return;
6187330f729Sjoerg
6197330f729Sjoerg for (const ThunkInfo& Thunk : *ThunkInfoVector)
6207330f729Sjoerg maybeEmitThunk(GD, Thunk, /*ForVTable=*/false);
6217330f729Sjoerg }
6227330f729Sjoerg
addRelativeComponent(ConstantArrayBuilder & builder,llvm::Constant * component,unsigned vtableAddressPoint,bool vtableHasLocalLinkage,bool isCompleteDtor) const623*e038c9c4Sjoerg void CodeGenVTables::addRelativeComponent(ConstantArrayBuilder &builder,
624*e038c9c4Sjoerg llvm::Constant *component,
625*e038c9c4Sjoerg unsigned vtableAddressPoint,
626*e038c9c4Sjoerg bool vtableHasLocalLinkage,
627*e038c9c4Sjoerg bool isCompleteDtor) const {
628*e038c9c4Sjoerg // No need to get the offset of a nullptr.
629*e038c9c4Sjoerg if (component->isNullValue())
630*e038c9c4Sjoerg return builder.add(llvm::ConstantInt::get(CGM.Int32Ty, 0));
6317330f729Sjoerg
632*e038c9c4Sjoerg auto *globalVal =
633*e038c9c4Sjoerg cast<llvm::GlobalValue>(component->stripPointerCastsAndAliases());
634*e038c9c4Sjoerg llvm::Module &module = CGM.getModule();
635*e038c9c4Sjoerg
636*e038c9c4Sjoerg // We don't want to copy the linkage of the vtable exactly because we still
637*e038c9c4Sjoerg // want the stub/proxy to be emitted for properly calculating the offset.
638*e038c9c4Sjoerg // Examples where there would be no symbol emitted are available_externally
639*e038c9c4Sjoerg // and private linkages.
640*e038c9c4Sjoerg auto stubLinkage = vtableHasLocalLinkage ? llvm::GlobalValue::InternalLinkage
641*e038c9c4Sjoerg : llvm::GlobalValue::ExternalLinkage;
642*e038c9c4Sjoerg
643*e038c9c4Sjoerg llvm::Constant *target;
644*e038c9c4Sjoerg if (auto *func = dyn_cast<llvm::Function>(globalVal)) {
645*e038c9c4Sjoerg target = llvm::DSOLocalEquivalent::get(func);
646*e038c9c4Sjoerg } else {
647*e038c9c4Sjoerg llvm::SmallString<16> rttiProxyName(globalVal->getName());
648*e038c9c4Sjoerg rttiProxyName.append(".rtti_proxy");
649*e038c9c4Sjoerg
650*e038c9c4Sjoerg // The RTTI component may not always be emitted in the same linkage unit as
651*e038c9c4Sjoerg // the vtable. As a general case, we can make a dso_local proxy to the RTTI
652*e038c9c4Sjoerg // that points to the actual RTTI struct somewhere. This will result in a
653*e038c9c4Sjoerg // GOTPCREL relocation when taking the relative offset to the proxy.
654*e038c9c4Sjoerg llvm::GlobalVariable *proxy = module.getNamedGlobal(rttiProxyName);
655*e038c9c4Sjoerg if (!proxy) {
656*e038c9c4Sjoerg proxy = new llvm::GlobalVariable(module, globalVal->getType(),
657*e038c9c4Sjoerg /*isConstant=*/true, stubLinkage,
658*e038c9c4Sjoerg globalVal, rttiProxyName);
659*e038c9c4Sjoerg proxy->setDSOLocal(true);
660*e038c9c4Sjoerg proxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
661*e038c9c4Sjoerg if (!proxy->hasLocalLinkage()) {
662*e038c9c4Sjoerg proxy->setVisibility(llvm::GlobalValue::HiddenVisibility);
663*e038c9c4Sjoerg proxy->setComdat(module.getOrInsertComdat(rttiProxyName));
664*e038c9c4Sjoerg }
665*e038c9c4Sjoerg }
666*e038c9c4Sjoerg target = proxy;
667*e038c9c4Sjoerg }
668*e038c9c4Sjoerg
669*e038c9c4Sjoerg builder.addRelativeOffsetToPosition(CGM.Int32Ty, target,
670*e038c9c4Sjoerg /*position=*/vtableAddressPoint);
671*e038c9c4Sjoerg }
672*e038c9c4Sjoerg
useRelativeLayout() const673*e038c9c4Sjoerg bool CodeGenVTables::useRelativeLayout() const {
674*e038c9c4Sjoerg return CGM.getTarget().getCXXABI().isItaniumFamily() &&
675*e038c9c4Sjoerg CGM.getItaniumVTableContext().isRelativeLayout();
676*e038c9c4Sjoerg }
677*e038c9c4Sjoerg
getVTableComponentType() const678*e038c9c4Sjoerg llvm::Type *CodeGenVTables::getVTableComponentType() const {
679*e038c9c4Sjoerg if (useRelativeLayout())
680*e038c9c4Sjoerg return CGM.Int32Ty;
681*e038c9c4Sjoerg return CGM.Int8PtrTy;
682*e038c9c4Sjoerg }
683*e038c9c4Sjoerg
AddPointerLayoutOffset(const CodeGenModule & CGM,ConstantArrayBuilder & builder,CharUnits offset)684*e038c9c4Sjoerg static void AddPointerLayoutOffset(const CodeGenModule &CGM,
685*e038c9c4Sjoerg ConstantArrayBuilder &builder,
686*e038c9c4Sjoerg CharUnits offset) {
6877330f729Sjoerg builder.add(llvm::ConstantExpr::getIntToPtr(
6887330f729Sjoerg llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()),
6897330f729Sjoerg CGM.Int8PtrTy));
690*e038c9c4Sjoerg }
691*e038c9c4Sjoerg
AddRelativeLayoutOffset(const CodeGenModule & CGM,ConstantArrayBuilder & builder,CharUnits offset)692*e038c9c4Sjoerg static void AddRelativeLayoutOffset(const CodeGenModule &CGM,
693*e038c9c4Sjoerg ConstantArrayBuilder &builder,
694*e038c9c4Sjoerg CharUnits offset) {
695*e038c9c4Sjoerg builder.add(llvm::ConstantInt::get(CGM.Int32Ty, offset.getQuantity()));
696*e038c9c4Sjoerg }
697*e038c9c4Sjoerg
addVTableComponent(ConstantArrayBuilder & builder,const VTableLayout & layout,unsigned componentIndex,llvm::Constant * rtti,unsigned & nextVTableThunkIndex,unsigned vtableAddressPoint,bool vtableHasLocalLinkage)698*e038c9c4Sjoerg void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
699*e038c9c4Sjoerg const VTableLayout &layout,
700*e038c9c4Sjoerg unsigned componentIndex,
701*e038c9c4Sjoerg llvm::Constant *rtti,
702*e038c9c4Sjoerg unsigned &nextVTableThunkIndex,
703*e038c9c4Sjoerg unsigned vtableAddressPoint,
704*e038c9c4Sjoerg bool vtableHasLocalLinkage) {
705*e038c9c4Sjoerg auto &component = layout.vtable_components()[componentIndex];
706*e038c9c4Sjoerg
707*e038c9c4Sjoerg auto addOffsetConstant =
708*e038c9c4Sjoerg useRelativeLayout() ? AddRelativeLayoutOffset : AddPointerLayoutOffset;
7097330f729Sjoerg
7107330f729Sjoerg switch (component.getKind()) {
7117330f729Sjoerg case VTableComponent::CK_VCallOffset:
712*e038c9c4Sjoerg return addOffsetConstant(CGM, builder, component.getVCallOffset());
7137330f729Sjoerg
7147330f729Sjoerg case VTableComponent::CK_VBaseOffset:
715*e038c9c4Sjoerg return addOffsetConstant(CGM, builder, component.getVBaseOffset());
7167330f729Sjoerg
7177330f729Sjoerg case VTableComponent::CK_OffsetToTop:
718*e038c9c4Sjoerg return addOffsetConstant(CGM, builder, component.getOffsetToTop());
7197330f729Sjoerg
7207330f729Sjoerg case VTableComponent::CK_RTTI:
721*e038c9c4Sjoerg if (useRelativeLayout())
722*e038c9c4Sjoerg return addRelativeComponent(builder, rtti, vtableAddressPoint,
723*e038c9c4Sjoerg vtableHasLocalLinkage,
724*e038c9c4Sjoerg /*isCompleteDtor=*/false);
725*e038c9c4Sjoerg else
7267330f729Sjoerg return builder.add(llvm::ConstantExpr::getBitCast(rtti, CGM.Int8PtrTy));
7277330f729Sjoerg
7287330f729Sjoerg case VTableComponent::CK_FunctionPointer:
7297330f729Sjoerg case VTableComponent::CK_CompleteDtorPointer:
7307330f729Sjoerg case VTableComponent::CK_DeletingDtorPointer: {
731*e038c9c4Sjoerg GlobalDecl GD = component.getGlobalDecl();
7327330f729Sjoerg
7337330f729Sjoerg if (CGM.getLangOpts().CUDA) {
7347330f729Sjoerg // Emit NULL for methods we can't codegen on this
7357330f729Sjoerg // side. Otherwise we'd end up with vtable with unresolved
7367330f729Sjoerg // references.
7377330f729Sjoerg const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
7387330f729Sjoerg // OK on device side: functions w/ __device__ attribute
7397330f729Sjoerg // OK on host side: anything except __device__-only functions.
7407330f729Sjoerg bool CanEmitMethod =
7417330f729Sjoerg CGM.getLangOpts().CUDAIsDevice
7427330f729Sjoerg ? MD->hasAttr<CUDADeviceAttr>()
7437330f729Sjoerg : (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
7447330f729Sjoerg if (!CanEmitMethod)
745*e038c9c4Sjoerg return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int8PtrTy));
7467330f729Sjoerg // Method is acceptable, continue processing as usual.
7477330f729Sjoerg }
7487330f729Sjoerg
749*e038c9c4Sjoerg auto getSpecialVirtualFn = [&](StringRef name) -> llvm::Constant * {
750*e038c9c4Sjoerg // FIXME(PR43094): When merging comdat groups, lld can select a local
751*e038c9c4Sjoerg // symbol as the signature symbol even though it cannot be accessed
752*e038c9c4Sjoerg // outside that symbol's TU. The relative vtables ABI would make
753*e038c9c4Sjoerg // __cxa_pure_virtual and __cxa_deleted_virtual local symbols, and
754*e038c9c4Sjoerg // depending on link order, the comdat groups could resolve to the one
755*e038c9c4Sjoerg // with the local symbol. As a temporary solution, fill these components
756*e038c9c4Sjoerg // with zero. We shouldn't be calling these in the first place anyway.
757*e038c9c4Sjoerg if (useRelativeLayout())
758*e038c9c4Sjoerg return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
759*e038c9c4Sjoerg
760*e038c9c4Sjoerg // For NVPTX devices in OpenMP emit special functon as null pointers,
761*e038c9c4Sjoerg // otherwise linking ends up with unresolved references.
762*e038c9c4Sjoerg if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPIsDevice &&
763*e038c9c4Sjoerg CGM.getTriple().isNVPTX())
764*e038c9c4Sjoerg return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
7657330f729Sjoerg llvm::FunctionType *fnTy =
7667330f729Sjoerg llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
7677330f729Sjoerg llvm::Constant *fn = cast<llvm::Constant>(
7687330f729Sjoerg CGM.CreateRuntimeFunction(fnTy, name).getCallee());
7697330f729Sjoerg if (auto f = dyn_cast<llvm::Function>(fn))
7707330f729Sjoerg f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
7717330f729Sjoerg return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy);
7727330f729Sjoerg };
7737330f729Sjoerg
7747330f729Sjoerg llvm::Constant *fnPtr;
7757330f729Sjoerg
7767330f729Sjoerg // Pure virtual member functions.
7777330f729Sjoerg if (cast<CXXMethodDecl>(GD.getDecl())->isPure()) {
7787330f729Sjoerg if (!PureVirtualFn)
7797330f729Sjoerg PureVirtualFn =
7807330f729Sjoerg getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
7817330f729Sjoerg fnPtr = PureVirtualFn;
7827330f729Sjoerg
7837330f729Sjoerg // Deleted virtual member functions.
7847330f729Sjoerg } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
7857330f729Sjoerg if (!DeletedVirtualFn)
7867330f729Sjoerg DeletedVirtualFn =
7877330f729Sjoerg getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName());
7887330f729Sjoerg fnPtr = DeletedVirtualFn;
7897330f729Sjoerg
7907330f729Sjoerg // Thunks.
7917330f729Sjoerg } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
792*e038c9c4Sjoerg layout.vtable_thunks()[nextVTableThunkIndex].first ==
793*e038c9c4Sjoerg componentIndex) {
7947330f729Sjoerg auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;
7957330f729Sjoerg
7967330f729Sjoerg nextVTableThunkIndex++;
7977330f729Sjoerg fnPtr = maybeEmitThunk(GD, thunkInfo, /*ForVTable=*/true);
7987330f729Sjoerg
7997330f729Sjoerg // Otherwise we can use the method definition directly.
8007330f729Sjoerg } else {
8017330f729Sjoerg llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
8027330f729Sjoerg fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true);
8037330f729Sjoerg }
8047330f729Sjoerg
805*e038c9c4Sjoerg if (useRelativeLayout()) {
806*e038c9c4Sjoerg return addRelativeComponent(
807*e038c9c4Sjoerg builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,
808*e038c9c4Sjoerg component.getKind() == VTableComponent::CK_CompleteDtorPointer);
809*e038c9c4Sjoerg } else
810*e038c9c4Sjoerg return builder.add(llvm::ConstantExpr::getBitCast(fnPtr, CGM.Int8PtrTy));
8117330f729Sjoerg }
8127330f729Sjoerg
8137330f729Sjoerg case VTableComponent::CK_UnusedFunctionPointer:
814*e038c9c4Sjoerg if (useRelativeLayout())
815*e038c9c4Sjoerg return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int32Ty));
816*e038c9c4Sjoerg else
8177330f729Sjoerg return builder.addNullPointer(CGM.Int8PtrTy);
8187330f729Sjoerg }
8197330f729Sjoerg
8207330f729Sjoerg llvm_unreachable("Unexpected vtable component kind");
8217330f729Sjoerg }
8227330f729Sjoerg
getVTableType(const VTableLayout & layout)8237330f729Sjoerg llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) {
8247330f729Sjoerg SmallVector<llvm::Type *, 4> tys;
825*e038c9c4Sjoerg llvm::Type *componentType = getVTableComponentType();
826*e038c9c4Sjoerg for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i)
827*e038c9c4Sjoerg tys.push_back(llvm::ArrayType::get(componentType, layout.getVTableSize(i)));
8287330f729Sjoerg
8297330f729Sjoerg return llvm::StructType::get(CGM.getLLVMContext(), tys);
8307330f729Sjoerg }
8317330f729Sjoerg
createVTableInitializer(ConstantStructBuilder & builder,const VTableLayout & layout,llvm::Constant * rtti,bool vtableHasLocalLinkage)8327330f729Sjoerg void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder,
8337330f729Sjoerg const VTableLayout &layout,
834*e038c9c4Sjoerg llvm::Constant *rtti,
835*e038c9c4Sjoerg bool vtableHasLocalLinkage) {
836*e038c9c4Sjoerg llvm::Type *componentType = getVTableComponentType();
837*e038c9c4Sjoerg
838*e038c9c4Sjoerg const auto &addressPoints = layout.getAddressPointIndices();
8397330f729Sjoerg unsigned nextVTableThunkIndex = 0;
840*e038c9c4Sjoerg for (unsigned vtableIndex = 0, endIndex = layout.getNumVTables();
841*e038c9c4Sjoerg vtableIndex != endIndex; ++vtableIndex) {
842*e038c9c4Sjoerg auto vtableElem = builder.beginArray(componentType);
843*e038c9c4Sjoerg
844*e038c9c4Sjoerg size_t vtableStart = layout.getVTableOffset(vtableIndex);
845*e038c9c4Sjoerg size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex);
846*e038c9c4Sjoerg for (size_t componentIndex = vtableStart; componentIndex < vtableEnd;
847*e038c9c4Sjoerg ++componentIndex) {
848*e038c9c4Sjoerg addVTableComponent(vtableElem, layout, componentIndex, rtti,
849*e038c9c4Sjoerg nextVTableThunkIndex, addressPoints[vtableIndex],
850*e038c9c4Sjoerg vtableHasLocalLinkage);
8517330f729Sjoerg }
8527330f729Sjoerg vtableElem.finishAndAddTo(builder);
8537330f729Sjoerg }
8547330f729Sjoerg }
8557330f729Sjoerg
GenerateConstructionVTable(const CXXRecordDecl * RD,const BaseSubobject & Base,bool BaseIsVirtual,llvm::GlobalVariable::LinkageTypes Linkage,VTableAddressPointsMapTy & AddressPoints)856*e038c9c4Sjoerg llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable(
857*e038c9c4Sjoerg const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual,
8587330f729Sjoerg llvm::GlobalVariable::LinkageTypes Linkage,
8597330f729Sjoerg VTableAddressPointsMapTy &AddressPoints) {
8607330f729Sjoerg if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
8617330f729Sjoerg DI->completeClassData(Base.getBase());
8627330f729Sjoerg
8637330f729Sjoerg std::unique_ptr<VTableLayout> VTLayout(
8647330f729Sjoerg getItaniumVTableContext().createConstructionVTableLayout(
8657330f729Sjoerg Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));
8667330f729Sjoerg
8677330f729Sjoerg // Add the address points.
8687330f729Sjoerg AddressPoints = VTLayout->getAddressPoints();
8697330f729Sjoerg
8707330f729Sjoerg // Get the mangled construction vtable name.
8717330f729Sjoerg SmallString<256> OutName;
8727330f729Sjoerg llvm::raw_svector_ostream Out(OutName);
8737330f729Sjoerg cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext())
8747330f729Sjoerg .mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(),
8757330f729Sjoerg Base.getBase(), Out);
876*e038c9c4Sjoerg SmallString<256> Name(OutName);
877*e038c9c4Sjoerg
878*e038c9c4Sjoerg bool UsingRelativeLayout = getItaniumVTableContext().isRelativeLayout();
879*e038c9c4Sjoerg bool VTableAliasExists =
880*e038c9c4Sjoerg UsingRelativeLayout && CGM.getModule().getNamedAlias(Name);
881*e038c9c4Sjoerg if (VTableAliasExists) {
882*e038c9c4Sjoerg // We previously made the vtable hidden and changed its name.
883*e038c9c4Sjoerg Name.append(".local");
884*e038c9c4Sjoerg }
8857330f729Sjoerg
8867330f729Sjoerg llvm::Type *VTType = getVTableType(*VTLayout);
8877330f729Sjoerg
8887330f729Sjoerg // Construction vtable symbols are not part of the Itanium ABI, so we cannot
8897330f729Sjoerg // guarantee that they actually will be available externally. Instead, when
8907330f729Sjoerg // emitting an available_externally VTT, we provide references to an internal
8917330f729Sjoerg // linkage construction vtable. The ABI only requires complete-object vtables
8927330f729Sjoerg // to be the same for all instances of a type, not construction vtables.
8937330f729Sjoerg if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
8947330f729Sjoerg Linkage = llvm::GlobalVariable::InternalLinkage;
8957330f729Sjoerg
8967330f729Sjoerg unsigned Align = CGM.getDataLayout().getABITypeAlignment(VTType);
8977330f729Sjoerg
8987330f729Sjoerg // Create the variable that will hold the construction vtable.
8997330f729Sjoerg llvm::GlobalVariable *VTable =
9007330f729Sjoerg CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align);
9017330f729Sjoerg
9027330f729Sjoerg // V-tables are always unnamed_addr.
9037330f729Sjoerg VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
9047330f729Sjoerg
9057330f729Sjoerg llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
9067330f729Sjoerg CGM.getContext().getTagDeclType(Base.getBase()));
9077330f729Sjoerg
9087330f729Sjoerg // Create and set the initializer.
9097330f729Sjoerg ConstantInitBuilder builder(CGM);
9107330f729Sjoerg auto components = builder.beginStruct();
911*e038c9c4Sjoerg createVTableInitializer(components, *VTLayout, RTTI,
912*e038c9c4Sjoerg VTable->hasLocalLinkage());
9137330f729Sjoerg components.finishAndSetAsInitializer(VTable);
9147330f729Sjoerg
9157330f729Sjoerg // Set properties only after the initializer has been set to ensure that the
9167330f729Sjoerg // GV is treated as definition and not declaration.
9177330f729Sjoerg assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration");
9187330f729Sjoerg CGM.setGVProperties(VTable, RD);
9197330f729Sjoerg
9207330f729Sjoerg CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout.get());
9217330f729Sjoerg
922*e038c9c4Sjoerg if (UsingRelativeLayout && !VTable->isDSOLocal())
923*e038c9c4Sjoerg GenerateRelativeVTableAlias(VTable, OutName);
924*e038c9c4Sjoerg
9257330f729Sjoerg return VTable;
9267330f729Sjoerg }
9277330f729Sjoerg
928*e038c9c4Sjoerg // If the VTable is not dso_local, then we will not be able to indicate that
929*e038c9c4Sjoerg // the VTable does not need a relocation and move into rodata. A frequent
930*e038c9c4Sjoerg // time this can occur is for classes that should be made public from a DSO
931*e038c9c4Sjoerg // (like in libc++). For cases like these, we can make the vtable hidden or
932*e038c9c4Sjoerg // private and create a public alias with the same visibility and linkage as
933*e038c9c4Sjoerg // the original vtable type.
GenerateRelativeVTableAlias(llvm::GlobalVariable * VTable,llvm::StringRef AliasNameRef)934*e038c9c4Sjoerg void CodeGenVTables::GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
935*e038c9c4Sjoerg llvm::StringRef AliasNameRef) {
936*e038c9c4Sjoerg assert(getItaniumVTableContext().isRelativeLayout() &&
937*e038c9c4Sjoerg "Can only use this if the relative vtable ABI is used");
938*e038c9c4Sjoerg assert(!VTable->isDSOLocal() && "This should be called only if the vtable is "
939*e038c9c4Sjoerg "not guaranteed to be dso_local");
940*e038c9c4Sjoerg
941*e038c9c4Sjoerg // If the vtable is available_externally, we shouldn't (or need to) generate
942*e038c9c4Sjoerg // an alias for it in the first place since the vtable won't actually by
943*e038c9c4Sjoerg // emitted in this compilation unit.
944*e038c9c4Sjoerg if (VTable->hasAvailableExternallyLinkage())
945*e038c9c4Sjoerg return;
946*e038c9c4Sjoerg
947*e038c9c4Sjoerg // Create a new string in the event the alias is already the name of the
948*e038c9c4Sjoerg // vtable. Using the reference directly could lead to use of an inititialized
949*e038c9c4Sjoerg // value in the module's StringMap.
950*e038c9c4Sjoerg llvm::SmallString<256> AliasName(AliasNameRef);
951*e038c9c4Sjoerg VTable->setName(AliasName + ".local");
952*e038c9c4Sjoerg
953*e038c9c4Sjoerg auto Linkage = VTable->getLinkage();
954*e038c9c4Sjoerg assert(llvm::GlobalAlias::isValidLinkage(Linkage) &&
955*e038c9c4Sjoerg "Invalid vtable alias linkage");
956*e038c9c4Sjoerg
957*e038c9c4Sjoerg llvm::GlobalAlias *VTableAlias = CGM.getModule().getNamedAlias(AliasName);
958*e038c9c4Sjoerg if (!VTableAlias) {
959*e038c9c4Sjoerg VTableAlias = llvm::GlobalAlias::create(VTable->getValueType(),
960*e038c9c4Sjoerg VTable->getAddressSpace(), Linkage,
961*e038c9c4Sjoerg AliasName, &CGM.getModule());
962*e038c9c4Sjoerg } else {
963*e038c9c4Sjoerg assert(VTableAlias->getValueType() == VTable->getValueType());
964*e038c9c4Sjoerg assert(VTableAlias->getLinkage() == Linkage);
965*e038c9c4Sjoerg }
966*e038c9c4Sjoerg VTableAlias->setVisibility(VTable->getVisibility());
967*e038c9c4Sjoerg VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());
968*e038c9c4Sjoerg
969*e038c9c4Sjoerg // Both of these imply dso_local for the vtable.
970*e038c9c4Sjoerg if (!VTable->hasComdat()) {
971*e038c9c4Sjoerg // If this is in a comdat, then we shouldn't make the linkage private due to
972*e038c9c4Sjoerg // an issue in lld where private symbols can be used as the key symbol when
973*e038c9c4Sjoerg // choosing the prevelant group. This leads to "relocation refers to a
974*e038c9c4Sjoerg // symbol in a discarded section".
975*e038c9c4Sjoerg VTable->setLinkage(llvm::GlobalValue::PrivateLinkage);
976*e038c9c4Sjoerg } else {
977*e038c9c4Sjoerg // We should at least make this hidden since we don't want to expose it.
978*e038c9c4Sjoerg VTable->setVisibility(llvm::GlobalValue::HiddenVisibility);
979*e038c9c4Sjoerg }
980*e038c9c4Sjoerg
981*e038c9c4Sjoerg VTableAlias->setAliasee(VTable);
982*e038c9c4Sjoerg }
983*e038c9c4Sjoerg
shouldEmitAvailableExternallyVTable(const CodeGenModule & CGM,const CXXRecordDecl * RD)9847330f729Sjoerg static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM,
9857330f729Sjoerg const CXXRecordDecl *RD) {
9867330f729Sjoerg return CGM.getCodeGenOpts().OptimizationLevel > 0 &&
9877330f729Sjoerg CGM.getCXXABI().canSpeculativelyEmitVTable(RD);
9887330f729Sjoerg }
9897330f729Sjoerg
9907330f729Sjoerg /// Compute the required linkage of the vtable for the given class.
9917330f729Sjoerg ///
9927330f729Sjoerg /// Note that we only call this at the end of the translation unit.
9937330f729Sjoerg llvm::GlobalVariable::LinkageTypes
getVTableLinkage(const CXXRecordDecl * RD)9947330f729Sjoerg CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
9957330f729Sjoerg if (!RD->isExternallyVisible())
9967330f729Sjoerg return llvm::GlobalVariable::InternalLinkage;
9977330f729Sjoerg
9987330f729Sjoerg // We're at the end of the translation unit, so the current key
9997330f729Sjoerg // function is fully correct.
10007330f729Sjoerg const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD);
10017330f729Sjoerg if (keyFunction && !RD->hasAttr<DLLImportAttr>()) {
10027330f729Sjoerg // If this class has a key function, use that to determine the
10037330f729Sjoerg // linkage of the vtable.
10047330f729Sjoerg const FunctionDecl *def = nullptr;
10057330f729Sjoerg if (keyFunction->hasBody(def))
10067330f729Sjoerg keyFunction = cast<CXXMethodDecl>(def);
10077330f729Sjoerg
10087330f729Sjoerg switch (keyFunction->getTemplateSpecializationKind()) {
10097330f729Sjoerg case TSK_Undeclared:
10107330f729Sjoerg case TSK_ExplicitSpecialization:
10117330f729Sjoerg assert((def || CodeGenOpts.OptimizationLevel > 0 ||
10127330f729Sjoerg CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo) &&
10137330f729Sjoerg "Shouldn't query vtable linkage without key function, "
10147330f729Sjoerg "optimizations, or debug info");
10157330f729Sjoerg if (!def && CodeGenOpts.OptimizationLevel > 0)
10167330f729Sjoerg return llvm::GlobalVariable::AvailableExternallyLinkage;
10177330f729Sjoerg
10187330f729Sjoerg if (keyFunction->isInlined())
10197330f729Sjoerg return !Context.getLangOpts().AppleKext ?
10207330f729Sjoerg llvm::GlobalVariable::LinkOnceODRLinkage :
10217330f729Sjoerg llvm::Function::InternalLinkage;
10227330f729Sjoerg
10237330f729Sjoerg return llvm::GlobalVariable::ExternalLinkage;
10247330f729Sjoerg
10257330f729Sjoerg case TSK_ImplicitInstantiation:
10267330f729Sjoerg return !Context.getLangOpts().AppleKext ?
10277330f729Sjoerg llvm::GlobalVariable::LinkOnceODRLinkage :
10287330f729Sjoerg llvm::Function::InternalLinkage;
10297330f729Sjoerg
10307330f729Sjoerg case TSK_ExplicitInstantiationDefinition:
10317330f729Sjoerg return !Context.getLangOpts().AppleKext ?
10327330f729Sjoerg llvm::GlobalVariable::WeakODRLinkage :
10337330f729Sjoerg llvm::Function::InternalLinkage;
10347330f729Sjoerg
10357330f729Sjoerg case TSK_ExplicitInstantiationDeclaration:
10367330f729Sjoerg llvm_unreachable("Should not have been asked to emit this");
10377330f729Sjoerg }
10387330f729Sjoerg }
10397330f729Sjoerg
10407330f729Sjoerg // -fapple-kext mode does not support weak linkage, so we must use
10417330f729Sjoerg // internal linkage.
10427330f729Sjoerg if (Context.getLangOpts().AppleKext)
10437330f729Sjoerg return llvm::Function::InternalLinkage;
10447330f729Sjoerg
10457330f729Sjoerg llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
10467330f729Sjoerg llvm::GlobalValue::LinkOnceODRLinkage;
10477330f729Sjoerg llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
10487330f729Sjoerg llvm::GlobalValue::WeakODRLinkage;
10497330f729Sjoerg if (RD->hasAttr<DLLExportAttr>()) {
10507330f729Sjoerg // Cannot discard exported vtables.
10517330f729Sjoerg DiscardableODRLinkage = NonDiscardableODRLinkage;
10527330f729Sjoerg } else if (RD->hasAttr<DLLImportAttr>()) {
10537330f729Sjoerg // Imported vtables are available externally.
10547330f729Sjoerg DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
10557330f729Sjoerg NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
10567330f729Sjoerg }
10577330f729Sjoerg
10587330f729Sjoerg switch (RD->getTemplateSpecializationKind()) {
10597330f729Sjoerg case TSK_Undeclared:
10607330f729Sjoerg case TSK_ExplicitSpecialization:
10617330f729Sjoerg case TSK_ImplicitInstantiation:
10627330f729Sjoerg return DiscardableODRLinkage;
10637330f729Sjoerg
10647330f729Sjoerg case TSK_ExplicitInstantiationDeclaration:
10657330f729Sjoerg // Explicit instantiations in MSVC do not provide vtables, so we must emit
10667330f729Sjoerg // our own.
10677330f729Sjoerg if (getTarget().getCXXABI().isMicrosoft())
10687330f729Sjoerg return DiscardableODRLinkage;
10697330f729Sjoerg return shouldEmitAvailableExternallyVTable(*this, RD)
10707330f729Sjoerg ? llvm::GlobalVariable::AvailableExternallyLinkage
10717330f729Sjoerg : llvm::GlobalVariable::ExternalLinkage;
10727330f729Sjoerg
10737330f729Sjoerg case TSK_ExplicitInstantiationDefinition:
10747330f729Sjoerg return NonDiscardableODRLinkage;
10757330f729Sjoerg }
10767330f729Sjoerg
10777330f729Sjoerg llvm_unreachable("Invalid TemplateSpecializationKind!");
10787330f729Sjoerg }
10797330f729Sjoerg
10807330f729Sjoerg /// This is a callback from Sema to tell us that a particular vtable is
10817330f729Sjoerg /// required to be emitted in this translation unit.
10827330f729Sjoerg ///
10837330f729Sjoerg /// This is only called for vtables that _must_ be emitted (mainly due to key
10847330f729Sjoerg /// functions). For weak vtables, CodeGen tracks when they are needed and
10857330f729Sjoerg /// emits them as-needed.
EmitVTable(CXXRecordDecl * theClass)10867330f729Sjoerg void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) {
10877330f729Sjoerg VTables.GenerateClassData(theClass);
10887330f729Sjoerg }
10897330f729Sjoerg
10907330f729Sjoerg void
GenerateClassData(const CXXRecordDecl * RD)10917330f729Sjoerg CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
10927330f729Sjoerg if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
10937330f729Sjoerg DI->completeClassData(RD);
10947330f729Sjoerg
10957330f729Sjoerg if (RD->getNumVBases())
10967330f729Sjoerg CGM.getCXXABI().emitVirtualInheritanceTables(RD);
10977330f729Sjoerg
10987330f729Sjoerg CGM.getCXXABI().emitVTableDefinitions(*this, RD);
10997330f729Sjoerg }
11007330f729Sjoerg
11017330f729Sjoerg /// At this point in the translation unit, does it appear that can we
11027330f729Sjoerg /// rely on the vtable being defined elsewhere in the program?
11037330f729Sjoerg ///
11047330f729Sjoerg /// The response is really only definitive when called at the end of
11057330f729Sjoerg /// the translation unit.
11067330f729Sjoerg ///
11077330f729Sjoerg /// The only semantic restriction here is that the object file should
11087330f729Sjoerg /// not contain a vtable definition when that vtable is defined
11097330f729Sjoerg /// strongly elsewhere. Otherwise, we'd just like to avoid emitting
11107330f729Sjoerg /// vtables when unnecessary.
isVTableExternal(const CXXRecordDecl * RD)11117330f729Sjoerg bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
11127330f729Sjoerg assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
11137330f729Sjoerg
11147330f729Sjoerg // We always synthesize vtables if they are needed in the MS ABI. MSVC doesn't
11157330f729Sjoerg // emit them even if there is an explicit template instantiation.
11167330f729Sjoerg if (CGM.getTarget().getCXXABI().isMicrosoft())
11177330f729Sjoerg return false;
11187330f729Sjoerg
11197330f729Sjoerg // If we have an explicit instantiation declaration (and not a
11207330f729Sjoerg // definition), the vtable is defined elsewhere.
11217330f729Sjoerg TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
11227330f729Sjoerg if (TSK == TSK_ExplicitInstantiationDeclaration)
11237330f729Sjoerg return true;
11247330f729Sjoerg
11257330f729Sjoerg // Otherwise, if the class is an instantiated template, the
11267330f729Sjoerg // vtable must be defined here.
11277330f729Sjoerg if (TSK == TSK_ImplicitInstantiation ||
11287330f729Sjoerg TSK == TSK_ExplicitInstantiationDefinition)
11297330f729Sjoerg return false;
11307330f729Sjoerg
11317330f729Sjoerg // Otherwise, if the class doesn't have a key function (possibly
11327330f729Sjoerg // anymore), the vtable must be defined here.
11337330f729Sjoerg const CXXMethodDecl *keyFunction = CGM.getContext().getCurrentKeyFunction(RD);
11347330f729Sjoerg if (!keyFunction)
11357330f729Sjoerg return false;
11367330f729Sjoerg
11377330f729Sjoerg // Otherwise, if we don't have a definition of the key function, the
11387330f729Sjoerg // vtable must be defined somewhere else.
11397330f729Sjoerg return !keyFunction->hasBody();
11407330f729Sjoerg }
11417330f729Sjoerg
11427330f729Sjoerg /// Given that we're currently at the end of the translation unit, and
11437330f729Sjoerg /// we've emitted a reference to the vtable for this class, should
11447330f729Sjoerg /// we define that vtable?
shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule & CGM,const CXXRecordDecl * RD)11457330f729Sjoerg static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
11467330f729Sjoerg const CXXRecordDecl *RD) {
11477330f729Sjoerg // If vtable is internal then it has to be done.
11487330f729Sjoerg if (!CGM.getVTables().isVTableExternal(RD))
11497330f729Sjoerg return true;
11507330f729Sjoerg
11517330f729Sjoerg // If it's external then maybe we will need it as available_externally.
11527330f729Sjoerg return shouldEmitAvailableExternallyVTable(CGM, RD);
11537330f729Sjoerg }
11547330f729Sjoerg
11557330f729Sjoerg /// Given that at some point we emitted a reference to one or more
11567330f729Sjoerg /// vtables, and that we are now at the end of the translation unit,
11577330f729Sjoerg /// decide whether we should emit them.
EmitDeferredVTables()11587330f729Sjoerg void CodeGenModule::EmitDeferredVTables() {
11597330f729Sjoerg #ifndef NDEBUG
11607330f729Sjoerg // Remember the size of DeferredVTables, because we're going to assume
11617330f729Sjoerg // that this entire operation doesn't modify it.
11627330f729Sjoerg size_t savedSize = DeferredVTables.size();
11637330f729Sjoerg #endif
11647330f729Sjoerg
11657330f729Sjoerg for (const CXXRecordDecl *RD : DeferredVTables)
11667330f729Sjoerg if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD))
11677330f729Sjoerg VTables.GenerateClassData(RD);
11687330f729Sjoerg else if (shouldOpportunisticallyEmitVTables())
11697330f729Sjoerg OpportunisticVTables.push_back(RD);
11707330f729Sjoerg
11717330f729Sjoerg assert(savedSize == DeferredVTables.size() &&
11727330f729Sjoerg "deferred extra vtables during vtable emission?");
11737330f729Sjoerg DeferredVTables.clear();
11747330f729Sjoerg }
11757330f729Sjoerg
HasLTOVisibilityPublicStd(const CXXRecordDecl * RD)1176*e038c9c4Sjoerg bool CodeGenModule::HasLTOVisibilityPublicStd(const CXXRecordDecl *RD) {
1177*e038c9c4Sjoerg if (!getCodeGenOpts().LTOVisibilityPublicStd)
1178*e038c9c4Sjoerg return false;
1179*e038c9c4Sjoerg
1180*e038c9c4Sjoerg const DeclContext *DC = RD;
1181*e038c9c4Sjoerg while (1) {
1182*e038c9c4Sjoerg auto *D = cast<Decl>(DC);
1183*e038c9c4Sjoerg DC = DC->getParent();
1184*e038c9c4Sjoerg if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
1185*e038c9c4Sjoerg if (auto *ND = dyn_cast<NamespaceDecl>(D))
1186*e038c9c4Sjoerg if (const IdentifierInfo *II = ND->getIdentifier())
1187*e038c9c4Sjoerg if (II->isStr("std") || II->isStr("stdext"))
1188*e038c9c4Sjoerg return true;
1189*e038c9c4Sjoerg break;
1190*e038c9c4Sjoerg }
1191*e038c9c4Sjoerg }
1192*e038c9c4Sjoerg
1193*e038c9c4Sjoerg return false;
1194*e038c9c4Sjoerg }
1195*e038c9c4Sjoerg
HasHiddenLTOVisibility(const CXXRecordDecl * RD)11967330f729Sjoerg bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
11977330f729Sjoerg LinkageInfo LV = RD->getLinkageAndVisibility();
11987330f729Sjoerg if (!isExternallyVisible(LV.getLinkage()))
11997330f729Sjoerg return true;
12007330f729Sjoerg
12017330f729Sjoerg if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
12027330f729Sjoerg return false;
12037330f729Sjoerg
12047330f729Sjoerg if (getTriple().isOSBinFormatCOFF()) {
12057330f729Sjoerg if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
12067330f729Sjoerg return false;
12077330f729Sjoerg } else {
12087330f729Sjoerg if (LV.getVisibility() != HiddenVisibility)
12097330f729Sjoerg return false;
12107330f729Sjoerg }
12117330f729Sjoerg
1212*e038c9c4Sjoerg return !HasLTOVisibilityPublicStd(RD);
12137330f729Sjoerg }
12147330f729Sjoerg
GetVCallVisibilityLevel(const CXXRecordDecl * RD,llvm::DenseSet<const CXXRecordDecl * > & Visited)1215*e038c9c4Sjoerg llvm::GlobalObject::VCallVisibility CodeGenModule::GetVCallVisibilityLevel(
1216*e038c9c4Sjoerg const CXXRecordDecl *RD, llvm::DenseSet<const CXXRecordDecl *> &Visited) {
1217*e038c9c4Sjoerg // If we have already visited this RD (which means this is a recursive call
1218*e038c9c4Sjoerg // since the initial call should have an empty Visited set), return the max
1219*e038c9c4Sjoerg // visibility. The recursive calls below compute the min between the result
1220*e038c9c4Sjoerg // of the recursive call and the current TypeVis, so returning the max here
1221*e038c9c4Sjoerg // ensures that it will have no effect on the current TypeVis.
1222*e038c9c4Sjoerg if (!Visited.insert(RD).second)
1223*e038c9c4Sjoerg return llvm::GlobalObject::VCallVisibilityTranslationUnit;
12247330f729Sjoerg
12257330f729Sjoerg LinkageInfo LV = RD->getLinkageAndVisibility();
12267330f729Sjoerg llvm::GlobalObject::VCallVisibility TypeVis;
12277330f729Sjoerg if (!isExternallyVisible(LV.getLinkage()))
12287330f729Sjoerg TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
12297330f729Sjoerg else if (HasHiddenLTOVisibility(RD))
12307330f729Sjoerg TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
12317330f729Sjoerg else
12327330f729Sjoerg TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
12337330f729Sjoerg
12347330f729Sjoerg for (auto B : RD->bases())
12357330f729Sjoerg if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1236*e038c9c4Sjoerg TypeVis = std::min(
1237*e038c9c4Sjoerg TypeVis,
1238*e038c9c4Sjoerg GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited));
12397330f729Sjoerg
12407330f729Sjoerg for (auto B : RD->vbases())
12417330f729Sjoerg if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1242*e038c9c4Sjoerg TypeVis = std::min(
1243*e038c9c4Sjoerg TypeVis,
1244*e038c9c4Sjoerg GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited));
12457330f729Sjoerg
12467330f729Sjoerg return TypeVis;
12477330f729Sjoerg }
12487330f729Sjoerg
EmitVTableTypeMetadata(const CXXRecordDecl * RD,llvm::GlobalVariable * VTable,const VTableLayout & VTLayout)12497330f729Sjoerg void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
12507330f729Sjoerg llvm::GlobalVariable *VTable,
12517330f729Sjoerg const VTableLayout &VTLayout) {
12527330f729Sjoerg if (!getCodeGenOpts().LTOUnit)
12537330f729Sjoerg return;
12547330f729Sjoerg
12557330f729Sjoerg CharUnits PointerWidth =
12567330f729Sjoerg Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
12577330f729Sjoerg
12587330f729Sjoerg typedef std::pair<const CXXRecordDecl *, unsigned> AddressPoint;
12597330f729Sjoerg std::vector<AddressPoint> AddressPoints;
12607330f729Sjoerg for (auto &&AP : VTLayout.getAddressPoints())
12617330f729Sjoerg AddressPoints.push_back(std::make_pair(
12627330f729Sjoerg AP.first.getBase(), VTLayout.getVTableOffset(AP.second.VTableIndex) +
12637330f729Sjoerg AP.second.AddressPointIndex));
12647330f729Sjoerg
12657330f729Sjoerg // Sort the address points for determinism.
12667330f729Sjoerg llvm::sort(AddressPoints, [this](const AddressPoint &AP1,
12677330f729Sjoerg const AddressPoint &AP2) {
12687330f729Sjoerg if (&AP1 == &AP2)
12697330f729Sjoerg return false;
12707330f729Sjoerg
12717330f729Sjoerg std::string S1;
12727330f729Sjoerg llvm::raw_string_ostream O1(S1);
12737330f729Sjoerg getCXXABI().getMangleContext().mangleTypeName(
12747330f729Sjoerg QualType(AP1.first->getTypeForDecl(), 0), O1);
12757330f729Sjoerg O1.flush();
12767330f729Sjoerg
12777330f729Sjoerg std::string S2;
12787330f729Sjoerg llvm::raw_string_ostream O2(S2);
12797330f729Sjoerg getCXXABI().getMangleContext().mangleTypeName(
12807330f729Sjoerg QualType(AP2.first->getTypeForDecl(), 0), O2);
12817330f729Sjoerg O2.flush();
12827330f729Sjoerg
12837330f729Sjoerg if (S1 < S2)
12847330f729Sjoerg return true;
12857330f729Sjoerg if (S1 != S2)
12867330f729Sjoerg return false;
12877330f729Sjoerg
12887330f729Sjoerg return AP1.second < AP2.second;
12897330f729Sjoerg });
12907330f729Sjoerg
12917330f729Sjoerg ArrayRef<VTableComponent> Comps = VTLayout.vtable_components();
12927330f729Sjoerg for (auto AP : AddressPoints) {
12937330f729Sjoerg // Create type metadata for the address point.
12947330f729Sjoerg AddVTableTypeMetadata(VTable, PointerWidth * AP.second, AP.first);
12957330f729Sjoerg
12967330f729Sjoerg // The class associated with each address point could also potentially be
12977330f729Sjoerg // used for indirect calls via a member function pointer, so we need to
12987330f729Sjoerg // annotate the address of each function pointer with the appropriate member
12997330f729Sjoerg // function pointer type.
13007330f729Sjoerg for (unsigned I = 0; I != Comps.size(); ++I) {
13017330f729Sjoerg if (Comps[I].getKind() != VTableComponent::CK_FunctionPointer)
13027330f729Sjoerg continue;
13037330f729Sjoerg llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
13047330f729Sjoerg Context.getMemberPointerType(
13057330f729Sjoerg Comps[I].getFunctionDecl()->getType(),
13067330f729Sjoerg Context.getRecordType(AP.first).getTypePtr()));
13077330f729Sjoerg VTable->addTypeMetadata((PointerWidth * I).getQuantity(), MD);
13087330f729Sjoerg }
13097330f729Sjoerg }
13107330f729Sjoerg
1311*e038c9c4Sjoerg if (getCodeGenOpts().VirtualFunctionElimination ||
1312*e038c9c4Sjoerg getCodeGenOpts().WholeProgramVTables) {
1313*e038c9c4Sjoerg llvm::DenseSet<const CXXRecordDecl *> Visited;
1314*e038c9c4Sjoerg llvm::GlobalObject::VCallVisibility TypeVis =
1315*e038c9c4Sjoerg GetVCallVisibilityLevel(RD, Visited);
13167330f729Sjoerg if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1317*e038c9c4Sjoerg VTable->setVCallVisibilityMetadata(TypeVis);
13187330f729Sjoerg }
13197330f729Sjoerg }
1320