xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CGDeclCXX.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This contains code dealing with code generation of C++ declarations
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "CGCXXABI.h"
14*12c85518Srobert #include "CGHLSLRuntime.h"
15e5dd7070Spatrick #include "CGObjCRuntime.h"
16e5dd7070Spatrick #include "CGOpenMPRuntime.h"
17e5dd7070Spatrick #include "CodeGenFunction.h"
18e5dd7070Spatrick #include "TargetInfo.h"
19e5dd7070Spatrick #include "clang/AST/Attr.h"
20ec727ea7Spatrick #include "clang/Basic/LangOptions.h"
21e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
22e5dd7070Spatrick #include "llvm/IR/Intrinsics.h"
23e5dd7070Spatrick #include "llvm/IR/MDBuilder.h"
24e5dd7070Spatrick #include "llvm/Support/Path.h"
25e5dd7070Spatrick 
26e5dd7070Spatrick using namespace clang;
27e5dd7070Spatrick using namespace CodeGen;
28e5dd7070Spatrick 
EmitDeclInit(CodeGenFunction & CGF,const VarDecl & D,ConstantAddress DeclPtr)29e5dd7070Spatrick static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
30e5dd7070Spatrick                          ConstantAddress DeclPtr) {
31e5dd7070Spatrick   assert(
32e5dd7070Spatrick       (D.hasGlobalStorage() ||
33e5dd7070Spatrick        (D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) &&
34e5dd7070Spatrick       "VarDecl must have global or local (in the case of OpenCL) storage!");
35e5dd7070Spatrick   assert(!D.getType()->isReferenceType() &&
36e5dd7070Spatrick          "Should not call EmitDeclInit on a reference!");
37e5dd7070Spatrick 
38e5dd7070Spatrick   QualType type = D.getType();
39e5dd7070Spatrick   LValue lv = CGF.MakeAddrLValue(DeclPtr, type);
40e5dd7070Spatrick 
41e5dd7070Spatrick   const Expr *Init = D.getInit();
42e5dd7070Spatrick   switch (CGF.getEvaluationKind(type)) {
43e5dd7070Spatrick   case TEK_Scalar: {
44e5dd7070Spatrick     CodeGenModule &CGM = CGF.CGM;
45e5dd7070Spatrick     if (lv.isObjCStrong())
46e5dd7070Spatrick       CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init),
47e5dd7070Spatrick                                                 DeclPtr, D.getTLSKind());
48e5dd7070Spatrick     else if (lv.isObjCWeak())
49e5dd7070Spatrick       CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init),
50e5dd7070Spatrick                                               DeclPtr);
51e5dd7070Spatrick     else
52e5dd7070Spatrick       CGF.EmitScalarInit(Init, &D, lv, false);
53e5dd7070Spatrick     return;
54e5dd7070Spatrick   }
55e5dd7070Spatrick   case TEK_Complex:
56e5dd7070Spatrick     CGF.EmitComplexExprIntoLValue(Init, lv, /*isInit*/ true);
57e5dd7070Spatrick     return;
58e5dd7070Spatrick   case TEK_Aggregate:
59e5dd7070Spatrick     CGF.EmitAggExpr(Init,
60e5dd7070Spatrick                     AggValueSlot::forLValue(lv, CGF, AggValueSlot::IsDestructed,
61e5dd7070Spatrick                                             AggValueSlot::DoesNotNeedGCBarriers,
62e5dd7070Spatrick                                             AggValueSlot::IsNotAliased,
63e5dd7070Spatrick                                             AggValueSlot::DoesNotOverlap));
64e5dd7070Spatrick     return;
65e5dd7070Spatrick   }
66e5dd7070Spatrick   llvm_unreachable("bad evaluation kind");
67e5dd7070Spatrick }
68e5dd7070Spatrick 
69e5dd7070Spatrick /// Emit code to cause the destruction of the given variable with
70e5dd7070Spatrick /// static storage duration.
EmitDeclDestroy(CodeGenFunction & CGF,const VarDecl & D,ConstantAddress Addr)71e5dd7070Spatrick static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
72e5dd7070Spatrick                             ConstantAddress Addr) {
73e5dd7070Spatrick   // Honor __attribute__((no_destroy)) and bail instead of attempting
74e5dd7070Spatrick   // to emit a reference to a possibly nonexistent destructor, which
75e5dd7070Spatrick   // in turn can cause a crash. This will result in a global constructor
76e5dd7070Spatrick   // that isn't balanced out by a destructor call as intended by the
77e5dd7070Spatrick   // attribute. This also checks for -fno-c++-static-destructors and
78e5dd7070Spatrick   // bails even if the attribute is not present.
79e5dd7070Spatrick   QualType::DestructionKind DtorKind = D.needsDestruction(CGF.getContext());
80e5dd7070Spatrick 
81e5dd7070Spatrick   // FIXME:  __attribute__((cleanup)) ?
82e5dd7070Spatrick 
83e5dd7070Spatrick   switch (DtorKind) {
84e5dd7070Spatrick   case QualType::DK_none:
85e5dd7070Spatrick     return;
86e5dd7070Spatrick 
87e5dd7070Spatrick   case QualType::DK_cxx_destructor:
88e5dd7070Spatrick     break;
89e5dd7070Spatrick 
90e5dd7070Spatrick   case QualType::DK_objc_strong_lifetime:
91e5dd7070Spatrick   case QualType::DK_objc_weak_lifetime:
92e5dd7070Spatrick   case QualType::DK_nontrivial_c_struct:
93e5dd7070Spatrick     // We don't care about releasing objects during process teardown.
94e5dd7070Spatrick     assert(!D.getTLSKind() && "should have rejected this");
95e5dd7070Spatrick     return;
96e5dd7070Spatrick   }
97e5dd7070Spatrick 
98e5dd7070Spatrick   llvm::FunctionCallee Func;
99e5dd7070Spatrick   llvm::Constant *Argument;
100e5dd7070Spatrick 
101e5dd7070Spatrick   CodeGenModule &CGM = CGF.CGM;
102e5dd7070Spatrick   QualType Type = D.getType();
103e5dd7070Spatrick 
104e5dd7070Spatrick   // Special-case non-array C++ destructors, if they have the right signature.
105e5dd7070Spatrick   // Under some ABIs, destructors return this instead of void, and cannot be
106e5dd7070Spatrick   // passed directly to __cxa_atexit if the target does not allow this
107e5dd7070Spatrick   // mismatch.
108e5dd7070Spatrick   const CXXRecordDecl *Record = Type->getAsCXXRecordDecl();
109e5dd7070Spatrick   bool CanRegisterDestructor =
110e5dd7070Spatrick       Record && (!CGM.getCXXABI().HasThisReturn(
111e5dd7070Spatrick                      GlobalDecl(Record->getDestructor(), Dtor_Complete)) ||
112e5dd7070Spatrick                  CGM.getCXXABI().canCallMismatchedFunctionType());
113e5dd7070Spatrick   // If __cxa_atexit is disabled via a flag, a different helper function is
114e5dd7070Spatrick   // generated elsewhere which uses atexit instead, and it takes the destructor
115e5dd7070Spatrick   // directly.
116e5dd7070Spatrick   bool UsingExternalHelper = !CGM.getCodeGenOpts().CXAAtExit;
117e5dd7070Spatrick   if (Record && (CanRegisterDestructor || UsingExternalHelper)) {
118e5dd7070Spatrick     assert(!Record->hasTrivialDestructor());
119e5dd7070Spatrick     CXXDestructorDecl *Dtor = Record->getDestructor();
120e5dd7070Spatrick 
121e5dd7070Spatrick     Func = CGM.getAddrAndTypeOfCXXStructor(GlobalDecl(Dtor, Dtor_Complete));
122e5dd7070Spatrick     if (CGF.getContext().getLangOpts().OpenCL) {
123e5dd7070Spatrick       auto DestAS =
124e5dd7070Spatrick           CGM.getTargetCodeGenInfo().getAddrSpaceOfCxaAtexitPtrParam();
125e5dd7070Spatrick       auto DestTy = CGF.getTypes().ConvertType(Type)->getPointerTo(
126e5dd7070Spatrick           CGM.getContext().getTargetAddressSpace(DestAS));
127e5dd7070Spatrick       auto SrcAS = D.getType().getQualifiers().getAddressSpace();
128e5dd7070Spatrick       if (DestAS == SrcAS)
129e5dd7070Spatrick         Argument = llvm::ConstantExpr::getBitCast(Addr.getPointer(), DestTy);
130e5dd7070Spatrick       else
131e5dd7070Spatrick         // FIXME: On addr space mismatch we are passing NULL. The generation
132e5dd7070Spatrick         // of the global destructor function should be adjusted accordingly.
133e5dd7070Spatrick         Argument = llvm::ConstantPointerNull::get(DestTy);
134e5dd7070Spatrick     } else {
135e5dd7070Spatrick       Argument = llvm::ConstantExpr::getBitCast(
136e5dd7070Spatrick           Addr.getPointer(), CGF.getTypes().ConvertType(Type)->getPointerTo());
137e5dd7070Spatrick     }
138e5dd7070Spatrick   // Otherwise, the standard logic requires a helper function.
139e5dd7070Spatrick   } else {
140*12c85518Srobert     Addr = Addr.getElementBitCast(CGF.ConvertTypeForMem(Type));
141e5dd7070Spatrick     Func = CodeGenFunction(CGM)
142e5dd7070Spatrick            .generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind),
143e5dd7070Spatrick                                   CGF.needsEHCleanup(DtorKind), &D);
144e5dd7070Spatrick     Argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);
145e5dd7070Spatrick   }
146e5dd7070Spatrick 
147e5dd7070Spatrick   CGM.getCXXABI().registerGlobalDtor(CGF, D, Func, Argument);
148e5dd7070Spatrick }
149e5dd7070Spatrick 
150e5dd7070Spatrick /// Emit code to cause the variable at the given address to be considered as
151e5dd7070Spatrick /// constant from this point onwards.
EmitDeclInvariant(CodeGenFunction & CGF,const VarDecl & D,llvm::Constant * Addr)152e5dd7070Spatrick static void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D,
153e5dd7070Spatrick                               llvm::Constant *Addr) {
154e5dd7070Spatrick   return CGF.EmitInvariantStart(
155e5dd7070Spatrick       Addr, CGF.getContext().getTypeSizeInChars(D.getType()));
156e5dd7070Spatrick }
157e5dd7070Spatrick 
EmitInvariantStart(llvm::Constant * Addr,CharUnits Size)158e5dd7070Spatrick void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) {
159e5dd7070Spatrick   // Do not emit the intrinsic if we're not optimizing.
160e5dd7070Spatrick   if (!CGM.getCodeGenOpts().OptimizationLevel)
161e5dd7070Spatrick     return;
162e5dd7070Spatrick 
163e5dd7070Spatrick   // Grab the llvm.invariant.start intrinsic.
164e5dd7070Spatrick   llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
165e5dd7070Spatrick   // Overloaded address space type.
166e5dd7070Spatrick   llvm::Type *ObjectPtr[1] = {Int8PtrTy};
167e5dd7070Spatrick   llvm::Function *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr);
168e5dd7070Spatrick 
169e5dd7070Spatrick   // Emit a call with the size in bytes of the object.
170e5dd7070Spatrick   uint64_t Width = Size.getQuantity();
171e5dd7070Spatrick   llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(Int64Ty, Width),
172e5dd7070Spatrick                            llvm::ConstantExpr::getBitCast(Addr, Int8PtrTy)};
173e5dd7070Spatrick   Builder.CreateCall(InvariantStart, Args);
174e5dd7070Spatrick }
175e5dd7070Spatrick 
EmitCXXGlobalVarDeclInit(const VarDecl & D,llvm::GlobalVariable * GV,bool PerformInit)176e5dd7070Spatrick void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
177*12c85518Srobert                                                llvm::GlobalVariable *GV,
178e5dd7070Spatrick                                                bool PerformInit) {
179e5dd7070Spatrick 
180e5dd7070Spatrick   const Expr *Init = D.getInit();
181e5dd7070Spatrick   QualType T = D.getType();
182e5dd7070Spatrick 
183e5dd7070Spatrick   // The address space of a static local variable (DeclPtr) may be different
184e5dd7070Spatrick   // from the address space of the "this" argument of the constructor. In that
185e5dd7070Spatrick   // case, we need an addrspacecast before calling the constructor.
186e5dd7070Spatrick   //
187e5dd7070Spatrick   // struct StructWithCtor {
188e5dd7070Spatrick   //   __device__ StructWithCtor() {...}
189e5dd7070Spatrick   // };
190e5dd7070Spatrick   // __device__ void foo() {
191e5dd7070Spatrick   //   __shared__ StructWithCtor s;
192e5dd7070Spatrick   //   ...
193e5dd7070Spatrick   // }
194e5dd7070Spatrick   //
195e5dd7070Spatrick   // For example, in the above CUDA code, the static local variable s has a
196e5dd7070Spatrick   // "shared" address space qualifier, but the constructor of StructWithCtor
197e5dd7070Spatrick   // expects "this" in the "generic" address space.
198*12c85518Srobert   unsigned ExpectedAddrSpace = getTypes().getTargetAddressSpace(T);
199*12c85518Srobert   unsigned ActualAddrSpace = GV->getAddressSpace();
200*12c85518Srobert   llvm::Constant *DeclPtr = GV;
201e5dd7070Spatrick   if (ActualAddrSpace != ExpectedAddrSpace) {
202*12c85518Srobert     llvm::PointerType *PTy = llvm::PointerType::getWithSamePointeeType(
203*12c85518Srobert         GV->getType(), ExpectedAddrSpace);
204e5dd7070Spatrick     DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
205e5dd7070Spatrick   }
206e5dd7070Spatrick 
207*12c85518Srobert   ConstantAddress DeclAddr(
208*12c85518Srobert       DeclPtr, GV->getValueType(), getContext().getDeclAlign(&D));
209e5dd7070Spatrick 
210e5dd7070Spatrick   if (!T->isReferenceType()) {
211e5dd7070Spatrick     if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd &&
212e5dd7070Spatrick         D.hasAttr<OMPThreadPrivateDeclAttr>()) {
213e5dd7070Spatrick       (void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(
214e5dd7070Spatrick           &D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
215e5dd7070Spatrick           PerformInit, this);
216e5dd7070Spatrick     }
217e5dd7070Spatrick     if (PerformInit)
218e5dd7070Spatrick       EmitDeclInit(*this, D, DeclAddr);
219e5dd7070Spatrick     if (CGM.isTypeConstant(D.getType(), true))
220e5dd7070Spatrick       EmitDeclInvariant(*this, D, DeclPtr);
221e5dd7070Spatrick     else
222e5dd7070Spatrick       EmitDeclDestroy(*this, D, DeclAddr);
223e5dd7070Spatrick     return;
224e5dd7070Spatrick   }
225e5dd7070Spatrick 
226e5dd7070Spatrick   assert(PerformInit && "cannot have constant initializer which needs "
227e5dd7070Spatrick          "destruction for reference");
228e5dd7070Spatrick   RValue RV = EmitReferenceBindingToExpr(Init);
229e5dd7070Spatrick   EmitStoreOfScalar(RV.getScalarVal(), DeclAddr, false, T);
230e5dd7070Spatrick }
231e5dd7070Spatrick 
232e5dd7070Spatrick /// Create a stub function, suitable for being passed to atexit,
233e5dd7070Spatrick /// which passes the given address to the given destructor function.
createAtExitStub(const VarDecl & VD,llvm::FunctionCallee dtor,llvm::Constant * addr)234e5dd7070Spatrick llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD,
235e5dd7070Spatrick                                                   llvm::FunctionCallee dtor,
236e5dd7070Spatrick                                                   llvm::Constant *addr) {
237e5dd7070Spatrick   // Get the destructor function type, void(*)(void).
238e5dd7070Spatrick   llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);
239e5dd7070Spatrick   SmallString<256> FnName;
240e5dd7070Spatrick   {
241e5dd7070Spatrick     llvm::raw_svector_ostream Out(FnName);
242e5dd7070Spatrick     CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);
243e5dd7070Spatrick   }
244e5dd7070Spatrick 
245e5dd7070Spatrick   const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
246ec727ea7Spatrick   llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(
247e5dd7070Spatrick       ty, FnName.str(), FI, VD.getLocation());
248e5dd7070Spatrick 
249e5dd7070Spatrick   CodeGenFunction CGF(CGM);
250e5dd7070Spatrick 
251e5dd7070Spatrick   CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit),
252a9ac8606Spatrick                     CGM.getContext().VoidTy, fn, FI, FunctionArgList(),
253a9ac8606Spatrick                     VD.getLocation(), VD.getInit()->getExprLoc());
254a9ac8606Spatrick   // Emit an artificial location for this function.
255a9ac8606Spatrick   auto AL = ApplyDebugLocation::CreateArtificial(CGF);
256e5dd7070Spatrick 
257e5dd7070Spatrick   llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
258e5dd7070Spatrick 
259e5dd7070Spatrick   // Make sure the call and the callee agree on calling convention.
260e5dd7070Spatrick   if (auto *dtorFn = dyn_cast<llvm::Function>(
261e5dd7070Spatrick           dtor.getCallee()->stripPointerCastsAndAliases()))
262e5dd7070Spatrick     call->setCallingConv(dtorFn->getCallingConv());
263e5dd7070Spatrick 
264e5dd7070Spatrick   CGF.FinishFunction();
265e5dd7070Spatrick 
266e5dd7070Spatrick   return fn;
267e5dd7070Spatrick }
268e5dd7070Spatrick 
269a9ac8606Spatrick /// Create a stub function, suitable for being passed to __pt_atexit_np,
270a9ac8606Spatrick /// which passes the given address to the given destructor function.
createTLSAtExitStub(const VarDecl & D,llvm::FunctionCallee Dtor,llvm::Constant * Addr,llvm::FunctionCallee & AtExit)271a9ac8606Spatrick llvm::Function *CodeGenFunction::createTLSAtExitStub(
272a9ac8606Spatrick     const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr,
273a9ac8606Spatrick     llvm::FunctionCallee &AtExit) {
274a9ac8606Spatrick   SmallString<256> FnName;
275a9ac8606Spatrick   {
276a9ac8606Spatrick     llvm::raw_svector_ostream Out(FnName);
277a9ac8606Spatrick     CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&D, Out);
278a9ac8606Spatrick   }
279a9ac8606Spatrick 
280a9ac8606Spatrick   const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo(
281a9ac8606Spatrick       getContext().IntTy, /*instanceMethod=*/false, /*chainCall=*/false,
282a9ac8606Spatrick       {getContext().IntTy}, FunctionType::ExtInfo(), {}, RequiredArgs::All);
283a9ac8606Spatrick 
284a9ac8606Spatrick   // Get the stub function type, int(*)(int,...).
285a9ac8606Spatrick   llvm::FunctionType *StubTy =
286a9ac8606Spatrick       llvm::FunctionType::get(CGM.IntTy, {CGM.IntTy}, true);
287a9ac8606Spatrick 
288a9ac8606Spatrick   llvm::Function *DtorStub = CGM.CreateGlobalInitOrCleanUpFunction(
289a9ac8606Spatrick       StubTy, FnName.str(), FI, D.getLocation());
290a9ac8606Spatrick 
291a9ac8606Spatrick   CodeGenFunction CGF(CGM);
292a9ac8606Spatrick 
293a9ac8606Spatrick   FunctionArgList Args;
294a9ac8606Spatrick   ImplicitParamDecl IPD(CGM.getContext(), CGM.getContext().IntTy,
295a9ac8606Spatrick                         ImplicitParamDecl::Other);
296a9ac8606Spatrick   Args.push_back(&IPD);
297a9ac8606Spatrick   QualType ResTy = CGM.getContext().IntTy;
298a9ac8606Spatrick 
299a9ac8606Spatrick   CGF.StartFunction(GlobalDecl(&D, DynamicInitKind::AtExit), ResTy, DtorStub,
300a9ac8606Spatrick                     FI, Args, D.getLocation(), D.getInit()->getExprLoc());
301a9ac8606Spatrick 
302a9ac8606Spatrick   // Emit an artificial location for this function.
303a9ac8606Spatrick   auto AL = ApplyDebugLocation::CreateArtificial(CGF);
304a9ac8606Spatrick 
305a9ac8606Spatrick   llvm::CallInst *call = CGF.Builder.CreateCall(Dtor, Addr);
306a9ac8606Spatrick 
307a9ac8606Spatrick   // Make sure the call and the callee agree on calling convention.
308a9ac8606Spatrick   if (auto *DtorFn = dyn_cast<llvm::Function>(
309a9ac8606Spatrick           Dtor.getCallee()->stripPointerCastsAndAliases()))
310a9ac8606Spatrick     call->setCallingConv(DtorFn->getCallingConv());
311a9ac8606Spatrick 
312a9ac8606Spatrick   // Return 0 from function
313a9ac8606Spatrick   CGF.Builder.CreateStore(llvm::Constant::getNullValue(CGM.IntTy),
314a9ac8606Spatrick                           CGF.ReturnValue);
315a9ac8606Spatrick 
316a9ac8606Spatrick   CGF.FinishFunction();
317a9ac8606Spatrick 
318a9ac8606Spatrick   return DtorStub;
319a9ac8606Spatrick }
320a9ac8606Spatrick 
321e5dd7070Spatrick /// Register a global destructor using the C atexit runtime function.
registerGlobalDtorWithAtExit(const VarDecl & VD,llvm::FunctionCallee dtor,llvm::Constant * addr)322e5dd7070Spatrick void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD,
323e5dd7070Spatrick                                                    llvm::FunctionCallee dtor,
324e5dd7070Spatrick                                                    llvm::Constant *addr) {
325e5dd7070Spatrick   // Create a function which calls the destructor.
326e5dd7070Spatrick   llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr);
327e5dd7070Spatrick   registerGlobalDtorWithAtExit(dtorStub);
328e5dd7070Spatrick }
329e5dd7070Spatrick 
registerGlobalDtorWithAtExit(llvm::Constant * dtorStub)330e5dd7070Spatrick void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtorStub) {
331e5dd7070Spatrick   // extern "C" int atexit(void (*f)(void));
332a9ac8606Spatrick   assert(dtorStub->getType() ==
333a9ac8606Spatrick              llvm::PointerType::get(
334a9ac8606Spatrick                  llvm::FunctionType::get(CGM.VoidTy, false),
335a9ac8606Spatrick                  dtorStub->getType()->getPointerAddressSpace()) &&
336ec727ea7Spatrick          "Argument to atexit has a wrong type.");
337ec727ea7Spatrick 
338e5dd7070Spatrick   llvm::FunctionType *atexitTy =
339e5dd7070Spatrick       llvm::FunctionType::get(IntTy, dtorStub->getType(), false);
340e5dd7070Spatrick 
341e5dd7070Spatrick   llvm::FunctionCallee atexit =
342e5dd7070Spatrick       CGM.CreateRuntimeFunction(atexitTy, "atexit", llvm::AttributeList(),
343e5dd7070Spatrick                                 /*Local=*/true);
344e5dd7070Spatrick   if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
345e5dd7070Spatrick     atexitFn->setDoesNotThrow();
346e5dd7070Spatrick 
347e5dd7070Spatrick   EmitNounwindRuntimeCall(atexit, dtorStub);
348e5dd7070Spatrick }
349e5dd7070Spatrick 
350ec727ea7Spatrick llvm::Value *
unregisterGlobalDtorWithUnAtExit(llvm::Constant * dtorStub)351a9ac8606Spatrick CodeGenFunction::unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub) {
352ec727ea7Spatrick   // The unatexit subroutine unregisters __dtor functions that were previously
353ec727ea7Spatrick   // registered by the atexit subroutine. If the referenced function is found,
354ec727ea7Spatrick   // it is removed from the list of functions that are called at normal program
355ec727ea7Spatrick   // termination and the unatexit returns a value of 0, otherwise a non-zero
356ec727ea7Spatrick   // value is returned.
357ec727ea7Spatrick   //
358ec727ea7Spatrick   // extern "C" int unatexit(void (*f)(void));
359a9ac8606Spatrick   assert(dtorStub->getType() ==
360a9ac8606Spatrick              llvm::PointerType::get(
361a9ac8606Spatrick                  llvm::FunctionType::get(CGM.VoidTy, false),
362a9ac8606Spatrick                  dtorStub->getType()->getPointerAddressSpace()) &&
363ec727ea7Spatrick          "Argument to unatexit has a wrong type.");
364ec727ea7Spatrick 
365ec727ea7Spatrick   llvm::FunctionType *unatexitTy =
366ec727ea7Spatrick       llvm::FunctionType::get(IntTy, {dtorStub->getType()}, /*isVarArg=*/false);
367ec727ea7Spatrick 
368ec727ea7Spatrick   llvm::FunctionCallee unatexit =
369ec727ea7Spatrick       CGM.CreateRuntimeFunction(unatexitTy, "unatexit", llvm::AttributeList());
370ec727ea7Spatrick 
371ec727ea7Spatrick   cast<llvm::Function>(unatexit.getCallee())->setDoesNotThrow();
372ec727ea7Spatrick 
373ec727ea7Spatrick   return EmitNounwindRuntimeCall(unatexit, dtorStub);
374ec727ea7Spatrick }
375ec727ea7Spatrick 
EmitCXXGuardedInit(const VarDecl & D,llvm::GlobalVariable * DeclPtr,bool PerformInit)376e5dd7070Spatrick void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,
377e5dd7070Spatrick                                          llvm::GlobalVariable *DeclPtr,
378e5dd7070Spatrick                                          bool PerformInit) {
379e5dd7070Spatrick   // If we've been asked to forbid guard variables, emit an error now.
380e5dd7070Spatrick   // This diagnostic is hard-coded for Darwin's use case;  we can find
381e5dd7070Spatrick   // better phrasing if someone else needs it.
382e5dd7070Spatrick   if (CGM.getCodeGenOpts().ForbidGuardVariables)
383e5dd7070Spatrick     CGM.Error(D.getLocation(),
384e5dd7070Spatrick               "this initialization requires a guard variable, which "
385e5dd7070Spatrick               "the kernel does not support");
386e5dd7070Spatrick 
387e5dd7070Spatrick   CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);
388e5dd7070Spatrick }
389e5dd7070Spatrick 
EmitCXXGuardedInitBranch(llvm::Value * NeedsInit,llvm::BasicBlock * InitBlock,llvm::BasicBlock * NoInitBlock,GuardKind Kind,const VarDecl * D)390e5dd7070Spatrick void CodeGenFunction::EmitCXXGuardedInitBranch(llvm::Value *NeedsInit,
391e5dd7070Spatrick                                                llvm::BasicBlock *InitBlock,
392e5dd7070Spatrick                                                llvm::BasicBlock *NoInitBlock,
393e5dd7070Spatrick                                                GuardKind Kind,
394e5dd7070Spatrick                                                const VarDecl *D) {
395e5dd7070Spatrick   assert((Kind == GuardKind::TlsGuard || D) && "no guarded variable");
396e5dd7070Spatrick 
397e5dd7070Spatrick   // A guess at how many times we will enter the initialization of a
398e5dd7070Spatrick   // variable, depending on the kind of variable.
399e5dd7070Spatrick   static const uint64_t InitsPerTLSVar = 1024;
400e5dd7070Spatrick   static const uint64_t InitsPerLocalVar = 1024 * 1024;
401e5dd7070Spatrick 
402e5dd7070Spatrick   llvm::MDNode *Weights;
403e5dd7070Spatrick   if (Kind == GuardKind::VariableGuard && !D->isLocalVarDecl()) {
404e5dd7070Spatrick     // For non-local variables, don't apply any weighting for now. Due to our
405e5dd7070Spatrick     // use of COMDATs, we expect there to be at most one initialization of the
406e5dd7070Spatrick     // variable per DSO, but we have no way to know how many DSOs will try to
407e5dd7070Spatrick     // initialize the variable.
408e5dd7070Spatrick     Weights = nullptr;
409e5dd7070Spatrick   } else {
410e5dd7070Spatrick     uint64_t NumInits;
411e5dd7070Spatrick     // FIXME: For the TLS case, collect and use profiling information to
412e5dd7070Spatrick     // determine a more accurate brach weight.
413e5dd7070Spatrick     if (Kind == GuardKind::TlsGuard || D->getTLSKind())
414e5dd7070Spatrick       NumInits = InitsPerTLSVar;
415e5dd7070Spatrick     else
416e5dd7070Spatrick       NumInits = InitsPerLocalVar;
417e5dd7070Spatrick 
418e5dd7070Spatrick     // The probability of us entering the initializer is
419e5dd7070Spatrick     //   1 / (total number of times we attempt to initialize the variable).
420e5dd7070Spatrick     llvm::MDBuilder MDHelper(CGM.getLLVMContext());
421e5dd7070Spatrick     Weights = MDHelper.createBranchWeights(1, NumInits - 1);
422e5dd7070Spatrick   }
423e5dd7070Spatrick 
424e5dd7070Spatrick   Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
425e5dd7070Spatrick }
426e5dd7070Spatrick 
CreateGlobalInitOrCleanUpFunction(llvm::FunctionType * FTy,const Twine & Name,const CGFunctionInfo & FI,SourceLocation Loc,bool TLS,llvm::GlobalVariable::LinkageTypes Linkage)427ec727ea7Spatrick llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(
428e5dd7070Spatrick     llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI,
429*12c85518Srobert     SourceLocation Loc, bool TLS, llvm::GlobalVariable::LinkageTypes Linkage) {
430*12c85518Srobert   llvm::Function *Fn = llvm::Function::Create(FTy, Linkage, Name, &getModule());
431ec727ea7Spatrick 
432e5dd7070Spatrick   if (!getLangOpts().AppleKext && !TLS) {
433e5dd7070Spatrick     // Set the section if needed.
434e5dd7070Spatrick     if (const char *Section = getTarget().getStaticInitSectionSpecifier())
435e5dd7070Spatrick       Fn->setSection(Section);
436e5dd7070Spatrick   }
437e5dd7070Spatrick 
438*12c85518Srobert   if (Linkage == llvm::GlobalVariable::InternalLinkage)
439e5dd7070Spatrick     SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
440e5dd7070Spatrick 
441e5dd7070Spatrick   Fn->setCallingConv(getRuntimeCC());
442e5dd7070Spatrick 
443e5dd7070Spatrick   if (!getLangOpts().Exceptions)
444e5dd7070Spatrick     Fn->setDoesNotThrow();
445e5dd7070Spatrick 
446e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::Address) &&
447a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::Address, Fn, Loc))
448e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
449e5dd7070Spatrick 
450e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
451a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::KernelAddress, Fn, Loc))
452e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
453e5dd7070Spatrick 
454e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
455a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::HWAddress, Fn, Loc))
456e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
457e5dd7070Spatrick 
458e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&
459a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn, Loc))
460e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
461e5dd7070Spatrick 
462*12c85518Srobert   if (getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
463*12c85518Srobert       !isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc))
464e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
465e5dd7070Spatrick 
466e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
467a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc))
468e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeThread);
469e5dd7070Spatrick 
470e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
471a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::Memory, Fn, Loc))
472e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
473e5dd7070Spatrick 
474e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&
475a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::KernelMemory, Fn, Loc))
476e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
477e5dd7070Spatrick 
478e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
479a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::SafeStack, Fn, Loc))
480e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::SafeStack);
481e5dd7070Spatrick 
482e5dd7070Spatrick   if (getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&
483a9ac8606Spatrick       !isInNoSanitizeList(SanitizerKind::ShadowCallStack, Fn, Loc))
484e5dd7070Spatrick     Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
485e5dd7070Spatrick 
486e5dd7070Spatrick   return Fn;
487e5dd7070Spatrick }
488e5dd7070Spatrick 
489e5dd7070Spatrick /// Create a global pointer to a function that will initialize a global
490e5dd7070Spatrick /// variable.  The user has requested that this pointer be emitted in a specific
491e5dd7070Spatrick /// section.
EmitPointerToInitFunc(const VarDecl * D,llvm::GlobalVariable * GV,llvm::Function * InitFunc,InitSegAttr * ISA)492e5dd7070Spatrick void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,
493e5dd7070Spatrick                                           llvm::GlobalVariable *GV,
494e5dd7070Spatrick                                           llvm::Function *InitFunc,
495e5dd7070Spatrick                                           InitSegAttr *ISA) {
496e5dd7070Spatrick   llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable(
497e5dd7070Spatrick       TheModule, InitFunc->getType(), /*isConstant=*/true,
498e5dd7070Spatrick       llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr");
499e5dd7070Spatrick   PtrArray->setSection(ISA->getSection());
500e5dd7070Spatrick   addUsedGlobal(PtrArray);
501e5dd7070Spatrick 
502e5dd7070Spatrick   // If the GV is already in a comdat group, then we have to join it.
503e5dd7070Spatrick   if (llvm::Comdat *C = GV->getComdat())
504e5dd7070Spatrick     PtrArray->setComdat(C);
505e5dd7070Spatrick }
506e5dd7070Spatrick 
507e5dd7070Spatrick void
EmitCXXGlobalVarDeclInitFunc(const VarDecl * D,llvm::GlobalVariable * Addr,bool PerformInit)508e5dd7070Spatrick CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
509e5dd7070Spatrick                                             llvm::GlobalVariable *Addr,
510e5dd7070Spatrick                                             bool PerformInit) {
511e5dd7070Spatrick 
512e5dd7070Spatrick   // According to E.2.3.1 in CUDA-7.5 Programming guide: __device__,
513e5dd7070Spatrick   // __constant__ and __shared__ variables defined in namespace scope,
514e5dd7070Spatrick   // that are of class type, cannot have a non-empty constructor. All
515e5dd7070Spatrick   // the checks have been done in Sema by now. Whatever initializers
516e5dd7070Spatrick   // are allowed are empty and we just need to ignore them here.
517e5dd7070Spatrick   if (getLangOpts().CUDAIsDevice && !getLangOpts().GPUAllowDeviceInit &&
518e5dd7070Spatrick       (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() ||
519e5dd7070Spatrick        D->hasAttr<CUDASharedAttr>()))
520e5dd7070Spatrick     return;
521e5dd7070Spatrick 
522e5dd7070Spatrick   if (getLangOpts().OpenMP &&
523e5dd7070Spatrick       getOpenMPRuntime().emitDeclareTargetVarDefinition(D, Addr, PerformInit))
524e5dd7070Spatrick     return;
525e5dd7070Spatrick 
526e5dd7070Spatrick   // Check if we've already initialized this decl.
527e5dd7070Spatrick   auto I = DelayedCXXInitPosition.find(D);
528e5dd7070Spatrick   if (I != DelayedCXXInitPosition.end() && I->second == ~0U)
529e5dd7070Spatrick     return;
530e5dd7070Spatrick 
531e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
532e5dd7070Spatrick   SmallString<256> FnName;
533e5dd7070Spatrick   {
534e5dd7070Spatrick     llvm::raw_svector_ostream Out(FnName);
535e5dd7070Spatrick     getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);
536e5dd7070Spatrick   }
537e5dd7070Spatrick 
538e5dd7070Spatrick   // Create a variable initialization function.
539ec727ea7Spatrick   llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(
540ec727ea7Spatrick       FTy, FnName.str(), getTypes().arrangeNullaryFunction(), D->getLocation());
541e5dd7070Spatrick 
542e5dd7070Spatrick   auto *ISA = D->getAttr<InitSegAttr>();
543e5dd7070Spatrick   CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
544e5dd7070Spatrick                                                           PerformInit);
545e5dd7070Spatrick 
546e5dd7070Spatrick   llvm::GlobalVariable *COMDATKey =
547e5dd7070Spatrick       supportsCOMDAT() && D->isExternallyVisible() ? Addr : nullptr;
548e5dd7070Spatrick 
549e5dd7070Spatrick   if (D->getTLSKind()) {
550e5dd7070Spatrick     // FIXME: Should we support init_priority for thread_local?
551e5dd7070Spatrick     // FIXME: We only need to register one __cxa_thread_atexit function for the
552e5dd7070Spatrick     // entire TU.
553e5dd7070Spatrick     CXXThreadLocalInits.push_back(Fn);
554e5dd7070Spatrick     CXXThreadLocalInitVars.push_back(D);
555e5dd7070Spatrick   } else if (PerformInit && ISA) {
556*12c85518Srobert     // Contract with backend that "init_seg(compiler)" corresponds to priority
557*12c85518Srobert     // 200 and "init_seg(lib)" corresponds to priority 400.
558*12c85518Srobert     int Priority = -1;
559*12c85518Srobert     if (ISA->getSection() == ".CRT$XCC")
560*12c85518Srobert       Priority = 200;
561*12c85518Srobert     else if (ISA->getSection() == ".CRT$XCL")
562*12c85518Srobert       Priority = 400;
563*12c85518Srobert 
564*12c85518Srobert     if (Priority != -1)
565*12c85518Srobert       AddGlobalCtor(Fn, Priority, ~0U, COMDATKey);
566*12c85518Srobert     else
567e5dd7070Spatrick       EmitPointerToInitFunc(D, Addr, Fn, ISA);
568e5dd7070Spatrick   } else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {
569a9ac8606Spatrick     OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(),
570a9ac8606Spatrick                                           PrioritizedCXXGlobalInits.size());
571e5dd7070Spatrick     PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
572e5dd7070Spatrick   } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
573a9ac8606Spatrick              getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR ||
574a9ac8606Spatrick              D->hasAttr<SelectAnyAttr>()) {
575e5dd7070Spatrick     // C++ [basic.start.init]p2:
576e5dd7070Spatrick     //   Definitions of explicitly specialized class template static data
577e5dd7070Spatrick     //   members have ordered initialization. Other class template static data
578e5dd7070Spatrick     //   members (i.e., implicitly or explicitly instantiated specializations)
579e5dd7070Spatrick     //   have unordered initialization.
580e5dd7070Spatrick     //
581e5dd7070Spatrick     // As a consequence, we can put them into their own llvm.global_ctors entry.
582e5dd7070Spatrick     //
583e5dd7070Spatrick     // If the global is externally visible, put the initializer into a COMDAT
584e5dd7070Spatrick     // group with the global being initialized.  On most platforms, this is a
585e5dd7070Spatrick     // minor startup time optimization.  In the MS C++ ABI, there are no guard
586e5dd7070Spatrick     // variables, so this COMDAT key is required for correctness.
587a9ac8606Spatrick     //
588e5dd7070Spatrick     // SelectAny globals will be comdat-folded. Put the initializer into a
589e5dd7070Spatrick     // COMDAT group associated with the global, so the initializers get folded
590e5dd7070Spatrick     // too.
591*12c85518Srobert     I = DelayedCXXInitPosition.find(D);
592*12c85518Srobert     // CXXGlobalInits.size() is the lex order number for the next deferred
593*12c85518Srobert     // VarDecl. Use it when the current VarDecl is non-deferred. Although this
594*12c85518Srobert     // lex order number is shared between current VarDecl and some following
595*12c85518Srobert     // VarDecls, their order of insertion into `llvm.global_ctors` is the same
596*12c85518Srobert     // as the lexing order and the following stable sort would preserve such
597*12c85518Srobert     // order.
598*12c85518Srobert     unsigned LexOrder =
599*12c85518Srobert         I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
600*12c85518Srobert     AddGlobalCtor(Fn, 65535, LexOrder, COMDATKey);
601a9ac8606Spatrick     if (COMDATKey && (getTriple().isOSBinFormatELF() ||
602a9ac8606Spatrick                       getTarget().getCXXABI().isMicrosoft())) {
603a9ac8606Spatrick       // When COMDAT is used on ELF or in the MS C++ ABI, the key must be in
604a9ac8606Spatrick       // llvm.used to prevent linker GC.
605a9ac8606Spatrick       addUsedGlobal(COMDATKey);
606a9ac8606Spatrick     }
607*12c85518Srobert 
608*12c85518Srobert     // If we used a COMDAT key for the global ctor, the init function can be
609*12c85518Srobert     // discarded if the global ctor entry is discarded.
610*12c85518Srobert     // FIXME: Do we need to restrict this to ELF and Wasm?
611*12c85518Srobert     llvm::Comdat *C = Addr->getComdat();
612*12c85518Srobert     if (COMDATKey && C &&
613*12c85518Srobert         (getTarget().getTriple().isOSBinFormatELF() ||
614*12c85518Srobert          getTarget().getTriple().isOSBinFormatWasm())) {
615*12c85518Srobert       Fn->setComdat(C);
616*12c85518Srobert     }
617e5dd7070Spatrick   } else {
618e5dd7070Spatrick     I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash.
619e5dd7070Spatrick     if (I == DelayedCXXInitPosition.end()) {
620e5dd7070Spatrick       CXXGlobalInits.push_back(Fn);
621e5dd7070Spatrick     } else if (I->second != ~0U) {
622e5dd7070Spatrick       assert(I->second < CXXGlobalInits.size() &&
623e5dd7070Spatrick              CXXGlobalInits[I->second] == nullptr);
624e5dd7070Spatrick       CXXGlobalInits[I->second] = Fn;
625e5dd7070Spatrick     }
626e5dd7070Spatrick   }
627e5dd7070Spatrick 
628e5dd7070Spatrick   // Remember that we already emitted the initializer for this global.
629e5dd7070Spatrick   DelayedCXXInitPosition[D] = ~0U;
630e5dd7070Spatrick }
631e5dd7070Spatrick 
EmitCXXThreadLocalInitFunc()632e5dd7070Spatrick void CodeGenModule::EmitCXXThreadLocalInitFunc() {
633e5dd7070Spatrick   getCXXABI().EmitThreadLocalInitFuncs(
634e5dd7070Spatrick       *this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
635e5dd7070Spatrick 
636e5dd7070Spatrick   CXXThreadLocalInits.clear();
637e5dd7070Spatrick   CXXThreadLocalInitVars.clear();
638e5dd7070Spatrick   CXXThreadLocals.clear();
639e5dd7070Spatrick }
640e5dd7070Spatrick 
641*12c85518Srobert /* Build the initializer for a C++20 module:
642*12c85518Srobert    This is arranged to be run only once regardless of how many times the module
643*12c85518Srobert    might be included transitively.  This arranged by using a guard variable.
644*12c85518Srobert 
645*12c85518Srobert    If there are no initalizers at all (and also no imported modules) we reduce
646*12c85518Srobert    this to an empty function (since the Itanium ABI requires that this function
647*12c85518Srobert    be available to a caller, which might be produced by a different
648*12c85518Srobert    implementation).
649*12c85518Srobert 
650*12c85518Srobert    First we call any initializers for imported modules.
651*12c85518Srobert    We then call initializers for the Global Module Fragment (if present)
652*12c85518Srobert    We then call initializers for the current module.
653*12c85518Srobert    We then call initializers for the Private Module Fragment (if present)
654*12c85518Srobert */
655*12c85518Srobert 
EmitCXXModuleInitFunc(Module * Primary)656*12c85518Srobert void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
657*12c85518Srobert   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
658*12c85518Srobert     CXXGlobalInits.pop_back();
659*12c85518Srobert 
660*12c85518Srobert   // As noted above, we create the function, even if it is empty.
661*12c85518Srobert   // Module initializers for imported modules are emitted first.
662*12c85518Srobert 
663*12c85518Srobert   // Collect all the modules that we import
664*12c85518Srobert   SmallVector<Module *> AllImports;
665*12c85518Srobert   // Ones that we export
666*12c85518Srobert   for (auto I : Primary->Exports)
667*12c85518Srobert     AllImports.push_back(I.getPointer());
668*12c85518Srobert   // Ones that we only import.
669*12c85518Srobert   for (Module *M : Primary->Imports)
670*12c85518Srobert     AllImports.push_back(M);
671*12c85518Srobert 
672*12c85518Srobert   SmallVector<llvm::Function *, 8> ModuleInits;
673*12c85518Srobert   for (Module *M : AllImports) {
674*12c85518Srobert     // No Itanium initializer in header like modules.
675*12c85518Srobert     if (M->isHeaderLikeModule())
676*12c85518Srobert       continue; // TODO: warn of mixed use of module map modules and C++20?
677*12c85518Srobert     llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
678*12c85518Srobert     SmallString<256> FnName;
679*12c85518Srobert     {
680*12c85518Srobert       llvm::raw_svector_ostream Out(FnName);
681*12c85518Srobert       cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
682*12c85518Srobert           .mangleModuleInitializer(M, Out);
683*12c85518Srobert     }
684*12c85518Srobert     assert(!GetGlobalValue(FnName.str()) &&
685*12c85518Srobert            "We should only have one use of the initializer call");
686*12c85518Srobert     llvm::Function *Fn = llvm::Function::Create(
687*12c85518Srobert         FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());
688*12c85518Srobert     ModuleInits.push_back(Fn);
689*12c85518Srobert   }
690*12c85518Srobert 
691*12c85518Srobert   // Add any initializers with specified priority; this uses the same  approach
692*12c85518Srobert   // as EmitCXXGlobalInitFunc().
693*12c85518Srobert   if (!PrioritizedCXXGlobalInits.empty()) {
694*12c85518Srobert     SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
695*12c85518Srobert     llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
696*12c85518Srobert                          PrioritizedCXXGlobalInits.end());
697*12c85518Srobert     for (SmallVectorImpl<GlobalInitData>::iterator
698*12c85518Srobert              I = PrioritizedCXXGlobalInits.begin(),
699*12c85518Srobert              E = PrioritizedCXXGlobalInits.end();
700*12c85518Srobert          I != E;) {
701*12c85518Srobert       SmallVectorImpl<GlobalInitData>::iterator PrioE =
702*12c85518Srobert           std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
703*12c85518Srobert 
704*12c85518Srobert       for (; I < PrioE; ++I)
705*12c85518Srobert         ModuleInits.push_back(I->second);
706*12c85518Srobert     }
707*12c85518Srobert   }
708*12c85518Srobert 
709*12c85518Srobert   // Now append the ones without specified priority.
710*12c85518Srobert   for (auto *F : CXXGlobalInits)
711*12c85518Srobert     ModuleInits.push_back(F);
712*12c85518Srobert 
713*12c85518Srobert   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
714*12c85518Srobert   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
715*12c85518Srobert 
716*12c85518Srobert   // We now build the initializer for this module, which has a mangled name
717*12c85518Srobert   // as per the Itanium ABI .  The action of the initializer is guarded so that
718*12c85518Srobert   // each init is run just once (even though a module might be imported
719*12c85518Srobert   // multiple times via nested use).
720*12c85518Srobert   llvm::Function *Fn;
721*12c85518Srobert   {
722*12c85518Srobert     SmallString<256> InitFnName;
723*12c85518Srobert     llvm::raw_svector_ostream Out(InitFnName);
724*12c85518Srobert     cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
725*12c85518Srobert         .mangleModuleInitializer(Primary, Out);
726*12c85518Srobert     Fn = CreateGlobalInitOrCleanUpFunction(
727*12c85518Srobert         FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,
728*12c85518Srobert         llvm::GlobalVariable::ExternalLinkage);
729*12c85518Srobert 
730*12c85518Srobert     // If we have a completely empty initializer then we do not want to create
731*12c85518Srobert     // the guard variable.
732*12c85518Srobert     ConstantAddress GuardAddr = ConstantAddress::invalid();
733*12c85518Srobert     if (!AllImports.empty() || !PrioritizedCXXGlobalInits.empty() ||
734*12c85518Srobert         !CXXGlobalInits.empty()) {
735*12c85518Srobert       // Create the guard var.
736*12c85518Srobert       llvm::GlobalVariable *Guard = new llvm::GlobalVariable(
737*12c85518Srobert           getModule(), Int8Ty, /*isConstant=*/false,
738*12c85518Srobert           llvm::GlobalVariable::InternalLinkage,
739*12c85518Srobert           llvm::ConstantInt::get(Int8Ty, 0), InitFnName.str() + "__in_chrg");
740*12c85518Srobert       CharUnits GuardAlign = CharUnits::One();
741*12c85518Srobert       Guard->setAlignment(GuardAlign.getAsAlign());
742*12c85518Srobert       GuardAddr = ConstantAddress(Guard, Int8Ty, GuardAlign);
743*12c85518Srobert     }
744*12c85518Srobert     CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,
745*12c85518Srobert                                                      GuardAddr);
746*12c85518Srobert   }
747*12c85518Srobert 
748*12c85518Srobert   // We allow for the case that a module object is added to a linked binary
749*12c85518Srobert   // without a specific call to the the initializer.  This also ensures that
750*12c85518Srobert   // implementation partition initializers are called when the partition
751*12c85518Srobert   // is not imported as an interface.
752*12c85518Srobert   AddGlobalCtor(Fn);
753*12c85518Srobert 
754*12c85518Srobert   // See the comment in EmitCXXGlobalInitFunc about OpenCL global init
755*12c85518Srobert   // functions.
756*12c85518Srobert   if (getLangOpts().OpenCL) {
757*12c85518Srobert     GenKernelArgMetadata(Fn);
758*12c85518Srobert     Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
759*12c85518Srobert   }
760*12c85518Srobert 
761*12c85518Srobert   assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice ||
762*12c85518Srobert          getLangOpts().GPUAllowDeviceInit);
763*12c85518Srobert   if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) {
764*12c85518Srobert     Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
765*12c85518Srobert     Fn->addFnAttr("device-init");
766*12c85518Srobert   }
767*12c85518Srobert 
768*12c85518Srobert   // We are done with the inits.
769*12c85518Srobert   AllImports.clear();
770*12c85518Srobert   PrioritizedCXXGlobalInits.clear();
771*12c85518Srobert   CXXGlobalInits.clear();
772*12c85518Srobert   ModuleInits.clear();
773*12c85518Srobert }
774*12c85518Srobert 
getTransformedFileName(llvm::Module & M)775ec727ea7Spatrick static SmallString<128> getTransformedFileName(llvm::Module &M) {
776ec727ea7Spatrick   SmallString<128> FileName = llvm::sys::path::filename(M.getName());
777ec727ea7Spatrick 
778ec727ea7Spatrick   if (FileName.empty())
779ec727ea7Spatrick     FileName = "<null>";
780ec727ea7Spatrick 
781ec727ea7Spatrick   for (size_t i = 0; i < FileName.size(); ++i) {
782ec727ea7Spatrick     // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
783ec727ea7Spatrick     // to be the set of C preprocessing numbers.
784ec727ea7Spatrick     if (!isPreprocessingNumberBody(FileName[i]))
785ec727ea7Spatrick       FileName[i] = '_';
786ec727ea7Spatrick   }
787ec727ea7Spatrick 
788ec727ea7Spatrick   return FileName;
789ec727ea7Spatrick }
790ec727ea7Spatrick 
getPrioritySuffix(unsigned int Priority)791a9ac8606Spatrick static std::string getPrioritySuffix(unsigned int Priority) {
792a9ac8606Spatrick   assert(Priority <= 65535 && "Priority should always be <= 65535.");
793a9ac8606Spatrick 
794a9ac8606Spatrick   // Compute the function suffix from priority. Prepend with zeroes to make
795a9ac8606Spatrick   // sure the function names are also ordered as priorities.
796a9ac8606Spatrick   std::string PrioritySuffix = llvm::utostr(Priority);
797a9ac8606Spatrick   PrioritySuffix = std::string(6 - PrioritySuffix.size(), '0') + PrioritySuffix;
798a9ac8606Spatrick 
799a9ac8606Spatrick   return PrioritySuffix;
800a9ac8606Spatrick }
801a9ac8606Spatrick 
802e5dd7070Spatrick void
EmitCXXGlobalInitFunc()803e5dd7070Spatrick CodeGenModule::EmitCXXGlobalInitFunc() {
804e5dd7070Spatrick   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
805e5dd7070Spatrick     CXXGlobalInits.pop_back();
806e5dd7070Spatrick 
807*12c85518Srobert   // When we import C++20 modules, we must run their initializers first.
808*12c85518Srobert   SmallVector<llvm::Function *, 8> ModuleInits;
809*12c85518Srobert   if (CXX20ModuleInits)
810*12c85518Srobert     for (Module *M : ImportedModules) {
811*12c85518Srobert       // No Itanium initializer in header like modules.
812*12c85518Srobert       if (M->isHeaderLikeModule())
813*12c85518Srobert         continue;
814*12c85518Srobert       llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
815*12c85518Srobert       SmallString<256> FnName;
816*12c85518Srobert       {
817*12c85518Srobert         llvm::raw_svector_ostream Out(FnName);
818*12c85518Srobert         cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
819*12c85518Srobert             .mangleModuleInitializer(M, Out);
820*12c85518Srobert       }
821*12c85518Srobert       assert(!GetGlobalValue(FnName.str()) &&
822*12c85518Srobert              "We should only have one use of the initializer call");
823*12c85518Srobert       llvm::Function *Fn = llvm::Function::Create(
824*12c85518Srobert           FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());
825*12c85518Srobert       ModuleInits.push_back(Fn);
826*12c85518Srobert     }
827*12c85518Srobert 
828*12c85518Srobert   if (ModuleInits.empty() && CXXGlobalInits.empty() &&
829*12c85518Srobert       PrioritizedCXXGlobalInits.empty())
830e5dd7070Spatrick     return;
831e5dd7070Spatrick 
832e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
833e5dd7070Spatrick   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
834e5dd7070Spatrick 
835ec727ea7Spatrick   // Create our global prioritized initialization function.
836e5dd7070Spatrick   if (!PrioritizedCXXGlobalInits.empty()) {
837e5dd7070Spatrick     SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
838e5dd7070Spatrick     llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
839e5dd7070Spatrick                          PrioritizedCXXGlobalInits.end());
840e5dd7070Spatrick     // Iterate over "chunks" of ctors with same priority and emit each chunk
841e5dd7070Spatrick     // into separate function. Note - everything is sorted first by priority,
842e5dd7070Spatrick     // second - by lex order, so we emit ctor functions in proper order.
843e5dd7070Spatrick     for (SmallVectorImpl<GlobalInitData >::iterator
844e5dd7070Spatrick            I = PrioritizedCXXGlobalInits.begin(),
845e5dd7070Spatrick            E = PrioritizedCXXGlobalInits.end(); I != E; ) {
846e5dd7070Spatrick       SmallVectorImpl<GlobalInitData >::iterator
847e5dd7070Spatrick         PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
848e5dd7070Spatrick 
849e5dd7070Spatrick       LocalCXXGlobalInits.clear();
850a9ac8606Spatrick 
851a9ac8606Spatrick       unsigned int Priority = I->first.priority;
852ec727ea7Spatrick       llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(
853a9ac8606Spatrick           FTy, "_GLOBAL__I_" + getPrioritySuffix(Priority), FI);
854e5dd7070Spatrick 
855*12c85518Srobert       // Prepend the module inits to the highest priority set.
856*12c85518Srobert       if (!ModuleInits.empty()) {
857*12c85518Srobert         for (auto *F : ModuleInits)
858*12c85518Srobert           LocalCXXGlobalInits.push_back(F);
859*12c85518Srobert         ModuleInits.clear();
860*12c85518Srobert       }
861*12c85518Srobert 
862e5dd7070Spatrick       for (; I < PrioE; ++I)
863e5dd7070Spatrick         LocalCXXGlobalInits.push_back(I->second);
864e5dd7070Spatrick 
865e5dd7070Spatrick       CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits);
866e5dd7070Spatrick       AddGlobalCtor(Fn, Priority);
867e5dd7070Spatrick     }
868e5dd7070Spatrick     PrioritizedCXXGlobalInits.clear();
869e5dd7070Spatrick   }
870e5dd7070Spatrick 
871*12c85518Srobert   if (getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&
872*12c85518Srobert       CXXGlobalInits.empty())
873ec727ea7Spatrick     return;
874e5dd7070Spatrick 
875*12c85518Srobert   for (auto *F : CXXGlobalInits)
876*12c85518Srobert     ModuleInits.push_back(F);
877*12c85518Srobert   CXXGlobalInits.clear();
878*12c85518Srobert 
879ec727ea7Spatrick   // Include the filename in the symbol name. Including "sub_" matches gcc
880ec727ea7Spatrick   // and makes sure these symbols appear lexicographically behind the symbols
881ec727ea7Spatrick   // with priority emitted above.
882*12c85518Srobert   llvm::Function *Fn;
883*12c85518Srobert   if (CXX20ModuleInits && getContext().getModuleForCodeGen()) {
884*12c85518Srobert     SmallString<256> InitFnName;
885*12c85518Srobert     llvm::raw_svector_ostream Out(InitFnName);
886*12c85518Srobert     cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
887*12c85518Srobert         .mangleModuleInitializer(getContext().getModuleForCodeGen(), Out);
888*12c85518Srobert     Fn = CreateGlobalInitOrCleanUpFunction(
889*12c85518Srobert         FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,
890*12c85518Srobert         llvm::GlobalVariable::ExternalLinkage);
891*12c85518Srobert   } else
892*12c85518Srobert     Fn = CreateGlobalInitOrCleanUpFunction(
893*12c85518Srobert         FTy,
894*12c85518Srobert         llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())),
895a9ac8606Spatrick         FI);
896e5dd7070Spatrick 
897*12c85518Srobert   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits);
898e5dd7070Spatrick   AddGlobalCtor(Fn);
899e5dd7070Spatrick 
900e5dd7070Spatrick   // In OpenCL global init functions must be converted to kernels in order to
901e5dd7070Spatrick   // be able to launch them from the host.
902e5dd7070Spatrick   // FIXME: Some more work might be needed to handle destructors correctly.
903e5dd7070Spatrick   // Current initialization function makes use of function pointers callbacks.
904e5dd7070Spatrick   // We can't support function pointers especially between host and device.
905e5dd7070Spatrick   // However it seems global destruction has little meaning without any
906e5dd7070Spatrick   // dynamic resource allocation on the device and program scope variables are
907e5dd7070Spatrick   // destroyed by the runtime when program is released.
908e5dd7070Spatrick   if (getLangOpts().OpenCL) {
909*12c85518Srobert     GenKernelArgMetadata(Fn);
910e5dd7070Spatrick     Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
911e5dd7070Spatrick   }
912e5dd7070Spatrick 
913a9ac8606Spatrick   assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice ||
914a9ac8606Spatrick          getLangOpts().GPUAllowDeviceInit);
915a9ac8606Spatrick   if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) {
916e5dd7070Spatrick     Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
917e5dd7070Spatrick     Fn->addFnAttr("device-init");
918e5dd7070Spatrick   }
919e5dd7070Spatrick 
920*12c85518Srobert   ModuleInits.clear();
921e5dd7070Spatrick }
922e5dd7070Spatrick 
EmitCXXGlobalCleanUpFunc()923ec727ea7Spatrick void CodeGenModule::EmitCXXGlobalCleanUpFunc() {
924a9ac8606Spatrick   if (CXXGlobalDtorsOrStermFinalizers.empty() &&
925a9ac8606Spatrick       PrioritizedCXXStermFinalizers.empty())
926e5dd7070Spatrick     return;
927e5dd7070Spatrick 
928e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
929e5dd7070Spatrick   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
930e5dd7070Spatrick 
931a9ac8606Spatrick   // Create our global prioritized cleanup function.
932a9ac8606Spatrick   if (!PrioritizedCXXStermFinalizers.empty()) {
933a9ac8606Spatrick     SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers;
934a9ac8606Spatrick     llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),
935a9ac8606Spatrick                          PrioritizedCXXStermFinalizers.end());
936a9ac8606Spatrick     // Iterate over "chunks" of dtors with same priority and emit each chunk
937a9ac8606Spatrick     // into separate function. Note - everything is sorted first by priority,
938a9ac8606Spatrick     // second - by lex order, so we emit dtor functions in proper order.
939a9ac8606Spatrick     for (SmallVectorImpl<StermFinalizerData>::iterator
940a9ac8606Spatrick              I = PrioritizedCXXStermFinalizers.begin(),
941a9ac8606Spatrick              E = PrioritizedCXXStermFinalizers.end();
942a9ac8606Spatrick          I != E;) {
943a9ac8606Spatrick       SmallVectorImpl<StermFinalizerData>::iterator PrioE =
944a9ac8606Spatrick           std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());
945a9ac8606Spatrick 
946a9ac8606Spatrick       LocalCXXStermFinalizers.clear();
947a9ac8606Spatrick 
948a9ac8606Spatrick       unsigned int Priority = I->first.priority;
949a9ac8606Spatrick       llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(
950a9ac8606Spatrick           FTy, "_GLOBAL__a_" + getPrioritySuffix(Priority), FI);
951a9ac8606Spatrick 
952a9ac8606Spatrick       for (; I < PrioE; ++I) {
953a9ac8606Spatrick         llvm::FunctionCallee DtorFn = I->second;
954a9ac8606Spatrick         LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),
955a9ac8606Spatrick                                              DtorFn.getCallee(), nullptr);
956ec727ea7Spatrick       }
957ec727ea7Spatrick 
958a9ac8606Spatrick       CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
959a9ac8606Spatrick           Fn, LocalCXXStermFinalizers);
960a9ac8606Spatrick       AddGlobalDtor(Fn, Priority);
961ec727ea7Spatrick     }
962a9ac8606Spatrick     PrioritizedCXXStermFinalizers.clear();
963a9ac8606Spatrick   }
964a9ac8606Spatrick 
965a9ac8606Spatrick   if (CXXGlobalDtorsOrStermFinalizers.empty())
966a9ac8606Spatrick     return;
967a9ac8606Spatrick 
968a9ac8606Spatrick   // Create our global cleanup function.
969a9ac8606Spatrick   llvm::Function *Fn =
970a9ac8606Spatrick       CreateGlobalInitOrCleanUpFunction(FTy, "_GLOBAL__D_a", FI);
971ec727ea7Spatrick 
972ec727ea7Spatrick   CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
973ec727ea7Spatrick       Fn, CXXGlobalDtorsOrStermFinalizers);
974e5dd7070Spatrick   AddGlobalDtor(Fn);
975ec727ea7Spatrick   CXXGlobalDtorsOrStermFinalizers.clear();
976e5dd7070Spatrick }
977e5dd7070Spatrick 
978e5dd7070Spatrick /// Emit the code necessary to initialize the given global variable.
GenerateCXXGlobalVarDeclInitFunc(llvm::Function * Fn,const VarDecl * D,llvm::GlobalVariable * Addr,bool PerformInit)979e5dd7070Spatrick void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
980e5dd7070Spatrick                                                        const VarDecl *D,
981e5dd7070Spatrick                                                  llvm::GlobalVariable *Addr,
982e5dd7070Spatrick                                                        bool PerformInit) {
983e5dd7070Spatrick   // Check if we need to emit debug info for variable initializer.
984e5dd7070Spatrick   if (D->hasAttr<NoDebugAttr>())
985e5dd7070Spatrick     DebugInfo = nullptr; // disable debug info indefinitely for this function
986e5dd7070Spatrick 
987e5dd7070Spatrick   CurEHLocation = D->getBeginLoc();
988e5dd7070Spatrick 
989e5dd7070Spatrick   StartFunction(GlobalDecl(D, DynamicInitKind::Initializer),
990e5dd7070Spatrick                 getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(),
991a9ac8606Spatrick                 FunctionArgList());
992a9ac8606Spatrick   // Emit an artificial location for this function.
993a9ac8606Spatrick   auto AL = ApplyDebugLocation::CreateArtificial(*this);
994e5dd7070Spatrick 
995e5dd7070Spatrick   // Use guarded initialization if the global variable is weak. This
996e5dd7070Spatrick   // occurs for, e.g., instantiated static data members and
997e5dd7070Spatrick   // definitions explicitly marked weak.
998e5dd7070Spatrick   //
999e5dd7070Spatrick   // Also use guarded initialization for a variable with dynamic TLS and
1000e5dd7070Spatrick   // unordered initialization. (If the initialization is ordered, the ABI
1001e5dd7070Spatrick   // layer will guard the whole-TU initialization for us.)
1002e5dd7070Spatrick   if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage() ||
1003e5dd7070Spatrick       (D->getTLSKind() == VarDecl::TLS_Dynamic &&
1004e5dd7070Spatrick        isTemplateInstantiation(D->getTemplateSpecializationKind()))) {
1005e5dd7070Spatrick     EmitCXXGuardedInit(*D, Addr, PerformInit);
1006e5dd7070Spatrick   } else {
1007e5dd7070Spatrick     EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
1008e5dd7070Spatrick   }
1009e5dd7070Spatrick 
1010*12c85518Srobert   if (getLangOpts().HLSL)
1011*12c85518Srobert     CGM.getHLSLRuntime().annotateHLSLResource(D, Addr);
1012*12c85518Srobert 
1013e5dd7070Spatrick   FinishFunction();
1014e5dd7070Spatrick }
1015e5dd7070Spatrick 
1016e5dd7070Spatrick void
GenerateCXXGlobalInitFunc(llvm::Function * Fn,ArrayRef<llvm::Function * > Decls,ConstantAddress Guard)1017e5dd7070Spatrick CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
1018e5dd7070Spatrick                                            ArrayRef<llvm::Function *> Decls,
1019e5dd7070Spatrick                                            ConstantAddress Guard) {
1020e5dd7070Spatrick   {
1021e5dd7070Spatrick     auto NL = ApplyDebugLocation::CreateEmpty(*this);
1022e5dd7070Spatrick     StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
1023e5dd7070Spatrick                   getTypes().arrangeNullaryFunction(), FunctionArgList());
1024e5dd7070Spatrick     // Emit an artificial location for this function.
1025e5dd7070Spatrick     auto AL = ApplyDebugLocation::CreateArtificial(*this);
1026e5dd7070Spatrick 
1027e5dd7070Spatrick     llvm::BasicBlock *ExitBlock = nullptr;
1028e5dd7070Spatrick     if (Guard.isValid()) {
1029e5dd7070Spatrick       // If we have a guard variable, check whether we've already performed
1030e5dd7070Spatrick       // these initializations. This happens for TLS initialization functions.
1031e5dd7070Spatrick       llvm::Value *GuardVal = Builder.CreateLoad(Guard);
1032e5dd7070Spatrick       llvm::Value *Uninit = Builder.CreateIsNull(GuardVal,
1033e5dd7070Spatrick                                                  "guard.uninitialized");
1034e5dd7070Spatrick       llvm::BasicBlock *InitBlock = createBasicBlock("init");
1035e5dd7070Spatrick       ExitBlock = createBasicBlock("exit");
1036e5dd7070Spatrick       EmitCXXGuardedInitBranch(Uninit, InitBlock, ExitBlock,
1037e5dd7070Spatrick                                GuardKind::TlsGuard, nullptr);
1038e5dd7070Spatrick       EmitBlock(InitBlock);
1039e5dd7070Spatrick       // Mark as initialized before initializing anything else. If the
1040e5dd7070Spatrick       // initializers use previously-initialized thread_local vars, that's
1041e5dd7070Spatrick       // probably supposed to be OK, but the standard doesn't say.
1042e5dd7070Spatrick       Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
1043e5dd7070Spatrick 
1044e5dd7070Spatrick       // The guard variable can't ever change again.
1045e5dd7070Spatrick       EmitInvariantStart(
1046e5dd7070Spatrick           Guard.getPointer(),
1047e5dd7070Spatrick           CharUnits::fromQuantity(
1048e5dd7070Spatrick               CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())));
1049e5dd7070Spatrick     }
1050e5dd7070Spatrick 
1051e5dd7070Spatrick     RunCleanupsScope Scope(*this);
1052e5dd7070Spatrick 
1053e5dd7070Spatrick     // When building in Objective-C++ ARC mode, create an autorelease pool
1054e5dd7070Spatrick     // around the global initializers.
1055e5dd7070Spatrick     if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) {
1056e5dd7070Spatrick       llvm::Value *token = EmitObjCAutoreleasePoolPush();
1057e5dd7070Spatrick       EmitObjCAutoreleasePoolCleanup(token);
1058e5dd7070Spatrick     }
1059e5dd7070Spatrick 
1060e5dd7070Spatrick     for (unsigned i = 0, e = Decls.size(); i != e; ++i)
1061e5dd7070Spatrick       if (Decls[i])
1062e5dd7070Spatrick         EmitRuntimeCall(Decls[i]);
1063e5dd7070Spatrick 
1064e5dd7070Spatrick     Scope.ForceCleanup();
1065e5dd7070Spatrick 
1066e5dd7070Spatrick     if (ExitBlock) {
1067e5dd7070Spatrick       Builder.CreateBr(ExitBlock);
1068e5dd7070Spatrick       EmitBlock(ExitBlock);
1069e5dd7070Spatrick     }
1070e5dd7070Spatrick   }
1071e5dd7070Spatrick 
1072e5dd7070Spatrick   FinishFunction();
1073e5dd7070Spatrick }
1074e5dd7070Spatrick 
GenerateCXXGlobalCleanUpFunc(llvm::Function * Fn,ArrayRef<std::tuple<llvm::FunctionType *,llvm::WeakTrackingVH,llvm::Constant * >> DtorsOrStermFinalizers)1075ec727ea7Spatrick void CodeGenFunction::GenerateCXXGlobalCleanUpFunc(
1076e5dd7070Spatrick     llvm::Function *Fn,
1077a9ac8606Spatrick     ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
1078a9ac8606Spatrick                         llvm::Constant *>>
1079a9ac8606Spatrick         DtorsOrStermFinalizers) {
1080e5dd7070Spatrick   {
1081e5dd7070Spatrick     auto NL = ApplyDebugLocation::CreateEmpty(*this);
1082e5dd7070Spatrick     StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
1083e5dd7070Spatrick                   getTypes().arrangeNullaryFunction(), FunctionArgList());
1084e5dd7070Spatrick     // Emit an artificial location for this function.
1085e5dd7070Spatrick     auto AL = ApplyDebugLocation::CreateArtificial(*this);
1086e5dd7070Spatrick 
1087ec727ea7Spatrick     // Emit the cleanups, in reverse order from construction.
1088ec727ea7Spatrick     for (unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {
1089e5dd7070Spatrick       llvm::FunctionType *CalleeTy;
1090e5dd7070Spatrick       llvm::Value *Callee;
1091e5dd7070Spatrick       llvm::Constant *Arg;
1092ec727ea7Spatrick       std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
1093ec727ea7Spatrick 
1094ec727ea7Spatrick       llvm::CallInst *CI = nullptr;
1095ec727ea7Spatrick       if (Arg == nullptr) {
1096ec727ea7Spatrick         assert(
1097ec727ea7Spatrick             CGM.getCXXABI().useSinitAndSterm() &&
1098ec727ea7Spatrick             "Arg could not be nullptr unless using sinit and sterm functions.");
1099ec727ea7Spatrick         CI = Builder.CreateCall(CalleeTy, Callee);
1100ec727ea7Spatrick       } else
1101ec727ea7Spatrick         CI = Builder.CreateCall(CalleeTy, Callee, Arg);
1102ec727ea7Spatrick 
1103e5dd7070Spatrick       // Make sure the call and the callee agree on calling convention.
1104e5dd7070Spatrick       if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
1105e5dd7070Spatrick         CI->setCallingConv(F->getCallingConv());
1106e5dd7070Spatrick     }
1107e5dd7070Spatrick   }
1108e5dd7070Spatrick 
1109e5dd7070Spatrick   FinishFunction();
1110e5dd7070Spatrick }
1111e5dd7070Spatrick 
1112e5dd7070Spatrick /// generateDestroyHelper - Generates a helper function which, when
1113e5dd7070Spatrick /// invoked, destroys the given object.  The address of the object
1114e5dd7070Spatrick /// should be in global memory.
generateDestroyHelper(Address addr,QualType type,Destroyer * destroyer,bool useEHCleanupForArray,const VarDecl * VD)1115e5dd7070Spatrick llvm::Function *CodeGenFunction::generateDestroyHelper(
1116e5dd7070Spatrick     Address addr, QualType type, Destroyer *destroyer,
1117e5dd7070Spatrick     bool useEHCleanupForArray, const VarDecl *VD) {
1118e5dd7070Spatrick   FunctionArgList args;
1119e5dd7070Spatrick   ImplicitParamDecl Dst(getContext(), getContext().VoidPtrTy,
1120e5dd7070Spatrick                         ImplicitParamDecl::Other);
1121e5dd7070Spatrick   args.push_back(&Dst);
1122e5dd7070Spatrick 
1123e5dd7070Spatrick   const CGFunctionInfo &FI =
1124e5dd7070Spatrick     CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, args);
1125e5dd7070Spatrick   llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
1126ec727ea7Spatrick   llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(
1127e5dd7070Spatrick       FTy, "__cxx_global_array_dtor", FI, VD->getLocation());
1128e5dd7070Spatrick 
1129e5dd7070Spatrick   CurEHLocation = VD->getBeginLoc();
1130e5dd7070Spatrick 
1131a9ac8606Spatrick   StartFunction(GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor),
1132a9ac8606Spatrick                 getContext().VoidTy, fn, FI, args);
1133a9ac8606Spatrick   // Emit an artificial location for this function.
1134a9ac8606Spatrick   auto AL = ApplyDebugLocation::CreateArtificial(*this);
1135e5dd7070Spatrick 
1136e5dd7070Spatrick   emitDestroy(addr, type, destroyer, useEHCleanupForArray);
1137e5dd7070Spatrick 
1138e5dd7070Spatrick   FinishFunction();
1139e5dd7070Spatrick 
1140e5dd7070Spatrick   return fn;
1141e5dd7070Spatrick }
1142