CGDeclCXX.cpp revision 78d1a10e13a1abfd4830bccf2a97b2993da1ed5c
15ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson//===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===// 25ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// 35ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// The LLVM Compiler Infrastructure 45ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// 55ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// This file is distributed under the University of Illinois Open Source 65ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// License. See LICENSE.TXT for details. 75ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// 85ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson//===----------------------------------------------------------------------===// 95ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// 105ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// This contains code dealing with code generation of C++ declarations 115ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson// 125ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson//===----------------------------------------------------------------------===// 135ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 145ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson#include "CodeGenFunction.h" 15ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian#include "CGObjCRuntime.h" 164c40d98ab7acf5f27fa89b17bd8fc0ef7683df37John McCall#include "CGCXXABI.h" 1706057cef0bcd7804e80f3ce2bbe352178396c715Chandler Carruth#include "clang/Frontend/CodeGenOptions.h" 1886a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor#include "llvm/Intrinsics.h" 1986a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor 205ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlssonusing namespace clang; 215ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlssonusing namespace CodeGen; 225ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 23fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlssonstatic void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, 24fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Constant *DeclPtr) { 25fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); 26fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson assert(!D.getType()->isReferenceType() && 27fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson "Should not call EmitDeclInit on a reference!"); 28fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 29fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson ASTContext &Context = CGF.getContext(); 305ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 316da2c716017d5c8530ec99779524491ebc5dadb8Eli Friedman CharUnits alignment = Context.getDeclAlign(&D); 32a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall QualType type = D.getType(); 33a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall LValue lv = CGF.MakeAddrLValue(DeclPtr, type, alignment); 34a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall 35a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall const Expr *Init = D.getInit(); 36a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall if (!CGF.hasAggregateLLVMType(type)) { 37ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian CodeGenModule &CGM = CGF.CGM; 38a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall if (lv.isObjCStrong()) 39f85e193739c953358c865005855253af4f68a497John McCall CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init), 40f85e193739c953358c865005855253af4f68a497John McCall DeclPtr, D.isThreadSpecified()); 41a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall else if (lv.isObjCWeak()) 42a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init), 43a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall DeclPtr); 44ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian else 45a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall CGF.EmitScalarInit(Init, &D, lv, false); 46a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall } else if (type->isAnyComplexType()) { 47a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile()); 485ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } else { 49649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, 50649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::DoesNotNeedGCBarriers, 51649b4a1a9b5e6f768ca0cb84bd97b00f51083e15Chad Rosier AggValueSlot::IsNotAliased)); 525ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } 535ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson} 545ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 555cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall/// Emit code to cause the destruction of the given variable with 565cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall/// static storage duration. 57cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregorstatic void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 58a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall llvm::Constant *addr) { 59cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CodeGenModule &CGM = CGF.CGM; 60a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 61a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall // FIXME: __attribute__((cleanup)) ? 62cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 63a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall QualType type = D.getType(); 64a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall QualType::DestructionKind dtorKind = type.isDestructedType(); 65a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 66a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall switch (dtorKind) { 67a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall case QualType::DK_none: 68cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 69a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 70a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall case QualType::DK_cxx_destructor: 71a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall break; 72a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 73a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall case QualType::DK_objc_strong_lifetime: 74a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall case QualType::DK_objc_weak_lifetime: 75a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall // We don't care about releasing objects during process teardown. 76cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 77a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall } 78a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 79a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall llvm::Constant *function; 80a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall llvm::Constant *argument; 81a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 82a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall // Special-case non-array C++ destructors, where there's a function 83a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall // with the right signature that we can just call. 84a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall const CXXRecordDecl *record = 0; 85a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall if (dtorKind == QualType::DK_cxx_destructor && 86a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall (record = type->getAsCXXRecordDecl())) { 87a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall assert(!record->hasTrivialDestructor()); 88a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall CXXDestructorDecl *dtor = record->getDestructor(); 89a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 90a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall function = CGM.GetAddrOfCXXDestructor(dtor, Dtor_Complete); 91a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall argument = addr; 92a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 93a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall // Otherwise, the standard logic requires a helper function. 94a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall } else { 95a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall function = CodeGenFunction(CGM).generateDestroyHelper(addr, type, 96a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall CGF.getDestroyer(dtorKind), 97a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall CGF.needsEHCleanup(dtorKind)); 98a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall argument = llvm::Constant::getNullValue(CGF.Int8PtrTy); 99a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall } 100a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 10120bb175cb8ae5844034828db094fb948c0e3454aJohn McCall CGM.getCXXABI().registerGlobalDtor(CGF, function, argument); 102cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor} 103cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 104abb943284cabd9131586c2758a4f02baba668aceRichard Smith/// Emit code to cause the variable at the given address to be considered as 105abb943284cabd9131586c2758a4f02baba668aceRichard Smith/// constant from this point onwards. 106ef7844666b36226521e459d18f2834dacaa039e3Nick Lewyckystatic void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D, 107ef7844666b36226521e459d18f2834dacaa039e3Nick Lewycky llvm::Constant *Addr) { 10800a8c3f6c979a11b15b2a4a4ce08c7888634d6cdRichard Smith // Don't emit the intrinsic if we're not optimizing. 10900a8c3f6c979a11b15b2a4a4ce08c7888634d6cdRichard Smith if (!CGF.CGM.getCodeGenOpts().OptimizationLevel) 11000a8c3f6c979a11b15b2a4a4ce08c7888634d6cdRichard Smith return; 11100a8c3f6c979a11b15b2a4a4ce08c7888634d6cdRichard Smith 112abb943284cabd9131586c2758a4f02baba668aceRichard Smith // Grab the llvm.invariant.start intrinsic. 113abb943284cabd9131586c2758a4f02baba668aceRichard Smith llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start; 114abb943284cabd9131586c2758a4f02baba668aceRichard Smith llvm::Constant *InvariantStart = CGF.CGM.getIntrinsic(InvStartID); 115abb943284cabd9131586c2758a4f02baba668aceRichard Smith 116ef7844666b36226521e459d18f2834dacaa039e3Nick Lewycky // Emit a call with the size in bytes of the object. 117ef7844666b36226521e459d18f2834dacaa039e3Nick Lewycky CharUnits WidthChars = CGF.getContext().getTypeSizeInChars(D.getType()); 118ef7844666b36226521e459d18f2834dacaa039e3Nick Lewycky uint64_t Width = WidthChars.getQuantity(); 119ef7844666b36226521e459d18f2834dacaa039e3Nick Lewycky llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(CGF.Int64Ty, Width), 120abb943284cabd9131586c2758a4f02baba668aceRichard Smith llvm::ConstantExpr::getBitCast(Addr, CGF.Int8PtrTy)}; 121abb943284cabd9131586c2758a4f02baba668aceRichard Smith CGF.Builder.CreateCall(InvariantStart, Args); 122abb943284cabd9131586c2758a4f02baba668aceRichard Smith} 123abb943284cabd9131586c2758a4f02baba668aceRichard Smith 124fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlssonvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 1257ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith llvm::Constant *DeclPtr, 1267ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith bool PerformInit) { 127fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 128fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson const Expr *Init = D.getInit(); 129fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson QualType T = D.getType(); 130fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 131fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!T->isReferenceType()) { 1327ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith if (PerformInit) 1337ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith EmitDeclInit(*this, D, DeclPtr); 134abb943284cabd9131586c2758a4f02baba668aceRichard Smith if (CGM.isTypeConstant(D.getType(), true)) 135ef7844666b36226521e459d18f2834dacaa039e3Nick Lewycky EmitDeclInvariant(*this, D, DeclPtr); 136abb943284cabd9131586c2758a4f02baba668aceRichard Smith else 137abb943284cabd9131586c2758a4f02baba668aceRichard Smith EmitDeclDestroy(*this, D, DeclPtr); 138fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson return; 139fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson } 140045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson 1417ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith assert(PerformInit && "cannot have constant initializer which needs " 1427ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith "destruction for reference"); 14391a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 144045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson RValue RV = EmitReferenceBindingToExpr(Init, &D); 14591a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); 146fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson} 147eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 14830fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCallstatic llvm::Function * 14930fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCallCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 15030fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::FunctionType *ty, 15130fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall const Twine &name); 15230fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall 15330fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall/// Create a stub function, suitable for being passed to atexit, 15430fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall/// which passes the given address to the given destructor function. 15530fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCallstatic llvm::Constant *createAtExitStub(CodeGenModule &CGM, 15630fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::Constant *dtor, 15730fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::Constant *addr) { 15830fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall // Get the destructor function type, void(*)(void). 15930fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false); 16030fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::Function *fn = 16130fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall CreateGlobalInitOrDestructFunction(CGM, ty, 16230fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall Twine("__dtor_", addr->getName())); 16330fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall 16430fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall CodeGenFunction CGF(CGM); 165efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 16630fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, fn, 16730fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall CGM.getTypes().arrangeNullaryFunction(), 16830fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall FunctionArgList(), SourceLocation()); 169eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 17030fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); 17130fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall 17230fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall // Make sure the call and the callee agree on calling convention. 17330fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall if (llvm::Function *dtorFn = 17430fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall dyn_cast<llvm::Function>(dtor->stripPointerCasts())) 17530fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall call->setCallingConv(dtorFn->getCallingConv()); 176eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 17730fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall CGF.FinishFunction(); 178eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 17930fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall return fn; 18030fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall} 18130fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall 18220bb175cb8ae5844034828db094fb948c0e3454aJohn McCall/// Register a global destructor using the C atexit runtime function. 18320bb175cb8ae5844034828db094fb948c0e3454aJohn McCallvoid CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtor, 18420bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Constant *addr) { 18530fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall // Create a function which calls the destructor. 18620bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::Constant *dtorStub = createAtExitStub(CGM, dtor, addr); 18730fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall 18830fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall // extern "C" int atexit(void (*f)(void)); 18930fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::FunctionType *atexitTy = 19020bb175cb8ae5844034828db094fb948c0e3454aJohn McCall llvm::FunctionType::get(IntTy, dtorStub->getType(), false); 19130fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall 19230fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall llvm::Constant *atexit = 19320bb175cb8ae5844034828db094fb948c0e3454aJohn McCall CGM.CreateRuntimeFunction(atexitTy, "atexit"); 19430fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit)) 19530fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall atexitFn->setDoesNotThrow(); 19630fa3707c440222f65fcbb78ee8677462ea0d9ceJohn McCall 19720bb175cb8ae5844034828db094fb948c0e3454aJohn McCall Builder.CreateCall(atexit, dtorStub)->setDoesNotThrow(); 198eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 199eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 2003030eb82593097502469a8b3fc26112c79c75605John McCallvoid CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, 2010f30a12ce7b3d4d86c9ca9072f587da77c8eef34Chandler Carruth llvm::GlobalVariable *DeclPtr, 2027ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith bool PerformInit) { 20332096695c76033a6b0b1747c439f7378a11e8312John McCall // If we've been asked to forbid guard variables, emit an error now. 20432096695c76033a6b0b1747c439f7378a11e8312John McCall // This diagnostic is hard-coded for Darwin's use case; we can find 20532096695c76033a6b0b1747c439f7378a11e8312John McCall // better phrasing if someone else needs it. 20632096695c76033a6b0b1747c439f7378a11e8312John McCall if (CGM.getCodeGenOpts().ForbidGuardVariables) 20732096695c76033a6b0b1747c439f7378a11e8312John McCall CGM.Error(D.getLocation(), 20832096695c76033a6b0b1747c439f7378a11e8312John McCall "this initialization requires a guard variable, which " 20932096695c76033a6b0b1747c439f7378a11e8312John McCall "the kernel does not support"); 21032096695c76033a6b0b1747c439f7378a11e8312John McCall 2110f30a12ce7b3d4d86c9ca9072f587da77c8eef34Chandler Carruth CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit); 2125cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 2135cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 2149dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlssonstatic llvm::Function * 2159dc046e70d189457968e4c3b986da75b5d98ce8eAnders CarlssonCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 2162acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy, 217a0786c91dfd920573e26c82e242143b6ec610b19NAKAMURA Takumi const Twine &Name) { 2189dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 2199dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 2209dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson Name, &CGM.getModule()); 2214e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!CGM.getContext().getLangOpts().AppleKext) { 222d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian // Set the section if needed. 223d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian if (const char *Section = 224bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor CGM.getContext().getTargetInfo().getStaticInitSectionSpecifier()) 225d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian Fn->setSection(Section); 226d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian } 22718af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson 2284e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!CGM.getLangOpts().Exceptions) 229044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall Fn->setDoesNotThrow(); 230044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall 231b9d2b3b8edf7a0dc56e55acb1cf87338d5648daaKostya Serebryany if (CGM.getLangOpts().AddressSanitizer) 232b9d2b3b8edf7a0dc56e55acb1cf87338d5648daaKostya Serebryany Fn->addFnAttr(llvm::Attribute::AddressSafety); 233b9d2b3b8edf7a0dc56e55acb1cf87338d5648daaKostya Serebryany 2349dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson return Fn; 2359dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson} 2369dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 237efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 2383030eb82593097502469a8b3fc26112c79c75605John McCallCodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 2397ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith llvm::GlobalVariable *Addr, 2407ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith bool PerformInit) { 2418b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 2426c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2436c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman // Create a variable initialization function. 2446c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman llvm::Function *Fn = 2459dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 2466c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2477ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr, 2487ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith PerformInit); 2496c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2509f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (D->hasAttr<InitPriorityAttr>()) { 2519f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 252ec2830d930e306124c2ba6bf1060a3c71dced6eaChris Lattner OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 253e0b691a25f801d8be552c9387863637b9526e639Fariborz Jahanian PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 254bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(D); 255bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 256bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall else { 257bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall llvm::DenseMap<const Decl *, unsigned>::iterator I = 258bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.find(D); 259bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (I == DelayedCXXInitPosition.end()) { 260bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.push_back(Fn); 261bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } else { 262bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall assert(CXXGlobalInits[I->second] == 0); 263bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits[I->second] = Fn; 264bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(I); 265bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 2669f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2676c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman} 2686c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 269efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 270efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenModule::EmitCXXGlobalInitFunc() { 271bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 272bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.pop_back(); 273bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall 2749f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 275eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson return; 276eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 2778b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 278eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 279eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Create our global initialization function. 2809dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 2819dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 282efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2839f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (!PrioritizedCXXGlobalInits.empty()) { 2845f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 285027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 286f489688114275c821b1e647e26f71eeb94d8ab24Fariborz Jahanian PrioritizedCXXGlobalInits.end()); 2879f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) { 2889f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; 2899f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.push_back(Fn); 2909f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 291bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); 2929f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2939f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &LocalCXXGlobalInits[0], 2949f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.size()); 2959f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2969f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian else 2979f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2989f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &CXXGlobalInits[0], 2999f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CXXGlobalInits.size()); 300efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalCtor(Fn); 30154ec6c59d8b2e529fc3f07ae97415721f394ad92Axel Naumann CXXGlobalInits.clear(); 30254ec6c59d8b2e529fc3f07ae97415721f394ad92Axel Naumann PrioritizedCXXGlobalInits.clear(); 303efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 304efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 305efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenModule::EmitCXXGlobalDtorFunc() { 306efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (CXXGlobalDtors.empty()) 307efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 308efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 3098b418685e9e4f02f4eb2a76e1ec063e07552b68dChris Lattner llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 310eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 311efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Create our global destructor function. 312efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Function *Fn = 3139dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 314efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 3153f88f686e32949ffe02ccb551f482f9cf810358bJohn McCall CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors); 316efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalDtor(Fn); 317efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 318efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 3193030eb82593097502469a8b3fc26112c79c75605John McCall/// Emit the code necessary to initialize the given global variable. 320efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 3213030eb82593097502469a8b3fc26112c79c75605John McCall const VarDecl *D, 3227ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith llvm::GlobalVariable *Addr, 3237ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith bool PerformInit) { 32478d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky if (CGM.getModuleDebugInfo() && !D->hasAttr<NoDebugAttr>()) 32578d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky DebugInfo = CGM.getModuleDebugInfo(); 32678d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky 32778d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky StartFunction(GlobalDecl(D), getContext().VoidTy, Fn, 328de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall getTypes().arrangeNullaryFunction(), 32978d1a10e13a1abfd4830bccf2a97b2993da1ed5cNick Lewycky FunctionArgList(), D->getInit()->getExprLoc()); 3306c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 331e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor // Use guarded initialization if the global variable is weak. This 332e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor // occurs for, e.g., instantiated static data members and 333e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor // definitions explicitly marked weak. 334e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage || 335e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) { 3367ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith EmitCXXGuardedInit(*D, Addr, PerformInit); 3373030eb82593097502469a8b3fc26112c79c75605John McCall } else { 3387ca4850a3e3530fa6c93b64b740446e32c97f992Richard Smith EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit); 33992d835a86ac334768d0b75936201e4fea3941c1fFariborz Jahanian } 3406c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 3416c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman FinishFunction(); 342efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 343eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 344efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 345efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant **Decls, 346efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar unsigned NumDecls) { 347d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 348de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall getTypes().arrangeNullaryFunction(), 349d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList(), SourceLocation()); 350efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 351f85e193739c953358c865005855253af4f68a497John McCall RunCleanupsScope Scope(*this); 352f85e193739c953358c865005855253af4f68a497John McCall 353f85e193739c953358c865005855253af4f68a497John McCall // When building in Objective-C++ ARC mode, create an autorelease pool 354f85e193739c953358c865005855253af4f68a497John McCall // around the global initializers. 3554e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) { 356f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *token = EmitObjCAutoreleasePoolPush(); 357f85e193739c953358c865005855253af4f68a497John McCall EmitObjCAutoreleasePoolCleanup(token); 358f85e193739c953358c865005855253af4f68a497John McCall } 359f85e193739c953358c865005855253af4f68a497John McCall 360efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar for (unsigned i = 0; i != NumDecls; ++i) 361bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (Decls[i]) 362f85e193739c953358c865005855253af4f68a497John McCall Builder.CreateCall(Decls[i]); 363efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 364f85e193739c953358c865005855253af4f68a497John McCall Scope.ForceCleanup(); 365f85e193739c953358c865005855253af4f68a497John McCall 366efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 367efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 368efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 3693f88f686e32949ffe02ccb551f482f9cf810358bJohn McCallvoid CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, 370810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 371efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar &DtorsAndObjects) { 372d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 373de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall getTypes().arrangeNullaryFunction(), 374d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList(), SourceLocation()); 375efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 376efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Emit the dtors, in reverse order from construction. 377c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 378810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 379c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner llvm::CallInst *CI = Builder.CreateCall(Callee, 380c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner DtorsAndObjects[e - i - 1].second); 381c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner // Make sure the call and the callee agree on calling convention. 382c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 383c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner CI->setCallingConv(F->getCallingConv()); 384c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner } 385efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 386efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 387eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 388eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 389a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall/// generateDestroyHelper - Generates a helper function which, when 390a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall/// invoked, destroys the given object. 391772913659894551b02f342e3577e7219e4f9a701Anders Carlssonllvm::Function * 392a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCallCodeGenFunction::generateDestroyHelper(llvm::Constant *addr, 393a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall QualType type, 394516bbd42e62d709013824d6fb8445a0cfda3129aPeter Collingbourne Destroyer *destroyer, 395a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall bool useEHCleanupForArray) { 396d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList args; 397d26bc76c98006609002d9930f8840490e88ac5b5John McCall ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy); 398d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&dst); 399772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 400772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const CGFunctionInfo &FI = 401de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall CGM.getTypes().arrangeFunctionDeclaration(getContext().VoidTy, args, 402de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall FunctionType::ExtInfo(), 403de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall /*variadic*/ false); 404de5d3c717684f3821b8db58037bc7140acf134aaJohn McCall llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI); 405a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall llvm::Function *fn = 4069dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 407772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 408a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args, 409d26bc76c98006609002d9930f8840490e88ac5b5John McCall SourceLocation()); 410772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 411a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall emitDestroy(addr, type, destroyer, useEHCleanupForArray); 412772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 413772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FinishFunction(); 414772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 415a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall return fn; 416772913659894551b02f342e3577e7219e4f9a701Anders Carlsson} 417