CGDeclCXX.cpp revision 91a16fa3265686b90054715eea504d9b4a13438b
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" 1506057cef0bcd7804e80f3ce2bbe352178396c715Chandler Carruth#include "clang/Frontend/CodeGenOptions.h" 1686a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor#include "llvm/Intrinsics.h" 1786a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor 185ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlssonusing namespace clang; 195ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlssonusing namespace CodeGen; 205ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 21fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlssonstatic void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, 22fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Constant *DeclPtr) { 23fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); 24fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson assert(!D.getType()->isReferenceType() && 25fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson "Should not call EmitDeclInit on a reference!"); 26fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 27fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson ASTContext &Context = CGF.getContext(); 28fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 295ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson const Expr *Init = D.getInit(); 305ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson QualType T = D.getType(); 31fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson bool isVolatile = Context.getCanonicalType(T).isVolatileQualified(); 325ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 3391a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = Context.getDeclAlign(&D).getQuantity(); 34fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!CGF.hasAggregateLLVMType(T)) { 35fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Value *V = CGF.EmitScalarExpr(Init); 3691a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, Alignment, T); 375ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } else if (T->isAnyComplexType()) { 38fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile); 395ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } else { 40fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson CGF.EmitAggExpr(Init, DeclPtr, isVolatile); 415ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } 425ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson} 435ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 44cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregorstatic void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 45cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor llvm::Constant *DeclPtr) { 46cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CodeGenModule &CGM = CGF.CGM; 47cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor ASTContext &Context = CGF.getContext(); 48cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 49cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor QualType T = D.getType(); 50cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 5185aca0f6a9da02bda705690fd56d0aa713604f08John McCall // Drill down past array types. 52cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const ConstantArrayType *Array = Context.getAsConstantArrayType(T); 53cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (Array) 54cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor T = Context.getBaseElementType(Array); 55cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 5685aca0f6a9da02bda705690fd56d0aa713604f08John McCall /// If that's not a record, we're done. 5785aca0f6a9da02bda705690fd56d0aa713604f08John McCall /// FIXME: __attribute__((cleanup)) ? 58cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const RecordType *RT = T->getAs<RecordType>(); 59cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (!RT) 60cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 61cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 62cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 63cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (RD->hasTrivialDestructor()) 64cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 65cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 661d110e05e0ff48c1c7a483d6b7fd094cdf28316aDouglas Gregor CXXDestructorDecl *Dtor = RD->getDestructor(); 67cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 68cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor llvm::Constant *DtorFn; 69cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (Array) { 70cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DtorFn = 7102e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, Array, 7202e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson DeclPtr); 73cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const llvm::Type *Int8PtrTy = 7402e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 75cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DeclPtr = llvm::Constant::getNullValue(Int8PtrTy); 76cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor } else 77cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete); 78cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 79cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr); 80cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor} 81cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 82fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlssonvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 83fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Constant *DeclPtr) { 84fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 85fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson const Expr *Init = D.getInit(); 86fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson QualType T = D.getType(); 87fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 88fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!T->isReferenceType()) { 89fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson EmitDeclInit(*this, D, DeclPtr); 90cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor EmitDeclDestroy(*this, D, DeclPtr); 91fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson return; 92fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson } 93045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson 9491a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 95045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson RValue RV = EmitReferenceBindingToExpr(Init, &D); 9691a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); 97fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson} 98eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 99efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 100efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 101efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant *DeclPtr) { 102efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Generate a global destructor entry if not using __cxa_atexit. 103efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (!CGM.getCodeGenOpts().CXAAtExit) { 104efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 105efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 106efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar } 107efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 108eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *Int8PtrTy = 109eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 110eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 111eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson std::vector<const llvm::Type *> Params; 112eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 113eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 114eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the destructor function type 115eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *DtorFnTy = 116eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); 117eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 118eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 119eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.clear(); 120eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(DtorFnTy); 121eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 122eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 123eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 124eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the __cxa_atexit function type 125eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 126eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::FunctionType *AtExitFnTy = 127eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 128eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 129eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 130eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__cxa_atexit"); 131eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 132eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, 133eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__dso_handle"); 134eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), 135eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), 136eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; 137eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args)); 138eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 139eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 1409dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlssonstatic llvm::Function * 1419dc046e70d189457968e4c3b986da75b5d98ce8eAnders CarlssonCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 1429dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson const llvm::FunctionType *FTy, 1439dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::StringRef Name) { 1449dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 1459dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 1469dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson Name, &CGM.getModule()); 1479dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 14818af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson // Set the section if needed. 14918af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson if (const char *Section = 15018af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson CGM.getContext().Target.getStaticInitSectionSpecifier()) 15118af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson Fn->setSection(Section); 15218af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson 153044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall if (!CGM.getLangOptions().Exceptions) 154044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall Fn->setDoesNotThrow(); 155044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall 1569dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson return Fn; 1579dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson} 1589dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 159efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 160efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) { 1616c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman const llvm::FunctionType *FTy 1626c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 1636c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman false); 1646c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1656c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman // Create a variable initialization function. 1666c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman llvm::Function *Fn = 1679dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 1686c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 169efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D); 1706c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1719f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (D->hasAttr<InitPriorityAttr>()) { 1729f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 173ec2830d930e306124c2ba6bf1060a3c71dced6eaChris Lattner OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 174e0b691a25f801d8be552c9387863637b9526e639Fariborz Jahanian PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 175bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(D); 176bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 177bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall else { 178bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall llvm::DenseMap<const Decl *, unsigned>::iterator I = 179bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.find(D); 180bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (I == DelayedCXXInitPosition.end()) { 181bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.push_back(Fn); 182bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } else { 183bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall assert(CXXGlobalInits[I->second] == 0); 184bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits[I->second] = Fn; 185bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(I); 186bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 1879f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 1886c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman} 1896c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 190efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 191efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenModule::EmitCXXGlobalInitFunc() { 192bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 193bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.pop_back(); 194bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall 1959f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 196eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson return; 197eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 198eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::FunctionType *FTy 199eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 200eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson false); 201eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 202eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Create our global initialization function. 2039dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 2049dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 205efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2069f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (!PrioritizedCXXGlobalInits.empty()) { 207027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 208027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 209f489688114275c821b1e647e26f71eeb94d8ab24Fariborz Jahanian PrioritizedCXXGlobalInits.end()); 2109f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) { 2119f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; 2129f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.push_back(Fn); 2139f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 214bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); 2159f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2169f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &LocalCXXGlobalInits[0], 2179f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.size()); 2189f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2199f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian else 2209f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2219f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &CXXGlobalInits[0], 2229f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CXXGlobalInits.size()); 223efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalCtor(Fn); 224efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 225efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 226efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenModule::EmitCXXGlobalDtorFunc() { 227efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (CXXGlobalDtors.empty()) 228efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 229efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 230efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar const llvm::FunctionType *FTy 231efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 232efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar false); 233eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 234efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Create our global destructor function. 235efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Function *Fn = 2369dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 237efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 238efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 239efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalDtor(Fn); 240efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 241efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 242efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 243efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar const VarDecl *D) { 2446c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 2456c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman SourceLocation()); 2466c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 247efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D); 248efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar EmitCXXGlobalVarDeclInit(*D, DeclPtr); 2496c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2506c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman FinishFunction(); 251efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 252eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 253efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 254efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant **Decls, 255efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar unsigned NumDecls) { 256efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 257efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar SourceLocation()); 258efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 259efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar for (unsigned i = 0; i != NumDecls; ++i) 260bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (Decls[i]) 261bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall Builder.CreateCall(Decls[i]); 262efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 263efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 264efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 265efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 266efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 267810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 268efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar &DtorsAndObjects) { 269efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 270efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar SourceLocation()); 271efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 272efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Emit the dtors, in reverse order from construction. 273c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 274810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 275c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner llvm::CallInst *CI = Builder.CreateCall(Callee, 276c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner DtorsAndObjects[e - i - 1].second); 277c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner // Make sure the call and the callee agree on calling convention. 278c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 279c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner CI->setCallingConv(F->getCallingConv()); 280c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner } 281efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 282efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 283eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 284eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 285a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlssonstatic llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) { 286a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // int __cxa_guard_acquire(__int64_t *guard_object); 287a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 288a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::Type *Int64PtrTy = 289a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 290a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 291a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson std::vector<const llvm::Type*> Args(1, Int64PtrTy); 292a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 293a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::FunctionType *FTy = 294a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy), 295a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Args, /*isVarArg=*/false); 296a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 297a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire"); 298a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson} 299a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 300a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlssonstatic llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) { 301a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // void __cxa_guard_release(__int64_t *guard_object); 302a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 303a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::Type *Int64PtrTy = 304a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 305a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 306a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson std::vector<const llvm::Type*> Args(1, Int64PtrTy); 307a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 308a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::FunctionType *FTy = 309a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 310a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Args, /*isVarArg=*/false); 311a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 312a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release"); 313a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson} 314a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 315a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlssonstatic llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) { 316a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // void __cxa_guard_abort(__int64_t *guard_object); 317a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 318a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::Type *Int64PtrTy = 319a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 320a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 321a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson std::vector<const llvm::Type*> Args(1, Int64PtrTy); 322a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 323a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::FunctionType *FTy = 324a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 325a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Args, /*isVarArg=*/false); 326a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 327a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort"); 328a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson} 329a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 330e540e637cbb9e3963c512b179779b8afcc190026John McCallnamespace { 3311f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallGuardAbort : EHScopeStack::Cleanup { 332e540e637cbb9e3963c512b179779b8afcc190026John McCall llvm::GlobalVariable *Guard; 333e540e637cbb9e3963c512b179779b8afcc190026John McCall CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {} 334e540e637cbb9e3963c512b179779b8afcc190026John McCall 335e540e637cbb9e3963c512b179779b8afcc190026John McCall void Emit(CodeGenFunction &CGF, bool IsForEH) { 336e540e637cbb9e3963c512b179779b8afcc190026John McCall // It shouldn't be possible for this to throw, but if it can, 337e540e637cbb9e3963c512b179779b8afcc190026John McCall // this should allow for the possibility of an invoke. 338e540e637cbb9e3963c512b179779b8afcc190026John McCall CGF.Builder.CreateCall(getGuardAbortFn(CGF), Guard) 339e540e637cbb9e3963c512b179779b8afcc190026John McCall ->setDoesNotThrow(); 340e540e637cbb9e3963c512b179779b8afcc190026John McCall } 341e540e637cbb9e3963c512b179779b8afcc190026John McCall }; 342e540e637cbb9e3963c512b179779b8afcc190026John McCall} 343e540e637cbb9e3963c512b179779b8afcc190026John McCall 344eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlssonvoid 345eb4072ed06c884f1053047ad88846cbffd5ac62eAnders CarlssonCodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, 346eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::GlobalVariable *GV) { 347fe67f3bfc09caa66ab1398c03418c35bea77caf4John McCall // Bail out early if this initializer isn't reachable. 348fe67f3bfc09caa66ab1398c03418c35bea77caf4John McCall if (!Builder.GetInsertBlock()) return; 349fe67f3bfc09caa66ab1398c03418c35bea77caf4John McCall 350a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics; 351a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 352eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::SmallString<256> GuardVName; 353eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson CGM.getMangleContext().mangleGuardVariable(&D, GuardVName); 354eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 355eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Create the guard variable. 356e540e637cbb9e3963c512b179779b8afcc190026John McCall llvm::GlobalVariable *GuardVariable = 357a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson new llvm::GlobalVariable(CGM.getModule(), Int64Ty, 358eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson false, GV->getLinkage(), 359a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Constant::getNullValue(Int64Ty), 360eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson GuardVName.str()); 361eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 362eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Load the first byte of the guard variable. 363eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *PtrTy 364eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 365a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Value *V = 366a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp"); 367eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 368a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check"); 369eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::BasicBlock *EndBlock = createBasicBlock("init.end"); 370eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 371a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // Check if the first byte of the guard variable is zero. 372a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"), 373a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson InitCheckBlock, EndBlock); 374eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 375a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson EmitBlock(InitCheckBlock); 376a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 37786a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor // Variables used when coping with thread-safe statics and exceptions. 37886a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor if (ThreadsafeStatics) { 379a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // Call __cxa_guard_acquire. 380a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable); 381a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 382a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::BasicBlock *InitBlock = createBasicBlock("init"); 383a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 384a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), 385a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson InitBlock, EndBlock); 386a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 387f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Call __cxa_guard_abort along the exceptional edge. 388e540e637cbb9e3963c512b179779b8afcc190026John McCall if (Exceptions) 3891f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable); 39086a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor 39186a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor EmitBlock(InitBlock); 392a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson } 393eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 394fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (D.getType()->isReferenceType()) { 39591a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 396864143fe14b8059eed1413d38854b689f7b21016Anders Carlsson QualType T = D.getType(); 397045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson RValue RV = EmitReferenceBindingToExpr(D.getInit(), &D); 39891a16fa3265686b90054715eea504d9b4a13438bDaniel Dunbar EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, Alignment, T); 399fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson } else 400fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson EmitDeclInit(*this, D, GV); 401eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 402a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson if (ThreadsafeStatics) { 403224124c7b85596157201a67a7ba12d2b0f5c153cJohn McCall // Pop the guard-abort cleanup if we pushed one. 404224124c7b85596157201a67a7ba12d2b0f5c153cJohn McCall if (Exceptions) 405224124c7b85596157201a67a7ba12d2b0f5c153cJohn McCall PopCleanupBlock(); 406224124c7b85596157201a67a7ba12d2b0f5c153cJohn McCall 407f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Call __cxa_guard_release. This cannot throw. 40886a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable); 409a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson } else { 410a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Value *One = 411a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1); 412a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy)); 413a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson } 414eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 415cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor // Register the call to the destructor. 416cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (!D.getType()->isReferenceType()) 417cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor EmitDeclDestroy(*this, D, GV); 418cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 419eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson EmitBlock(EndBlock); 420eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 421772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 422772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 423772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// invoked, calls the default destructor on array elements in reverse order of 424772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// construction. 425772913659894551b02f342e3577e7219e4f9a701Anders Carlssonllvm::Function * 426772913659894551b02f342e3577e7219e4f9a701Anders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 427772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const ArrayType *Array, 428772913659894551b02f342e3577e7219e4f9a701Anders Carlsson llvm::Value *This) { 429772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FunctionArgList Args; 430772913659894551b02f342e3577e7219e4f9a701Anders Carlsson ImplicitParamDecl *Dst = 431772913659894551b02f342e3577e7219e4f9a701Anders Carlsson ImplicitParamDecl::Create(getContext(), 0, 432772913659894551b02f342e3577e7219e4f9a701Anders Carlsson SourceLocation(), 0, 433772913659894551b02f342e3577e7219e4f9a701Anders Carlsson getContext().getPointerType(getContext().VoidTy)); 434772913659894551b02f342e3577e7219e4f9a701Anders Carlsson Args.push_back(std::make_pair(Dst, Dst->getType())); 435772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 436772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const CGFunctionInfo &FI = 437772913659894551b02f342e3577e7219e4f9a701Anders Carlsson CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args, 438772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FunctionType::ExtInfo()); 439772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 4409dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 4419dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 442772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 443772913659894551b02f342e3577e7219e4f9a701Anders Carlsson StartFunction(GlobalDecl(), getContext().VoidTy, Fn, Args, SourceLocation()); 444772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 445772913659894551b02f342e3577e7219e4f9a701Anders Carlsson QualType BaseElementTy = getContext().getBaseElementType(Array); 446772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo(); 447772913659894551b02f342e3577e7219e4f9a701Anders Carlsson llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 448772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 449772913659894551b02f342e3577e7219e4f9a701Anders Carlsson EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 450772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 451772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FinishFunction(); 452772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 453772913659894551b02f342e3577e7219e4f9a701Anders Carlsson return Fn; 454772913659894551b02f342e3577e7219e4f9a701Anders Carlsson} 455