xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/CGVTables.cpp (revision 62987288060ff68c817b7056815aa9fb8ba8ecd7)
10b57cec5SDimitry Andric //===--- CGVTables.cpp - Emit LLVM Code for C++ vtables -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This contains code dealing with C++ code generation of virtual tables.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "CGCXXABI.h"
140b57cec5SDimitry Andric #include "CodeGenFunction.h"
150b57cec5SDimitry Andric #include "CodeGenModule.h"
16480093f4SDimitry Andric #include "clang/AST/Attr.h"
170b57cec5SDimitry Andric #include "clang/AST/CXXInheritance.h"
180b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h"
190b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
200b57cec5SDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h"
210b57cec5SDimitry Andric #include "clang/CodeGen/ConstantInitBuilder.h"
220b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
230b57cec5SDimitry Andric #include "llvm/Support/Format.h"
240b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h"
250b57cec5SDimitry Andric #include <algorithm>
260b57cec5SDimitry Andric #include <cstdio>
275f757f3fSDimitry Andric #include <utility>
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric using namespace clang;
300b57cec5SDimitry Andric using namespace CodeGen;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
330b57cec5SDimitry Andric     : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric llvm::Constant *CodeGenModule::GetAddrOfThunk(StringRef Name, llvm::Type *FnTy,
360b57cec5SDimitry Andric                                               GlobalDecl GD) {
370b57cec5SDimitry Andric   return GetOrCreateLLVMFunction(Name, FnTy, GD, /*ForVTable=*/true,
380b57cec5SDimitry Andric                                  /*DontDefer=*/true, /*IsThunk=*/true);
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
420b57cec5SDimitry Andric                                llvm::Function *ThunkFn, bool ForVTable,
430b57cec5SDimitry Andric                                GlobalDecl GD) {
440b57cec5SDimitry Andric   CGM.setFunctionLinkage(GD, ThunkFn);
450b57cec5SDimitry Andric   CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
460b57cec5SDimitry Andric                                   !Thunk.Return.isEmpty());
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   // Set the right visibility.
490b57cec5SDimitry Andric   CGM.setGVProperties(ThunkFn, GD);
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   if (!CGM.getCXXABI().exportThunk()) {
520b57cec5SDimitry Andric     ThunkFn->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
530b57cec5SDimitry Andric     ThunkFn->setDSOLocal(true);
540b57cec5SDimitry Andric   }
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
570b57cec5SDimitry Andric     ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric #ifndef NDEBUG
610b57cec5SDimitry Andric static bool similar(const ABIArgInfo &infoL, CanQualType typeL,
620b57cec5SDimitry Andric                     const ABIArgInfo &infoR, CanQualType typeR) {
630b57cec5SDimitry Andric   return (infoL.getKind() == infoR.getKind() &&
640b57cec5SDimitry Andric           (typeL == typeR ||
650b57cec5SDimitry Andric            (isa<PointerType>(typeL) && isa<PointerType>(typeR)) ||
660b57cec5SDimitry Andric            (isa<ReferenceType>(typeL) && isa<ReferenceType>(typeR))));
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric #endif
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric static RValue PerformReturnAdjustment(CodeGenFunction &CGF,
710b57cec5SDimitry Andric                                       QualType ResultType, RValue RV,
720b57cec5SDimitry Andric                                       const ThunkInfo &Thunk) {
730b57cec5SDimitry Andric   // Emit the return adjustment.
740b57cec5SDimitry Andric   bool NullCheckValue = !ResultType->isReferenceType();
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   llvm::BasicBlock *AdjustNull = nullptr;
770b57cec5SDimitry Andric   llvm::BasicBlock *AdjustNotNull = nullptr;
780b57cec5SDimitry Andric   llvm::BasicBlock *AdjustEnd = nullptr;
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   llvm::Value *ReturnValue = RV.getScalarVal();
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   if (NullCheckValue) {
830b57cec5SDimitry Andric     AdjustNull = CGF.createBasicBlock("adjust.null");
840b57cec5SDimitry Andric     AdjustNotNull = CGF.createBasicBlock("adjust.notnull");
850b57cec5SDimitry Andric     AdjustEnd = CGF.createBasicBlock("adjust.end");
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric     llvm::Value *IsNull = CGF.Builder.CreateIsNull(ReturnValue);
880b57cec5SDimitry Andric     CGF.Builder.CreateCondBr(IsNull, AdjustNull, AdjustNotNull);
890b57cec5SDimitry Andric     CGF.EmitBlock(AdjustNotNull);
900b57cec5SDimitry Andric   }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   auto ClassDecl = ResultType->getPointeeType()->getAsCXXRecordDecl();
930b57cec5SDimitry Andric   auto ClassAlign = CGF.CGM.getClassPointerAlignment(ClassDecl);
9481ad6265SDimitry Andric   ReturnValue = CGF.CGM.getCXXABI().performReturnAdjustment(
9581ad6265SDimitry Andric       CGF,
9681ad6265SDimitry Andric       Address(ReturnValue, CGF.ConvertTypeForMem(ResultType->getPointeeType()),
9781ad6265SDimitry Andric               ClassAlign),
980fca6ea1SDimitry Andric       ClassDecl, Thunk.Return);
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   if (NullCheckValue) {
1010b57cec5SDimitry Andric     CGF.Builder.CreateBr(AdjustEnd);
1020b57cec5SDimitry Andric     CGF.EmitBlock(AdjustNull);
1030b57cec5SDimitry Andric     CGF.Builder.CreateBr(AdjustEnd);
1040b57cec5SDimitry Andric     CGF.EmitBlock(AdjustEnd);
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric     llvm::PHINode *PHI = CGF.Builder.CreatePHI(ReturnValue->getType(), 2);
1070b57cec5SDimitry Andric     PHI->addIncoming(ReturnValue, AdjustNotNull);
1080b57cec5SDimitry Andric     PHI->addIncoming(llvm::Constant::getNullValue(ReturnValue->getType()),
1090b57cec5SDimitry Andric                      AdjustNull);
1100b57cec5SDimitry Andric     ReturnValue = PHI;
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   return RValue::get(ReturnValue);
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric /// This function clones a function's DISubprogram node and enters it into
1170b57cec5SDimitry Andric /// a value map with the intent that the map can be utilized by the cloner
1180b57cec5SDimitry Andric /// to short-circuit Metadata node mapping.
1190b57cec5SDimitry Andric /// Furthermore, the function resolves any DILocalVariable nodes referenced
1200b57cec5SDimitry Andric /// by dbg.value intrinsics so they can be properly mapped during cloning.
1210b57cec5SDimitry Andric static void resolveTopLevelMetadata(llvm::Function *Fn,
1220b57cec5SDimitry Andric                                     llvm::ValueToValueMapTy &VMap) {
1230b57cec5SDimitry Andric   // Clone the DISubprogram node and put it into the Value map.
1240b57cec5SDimitry Andric   auto *DIS = Fn->getSubprogram();
1250b57cec5SDimitry Andric   if (!DIS)
1260b57cec5SDimitry Andric     return;
1270b57cec5SDimitry Andric   auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
1280b57cec5SDimitry Andric   VMap.MD()[DIS].reset(NewDIS);
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   // Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes
1310b57cec5SDimitry Andric   // they are referencing.
132bdd1243dSDimitry Andric   for (auto &BB : *Fn) {
1330b57cec5SDimitry Andric     for (auto &I : BB) {
1340fca6ea1SDimitry Andric       for (llvm::DbgVariableRecord &DVR :
1350fca6ea1SDimitry Andric            llvm::filterDbgVars(I.getDbgRecordRange())) {
1360fca6ea1SDimitry Andric         auto *DILocal = DVR.getVariable();
1370fca6ea1SDimitry Andric         if (!DILocal->isResolved())
1380fca6ea1SDimitry Andric           DILocal->resolve();
1390fca6ea1SDimitry Andric       }
1400b57cec5SDimitry Andric       if (auto *DII = dyn_cast<llvm::DbgVariableIntrinsic>(&I)) {
1410b57cec5SDimitry Andric         auto *DILocal = DII->getVariable();
1420b57cec5SDimitry Andric         if (!DILocal->isResolved())
1430b57cec5SDimitry Andric           DILocal->resolve();
1440b57cec5SDimitry Andric       }
1450b57cec5SDimitry Andric     }
1460b57cec5SDimitry Andric   }
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric // This function does roughly the same thing as GenerateThunk, but in a
1500b57cec5SDimitry Andric // very different way, so that va_start and va_end work correctly.
1510b57cec5SDimitry Andric // FIXME: This function assumes "this" is the first non-sret LLVM argument of
1520b57cec5SDimitry Andric //        a function, and that there is an alloca built in the entry block
1530b57cec5SDimitry Andric //        for all accesses to "this".
1540b57cec5SDimitry Andric // FIXME: This function assumes there is only one "ret" statement per function.
1550b57cec5SDimitry Andric // FIXME: Cloning isn't correct in the presence of indirect goto!
1560b57cec5SDimitry Andric // FIXME: This implementation of thunks bloats codesize by duplicating the
1570b57cec5SDimitry Andric //        function definition.  There are alternatives:
1580b57cec5SDimitry Andric //        1. Add some sort of stub support to LLVM for cases where we can
1590b57cec5SDimitry Andric //           do a this adjustment, then a sibcall.
1600b57cec5SDimitry Andric //        2. We could transform the definition to take a va_list instead of an
1610b57cec5SDimitry Andric //           actual variable argument list, then have the thunks (including a
1620b57cec5SDimitry Andric //           no-op thunk for the regular definition) call va_start/va_end.
1630b57cec5SDimitry Andric //           There's a bit of per-call overhead for this solution, but it's
1640b57cec5SDimitry Andric //           better for codesize if the definition is long.
1650b57cec5SDimitry Andric llvm::Function *
1660b57cec5SDimitry Andric CodeGenFunction::GenerateVarArgsThunk(llvm::Function *Fn,
1670b57cec5SDimitry Andric                                       const CGFunctionInfo &FnInfo,
1680b57cec5SDimitry Andric                                       GlobalDecl GD, const ThunkInfo &Thunk) {
1690b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
170a7dea167SDimitry Andric   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
1710b57cec5SDimitry Andric   QualType ResultType = FPT->getReturnType();
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric   // Get the original function
1740b57cec5SDimitry Andric   assert(FnInfo.isVariadic());
1750b57cec5SDimitry Andric   llvm::Type *Ty = CGM.getTypes().GetFunctionType(FnInfo);
1760b57cec5SDimitry Andric   llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
1770b57cec5SDimitry Andric   llvm::Function *BaseFn = cast<llvm::Function>(Callee);
1780b57cec5SDimitry Andric 
179a7dea167SDimitry Andric   // Cloning can't work if we don't have a definition. The Microsoft ABI may
180a7dea167SDimitry Andric   // require thunks when a definition is not available. Emit an error in these
181a7dea167SDimitry Andric   // cases.
182a7dea167SDimitry Andric   if (!MD->isDefined()) {
183a7dea167SDimitry Andric     CGM.ErrorUnsupported(MD, "return-adjusting thunk with variadic arguments");
184a7dea167SDimitry Andric     return Fn;
185a7dea167SDimitry Andric   }
186a7dea167SDimitry Andric   assert(!BaseFn->isDeclaration() && "cannot clone undefined variadic method");
187a7dea167SDimitry Andric 
1880b57cec5SDimitry Andric   // Clone to thunk.
1890b57cec5SDimitry Andric   llvm::ValueToValueMapTy VMap;
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   // We are cloning a function while some Metadata nodes are still unresolved.
1920b57cec5SDimitry Andric   // Ensure that the value mapper does not encounter any of them.
1930b57cec5SDimitry Andric   resolveTopLevelMetadata(BaseFn, VMap);
1940b57cec5SDimitry Andric   llvm::Function *NewFn = llvm::CloneFunction(BaseFn, VMap);
1950b57cec5SDimitry Andric   Fn->replaceAllUsesWith(NewFn);
1960b57cec5SDimitry Andric   NewFn->takeName(Fn);
1970b57cec5SDimitry Andric   Fn->eraseFromParent();
1980b57cec5SDimitry Andric   Fn = NewFn;
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric   // "Initialize" CGF (minimally).
2010b57cec5SDimitry Andric   CurFn = Fn;
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   // Get the "this" value
2040b57cec5SDimitry Andric   llvm::Function::arg_iterator AI = Fn->arg_begin();
2050b57cec5SDimitry Andric   if (CGM.ReturnTypeUsesSRet(FnInfo))
2060b57cec5SDimitry Andric     ++AI;
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   // Find the first store of "this", which will be to the alloca associated
2090b57cec5SDimitry Andric   // with "this".
2100fca6ea1SDimitry Andric   Address ThisPtr = makeNaturalAddressForPointer(
2110fca6ea1SDimitry Andric       &*AI, MD->getFunctionObjectParameterType(),
21281ad6265SDimitry Andric       CGM.getClassPointerAlignment(MD->getParent()));
2130b57cec5SDimitry Andric   llvm::BasicBlock *EntryBB = &Fn->front();
2140b57cec5SDimitry Andric   llvm::BasicBlock::iterator ThisStore =
215349cc55cSDimitry Andric       llvm::find_if(*EntryBB, [&](llvm::Instruction &I) {
2160fca6ea1SDimitry Andric         return isa<llvm::StoreInst>(I) && I.getOperand(0) == &*AI;
2170b57cec5SDimitry Andric       });
2180b57cec5SDimitry Andric   assert(ThisStore != EntryBB->end() &&
2190b57cec5SDimitry Andric          "Store of this should be in entry block?");
2200b57cec5SDimitry Andric   // Adjust "this", if necessary.
2210b57cec5SDimitry Andric   Builder.SetInsertPoint(&*ThisStore);
2220fca6ea1SDimitry Andric 
2230fca6ea1SDimitry Andric   const CXXRecordDecl *ThisValueClass = Thunk.ThisType->getPointeeCXXRecordDecl();
2240fca6ea1SDimitry Andric   llvm::Value *AdjustedThisPtr = CGM.getCXXABI().performThisAdjustment(
2250fca6ea1SDimitry Andric       *this, ThisPtr, ThisValueClass, Thunk);
226a7dea167SDimitry Andric   AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr,
227a7dea167SDimitry Andric                                           ThisStore->getOperand(0)->getType());
2280b57cec5SDimitry Andric   ThisStore->setOperand(0, AdjustedThisPtr);
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   if (!Thunk.Return.isEmpty()) {
2310b57cec5SDimitry Andric     // Fix up the returned value, if necessary.
2320b57cec5SDimitry Andric     for (llvm::BasicBlock &BB : *Fn) {
2330b57cec5SDimitry Andric       llvm::Instruction *T = BB.getTerminator();
2340b57cec5SDimitry Andric       if (isa<llvm::ReturnInst>(T)) {
2350b57cec5SDimitry Andric         RValue RV = RValue::get(T->getOperand(0));
2360b57cec5SDimitry Andric         T->eraseFromParent();
2370b57cec5SDimitry Andric         Builder.SetInsertPoint(&BB);
2380b57cec5SDimitry Andric         RV = PerformReturnAdjustment(*this, ResultType, RV, Thunk);
2390b57cec5SDimitry Andric         Builder.CreateRet(RV.getScalarVal());
2400b57cec5SDimitry Andric         break;
2410b57cec5SDimitry Andric       }
2420b57cec5SDimitry Andric     }
2430b57cec5SDimitry Andric   }
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric   return Fn;
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric void CodeGenFunction::StartThunk(llvm::Function *Fn, GlobalDecl GD,
2490b57cec5SDimitry Andric                                  const CGFunctionInfo &FnInfo,
2500b57cec5SDimitry Andric                                  bool IsUnprototyped) {
2510b57cec5SDimitry Andric   assert(!CurGD.getDecl() && "CurGD was already set!");
2520b57cec5SDimitry Andric   CurGD = GD;
2530b57cec5SDimitry Andric   CurFuncIsThunk = true;
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   // Build FunctionArgs.
2560b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
2570b57cec5SDimitry Andric   QualType ThisType = MD->getThisType();
2580b57cec5SDimitry Andric   QualType ResultType;
2590b57cec5SDimitry Andric   if (IsUnprototyped)
2600b57cec5SDimitry Andric     ResultType = CGM.getContext().VoidTy;
2610b57cec5SDimitry Andric   else if (CGM.getCXXABI().HasThisReturn(GD))
2620b57cec5SDimitry Andric     ResultType = ThisType;
2630b57cec5SDimitry Andric   else if (CGM.getCXXABI().hasMostDerivedReturn(GD))
2640b57cec5SDimitry Andric     ResultType = CGM.getContext().VoidPtrTy;
2650b57cec5SDimitry Andric   else
266a7dea167SDimitry Andric     ResultType = MD->getType()->castAs<FunctionProtoType>()->getReturnType();
2670b57cec5SDimitry Andric   FunctionArgList FunctionArgs;
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   // Create the implicit 'this' parameter declaration.
2700b57cec5SDimitry Andric   CGM.getCXXABI().buildThisParam(*this, FunctionArgs);
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   // Add the rest of the parameters, if we have a prototype to work with.
2730b57cec5SDimitry Andric   if (!IsUnprototyped) {
2740b57cec5SDimitry Andric     FunctionArgs.append(MD->param_begin(), MD->param_end());
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric     if (isa<CXXDestructorDecl>(MD))
2770b57cec5SDimitry Andric       CGM.getCXXABI().addImplicitStructorParams(*this, ResultType,
2780b57cec5SDimitry Andric                                                 FunctionArgs);
2790b57cec5SDimitry Andric   }
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   // Start defining the function.
2820b57cec5SDimitry Andric   auto NL = ApplyDebugLocation::CreateEmpty(*this);
2830b57cec5SDimitry Andric   StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
2840b57cec5SDimitry Andric                 MD->getLocation());
2850b57cec5SDimitry Andric   // Create a scope with an artificial location for the body of this function.
2860b57cec5SDimitry Andric   auto AL = ApplyDebugLocation::CreateArtificial(*this);
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves.
2890b57cec5SDimitry Andric   CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
2900b57cec5SDimitry Andric   CXXThisValue = CXXABIThisValue;
2910b57cec5SDimitry Andric   CurCodeDecl = MD;
2920b57cec5SDimitry Andric   CurFuncDecl = MD;
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric void CodeGenFunction::FinishThunk() {
2960b57cec5SDimitry Andric   // Clear these to restore the invariants expected by
2970b57cec5SDimitry Andric   // StartFunction/FinishFunction.
2980b57cec5SDimitry Andric   CurCodeDecl = nullptr;
2990b57cec5SDimitry Andric   CurFuncDecl = nullptr;
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   FinishFunction();
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric void CodeGenFunction::EmitCallAndReturnForThunk(llvm::FunctionCallee Callee,
3050b57cec5SDimitry Andric                                                 const ThunkInfo *Thunk,
3060b57cec5SDimitry Andric                                                 bool IsUnprototyped) {
3070b57cec5SDimitry Andric   assert(isa<CXXMethodDecl>(CurGD.getDecl()) &&
3080b57cec5SDimitry Andric          "Please use a new CGF for this thunk");
3090b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CurGD.getDecl());
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   // Adjust the 'this' pointer if necessary
3120fca6ea1SDimitry Andric   const CXXRecordDecl *ThisValueClass =
3130fca6ea1SDimitry Andric       MD->getThisType()->getPointeeCXXRecordDecl();
3140fca6ea1SDimitry Andric   if (Thunk)
3150fca6ea1SDimitry Andric     ThisValueClass = Thunk->ThisType->getPointeeCXXRecordDecl();
3160fca6ea1SDimitry Andric 
3170b57cec5SDimitry Andric   llvm::Value *AdjustedThisPtr =
3180fca6ea1SDimitry Andric       Thunk ? CGM.getCXXABI().performThisAdjustment(*this, LoadCXXThisAddress(),
3190fca6ea1SDimitry Andric                                                     ThisValueClass, *Thunk)
3200b57cec5SDimitry Andric             : LoadCXXThis();
3210b57cec5SDimitry Andric 
322a7dea167SDimitry Andric   // If perfect forwarding is required a variadic method, a method using
323a7dea167SDimitry Andric   // inalloca, or an unprototyped thunk, use musttail. Emit an error if this
324a7dea167SDimitry Andric   // thunk requires a return adjustment, since that is impossible with musttail.
325a7dea167SDimitry Andric   if (CurFnInfo->usesInAlloca() || CurFnInfo->isVariadic() || IsUnprototyped) {
3260b57cec5SDimitry Andric     if (Thunk && !Thunk->Return.isEmpty()) {
3270b57cec5SDimitry Andric       if (IsUnprototyped)
3280b57cec5SDimitry Andric         CGM.ErrorUnsupported(
3290b57cec5SDimitry Andric             MD, "return-adjusting thunk with incomplete parameter type");
330a7dea167SDimitry Andric       else if (CurFnInfo->isVariadic())
331a7dea167SDimitry Andric         llvm_unreachable("shouldn't try to emit musttail return-adjusting "
332a7dea167SDimitry Andric                          "thunks for variadic functions");
3330b57cec5SDimitry Andric       else
3340b57cec5SDimitry Andric         CGM.ErrorUnsupported(
3350b57cec5SDimitry Andric             MD, "non-trivial argument copy for return-adjusting thunk");
3360b57cec5SDimitry Andric     }
3370b57cec5SDimitry Andric     EmitMustTailThunk(CurGD, AdjustedThisPtr, Callee);
3380b57cec5SDimitry Andric     return;
3390b57cec5SDimitry Andric   }
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   // Start building CallArgs.
3420b57cec5SDimitry Andric   CallArgList CallArgs;
3430b57cec5SDimitry Andric   QualType ThisType = MD->getThisType();
3440b57cec5SDimitry Andric   CallArgs.add(RValue::get(AdjustedThisPtr), ThisType);
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(MD))
3470b57cec5SDimitry Andric     CGM.getCXXABI().adjustCallArgsForDestructorThunk(*this, CurGD, CallArgs);
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric #ifndef NDEBUG
3500b57cec5SDimitry Andric   unsigned PrefixArgs = CallArgs.size() - 1;
3510b57cec5SDimitry Andric #endif
3520b57cec5SDimitry Andric   // Add the rest of the arguments.
3530b57cec5SDimitry Andric   for (const ParmVarDecl *PD : MD->parameters())
3540b57cec5SDimitry Andric     EmitDelegateCallArg(CallArgs, PD, SourceLocation());
3550b57cec5SDimitry Andric 
356480093f4SDimitry Andric   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric #ifndef NDEBUG
3590b57cec5SDimitry Andric   const CGFunctionInfo &CallFnInfo = CGM.getTypes().arrangeCXXMethodCall(
3600b57cec5SDimitry Andric       CallArgs, FPT, RequiredArgs::forPrototypePlus(FPT, 1), PrefixArgs);
3610b57cec5SDimitry Andric   assert(CallFnInfo.getRegParm() == CurFnInfo->getRegParm() &&
3620b57cec5SDimitry Andric          CallFnInfo.isNoReturn() == CurFnInfo->isNoReturn() &&
3630b57cec5SDimitry Andric          CallFnInfo.getCallingConvention() == CurFnInfo->getCallingConvention());
3640b57cec5SDimitry Andric   assert(isa<CXXDestructorDecl>(MD) || // ignore dtor return types
3650b57cec5SDimitry Andric          similar(CallFnInfo.getReturnInfo(), CallFnInfo.getReturnType(),
3660b57cec5SDimitry Andric                  CurFnInfo->getReturnInfo(), CurFnInfo->getReturnType()));
3670b57cec5SDimitry Andric   assert(CallFnInfo.arg_size() == CurFnInfo->arg_size());
3680b57cec5SDimitry Andric   for (unsigned i = 0, e = CurFnInfo->arg_size(); i != e; ++i)
3690b57cec5SDimitry Andric     assert(similar(CallFnInfo.arg_begin()[i].info,
3700b57cec5SDimitry Andric                    CallFnInfo.arg_begin()[i].type,
3710b57cec5SDimitry Andric                    CurFnInfo->arg_begin()[i].info,
3720b57cec5SDimitry Andric                    CurFnInfo->arg_begin()[i].type));
3730b57cec5SDimitry Andric #endif
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric   // Determine whether we have a return value slot to use.
3760b57cec5SDimitry Andric   QualType ResultType = CGM.getCXXABI().HasThisReturn(CurGD)
3770b57cec5SDimitry Andric                             ? ThisType
3780b57cec5SDimitry Andric                             : CGM.getCXXABI().hasMostDerivedReturn(CurGD)
3790b57cec5SDimitry Andric                                   ? CGM.getContext().VoidPtrTy
3800b57cec5SDimitry Andric                                   : FPT->getReturnType();
3810b57cec5SDimitry Andric   ReturnValueSlot Slot;
3820b57cec5SDimitry Andric   if (!ResultType->isVoidType() &&
3835ffd83dbSDimitry Andric       (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect ||
3845ffd83dbSDimitry Andric        hasAggregateEvaluationKind(ResultType)))
3855ffd83dbSDimitry Andric     Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified(),
3865ffd83dbSDimitry Andric                            /*IsUnused=*/false, /*IsExternallyDestructed=*/true);
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   // Now emit our call.
3890b57cec5SDimitry Andric   llvm::CallBase *CallOrInvoke;
3900b57cec5SDimitry Andric   RValue RV = EmitCall(*CurFnInfo, CGCallee::forDirect(Callee, CurGD), Slot,
3910b57cec5SDimitry Andric                        CallArgs, &CallOrInvoke);
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric   // Consider return adjustment if we have ThunkInfo.
3940b57cec5SDimitry Andric   if (Thunk && !Thunk->Return.isEmpty())
3950b57cec5SDimitry Andric     RV = PerformReturnAdjustment(*this, ResultType, RV, *Thunk);
3960b57cec5SDimitry Andric   else if (llvm::CallInst* Call = dyn_cast<llvm::CallInst>(CallOrInvoke))
3970b57cec5SDimitry Andric     Call->setTailCallKind(llvm::CallInst::TCK_Tail);
3980b57cec5SDimitry Andric 
3990b57cec5SDimitry Andric   // Emit return.
4000b57cec5SDimitry Andric   if (!ResultType->isVoidType() && Slot.isNull())
4010b57cec5SDimitry Andric     CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType);
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   // Disable the final ARC autorelease.
4040b57cec5SDimitry Andric   AutoreleaseResult = false;
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric   FinishThunk();
4070b57cec5SDimitry Andric }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric void CodeGenFunction::EmitMustTailThunk(GlobalDecl GD,
4100b57cec5SDimitry Andric                                         llvm::Value *AdjustedThisPtr,
4110b57cec5SDimitry Andric                                         llvm::FunctionCallee Callee) {
4120b57cec5SDimitry Andric   // Emitting a musttail call thunk doesn't use any of the CGCall.cpp machinery
4130b57cec5SDimitry Andric   // to translate AST arguments into LLVM IR arguments.  For thunks, we know
4140b57cec5SDimitry Andric   // that the caller prototype more or less matches the callee prototype with
4150b57cec5SDimitry Andric   // the exception of 'this'.
41681ad6265SDimitry Andric   SmallVector<llvm::Value *, 8> Args(llvm::make_pointer_range(CurFn->args()));
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   // Set the adjusted 'this' pointer.
4190b57cec5SDimitry Andric   const ABIArgInfo &ThisAI = CurFnInfo->arg_begin()->info;
4200b57cec5SDimitry Andric   if (ThisAI.isDirect()) {
4210b57cec5SDimitry Andric     const ABIArgInfo &RetAI = CurFnInfo->getReturnInfo();
4220b57cec5SDimitry Andric     int ThisArgNo = RetAI.isIndirect() && !RetAI.isSRetAfterThis() ? 1 : 0;
4230b57cec5SDimitry Andric     llvm::Type *ThisType = Args[ThisArgNo]->getType();
4240b57cec5SDimitry Andric     if (ThisType != AdjustedThisPtr->getType())
4250b57cec5SDimitry Andric       AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
4260b57cec5SDimitry Andric     Args[ThisArgNo] = AdjustedThisPtr;
4270b57cec5SDimitry Andric   } else {
4280b57cec5SDimitry Andric     assert(ThisAI.isInAlloca() && "this is passed directly or inalloca");
4290b57cec5SDimitry Andric     Address ThisAddr = GetAddrOfLocalVar(CXXABIThisDecl);
4300b57cec5SDimitry Andric     llvm::Type *ThisType = ThisAddr.getElementType();
4310b57cec5SDimitry Andric     if (ThisType != AdjustedThisPtr->getType())
4320b57cec5SDimitry Andric       AdjustedThisPtr = Builder.CreateBitCast(AdjustedThisPtr, ThisType);
4330b57cec5SDimitry Andric     Builder.CreateStore(AdjustedThisPtr, ThisAddr);
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   // Emit the musttail call manually.  Even if the prologue pushed cleanups, we
4370b57cec5SDimitry Andric   // don't actually want to run them.
4380b57cec5SDimitry Andric   llvm::CallInst *Call = Builder.CreateCall(Callee, Args);
4390b57cec5SDimitry Andric   Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric   // Apply the standard set of call attributes.
4420b57cec5SDimitry Andric   unsigned CallingConv;
4430b57cec5SDimitry Andric   llvm::AttributeList Attrs;
4440b57cec5SDimitry Andric   CGM.ConstructAttributeList(Callee.getCallee()->getName(), *CurFnInfo, GD,
445fe6060f1SDimitry Andric                              Attrs, CallingConv, /*AttrOnCallSite=*/true,
446fe6060f1SDimitry Andric                              /*IsThunk=*/false);
4470b57cec5SDimitry Andric   Call->setAttributes(Attrs);
4480b57cec5SDimitry Andric   Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric   if (Call->getType()->isVoidTy())
4510b57cec5SDimitry Andric     Builder.CreateRetVoid();
4520b57cec5SDimitry Andric   else
4530b57cec5SDimitry Andric     Builder.CreateRet(Call);
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   // Finish the function to maintain CodeGenFunction invariants.
4560b57cec5SDimitry Andric   // FIXME: Don't emit unreachable code.
4570b57cec5SDimitry Andric   EmitBlock(createBasicBlock());
4583788a439SDimitry Andric 
4593788a439SDimitry Andric   FinishThunk();
4600b57cec5SDimitry Andric }
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric void CodeGenFunction::generateThunk(llvm::Function *Fn,
4630b57cec5SDimitry Andric                                     const CGFunctionInfo &FnInfo, GlobalDecl GD,
4640b57cec5SDimitry Andric                                     const ThunkInfo &Thunk,
4650b57cec5SDimitry Andric                                     bool IsUnprototyped) {
4660b57cec5SDimitry Andric   StartThunk(Fn, GD, FnInfo, IsUnprototyped);
4670b57cec5SDimitry Andric   // Create a scope with an artificial location for the body of this function.
4680b57cec5SDimitry Andric   auto AL = ApplyDebugLocation::CreateArtificial(*this);
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   // Get our callee. Use a placeholder type if this method is unprototyped so
4710b57cec5SDimitry Andric   // that CodeGenModule doesn't try to set attributes.
4720b57cec5SDimitry Andric   llvm::Type *Ty;
4730b57cec5SDimitry Andric   if (IsUnprototyped)
4740b57cec5SDimitry Andric     Ty = llvm::StructType::get(getLLVMContext());
4750b57cec5SDimitry Andric   else
4760b57cec5SDimitry Andric     Ty = CGM.getTypes().GetFunctionType(FnInfo);
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric   llvm::Constant *Callee = CGM.GetAddrOfFunction(GD, Ty, /*ForVTable=*/true);
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   // Make the call and return the result.
4810b57cec5SDimitry Andric   EmitCallAndReturnForThunk(llvm::FunctionCallee(Fn->getFunctionType(), Callee),
4820b57cec5SDimitry Andric                             &Thunk, IsUnprototyped);
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric static bool shouldEmitVTableThunk(CodeGenModule &CGM, const CXXMethodDecl *MD,
4860b57cec5SDimitry Andric                                   bool IsUnprototyped, bool ForVTable) {
4870b57cec5SDimitry Andric   // Always emit thunks in the MS C++ ABI. We cannot rely on other TUs to
4880b57cec5SDimitry Andric   // provide thunks for us.
4890b57cec5SDimitry Andric   if (CGM.getTarget().getCXXABI().isMicrosoft())
4900b57cec5SDimitry Andric     return true;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   // In the Itanium C++ ABI, vtable thunks are provided by TUs that provide
4930b57cec5SDimitry Andric   // definitions of the main method. Therefore, emitting thunks with the vtable
4940b57cec5SDimitry Andric   // is purely an optimization. Emit the thunk if optimizations are enabled and
4950b57cec5SDimitry Andric   // all of the parameter types are complete.
4960b57cec5SDimitry Andric   if (ForVTable)
4970b57cec5SDimitry Andric     return CGM.getCodeGenOpts().OptimizationLevel && !IsUnprototyped;
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric   // Always emit thunks along with the method definition.
5000b57cec5SDimitry Andric   return true;
5010b57cec5SDimitry Andric }
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric llvm::Constant *CodeGenVTables::maybeEmitThunk(GlobalDecl GD,
5040b57cec5SDimitry Andric                                                const ThunkInfo &TI,
5050b57cec5SDimitry Andric                                                bool ForVTable) {
5060b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   // First, get a declaration. Compute the mangled name. Don't worry about
5090b57cec5SDimitry Andric   // getting the function prototype right, since we may only need this
5100b57cec5SDimitry Andric   // declaration to fill in a vtable slot.
5110b57cec5SDimitry Andric   SmallString<256> Name;
5120b57cec5SDimitry Andric   MangleContext &MCtx = CGM.getCXXABI().getMangleContext();
5130b57cec5SDimitry Andric   llvm::raw_svector_ostream Out(Name);
5140fca6ea1SDimitry Andric 
5150fca6ea1SDimitry Andric   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
5160fca6ea1SDimitry Andric     MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI,
5170fca6ea1SDimitry Andric                             /* elideOverrideInfo */ false, Out);
5180fca6ea1SDimitry Andric   } else
5190fca6ea1SDimitry Andric     MCtx.mangleThunk(MD, TI, /* elideOverrideInfo */ false, Out);
5200fca6ea1SDimitry Andric 
5210fca6ea1SDimitry Andric   if (CGM.getContext().useAbbreviatedThunkName(GD, Name.str())) {
5220fca6ea1SDimitry Andric     Name = "";
5230b57cec5SDimitry Andric     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
5240fca6ea1SDimitry Andric       MCtx.mangleCXXDtorThunk(DD, GD.getDtorType(), TI,
5250fca6ea1SDimitry Andric                               /* elideOverrideInfo */ true, Out);
5260b57cec5SDimitry Andric     else
5270fca6ea1SDimitry Andric       MCtx.mangleThunk(MD, TI, /* elideOverrideInfo */ true, Out);
5280fca6ea1SDimitry Andric   }
5290fca6ea1SDimitry Andric 
5300b57cec5SDimitry Andric   llvm::Type *ThunkVTableTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
5310b57cec5SDimitry Andric   llvm::Constant *Thunk = CGM.GetAddrOfThunk(Name, ThunkVTableTy, GD);
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   // If we don't need to emit a definition, return this declaration as is.
5340b57cec5SDimitry Andric   bool IsUnprototyped = !CGM.getTypes().isFuncTypeConvertible(
5350b57cec5SDimitry Andric       MD->getType()->castAs<FunctionType>());
5360b57cec5SDimitry Andric   if (!shouldEmitVTableThunk(CGM, MD, IsUnprototyped, ForVTable))
5370b57cec5SDimitry Andric     return Thunk;
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric   // Arrange a function prototype appropriate for a function definition. In some
5400b57cec5SDimitry Andric   // cases in the MS ABI, we may need to build an unprototyped musttail thunk.
5410b57cec5SDimitry Andric   const CGFunctionInfo &FnInfo =
5420b57cec5SDimitry Andric       IsUnprototyped ? CGM.getTypes().arrangeUnprototypedMustTailThunk(MD)
5430b57cec5SDimitry Andric                      : CGM.getTypes().arrangeGlobalDeclaration(GD);
5440b57cec5SDimitry Andric   llvm::FunctionType *ThunkFnTy = CGM.getTypes().GetFunctionType(FnInfo);
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   // If the type of the underlying GlobalValue is wrong, we'll have to replace
5470b57cec5SDimitry Andric   // it. It should be a declaration.
5480b57cec5SDimitry Andric   llvm::Function *ThunkFn = cast<llvm::Function>(Thunk->stripPointerCasts());
5490b57cec5SDimitry Andric   if (ThunkFn->getFunctionType() != ThunkFnTy) {
5500b57cec5SDimitry Andric     llvm::GlobalValue *OldThunkFn = ThunkFn;
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric     assert(OldThunkFn->isDeclaration() && "Shouldn't replace non-declaration");
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric     // Remove the name from the old thunk function and get a new thunk.
5550b57cec5SDimitry Andric     OldThunkFn->setName(StringRef());
5560b57cec5SDimitry Andric     ThunkFn = llvm::Function::Create(ThunkFnTy, llvm::Function::ExternalLinkage,
5570b57cec5SDimitry Andric                                      Name.str(), &CGM.getModule());
558fe6060f1SDimitry Andric     CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false);
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric     if (!OldThunkFn->use_empty()) {
5615f757f3fSDimitry Andric       OldThunkFn->replaceAllUsesWith(ThunkFn);
5620b57cec5SDimitry Andric     }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric     // Remove the old thunk.
5650b57cec5SDimitry Andric     OldThunkFn->eraseFromParent();
5660b57cec5SDimitry Andric   }
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   bool ABIHasKeyFunctions = CGM.getTarget().getCXXABI().hasKeyFunctions();
5690b57cec5SDimitry Andric   bool UseAvailableExternallyLinkage = ForVTable && ABIHasKeyFunctions;
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric   if (!ThunkFn->isDeclaration()) {
5720b57cec5SDimitry Andric     if (!ABIHasKeyFunctions || UseAvailableExternallyLinkage) {
5730b57cec5SDimitry Andric       // There is already a thunk emitted for this function, do nothing.
5740b57cec5SDimitry Andric       return ThunkFn;
5750b57cec5SDimitry Andric     }
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric     setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
5780b57cec5SDimitry Andric     return ThunkFn;
5790b57cec5SDimitry Andric   }
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric   // If this will be unprototyped, add the "thunk" attribute so that LLVM knows
5820b57cec5SDimitry Andric   // that the return type is meaningless. These thunks can be used to call
5830b57cec5SDimitry Andric   // functions with differing return types, and the caller is required to cast
5840b57cec5SDimitry Andric   // the prototype appropriately to extract the correct value.
5850b57cec5SDimitry Andric   if (IsUnprototyped)
5860b57cec5SDimitry Andric     ThunkFn->addFnAttr("thunk");
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   CGM.SetLLVMFunctionAttributesForDefinition(GD.getDecl(), ThunkFn);
5890b57cec5SDimitry Andric 
590a7dea167SDimitry Andric   // Thunks for variadic methods are special because in general variadic
5913788a439SDimitry Andric   // arguments cannot be perfectly forwarded. In the general case, clang
592a7dea167SDimitry Andric   // implements such thunks by cloning the original function body. However, for
593a7dea167SDimitry Andric   // thunks with no return adjustment on targets that support musttail, we can
594a7dea167SDimitry Andric   // use musttail to perfectly forward the variadic arguments.
595a7dea167SDimitry Andric   bool ShouldCloneVarArgs = false;
5960b57cec5SDimitry Andric   if (!IsUnprototyped && ThunkFn->isVarArg()) {
597a7dea167SDimitry Andric     ShouldCloneVarArgs = true;
598a7dea167SDimitry Andric     if (TI.Return.isEmpty()) {
599a7dea167SDimitry Andric       switch (CGM.getTriple().getArch()) {
600a7dea167SDimitry Andric       case llvm::Triple::x86_64:
601a7dea167SDimitry Andric       case llvm::Triple::x86:
602a7dea167SDimitry Andric       case llvm::Triple::aarch64:
603a7dea167SDimitry Andric         ShouldCloneVarArgs = false;
604a7dea167SDimitry Andric         break;
605a7dea167SDimitry Andric       default:
606a7dea167SDimitry Andric         break;
607a7dea167SDimitry Andric       }
608a7dea167SDimitry Andric     }
609a7dea167SDimitry Andric   }
610a7dea167SDimitry Andric 
611a7dea167SDimitry Andric   if (ShouldCloneVarArgs) {
6120b57cec5SDimitry Andric     if (UseAvailableExternallyLinkage)
6130b57cec5SDimitry Andric       return ThunkFn;
614a7dea167SDimitry Andric     ThunkFn =
615a7dea167SDimitry Andric         CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, TI);
6160b57cec5SDimitry Andric   } else {
6170b57cec5SDimitry Andric     // Normal thunk body generation.
6180b57cec5SDimitry Andric     CodeGenFunction(CGM).generateThunk(ThunkFn, FnInfo, GD, TI, IsUnprototyped);
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric   setThunkProperties(CGM, TI, ThunkFn, ForVTable, GD);
6220b57cec5SDimitry Andric   return ThunkFn;
6230b57cec5SDimitry Andric }
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric void CodeGenVTables::EmitThunks(GlobalDecl GD) {
6260b57cec5SDimitry Andric   const CXXMethodDecl *MD =
6270b57cec5SDimitry Andric     cast<CXXMethodDecl>(GD.getDecl())->getCanonicalDecl();
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric   // We don't need to generate thunks for the base destructor.
6300b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
6310b57cec5SDimitry Andric     return;
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric   const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector =
6340b57cec5SDimitry Andric       VTContext->getThunkInfo(GD);
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric   if (!ThunkInfoVector)
6370b57cec5SDimitry Andric     return;
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   for (const ThunkInfo& Thunk : *ThunkInfoVector)
6400b57cec5SDimitry Andric     maybeEmitThunk(GD, Thunk, /*ForVTable=*/false);
6410b57cec5SDimitry Andric }
6420b57cec5SDimitry Andric 
6435ffd83dbSDimitry Andric void CodeGenVTables::addRelativeComponent(ConstantArrayBuilder &builder,
6445ffd83dbSDimitry Andric                                           llvm::Constant *component,
6455ffd83dbSDimitry Andric                                           unsigned vtableAddressPoint,
6465ffd83dbSDimitry Andric                                           bool vtableHasLocalLinkage,
6475ffd83dbSDimitry Andric                                           bool isCompleteDtor) const {
6485ffd83dbSDimitry Andric   // No need to get the offset of a nullptr.
6495ffd83dbSDimitry Andric   if (component->isNullValue())
6505ffd83dbSDimitry Andric     return builder.add(llvm::ConstantInt::get(CGM.Int32Ty, 0));
6510b57cec5SDimitry Andric 
6525ffd83dbSDimitry Andric   auto *globalVal =
6535ffd83dbSDimitry Andric       cast<llvm::GlobalValue>(component->stripPointerCastsAndAliases());
6545ffd83dbSDimitry Andric   llvm::Module &module = CGM.getModule();
6555ffd83dbSDimitry Andric 
6565ffd83dbSDimitry Andric   // We don't want to copy the linkage of the vtable exactly because we still
6575ffd83dbSDimitry Andric   // want the stub/proxy to be emitted for properly calculating the offset.
6585ffd83dbSDimitry Andric   // Examples where there would be no symbol emitted are available_externally
6595ffd83dbSDimitry Andric   // and private linkages.
6605f757f3fSDimitry Andric   //
6615f757f3fSDimitry Andric   // `internal` linkage results in STB_LOCAL Elf binding while still manifesting a
6625f757f3fSDimitry Andric   // local symbol.
6635f757f3fSDimitry Andric   //
6645f757f3fSDimitry Andric   // `linkonce_odr` linkage results in a STB_DEFAULT Elf binding but also allows for
6655f757f3fSDimitry Andric   // the rtti_proxy to be transparently replaced with a GOTPCREL reloc by a
6665f757f3fSDimitry Andric   // target that supports this replacement.
6675f757f3fSDimitry Andric   auto stubLinkage = vtableHasLocalLinkage
6685f757f3fSDimitry Andric                          ? llvm::GlobalValue::InternalLinkage
6695f757f3fSDimitry Andric                          : llvm::GlobalValue::LinkOnceODRLinkage;
6705ffd83dbSDimitry Andric 
6715ffd83dbSDimitry Andric   llvm::Constant *target;
6725ffd83dbSDimitry Andric   if (auto *func = dyn_cast<llvm::Function>(globalVal)) {
673e8d8bef9SDimitry Andric     target = llvm::DSOLocalEquivalent::get(func);
6745ffd83dbSDimitry Andric   } else {
6755ffd83dbSDimitry Andric     llvm::SmallString<16> rttiProxyName(globalVal->getName());
6765ffd83dbSDimitry Andric     rttiProxyName.append(".rtti_proxy");
6775ffd83dbSDimitry Andric 
6785ffd83dbSDimitry Andric     // The RTTI component may not always be emitted in the same linkage unit as
6795ffd83dbSDimitry Andric     // the vtable. As a general case, we can make a dso_local proxy to the RTTI
6805ffd83dbSDimitry Andric     // that points to the actual RTTI struct somewhere. This will result in a
6815ffd83dbSDimitry Andric     // GOTPCREL relocation when taking the relative offset to the proxy.
6825ffd83dbSDimitry Andric     llvm::GlobalVariable *proxy = module.getNamedGlobal(rttiProxyName);
6835ffd83dbSDimitry Andric     if (!proxy) {
6845ffd83dbSDimitry Andric       proxy = new llvm::GlobalVariable(module, globalVal->getType(),
6855ffd83dbSDimitry Andric                                        /*isConstant=*/true, stubLinkage,
6865ffd83dbSDimitry Andric                                        globalVal, rttiProxyName);
6875ffd83dbSDimitry Andric       proxy->setDSOLocal(true);
6885ffd83dbSDimitry Andric       proxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
6895ffd83dbSDimitry Andric       if (!proxy->hasLocalLinkage()) {
6905ffd83dbSDimitry Andric         proxy->setVisibility(llvm::GlobalValue::HiddenVisibility);
6915ffd83dbSDimitry Andric         proxy->setComdat(module.getOrInsertComdat(rttiProxyName));
6925ffd83dbSDimitry Andric       }
693bdd1243dSDimitry Andric       // Do not instrument the rtti proxies with hwasan to avoid a duplicate
694bdd1243dSDimitry Andric       // symbol error. Aliases generated by hwasan will retain the same namebut
695bdd1243dSDimitry Andric       // the addresses they are set to may have different tags from different
696bdd1243dSDimitry Andric       // compilation units. We don't run into this without hwasan because the
697bdd1243dSDimitry Andric       // proxies are in comdat groups, but those aren't propagated to the alias.
698bdd1243dSDimitry Andric       RemoveHwasanMetadata(proxy);
6995ffd83dbSDimitry Andric     }
7005ffd83dbSDimitry Andric     target = proxy;
7015ffd83dbSDimitry Andric   }
7025ffd83dbSDimitry Andric 
7035ffd83dbSDimitry Andric   builder.addRelativeOffsetToPosition(CGM.Int32Ty, target,
7045ffd83dbSDimitry Andric                                       /*position=*/vtableAddressPoint);
7055ffd83dbSDimitry Andric }
7065ffd83dbSDimitry Andric 
707bdd1243dSDimitry Andric static bool UseRelativeLayout(const CodeGenModule &CGM) {
7085ffd83dbSDimitry Andric   return CGM.getTarget().getCXXABI().isItaniumFamily() &&
7095ffd83dbSDimitry Andric          CGM.getItaniumVTableContext().isRelativeLayout();
7105ffd83dbSDimitry Andric }
7115ffd83dbSDimitry Andric 
712bdd1243dSDimitry Andric bool CodeGenVTables::useRelativeLayout() const {
713bdd1243dSDimitry Andric   return UseRelativeLayout(CGM);
714bdd1243dSDimitry Andric }
715bdd1243dSDimitry Andric 
716bdd1243dSDimitry Andric llvm::Type *CodeGenModule::getVTableComponentType() const {
717bdd1243dSDimitry Andric   if (UseRelativeLayout(*this))
718bdd1243dSDimitry Andric     return Int32Ty;
71906c3fb27SDimitry Andric   return GlobalsInt8PtrTy;
720bdd1243dSDimitry Andric }
721bdd1243dSDimitry Andric 
7225ffd83dbSDimitry Andric llvm::Type *CodeGenVTables::getVTableComponentType() const {
723bdd1243dSDimitry Andric   return CGM.getVTableComponentType();
7245ffd83dbSDimitry Andric }
7255ffd83dbSDimitry Andric 
7265ffd83dbSDimitry Andric static void AddPointerLayoutOffset(const CodeGenModule &CGM,
7275ffd83dbSDimitry Andric                                    ConstantArrayBuilder &builder,
7285ffd83dbSDimitry Andric                                    CharUnits offset) {
7290b57cec5SDimitry Andric   builder.add(llvm::ConstantExpr::getIntToPtr(
7300b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity()),
73106c3fb27SDimitry Andric       CGM.GlobalsInt8PtrTy));
7325ffd83dbSDimitry Andric }
7335ffd83dbSDimitry Andric 
7345ffd83dbSDimitry Andric static void AddRelativeLayoutOffset(const CodeGenModule &CGM,
7355ffd83dbSDimitry Andric                                     ConstantArrayBuilder &builder,
7365ffd83dbSDimitry Andric                                     CharUnits offset) {
7375ffd83dbSDimitry Andric   builder.add(llvm::ConstantInt::get(CGM.Int32Ty, offset.getQuantity()));
7385ffd83dbSDimitry Andric }
7395ffd83dbSDimitry Andric 
7405ffd83dbSDimitry Andric void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
7415ffd83dbSDimitry Andric                                         const VTableLayout &layout,
7425ffd83dbSDimitry Andric                                         unsigned componentIndex,
7435ffd83dbSDimitry Andric                                         llvm::Constant *rtti,
7445ffd83dbSDimitry Andric                                         unsigned &nextVTableThunkIndex,
7455ffd83dbSDimitry Andric                                         unsigned vtableAddressPoint,
7465ffd83dbSDimitry Andric                                         bool vtableHasLocalLinkage) {
7475ffd83dbSDimitry Andric   auto &component = layout.vtable_components()[componentIndex];
7485ffd83dbSDimitry Andric 
7495ffd83dbSDimitry Andric   auto addOffsetConstant =
7505ffd83dbSDimitry Andric       useRelativeLayout() ? AddRelativeLayoutOffset : AddPointerLayoutOffset;
7510b57cec5SDimitry Andric 
7520b57cec5SDimitry Andric   switch (component.getKind()) {
7530b57cec5SDimitry Andric   case VTableComponent::CK_VCallOffset:
7545ffd83dbSDimitry Andric     return addOffsetConstant(CGM, builder, component.getVCallOffset());
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   case VTableComponent::CK_VBaseOffset:
7575ffd83dbSDimitry Andric     return addOffsetConstant(CGM, builder, component.getVBaseOffset());
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   case VTableComponent::CK_OffsetToTop:
7605ffd83dbSDimitry Andric     return addOffsetConstant(CGM, builder, component.getOffsetToTop());
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   case VTableComponent::CK_RTTI:
7635ffd83dbSDimitry Andric     if (useRelativeLayout())
7645ffd83dbSDimitry Andric       return addRelativeComponent(builder, rtti, vtableAddressPoint,
7655ffd83dbSDimitry Andric                                   vtableHasLocalLinkage,
7665ffd83dbSDimitry Andric                                   /*isCompleteDtor=*/false);
7675ffd83dbSDimitry Andric     else
76806c3fb27SDimitry Andric       return builder.add(rtti);
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric   case VTableComponent::CK_FunctionPointer:
7710b57cec5SDimitry Andric   case VTableComponent::CK_CompleteDtorPointer:
7720b57cec5SDimitry Andric   case VTableComponent::CK_DeletingDtorPointer: {
773fe6060f1SDimitry Andric     GlobalDecl GD = component.getGlobalDecl();
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric     if (CGM.getLangOpts().CUDA) {
7760b57cec5SDimitry Andric       // Emit NULL for methods we can't codegen on this
7770b57cec5SDimitry Andric       // side. Otherwise we'd end up with vtable with unresolved
7780b57cec5SDimitry Andric       // references.
7790b57cec5SDimitry Andric       const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
7800b57cec5SDimitry Andric       // OK on device side: functions w/ __device__ attribute
7810b57cec5SDimitry Andric       // OK on host side: anything except __device__-only functions.
7820b57cec5SDimitry Andric       bool CanEmitMethod =
7830b57cec5SDimitry Andric           CGM.getLangOpts().CUDAIsDevice
7840b57cec5SDimitry Andric               ? MD->hasAttr<CUDADeviceAttr>()
7850b57cec5SDimitry Andric               : (MD->hasAttr<CUDAHostAttr>() || !MD->hasAttr<CUDADeviceAttr>());
7860b57cec5SDimitry Andric       if (!CanEmitMethod)
78706c3fb27SDimitry Andric         return builder.add(
78806c3fb27SDimitry Andric             llvm::ConstantExpr::getNullValue(CGM.GlobalsInt8PtrTy));
7890b57cec5SDimitry Andric       // Method is acceptable, continue processing as usual.
7900b57cec5SDimitry Andric     }
7910b57cec5SDimitry Andric 
792480093f4SDimitry Andric     auto getSpecialVirtualFn = [&](StringRef name) -> llvm::Constant * {
7935ffd83dbSDimitry Andric       // FIXME(PR43094): When merging comdat groups, lld can select a local
7945ffd83dbSDimitry Andric       // symbol as the signature symbol even though it cannot be accessed
7955ffd83dbSDimitry Andric       // outside that symbol's TU. The relative vtables ABI would make
7965ffd83dbSDimitry Andric       // __cxa_pure_virtual and __cxa_deleted_virtual local symbols, and
7975ffd83dbSDimitry Andric       // depending on link order, the comdat groups could resolve to the one
7985ffd83dbSDimitry Andric       // with the local symbol. As a temporary solution, fill these components
7995ffd83dbSDimitry Andric       // with zero. We shouldn't be calling these in the first place anyway.
8005ffd83dbSDimitry Andric       if (useRelativeLayout())
80106c3fb27SDimitry Andric         return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy);
8025ffd83dbSDimitry Andric 
803480093f4SDimitry Andric       // For NVPTX devices in OpenMP emit special functon as null pointers,
804480093f4SDimitry Andric       // otherwise linking ends up with unresolved references.
80506c3fb27SDimitry Andric       if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPIsTargetDevice &&
806480093f4SDimitry Andric           CGM.getTriple().isNVPTX())
80706c3fb27SDimitry Andric         return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy);
8080b57cec5SDimitry Andric       llvm::FunctionType *fnTy =
8090b57cec5SDimitry Andric           llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
8100b57cec5SDimitry Andric       llvm::Constant *fn = cast<llvm::Constant>(
8110b57cec5SDimitry Andric           CGM.CreateRuntimeFunction(fnTy, name).getCallee());
8120b57cec5SDimitry Andric       if (auto f = dyn_cast<llvm::Function>(fn))
8130b57cec5SDimitry Andric         f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
81406c3fb27SDimitry Andric       return fn;
8150b57cec5SDimitry Andric     };
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric     llvm::Constant *fnPtr;
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric     // Pure virtual member functions.
8207a6dacacSDimitry Andric     if (cast<CXXMethodDecl>(GD.getDecl())->isPureVirtual()) {
8210b57cec5SDimitry Andric       if (!PureVirtualFn)
8220b57cec5SDimitry Andric         PureVirtualFn =
8230b57cec5SDimitry Andric             getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
8240b57cec5SDimitry Andric       fnPtr = PureVirtualFn;
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric     // Deleted virtual member functions.
8270b57cec5SDimitry Andric     } else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
8280b57cec5SDimitry Andric       if (!DeletedVirtualFn)
8290b57cec5SDimitry Andric         DeletedVirtualFn =
8300b57cec5SDimitry Andric             getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName());
8310b57cec5SDimitry Andric       fnPtr = DeletedVirtualFn;
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric     // Thunks.
8340b57cec5SDimitry Andric     } else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
8355ffd83dbSDimitry Andric                layout.vtable_thunks()[nextVTableThunkIndex].first ==
8365ffd83dbSDimitry Andric                    componentIndex) {
8370b57cec5SDimitry Andric       auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;
8380b57cec5SDimitry Andric 
8390b57cec5SDimitry Andric       nextVTableThunkIndex++;
8400b57cec5SDimitry Andric       fnPtr = maybeEmitThunk(GD, thunkInfo, /*ForVTable=*/true);
8410fca6ea1SDimitry Andric       if (CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers) {
8420fca6ea1SDimitry Andric         assert(thunkInfo.Method &&  "Method not set");
8430fca6ea1SDimitry Andric         GD = GD.getWithDecl(thunkInfo.Method);
8440fca6ea1SDimitry Andric       }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric     // Otherwise we can use the method definition directly.
8470b57cec5SDimitry Andric     } else {
8480b57cec5SDimitry Andric       llvm::Type *fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
8490b57cec5SDimitry Andric       fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true);
8500fca6ea1SDimitry Andric       if (CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers)
8510fca6ea1SDimitry Andric         GD = getItaniumVTableContext().findOriginalMethod(GD);
8520b57cec5SDimitry Andric     }
8530b57cec5SDimitry Andric 
8545ffd83dbSDimitry Andric     if (useRelativeLayout()) {
8555ffd83dbSDimitry Andric       return addRelativeComponent(
8565ffd83dbSDimitry Andric           builder, fnPtr, vtableAddressPoint, vtableHasLocalLinkage,
8575ffd83dbSDimitry Andric           component.getKind() == VTableComponent::CK_CompleteDtorPointer);
85806c3fb27SDimitry Andric     } else {
85906c3fb27SDimitry Andric       // TODO: this icky and only exists due to functions being in the generic
86006c3fb27SDimitry Andric       //       address space, rather than the global one, even though they are
86106c3fb27SDimitry Andric       //       globals;  fixing said issue might be intrusive, and will be done
86206c3fb27SDimitry Andric       //       later.
86306c3fb27SDimitry Andric       unsigned FnAS = fnPtr->getType()->getPointerAddressSpace();
86406c3fb27SDimitry Andric       unsigned GVAS = CGM.GlobalsInt8PtrTy->getPointerAddressSpace();
86506c3fb27SDimitry Andric 
86606c3fb27SDimitry Andric       if (FnAS != GVAS)
86706c3fb27SDimitry Andric         fnPtr =
86806c3fb27SDimitry Andric             llvm::ConstantExpr::getAddrSpaceCast(fnPtr, CGM.GlobalsInt8PtrTy);
8690fca6ea1SDimitry Andric       if (const auto &Schema =
8700fca6ea1SDimitry Andric           CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers)
8710fca6ea1SDimitry Andric         return builder.addSignedPointer(fnPtr, Schema, GD, QualType());
87206c3fb27SDimitry Andric       return builder.add(fnPtr);
87306c3fb27SDimitry Andric     }
8740b57cec5SDimitry Andric   }
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric   case VTableComponent::CK_UnusedFunctionPointer:
8775ffd83dbSDimitry Andric     if (useRelativeLayout())
8785ffd83dbSDimitry Andric       return builder.add(llvm::ConstantExpr::getNullValue(CGM.Int32Ty));
8795ffd83dbSDimitry Andric     else
88006c3fb27SDimitry Andric       return builder.addNullPointer(CGM.GlobalsInt8PtrTy);
8810b57cec5SDimitry Andric   }
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric   llvm_unreachable("Unexpected vtable component kind");
8840b57cec5SDimitry Andric }
8850b57cec5SDimitry Andric 
8860b57cec5SDimitry Andric llvm::Type *CodeGenVTables::getVTableType(const VTableLayout &layout) {
8870b57cec5SDimitry Andric   SmallVector<llvm::Type *, 4> tys;
8885ffd83dbSDimitry Andric   llvm::Type *componentType = getVTableComponentType();
8895ffd83dbSDimitry Andric   for (unsigned i = 0, e = layout.getNumVTables(); i != e; ++i)
8905ffd83dbSDimitry Andric     tys.push_back(llvm::ArrayType::get(componentType, layout.getVTableSize(i)));
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric   return llvm::StructType::get(CGM.getLLVMContext(), tys);
8930b57cec5SDimitry Andric }
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric void CodeGenVTables::createVTableInitializer(ConstantStructBuilder &builder,
8960b57cec5SDimitry Andric                                              const VTableLayout &layout,
8975ffd83dbSDimitry Andric                                              llvm::Constant *rtti,
8985ffd83dbSDimitry Andric                                              bool vtableHasLocalLinkage) {
8995ffd83dbSDimitry Andric   llvm::Type *componentType = getVTableComponentType();
9005ffd83dbSDimitry Andric 
9015ffd83dbSDimitry Andric   const auto &addressPoints = layout.getAddressPointIndices();
9020b57cec5SDimitry Andric   unsigned nextVTableThunkIndex = 0;
9035ffd83dbSDimitry Andric   for (unsigned vtableIndex = 0, endIndex = layout.getNumVTables();
9045ffd83dbSDimitry Andric        vtableIndex != endIndex; ++vtableIndex) {
9055ffd83dbSDimitry Andric     auto vtableElem = builder.beginArray(componentType);
9065ffd83dbSDimitry Andric 
9075ffd83dbSDimitry Andric     size_t vtableStart = layout.getVTableOffset(vtableIndex);
9085ffd83dbSDimitry Andric     size_t vtableEnd = vtableStart + layout.getVTableSize(vtableIndex);
9095ffd83dbSDimitry Andric     for (size_t componentIndex = vtableStart; componentIndex < vtableEnd;
9105ffd83dbSDimitry Andric          ++componentIndex) {
9115ffd83dbSDimitry Andric       addVTableComponent(vtableElem, layout, componentIndex, rtti,
9125ffd83dbSDimitry Andric                          nextVTableThunkIndex, addressPoints[vtableIndex],
9135ffd83dbSDimitry Andric                          vtableHasLocalLinkage);
9140b57cec5SDimitry Andric     }
9150b57cec5SDimitry Andric     vtableElem.finishAndAddTo(builder);
9160b57cec5SDimitry Andric   }
9170b57cec5SDimitry Andric }
9180b57cec5SDimitry Andric 
9195ffd83dbSDimitry Andric llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable(
9205ffd83dbSDimitry Andric     const CXXRecordDecl *RD, const BaseSubobject &Base, bool BaseIsVirtual,
9210b57cec5SDimitry Andric     llvm::GlobalVariable::LinkageTypes Linkage,
9220b57cec5SDimitry Andric     VTableAddressPointsMapTy &AddressPoints) {
9230b57cec5SDimitry Andric   if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
9240b57cec5SDimitry Andric     DI->completeClassData(Base.getBase());
9250b57cec5SDimitry Andric 
9260b57cec5SDimitry Andric   std::unique_ptr<VTableLayout> VTLayout(
9270b57cec5SDimitry Andric       getItaniumVTableContext().createConstructionVTableLayout(
9280b57cec5SDimitry Andric           Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric   // Add the address points.
9310b57cec5SDimitry Andric   AddressPoints = VTLayout->getAddressPoints();
9320b57cec5SDimitry Andric 
9330b57cec5SDimitry Andric   // Get the mangled construction vtable name.
9340b57cec5SDimitry Andric   SmallString<256> OutName;
9350b57cec5SDimitry Andric   llvm::raw_svector_ostream Out(OutName);
9360b57cec5SDimitry Andric   cast<ItaniumMangleContext>(CGM.getCXXABI().getMangleContext())
9370b57cec5SDimitry Andric       .mangleCXXCtorVTable(RD, Base.getBaseOffset().getQuantity(),
9380b57cec5SDimitry Andric                            Base.getBase(), Out);
9395ffd83dbSDimitry Andric   SmallString<256> Name(OutName);
9405ffd83dbSDimitry Andric 
9415ffd83dbSDimitry Andric   bool UsingRelativeLayout = getItaniumVTableContext().isRelativeLayout();
9425ffd83dbSDimitry Andric   bool VTableAliasExists =
9435ffd83dbSDimitry Andric       UsingRelativeLayout && CGM.getModule().getNamedAlias(Name);
9445ffd83dbSDimitry Andric   if (VTableAliasExists) {
9455ffd83dbSDimitry Andric     // We previously made the vtable hidden and changed its name.
9465ffd83dbSDimitry Andric     Name.append(".local");
9475ffd83dbSDimitry Andric   }
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric   llvm::Type *VTType = getVTableType(*VTLayout);
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric   // Construction vtable symbols are not part of the Itanium ABI, so we cannot
9520b57cec5SDimitry Andric   // guarantee that they actually will be available externally. Instead, when
9530b57cec5SDimitry Andric   // emitting an available_externally VTT, we provide references to an internal
9540b57cec5SDimitry Andric   // linkage construction vtable. The ABI only requires complete-object vtables
9550b57cec5SDimitry Andric   // to be the same for all instances of a type, not construction vtables.
9560b57cec5SDimitry Andric   if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
9570b57cec5SDimitry Andric     Linkage = llvm::GlobalVariable::InternalLinkage;
9580b57cec5SDimitry Andric 
959bdd1243dSDimitry Andric   llvm::Align Align = CGM.getDataLayout().getABITypeAlign(VTType);
9600b57cec5SDimitry Andric 
9610b57cec5SDimitry Andric   // Create the variable that will hold the construction vtable.
9620b57cec5SDimitry Andric   llvm::GlobalVariable *VTable =
9630b57cec5SDimitry Andric       CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align);
9640b57cec5SDimitry Andric 
9650b57cec5SDimitry Andric   // V-tables are always unnamed_addr.
9660b57cec5SDimitry Andric   VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric   llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
9690b57cec5SDimitry Andric       CGM.getContext().getTagDeclType(Base.getBase()));
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   // Create and set the initializer.
9720b57cec5SDimitry Andric   ConstantInitBuilder builder(CGM);
9730b57cec5SDimitry Andric   auto components = builder.beginStruct();
9745ffd83dbSDimitry Andric   createVTableInitializer(components, *VTLayout, RTTI,
9755ffd83dbSDimitry Andric                           VTable->hasLocalLinkage());
9760b57cec5SDimitry Andric   components.finishAndSetAsInitializer(VTable);
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   // Set properties only after the initializer has been set to ensure that the
9790b57cec5SDimitry Andric   // GV is treated as definition and not declaration.
9800b57cec5SDimitry Andric   assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration");
9810b57cec5SDimitry Andric   CGM.setGVProperties(VTable, RD);
9820b57cec5SDimitry Andric 
983a7dea167SDimitry Andric   CGM.EmitVTableTypeMetadata(RD, VTable, *VTLayout.get());
9840b57cec5SDimitry Andric 
985bdd1243dSDimitry Andric   if (UsingRelativeLayout) {
986bdd1243dSDimitry Andric     RemoveHwasanMetadata(VTable);
987bdd1243dSDimitry Andric     if (!VTable->isDSOLocal())
9885ffd83dbSDimitry Andric       GenerateRelativeVTableAlias(VTable, OutName);
989bdd1243dSDimitry Andric   }
9905ffd83dbSDimitry Andric 
9910b57cec5SDimitry Andric   return VTable;
9920b57cec5SDimitry Andric }
9930b57cec5SDimitry Andric 
994bdd1243dSDimitry Andric // Ensure this vtable is not instrumented by hwasan. That is, a global alias is
995bdd1243dSDimitry Andric // not generated for it. This is mainly used by the relative-vtables ABI where
996bdd1243dSDimitry Andric // vtables instead contain 32-bit offsets between the vtable and function
997bdd1243dSDimitry Andric // pointers. Hwasan is disabled for these vtables for now because the tag in a
998bdd1243dSDimitry Andric // vtable pointer may fail the overflow check when resolving 32-bit PLT
999bdd1243dSDimitry Andric // relocations. A future alternative for this would be finding which usages of
1000bdd1243dSDimitry Andric // the vtable can continue to use the untagged hwasan value without any loss of
1001bdd1243dSDimitry Andric // value in hwasan.
1002bdd1243dSDimitry Andric void CodeGenVTables::RemoveHwasanMetadata(llvm::GlobalValue *GV) const {
1003bdd1243dSDimitry Andric   if (CGM.getLangOpts().Sanitize.has(SanitizerKind::HWAddress)) {
1004bdd1243dSDimitry Andric     llvm::GlobalValue::SanitizerMetadata Meta;
1005bdd1243dSDimitry Andric     if (GV->hasSanitizerMetadata())
1006bdd1243dSDimitry Andric       Meta = GV->getSanitizerMetadata();
1007bdd1243dSDimitry Andric     Meta.NoHWAddress = true;
1008bdd1243dSDimitry Andric     GV->setSanitizerMetadata(Meta);
1009bdd1243dSDimitry Andric   }
1010bdd1243dSDimitry Andric }
1011bdd1243dSDimitry Andric 
10125ffd83dbSDimitry Andric // If the VTable is not dso_local, then we will not be able to indicate that
10135ffd83dbSDimitry Andric // the VTable does not need a relocation and move into rodata. A frequent
10145ffd83dbSDimitry Andric // time this can occur is for classes that should be made public from a DSO
10155ffd83dbSDimitry Andric // (like in libc++). For cases like these, we can make the vtable hidden or
10165ffd83dbSDimitry Andric // private and create a public alias with the same visibility and linkage as
10175ffd83dbSDimitry Andric // the original vtable type.
10185ffd83dbSDimitry Andric void CodeGenVTables::GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable,
10195ffd83dbSDimitry Andric                                                  llvm::StringRef AliasNameRef) {
10205ffd83dbSDimitry Andric   assert(getItaniumVTableContext().isRelativeLayout() &&
10215ffd83dbSDimitry Andric          "Can only use this if the relative vtable ABI is used");
10225ffd83dbSDimitry Andric   assert(!VTable->isDSOLocal() && "This should be called only if the vtable is "
10235ffd83dbSDimitry Andric                                   "not guaranteed to be dso_local");
10245ffd83dbSDimitry Andric 
10255ffd83dbSDimitry Andric   // If the vtable is available_externally, we shouldn't (or need to) generate
10265ffd83dbSDimitry Andric   // an alias for it in the first place since the vtable won't actually by
10275ffd83dbSDimitry Andric   // emitted in this compilation unit.
10285ffd83dbSDimitry Andric   if (VTable->hasAvailableExternallyLinkage())
10295ffd83dbSDimitry Andric     return;
10305ffd83dbSDimitry Andric 
10315ffd83dbSDimitry Andric   // Create a new string in the event the alias is already the name of the
10325ffd83dbSDimitry Andric   // vtable. Using the reference directly could lead to use of an inititialized
10335ffd83dbSDimitry Andric   // value in the module's StringMap.
10345ffd83dbSDimitry Andric   llvm::SmallString<256> AliasName(AliasNameRef);
10355ffd83dbSDimitry Andric   VTable->setName(AliasName + ".local");
10365ffd83dbSDimitry Andric 
10375ffd83dbSDimitry Andric   auto Linkage = VTable->getLinkage();
10385ffd83dbSDimitry Andric   assert(llvm::GlobalAlias::isValidLinkage(Linkage) &&
10395ffd83dbSDimitry Andric          "Invalid vtable alias linkage");
10405ffd83dbSDimitry Andric 
10415ffd83dbSDimitry Andric   llvm::GlobalAlias *VTableAlias = CGM.getModule().getNamedAlias(AliasName);
10425ffd83dbSDimitry Andric   if (!VTableAlias) {
10435ffd83dbSDimitry Andric     VTableAlias = llvm::GlobalAlias::create(VTable->getValueType(),
10445ffd83dbSDimitry Andric                                             VTable->getAddressSpace(), Linkage,
10455ffd83dbSDimitry Andric                                             AliasName, &CGM.getModule());
10465ffd83dbSDimitry Andric   } else {
10475ffd83dbSDimitry Andric     assert(VTableAlias->getValueType() == VTable->getValueType());
10485ffd83dbSDimitry Andric     assert(VTableAlias->getLinkage() == Linkage);
10495ffd83dbSDimitry Andric   }
10505ffd83dbSDimitry Andric   VTableAlias->setVisibility(VTable->getVisibility());
10515ffd83dbSDimitry Andric   VTableAlias->setUnnamedAddr(VTable->getUnnamedAddr());
10525ffd83dbSDimitry Andric 
10535ffd83dbSDimitry Andric   // Both of these imply dso_local for the vtable.
10545ffd83dbSDimitry Andric   if (!VTable->hasComdat()) {
10555ffd83dbSDimitry Andric     // If this is in a comdat, then we shouldn't make the linkage private due to
10565ffd83dbSDimitry Andric     // an issue in lld where private symbols can be used as the key symbol when
10575ffd83dbSDimitry Andric     // choosing the prevelant group. This leads to "relocation refers to a
10585ffd83dbSDimitry Andric     // symbol in a discarded section".
10595ffd83dbSDimitry Andric     VTable->setLinkage(llvm::GlobalValue::PrivateLinkage);
10605ffd83dbSDimitry Andric   } else {
10615ffd83dbSDimitry Andric     // We should at least make this hidden since we don't want to expose it.
10625ffd83dbSDimitry Andric     VTable->setVisibility(llvm::GlobalValue::HiddenVisibility);
10635ffd83dbSDimitry Andric   }
10645ffd83dbSDimitry Andric 
10655ffd83dbSDimitry Andric   VTableAlias->setAliasee(VTable);
10665ffd83dbSDimitry Andric }
10675ffd83dbSDimitry Andric 
10680b57cec5SDimitry Andric static bool shouldEmitAvailableExternallyVTable(const CodeGenModule &CGM,
10690b57cec5SDimitry Andric                                                 const CXXRecordDecl *RD) {
10700b57cec5SDimitry Andric   return CGM.getCodeGenOpts().OptimizationLevel > 0 &&
10710b57cec5SDimitry Andric          CGM.getCXXABI().canSpeculativelyEmitVTable(RD);
10720b57cec5SDimitry Andric }
10730b57cec5SDimitry Andric 
10740b57cec5SDimitry Andric /// Compute the required linkage of the vtable for the given class.
10750b57cec5SDimitry Andric ///
10760b57cec5SDimitry Andric /// Note that we only call this at the end of the translation unit.
10770b57cec5SDimitry Andric llvm::GlobalVariable::LinkageTypes
10780b57cec5SDimitry Andric CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
10790b57cec5SDimitry Andric   if (!RD->isExternallyVisible())
10800b57cec5SDimitry Andric     return llvm::GlobalVariable::InternalLinkage;
10810b57cec5SDimitry Andric 
1082*62987288SDimitry Andric   // In windows, the linkage of vtable is not related to modules.
1083*62987288SDimitry Andric   bool IsInNamedModule = !getTarget().getCXXABI().isMicrosoft() &&
1084*62987288SDimitry Andric         RD->isInNamedModule();
1085*62987288SDimitry Andric   // If the CXXRecordDecl is not in a module unit, we need to get
1086*62987288SDimitry Andric   // its key function. We're at the end of the translation unit, so the current
1087*62987288SDimitry Andric   // key function is fully correct.
1088*62987288SDimitry Andric   const CXXMethodDecl *keyFunction =
1089*62987288SDimitry Andric       IsInNamedModule ? nullptr : Context.getCurrentKeyFunction(RD);
1090*62987288SDimitry Andric   if (IsInNamedModule || (keyFunction && !RD->hasAttr<DLLImportAttr>())) {
10910b57cec5SDimitry Andric     // If this class has a key function, use that to determine the
10920b57cec5SDimitry Andric     // linkage of the vtable.
10930b57cec5SDimitry Andric     const FunctionDecl *def = nullptr;
1094*62987288SDimitry Andric     if (keyFunction && keyFunction->hasBody(def))
10950b57cec5SDimitry Andric       keyFunction = cast<CXXMethodDecl>(def);
10960b57cec5SDimitry Andric 
1097*62987288SDimitry Andric     bool IsExternalDefinition =
1098*62987288SDimitry Andric         IsInNamedModule ? RD->shouldEmitInExternalSource() : !def;
1099*62987288SDimitry Andric 
1100*62987288SDimitry Andric     TemplateSpecializationKind Kind =
1101*62987288SDimitry Andric         IsInNamedModule ? RD->getTemplateSpecializationKind()
1102*62987288SDimitry Andric                         : keyFunction->getTemplateSpecializationKind();
1103*62987288SDimitry Andric 
1104*62987288SDimitry Andric     switch (Kind) {
11050b57cec5SDimitry Andric     case TSK_Undeclared:
11060b57cec5SDimitry Andric     case TSK_ExplicitSpecialization:
110706c3fb27SDimitry Andric       assert(
1108*62987288SDimitry Andric           (IsInNamedModule || def || CodeGenOpts.OptimizationLevel > 0 ||
110906c3fb27SDimitry Andric            CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo) &&
1110*62987288SDimitry Andric           "Shouldn't query vtable linkage without the class in module units, "
1111*62987288SDimitry Andric           "key function, optimizations, or debug info");
1112*62987288SDimitry Andric       if (IsExternalDefinition && CodeGenOpts.OptimizationLevel > 0)
11130b57cec5SDimitry Andric         return llvm::GlobalVariable::AvailableExternallyLinkage;
11140b57cec5SDimitry Andric 
1115*62987288SDimitry Andric       if (keyFunction && keyFunction->isInlined())
111606c3fb27SDimitry Andric         return !Context.getLangOpts().AppleKext
111706c3fb27SDimitry Andric                    ? llvm::GlobalVariable::LinkOnceODRLinkage
111806c3fb27SDimitry Andric                    : llvm::Function::InternalLinkage;
11190b57cec5SDimitry Andric 
11200b57cec5SDimitry Andric       return llvm::GlobalVariable::ExternalLinkage;
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric       case TSK_ImplicitInstantiation:
11230b57cec5SDimitry Andric         return !Context.getLangOpts().AppleKext ?
11240b57cec5SDimitry Andric                  llvm::GlobalVariable::LinkOnceODRLinkage :
11250b57cec5SDimitry Andric                  llvm::Function::InternalLinkage;
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric       case TSK_ExplicitInstantiationDefinition:
11280b57cec5SDimitry Andric         return !Context.getLangOpts().AppleKext ?
11290b57cec5SDimitry Andric                  llvm::GlobalVariable::WeakODRLinkage :
11300b57cec5SDimitry Andric                  llvm::Function::InternalLinkage;
11310b57cec5SDimitry Andric 
11320b57cec5SDimitry Andric       case TSK_ExplicitInstantiationDeclaration:
11330b57cec5SDimitry Andric         llvm_unreachable("Should not have been asked to emit this");
11340b57cec5SDimitry Andric       }
11350b57cec5SDimitry Andric   }
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric   // -fapple-kext mode does not support weak linkage, so we must use
11380b57cec5SDimitry Andric   // internal linkage.
11390b57cec5SDimitry Andric   if (Context.getLangOpts().AppleKext)
11400b57cec5SDimitry Andric     return llvm::Function::InternalLinkage;
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric   llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
11430b57cec5SDimitry Andric       llvm::GlobalValue::LinkOnceODRLinkage;
11440b57cec5SDimitry Andric   llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
11450b57cec5SDimitry Andric       llvm::GlobalValue::WeakODRLinkage;
11460b57cec5SDimitry Andric   if (RD->hasAttr<DLLExportAttr>()) {
11470b57cec5SDimitry Andric     // Cannot discard exported vtables.
11480b57cec5SDimitry Andric     DiscardableODRLinkage = NonDiscardableODRLinkage;
11490b57cec5SDimitry Andric   } else if (RD->hasAttr<DLLImportAttr>()) {
11500b57cec5SDimitry Andric     // Imported vtables are available externally.
11510b57cec5SDimitry Andric     DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
11520b57cec5SDimitry Andric     NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
11530b57cec5SDimitry Andric   }
11540b57cec5SDimitry Andric 
11550b57cec5SDimitry Andric   switch (RD->getTemplateSpecializationKind()) {
11560b57cec5SDimitry Andric     case TSK_Undeclared:
11570b57cec5SDimitry Andric     case TSK_ExplicitSpecialization:
11580b57cec5SDimitry Andric     case TSK_ImplicitInstantiation:
11590b57cec5SDimitry Andric       return DiscardableODRLinkage;
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDeclaration:
11620b57cec5SDimitry Andric       // Explicit instantiations in MSVC do not provide vtables, so we must emit
11630b57cec5SDimitry Andric       // our own.
11640b57cec5SDimitry Andric       if (getTarget().getCXXABI().isMicrosoft())
11650b57cec5SDimitry Andric         return DiscardableODRLinkage;
11660b57cec5SDimitry Andric       return shouldEmitAvailableExternallyVTable(*this, RD)
11670b57cec5SDimitry Andric                  ? llvm::GlobalVariable::AvailableExternallyLinkage
11680b57cec5SDimitry Andric                  : llvm::GlobalVariable::ExternalLinkage;
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDefinition:
11710b57cec5SDimitry Andric       return NonDiscardableODRLinkage;
11720b57cec5SDimitry Andric   }
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateSpecializationKind!");
11750b57cec5SDimitry Andric }
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric /// This is a callback from Sema to tell us that a particular vtable is
11780b57cec5SDimitry Andric /// required to be emitted in this translation unit.
11790b57cec5SDimitry Andric ///
11800b57cec5SDimitry Andric /// This is only called for vtables that _must_ be emitted (mainly due to key
11810b57cec5SDimitry Andric /// functions).  For weak vtables, CodeGen tracks when they are needed and
11820b57cec5SDimitry Andric /// emits them as-needed.
11830b57cec5SDimitry Andric void CodeGenModule::EmitVTable(CXXRecordDecl *theClass) {
11840b57cec5SDimitry Andric   VTables.GenerateClassData(theClass);
11850b57cec5SDimitry Andric }
11860b57cec5SDimitry Andric 
11870b57cec5SDimitry Andric void
11880b57cec5SDimitry Andric CodeGenVTables::GenerateClassData(const CXXRecordDecl *RD) {
11890b57cec5SDimitry Andric   if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
11900b57cec5SDimitry Andric     DI->completeClassData(RD);
11910b57cec5SDimitry Andric 
11920b57cec5SDimitry Andric   if (RD->getNumVBases())
11930b57cec5SDimitry Andric     CGM.getCXXABI().emitVirtualInheritanceTables(RD);
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric   CGM.getCXXABI().emitVTableDefinitions(*this, RD);
11960b57cec5SDimitry Andric }
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric /// At this point in the translation unit, does it appear that can we
11990b57cec5SDimitry Andric /// rely on the vtable being defined elsewhere in the program?
12000b57cec5SDimitry Andric ///
12010b57cec5SDimitry Andric /// The response is really only definitive when called at the end of
12020b57cec5SDimitry Andric /// the translation unit.
12030b57cec5SDimitry Andric ///
12040b57cec5SDimitry Andric /// The only semantic restriction here is that the object file should
12050b57cec5SDimitry Andric /// not contain a vtable definition when that vtable is defined
12060b57cec5SDimitry Andric /// strongly elsewhere.  Otherwise, we'd just like to avoid emitting
12070b57cec5SDimitry Andric /// vtables when unnecessary.
12080b57cec5SDimitry Andric bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
12090b57cec5SDimitry Andric   assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric   // We always synthesize vtables if they are needed in the MS ABI. MSVC doesn't
12120b57cec5SDimitry Andric   // emit them even if there is an explicit template instantiation.
12130b57cec5SDimitry Andric   if (CGM.getTarget().getCXXABI().isMicrosoft())
12140b57cec5SDimitry Andric     return false;
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric   // If we have an explicit instantiation declaration (and not a
12170b57cec5SDimitry Andric   // definition), the vtable is defined elsewhere.
12180b57cec5SDimitry Andric   TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
12190b57cec5SDimitry Andric   if (TSK == TSK_ExplicitInstantiationDeclaration)
12200b57cec5SDimitry Andric     return true;
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric   // Otherwise, if the class is an instantiated template, the
12230b57cec5SDimitry Andric   // vtable must be defined here.
12240b57cec5SDimitry Andric   if (TSK == TSK_ImplicitInstantiation ||
12250b57cec5SDimitry Andric       TSK == TSK_ExplicitInstantiationDefinition)
12260b57cec5SDimitry Andric     return false;
12270b57cec5SDimitry Andric 
1228*62987288SDimitry Andric   // Otherwise, if the class is attached to a module, the tables are uniquely
1229*62987288SDimitry Andric   // emitted in the object for the module unit in which it is defined.
1230*62987288SDimitry Andric   if (RD->isInNamedModule())
1231*62987288SDimitry Andric     return RD->shouldEmitInExternalSource();
1232*62987288SDimitry Andric 
12330b57cec5SDimitry Andric   // Otherwise, if the class doesn't have a key function (possibly
12340b57cec5SDimitry Andric   // anymore), the vtable must be defined here.
12350b57cec5SDimitry Andric   const CXXMethodDecl *keyFunction = CGM.getContext().getCurrentKeyFunction(RD);
12360b57cec5SDimitry Andric   if (!keyFunction)
12370b57cec5SDimitry Andric     return false;
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric   // Otherwise, if we don't have a definition of the key function, the
12400b57cec5SDimitry Andric   // vtable must be defined somewhere else.
1241*62987288SDimitry Andric   return !keyFunction->hasBody();
12420b57cec5SDimitry Andric }
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric /// Given that we're currently at the end of the translation unit, and
12450b57cec5SDimitry Andric /// we've emitted a reference to the vtable for this class, should
12460b57cec5SDimitry Andric /// we define that vtable?
12470b57cec5SDimitry Andric static bool shouldEmitVTableAtEndOfTranslationUnit(CodeGenModule &CGM,
12480b57cec5SDimitry Andric                                                    const CXXRecordDecl *RD) {
12490b57cec5SDimitry Andric   // If vtable is internal then it has to be done.
12500b57cec5SDimitry Andric   if (!CGM.getVTables().isVTableExternal(RD))
12510b57cec5SDimitry Andric     return true;
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric   // If it's external then maybe we will need it as available_externally.
12540b57cec5SDimitry Andric   return shouldEmitAvailableExternallyVTable(CGM, RD);
12550b57cec5SDimitry Andric }
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric /// Given that at some point we emitted a reference to one or more
12580b57cec5SDimitry Andric /// vtables, and that we are now at the end of the translation unit,
12590b57cec5SDimitry Andric /// decide whether we should emit them.
12600b57cec5SDimitry Andric void CodeGenModule::EmitDeferredVTables() {
12610b57cec5SDimitry Andric #ifndef NDEBUG
12620b57cec5SDimitry Andric   // Remember the size of DeferredVTables, because we're going to assume
12630b57cec5SDimitry Andric   // that this entire operation doesn't modify it.
12640b57cec5SDimitry Andric   size_t savedSize = DeferredVTables.size();
12650b57cec5SDimitry Andric #endif
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric   for (const CXXRecordDecl *RD : DeferredVTables)
12680b57cec5SDimitry Andric     if (shouldEmitVTableAtEndOfTranslationUnit(*this, RD))
12690b57cec5SDimitry Andric       VTables.GenerateClassData(RD);
12700b57cec5SDimitry Andric     else if (shouldOpportunisticallyEmitVTables())
12710b57cec5SDimitry Andric       OpportunisticVTables.push_back(RD);
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric   assert(savedSize == DeferredVTables.size() &&
12740b57cec5SDimitry Andric          "deferred extra vtables during vtable emission?");
12750b57cec5SDimitry Andric   DeferredVTables.clear();
12760b57cec5SDimitry Andric }
12770b57cec5SDimitry Andric 
127881ad6265SDimitry Andric bool CodeGenModule::AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD) {
127906c3fb27SDimitry Andric   if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>() ||
128006c3fb27SDimitry Andric       RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
128181ad6265SDimitry Andric     return true;
128281ad6265SDimitry Andric 
12835ffd83dbSDimitry Andric   if (!getCodeGenOpts().LTOVisibilityPublicStd)
12845ffd83dbSDimitry Andric     return false;
12855ffd83dbSDimitry Andric 
12865ffd83dbSDimitry Andric   const DeclContext *DC = RD;
128704eeddc0SDimitry Andric   while (true) {
12885ffd83dbSDimitry Andric     auto *D = cast<Decl>(DC);
12895ffd83dbSDimitry Andric     DC = DC->getParent();
12905ffd83dbSDimitry Andric     if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
12915ffd83dbSDimitry Andric       if (auto *ND = dyn_cast<NamespaceDecl>(D))
12925ffd83dbSDimitry Andric         if (const IdentifierInfo *II = ND->getIdentifier())
12935ffd83dbSDimitry Andric           if (II->isStr("std") || II->isStr("stdext"))
12945ffd83dbSDimitry Andric             return true;
12955ffd83dbSDimitry Andric       break;
12965ffd83dbSDimitry Andric     }
12975ffd83dbSDimitry Andric   }
12985ffd83dbSDimitry Andric 
12995ffd83dbSDimitry Andric   return false;
13005ffd83dbSDimitry Andric }
13015ffd83dbSDimitry Andric 
13020b57cec5SDimitry Andric bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
13030b57cec5SDimitry Andric   LinkageInfo LV = RD->getLinkageAndVisibility();
13040b57cec5SDimitry Andric   if (!isExternallyVisible(LV.getLinkage()))
13050b57cec5SDimitry Andric     return true;
13060b57cec5SDimitry Andric 
130706c3fb27SDimitry Andric   if (!getTriple().isOSBinFormatCOFF() &&
130806c3fb27SDimitry Andric       LV.getVisibility() != HiddenVisibility)
13090b57cec5SDimitry Andric     return false;
13100b57cec5SDimitry Andric 
131181ad6265SDimitry Andric   return !AlwaysHasLTOVisibilityPublic(RD);
13120b57cec5SDimitry Andric }
13130b57cec5SDimitry Andric 
1314e8d8bef9SDimitry Andric llvm::GlobalObject::VCallVisibility CodeGenModule::GetVCallVisibilityLevel(
1315e8d8bef9SDimitry Andric     const CXXRecordDecl *RD, llvm::DenseSet<const CXXRecordDecl *> &Visited) {
1316e8d8bef9SDimitry Andric   // If we have already visited this RD (which means this is a recursive call
1317e8d8bef9SDimitry Andric   // since the initial call should have an empty Visited set), return the max
1318e8d8bef9SDimitry Andric   // visibility. The recursive calls below compute the min between the result
1319e8d8bef9SDimitry Andric   // of the recursive call and the current TypeVis, so returning the max here
1320e8d8bef9SDimitry Andric   // ensures that it will have no effect on the current TypeVis.
1321e8d8bef9SDimitry Andric   if (!Visited.insert(RD).second)
1322e8d8bef9SDimitry Andric     return llvm::GlobalObject::VCallVisibilityTranslationUnit;
1323e8d8bef9SDimitry Andric 
1324a7dea167SDimitry Andric   LinkageInfo LV = RD->getLinkageAndVisibility();
1325a7dea167SDimitry Andric   llvm::GlobalObject::VCallVisibility TypeVis;
1326a7dea167SDimitry Andric   if (!isExternallyVisible(LV.getLinkage()))
1327a7dea167SDimitry Andric     TypeVis = llvm::GlobalObject::VCallVisibilityTranslationUnit;
1328a7dea167SDimitry Andric   else if (HasHiddenLTOVisibility(RD))
1329a7dea167SDimitry Andric     TypeVis = llvm::GlobalObject::VCallVisibilityLinkageUnit;
1330a7dea167SDimitry Andric   else
1331a7dea167SDimitry Andric     TypeVis = llvm::GlobalObject::VCallVisibilityPublic;
1332a7dea167SDimitry Andric 
133306c3fb27SDimitry Andric   for (const auto &B : RD->bases())
1334a7dea167SDimitry Andric     if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1335e8d8bef9SDimitry Andric       TypeVis = std::min(
1336e8d8bef9SDimitry Andric           TypeVis,
1337e8d8bef9SDimitry Andric           GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited));
1338a7dea167SDimitry Andric 
133906c3fb27SDimitry Andric   for (const auto &B : RD->vbases())
1340a7dea167SDimitry Andric     if (B.getType()->getAsCXXRecordDecl()->isDynamicClass())
1341e8d8bef9SDimitry Andric       TypeVis = std::min(
1342e8d8bef9SDimitry Andric           TypeVis,
1343e8d8bef9SDimitry Andric           GetVCallVisibilityLevel(B.getType()->getAsCXXRecordDecl(), Visited));
1344a7dea167SDimitry Andric 
1345a7dea167SDimitry Andric   return TypeVis;
1346a7dea167SDimitry Andric }
1347a7dea167SDimitry Andric 
1348a7dea167SDimitry Andric void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
1349a7dea167SDimitry Andric                                            llvm::GlobalVariable *VTable,
13500b57cec5SDimitry Andric                                            const VTableLayout &VTLayout) {
13515f757f3fSDimitry Andric   // Emit type metadata on vtables with LTO or IR instrumentation.
13525f757f3fSDimitry Andric   // In IR instrumentation, the type metadata is used to find out vtable
13535f757f3fSDimitry Andric   // definitions (for type profiling) among all global variables.
13545f757f3fSDimitry Andric   if (!getCodeGenOpts().LTOUnit && !getCodeGenOpts().hasProfileIRInstr())
13550b57cec5SDimitry Andric     return;
13560b57cec5SDimitry Andric 
1357bdd1243dSDimitry Andric   CharUnits ComponentWidth = GetTargetTypeStoreSize(getVTableComponentType());
13580b57cec5SDimitry Andric 
13595f757f3fSDimitry Andric   struct AddressPoint {
13605f757f3fSDimitry Andric     const CXXRecordDecl *Base;
13615f757f3fSDimitry Andric     size_t Offset;
13625f757f3fSDimitry Andric     std::string TypeName;
13635f757f3fSDimitry Andric     bool operator<(const AddressPoint &RHS) const {
13645f757f3fSDimitry Andric       int D = TypeName.compare(RHS.TypeName);
13655f757f3fSDimitry Andric       return D < 0 || (D == 0 && Offset < RHS.Offset);
13665f757f3fSDimitry Andric     }
13675f757f3fSDimitry Andric   };
13680b57cec5SDimitry Andric   std::vector<AddressPoint> AddressPoints;
13695f757f3fSDimitry Andric   for (auto &&AP : VTLayout.getAddressPoints()) {
13705f757f3fSDimitry Andric     AddressPoint N{AP.first.getBase(),
13715f757f3fSDimitry Andric                    VTLayout.getVTableOffset(AP.second.VTableIndex) +
13725f757f3fSDimitry Andric                        AP.second.AddressPointIndex,
13735f757f3fSDimitry Andric                    {}};
13745f757f3fSDimitry Andric     llvm::raw_string_ostream Stream(N.TypeName);
13755f757f3fSDimitry Andric     getCXXABI().getMangleContext().mangleCanonicalTypeName(
13765f757f3fSDimitry Andric         QualType(N.Base->getTypeForDecl(), 0), Stream);
13775f757f3fSDimitry Andric     AddressPoints.push_back(std::move(N));
13785f757f3fSDimitry Andric   }
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric   // Sort the address points for determinism.
13815f757f3fSDimitry Andric   llvm::sort(AddressPoints);
13820b57cec5SDimitry Andric 
13830b57cec5SDimitry Andric   ArrayRef<VTableComponent> Comps = VTLayout.vtable_components();
13840b57cec5SDimitry Andric   for (auto AP : AddressPoints) {
13850b57cec5SDimitry Andric     // Create type metadata for the address point.
13865f757f3fSDimitry Andric     AddVTableTypeMetadata(VTable, ComponentWidth * AP.Offset, AP.Base);
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric     // The class associated with each address point could also potentially be
13890b57cec5SDimitry Andric     // used for indirect calls via a member function pointer, so we need to
13900b57cec5SDimitry Andric     // annotate the address of each function pointer with the appropriate member
13910b57cec5SDimitry Andric     // function pointer type.
13920b57cec5SDimitry Andric     for (unsigned I = 0; I != Comps.size(); ++I) {
13930b57cec5SDimitry Andric       if (Comps[I].getKind() != VTableComponent::CK_FunctionPointer)
13940b57cec5SDimitry Andric         continue;
13950b57cec5SDimitry Andric       llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
13960b57cec5SDimitry Andric           Context.getMemberPointerType(
13970b57cec5SDimitry Andric               Comps[I].getFunctionDecl()->getType(),
13985f757f3fSDimitry Andric               Context.getRecordType(AP.Base).getTypePtr()));
1399bdd1243dSDimitry Andric       VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD);
14000b57cec5SDimitry Andric     }
14010b57cec5SDimitry Andric   }
1402a7dea167SDimitry Andric 
14035ffd83dbSDimitry Andric   if (getCodeGenOpts().VirtualFunctionElimination ||
14045ffd83dbSDimitry Andric       getCodeGenOpts().WholeProgramVTables) {
1405e8d8bef9SDimitry Andric     llvm::DenseSet<const CXXRecordDecl *> Visited;
1406e8d8bef9SDimitry Andric     llvm::GlobalObject::VCallVisibility TypeVis =
1407e8d8bef9SDimitry Andric         GetVCallVisibilityLevel(RD, Visited);
1408a7dea167SDimitry Andric     if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
14095ffd83dbSDimitry Andric       VTable->setVCallVisibilityMetadata(TypeVis);
1410a7dea167SDimitry Andric   }
14110b57cec5SDimitry Andric }
1412