CGDeclCXX.cpp revision ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bf
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(); 30fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 315ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson const Expr *Init = D.getInit(); 325ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson QualType T = D.getType(); 33fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson bool isVolatile = Context.getCanonicalType(T).isVolatileQualified(); 345ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 3591a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = Context.getDeclAlign(&D).getQuantity(); 36fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!CGF.hasAggregateLLVMType(T)) { 37fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Value *V = CGF.EmitScalarExpr(Init); 38ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian CodeGenModule &CGM = CGF.CGM; 39ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian if (CGF.getContext().getObjCGCAttrKind(T) == Qualifiers::Strong) 40ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, V, DeclPtr, 41ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian D.isThreadSpecified()); 42ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian else if (CGF.getContext().getObjCGCAttrKind(T) == Qualifiers::Weak) 43ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, V, DeclPtr); 44ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian else 45ec8051276e5ba5eb3f8dcb0ebb96e17495cbc2bfFariborz Jahanian CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, Alignment, T); 465ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } else if (T->isAnyComplexType()) { 47fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile); 485ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } else { 49558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall CGF.EmitAggExpr(Init, AggValueSlot::forAddr(DeclPtr, isVolatile, true)); 505ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } 515ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson} 525ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 535cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall/// Emit code to cause the destruction of the given variable with 545cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall/// static storage duration. 55cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregorstatic void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 56cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor llvm::Constant *DeclPtr) { 57cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CodeGenModule &CGM = CGF.CGM; 58cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor ASTContext &Context = CGF.getContext(); 59cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 60cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor QualType T = D.getType(); 61cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 6285aca0f6a9da02bda705690fd56d0aa713604f08John McCall // Drill down past array types. 63cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const ConstantArrayType *Array = Context.getAsConstantArrayType(T); 64cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (Array) 65cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor T = Context.getBaseElementType(Array); 66cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 6785aca0f6a9da02bda705690fd56d0aa713604f08John McCall /// If that's not a record, we're done. 6885aca0f6a9da02bda705690fd56d0aa713604f08John McCall /// FIXME: __attribute__((cleanup)) ? 69cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const RecordType *RT = T->getAs<RecordType>(); 70cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (!RT) 71cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 72cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 73cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 74cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (RD->hasTrivialDestructor()) 75cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 76cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 771d110e05e0ff48c1c7a483d6b7fd094cdf28316aDouglas Gregor CXXDestructorDecl *Dtor = RD->getDestructor(); 78cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 79cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor llvm::Constant *DtorFn; 80cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (Array) { 81cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DtorFn = 8202e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, Array, 8302e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson DeclPtr); 84cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const llvm::Type *Int8PtrTy = 8502e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 86cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DeclPtr = llvm::Constant::getNullValue(Int8PtrTy); 87cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor } else 88cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete); 89cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 90cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr); 91cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor} 92cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 93fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlssonvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 94fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Constant *DeclPtr) { 95fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 96fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson const Expr *Init = D.getInit(); 97fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson QualType T = D.getType(); 98fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 99fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!T->isReferenceType()) { 100fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson EmitDeclInit(*this, D, DeclPtr); 101cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor EmitDeclDestroy(*this, D, DeclPtr); 102fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson return; 103fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson } 104045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson 10591a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 106045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson RValue RV = EmitReferenceBindingToExpr(Init, &D); 10791a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); 108fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson} 109eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 110efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 111efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 112efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant *DeclPtr) { 113efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Generate a global destructor entry if not using __cxa_atexit. 114efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (!CGM.getCodeGenOpts().CXAAtExit) { 115efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 116efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 117efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar } 118efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 119eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *Int8PtrTy = 120eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 121eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 122eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson std::vector<const llvm::Type *> Params; 123eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 124eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 125eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the destructor function type 126eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *DtorFnTy = 127eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); 128eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 129eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 130eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.clear(); 131eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(DtorFnTy); 132eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 133eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 134eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 135eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the __cxa_atexit function type 136eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 137eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::FunctionType *AtExitFnTy = 138eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 139eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 140eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 141eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__cxa_atexit"); 142eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 143eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, 144eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__dso_handle"); 145eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), 146eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), 147eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; 148eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args)); 149eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 150eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 1513030eb82593097502469a8b3fc26112c79c75605John McCallvoid CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, 1523030eb82593097502469a8b3fc26112c79c75605John McCall llvm::GlobalVariable *DeclPtr) { 1533030eb82593097502469a8b3fc26112c79c75605John McCall CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr); 1545cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall} 1555cd91b513455fd7753e8815b54f0a49bbca6602dJohn McCall 1569dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlssonstatic llvm::Function * 1579dc046e70d189457968e4c3b986da75b5d98ce8eAnders CarlssonCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 1589dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson const llvm::FunctionType *FTy, 1599dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::StringRef Name) { 1609dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 1619dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 1629dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson Name, &CGM.getModule()); 1639dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 16418af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson // Set the section if needed. 16518af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson if (const char *Section = 16618af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson CGM.getContext().Target.getStaticInitSectionSpecifier()) 16718af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson Fn->setSection(Section); 16818af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson 169044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall if (!CGM.getLangOptions().Exceptions) 170044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall Fn->setDoesNotThrow(); 171044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall 1729dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson return Fn; 1739dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson} 1749dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 175efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 1763030eb82593097502469a8b3fc26112c79c75605John McCallCodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 1773030eb82593097502469a8b3fc26112c79c75605John McCall llvm::GlobalVariable *Addr) { 1786c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman const llvm::FunctionType *FTy 1796c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 1806c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman false); 1816c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1826c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman // Create a variable initialization function. 1836c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman llvm::Function *Fn = 1849dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 1856c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1863030eb82593097502469a8b3fc26112c79c75605John McCall CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr); 1876c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1889f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (D->hasAttr<InitPriorityAttr>()) { 1899f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 190ec2830d930e306124c2ba6bf1060a3c71dced6eaChris Lattner OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 191e0b691a25f801d8be552c9387863637b9526e639Fariborz Jahanian PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 192bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(D); 193bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 194bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall else { 195bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall llvm::DenseMap<const Decl *, unsigned>::iterator I = 196bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.find(D); 197bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (I == DelayedCXXInitPosition.end()) { 198bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.push_back(Fn); 199bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } else { 200bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall assert(CXXGlobalInits[I->second] == 0); 201bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits[I->second] = Fn; 202bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(I); 203bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 2049f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2056c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman} 2066c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 207efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 208efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenModule::EmitCXXGlobalInitFunc() { 209bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 210bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.pop_back(); 211bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall 2129f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 213eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson return; 214eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 215eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::FunctionType *FTy 216eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 217eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson false); 218eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 219eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Create our global initialization function. 2209dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 2219dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 222efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2239f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (!PrioritizedCXXGlobalInits.empty()) { 224027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 225027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 226f489688114275c821b1e647e26f71eeb94d8ab24Fariborz Jahanian PrioritizedCXXGlobalInits.end()); 2279f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) { 2289f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; 2299f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.push_back(Fn); 2309f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 231bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); 2329f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2339f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &LocalCXXGlobalInits[0], 2349f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.size()); 2359f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2369f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian else 2379f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2389f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &CXXGlobalInits[0], 2399f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CXXGlobalInits.size()); 240efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalCtor(Fn); 241efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 242efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 243efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenModule::EmitCXXGlobalDtorFunc() { 244efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (CXXGlobalDtors.empty()) 245efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 246efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 247efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar const llvm::FunctionType *FTy 248efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 249efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar false); 250eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 251efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Create our global destructor function. 252efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Function *Fn = 2539dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 254efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 255efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 256efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalDtor(Fn); 257efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 258efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2593030eb82593097502469a8b3fc26112c79c75605John McCall/// Emit the code necessary to initialize the given global variable. 260efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 2613030eb82593097502469a8b3fc26112c79c75605John McCall const VarDecl *D, 2623030eb82593097502469a8b3fc26112c79c75605John McCall llvm::GlobalVariable *Addr) { 2636c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 2646c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman SourceLocation()); 2656c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2663030eb82593097502469a8b3fc26112c79c75605John McCall // Use guarded initialization if the global variable is weak due to 2673030eb82593097502469a8b3fc26112c79c75605John McCall // being a class template's static data member. 2683030eb82593097502469a8b3fc26112c79c75605John McCall if (Addr->hasWeakLinkage() && D->getInstantiatedFromStaticDataMember()) { 2693030eb82593097502469a8b3fc26112c79c75605John McCall EmitCXXGuardedInit(*D, Addr); 2703030eb82593097502469a8b3fc26112c79c75605John McCall } else { 2713030eb82593097502469a8b3fc26112c79c75605John McCall EmitCXXGlobalVarDeclInit(*D, Addr); 27292d835a86ac334768d0b75936201e4fea3941c1fFariborz Jahanian } 2736c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2746c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman FinishFunction(); 275efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 276eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 277efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 278efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant **Decls, 279efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar unsigned NumDecls) { 280efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 281efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar SourceLocation()); 282efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 283efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar for (unsigned i = 0; i != NumDecls; ++i) 284bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (Decls[i]) 285bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall Builder.CreateCall(Decls[i]); 286efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 287efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 288efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 289efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 290efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 291810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 292efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar &DtorsAndObjects) { 293efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 294efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar SourceLocation()); 295efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 296efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Emit the dtors, in reverse order from construction. 297c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 298810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 299c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner llvm::CallInst *CI = Builder.CreateCall(Callee, 300c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner DtorsAndObjects[e - i - 1].second); 301c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner // Make sure the call and the callee agree on calling convention. 302c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 303c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner CI->setCallingConv(F->getCallingConv()); 304c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner } 305efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 306efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 307eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 308eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 309772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 310772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// invoked, calls the default destructor on array elements in reverse order of 311772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// construction. 312772913659894551b02f342e3577e7219e4f9a701Anders Carlssonllvm::Function * 313772913659894551b02f342e3577e7219e4f9a701Anders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 314772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const ArrayType *Array, 315772913659894551b02f342e3577e7219e4f9a701Anders Carlsson llvm::Value *This) { 316772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FunctionArgList Args; 317772913659894551b02f342e3577e7219e4f9a701Anders Carlsson ImplicitParamDecl *Dst = 318772913659894551b02f342e3577e7219e4f9a701Anders Carlsson ImplicitParamDecl::Create(getContext(), 0, 319772913659894551b02f342e3577e7219e4f9a701Anders Carlsson SourceLocation(), 0, 320772913659894551b02f342e3577e7219e4f9a701Anders Carlsson getContext().getPointerType(getContext().VoidTy)); 321772913659894551b02f342e3577e7219e4f9a701Anders Carlsson Args.push_back(std::make_pair(Dst, Dst->getType())); 322772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 323772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const CGFunctionInfo &FI = 324772913659894551b02f342e3577e7219e4f9a701Anders Carlsson CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args, 325772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FunctionType::ExtInfo()); 326772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 3279dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 3289dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 329772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 330772913659894551b02f342e3577e7219e4f9a701Anders Carlsson StartFunction(GlobalDecl(), getContext().VoidTy, Fn, Args, SourceLocation()); 331772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 332772913659894551b02f342e3577e7219e4f9a701Anders Carlsson QualType BaseElementTy = getContext().getBaseElementType(Array); 333772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo(); 334772913659894551b02f342e3577e7219e4f9a701Anders Carlsson llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 335772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 336772913659894551b02f342e3577e7219e4f9a701Anders Carlsson EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 337772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 338772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FinishFunction(); 339772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 340772913659894551b02f342e3577e7219e4f9a701Anders Carlsson return Fn; 341772913659894551b02f342e3577e7219e4f9a701Anders Carlsson} 342