xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This contains code dealing with code generation of C++ declarations
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "CGCXXABI.h"
14bdd1243dSDimitry Andric #include "CGHLSLRuntime.h"
150b57cec5SDimitry Andric #include "CGObjCRuntime.h"
160b57cec5SDimitry Andric #include "CGOpenMPRuntime.h"
17480093f4SDimitry Andric #include "CodeGenFunction.h"
180b57cec5SDimitry Andric #include "TargetInfo.h"
19480093f4SDimitry Andric #include "clang/AST/Attr.h"
205ffd83dbSDimitry Andric #include "clang/Basic/LangOptions.h"
210b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
220b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
230b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
240b57cec5SDimitry Andric #include "llvm/Support/Path.h"
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace clang;
270b57cec5SDimitry Andric using namespace CodeGen;
280b57cec5SDimitry Andric 
EmitDeclInit(CodeGenFunction & CGF,const VarDecl & D,ConstantAddress DeclPtr)290b57cec5SDimitry Andric static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
300b57cec5SDimitry Andric                          ConstantAddress DeclPtr) {
310b57cec5SDimitry Andric   assert(
320b57cec5SDimitry Andric       (D.hasGlobalStorage() ||
330b57cec5SDimitry Andric        (D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) &&
340b57cec5SDimitry Andric       "VarDecl must have global or local (in the case of OpenCL) storage!");
350b57cec5SDimitry Andric   assert(!D.getType()->isReferenceType() &&
360b57cec5SDimitry Andric          "Should not call EmitDeclInit on a reference!");
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   QualType type = D.getType();
390b57cec5SDimitry Andric   LValue lv = CGF.MakeAddrLValue(DeclPtr, type);
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   const Expr *Init = D.getInit();
420b57cec5SDimitry Andric   switch (CGF.getEvaluationKind(type)) {
430b57cec5SDimitry Andric   case TEK_Scalar: {
440b57cec5SDimitry Andric     CodeGenModule &CGM = CGF.CGM;
450b57cec5SDimitry Andric     if (lv.isObjCStrong())
460b57cec5SDimitry Andric       CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init),
470b57cec5SDimitry Andric                                                 DeclPtr, D.getTLSKind());
480b57cec5SDimitry Andric     else if (lv.isObjCWeak())
490b57cec5SDimitry Andric       CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init),
500b57cec5SDimitry Andric                                               DeclPtr);
510b57cec5SDimitry Andric     else
520b57cec5SDimitry Andric       CGF.EmitScalarInit(Init, &D, lv, false);
530b57cec5SDimitry Andric     return;
540b57cec5SDimitry Andric   }
550b57cec5SDimitry Andric   case TEK_Complex:
560b57cec5SDimitry Andric     CGF.EmitComplexExprIntoLValue(Init, lv, /*isInit*/ true);
570b57cec5SDimitry Andric     return;
580b57cec5SDimitry Andric   case TEK_Aggregate:
59480093f4SDimitry Andric     CGF.EmitAggExpr(Init,
60*0fca6ea1SDimitry Andric                     AggValueSlot::forLValue(lv, AggValueSlot::IsDestructed,
610b57cec5SDimitry Andric                                             AggValueSlot::DoesNotNeedGCBarriers,
620b57cec5SDimitry Andric                                             AggValueSlot::IsNotAliased,
630b57cec5SDimitry Andric                                             AggValueSlot::DoesNotOverlap));
640b57cec5SDimitry Andric     return;
650b57cec5SDimitry Andric   }
660b57cec5SDimitry Andric   llvm_unreachable("bad evaluation kind");
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric /// Emit code to cause the destruction of the given variable with
700b57cec5SDimitry Andric /// static storage duration.
EmitDeclDestroy(CodeGenFunction & CGF,const VarDecl & D,ConstantAddress Addr)710b57cec5SDimitry Andric static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
720b57cec5SDimitry Andric                             ConstantAddress Addr) {
730b57cec5SDimitry Andric   // Honor __attribute__((no_destroy)) and bail instead of attempting
740b57cec5SDimitry Andric   // to emit a reference to a possibly nonexistent destructor, which
750b57cec5SDimitry Andric   // in turn can cause a crash. This will result in a global constructor
760b57cec5SDimitry Andric   // that isn't balanced out by a destructor call as intended by the
770b57cec5SDimitry Andric   // attribute. This also checks for -fno-c++-static-destructors and
780b57cec5SDimitry Andric   // bails even if the attribute is not present.
79a7dea167SDimitry Andric   QualType::DestructionKind DtorKind = D.needsDestruction(CGF.getContext());
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   // FIXME:  __attribute__((cleanup)) ?
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric   switch (DtorKind) {
840b57cec5SDimitry Andric   case QualType::DK_none:
850b57cec5SDimitry Andric     return;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   case QualType::DK_cxx_destructor:
880b57cec5SDimitry Andric     break;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   case QualType::DK_objc_strong_lifetime:
910b57cec5SDimitry Andric   case QualType::DK_objc_weak_lifetime:
920b57cec5SDimitry Andric   case QualType::DK_nontrivial_c_struct:
930b57cec5SDimitry Andric     // We don't care about releasing objects during process teardown.
940b57cec5SDimitry Andric     assert(!D.getTLSKind() && "should have rejected this");
950b57cec5SDimitry Andric     return;
960b57cec5SDimitry Andric   }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   llvm::FunctionCallee Func;
990b57cec5SDimitry Andric   llvm::Constant *Argument;
1000b57cec5SDimitry Andric 
101a7dea167SDimitry Andric   CodeGenModule &CGM = CGF.CGM;
102a7dea167SDimitry Andric   QualType Type = D.getType();
103a7dea167SDimitry Andric 
1040b57cec5SDimitry Andric   // Special-case non-array C++ destructors, if they have the right signature.
1050b57cec5SDimitry Andric   // Under some ABIs, destructors return this instead of void, and cannot be
1060b57cec5SDimitry Andric   // passed directly to __cxa_atexit if the target does not allow this
1070b57cec5SDimitry Andric   // mismatch.
1080b57cec5SDimitry Andric   const CXXRecordDecl *Record = Type->getAsCXXRecordDecl();
1090b57cec5SDimitry Andric   bool CanRegisterDestructor =
1100b57cec5SDimitry Andric       Record && (!CGM.getCXXABI().HasThisReturn(
1110b57cec5SDimitry Andric                      GlobalDecl(Record->getDestructor(), Dtor_Complete)) ||
1120b57cec5SDimitry Andric                  CGM.getCXXABI().canCallMismatchedFunctionType());
1130b57cec5SDimitry Andric   // If __cxa_atexit is disabled via a flag, a different helper function is
1140b57cec5SDimitry Andric   // generated elsewhere which uses atexit instead, and it takes the destructor
1150b57cec5SDimitry Andric   // directly.
1160b57cec5SDimitry Andric   bool UsingExternalHelper = !CGM.getCodeGenOpts().CXAAtExit;
1170b57cec5SDimitry Andric   if (Record && (CanRegisterDestructor || UsingExternalHelper)) {
1180b57cec5SDimitry Andric     assert(!Record->hasTrivialDestructor());
1190b57cec5SDimitry Andric     CXXDestructorDecl *Dtor = Record->getDestructor();
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric     Func = CGM.getAddrAndTypeOfCXXStructor(GlobalDecl(Dtor, Dtor_Complete));
1220b57cec5SDimitry Andric     if (CGF.getContext().getLangOpts().OpenCL) {
1230b57cec5SDimitry Andric       auto DestAS =
1240b57cec5SDimitry Andric           CGM.getTargetCodeGenInfo().getAddrSpaceOfCxaAtexitPtrParam();
12506c3fb27SDimitry Andric       auto DestTy = llvm::PointerType::get(
12606c3fb27SDimitry Andric           CGM.getLLVMContext(), CGM.getContext().getTargetAddressSpace(DestAS));
1270b57cec5SDimitry Andric       auto SrcAS = D.getType().getQualifiers().getAddressSpace();
1280b57cec5SDimitry Andric       if (DestAS == SrcAS)
1295f757f3fSDimitry Andric         Argument = Addr.getPointer();
1300b57cec5SDimitry Andric       else
1310b57cec5SDimitry Andric         // FIXME: On addr space mismatch we are passing NULL. The generation
1320b57cec5SDimitry Andric         // of the global destructor function should be adjusted accordingly.
1330b57cec5SDimitry Andric         Argument = llvm::ConstantPointerNull::get(DestTy);
1340b57cec5SDimitry Andric     } else {
13506c3fb27SDimitry Andric       Argument = Addr.getPointer();
1360b57cec5SDimitry Andric     }
1370b57cec5SDimitry Andric   // Otherwise, the standard logic requires a helper function.
1380b57cec5SDimitry Andric   } else {
13906c3fb27SDimitry Andric     Addr = Addr.withElementType(CGF.ConvertTypeForMem(Type));
1400b57cec5SDimitry Andric     Func = CodeGenFunction(CGM)
1410b57cec5SDimitry Andric            .generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind),
1420b57cec5SDimitry Andric                                   CGF.needsEHCleanup(DtorKind), &D);
1430b57cec5SDimitry Andric     Argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);
1440b57cec5SDimitry Andric   }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric   CGM.getCXXABI().registerGlobalDtor(CGF, D, Func, Argument);
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric /// Emit code to cause the variable at the given address to be considered as
1500b57cec5SDimitry Andric /// constant from this point onwards.
EmitDeclInvariant(CodeGenFunction & CGF,const VarDecl & D,llvm::Constant * Addr)1510b57cec5SDimitry Andric static void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D,
1520b57cec5SDimitry Andric                               llvm::Constant *Addr) {
1530b57cec5SDimitry Andric   return CGF.EmitInvariantStart(
1540b57cec5SDimitry Andric       Addr, CGF.getContext().getTypeSizeInChars(D.getType()));
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
EmitInvariantStart(llvm::Constant * Addr,CharUnits Size)1570b57cec5SDimitry Andric void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) {
1580b57cec5SDimitry Andric   // Do not emit the intrinsic if we're not optimizing.
1590b57cec5SDimitry Andric   if (!CGM.getCodeGenOpts().OptimizationLevel)
1600b57cec5SDimitry Andric     return;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   // Grab the llvm.invariant.start intrinsic.
1630b57cec5SDimitry Andric   llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
1640b57cec5SDimitry Andric   // Overloaded address space type.
165*0fca6ea1SDimitry Andric   assert(Addr->getType()->isPointerTy() && "Address must be a pointer");
166*0fca6ea1SDimitry Andric   llvm::Type *ObjectPtr[1] = {Addr->getType()};
1670b57cec5SDimitry Andric   llvm::Function *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr);
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   // Emit a call with the size in bytes of the object.
1700b57cec5SDimitry Andric   uint64_t Width = Size.getQuantity();
1715f757f3fSDimitry Andric   llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(Int64Ty, Width), Addr};
1720b57cec5SDimitry Andric   Builder.CreateCall(InvariantStart, Args);
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
EmitCXXGlobalVarDeclInit(const VarDecl & D,llvm::GlobalVariable * GV,bool PerformInit)1750b57cec5SDimitry Andric void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
1760eae32dcSDimitry Andric                                                llvm::GlobalVariable *GV,
1770b57cec5SDimitry Andric                                                bool PerformInit) {
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric   const Expr *Init = D.getInit();
1800b57cec5SDimitry Andric   QualType T = D.getType();
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   // The address space of a static local variable (DeclPtr) may be different
1830b57cec5SDimitry Andric   // from the address space of the "this" argument of the constructor. In that
1840b57cec5SDimitry Andric   // case, we need an addrspacecast before calling the constructor.
1850b57cec5SDimitry Andric   //
1860b57cec5SDimitry Andric   // struct StructWithCtor {
1870b57cec5SDimitry Andric   //   __device__ StructWithCtor() {...}
1880b57cec5SDimitry Andric   // };
1890b57cec5SDimitry Andric   // __device__ void foo() {
1900b57cec5SDimitry Andric   //   __shared__ StructWithCtor s;
1910b57cec5SDimitry Andric   //   ...
1920b57cec5SDimitry Andric   // }
1930b57cec5SDimitry Andric   //
1940b57cec5SDimitry Andric   // For example, in the above CUDA code, the static local variable s has a
1950b57cec5SDimitry Andric   // "shared" address space qualifier, but the constructor of StructWithCtor
1960b57cec5SDimitry Andric   // expects "this" in the "generic" address space.
197bdd1243dSDimitry Andric   unsigned ExpectedAddrSpace = getTypes().getTargetAddressSpace(T);
1980eae32dcSDimitry Andric   unsigned ActualAddrSpace = GV->getAddressSpace();
1990eae32dcSDimitry Andric   llvm::Constant *DeclPtr = GV;
2000b57cec5SDimitry Andric   if (ActualAddrSpace != ExpectedAddrSpace) {
20106c3fb27SDimitry Andric     llvm::PointerType *PTy =
20206c3fb27SDimitry Andric         llvm::PointerType::get(getLLVMContext(), ExpectedAddrSpace);
2030b57cec5SDimitry Andric     DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
2040b57cec5SDimitry Andric   }
2050b57cec5SDimitry Andric 
2060eae32dcSDimitry Andric   ConstantAddress DeclAddr(
2070eae32dcSDimitry Andric       DeclPtr, GV->getValueType(), getContext().getDeclAlign(&D));
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   if (!T->isReferenceType()) {
2100b57cec5SDimitry Andric     if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd &&
2110b57cec5SDimitry Andric         D.hasAttr<OMPThreadPrivateDeclAttr>()) {
2120b57cec5SDimitry Andric       (void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(
2130b57cec5SDimitry Andric           &D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
2140b57cec5SDimitry Andric           PerformInit, this);
2150b57cec5SDimitry Andric     }
21606c3fb27SDimitry Andric     bool NeedsDtor =
21706c3fb27SDimitry Andric         D.needsDestruction(getContext()) == QualType::DK_cxx_destructor;
2180b57cec5SDimitry Andric     if (PerformInit)
2190b57cec5SDimitry Andric       EmitDeclInit(*this, D, DeclAddr);
2205f757f3fSDimitry Andric     if (D.getType().isConstantStorage(getContext(), true, !NeedsDtor))
2210b57cec5SDimitry Andric       EmitDeclInvariant(*this, D, DeclPtr);
2220b57cec5SDimitry Andric     else
2230b57cec5SDimitry Andric       EmitDeclDestroy(*this, D, DeclAddr);
2240b57cec5SDimitry Andric     return;
2250b57cec5SDimitry Andric   }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   assert(PerformInit && "cannot have constant initializer which needs "
2280b57cec5SDimitry Andric          "destruction for reference");
2290b57cec5SDimitry Andric   RValue RV = EmitReferenceBindingToExpr(Init);
2300b57cec5SDimitry Andric   EmitStoreOfScalar(RV.getScalarVal(), DeclAddr, false, T);
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric /// Create a stub function, suitable for being passed to atexit,
2340b57cec5SDimitry Andric /// which passes the given address to the given destructor function.
createAtExitStub(const VarDecl & VD,llvm::FunctionCallee dtor,llvm::Constant * addr)235*0fca6ea1SDimitry Andric llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
2360b57cec5SDimitry Andric                                                   llvm::FunctionCallee dtor,
2370b57cec5SDimitry Andric                                                   llvm::Constant *addr) {
2380b57cec5SDimitry Andric   // Get the destructor function type, void(*)(void).
2390b57cec5SDimitry Andric   llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);
2400b57cec5SDimitry Andric   SmallString<256> FnName;
2410b57cec5SDimitry Andric   {
2420b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(FnName);
2430b57cec5SDimitry Andric     CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);
2440b57cec5SDimitry Andric   }
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric   const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2475ffd83dbSDimitry Andric   llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(
2480b57cec5SDimitry Andric       ty, FnName.str(), FI, VD.getLocation());
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric   CodeGenFunction CGF(CGM);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit),
253e8d8bef9SDimitry Andric                     CGM.getContext().VoidTy, fn, FI, FunctionArgList(),
254e8d8bef9SDimitry Andric                     VD.getLocation(), VD.getInit()->getExprLoc());
255e8d8bef9SDimitry Andric   // Emit an artificial location for this function.
256e8d8bef9SDimitry Andric   auto AL = ApplyDebugLocation::CreateArtificial(CGF);
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   // Make sure the call and the callee agree on calling convention.
261a7dea167SDimitry Andric   if (auto *dtorFn = dyn_cast<llvm::Function>(
262a7dea167SDimitry Andric           dtor.getCallee()->stripPointerCastsAndAliases()))
2630b57cec5SDimitry Andric     call->setCallingConv(dtorFn->getCallingConv());
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   CGF.FinishFunction();
2660b57cec5SDimitry Andric 
267*0fca6ea1SDimitry Andric   // Get a proper function pointer.
268*0fca6ea1SDimitry Andric   FunctionProtoType::ExtProtoInfo EPI(getContext().getDefaultCallingConvention(
269*0fca6ea1SDimitry Andric       /*IsVariadic=*/false, /*IsCXXMethod=*/false));
270*0fca6ea1SDimitry Andric   QualType fnType = getContext().getFunctionType(getContext().VoidTy,
271*0fca6ea1SDimitry Andric                                                  {getContext().VoidPtrTy}, EPI);
272*0fca6ea1SDimitry Andric   return CGM.getFunctionPointer(fn, fnType);
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric 
275fe6060f1SDimitry Andric /// Create a stub function, suitable for being passed to __pt_atexit_np,
276fe6060f1SDimitry Andric /// which passes the given address to the given destructor function.
createTLSAtExitStub(const VarDecl & D,llvm::FunctionCallee Dtor,llvm::Constant * Addr,llvm::FunctionCallee & AtExit)277fe6060f1SDimitry Andric llvm::Function *CodeGenFunction::createTLSAtExitStub(
278fe6060f1SDimitry Andric     const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr,
279fe6060f1SDimitry Andric     llvm::FunctionCallee &AtExit) {
280fe6060f1SDimitry Andric   SmallString<256> FnName;
281fe6060f1SDimitry Andric   {
282fe6060f1SDimitry Andric     llvm::raw_svector_ostream Out(FnName);
283fe6060f1SDimitry Andric     CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&D, Out);
284fe6060f1SDimitry Andric   }
285fe6060f1SDimitry Andric 
286fe6060f1SDimitry Andric   const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo(
2878a4dda33SDimitry Andric       getContext().IntTy, FnInfoOpts::None, {getContext().IntTy},
2888a4dda33SDimitry Andric       FunctionType::ExtInfo(), {}, RequiredArgs::All);
289fe6060f1SDimitry Andric 
290fe6060f1SDimitry Andric   // Get the stub function type, int(*)(int,...).
291fe6060f1SDimitry Andric   llvm::FunctionType *StubTy =
292fe6060f1SDimitry Andric       llvm::FunctionType::get(CGM.IntTy, {CGM.IntTy}, true);
293fe6060f1SDimitry Andric 
294fe6060f1SDimitry Andric   llvm::Function *DtorStub = CGM.CreateGlobalInitOrCleanUpFunction(
295fe6060f1SDimitry Andric       StubTy, FnName.str(), FI, D.getLocation());
296fe6060f1SDimitry Andric 
297fe6060f1SDimitry Andric   CodeGenFunction CGF(CGM);
298fe6060f1SDimitry Andric 
299fe6060f1SDimitry Andric   FunctionArgList Args;
300fe6060f1SDimitry Andric   ImplicitParamDecl IPD(CGM.getContext(), CGM.getContext().IntTy,
3015f757f3fSDimitry Andric                         ImplicitParamKind::Other);
302fe6060f1SDimitry Andric   Args.push_back(&IPD);
303fe6060f1SDimitry Andric   QualType ResTy = CGM.getContext().IntTy;
304fe6060f1SDimitry Andric 
305fe6060f1SDimitry Andric   CGF.StartFunction(GlobalDecl(&D, DynamicInitKind::AtExit), ResTy, DtorStub,
306fe6060f1SDimitry Andric                     FI, Args, D.getLocation(), D.getInit()->getExprLoc());
307fe6060f1SDimitry Andric 
308fe6060f1SDimitry Andric   // Emit an artificial location for this function.
309fe6060f1SDimitry Andric   auto AL = ApplyDebugLocation::CreateArtificial(CGF);
310fe6060f1SDimitry Andric 
311fe6060f1SDimitry Andric   llvm::CallInst *call = CGF.Builder.CreateCall(Dtor, Addr);
312fe6060f1SDimitry Andric 
313fe6060f1SDimitry Andric   // Make sure the call and the callee agree on calling convention.
314fe6060f1SDimitry Andric   if (auto *DtorFn = dyn_cast<llvm::Function>(
315fe6060f1SDimitry Andric           Dtor.getCallee()->stripPointerCastsAndAliases()))
316fe6060f1SDimitry Andric     call->setCallingConv(DtorFn->getCallingConv());
317fe6060f1SDimitry Andric 
318fe6060f1SDimitry Andric   // Return 0 from function
319fe6060f1SDimitry Andric   CGF.Builder.CreateStore(llvm::Constant::getNullValue(CGM.IntTy),
320fe6060f1SDimitry Andric                           CGF.ReturnValue);
321fe6060f1SDimitry Andric 
322fe6060f1SDimitry Andric   CGF.FinishFunction();
323fe6060f1SDimitry Andric 
324fe6060f1SDimitry Andric   return DtorStub;
325fe6060f1SDimitry Andric }
326fe6060f1SDimitry Andric 
3270b57cec5SDimitry Andric /// Register a global destructor using the C atexit runtime function.
registerGlobalDtorWithAtExit(const VarDecl & VD,llvm::FunctionCallee dtor,llvm::Constant * addr)3280b57cec5SDimitry Andric void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD,
3290b57cec5SDimitry Andric                                                    llvm::FunctionCallee dtor,
3300b57cec5SDimitry Andric                                                    llvm::Constant *addr) {
3310b57cec5SDimitry Andric   // Create a function which calls the destructor.
3320b57cec5SDimitry Andric   llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr);
3330b57cec5SDimitry Andric   registerGlobalDtorWithAtExit(dtorStub);
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric 
3365f757f3fSDimitry Andric /// Register a global destructor using the LLVM 'llvm.global_dtors' global.
registerGlobalDtorWithLLVM(const VarDecl & VD,llvm::FunctionCallee Dtor,llvm::Constant * Addr)3375f757f3fSDimitry Andric void CodeGenFunction::registerGlobalDtorWithLLVM(const VarDecl &VD,
3385f757f3fSDimitry Andric                                                  llvm::FunctionCallee Dtor,
3395f757f3fSDimitry Andric                                                  llvm::Constant *Addr) {
3405f757f3fSDimitry Andric   // Create a function which calls the destructor.
341*0fca6ea1SDimitry Andric   llvm::Function *dtorStub =
342*0fca6ea1SDimitry Andric       cast<llvm::Function>(createAtExitStub(VD, Dtor, Addr));
3435f757f3fSDimitry Andric   CGM.AddGlobalDtor(dtorStub);
3445f757f3fSDimitry Andric }
3455f757f3fSDimitry Andric 
registerGlobalDtorWithAtExit(llvm::Constant * dtorStub)3460b57cec5SDimitry Andric void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtorStub) {
3470b57cec5SDimitry Andric   // extern "C" int atexit(void (*f)(void));
348e8d8bef9SDimitry Andric   assert(dtorStub->getType() ==
349e8d8bef9SDimitry Andric              llvm::PointerType::get(
350e8d8bef9SDimitry Andric                  llvm::FunctionType::get(CGM.VoidTy, false),
351e8d8bef9SDimitry Andric                  dtorStub->getType()->getPointerAddressSpace()) &&
3525ffd83dbSDimitry Andric          "Argument to atexit has a wrong type.");
3535ffd83dbSDimitry Andric 
3540b57cec5SDimitry Andric   llvm::FunctionType *atexitTy =
3550b57cec5SDimitry Andric       llvm::FunctionType::get(IntTy, dtorStub->getType(), false);
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric   llvm::FunctionCallee atexit =
3580b57cec5SDimitry Andric       CGM.CreateRuntimeFunction(atexitTy, "atexit", llvm::AttributeList(),
3590b57cec5SDimitry Andric                                 /*Local=*/true);
3600b57cec5SDimitry Andric   if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
3610b57cec5SDimitry Andric     atexitFn->setDoesNotThrow();
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric   EmitNounwindRuntimeCall(atexit, dtorStub);
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3665ffd83dbSDimitry Andric llvm::Value *
unregisterGlobalDtorWithUnAtExit(llvm::Constant * dtorStub)367e8d8bef9SDimitry Andric CodeGenFunction::unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub) {
3685ffd83dbSDimitry Andric   // The unatexit subroutine unregisters __dtor functions that were previously
3695ffd83dbSDimitry Andric   // registered by the atexit subroutine. If the referenced function is found,
3705ffd83dbSDimitry Andric   // it is removed from the list of functions that are called at normal program
3715ffd83dbSDimitry Andric   // termination and the unatexit returns a value of 0, otherwise a non-zero
3725ffd83dbSDimitry Andric   // value is returned.
3735ffd83dbSDimitry Andric   //
3745ffd83dbSDimitry Andric   // extern "C" int unatexit(void (*f)(void));
375e8d8bef9SDimitry Andric   assert(dtorStub->getType() ==
376e8d8bef9SDimitry Andric              llvm::PointerType::get(
377e8d8bef9SDimitry Andric                  llvm::FunctionType::get(CGM.VoidTy, false),
378e8d8bef9SDimitry Andric                  dtorStub->getType()->getPointerAddressSpace()) &&
3795ffd83dbSDimitry Andric          "Argument to unatexit has a wrong type.");
3805ffd83dbSDimitry Andric 
3815ffd83dbSDimitry Andric   llvm::FunctionType *unatexitTy =
3825ffd83dbSDimitry Andric       llvm::FunctionType::get(IntTy, {dtorStub->getType()}, /*isVarArg=*/false);
3835ffd83dbSDimitry Andric 
3845ffd83dbSDimitry Andric   llvm::FunctionCallee unatexit =
3855ffd83dbSDimitry Andric       CGM.CreateRuntimeFunction(unatexitTy, "unatexit", llvm::AttributeList());
3865ffd83dbSDimitry Andric 
3875ffd83dbSDimitry Andric   cast<llvm::Function>(unatexit.getCallee())->setDoesNotThrow();
3885ffd83dbSDimitry Andric 
3895ffd83dbSDimitry Andric   return EmitNounwindRuntimeCall(unatexit, dtorStub);
3905ffd83dbSDimitry Andric }
3915ffd83dbSDimitry Andric 
EmitCXXGuardedInit(const VarDecl & D,llvm::GlobalVariable * DeclPtr,bool PerformInit)3920b57cec5SDimitry Andric void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,
3930b57cec5SDimitry Andric                                          llvm::GlobalVariable *DeclPtr,
3940b57cec5SDimitry Andric                                          bool PerformInit) {
3950b57cec5SDimitry Andric   // If we've been asked to forbid guard variables, emit an error now.
3960b57cec5SDimitry Andric   // This diagnostic is hard-coded for Darwin's use case;  we can find
3970b57cec5SDimitry Andric   // better phrasing if someone else needs it.
3980b57cec5SDimitry Andric   if (CGM.getCodeGenOpts().ForbidGuardVariables)
3990b57cec5SDimitry Andric     CGM.Error(D.getLocation(),
4000b57cec5SDimitry Andric               "this initialization requires a guard variable, which "
4010b57cec5SDimitry Andric               "the kernel does not support");
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);
4040b57cec5SDimitry Andric }
4050b57cec5SDimitry Andric 
EmitCXXGuardedInitBranch(llvm::Value * NeedsInit,llvm::BasicBlock * InitBlock,llvm::BasicBlock * NoInitBlock,GuardKind Kind,const VarDecl * D)4060b57cec5SDimitry Andric void CodeGenFunction::EmitCXXGuardedInitBranch(llvm::Value *NeedsInit,
4070b57cec5SDimitry Andric                                                llvm::BasicBlock *InitBlock,
4080b57cec5SDimitry Andric                                                llvm::BasicBlock *NoInitBlock,
4090b57cec5SDimitry Andric                                                GuardKind Kind,
4100b57cec5SDimitry Andric                                                const VarDecl *D) {
4110b57cec5SDimitry Andric   assert((Kind == GuardKind::TlsGuard || D) && "no guarded variable");
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   // A guess at how many times we will enter the initialization of a
4140b57cec5SDimitry Andric   // variable, depending on the kind of variable.
4150b57cec5SDimitry Andric   static const uint64_t InitsPerTLSVar = 1024;
4160b57cec5SDimitry Andric   static const uint64_t InitsPerLocalVar = 1024 * 1024;
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   llvm::MDNode *Weights;
4190b57cec5SDimitry Andric   if (Kind == GuardKind::VariableGuard && !D->isLocalVarDecl()) {
4200b57cec5SDimitry Andric     // For non-local variables, don't apply any weighting for now. Due to our
4210b57cec5SDimitry Andric     // use of COMDATs, we expect there to be at most one initialization of the
4220b57cec5SDimitry Andric     // variable per DSO, but we have no way to know how many DSOs will try to
4230b57cec5SDimitry Andric     // initialize the variable.
4240b57cec5SDimitry Andric     Weights = nullptr;
4250b57cec5SDimitry Andric   } else {
4260b57cec5SDimitry Andric     uint64_t NumInits;
4270b57cec5SDimitry Andric     // FIXME: For the TLS case, collect and use profiling information to
4280b57cec5SDimitry Andric     // determine a more accurate brach weight.
4290b57cec5SDimitry Andric     if (Kind == GuardKind::TlsGuard || D->getTLSKind())
4300b57cec5SDimitry Andric       NumInits = InitsPerTLSVar;
4310b57cec5SDimitry Andric     else
4320b57cec5SDimitry Andric       NumInits = InitsPerLocalVar;
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric     // The probability of us entering the initializer is
4350b57cec5SDimitry Andric     //   1 / (total number of times we attempt to initialize the variable).
4360b57cec5SDimitry Andric     llvm::MDBuilder MDHelper(CGM.getLLVMContext());
4370b57cec5SDimitry Andric     Weights = MDHelper.createBranchWeights(1, NumInits - 1);
4380b57cec5SDimitry Andric   }
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric   Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
4410b57cec5SDimitry Andric }
4420b57cec5SDimitry Andric 
CreateGlobalInitOrCleanUpFunction(llvm::FunctionType * FTy,const Twine & Name,const CGFunctionInfo & FI,SourceLocation Loc,bool TLS,llvm::GlobalVariable::LinkageTypes Linkage)4435ffd83dbSDimitry Andric llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction(
4440b57cec5SDimitry Andric     llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI,
44581ad6265SDimitry Andric     SourceLocation Loc, bool TLS, llvm::GlobalVariable::LinkageTypes Linkage) {
44681ad6265SDimitry Andric   llvm::Function *Fn = llvm::Function::Create(FTy, Linkage, Name, &getModule());
4475ffd83dbSDimitry Andric 
4480b57cec5SDimitry Andric   if (!getLangOpts().AppleKext && !TLS) {
4490b57cec5SDimitry Andric     // Set the section if needed.
4500b57cec5SDimitry Andric     if (const char *Section = getTarget().getStaticInitSectionSpecifier())
4510b57cec5SDimitry Andric       Fn->setSection(Section);
4520b57cec5SDimitry Andric   }
4530b57cec5SDimitry Andric 
45481ad6265SDimitry Andric   if (Linkage == llvm::GlobalVariable::InternalLinkage)
4550b57cec5SDimitry Andric     SetInternalFunctionAttributes(GlobalDecl(), Fn, FI);
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric   Fn->setCallingConv(getRuntimeCC());
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   if (!getLangOpts().Exceptions)
4600b57cec5SDimitry Andric     Fn->setDoesNotThrow();
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::Address) &&
463fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::Address, Fn, Loc))
4640b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
467fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::KernelAddress, Fn, Loc))
4680b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
471fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::HWAddress, Fn, Loc))
4720b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&
475fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn, Loc))
4760b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
4770b57cec5SDimitry Andric 
47881ad6265SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
47981ad6265SDimitry Andric       !isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc))
4800b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
483fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc))
4840b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeThread);
4850b57cec5SDimitry Andric 
486*0fca6ea1SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) &&
487*0fca6ea1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::NumericalStability, Fn, Loc))
488*0fca6ea1SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
489*0fca6ea1SDimitry Andric 
4900b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
491fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::Memory, Fn, Loc))
4920b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&
495fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::KernelMemory, Fn, Loc))
4960b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
499fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::SafeStack, Fn, Loc))
5000b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::SafeStack);
5010b57cec5SDimitry Andric 
5020b57cec5SDimitry Andric   if (getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&
503fe6060f1SDimitry Andric       !isInNoSanitizeList(SanitizerKind::ShadowCallStack, Fn, Loc))
5040b57cec5SDimitry Andric     Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric   return Fn;
5070b57cec5SDimitry Andric }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric /// Create a global pointer to a function that will initialize a global
5100b57cec5SDimitry Andric /// variable.  The user has requested that this pointer be emitted in a specific
5110b57cec5SDimitry Andric /// section.
EmitPointerToInitFunc(const VarDecl * D,llvm::GlobalVariable * GV,llvm::Function * InitFunc,InitSegAttr * ISA)5120b57cec5SDimitry Andric void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,
5130b57cec5SDimitry Andric                                           llvm::GlobalVariable *GV,
5140b57cec5SDimitry Andric                                           llvm::Function *InitFunc,
5150b57cec5SDimitry Andric                                           InitSegAttr *ISA) {
5160b57cec5SDimitry Andric   llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable(
5170b57cec5SDimitry Andric       TheModule, InitFunc->getType(), /*isConstant=*/true,
5180b57cec5SDimitry Andric       llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr");
5190b57cec5SDimitry Andric   PtrArray->setSection(ISA->getSection());
5200b57cec5SDimitry Andric   addUsedGlobal(PtrArray);
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric   // If the GV is already in a comdat group, then we have to join it.
5230b57cec5SDimitry Andric   if (llvm::Comdat *C = GV->getComdat())
5240b57cec5SDimitry Andric     PtrArray->setComdat(C);
5250b57cec5SDimitry Andric }
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric void
EmitCXXGlobalVarDeclInitFunc(const VarDecl * D,llvm::GlobalVariable * Addr,bool PerformInit)5280b57cec5SDimitry Andric CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
5290b57cec5SDimitry Andric                                             llvm::GlobalVariable *Addr,
5300b57cec5SDimitry Andric                                             bool PerformInit) {
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   // According to E.2.3.1 in CUDA-7.5 Programming guide: __device__,
5330b57cec5SDimitry Andric   // __constant__ and __shared__ variables defined in namespace scope,
5340b57cec5SDimitry Andric   // that are of class type, cannot have a non-empty constructor. All
5350b57cec5SDimitry Andric   // the checks have been done in Sema by now. Whatever initializers
5360b57cec5SDimitry Andric   // are allowed are empty and we just need to ignore them here.
537480093f4SDimitry Andric   if (getLangOpts().CUDAIsDevice && !getLangOpts().GPUAllowDeviceInit &&
5380b57cec5SDimitry Andric       (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() ||
5390b57cec5SDimitry Andric        D->hasAttr<CUDASharedAttr>()))
5400b57cec5SDimitry Andric     return;
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric   // Check if we've already initialized this decl.
5430b57cec5SDimitry Andric   auto I = DelayedCXXInitPosition.find(D);
5440b57cec5SDimitry Andric   if (I != DelayedCXXInitPosition.end() && I->second == ~0U)
5450b57cec5SDimitry Andric     return;
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
5480b57cec5SDimitry Andric   SmallString<256> FnName;
5490b57cec5SDimitry Andric   {
5500b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(FnName);
5510b57cec5SDimitry Andric     getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);
5520b57cec5SDimitry Andric   }
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   // Create a variable initialization function.
5555ffd83dbSDimitry Andric   llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(
5565ffd83dbSDimitry Andric       FTy, FnName.str(), getTypes().arrangeNullaryFunction(), D->getLocation());
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric   auto *ISA = D->getAttr<InitSegAttr>();
5590b57cec5SDimitry Andric   CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
5600b57cec5SDimitry Andric                                                           PerformInit);
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric   llvm::GlobalVariable *COMDATKey =
5630b57cec5SDimitry Andric       supportsCOMDAT() && D->isExternallyVisible() ? Addr : nullptr;
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric   if (D->getTLSKind()) {
5660b57cec5SDimitry Andric     // FIXME: Should we support init_priority for thread_local?
5670b57cec5SDimitry Andric     // FIXME: We only need to register one __cxa_thread_atexit function for the
5680b57cec5SDimitry Andric     // entire TU.
5690b57cec5SDimitry Andric     CXXThreadLocalInits.push_back(Fn);
5700b57cec5SDimitry Andric     CXXThreadLocalInitVars.push_back(D);
5710b57cec5SDimitry Andric   } else if (PerformInit && ISA) {
572bdd1243dSDimitry Andric     // Contract with backend that "init_seg(compiler)" corresponds to priority
573bdd1243dSDimitry Andric     // 200 and "init_seg(lib)" corresponds to priority 400.
574bdd1243dSDimitry Andric     int Priority = -1;
575bdd1243dSDimitry Andric     if (ISA->getSection() == ".CRT$XCC")
576bdd1243dSDimitry Andric       Priority = 200;
577bdd1243dSDimitry Andric     else if (ISA->getSection() == ".CRT$XCL")
578bdd1243dSDimitry Andric       Priority = 400;
579bdd1243dSDimitry Andric 
580bdd1243dSDimitry Andric     if (Priority != -1)
581bdd1243dSDimitry Andric       AddGlobalCtor(Fn, Priority, ~0U, COMDATKey);
582bdd1243dSDimitry Andric     else
5830b57cec5SDimitry Andric       EmitPointerToInitFunc(D, Addr, Fn, ISA);
5840b57cec5SDimitry Andric   } else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {
585fe6060f1SDimitry Andric     OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(),
586fe6060f1SDimitry Andric                                           PrioritizedCXXGlobalInits.size());
5870b57cec5SDimitry Andric     PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
5880b57cec5SDimitry Andric   } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
5896e75b2fbSDimitry Andric              getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR ||
5906e75b2fbSDimitry Andric              D->hasAttr<SelectAnyAttr>()) {
5910b57cec5SDimitry Andric     // C++ [basic.start.init]p2:
5920b57cec5SDimitry Andric     //   Definitions of explicitly specialized class template static data
5930b57cec5SDimitry Andric     //   members have ordered initialization. Other class template static data
5940b57cec5SDimitry Andric     //   members (i.e., implicitly or explicitly instantiated specializations)
5950b57cec5SDimitry Andric     //   have unordered initialization.
5960b57cec5SDimitry Andric     //
5970b57cec5SDimitry Andric     // As a consequence, we can put them into their own llvm.global_ctors entry.
5980b57cec5SDimitry Andric     //
5990b57cec5SDimitry Andric     // If the global is externally visible, put the initializer into a COMDAT
6000b57cec5SDimitry Andric     // group with the global being initialized.  On most platforms, this is a
6010b57cec5SDimitry Andric     // minor startup time optimization.  In the MS C++ ABI, there are no guard
6020b57cec5SDimitry Andric     // variables, so this COMDAT key is required for correctness.
6036e75b2fbSDimitry Andric     //
6040b57cec5SDimitry Andric     // SelectAny globals will be comdat-folded. Put the initializer into a
6050b57cec5SDimitry Andric     // COMDAT group associated with the global, so the initializers get folded
6060b57cec5SDimitry Andric     // too.
607bdd1243dSDimitry Andric     I = DelayedCXXInitPosition.find(D);
608bdd1243dSDimitry Andric     // CXXGlobalInits.size() is the lex order number for the next deferred
609bdd1243dSDimitry Andric     // VarDecl. Use it when the current VarDecl is non-deferred. Although this
610bdd1243dSDimitry Andric     // lex order number is shared between current VarDecl and some following
611bdd1243dSDimitry Andric     // VarDecls, their order of insertion into `llvm.global_ctors` is the same
612bdd1243dSDimitry Andric     // as the lexing order and the following stable sort would preserve such
613bdd1243dSDimitry Andric     // order.
614bdd1243dSDimitry Andric     unsigned LexOrder =
615bdd1243dSDimitry Andric         I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
616bdd1243dSDimitry Andric     AddGlobalCtor(Fn, 65535, LexOrder, COMDATKey);
6176e75b2fbSDimitry Andric     if (COMDATKey && (getTriple().isOSBinFormatELF() ||
6186e75b2fbSDimitry Andric                       getTarget().getCXXABI().isMicrosoft())) {
6196e75b2fbSDimitry Andric       // When COMDAT is used on ELF or in the MS C++ ABI, the key must be in
6206e75b2fbSDimitry Andric       // llvm.used to prevent linker GC.
6216e75b2fbSDimitry Andric       addUsedGlobal(COMDATKey);
6226e75b2fbSDimitry Andric     }
623349cc55cSDimitry Andric 
624349cc55cSDimitry Andric     // If we used a COMDAT key for the global ctor, the init function can be
625349cc55cSDimitry Andric     // discarded if the global ctor entry is discarded.
626349cc55cSDimitry Andric     // FIXME: Do we need to restrict this to ELF and Wasm?
627349cc55cSDimitry Andric     llvm::Comdat *C = Addr->getComdat();
628349cc55cSDimitry Andric     if (COMDATKey && C &&
629349cc55cSDimitry Andric         (getTarget().getTriple().isOSBinFormatELF() ||
630349cc55cSDimitry Andric          getTarget().getTriple().isOSBinFormatWasm())) {
631349cc55cSDimitry Andric       Fn->setComdat(C);
632349cc55cSDimitry Andric     }
6330b57cec5SDimitry Andric   } else {
6340b57cec5SDimitry Andric     I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash.
6350b57cec5SDimitry Andric     if (I == DelayedCXXInitPosition.end()) {
6360b57cec5SDimitry Andric       CXXGlobalInits.push_back(Fn);
6370b57cec5SDimitry Andric     } else if (I->second != ~0U) {
6380b57cec5SDimitry Andric       assert(I->second < CXXGlobalInits.size() &&
6390b57cec5SDimitry Andric              CXXGlobalInits[I->second] == nullptr);
6400b57cec5SDimitry Andric       CXXGlobalInits[I->second] = Fn;
6410b57cec5SDimitry Andric     }
6420b57cec5SDimitry Andric   }
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   // Remember that we already emitted the initializer for this global.
6450b57cec5SDimitry Andric   DelayedCXXInitPosition[D] = ~0U;
6460b57cec5SDimitry Andric }
6470b57cec5SDimitry Andric 
EmitCXXThreadLocalInitFunc()6480b57cec5SDimitry Andric void CodeGenModule::EmitCXXThreadLocalInitFunc() {
6490b57cec5SDimitry Andric   getCXXABI().EmitThreadLocalInitFuncs(
6500b57cec5SDimitry Andric       *this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric   CXXThreadLocalInits.clear();
6530b57cec5SDimitry Andric   CXXThreadLocalInitVars.clear();
6540b57cec5SDimitry Andric   CXXThreadLocals.clear();
6550b57cec5SDimitry Andric }
6560b57cec5SDimitry Andric 
657fcaf7f86SDimitry Andric /* Build the initializer for a C++20 module:
658fcaf7f86SDimitry Andric    This is arranged to be run only once regardless of how many times the module
659bdd1243dSDimitry Andric    might be included transitively.  This arranged by using a guard variable.
660bdd1243dSDimitry Andric 
66106c3fb27SDimitry Andric    If there are no initializers at all (and also no imported modules) we reduce
662bdd1243dSDimitry Andric    this to an empty function (since the Itanium ABI requires that this function
663bdd1243dSDimitry Andric    be available to a caller, which might be produced by a different
664bdd1243dSDimitry Andric    implementation).
665fcaf7f86SDimitry Andric 
666fcaf7f86SDimitry Andric    First we call any initializers for imported modules.
667fcaf7f86SDimitry Andric    We then call initializers for the Global Module Fragment (if present)
668fcaf7f86SDimitry Andric    We then call initializers for the current module.
669fcaf7f86SDimitry Andric    We then call initializers for the Private Module Fragment (if present)
670fcaf7f86SDimitry Andric */
671fcaf7f86SDimitry Andric 
EmitCXXModuleInitFunc(Module * Primary)672fcaf7f86SDimitry Andric void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) {
6735f757f3fSDimitry Andric   assert(Primary->isInterfaceOrPartition() &&
6745f757f3fSDimitry Andric          "The function should only be called for C++20 named module interface"
6755f757f3fSDimitry Andric          " or partition.");
6765f757f3fSDimitry Andric 
677fcaf7f86SDimitry Andric   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
678fcaf7f86SDimitry Andric     CXXGlobalInits.pop_back();
679fcaf7f86SDimitry Andric 
680bdd1243dSDimitry Andric   // As noted above, we create the function, even if it is empty.
681fcaf7f86SDimitry Andric   // Module initializers for imported modules are emitted first.
682bdd1243dSDimitry Andric 
683bdd1243dSDimitry Andric   // Collect all the modules that we import
6845f757f3fSDimitry Andric   llvm::SmallSetVector<Module *, 8> AllImports;
685fcaf7f86SDimitry Andric   // Ones that we export
686fcaf7f86SDimitry Andric   for (auto I : Primary->Exports)
6875f757f3fSDimitry Andric     AllImports.insert(I.getPointer());
688fcaf7f86SDimitry Andric   // Ones that we only import.
689fcaf7f86SDimitry Andric   for (Module *M : Primary->Imports)
6905f757f3fSDimitry Andric     AllImports.insert(M);
6915f757f3fSDimitry Andric   // Ones that we import in the global module fragment or the private module
6925f757f3fSDimitry Andric   // fragment.
6935f757f3fSDimitry Andric   for (Module *SubM : Primary->submodules()) {
6945f757f3fSDimitry Andric     assert((SubM->isGlobalModule() || SubM->isPrivateModule()) &&
6955f757f3fSDimitry Andric            "The sub modules of C++20 module unit should only be global module "
6965f757f3fSDimitry Andric            "fragments or private module framents.");
6975f757f3fSDimitry Andric     assert(SubM->Exports.empty() &&
6985f757f3fSDimitry Andric            "The global mdoule fragments and the private module fragments are "
6995f757f3fSDimitry Andric            "not allowed to export import modules.");
7005f757f3fSDimitry Andric     for (Module *M : SubM->Imports)
7015f757f3fSDimitry Andric       AllImports.insert(M);
7025f757f3fSDimitry Andric   }
703fcaf7f86SDimitry Andric 
704fcaf7f86SDimitry Andric   SmallVector<llvm::Function *, 8> ModuleInits;
705fcaf7f86SDimitry Andric   for (Module *M : AllImports) {
70661cfbce3SDimitry Andric     // No Itanium initializer in header like modules.
70761cfbce3SDimitry Andric     if (M->isHeaderLikeModule())
708fcaf7f86SDimitry Andric       continue; // TODO: warn of mixed use of module map modules and C++20?
7095f757f3fSDimitry Andric     // We're allowed to skip the initialization if we are sure it doesn't
7105f757f3fSDimitry Andric     // do any thing.
7115f757f3fSDimitry Andric     if (!M->isNamedModuleInterfaceHasInit())
7125f757f3fSDimitry Andric       continue;
713fcaf7f86SDimitry Andric     llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
714fcaf7f86SDimitry Andric     SmallString<256> FnName;
715fcaf7f86SDimitry Andric     {
716fcaf7f86SDimitry Andric       llvm::raw_svector_ostream Out(FnName);
717fcaf7f86SDimitry Andric       cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
718fcaf7f86SDimitry Andric           .mangleModuleInitializer(M, Out);
719fcaf7f86SDimitry Andric     }
720fcaf7f86SDimitry Andric     assert(!GetGlobalValue(FnName.str()) &&
721fcaf7f86SDimitry Andric            "We should only have one use of the initializer call");
722fcaf7f86SDimitry Andric     llvm::Function *Fn = llvm::Function::Create(
723fcaf7f86SDimitry Andric         FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());
724fcaf7f86SDimitry Andric     ModuleInits.push_back(Fn);
725fcaf7f86SDimitry Andric   }
726fcaf7f86SDimitry Andric 
727fcaf7f86SDimitry Andric   // Add any initializers with specified priority; this uses the same  approach
728fcaf7f86SDimitry Andric   // as EmitCXXGlobalInitFunc().
729fcaf7f86SDimitry Andric   if (!PrioritizedCXXGlobalInits.empty()) {
730fcaf7f86SDimitry Andric     SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
731fcaf7f86SDimitry Andric     llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
732fcaf7f86SDimitry Andric                          PrioritizedCXXGlobalInits.end());
733fcaf7f86SDimitry Andric     for (SmallVectorImpl<GlobalInitData>::iterator
734fcaf7f86SDimitry Andric              I = PrioritizedCXXGlobalInits.begin(),
735fcaf7f86SDimitry Andric              E = PrioritizedCXXGlobalInits.end();
736fcaf7f86SDimitry Andric          I != E;) {
737fcaf7f86SDimitry Andric       SmallVectorImpl<GlobalInitData>::iterator PrioE =
738fcaf7f86SDimitry Andric           std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
739fcaf7f86SDimitry Andric 
740fcaf7f86SDimitry Andric       for (; I < PrioE; ++I)
741fcaf7f86SDimitry Andric         ModuleInits.push_back(I->second);
742fcaf7f86SDimitry Andric     }
743fcaf7f86SDimitry Andric   }
744fcaf7f86SDimitry Andric 
745fcaf7f86SDimitry Andric   // Now append the ones without specified priority.
746bdd1243dSDimitry Andric   for (auto *F : CXXGlobalInits)
747fcaf7f86SDimitry Andric     ModuleInits.push_back(F);
748fcaf7f86SDimitry Andric 
749fcaf7f86SDimitry Andric   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
750fcaf7f86SDimitry Andric   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
751fcaf7f86SDimitry Andric 
752fcaf7f86SDimitry Andric   // We now build the initializer for this module, which has a mangled name
753fcaf7f86SDimitry Andric   // as per the Itanium ABI .  The action of the initializer is guarded so that
754fcaf7f86SDimitry Andric   // each init is run just once (even though a module might be imported
755fcaf7f86SDimitry Andric   // multiple times via nested use).
756fcaf7f86SDimitry Andric   llvm::Function *Fn;
757fcaf7f86SDimitry Andric   {
758fcaf7f86SDimitry Andric     SmallString<256> InitFnName;
759fcaf7f86SDimitry Andric     llvm::raw_svector_ostream Out(InitFnName);
760fcaf7f86SDimitry Andric     cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
761fcaf7f86SDimitry Andric         .mangleModuleInitializer(Primary, Out);
762fcaf7f86SDimitry Andric     Fn = CreateGlobalInitOrCleanUpFunction(
763fcaf7f86SDimitry Andric         FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,
764fcaf7f86SDimitry Andric         llvm::GlobalVariable::ExternalLinkage);
765fcaf7f86SDimitry Andric 
766bdd1243dSDimitry Andric     // If we have a completely empty initializer then we do not want to create
767bdd1243dSDimitry Andric     // the guard variable.
768bdd1243dSDimitry Andric     ConstantAddress GuardAddr = ConstantAddress::invalid();
7695f757f3fSDimitry Andric     if (!ModuleInits.empty()) {
770bdd1243dSDimitry Andric       // Create the guard var.
771bdd1243dSDimitry Andric       llvm::GlobalVariable *Guard = new llvm::GlobalVariable(
772bdd1243dSDimitry Andric           getModule(), Int8Ty, /*isConstant=*/false,
773fcaf7f86SDimitry Andric           llvm::GlobalVariable::InternalLinkage,
774bdd1243dSDimitry Andric           llvm::ConstantInt::get(Int8Ty, 0), InitFnName.str() + "__in_chrg");
775fcaf7f86SDimitry Andric       CharUnits GuardAlign = CharUnits::One();
776fcaf7f86SDimitry Andric       Guard->setAlignment(GuardAlign.getAsAlign());
777bdd1243dSDimitry Andric       GuardAddr = ConstantAddress(Guard, Int8Ty, GuardAlign);
778bdd1243dSDimitry Andric     }
779bdd1243dSDimitry Andric     CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,
780bdd1243dSDimitry Andric                                                      GuardAddr);
781bdd1243dSDimitry Andric   }
782fcaf7f86SDimitry Andric 
783fcaf7f86SDimitry Andric   // We allow for the case that a module object is added to a linked binary
784bdd1243dSDimitry Andric   // without a specific call to the the initializer.  This also ensures that
785fcaf7f86SDimitry Andric   // implementation partition initializers are called when the partition
786fcaf7f86SDimitry Andric   // is not imported as an interface.
787fcaf7f86SDimitry Andric   AddGlobalCtor(Fn);
788fcaf7f86SDimitry Andric 
789fcaf7f86SDimitry Andric   // See the comment in EmitCXXGlobalInitFunc about OpenCL global init
790fcaf7f86SDimitry Andric   // functions.
791fcaf7f86SDimitry Andric   if (getLangOpts().OpenCL) {
792fcaf7f86SDimitry Andric     GenKernelArgMetadata(Fn);
793fcaf7f86SDimitry Andric     Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
794fcaf7f86SDimitry Andric   }
795fcaf7f86SDimitry Andric 
796fcaf7f86SDimitry Andric   assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice ||
797fcaf7f86SDimitry Andric          getLangOpts().GPUAllowDeviceInit);
798fcaf7f86SDimitry Andric   if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) {
799fcaf7f86SDimitry Andric     Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
800fcaf7f86SDimitry Andric     Fn->addFnAttr("device-init");
801fcaf7f86SDimitry Andric   }
802fcaf7f86SDimitry Andric 
803bdd1243dSDimitry Andric   // We are done with the inits.
804bdd1243dSDimitry Andric   AllImports.clear();
805bdd1243dSDimitry Andric   PrioritizedCXXGlobalInits.clear();
806bdd1243dSDimitry Andric   CXXGlobalInits.clear();
807fcaf7f86SDimitry Andric   ModuleInits.clear();
808fcaf7f86SDimitry Andric }
809fcaf7f86SDimitry Andric 
getTransformedFileName(llvm::Module & M)8105ffd83dbSDimitry Andric static SmallString<128> getTransformedFileName(llvm::Module &M) {
8115ffd83dbSDimitry Andric   SmallString<128> FileName = llvm::sys::path::filename(M.getName());
8125ffd83dbSDimitry Andric 
8135ffd83dbSDimitry Andric   if (FileName.empty())
8145ffd83dbSDimitry Andric     FileName = "<null>";
8155ffd83dbSDimitry Andric 
8165ffd83dbSDimitry Andric   for (size_t i = 0; i < FileName.size(); ++i) {
8175ffd83dbSDimitry Andric     // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
8185ffd83dbSDimitry Andric     // to be the set of C preprocessing numbers.
8195ffd83dbSDimitry Andric     if (!isPreprocessingNumberBody(FileName[i]))
8205ffd83dbSDimitry Andric       FileName[i] = '_';
8215ffd83dbSDimitry Andric   }
8225ffd83dbSDimitry Andric 
8235ffd83dbSDimitry Andric   return FileName;
8245ffd83dbSDimitry Andric }
8255ffd83dbSDimitry Andric 
getPrioritySuffix(unsigned int Priority)826fe6060f1SDimitry Andric static std::string getPrioritySuffix(unsigned int Priority) {
827fe6060f1SDimitry Andric   assert(Priority <= 65535 && "Priority should always be <= 65535.");
828fe6060f1SDimitry Andric 
829fe6060f1SDimitry Andric   // Compute the function suffix from priority. Prepend with zeroes to make
830fe6060f1SDimitry Andric   // sure the function names are also ordered as priorities.
831fe6060f1SDimitry Andric   std::string PrioritySuffix = llvm::utostr(Priority);
832fe6060f1SDimitry Andric   PrioritySuffix = std::string(6 - PrioritySuffix.size(), '0') + PrioritySuffix;
833fe6060f1SDimitry Andric 
834fe6060f1SDimitry Andric   return PrioritySuffix;
835fe6060f1SDimitry Andric }
836fe6060f1SDimitry Andric 
8370b57cec5SDimitry Andric void
EmitCXXGlobalInitFunc()8380b57cec5SDimitry Andric CodeGenModule::EmitCXXGlobalInitFunc() {
8390b57cec5SDimitry Andric   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
8400b57cec5SDimitry Andric     CXXGlobalInits.pop_back();
8410b57cec5SDimitry Andric 
842fcaf7f86SDimitry Andric   // When we import C++20 modules, we must run their initializers first.
843fcaf7f86SDimitry Andric   SmallVector<llvm::Function *, 8> ModuleInits;
844fcaf7f86SDimitry Andric   if (CXX20ModuleInits)
845fcaf7f86SDimitry Andric     for (Module *M : ImportedModules) {
84661cfbce3SDimitry Andric       // No Itanium initializer in header like modules.
84761cfbce3SDimitry Andric       if (M->isHeaderLikeModule())
848fcaf7f86SDimitry Andric         continue;
849*0fca6ea1SDimitry Andric       // We're allowed to skip the initialization if we are sure it doesn't
850*0fca6ea1SDimitry Andric       // do any thing.
851*0fca6ea1SDimitry Andric       if (!M->isNamedModuleInterfaceHasInit())
852*0fca6ea1SDimitry Andric         continue;
853fcaf7f86SDimitry Andric       llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
854fcaf7f86SDimitry Andric       SmallString<256> FnName;
855fcaf7f86SDimitry Andric       {
856fcaf7f86SDimitry Andric         llvm::raw_svector_ostream Out(FnName);
857fcaf7f86SDimitry Andric         cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
858fcaf7f86SDimitry Andric             .mangleModuleInitializer(M, Out);
859fcaf7f86SDimitry Andric       }
860fcaf7f86SDimitry Andric       assert(!GetGlobalValue(FnName.str()) &&
861fcaf7f86SDimitry Andric              "We should only have one use of the initializer call");
862fcaf7f86SDimitry Andric       llvm::Function *Fn = llvm::Function::Create(
863fcaf7f86SDimitry Andric           FTy, llvm::Function::ExternalLinkage, FnName.str(), &getModule());
864fcaf7f86SDimitry Andric       ModuleInits.push_back(Fn);
865fcaf7f86SDimitry Andric     }
866fcaf7f86SDimitry Andric 
867fcaf7f86SDimitry Andric   if (ModuleInits.empty() && CXXGlobalInits.empty() &&
868fcaf7f86SDimitry Andric       PrioritizedCXXGlobalInits.empty())
8690b57cec5SDimitry Andric     return;
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
8720b57cec5SDimitry Andric   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
8730b57cec5SDimitry Andric 
8745ffd83dbSDimitry Andric   // Create our global prioritized initialization function.
8750b57cec5SDimitry Andric   if (!PrioritizedCXXGlobalInits.empty()) {
8760b57cec5SDimitry Andric     SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
8770b57cec5SDimitry Andric     llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
8780b57cec5SDimitry Andric                          PrioritizedCXXGlobalInits.end());
8790b57cec5SDimitry Andric     // Iterate over "chunks" of ctors with same priority and emit each chunk
8800b57cec5SDimitry Andric     // into separate function. Note - everything is sorted first by priority,
8810b57cec5SDimitry Andric     // second - by lex order, so we emit ctor functions in proper order.
8820b57cec5SDimitry Andric     for (SmallVectorImpl<GlobalInitData >::iterator
8830b57cec5SDimitry Andric            I = PrioritizedCXXGlobalInits.begin(),
8840b57cec5SDimitry Andric            E = PrioritizedCXXGlobalInits.end(); I != E; ) {
8850b57cec5SDimitry Andric       SmallVectorImpl<GlobalInitData >::iterator
8860b57cec5SDimitry Andric         PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
8870b57cec5SDimitry Andric 
8880b57cec5SDimitry Andric       LocalCXXGlobalInits.clear();
889fe6060f1SDimitry Andric 
890fe6060f1SDimitry Andric       unsigned int Priority = I->first.priority;
8915ffd83dbSDimitry Andric       llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(
892fe6060f1SDimitry Andric           FTy, "_GLOBAL__I_" + getPrioritySuffix(Priority), FI);
8930b57cec5SDimitry Andric 
894fcaf7f86SDimitry Andric       // Prepend the module inits to the highest priority set.
895fcaf7f86SDimitry Andric       if (!ModuleInits.empty()) {
896bdd1243dSDimitry Andric         for (auto *F : ModuleInits)
897fcaf7f86SDimitry Andric           LocalCXXGlobalInits.push_back(F);
898fcaf7f86SDimitry Andric         ModuleInits.clear();
899fcaf7f86SDimitry Andric       }
900fcaf7f86SDimitry Andric 
9010b57cec5SDimitry Andric       for (; I < PrioE; ++I)
9020b57cec5SDimitry Andric         LocalCXXGlobalInits.push_back(I->second);
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric       CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits);
9050b57cec5SDimitry Andric       AddGlobalCtor(Fn, Priority);
9060b57cec5SDimitry Andric     }
9070b57cec5SDimitry Andric     PrioritizedCXXGlobalInits.clear();
9080b57cec5SDimitry Andric   }
9090b57cec5SDimitry Andric 
910fcaf7f86SDimitry Andric   if (getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&
911fcaf7f86SDimitry Andric       CXXGlobalInits.empty())
9125ffd83dbSDimitry Andric     return;
9130b57cec5SDimitry Andric 
914bdd1243dSDimitry Andric   for (auto *F : CXXGlobalInits)
915fcaf7f86SDimitry Andric     ModuleInits.push_back(F);
916fcaf7f86SDimitry Andric   CXXGlobalInits.clear();
917fcaf7f86SDimitry Andric 
9185ffd83dbSDimitry Andric   // Include the filename in the symbol name. Including "sub_" matches gcc
9195ffd83dbSDimitry Andric   // and makes sure these symbols appear lexicographically behind the symbols
92006c3fb27SDimitry Andric   // with priority emitted above.  Module implementation units behave the same
92106c3fb27SDimitry Andric   // way as a non-modular TU with imports.
922fcaf7f86SDimitry Andric   llvm::Function *Fn;
92306c3fb27SDimitry Andric   if (CXX20ModuleInits && getContext().getCurrentNamedModule() &&
92406c3fb27SDimitry Andric       !getContext().getCurrentNamedModule()->isModuleImplementation()) {
925fcaf7f86SDimitry Andric     SmallString<256> InitFnName;
926fcaf7f86SDimitry Andric     llvm::raw_svector_ostream Out(InitFnName);
927fcaf7f86SDimitry Andric     cast<ItaniumMangleContext>(getCXXABI().getMangleContext())
92806c3fb27SDimitry Andric         .mangleModuleInitializer(getContext().getCurrentNamedModule(), Out);
929fcaf7f86SDimitry Andric     Fn = CreateGlobalInitOrCleanUpFunction(
930fcaf7f86SDimitry Andric         FTy, llvm::Twine(InitFnName), FI, SourceLocation(), false,
931fcaf7f86SDimitry Andric         llvm::GlobalVariable::ExternalLinkage);
932fcaf7f86SDimitry Andric   } else
933fcaf7f86SDimitry Andric     Fn = CreateGlobalInitOrCleanUpFunction(
934fcaf7f86SDimitry Andric         FTy,
935fcaf7f86SDimitry Andric         llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())),
936e8d8bef9SDimitry Andric         FI);
9370b57cec5SDimitry Andric 
938fcaf7f86SDimitry Andric   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits);
9390b57cec5SDimitry Andric   AddGlobalCtor(Fn);
9400b57cec5SDimitry Andric 
9410b57cec5SDimitry Andric   // In OpenCL global init functions must be converted to kernels in order to
9420b57cec5SDimitry Andric   // be able to launch them from the host.
9430b57cec5SDimitry Andric   // FIXME: Some more work might be needed to handle destructors correctly.
9440b57cec5SDimitry Andric   // Current initialization function makes use of function pointers callbacks.
9450b57cec5SDimitry Andric   // We can't support function pointers especially between host and device.
9460b57cec5SDimitry Andric   // However it seems global destruction has little meaning without any
9470b57cec5SDimitry Andric   // dynamic resource allocation on the device and program scope variables are
9480b57cec5SDimitry Andric   // destroyed by the runtime when program is released.
9490b57cec5SDimitry Andric   if (getLangOpts().OpenCL) {
95081ad6265SDimitry Andric     GenKernelArgMetadata(Fn);
9510b57cec5SDimitry Andric     Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
9520b57cec5SDimitry Andric   }
9530b57cec5SDimitry Andric 
954fe6060f1SDimitry Andric   assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice ||
955fe6060f1SDimitry Andric          getLangOpts().GPUAllowDeviceInit);
956fe6060f1SDimitry Andric   if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) {
957480093f4SDimitry Andric     Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
958480093f4SDimitry Andric     Fn->addFnAttr("device-init");
959480093f4SDimitry Andric   }
960480093f4SDimitry Andric 
961fcaf7f86SDimitry Andric   ModuleInits.clear();
9620b57cec5SDimitry Andric }
9630b57cec5SDimitry Andric 
EmitCXXGlobalCleanUpFunc()9645ffd83dbSDimitry Andric void CodeGenModule::EmitCXXGlobalCleanUpFunc() {
965fe6060f1SDimitry Andric   if (CXXGlobalDtorsOrStermFinalizers.empty() &&
966fe6060f1SDimitry Andric       PrioritizedCXXStermFinalizers.empty())
9670b57cec5SDimitry Andric     return;
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
9700b57cec5SDimitry Andric   const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
9710b57cec5SDimitry Andric 
972fe6060f1SDimitry Andric   // Create our global prioritized cleanup function.
973fe6060f1SDimitry Andric   if (!PrioritizedCXXStermFinalizers.empty()) {
974fe6060f1SDimitry Andric     SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers;
975fe6060f1SDimitry Andric     llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),
976fe6060f1SDimitry Andric                          PrioritizedCXXStermFinalizers.end());
977fe6060f1SDimitry Andric     // Iterate over "chunks" of dtors with same priority and emit each chunk
978fe6060f1SDimitry Andric     // into separate function. Note - everything is sorted first by priority,
979fe6060f1SDimitry Andric     // second - by lex order, so we emit dtor functions in proper order.
980fe6060f1SDimitry Andric     for (SmallVectorImpl<StermFinalizerData>::iterator
981fe6060f1SDimitry Andric              I = PrioritizedCXXStermFinalizers.begin(),
982fe6060f1SDimitry Andric              E = PrioritizedCXXStermFinalizers.end();
983fe6060f1SDimitry Andric          I != E;) {
984fe6060f1SDimitry Andric       SmallVectorImpl<StermFinalizerData>::iterator PrioE =
985fe6060f1SDimitry Andric           std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());
986fe6060f1SDimitry Andric 
987fe6060f1SDimitry Andric       LocalCXXStermFinalizers.clear();
988fe6060f1SDimitry Andric 
989fe6060f1SDimitry Andric       unsigned int Priority = I->first.priority;
990fe6060f1SDimitry Andric       llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction(
991fe6060f1SDimitry Andric           FTy, "_GLOBAL__a_" + getPrioritySuffix(Priority), FI);
992fe6060f1SDimitry Andric 
993fe6060f1SDimitry Andric       for (; I < PrioE; ++I) {
994fe6060f1SDimitry Andric         llvm::FunctionCallee DtorFn = I->second;
995fe6060f1SDimitry Andric         LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),
996fe6060f1SDimitry Andric                                              DtorFn.getCallee(), nullptr);
997fe6060f1SDimitry Andric       }
998fe6060f1SDimitry Andric 
999fe6060f1SDimitry Andric       CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
1000fe6060f1SDimitry Andric           Fn, LocalCXXStermFinalizers);
1001fe6060f1SDimitry Andric       AddGlobalDtor(Fn, Priority);
1002fe6060f1SDimitry Andric     }
1003fe6060f1SDimitry Andric     PrioritizedCXXStermFinalizers.clear();
1004fe6060f1SDimitry Andric   }
1005fe6060f1SDimitry Andric 
1006fe6060f1SDimitry Andric   if (CXXGlobalDtorsOrStermFinalizers.empty())
1007fe6060f1SDimitry Andric     return;
1008fe6060f1SDimitry Andric 
10095ffd83dbSDimitry Andric   // Create our global cleanup function.
1010e8d8bef9SDimitry Andric   llvm::Function *Fn =
1011e8d8bef9SDimitry Andric       CreateGlobalInitOrCleanUpFunction(FTy, "_GLOBAL__D_a", FI);
10125ffd83dbSDimitry Andric 
10135ffd83dbSDimitry Andric   CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
10145ffd83dbSDimitry Andric       Fn, CXXGlobalDtorsOrStermFinalizers);
10150b57cec5SDimitry Andric   AddGlobalDtor(Fn);
10165ffd83dbSDimitry Andric   CXXGlobalDtorsOrStermFinalizers.clear();
10170b57cec5SDimitry Andric }
10180b57cec5SDimitry Andric 
10190b57cec5SDimitry Andric /// Emit the code necessary to initialize the given global variable.
GenerateCXXGlobalVarDeclInitFunc(llvm::Function * Fn,const VarDecl * D,llvm::GlobalVariable * Addr,bool PerformInit)10200b57cec5SDimitry Andric void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
10210b57cec5SDimitry Andric                                                        const VarDecl *D,
10220b57cec5SDimitry Andric                                                  llvm::GlobalVariable *Addr,
10230b57cec5SDimitry Andric                                                        bool PerformInit) {
10240b57cec5SDimitry Andric   // Check if we need to emit debug info for variable initializer.
10250b57cec5SDimitry Andric   if (D->hasAttr<NoDebugAttr>())
10260b57cec5SDimitry Andric     DebugInfo = nullptr; // disable debug info indefinitely for this function
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric   CurEHLocation = D->getBeginLoc();
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric   StartFunction(GlobalDecl(D, DynamicInitKind::Initializer),
10310b57cec5SDimitry Andric                 getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(),
1032e8d8bef9SDimitry Andric                 FunctionArgList());
1033e8d8bef9SDimitry Andric   // Emit an artificial location for this function.
1034e8d8bef9SDimitry Andric   auto AL = ApplyDebugLocation::CreateArtificial(*this);
10350b57cec5SDimitry Andric 
10360b57cec5SDimitry Andric   // Use guarded initialization if the global variable is weak. This
10370b57cec5SDimitry Andric   // occurs for, e.g., instantiated static data members and
10380b57cec5SDimitry Andric   // definitions explicitly marked weak.
10390b57cec5SDimitry Andric   //
10400b57cec5SDimitry Andric   // Also use guarded initialization for a variable with dynamic TLS and
10410b57cec5SDimitry Andric   // unordered initialization. (If the initialization is ordered, the ABI
10420b57cec5SDimitry Andric   // layer will guard the whole-TU initialization for us.)
10430b57cec5SDimitry Andric   if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage() ||
10440b57cec5SDimitry Andric       (D->getTLSKind() == VarDecl::TLS_Dynamic &&
10450b57cec5SDimitry Andric        isTemplateInstantiation(D->getTemplateSpecializationKind()))) {
10460b57cec5SDimitry Andric     EmitCXXGuardedInit(*D, Addr, PerformInit);
10470b57cec5SDimitry Andric   } else {
10480b57cec5SDimitry Andric     EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
10490b57cec5SDimitry Andric   }
10500b57cec5SDimitry Andric 
1051bdd1243dSDimitry Andric   if (getLangOpts().HLSL)
1052bdd1243dSDimitry Andric     CGM.getHLSLRuntime().annotateHLSLResource(D, Addr);
1053bdd1243dSDimitry Andric 
10540b57cec5SDimitry Andric   FinishFunction();
10550b57cec5SDimitry Andric }
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric void
GenerateCXXGlobalInitFunc(llvm::Function * Fn,ArrayRef<llvm::Function * > Decls,ConstantAddress Guard)10580b57cec5SDimitry Andric CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
10590b57cec5SDimitry Andric                                            ArrayRef<llvm::Function *> Decls,
10600b57cec5SDimitry Andric                                            ConstantAddress Guard) {
10610b57cec5SDimitry Andric   {
10620b57cec5SDimitry Andric     auto NL = ApplyDebugLocation::CreateEmpty(*this);
10630b57cec5SDimitry Andric     StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
10640b57cec5SDimitry Andric                   getTypes().arrangeNullaryFunction(), FunctionArgList());
10650b57cec5SDimitry Andric     // Emit an artificial location for this function.
10660b57cec5SDimitry Andric     auto AL = ApplyDebugLocation::CreateArtificial(*this);
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric     llvm::BasicBlock *ExitBlock = nullptr;
10690b57cec5SDimitry Andric     if (Guard.isValid()) {
10700b57cec5SDimitry Andric       // If we have a guard variable, check whether we've already performed
10710b57cec5SDimitry Andric       // these initializations. This happens for TLS initialization functions.
10720b57cec5SDimitry Andric       llvm::Value *GuardVal = Builder.CreateLoad(Guard);
10730b57cec5SDimitry Andric       llvm::Value *Uninit = Builder.CreateIsNull(GuardVal,
10740b57cec5SDimitry Andric                                                  "guard.uninitialized");
10750b57cec5SDimitry Andric       llvm::BasicBlock *InitBlock = createBasicBlock("init");
10760b57cec5SDimitry Andric       ExitBlock = createBasicBlock("exit");
10770b57cec5SDimitry Andric       EmitCXXGuardedInitBranch(Uninit, InitBlock, ExitBlock,
10780b57cec5SDimitry Andric                                GuardKind::TlsGuard, nullptr);
10790b57cec5SDimitry Andric       EmitBlock(InitBlock);
10800b57cec5SDimitry Andric       // Mark as initialized before initializing anything else. If the
10810b57cec5SDimitry Andric       // initializers use previously-initialized thread_local vars, that's
10820b57cec5SDimitry Andric       // probably supposed to be OK, but the standard doesn't say.
10830b57cec5SDimitry Andric       Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
10840b57cec5SDimitry Andric 
10850b57cec5SDimitry Andric       // The guard variable can't ever change again.
10860b57cec5SDimitry Andric       EmitInvariantStart(
10870b57cec5SDimitry Andric           Guard.getPointer(),
10880b57cec5SDimitry Andric           CharUnits::fromQuantity(
10890b57cec5SDimitry Andric               CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())));
10900b57cec5SDimitry Andric     }
10910b57cec5SDimitry Andric 
10920b57cec5SDimitry Andric     RunCleanupsScope Scope(*this);
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric     // When building in Objective-C++ ARC mode, create an autorelease pool
10950b57cec5SDimitry Andric     // around the global initializers.
10960b57cec5SDimitry Andric     if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) {
10970b57cec5SDimitry Andric       llvm::Value *token = EmitObjCAutoreleasePoolPush();
10980b57cec5SDimitry Andric       EmitObjCAutoreleasePoolCleanup(token);
10990b57cec5SDimitry Andric     }
11000b57cec5SDimitry Andric 
11010b57cec5SDimitry Andric     for (unsigned i = 0, e = Decls.size(); i != e; ++i)
11020b57cec5SDimitry Andric       if (Decls[i])
11030b57cec5SDimitry Andric         EmitRuntimeCall(Decls[i]);
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric     Scope.ForceCleanup();
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric     if (ExitBlock) {
11080b57cec5SDimitry Andric       Builder.CreateBr(ExitBlock);
11090b57cec5SDimitry Andric       EmitBlock(ExitBlock);
11100b57cec5SDimitry Andric     }
11110b57cec5SDimitry Andric   }
11120b57cec5SDimitry Andric 
11130b57cec5SDimitry Andric   FinishFunction();
11140b57cec5SDimitry Andric }
11150b57cec5SDimitry Andric 
GenerateCXXGlobalCleanUpFunc(llvm::Function * Fn,ArrayRef<std::tuple<llvm::FunctionType *,llvm::WeakTrackingVH,llvm::Constant * >> DtorsOrStermFinalizers)11165ffd83dbSDimitry Andric void CodeGenFunction::GenerateCXXGlobalCleanUpFunc(
11170b57cec5SDimitry Andric     llvm::Function *Fn,
1118fe6060f1SDimitry Andric     ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
1119fe6060f1SDimitry Andric                         llvm::Constant *>>
1120fe6060f1SDimitry Andric         DtorsOrStermFinalizers) {
11210b57cec5SDimitry Andric   {
11220b57cec5SDimitry Andric     auto NL = ApplyDebugLocation::CreateEmpty(*this);
11230b57cec5SDimitry Andric     StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
11240b57cec5SDimitry Andric                   getTypes().arrangeNullaryFunction(), FunctionArgList());
11250b57cec5SDimitry Andric     // Emit an artificial location for this function.
11260b57cec5SDimitry Andric     auto AL = ApplyDebugLocation::CreateArtificial(*this);
11270b57cec5SDimitry Andric 
11285ffd83dbSDimitry Andric     // Emit the cleanups, in reverse order from construction.
11295ffd83dbSDimitry Andric     for (unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {
11300b57cec5SDimitry Andric       llvm::FunctionType *CalleeTy;
11310b57cec5SDimitry Andric       llvm::Value *Callee;
11320b57cec5SDimitry Andric       llvm::Constant *Arg;
11335ffd83dbSDimitry Andric       std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
11345ffd83dbSDimitry Andric 
11355ffd83dbSDimitry Andric       llvm::CallInst *CI = nullptr;
11365ffd83dbSDimitry Andric       if (Arg == nullptr) {
11375ffd83dbSDimitry Andric         assert(
11385ffd83dbSDimitry Andric             CGM.getCXXABI().useSinitAndSterm() &&
11395ffd83dbSDimitry Andric             "Arg could not be nullptr unless using sinit and sterm functions.");
11405ffd83dbSDimitry Andric         CI = Builder.CreateCall(CalleeTy, Callee);
11415ffd83dbSDimitry Andric       } else
11425ffd83dbSDimitry Andric         CI = Builder.CreateCall(CalleeTy, Callee, Arg);
11435ffd83dbSDimitry Andric 
11440b57cec5SDimitry Andric       // Make sure the call and the callee agree on calling convention.
11450b57cec5SDimitry Andric       if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
11460b57cec5SDimitry Andric         CI->setCallingConv(F->getCallingConv());
11470b57cec5SDimitry Andric     }
11480b57cec5SDimitry Andric   }
11490b57cec5SDimitry Andric 
11500b57cec5SDimitry Andric   FinishFunction();
11510b57cec5SDimitry Andric }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric /// generateDestroyHelper - Generates a helper function which, when
11540b57cec5SDimitry Andric /// invoked, destroys the given object.  The address of the object
11550b57cec5SDimitry Andric /// should be in global memory.
generateDestroyHelper(Address addr,QualType type,Destroyer * destroyer,bool useEHCleanupForArray,const VarDecl * VD)11560b57cec5SDimitry Andric llvm::Function *CodeGenFunction::generateDestroyHelper(
11570b57cec5SDimitry Andric     Address addr, QualType type, Destroyer *destroyer,
11580b57cec5SDimitry Andric     bool useEHCleanupForArray, const VarDecl *VD) {
11590b57cec5SDimitry Andric   FunctionArgList args;
11600b57cec5SDimitry Andric   ImplicitParamDecl Dst(getContext(), getContext().VoidPtrTy,
11615f757f3fSDimitry Andric                         ImplicitParamKind::Other);
11620b57cec5SDimitry Andric   args.push_back(&Dst);
11630b57cec5SDimitry Andric 
11640b57cec5SDimitry Andric   const CGFunctionInfo &FI =
11650b57cec5SDimitry Andric     CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, args);
11660b57cec5SDimitry Andric   llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
11675ffd83dbSDimitry Andric   llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction(
11680b57cec5SDimitry Andric       FTy, "__cxx_global_array_dtor", FI, VD->getLocation());
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric   CurEHLocation = VD->getBeginLoc();
11710b57cec5SDimitry Andric 
1172e8d8bef9SDimitry Andric   StartFunction(GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor),
1173e8d8bef9SDimitry Andric                 getContext().VoidTy, fn, FI, args);
1174e8d8bef9SDimitry Andric   // Emit an artificial location for this function.
1175e8d8bef9SDimitry Andric   auto AL = ApplyDebugLocation::CreateArtificial(*this);
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric   emitDestroy(addr, type, destroyer, useEHCleanupForArray);
11780b57cec5SDimitry Andric 
11790b57cec5SDimitry Andric   FinishFunction();
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric   return fn;
11820b57cec5SDimitry Andric }
1183