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