CGDeclCXX.cpp revision 85aca0f6a9da02bda705690fd56d0aa713604f08
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 33fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!CGF.hasAggregateLLVMType(T)) { 34fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Value *V = CGF.EmitScalarExpr(Init); 35fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T); 365ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } else if (T->isAnyComplexType()) { 37fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile); 385ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } else { 39fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson CGF.EmitAggExpr(Init, DeclPtr, isVolatile); 405ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson } 415ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson} 425ec2e7ccb08b2a1598f12b2c6f59c6f31d035b5bAnders Carlsson 43cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregorstatic void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 44cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor llvm::Constant *DeclPtr) { 45cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CodeGenModule &CGM = CGF.CGM; 46cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor ASTContext &Context = CGF.getContext(); 47cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 48cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor QualType T = D.getType(); 49cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 5085aca0f6a9da02bda705690fd56d0aa713604f08John McCall // Drill down past array types. 51cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const ConstantArrayType *Array = Context.getAsConstantArrayType(T); 52cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (Array) 53cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor T = Context.getBaseElementType(Array); 54cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 5585aca0f6a9da02bda705690fd56d0aa713604f08John McCall /// If that's not a record, we're done. 5685aca0f6a9da02bda705690fd56d0aa713604f08John McCall /// FIXME: __attribute__((cleanup)) ? 57cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const RecordType *RT = T->getAs<RecordType>(); 58cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (!RT) 59cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 60cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 61cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 62cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (RD->hasTrivialDestructor()) 63cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor return; 64cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 651d110e05e0ff48c1c7a483d6b7fd094cdf28316aDouglas Gregor CXXDestructorDecl *Dtor = RD->getDestructor(); 66cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 67cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor llvm::Constant *DtorFn; 68cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (Array) { 69cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DtorFn = 7002e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, Array, 7102e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson DeclPtr); 72cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor const llvm::Type *Int8PtrTy = 7302e370a02f05b4a734fe5e8c88efc4ed9dac60faAnders Carlsson llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 74cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DeclPtr = llvm::Constant::getNullValue(Int8PtrTy); 75cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor } else 76cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete); 77cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 78cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr); 79cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor} 80cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 81fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlssonvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 82fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson llvm::Constant *DeclPtr) { 83fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 84fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson const Expr *Init = D.getInit(); 85fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson QualType T = D.getType(); 86fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson 87fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (!T->isReferenceType()) { 88fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson EmitDeclInit(*this, D, DeclPtr); 89cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor EmitDeclDestroy(*this, D, DeclPtr); 90fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson return; 91fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson } 92045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson 93045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson RValue RV = EmitReferenceBindingToExpr(Init, &D); 94045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T); 95fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson} 96eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 97efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 98efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 99efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant *DeclPtr) { 100efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Generate a global destructor entry if not using __cxa_atexit. 101efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (!CGM.getCodeGenOpts().CXAAtExit) { 102efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 103efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 104efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar } 105efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 106eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *Int8PtrTy = 107eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 108eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 109eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson std::vector<const llvm::Type *> Params; 110eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 111eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 112eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the destructor function type 113eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *DtorFnTy = 114eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); 115eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 116eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 117eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.clear(); 118eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(DtorFnTy); 119eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 120eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Params.push_back(Int8PtrTy); 121eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 122eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Get the __cxa_atexit function type 123eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 124eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::FunctionType *AtExitFnTy = 125eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 126eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 127eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 128eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__cxa_atexit"); 129eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 130eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, 131eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson "__dso_handle"); 132eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), 133eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), 134eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; 135eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args)); 136eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 137eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 1389dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlssonstatic llvm::Function * 1399dc046e70d189457968e4c3b986da75b5d98ce8eAnders CarlssonCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 1409dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson const llvm::FunctionType *FTy, 1419dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::StringRef Name) { 1429dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 1439dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 1449dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson Name, &CGM.getModule()); 1459dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 14618af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson // Set the section if needed. 14718af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson if (const char *Section = 14818af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson CGM.getContext().Target.getStaticInitSectionSpecifier()) 14918af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson Fn->setSection(Section); 15018af368c080b9d60e34e670cd01f7d2d3ad2ba48Anders Carlsson 151044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall if (!CGM.getLangOptions().Exceptions) 152044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall Fn->setDoesNotThrow(); 153044cc54a7d83c90857187c4cd4a0fd33664a7f7fJohn McCall 1549dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson return Fn; 1559dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson} 1569dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson 157efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 158efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) { 1596c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman const llvm::FunctionType *FTy 1606c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 1616c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman false); 1626c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1636c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman // Create a variable initialization function. 1646c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman llvm::Function *Fn = 1659dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 1666c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 167efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D); 1686c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 1699f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (D->hasAttr<InitPriorityAttr>()) { 1709f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 171ec2830d930e306124c2ba6bf1060a3c71dced6eaChris Lattner OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 172e0b691a25f801d8be552c9387863637b9526e639Fariborz Jahanian PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 173bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(D); 174bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 175bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall else { 176bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall llvm::DenseMap<const Decl *, unsigned>::iterator I = 177bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.find(D); 178bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (I == DelayedCXXInitPosition.end()) { 179bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.push_back(Fn); 180bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } else { 181bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall assert(CXXGlobalInits[I->second] == 0); 182bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits[I->second] = Fn; 183bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall DelayedCXXInitPosition.erase(I); 184bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall } 1859f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 1866c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman} 1876c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 188efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid 189efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel DunbarCodeGenModule::EmitCXXGlobalInitFunc() { 190bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 191bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall CXXGlobalInits.pop_back(); 192bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall 1939f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 194eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson return; 195eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 196eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::FunctionType *FTy 197eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 198eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson false); 199eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 200eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Create our global initialization function. 2019dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 2029dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 203efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 2049f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian if (!PrioritizedCXXGlobalInits.empty()) { 205027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 206027d7ed9d616d93ae7f02de79d17863725b14866Fariborz Jahanian llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 207f489688114275c821b1e647e26f71eeb94d8ab24Fariborz Jahanian PrioritizedCXXGlobalInits.end()); 2089f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) { 2099f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; 2109f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.push_back(Fn); 2119f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 212bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); 2139f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2149f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &LocalCXXGlobalInits[0], 2159f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian LocalCXXGlobalInits.size()); 2169f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian } 2179f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian else 2189f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 2199f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian &CXXGlobalInits[0], 2209f967c5e4bbeb48caf6d0e62056b3d3fee20bf7cFariborz Jahanian CXXGlobalInits.size()); 221efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalCtor(Fn); 222efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 223efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 224efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenModule::EmitCXXGlobalDtorFunc() { 225efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar if (CXXGlobalDtors.empty()) 226efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar return; 227efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 228efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar const llvm::FunctionType *FTy 229efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 230efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar false); 231eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 232efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Create our global destructor function. 233efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Function *Fn = 2349dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 235efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 236efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 237efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar AddGlobalDtor(Fn); 238efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 239efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 240efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 241efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar const VarDecl *D) { 2426c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 2436c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman SourceLocation()); 2446c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 245efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D); 246efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar EmitCXXGlobalVarDeclInit(*D, DeclPtr); 2476c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman 2486c6bda3b0b1d8adaac2ba3f4da7056e9f1eef52eEli Friedman FinishFunction(); 249efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 250eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 251efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 252efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar llvm::Constant **Decls, 253efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar unsigned NumDecls) { 254efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 255efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar SourceLocation()); 256efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 257efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar for (unsigned i = 0; i != NumDecls; ++i) 258bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall if (Decls[i]) 259bf40cb518312dde1c07e44fcae59bc4eec65589cJohn McCall Builder.CreateCall(Decls[i]); 260efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 261efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 262efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar} 263efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 264efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbarvoid CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 265810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 266efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar &DtorsAndObjects) { 267efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 268efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar SourceLocation()); 269efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 270efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar // Emit the dtors, in reverse order from construction. 271c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 272810112e28dc839715d17b0a786f23aaa19600ac0Chris Lattner llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 273c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner llvm::CallInst *CI = Builder.CreateCall(Callee, 274c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner DtorsAndObjects[e - i - 1].second); 275c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner // Make sure the call and the callee agree on calling convention. 276c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 277c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner CI->setCallingConv(F->getCallingConv()); 278c9a85f9b4cc8ed95ed7feeff554a74bf52bdc1f7Chris Lattner } 279efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar 280efb0fa9e11f75af51744a6159530ef7cc8efa24aDaniel Dunbar FinishFunction(); 281eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 282eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 283a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlssonstatic llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) { 284a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // int __cxa_guard_acquire(__int64_t *guard_object); 285a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 286a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::Type *Int64PtrTy = 287a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 288a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 289a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson std::vector<const llvm::Type*> Args(1, Int64PtrTy); 290a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 291a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::FunctionType *FTy = 292a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy), 293a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Args, /*isVarArg=*/false); 294a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 295a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire"); 296a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson} 297a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 298a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlssonstatic llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) { 299a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // void __cxa_guard_release(__int64_t *guard_object); 300a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 301a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::Type *Int64PtrTy = 302a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 303a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 304a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson std::vector<const llvm::Type*> Args(1, Int64PtrTy); 305a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 306a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::FunctionType *FTy = 307a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 308a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Args, /*isVarArg=*/false); 309a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 310a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release"); 311a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson} 312a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 313a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlssonstatic llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) { 314a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // void __cxa_guard_abort(__int64_t *guard_object); 315a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 316a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::Type *Int64PtrTy = 317a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 318a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 319a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson std::vector<const llvm::Type*> Args(1, Int64PtrTy); 320a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 321a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson const llvm::FunctionType *FTy = 322a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 323a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Args, /*isVarArg=*/false); 324a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 325a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort"); 326a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson} 327a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 328e540e637cbb9e3963c512b179779b8afcc190026John McCallnamespace { 3291f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall struct CallGuardAbort : EHScopeStack::Cleanup { 330e540e637cbb9e3963c512b179779b8afcc190026John McCall llvm::GlobalVariable *Guard; 331e540e637cbb9e3963c512b179779b8afcc190026John McCall CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {} 332e540e637cbb9e3963c512b179779b8afcc190026John McCall 333e540e637cbb9e3963c512b179779b8afcc190026John McCall void Emit(CodeGenFunction &CGF, bool IsForEH) { 334e540e637cbb9e3963c512b179779b8afcc190026John McCall // It shouldn't be possible for this to throw, but if it can, 335e540e637cbb9e3963c512b179779b8afcc190026John McCall // this should allow for the possibility of an invoke. 336e540e637cbb9e3963c512b179779b8afcc190026John McCall CGF.Builder.CreateCall(getGuardAbortFn(CGF), Guard) 337e540e637cbb9e3963c512b179779b8afcc190026John McCall ->setDoesNotThrow(); 338e540e637cbb9e3963c512b179779b8afcc190026John McCall } 339e540e637cbb9e3963c512b179779b8afcc190026John McCall }; 340e540e637cbb9e3963c512b179779b8afcc190026John McCall} 341e540e637cbb9e3963c512b179779b8afcc190026John McCall 342eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlssonvoid 343eb4072ed06c884f1053047ad88846cbffd5ac62eAnders CarlssonCodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, 344eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::GlobalVariable *GV) { 345fe67f3bfc09caa66ab1398c03418c35bea77caf4John McCall // Bail out early if this initializer isn't reachable. 346fe67f3bfc09caa66ab1398c03418c35bea77caf4John McCall if (!Builder.GetInsertBlock()) return; 347fe67f3bfc09caa66ab1398c03418c35bea77caf4John McCall 348a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics; 349a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 350eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::SmallString<256> GuardVName; 351eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson CGM.getMangleContext().mangleGuardVariable(&D, GuardVName); 352eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 353eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Create the guard variable. 354e540e637cbb9e3963c512b179779b8afcc190026John McCall llvm::GlobalVariable *GuardVariable = 355a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson new llvm::GlobalVariable(CGM.getModule(), Int64Ty, 356eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson false, GV->getLinkage(), 357a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Constant::getNullValue(Int64Ty), 358eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson GuardVName.str()); 359eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 360eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson // Load the first byte of the guard variable. 361eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson const llvm::Type *PtrTy 362eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 363a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Value *V = 364a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp"); 365eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 366a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check"); 367eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson llvm::BasicBlock *EndBlock = createBasicBlock("init.end"); 368eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 369a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // Check if the first byte of the guard variable is zero. 370a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"), 371a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson InitCheckBlock, EndBlock); 372eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 373a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson EmitBlock(InitCheckBlock); 374a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 37586a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor // Variables used when coping with thread-safe statics and exceptions. 37686a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor if (ThreadsafeStatics) { 377a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson // Call __cxa_guard_acquire. 378a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable); 379a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 380a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::BasicBlock *InitBlock = createBasicBlock("init"); 381a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 382a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), 383a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson InitBlock, EndBlock); 384a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson 385f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Call __cxa_guard_abort along the exceptional edge. 386e540e637cbb9e3963c512b179779b8afcc190026John McCall if (Exceptions) 3871f0fca54676cfa8616e7f3cd7a26788ab937e3cdJohn McCall EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable); 38886a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor 38986a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor EmitBlock(InitBlock); 390a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson } 391eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 392fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson if (D.getType()->isReferenceType()) { 393864143fe14b8059eed1413d38854b689f7b21016Anders Carlsson QualType T = D.getType(); 394045a6d84a0fa672eb5d914be1bb8f3baa226beb3Anders Carlsson RValue RV = EmitReferenceBindingToExpr(D.getInit(), &D); 395864143fe14b8059eed1413d38854b689f7b21016Anders Carlsson EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T); 396864143fe14b8059eed1413d38854b689f7b21016Anders Carlsson 397fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson } else 398fcbfdc1a93325471a262f0d94461273ae67ad3b6Anders Carlsson EmitDeclInit(*this, D, GV); 399eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 400a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson if (ThreadsafeStatics) { 401f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall // Call __cxa_guard_release. This cannot throw. 40286a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable); 403a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson } else { 404a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::Value *One = 405a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1); 406a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy)); 407a508b7de6c5246ab04ed69d0ab4e9977ec1fb4d4Anders Carlsson } 408eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson 409cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor // Register the call to the destructor. 410cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor if (!D.getType()->isReferenceType()) 411cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor EmitDeclDestroy(*this, D, GV); 412cc6a44b8bdecd9fc70211146e8ba3853b1fac784Douglas Gregor 413eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson EmitBlock(EndBlock); 414eb4072ed06c884f1053047ad88846cbffd5ac62eAnders Carlsson} 415772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 416772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 417772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// invoked, calls the default destructor on array elements in reverse order of 418772913659894551b02f342e3577e7219e4f9a701Anders Carlsson/// construction. 419772913659894551b02f342e3577e7219e4f9a701Anders Carlssonllvm::Function * 420772913659894551b02f342e3577e7219e4f9a701Anders CarlssonCodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 421772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const ArrayType *Array, 422772913659894551b02f342e3577e7219e4f9a701Anders Carlsson llvm::Value *This) { 423772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FunctionArgList Args; 424772913659894551b02f342e3577e7219e4f9a701Anders Carlsson ImplicitParamDecl *Dst = 425772913659894551b02f342e3577e7219e4f9a701Anders Carlsson ImplicitParamDecl::Create(getContext(), 0, 426772913659894551b02f342e3577e7219e4f9a701Anders Carlsson SourceLocation(), 0, 427772913659894551b02f342e3577e7219e4f9a701Anders Carlsson getContext().getPointerType(getContext().VoidTy)); 428772913659894551b02f342e3577e7219e4f9a701Anders Carlsson Args.push_back(std::make_pair(Dst, Dst->getType())); 429772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 430772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const CGFunctionInfo &FI = 431772913659894551b02f342e3577e7219e4f9a701Anders Carlsson CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args, 432772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FunctionType::ExtInfo()); 433772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 4349dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson llvm::Function *Fn = 4359dc046e70d189457968e4c3b986da75b5d98ce8eAnders Carlsson CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 436772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 437772913659894551b02f342e3577e7219e4f9a701Anders Carlsson StartFunction(GlobalDecl(), getContext().VoidTy, Fn, Args, SourceLocation()); 438772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 439772913659894551b02f342e3577e7219e4f9a701Anders Carlsson QualType BaseElementTy = getContext().getBaseElementType(Array); 440772913659894551b02f342e3577e7219e4f9a701Anders Carlsson const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo(); 441772913659894551b02f342e3577e7219e4f9a701Anders Carlsson llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 442772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 443772913659894551b02f342e3577e7219e4f9a701Anders Carlsson EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 444772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 445772913659894551b02f342e3577e7219e4f9a701Anders Carlsson FinishFunction(); 446772913659894551b02f342e3577e7219e4f9a701Anders Carlsson 447772913659894551b02f342e3577e7219e4f9a701Anders Carlsson return Fn; 448772913659894551b02f342e3577e7219e4f9a701Anders Carlsson} 449