CGDeclCXX.cpp revision 410ffb2bc5f072d58a73c14560345bcf77dec1cc
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 31a07398ed98ea2b55ad7a505a3aab18aed93b149fJohn McCall unsigned alignment = Context.getDeclAlign(&D).getQuantity(); 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 { 497c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, 50410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall AggValueSlot::DoesNotNeedGCBarriers, 51410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall 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 101a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall CGF.EmitCXXGlobalDtorRegistration(function, argument); 102cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor} 103cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 104fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlssonvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 105fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Constant *DeclPtr) { 106fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 107fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson const Expr *Init = D.getInit(); 108fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson QualType T = D.getType(); 109fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 110fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!T->isReferenceType()) { 111fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson EmitDeclInit(*this, D, DeclPtr); 112cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor EmitDeclDestroy(*this, D, DeclPtr); 113fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson return; 114fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson } 115045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson 11691a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 117045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson RValue RV = EmitReferenceBindingToExpr(Init, &D); 11891a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); 119fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson} 120eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 121efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 122efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 123efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant *DeclPtr) { 124efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Generate a global destructor entry if not using __cxa_atexit. 125efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (!CGM.getCodeGenOpts().CXAAtExit) { 126efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 127efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 128efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar } 129efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 130eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the destructor function type 1319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *DtorFnTy = 132d16c2cf1cafa413709aa487cbbd5dc392f1ba1ffJohn McCall llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 133da549e8995c447542d5631b8b67fcc3a9582797aJay Foad Int8PtrTy, false); 134eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 135eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 1369cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner llvm::Type *Params[] = { DtorFnTy, Int8PtrTy, Int8PtrTy }; 137eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 138eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the __cxa_atexit function type 139eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 1402acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *AtExitFnTy = 141eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 142eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 143eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 144eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__cxa_atexit"); 145bd4a0732f2f261f8269a71c2090bc3e9d001eca6Anders Carlsson if (llvm::Function *Fn = dyn_cast<llvm::Function>(AtExitFn)) 146bd4a0732f2f261f8269a71c2090bc3e9d001eca6Anders Carlsson Fn->setDoesNotThrow(); 147eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 148eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, 149eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__dso_handle"); 150eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), 151eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), 152eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; 1534c7d9f1507d0f102bd4133bba63348636facd469Jay Foad Builder.CreateCall(AtExitFn, Args); 154eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 155eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 1563030eb82593097502469a8b3fc26112c79c75605John McCallvoid CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, 1573030eb82593097502469a8b3fc26112c79c75605John McCall llvm::GlobalVariable *DeclPtr) { 15832096695c76033a6b0b1747c439f7378a11e8312John McCall // If we've been asked to forbid guard variables, emit an error now. 15932096695c76033a6b0b1747c439f7378a11e8312John McCall // This diagnostic is hard-coded for Darwin's use case; we can find 16032096695c76033a6b0b1747c439f7378a11e8312John McCall // better phrasing if someone else needs it. 16132096695c76033a6b0b1747c439f7378a11e8312John McCall if (CGM.getCodeGenOpts().ForbidGuardVariables) 16232096695c76033a6b0b1747c439f7378a11e8312John McCall CGM.Error(D.getLocation(), 16332096695c76033a6b0b1747c439f7378a11e8312John McCall "this initialization requires a guard variable, which " 16432096695c76033a6b0b1747c439f7378a11e8312John McCall "the kernel does not support"); 16532096695c76033a6b0b1747c439f7378a11e8312John McCall 1663030eb82593097502469a8b3fc26112c79c75605John McCall CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr); 1675cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 1685cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 1699dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlssonstatic llvm::Function * 1709dc046e70d189457968e4c3b986da75b5d98ce8eAnders CarlssonCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 1712acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy, 1725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Name) { 1739dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 1749dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 1759dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson Name, &CGM.getModule()); 176d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian if (!CGM.getContext().getLangOptions().AppleKext) { 177d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian // Set the section if needed. 178d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian if (const char *Section = 179d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian CGM.getContext().Target.getStaticInitSectionSpecifier()) 180d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian Fn->setSection(Section); 181d6c9a0f06ce7e164024d8e4dbf2423a5c5035084Fariborz Jahanian } 18218af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson 1837a17851eee37f933eb57a5af7e1a0eb455443f6aAnders Carlsson if (!CGM.getLangOptions().Exceptions) 184044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall Fn->setDoesNotThrow(); 185044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall 1869dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson return Fn; 1879dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson} 1889dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 189efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 1903030eb82593097502469a8b3fc26112c79c75605John McCallCodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 1913030eb82593097502469a8b3fc26112c79c75605John McCall llvm::GlobalVariable *Addr) { 1922acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy 1936c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 1946c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman false); 1956c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1966c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman // Create a variable initialization function. 1976c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman llvm::Function *Fn = 1989dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 1996c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2003030eb82593097502469a8b3fc26112c79c75605John McCall CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr); 2016c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2029f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (D->hasAttr<InitPriorityAttr>()) { 2039f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 204ec2830d930e306124c2ba6bf1060a3c71dced6eaChris Lattner OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 205e0b691a25f801d8be552c9387863637b9526e639Fariborz Jahanian PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 206bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(D); 207bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 208bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall else { 209bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall llvm::DenseMap<const Decl *, unsigned>::iterator I = 210bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.find(D); 211bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (I == DelayedCXXInitPosition.end()) { 212bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.push_back(Fn); 213bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } else { 214bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall assert(CXXGlobalInits[I->second] == 0); 215bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits[I->second] = Fn; 216bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(I); 217bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 2189f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2196c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman} 2206c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 221efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 222efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenModule::EmitCXXGlobalInitFunc() { 223bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 224bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.pop_back(); 225bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall 2269f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 227eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson return; 228eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 2292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy 230eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 231eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson false); 232eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 233eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Create our global initialization function. 2349dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 2359dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 236efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2379f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (!PrioritizedCXXGlobalInits.empty()) { 2385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 239027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 240f489688114275c821b1e647e26f71eeb94d8ab24Fariborz Jahanian PrioritizedCXXGlobalInits.end()); 2419f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) { 2429f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; 2439f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.push_back(Fn); 2449f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 245bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); 2469f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2479f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &LocalCXXGlobalInits[0], 2489f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.size()); 2499f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2509f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian else 2519f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2529f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &CXXGlobalInits[0], 2539f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CXXGlobalInits.size()); 254efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalCtor(Fn); 25554ec6c59d8b2e529fc3f07ae97415721f394ad92Axel Naumann CXXGlobalInits.clear(); 25654ec6c59d8b2e529fc3f07ae97415721f394ad92Axel Naumann PrioritizedCXXGlobalInits.clear(); 257efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 258efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 259efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenModule::EmitCXXGlobalDtorFunc() { 260efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (CXXGlobalDtors.empty()) 261efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 262efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2632acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy 264efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 265efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar false); 266eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 267efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Create our global destructor function. 268efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Function *Fn = 2699dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 270efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 271efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 272efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalDtor(Fn); 273efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 274efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2753030eb82593097502469a8b3fc26112c79c75605John McCall/// Emit the code necessary to initialize the given global variable. 276efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 2773030eb82593097502469a8b3fc26112c79c75605John McCall const VarDecl *D, 2783030eb82593097502469a8b3fc26112c79c75605John McCall llvm::GlobalVariable *Addr) { 279d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 280d26bc76c98006609002d9930f8840490e88ac5b5John McCall getTypes().getNullaryFunctionInfo(), 281d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList(), SourceLocation()); 2826c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 283e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor // Use guarded initialization if the global variable is weak. This 284e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor // occurs for, e.g., instantiated static data members and 285e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor // definitions explicitly marked weak. 286e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage || 287e67d1512f299e7f32182553f9941d61dae4f433eDouglas Gregor Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) { 2883030eb82593097502469a8b3fc26112c79c75605John McCall EmitCXXGuardedInit(*D, Addr); 2893030eb82593097502469a8b3fc26112c79c75605John McCall } else { 2903030eb82593097502469a8b3fc26112c79c75605John McCall EmitCXXGlobalVarDeclInit(*D, Addr); 29192d835a86ac334768d0b75936201e4fea3941c1fFariborz Jahanian } 2926c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2936c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman FinishFunction(); 294efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 295eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 296efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 297efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant **Decls, 298efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar unsigned NumDecls) { 299d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 300d26bc76c98006609002d9930f8840490e88ac5b5John McCall getTypes().getNullaryFunctionInfo(), 301d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList(), SourceLocation()); 302efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 303f85e193739c953358c865005855253af4f68a497John McCall RunCleanupsScope Scope(*this); 304f85e193739c953358c865005855253af4f68a497John McCall 305f85e193739c953358c865005855253af4f68a497John McCall // When building in Objective-C++ ARC mode, create an autorelease pool 306f85e193739c953358c865005855253af4f68a497John McCall // around the global initializers. 307f85e193739c953358c865005855253af4f68a497John McCall if (getLangOptions().ObjCAutoRefCount && getLangOptions().CPlusPlus) { 308f85e193739c953358c865005855253af4f68a497John McCall llvm::Value *token = EmitObjCAutoreleasePoolPush(); 309f85e193739c953358c865005855253af4f68a497John McCall EmitObjCAutoreleasePoolCleanup(token); 310f85e193739c953358c865005855253af4f68a497John McCall } 311f85e193739c953358c865005855253af4f68a497John McCall 312efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar for (unsigned i = 0; i != NumDecls; ++i) 313bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (Decls[i]) 314f85e193739c953358c865005855253af4f68a497John McCall Builder.CreateCall(Decls[i]); 315efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 316f85e193739c953358c865005855253af4f68a497John McCall Scope.ForceCleanup(); 317f85e193739c953358c865005855253af4f68a497John McCall 318efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 319efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 320efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 321efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 322810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 323efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar &DtorsAndObjects) { 324d26bc76c98006609002d9930f8840490e88ac5b5John McCall StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 325d26bc76c98006609002d9930f8840490e88ac5b5John McCall getTypes().getNullaryFunctionInfo(), 326d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList(), SourceLocation()); 327efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 328efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Emit the dtors, in reverse order from construction. 329c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 330810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 331c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner llvm::CallInst *CI = Builder.CreateCall(Callee, 332c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner DtorsAndObjects[e - i - 1].second); 333c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner // Make sure the call and the callee agree on calling convention. 334c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 335c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner CI->setCallingConv(F->getCallingConv()); 336c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner } 337efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 338efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 339eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 340eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 341a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall/// generateDestroyHelper - Generates a helper function which, when 342a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall/// invoked, destroys the given object. 343772913659894551b02f342e3577e7219e4f9a701Anders Carlssonllvm::Function * 344a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCallCodeGenFunction::generateDestroyHelper(llvm::Constant *addr, 345a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall QualType type, 346a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall Destroyer &destroyer, 347a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall bool useEHCleanupForArray) { 348d26bc76c98006609002d9930f8840490e88ac5b5John McCall FunctionArgList args; 349d26bc76c98006609002d9930f8840490e88ac5b5John McCall ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy); 350d26bc76c98006609002d9930f8840490e88ac5b5John McCall args.push_back(&dst); 351772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 352772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const CGFunctionInfo &FI = 353d26bc76c98006609002d9930f8840490e88ac5b5John McCall CGM.getTypes().getFunctionInfo(getContext().VoidTy, args, 354772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FunctionType::ExtInfo()); 3552acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 356a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall llvm::Function *fn = 3579dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 358772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 359a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args, 360d26bc76c98006609002d9930f8840490e88ac5b5John McCall SourceLocation()); 361772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 362a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall emitDestroy(addr, type, destroyer, useEHCleanupForArray); 363772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 364772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FinishFunction(); 365772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 366a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall return fn; 367772913659894551b02f342e3577e7219e4f9a701Anders Carlsson} 368a91f6661c4685fecee6dc09bdaef73254c1aaa06John McCall 369