Path: blob/main/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp
35233 views
//===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This contains code dealing with code generation of C++ declarations9//10//===----------------------------------------------------------------------===//1112#include "CGCXXABI.h"13#include "CGHLSLRuntime.h"14#include "CGObjCRuntime.h"15#include "CGOpenMPRuntime.h"16#include "CodeGenFunction.h"17#include "TargetInfo.h"18#include "clang/AST/Attr.h"19#include "clang/Basic/LangOptions.h"20#include "llvm/ADT/StringExtras.h"21#include "llvm/IR/Intrinsics.h"22#include "llvm/IR/MDBuilder.h"23#include "llvm/Support/Path.h"2425using namespace clang;26using namespace CodeGen;2728static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,29ConstantAddress DeclPtr) {30assert(31(D.hasGlobalStorage() ||32(D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) &&33"VarDecl must have global or local (in the case of OpenCL) storage!");34assert(!D.getType()->isReferenceType() &&35"Should not call EmitDeclInit on a reference!");3637QualType type = D.getType();38LValue lv = CGF.MakeAddrLValue(DeclPtr, type);3940const Expr *Init = D.getInit();41switch (CGF.getEvaluationKind(type)) {42case TEK_Scalar: {43CodeGenModule &CGM = CGF.CGM;44if (lv.isObjCStrong())45CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init),46DeclPtr, D.getTLSKind());47else if (lv.isObjCWeak())48CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init),49DeclPtr);50else51CGF.EmitScalarInit(Init, &D, lv, false);52return;53}54case TEK_Complex:55CGF.EmitComplexExprIntoLValue(Init, lv, /*isInit*/ true);56return;57case TEK_Aggregate:58CGF.EmitAggExpr(Init,59AggValueSlot::forLValue(lv, AggValueSlot::IsDestructed,60AggValueSlot::DoesNotNeedGCBarriers,61AggValueSlot::IsNotAliased,62AggValueSlot::DoesNotOverlap));63return;64}65llvm_unreachable("bad evaluation kind");66}6768/// Emit code to cause the destruction of the given variable with69/// static storage duration.70static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,71ConstantAddress Addr) {72// Honor __attribute__((no_destroy)) and bail instead of attempting73// to emit a reference to a possibly nonexistent destructor, which74// in turn can cause a crash. This will result in a global constructor75// that isn't balanced out by a destructor call as intended by the76// attribute. This also checks for -fno-c++-static-destructors and77// bails even if the attribute is not present.78QualType::DestructionKind DtorKind = D.needsDestruction(CGF.getContext());7980// FIXME: __attribute__((cleanup)) ?8182switch (DtorKind) {83case QualType::DK_none:84return;8586case QualType::DK_cxx_destructor:87break;8889case QualType::DK_objc_strong_lifetime:90case QualType::DK_objc_weak_lifetime:91case QualType::DK_nontrivial_c_struct:92// We don't care about releasing objects during process teardown.93assert(!D.getTLSKind() && "should have rejected this");94return;95}9697llvm::FunctionCallee Func;98llvm::Constant *Argument;99100CodeGenModule &CGM = CGF.CGM;101QualType Type = D.getType();102103// Special-case non-array C++ destructors, if they have the right signature.104// Under some ABIs, destructors return this instead of void, and cannot be105// passed directly to __cxa_atexit if the target does not allow this106// mismatch.107const CXXRecordDecl *Record = Type->getAsCXXRecordDecl();108bool CanRegisterDestructor =109Record && (!CGM.getCXXABI().HasThisReturn(110GlobalDecl(Record->getDestructor(), Dtor_Complete)) ||111CGM.getCXXABI().canCallMismatchedFunctionType());112// If __cxa_atexit is disabled via a flag, a different helper function is113// generated elsewhere which uses atexit instead, and it takes the destructor114// directly.115bool UsingExternalHelper = !CGM.getCodeGenOpts().CXAAtExit;116if (Record && (CanRegisterDestructor || UsingExternalHelper)) {117assert(!Record->hasTrivialDestructor());118CXXDestructorDecl *Dtor = Record->getDestructor();119120Func = CGM.getAddrAndTypeOfCXXStructor(GlobalDecl(Dtor, Dtor_Complete));121if (CGF.getContext().getLangOpts().OpenCL) {122auto DestAS =123CGM.getTargetCodeGenInfo().getAddrSpaceOfCxaAtexitPtrParam();124auto DestTy = llvm::PointerType::get(125CGM.getLLVMContext(), CGM.getContext().getTargetAddressSpace(DestAS));126auto SrcAS = D.getType().getQualifiers().getAddressSpace();127if (DestAS == SrcAS)128Argument = Addr.getPointer();129else130// FIXME: On addr space mismatch we are passing NULL. The generation131// of the global destructor function should be adjusted accordingly.132Argument = llvm::ConstantPointerNull::get(DestTy);133} else {134Argument = Addr.getPointer();135}136// Otherwise, the standard logic requires a helper function.137} else {138Addr = Addr.withElementType(CGF.ConvertTypeForMem(Type));139Func = CodeGenFunction(CGM)140.generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind),141CGF.needsEHCleanup(DtorKind), &D);142Argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);143}144145CGM.getCXXABI().registerGlobalDtor(CGF, D, Func, Argument);146}147148/// Emit code to cause the variable at the given address to be considered as149/// constant from this point onwards.150static void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D,151llvm::Constant *Addr) {152return CGF.EmitInvariantStart(153Addr, CGF.getContext().getTypeSizeInChars(D.getType()));154}155156void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) {157// Do not emit the intrinsic if we're not optimizing.158if (!CGM.getCodeGenOpts().OptimizationLevel)159return;160161// Grab the llvm.invariant.start intrinsic.162llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;163// Overloaded address space type.164assert(Addr->getType()->isPointerTy() && "Address must be a pointer");165llvm::Type *ObjectPtr[1] = {Addr->getType()};166llvm::Function *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr);167168// Emit a call with the size in bytes of the object.169uint64_t Width = Size.getQuantity();170llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(Int64Ty, Width), Addr};171Builder.CreateCall(InvariantStart, Args);172}173174void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,175llvm::GlobalVariable *GV,176bool PerformInit) {177178const Expr *Init = D.getInit();179QualType T = D.getType();180181// The address space of a static local variable (DeclPtr) may be different182// from the address space of the "this" argument of the constructor. In that183// case, we need an addrspacecast before calling the constructor.184//185// struct StructWithCtor {186// __device__ StructWithCtor() {...}187// };188// __device__ void foo() {189// __shared__ StructWithCtor s;190// ...191// }192//193// For example, in the above CUDA code, the static local variable s has a194// "shared" address space qualifier, but the constructor of StructWithCtor195// expects "this" in the "generic" address space.196unsigned ExpectedAddrSpace = getTypes().getTargetAddressSpace(T);197unsigned ActualAddrSpace = GV->getAddressSpace();198llvm::Constant *DeclPtr = GV;199if (ActualAddrSpace != ExpectedAddrSpace) {200llvm::PointerType *PTy =201llvm::PointerType::get(getLLVMContext(), ExpectedAddrSpace);202DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);203}204205ConstantAddress DeclAddr(206DeclPtr, GV->getValueType(), getContext().getDeclAlign(&D));207208if (!T->isReferenceType()) {209if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd &&210D.hasAttr<OMPThreadPrivateDeclAttr>()) {211(void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(212&D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),213PerformInit, this);214}215bool NeedsDtor =216D.needsDestruction(getContext()) == QualType::DK_cxx_destructor;217if (PerformInit)218EmitDeclInit(*this, D, DeclAddr);219if (D.getType().isConstantStorage(getContext(), true, !NeedsDtor))220EmitDeclInvariant(*this, D, DeclPtr);221else222EmitDeclDestroy(*this, D, DeclAddr);223return;224}225226assert(PerformInit && "cannot have constant initializer which needs "227"destruction for reference");228RValue RV = EmitReferenceBindingToExpr(Init);229EmitStoreOfScalar(RV.getScalarVal(), DeclAddr, false, T);230}231232/// Create a stub function, suitable for being passed to atexit,233/// which passes the given address to the given destructor function.234llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,235llvm::FunctionCallee dtor,236llvm::Constant *addr) {237// Get the destructor function type, void(*)(void).238llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);239SmallString<256> FnName;240{241llvm::raw_svector_ostream Out(FnName);242CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);243}244245const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();246llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(247ty, FnName.str(), FI, VD.getLocation());248249CodeGenFunction CGF(CGM);250251CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit),252CGM.getContext().VoidTy, fn, FI, FunctionArgList(),253VD.getLocation(), VD.getInit()->getExprLoc());254// Emit an artificial location for this function.255auto AL = ApplyDebugLocation::CreateArtificial(CGF);256257llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);258259// Make sure the call and the callee agree on calling convention.260if (auto *dtorFn = dyn_cast<llvm::Function>(261dtor.getCallee()->stripPointerCastsAndAliases()))262call->setCallingConv(dtorFn->getCallingConv());263264CGF.FinishFunction();265266// Get a proper function pointer.267FunctionProtoType::ExtProtoInfo EPI(getContext().getDefaultCallingConvention(268/*IsVariadic=*/false, /*IsCXXMethod=*/false));269QualType fnType = getContext().getFunctionType(getContext().VoidTy,270{getContext().VoidPtrTy}, EPI);271return CGM.getFunctionPointer(fn, fnType);272}273274/// Create a stub function, suitable for being passed to __pt_atexit_np,275/// which passes the given address to the given destructor function.276llvm::Function *CodeGenFunction::createTLSAtExitStub(277const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr,278llvm::FunctionCallee &AtExit) {279SmallString<256> FnName;280{281llvm::raw_svector_ostream Out(FnName);282CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&D, Out);283}284285const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo(286getContext().IntTy, FnInfoOpts::None, {getContext().IntTy},287FunctionType::ExtInfo(), {}, RequiredArgs::All);288289// Get the stub function type, int(*)(int,...).290llvm::FunctionType *StubTy =291llvm::FunctionType::get(CGM.IntTy, {CGM.IntTy}, true);292293llvm::Function *DtorStub = CGM.CreateGlobalInitOrCleanUpFunction(294StubTy, FnName.str(), FI, D.getLocation());295296CodeGenFunction CGF(CGM);297298FunctionArgList Args;299ImplicitParamDecl IPD(CGM.getContext(), CGM.getContext().IntTy,300ImplicitParamKind::Other);301Args.push_back(&IPD);302QualType ResTy = CGM.getContext().IntTy;303304CGF.StartFunction(GlobalDecl(&D, DynamicInitKind::AtExit), ResTy, DtorStub,305FI, Args, D.getLocation(), D.getInit()->getExprLoc());306307// Emit an artificial location for this function.308auto AL = ApplyDebugLocation::CreateArtificial(CGF);309310llvm::CallInst *call = CGF.Builder.CreateCall(Dtor, Addr);311312// Make sure the call and the callee agree on calling convention.313if (auto *DtorFn = dyn_cast<llvm::Function>(314Dtor.getCallee()->stripPointerCastsAndAliases()))315call->setCallingConv(DtorFn->getCallingConv());316317// Return 0 from function318CGF.Builder.CreateStore(llvm::Constant::getNullValue(CGM.IntTy),319CGF.ReturnValue);320321CGF.FinishFunction();322323return DtorStub;324}325326/// Register a global destructor using the C atexit runtime function.327void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD,328llvm::FunctionCallee dtor,329llvm::Constant *addr) {330// Create a function which calls the destructor.331llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr);332registerGlobalDtorWithAtExit(dtorStub);333}334335/// Register a global destructor using the LLVM 'llvm.global_dtors' global.336void CodeGenFunction::registerGlobalDtorWithLLVM(const VarDecl &VD,337llvm::FunctionCallee Dtor,338llvm::Constant *Addr) {339// Create a function which calls the destructor.340llvm::Function *dtorStub =341cast<llvm::Function>(createAtExitStub(VD, Dtor, Addr));342CGM.AddGlobalDtor(dtorStub);343}344345void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtorStub) {346// extern "C" int atexit(void (*f)(void));347assert(dtorStub->getType() ==348llvm::PointerType::get(349llvm::FunctionType::get(CGM.VoidTy, false),350dtorStub->getType()->getPointerAddressSpace()) &&351"Argument to atexit has a wrong type.");352353llvm::FunctionType *atexitTy =354llvm::FunctionType::get(IntTy, dtorStub->getType(), false);355356llvm::FunctionCallee atexit =357CGM.CreateRuntimeFunction(atexitTy, "atexit", llvm::AttributeList(),358/*Local=*/true);359if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))360atexitFn->setDoesNotThrow();361362EmitNounwindRuntimeCall(atexit, dtorStub);363}364365llvm::Value *366CodeGenFunction::unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub) {367// The unatexit subroutine unregisters __dtor functions that were previously368// registered by the atexit subroutine. If the referenced function is found,369// it is removed from the list of functions that are called at normal program370// termination and the unatexit returns a value of 0, otherwise a non-zero371// value is returned.372//373// extern "C" int unatexit(void (*f)(void));374assert(dtorStub->getType() ==375llvm::PointerType::get(376llvm::FunctionType::get(CGM.VoidTy, false),377dtorStub->getType()->getPointerAddressSpace()) &&378"Argument to unatexit has a wrong type.");379380llvm::FunctionType *unatexitTy =381llvm::FunctionType::get(IntTy, {dtorStub->getType()}, /*isVarArg=*/false);382383llvm::FunctionCallee unatexit =384CGM.CreateRuntimeFunction(unatexitTy, "unatexit", llvm::AttributeList());385386cast<llvm::Function>(unatexit.getCallee())->setDoesNotThrow();387388return EmitNounwindRuntimeCall(unatexit, dtorStub);389}390391void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,392llvm::GlobalVariable *DeclPtr,393bool PerformInit) {394// If we've been asked to forbid guard variables, emit an error now.395// This diagnostic is hard-coded for Darwin's use case; we can find396// better phrasing if someone else needs it.397if (CGM.getCodeGenOpts().ForbidGuardVariables)398CGM.Error(D.getLocation(),399"this initialization requires a guard variable, which "400"the kernel does not support");401402CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);403}404405void CodeGenFunction::EmitCXXGuardedInitBranch(llvm::Value *NeedsInit,406llvm::BasicBlock *InitBlock,407llvm::BasicBlock *NoInitBlock,408GuardKind Kind,409const VarDecl *D) {410assert((Kind == GuardKind::TlsGuard || D) && "no guarded variable");411412// A guess at how many times we will enter the initialization of a413// variable, depending on the kind of variable.414static const uint64_t InitsPerTLSVar = 1024;415static const uint64_t InitsPerLocalVar = 1024 * 1024;416417llvm::MDNode *Weights;418if (Kind == GuardKind::VariableGuard && !D->isLocalVarDecl()) {419// For non-local variables, don't apply any weighting for now. Due to our420// use of COMDATs, we expect there to be at most one initialization of the421// variable per DSO, but we have no way to know how many DSOs will try to422// initialize the variable.423Weights = nullptr;424} else {425uint64_t NumInits;426// FIXME: For the TLS case, collect and use profiling information to427// determine a more accurate brach weight.428if (Kind == GuardKind::TlsGuard || D->getTLSKind())429NumInits = InitsPerTLSVar;430else431NumInits = InitsPerLocalVar;432433// The probability of us entering the initializer is434// 1 / (total number of times we attempt to initialize the variable).435llvm::MDBuilder MDHelper(CGM.getLLVMContext());436Weights = MDHelper.createBranchWeights(1, NumInits - 1);437}438439Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);440}441442llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(443llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI,444SourceLocation Loc, bool TLS, llvm::GlobalVariable::LinkageTypes Linkage) {445llvm::Function *Fn = llvm::Function::Create(FTy, Linkage, Name, &getModule());446447if (!getLangOpts().AppleKext && !TLS) {448// Set the section if needed.449if (const char *Section = getTarget().getStaticInitSectionSpecifier())450Fn->setSection(Section);451}452453if (Linkage == llvm::GlobalVariable::InternalLinkage)454SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);455456Fn->setCallingConv(getRuntimeCC());457458if (!getLangOpts().Exceptions)459Fn->setDoesNotThrow();460461if (getLangOpts().Sanitize.has(SanitizerKind::Address) &&462!isInNoSanitizeList(SanitizerKind::Address, Fn, Loc))463Fn->addFnAttr(llvm::Attribute::SanitizeAddress);464465if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&466!isInNoSanitizeList(SanitizerKind::KernelAddress, Fn, Loc))467Fn->addFnAttr(llvm::Attribute::SanitizeAddress);468469if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&470!isInNoSanitizeList(SanitizerKind::HWAddress, Fn, Loc))471Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);472473if (getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&474!isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn, Loc))475Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);476477if (getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&478!isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc))479Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);480481if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&482!isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc))483Fn->addFnAttr(llvm::Attribute::SanitizeThread);484485if (getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) &&486!isInNoSanitizeList(SanitizerKind::NumericalStability, Fn, Loc))487Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);488489if (getLangOpts().Sanitize.has(SanitizerKind::Memory) &&490!isInNoSanitizeList(SanitizerKind::Memory, Fn, Loc))491Fn->addFnAttr(llvm::Attribute::SanitizeMemory);492493if (getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&494!isInNoSanitizeList(SanitizerKind::KernelMemory, Fn, Loc))495Fn->addFnAttr(llvm::Attribute::SanitizeMemory);496497if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&498!isInNoSanitizeList(SanitizerKind::SafeStack, Fn, Loc))499Fn->addFnAttr(llvm::Attribute::SafeStack);500501if (getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&502!isInNoSanitizeList(SanitizerKind::ShadowCallStack, Fn, Loc))503Fn->addFnAttr(llvm::Attribute::ShadowCallStack);504505return Fn;506}507508/// Create a global pointer to a function that will initialize a global509/// variable. The user has requested that this pointer be emitted in a specific510/// section.511void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,512llvm::GlobalVariable *GV,513llvm::Function *InitFunc,514InitSegAttr *ISA) {515llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable(516TheModule, InitFunc->getType(), /*isConstant=*/true,517llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr");518PtrArray->setSection(ISA->getSection());519addUsedGlobal(PtrArray);520521// If the GV is already in a comdat group, then we have to join it.522if (llvm::Comdat *C = GV->getComdat())523PtrArray->setComdat(C);524}525526void527CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,528llvm::GlobalVariable *Addr,529bool PerformInit) {530531// According to E.2.3.1 in CUDA-7.5 Programming guide: __device__,532// __constant__ and __shared__ variables defined in namespace scope,533// that are of class type, cannot have a non-empty constructor. All534// the checks have been done in Sema by now. Whatever initializers535// are allowed are empty and we just need to ignore them here.536if (getLangOpts().CUDAIsDevice && !getLangOpts().GPUAllowDeviceInit &&537(D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() ||538D->hasAttr<CUDASharedAttr>()))539return;540541// Check if we've already initialized this decl.542auto I = DelayedCXXInitPosition.find(D);543if (I != DelayedCXXInitPosition.end() && I->second == ~0U)544return;545546llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);547SmallString<256> FnName;548{549llvm::raw_svector_ostream Out(FnName);550getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);551}552553// Create a variable initialization function.554llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(555FTy, FnName.str(), getTypes().arrangeNullaryFunction(), D->getLocation());556557auto *ISA = D->getAttr<InitSegAttr>();558CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,559PerformInit);560561llvm::GlobalVariable *COMDATKey =562supportsCOMDAT() && D->isExternallyVisible() ? Addr : nullptr;563564if (D->getTLSKind()) {565// FIXME: Should we support init_priority for thread_local?566// FIXME: We only need to register one __cxa_thread_atexit function for the567// entire TU.568CXXThreadLocalInits.push_back(Fn);569CXXThreadLocalInitVars.push_back(D);570} else if (PerformInit && ISA) {571// Contract with backend that "init_seg(compiler)" corresponds to priority572// 200 and "init_seg(lib)" corresponds to priority 400.573int Priority = -1;574if (ISA->getSection() == ".CRT$XCC")575Priority = 200;576else if (ISA->getSection() == ".CRT$XCL")577Priority = 400;578579if (Priority != -1)580AddGlobalCtor(Fn, Priority, ~0U, COMDATKey);581else582EmitPointerToInitFunc(D, Addr, Fn, ISA);583} else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {584OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(),585PrioritizedCXXGlobalInits.size());586PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));587} else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||588getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR ||589D->hasAttr<SelectAnyAttr>()) {590// C++ [basic.start.init]p2:591// Definitions of explicitly specialized class template static data592// members have ordered initialization. Other class template static data593// members (i.e., implicitly or explicitly instantiated specializations)594// have unordered initialization.595//596// As a consequence, we can put them into their own llvm.global_ctors entry.597//598// If the global is externally visible, put the initializer into a COMDAT599// group with the global being initialized. On most platforms, this is a600// minor startup time optimization. In the MS C++ ABI, there are no guard601// variables, so this COMDAT key is required for correctness.602//603// SelectAny globals will be comdat-folded. Put the initializer into a604// COMDAT group associated with the global, so the initializers get folded605// too.606I = DelayedCXXInitPosition.find(D);607// CXXGlobalInits.size() is the lex order number for the next deferred608// VarDecl. Use it when the current VarDecl is non-deferred. Although this609// lex order number is shared between current VarDecl and some following610// VarDecls, their order of insertion into `llvm.global_ctors` is the same611// as the lexing order and the following stable sort would preserve such612// order.613unsigned LexOrder =614I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;615AddGlobalCtor(Fn, 65535, LexOrder, COMDATKey);616if (COMDATKey && (getTriple().isOSBinFormatELF() ||617getTarget().getCXXABI().isMicrosoft())) {618// When COMDAT is used on ELF or in the MS C++ ABI, the key must be in619// llvm.used to prevent linker GC.620addUsedGlobal(COMDATKey);621}622623// If we used a COMDAT key for the global ctor, the init function can be624// discarded if the global ctor entry is discarded.625// FIXME: Do we need to restrict this to ELF and Wasm?626llvm::Comdat *C = Addr->getComdat();627if (COMDATKey && C &&628(getTarget().getTriple().isOSBinFormatELF() ||629getTarget().getTriple().isOSBinFormatWasm())) {630Fn->setComdat(C);631}632} else {633I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash.634if (I == DelayedCXXInitPosition.end()) {635CXXGlobalInits.push_back(Fn);636} else if (I->second != ~0U) {637assert(I->second < CXXGlobalInits.size() &&638CXXGlobalInits[I->second] == nullptr);639CXXGlobalInits[I->second] = Fn;640}641}642643// Remember that we already emitted the initializer for this global.644DelayedCXXInitPosition[D] = ~0U;645}646647void CodeGenModule::EmitCXXThreadLocalInitFunc() {648getCXXABI().EmitThreadLocalInitFuncs(649*this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);650651CXXThreadLocalInits.clear();652CXXThreadLocalInitVars.clear();653CXXThreadLocals.clear();654}655656/* Build the initializer for a C++20 module:657This is arranged to be run only once regardless of how many times the module658might be included transitively. This arranged by using a guard variable.659660If there are no initializers at all (and also no imported modules) we reduce661this to an empty function (since the Itanium ABI requires that this function662be available to a caller, which might be produced by a different663implementation).664665First we call any initializers for imported modules.666We then call initializers for the Global Module Fragment (if present)667We then call initializers for the current module.668We then call initializers for the Private Module Fragment (if present)669*/670671void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {672assert(Primary->isInterfaceOrPartition() &&673"The function should only be called for C++20 named module interface"674" or partition.");675676while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())677CXXGlobalInits.pop_back();678679// As noted above, we create the function, even if it is empty.680// Module initializers for imported modules are emitted first.681682// Collect all the modules that we import683llvm::SmallSetVector<Module *, 8> AllImports;684// Ones that we export685for (auto I : Primary->Exports)686AllImports.insert(I.getPointer());687// Ones that we only import.688for (Module *M : Primary->Imports)689AllImports.insert(M);690// Ones that we import in the global module fragment or the private module691// fragment.692for (Module *SubM : Primary->submodules()) {693assert((SubM->isGlobalModule() || SubM->isPrivateModule()) &&694"The sub modules of C++20 module unit should only be global module "695"fragments or private module framents.");696assert(SubM->Exports.empty() &&697"The global mdoule fragments and the private module fragments are "698"not allowed to export import modules.");699for (Module *M : SubM->Imports)700AllImports.insert(M);701}702703SmallVector<llvm::Function *, 8> ModuleInits;704for (Module *M : AllImports) {705// No Itanium initializer in header like modules.706if (M->isHeaderLikeModule())707continue; // TODO: warn of mixed use of module map modules and C++20?708// We're allowed to skip the initialization if we are sure it doesn't709// do any thing.710if (!M->isNamedModuleInterfaceHasInit())711continue;712llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);713SmallString<256> FnName;714{715llvm::raw_svector_ostream Out(FnName);716cast<ItaniumMangleContext>(getCXXABI().getMangleContext())717.mangleModuleInitializer(M, Out);718}719assert(!GetGlobalValue(FnName.str()) &&720"We should only have one use of the initializer call");721llvm::Function *Fn = llvm::Function::Create(722FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());723ModuleInits.push_back(Fn);724}725726// Add any initializers with specified priority; this uses the same approach727// as EmitCXXGlobalInitFunc().728if (!PrioritizedCXXGlobalInits.empty()) {729SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;730llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),731PrioritizedCXXGlobalInits.end());732for (SmallVectorImpl<GlobalInitData>::iterator733I = PrioritizedCXXGlobalInits.begin(),734E = PrioritizedCXXGlobalInits.end();735I != E;) {736SmallVectorImpl<GlobalInitData>::iterator PrioE =737std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());738739for (; I < PrioE; ++I)740ModuleInits.push_back(I->second);741}742}743744// Now append the ones without specified priority.745for (auto *F : CXXGlobalInits)746ModuleInits.push_back(F);747748llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);749const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();750751// We now build the initializer for this module, which has a mangled name752// as per the Itanium ABI . The action of the initializer is guarded so that753// each init is run just once (even though a module might be imported754// multiple times via nested use).755llvm::Function *Fn;756{757SmallString<256> InitFnName;758llvm::raw_svector_ostream Out(InitFnName);759cast<ItaniumMangleContext>(getCXXABI().getMangleContext())760.mangleModuleInitializer(Primary, Out);761Fn = CreateGlobalInitOrCleanUpFunction(762FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,763llvm::GlobalVariable::ExternalLinkage);764765// If we have a completely empty initializer then we do not want to create766// the guard variable.767ConstantAddress GuardAddr = ConstantAddress::invalid();768if (!ModuleInits.empty()) {769// Create the guard var.770llvm::GlobalVariable *Guard = new llvm::GlobalVariable(771getModule(), Int8Ty, /*isConstant=*/false,772llvm::GlobalVariable::InternalLinkage,773llvm::ConstantInt::get(Int8Ty, 0), InitFnName.str() + "__in_chrg");774CharUnits GuardAlign = CharUnits::One();775Guard->setAlignment(GuardAlign.getAsAlign());776GuardAddr = ConstantAddress(Guard, Int8Ty, GuardAlign);777}778CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,779GuardAddr);780}781782// We allow for the case that a module object is added to a linked binary783// without a specific call to the the initializer. This also ensures that784// implementation partition initializers are called when the partition785// is not imported as an interface.786AddGlobalCtor(Fn);787788// See the comment in EmitCXXGlobalInitFunc about OpenCL global init789// functions.790if (getLangOpts().OpenCL) {791GenKernelArgMetadata(Fn);792Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);793}794795assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice ||796getLangOpts().GPUAllowDeviceInit);797if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) {798Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);799Fn->addFnAttr("device-init");800}801802// We are done with the inits.803AllImports.clear();804PrioritizedCXXGlobalInits.clear();805CXXGlobalInits.clear();806ModuleInits.clear();807}808809static SmallString<128> getTransformedFileName(llvm::Module &M) {810SmallString<128> FileName = llvm::sys::path::filename(M.getName());811812if (FileName.empty())813FileName = "<null>";814815for (size_t i = 0; i < FileName.size(); ++i) {816// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens817// to be the set of C preprocessing numbers.818if (!isPreprocessingNumberBody(FileName[i]))819FileName[i] = '_';820}821822return FileName;823}824825static std::string getPrioritySuffix(unsigned int Priority) {826assert(Priority <= 65535 && "Priority should always be <= 65535.");827828// Compute the function suffix from priority. Prepend with zeroes to make829// sure the function names are also ordered as priorities.830std::string PrioritySuffix = llvm::utostr(Priority);831PrioritySuffix = std::string(6 - PrioritySuffix.size(), '0') + PrioritySuffix;832833return PrioritySuffix;834}835836void837CodeGenModule::EmitCXXGlobalInitFunc() {838while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())839CXXGlobalInits.pop_back();840841// When we import C++20 modules, we must run their initializers first.842SmallVector<llvm::Function *, 8> ModuleInits;843if (CXX20ModuleInits)844for (Module *M : ImportedModules) {845// No Itanium initializer in header like modules.846if (M->isHeaderLikeModule())847continue;848// We're allowed to skip the initialization if we are sure it doesn't849// do any thing.850if (!M->isNamedModuleInterfaceHasInit())851continue;852llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);853SmallString<256> FnName;854{855llvm::raw_svector_ostream Out(FnName);856cast<ItaniumMangleContext>(getCXXABI().getMangleContext())857.mangleModuleInitializer(M, Out);858}859assert(!GetGlobalValue(FnName.str()) &&860"We should only have one use of the initializer call");861llvm::Function *Fn = llvm::Function::Create(862FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());863ModuleInits.push_back(Fn);864}865866if (ModuleInits.empty() && CXXGlobalInits.empty() &&867PrioritizedCXXGlobalInits.empty())868return;869870llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);871const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();872873// Create our global prioritized initialization function.874if (!PrioritizedCXXGlobalInits.empty()) {875SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;876llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),877PrioritizedCXXGlobalInits.end());878// Iterate over "chunks" of ctors with same priority and emit each chunk879// into separate function. Note - everything is sorted first by priority,880// second - by lex order, so we emit ctor functions in proper order.881for (SmallVectorImpl<GlobalInitData >::iterator882I = PrioritizedCXXGlobalInits.begin(),883E = PrioritizedCXXGlobalInits.end(); I != E; ) {884SmallVectorImpl<GlobalInitData >::iterator885PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());886887LocalCXXGlobalInits.clear();888889unsigned int Priority = I->first.priority;890llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(891FTy, "_GLOBAL__I_" + getPrioritySuffix(Priority), FI);892893// Prepend the module inits to the highest priority set.894if (!ModuleInits.empty()) {895for (auto *F : ModuleInits)896LocalCXXGlobalInits.push_back(F);897ModuleInits.clear();898}899900for (; I < PrioE; ++I)901LocalCXXGlobalInits.push_back(I->second);902903CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits);904AddGlobalCtor(Fn, Priority);905}906PrioritizedCXXGlobalInits.clear();907}908909if (getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&910CXXGlobalInits.empty())911return;912913for (auto *F : CXXGlobalInits)914ModuleInits.push_back(F);915CXXGlobalInits.clear();916917// Include the filename in the symbol name. Including "sub_" matches gcc918// and makes sure these symbols appear lexicographically behind the symbols919// with priority emitted above. Module implementation units behave the same920// way as a non-modular TU with imports.921llvm::Function *Fn;922if (CXX20ModuleInits && getContext().getCurrentNamedModule() &&923!getContext().getCurrentNamedModule()->isModuleImplementation()) {924SmallString<256> InitFnName;925llvm::raw_svector_ostream Out(InitFnName);926cast<ItaniumMangleContext>(getCXXABI().getMangleContext())927.mangleModuleInitializer(getContext().getCurrentNamedModule(), Out);928Fn = CreateGlobalInitOrCleanUpFunction(929FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,930llvm::GlobalVariable::ExternalLinkage);931} else932Fn = CreateGlobalInitOrCleanUpFunction(933FTy,934llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())),935FI);936937CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits);938AddGlobalCtor(Fn);939940// In OpenCL global init functions must be converted to kernels in order to941// be able to launch them from the host.942// FIXME: Some more work might be needed to handle destructors correctly.943// Current initialization function makes use of function pointers callbacks.944// We can't support function pointers especially between host and device.945// However it seems global destruction has little meaning without any946// dynamic resource allocation on the device and program scope variables are947// destroyed by the runtime when program is released.948if (getLangOpts().OpenCL) {949GenKernelArgMetadata(Fn);950Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);951}952953assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice ||954getLangOpts().GPUAllowDeviceInit);955if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) {956Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);957Fn->addFnAttr("device-init");958}959960ModuleInits.clear();961}962963void CodeGenModule::EmitCXXGlobalCleanUpFunc() {964if (CXXGlobalDtorsOrStermFinalizers.empty() &&965PrioritizedCXXStermFinalizers.empty())966return;967968llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);969const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();970971// Create our global prioritized cleanup function.972if (!PrioritizedCXXStermFinalizers.empty()) {973SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers;974llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),975PrioritizedCXXStermFinalizers.end());976// Iterate over "chunks" of dtors with same priority and emit each chunk977// into separate function. Note - everything is sorted first by priority,978// second - by lex order, so we emit dtor functions in proper order.979for (SmallVectorImpl<StermFinalizerData>::iterator980I = PrioritizedCXXStermFinalizers.begin(),981E = PrioritizedCXXStermFinalizers.end();982I != E;) {983SmallVectorImpl<StermFinalizerData>::iterator PrioE =984std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());985986LocalCXXStermFinalizers.clear();987988unsigned int Priority = I->first.priority;989llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(990FTy, "_GLOBAL__a_" + getPrioritySuffix(Priority), FI);991992for (; I < PrioE; ++I) {993llvm::FunctionCallee DtorFn = I->second;994LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),995DtorFn.getCallee(), nullptr);996}997998CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(999Fn, LocalCXXStermFinalizers);1000AddGlobalDtor(Fn, Priority);1001}1002PrioritizedCXXStermFinalizers.clear();1003}10041005if (CXXGlobalDtorsOrStermFinalizers.empty())1006return;10071008// Create our global cleanup function.1009llvm::Function *Fn =1010CreateGlobalInitOrCleanUpFunction(FTy, "_GLOBAL__D_a", FI);10111012CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(1013Fn, CXXGlobalDtorsOrStermFinalizers);1014AddGlobalDtor(Fn);1015CXXGlobalDtorsOrStermFinalizers.clear();1016}10171018/// Emit the code necessary to initialize the given global variable.1019void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,1020const VarDecl *D,1021llvm::GlobalVariable *Addr,1022bool PerformInit) {1023// Check if we need to emit debug info for variable initializer.1024if (D->hasAttr<NoDebugAttr>())1025DebugInfo = nullptr; // disable debug info indefinitely for this function10261027CurEHLocation = D->getBeginLoc();10281029StartFunction(GlobalDecl(D, DynamicInitKind::Initializer),1030getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(),1031FunctionArgList());1032// Emit an artificial location for this function.1033auto AL = ApplyDebugLocation::CreateArtificial(*this);10341035// Use guarded initialization if the global variable is weak. This1036// occurs for, e.g., instantiated static data members and1037// definitions explicitly marked weak.1038//1039// Also use guarded initialization for a variable with dynamic TLS and1040// unordered initialization. (If the initialization is ordered, the ABI1041// layer will guard the whole-TU initialization for us.)1042if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage() ||1043(D->getTLSKind() == VarDecl::TLS_Dynamic &&1044isTemplateInstantiation(D->getTemplateSpecializationKind()))) {1045EmitCXXGuardedInit(*D, Addr, PerformInit);1046} else {1047EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);1048}10491050if (getLangOpts().HLSL)1051CGM.getHLSLRuntime().annotateHLSLResource(D, Addr);10521053FinishFunction();1054}10551056void1057CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,1058ArrayRef<llvm::Function *> Decls,1059ConstantAddress Guard) {1060{1061auto NL = ApplyDebugLocation::CreateEmpty(*this);1062StartFunction(GlobalDecl(), getContext().VoidTy, Fn,1063getTypes().arrangeNullaryFunction(), FunctionArgList());1064// Emit an artificial location for this function.1065auto AL = ApplyDebugLocation::CreateArtificial(*this);10661067llvm::BasicBlock *ExitBlock = nullptr;1068if (Guard.isValid()) {1069// If we have a guard variable, check whether we've already performed1070// these initializations. This happens for TLS initialization functions.1071llvm::Value *GuardVal = Builder.CreateLoad(Guard);1072llvm::Value *Uninit = Builder.CreateIsNull(GuardVal,1073"guard.uninitialized");1074llvm::BasicBlock *InitBlock = createBasicBlock("init");1075ExitBlock = createBasicBlock("exit");1076EmitCXXGuardedInitBranch(Uninit, InitBlock, ExitBlock,1077GuardKind::TlsGuard, nullptr);1078EmitBlock(InitBlock);1079// Mark as initialized before initializing anything else. If the1080// initializers use previously-initialized thread_local vars, that's1081// probably supposed to be OK, but the standard doesn't say.1082Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);10831084// The guard variable can't ever change again.1085EmitInvariantStart(1086Guard.getPointer(),1087CharUnits::fromQuantity(1088CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())));1089}10901091RunCleanupsScope Scope(*this);10921093// When building in Objective-C++ ARC mode, create an autorelease pool1094// around the global initializers.1095if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) {1096llvm::Value *token = EmitObjCAutoreleasePoolPush();1097EmitObjCAutoreleasePoolCleanup(token);1098}10991100for (unsigned i = 0, e = Decls.size(); i != e; ++i)1101if (Decls[i])1102EmitRuntimeCall(Decls[i]);11031104Scope.ForceCleanup();11051106if (ExitBlock) {1107Builder.CreateBr(ExitBlock);1108EmitBlock(ExitBlock);1109}1110}11111112FinishFunction();1113}11141115void CodeGenFunction::GenerateCXXGlobalCleanUpFunc(1116llvm::Function *Fn,1117ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,1118llvm::Constant *>>1119DtorsOrStermFinalizers) {1120{1121auto NL = ApplyDebugLocation::CreateEmpty(*this);1122StartFunction(GlobalDecl(), getContext().VoidTy, Fn,1123getTypes().arrangeNullaryFunction(), FunctionArgList());1124// Emit an artificial location for this function.1125auto AL = ApplyDebugLocation::CreateArtificial(*this);11261127// Emit the cleanups, in reverse order from construction.1128for (unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {1129llvm::FunctionType *CalleeTy;1130llvm::Value *Callee;1131llvm::Constant *Arg;1132std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];11331134llvm::CallInst *CI = nullptr;1135if (Arg == nullptr) {1136assert(1137CGM.getCXXABI().useSinitAndSterm() &&1138"Arg could not be nullptr unless using sinit and sterm functions.");1139CI = Builder.CreateCall(CalleeTy, Callee);1140} else1141CI = Builder.CreateCall(CalleeTy, Callee, Arg);11421143// Make sure the call and the callee agree on calling convention.1144if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))1145CI->setCallingConv(F->getCallingConv());1146}1147}11481149FinishFunction();1150}11511152/// generateDestroyHelper - Generates a helper function which, when1153/// invoked, destroys the given object. The address of the object1154/// should be in global memory.1155llvm::Function *CodeGenFunction::generateDestroyHelper(1156Address addr, QualType type, Destroyer *destroyer,1157bool useEHCleanupForArray, const VarDecl *VD) {1158FunctionArgList args;1159ImplicitParamDecl Dst(getContext(), getContext().VoidPtrTy,1160ImplicitParamKind::Other);1161args.push_back(&Dst);11621163const CGFunctionInfo &FI =1164CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, args);1165llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);1166llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(1167FTy, "__cxx_global_array_dtor", FI, VD->getLocation());11681169CurEHLocation = VD->getBeginLoc();11701171StartFunction(GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor),1172getContext().VoidTy, fn, FI, args);1173// Emit an artificial location for this function.1174auto AL = ApplyDebugLocation::CreateArtificial(*this);11751176emitDestroy(addr, type, destroyer, useEHCleanupForArray);11771178FinishFunction();11791180return fn;1181}118211831184