1200583Srdivacky//===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===// 2200583Srdivacky// 3200583Srdivacky// The LLVM Compiler Infrastructure 4200583Srdivacky// 5200583Srdivacky// This file is distributed under the University of Illinois Open Source 6200583Srdivacky// License. See LICENSE.TXT for details. 7200583Srdivacky// 8200583Srdivacky//===----------------------------------------------------------------------===// 9200583Srdivacky// 10200583Srdivacky// This contains code dealing with code generation of C++ declarations 11200583Srdivacky// 12200583Srdivacky//===----------------------------------------------------------------------===// 13200583Srdivacky 14200583Srdivacky#include "CodeGenFunction.h" 15249423Sdim#include "CGCXXABI.h" 16218893Sdim#include "CGObjCRuntime.h" 17210299Sed#include "clang/Frontend/CodeGenOptions.h" 18243830Sdim#include "llvm/ADT/StringExtras.h" 19249423Sdim#include "llvm/IR/Intrinsics.h" 20208600Srdivacky 21200583Srdivackyusing namespace clang; 22200583Srdivackyusing namespace CodeGen; 23200583Srdivacky 24200583Srdivackystatic void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, 25200583Srdivacky llvm::Constant *DeclPtr) { 26200583Srdivacky assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); 27200583Srdivacky assert(!D.getType()->isReferenceType() && 28200583Srdivacky "Should not call EmitDeclInit on a reference!"); 29200583Srdivacky 30200583Srdivacky ASTContext &Context = CGF.getContext(); 31224145Sdim 32234353Sdim CharUnits alignment = Context.getDeclAlign(&D); 33224145Sdim QualType type = D.getType(); 34224145Sdim LValue lv = CGF.MakeAddrLValue(DeclPtr, type, alignment); 35224145Sdim 36200583Srdivacky const Expr *Init = D.getInit(); 37249423Sdim switch (CGF.getEvaluationKind(type)) { 38249423Sdim case TEK_Scalar: { 39218893Sdim CodeGenModule &CGM = CGF.CGM; 40224145Sdim if (lv.isObjCStrong()) 41224145Sdim CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init), 42251662Sdim DeclPtr, D.getTLSKind()); 43224145Sdim else if (lv.isObjCWeak()) 44224145Sdim CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init), 45224145Sdim DeclPtr); 46218893Sdim else 47224145Sdim CGF.EmitScalarInit(Init, &D, lv, false); 48249423Sdim return; 49249423Sdim } 50249423Sdim case TEK_Complex: 51249423Sdim CGF.EmitComplexExprIntoLValue(Init, lv, /*isInit*/ true); 52249423Sdim return; 53249423Sdim case TEK_Aggregate: 54226633Sdim CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, 55226633Sdim AggValueSlot::DoesNotNeedGCBarriers, 56226633Sdim AggValueSlot::IsNotAliased)); 57249423Sdim return; 58200583Srdivacky } 59249423Sdim llvm_unreachable("bad evaluation kind"); 60200583Srdivacky} 61200583Srdivacky 62218893Sdim/// Emit code to cause the destruction of the given variable with 63218893Sdim/// static storage duration. 64208600Srdivackystatic void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 65224145Sdim llvm::Constant *addr) { 66208600Srdivacky CodeGenModule &CGM = CGF.CGM; 67224145Sdim 68224145Sdim // FIXME: __attribute__((cleanup)) ? 69208600Srdivacky 70224145Sdim QualType type = D.getType(); 71224145Sdim QualType::DestructionKind dtorKind = type.isDestructedType(); 72224145Sdim 73224145Sdim switch (dtorKind) { 74224145Sdim case QualType::DK_none: 75208600Srdivacky return; 76224145Sdim 77224145Sdim case QualType::DK_cxx_destructor: 78224145Sdim break; 79224145Sdim 80224145Sdim case QualType::DK_objc_strong_lifetime: 81224145Sdim case QualType::DK_objc_weak_lifetime: 82224145Sdim // We don't care about releasing objects during process teardown. 83251662Sdim assert(!D.getTLSKind() && "should have rejected this"); 84208600Srdivacky return; 85224145Sdim } 86224145Sdim 87224145Sdim llvm::Constant *function; 88224145Sdim llvm::Constant *argument; 89224145Sdim 90224145Sdim // Special-case non-array C++ destructors, where there's a function 91224145Sdim // with the right signature that we can just call. 92224145Sdim const CXXRecordDecl *record = 0; 93224145Sdim if (dtorKind == QualType::DK_cxx_destructor && 94224145Sdim (record = type->getAsCXXRecordDecl())) { 95224145Sdim assert(!record->hasTrivialDestructor()); 96224145Sdim CXXDestructorDecl *dtor = record->getDestructor(); 97224145Sdim 98224145Sdim function = CGM.GetAddrOfCXXDestructor(dtor, Dtor_Complete); 99263508Sdim argument = llvm::ConstantExpr::getBitCast( 100263508Sdim addr, CGF.getTypes().ConvertType(type)->getPointerTo()); 101224145Sdim 102224145Sdim // Otherwise, the standard logic requires a helper function. 103224145Sdim } else { 104263508Sdim function = CodeGenFunction(CGM) 105263508Sdim .generateDestroyHelper(addr, type, CGF.getDestroyer(dtorKind), 106263508Sdim CGF.needsEHCleanup(dtorKind), &D); 107224145Sdim argument = llvm::Constant::getNullValue(CGF.Int8PtrTy); 108224145Sdim } 109224145Sdim 110251662Sdim CGM.getCXXABI().registerGlobalDtor(CGF, D, function, argument); 111208600Srdivacky} 112208600Srdivacky 113234353Sdim/// Emit code to cause the variable at the given address to be considered as 114234353Sdim/// constant from this point onwards. 115234353Sdimstatic void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D, 116234353Sdim llvm::Constant *Addr) { 117234353Sdim // Don't emit the intrinsic if we're not optimizing. 118234353Sdim if (!CGF.CGM.getCodeGenOpts().OptimizationLevel) 119234353Sdim return; 120234353Sdim 121234353Sdim // Grab the llvm.invariant.start intrinsic. 122234353Sdim llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start; 123234353Sdim llvm::Constant *InvariantStart = CGF.CGM.getIntrinsic(InvStartID); 124234353Sdim 125234353Sdim // Emit a call with the size in bytes of the object. 126234353Sdim CharUnits WidthChars = CGF.getContext().getTypeSizeInChars(D.getType()); 127234353Sdim uint64_t Width = WidthChars.getQuantity(); 128234353Sdim llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(CGF.Int64Ty, Width), 129234353Sdim llvm::ConstantExpr::getBitCast(Addr, CGF.Int8PtrTy)}; 130234353Sdim CGF.Builder.CreateCall(InvariantStart, Args); 131234353Sdim} 132234353Sdim 133200583Srdivackyvoid CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 134234353Sdim llvm::Constant *DeclPtr, 135234353Sdim bool PerformInit) { 136200583Srdivacky 137200583Srdivacky const Expr *Init = D.getInit(); 138200583Srdivacky QualType T = D.getType(); 139200583Srdivacky 140200583Srdivacky if (!T->isReferenceType()) { 141234353Sdim if (PerformInit) 142234353Sdim EmitDeclInit(*this, D, DeclPtr); 143234353Sdim if (CGM.isTypeConstant(D.getType(), true)) 144234353Sdim EmitDeclInvariant(*this, D, DeclPtr); 145234353Sdim else 146234353Sdim EmitDeclDestroy(*this, D, DeclPtr); 147200583Srdivacky return; 148200583Srdivacky } 149210299Sed 150234353Sdim assert(PerformInit && "cannot have constant initializer which needs " 151234353Sdim "destruction for reference"); 152212904Sdim unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 153263508Sdim RValue RV = EmitReferenceBindingToExpr(Init); 154212904Sdim EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); 155200583Srdivacky} 156200583Srdivacky 157234353Sdimstatic llvm::Function * 158234353SdimCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 159234353Sdim llvm::FunctionType *ty, 160251662Sdim const Twine &name, 161251662Sdim bool TLS = false); 162234353Sdim 163234353Sdim/// Create a stub function, suitable for being passed to atexit, 164234353Sdim/// which passes the given address to the given destructor function. 165263508Sdimstatic llvm::Constant *createAtExitStub(CodeGenModule &CGM, const VarDecl &VD, 166234353Sdim llvm::Constant *dtor, 167234353Sdim llvm::Constant *addr) { 168234353Sdim // Get the destructor function type, void(*)(void). 169234353Sdim llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false); 170263508Sdim SmallString<256> FnName; 171263508Sdim { 172263508Sdim llvm::raw_svector_ostream Out(FnName); 173263508Sdim CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out); 174263508Sdim } 175234353Sdim llvm::Function *fn = 176263508Sdim CreateGlobalInitOrDestructFunction(CGM, ty, FnName.str()); 177234353Sdim 178234353Sdim CodeGenFunction CGF(CGM); 179234353Sdim 180263508Sdim CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn, 181263508Sdim CGM.getTypes().arrangeNullaryFunction(), FunctionArgList(), 182263508Sdim SourceLocation()); 183243830Sdim 184234353Sdim llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); 185234353Sdim 186234353Sdim // Make sure the call and the callee agree on calling convention. 187234353Sdim if (llvm::Function *dtorFn = 188234353Sdim dyn_cast<llvm::Function>(dtor->stripPointerCasts())) 189234353Sdim call->setCallingConv(dtorFn->getCallingConv()); 190234353Sdim 191234353Sdim CGF.FinishFunction(); 192234353Sdim 193234353Sdim return fn; 194200583Srdivacky} 195200583Srdivacky 196239462Sdim/// Register a global destructor using the C atexit runtime function. 197263508Sdimvoid CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD, 198263508Sdim llvm::Constant *dtor, 199239462Sdim llvm::Constant *addr) { 200234353Sdim // Create a function which calls the destructor. 201263508Sdim llvm::Constant *dtorStub = createAtExitStub(CGM, VD, dtor, addr); 202234353Sdim 203234353Sdim // extern "C" int atexit(void (*f)(void)); 204234353Sdim llvm::FunctionType *atexitTy = 205239462Sdim llvm::FunctionType::get(IntTy, dtorStub->getType(), false); 206234353Sdim 207234353Sdim llvm::Constant *atexit = 208239462Sdim CGM.CreateRuntimeFunction(atexitTy, "atexit"); 209234353Sdim if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit)) 210234353Sdim atexitFn->setDoesNotThrow(); 211234353Sdim 212249423Sdim EmitNounwindRuntimeCall(atexit, dtorStub); 213234353Sdim} 214234353Sdim 215218893Sdimvoid CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, 216234353Sdim llvm::GlobalVariable *DeclPtr, 217234353Sdim bool PerformInit) { 218221345Sdim // If we've been asked to forbid guard variables, emit an error now. 219221345Sdim // This diagnostic is hard-coded for Darwin's use case; we can find 220221345Sdim // better phrasing if someone else needs it. 221221345Sdim if (CGM.getCodeGenOpts().ForbidGuardVariables) 222221345Sdim CGM.Error(D.getLocation(), 223221345Sdim "this initialization requires a guard variable, which " 224221345Sdim "the kernel does not support"); 225221345Sdim 226234353Sdim CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit); 227218893Sdim} 228218893Sdim 229210299Sedstatic llvm::Function * 230210299SedCreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 231226633Sdim llvm::FunctionType *FTy, 232251662Sdim const Twine &Name, bool TLS) { 233210299Sed llvm::Function *Fn = 234210299Sed llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 235210299Sed Name, &CGM.getModule()); 236251662Sdim if (!CGM.getLangOpts().AppleKext && !TLS) { 237218893Sdim // Set the section if needed. 238218893Sdim if (const char *Section = 239251662Sdim CGM.getTarget().getStaticInitSectionSpecifier()) 240218893Sdim Fn->setSection(Section); 241218893Sdim } 242210299Sed 243249423Sdim Fn->setCallingConv(CGM.getRuntimeCC()); 244249423Sdim 245234353Sdim if (!CGM.getLangOpts().Exceptions) 246210299Sed Fn->setDoesNotThrow(); 247210299Sed 248249423Sdim if (CGM.getSanOpts().Address) 249249423Sdim Fn->addFnAttr(llvm::Attribute::SanitizeAddress); 250249423Sdim if (CGM.getSanOpts().Thread) 251249423Sdim Fn->addFnAttr(llvm::Attribute::SanitizeThread); 252249423Sdim if (CGM.getSanOpts().Memory) 253249423Sdim Fn->addFnAttr(llvm::Attribute::SanitizeMemory); 254239462Sdim 255210299Sed return Fn; 256210299Sed} 257210299Sed 258200583Srdivackyvoid 259218893SdimCodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 260234353Sdim llvm::GlobalVariable *Addr, 261234353Sdim bool PerformInit) { 262234353Sdim llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 263263508Sdim SmallString<256> FnName; 264263508Sdim { 265263508Sdim llvm::raw_svector_ostream Out(FnName); 266263508Sdim getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out); 267263508Sdim } 268202379Srdivacky 269202379Srdivacky // Create a variable initialization function. 270202379Srdivacky llvm::Function *Fn = 271263508Sdim CreateGlobalInitOrDestructFunction(*this, FTy, FnName.str()); 272202379Srdivacky 273234353Sdim CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr, 274234353Sdim PerformInit); 275202379Srdivacky 276251662Sdim if (D->getTLSKind()) { 277251662Sdim // FIXME: Should we support init_priority for thread_local? 278251662Sdim // FIXME: Ideally, initialization of instantiated thread_local static data 279251662Sdim // members of class templates should not trigger initialization of other 280251662Sdim // entities in the TU. 281251662Sdim // FIXME: We only need to register one __cxa_thread_atexit function for the 282251662Sdim // entire TU. 283251662Sdim CXXThreadLocalInits.push_back(Fn); 284251662Sdim } else if (D->hasAttr<InitPriorityAttr>()) { 285210299Sed unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 286210299Sed OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 287210299Sed PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 288212904Sdim DelayedCXXInitPosition.erase(D); 289263508Sdim } else if (D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization && 290263508Sdim D->getTemplateSpecializationKind() != TSK_Undeclared) { 291263508Sdim // C++ [basic.start.init]p2: 292263508Sdim // Definitions of explicitly specialized class template static data 293263508Sdim // members have ordered initialization. Other class template static data 294263508Sdim // members (i.e., implicitly or explicitly instantiated specializations) 295263508Sdim // have unordered initialization. 296263508Sdim // 297263508Sdim // As a consequence, we can put them into their own llvm.global_ctors entry. 298263508Sdim // This should allow GlobalOpt to fire more often, and allow us to implement 299263508Sdim // the Microsoft C++ ABI, which uses COMDAT elimination to avoid double 300263508Sdim // initializaiton. 301263508Sdim AddGlobalCtor(Fn); 302263508Sdim DelayedCXXInitPosition.erase(D); 303251662Sdim } else { 304212904Sdim llvm::DenseMap<const Decl *, unsigned>::iterator I = 305212904Sdim DelayedCXXInitPosition.find(D); 306212904Sdim if (I == DelayedCXXInitPosition.end()) { 307212904Sdim CXXGlobalInits.push_back(Fn); 308212904Sdim } else { 309212904Sdim assert(CXXGlobalInits[I->second] == 0); 310212904Sdim CXXGlobalInits[I->second] = Fn; 311212904Sdim DelayedCXXInitPosition.erase(I); 312212904Sdim } 313212904Sdim } 314202379Srdivacky} 315202379Srdivacky 316251662Sdimvoid CodeGenModule::EmitCXXThreadLocalInitFunc() { 317251662Sdim llvm::Function *InitFn = 0; 318251662Sdim if (!CXXThreadLocalInits.empty()) { 319251662Sdim // Generate a guarded initialization function. 320251662Sdim llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 321251662Sdim InitFn = CreateGlobalInitOrDestructFunction(*this, FTy, "__tls_init", 322251662Sdim /*TLS*/ true); 323251662Sdim llvm::GlobalVariable *Guard = new llvm::GlobalVariable( 324251662Sdim getModule(), Int8Ty, false, llvm::GlobalVariable::InternalLinkage, 325251662Sdim llvm::ConstantInt::get(Int8Ty, 0), "__tls_guard"); 326251662Sdim Guard->setThreadLocal(true); 327251662Sdim CodeGenFunction(*this) 328251662Sdim .GenerateCXXGlobalInitFunc(InitFn, CXXThreadLocalInits, Guard); 329251662Sdim } 330251662Sdim 331251662Sdim getCXXABI().EmitThreadLocalInitFuncs(CXXThreadLocals, InitFn); 332251662Sdim 333251662Sdim CXXThreadLocalInits.clear(); 334251662Sdim CXXThreadLocals.clear(); 335251662Sdim} 336251662Sdim 337202379Srdivackyvoid 338200583SrdivackyCodeGenModule::EmitCXXGlobalInitFunc() { 339212904Sdim while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 340212904Sdim CXXGlobalInits.pop_back(); 341212904Sdim 342210299Sed if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 343200583Srdivacky return; 344200583Srdivacky 345234353Sdim llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 346200583Srdivacky 347243830Sdim 348200583Srdivacky // Create our global initialization function. 349210299Sed if (!PrioritizedCXXGlobalInits.empty()) { 350226633Sdim SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 351210299Sed llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 352243830Sdim PrioritizedCXXGlobalInits.end()); 353243830Sdim // Iterate over "chunks" of ctors with same priority and emit each chunk 354243830Sdim // into separate function. Note - everything is sorted first by priority, 355243830Sdim // second - by lex order, so we emit ctor functions in proper order. 356243830Sdim for (SmallVectorImpl<GlobalInitData >::iterator 357243830Sdim I = PrioritizedCXXGlobalInits.begin(), 358243830Sdim E = PrioritizedCXXGlobalInits.end(); I != E; ) { 359243830Sdim SmallVectorImpl<GlobalInitData >::iterator 360243830Sdim PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp()); 361243830Sdim 362243830Sdim LocalCXXGlobalInits.clear(); 363243830Sdim unsigned Priority = I->first.priority; 364243830Sdim // Compute the function suffix from priority. Prepend with zeroes to make 365243830Sdim // sure the function names are also ordered as priorities. 366243830Sdim std::string PrioritySuffix = llvm::utostr(Priority); 367243830Sdim // Priority is always <= 65535 (enforced by sema).. 368243830Sdim PrioritySuffix = std::string(6-PrioritySuffix.size(), '0')+PrioritySuffix; 369243830Sdim llvm::Function *Fn = 370243830Sdim CreateGlobalInitOrDestructFunction(*this, FTy, 371243830Sdim "_GLOBAL__I_" + PrioritySuffix); 372243830Sdim 373243830Sdim for (; I < PrioE; ++I) 374243830Sdim LocalCXXGlobalInits.push_back(I->second); 375243830Sdim 376251662Sdim CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits); 377243830Sdim AddGlobalCtor(Fn, Priority); 378243830Sdim } 379210299Sed } 380243830Sdim 381243830Sdim llvm::Function *Fn = 382243830Sdim CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 383243830Sdim 384251662Sdim CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits); 385200583Srdivacky AddGlobalCtor(Fn); 386243830Sdim 387223017Sdim CXXGlobalInits.clear(); 388223017Sdim PrioritizedCXXGlobalInits.clear(); 389200583Srdivacky} 390200583Srdivacky 391205408Srdivackyvoid CodeGenModule::EmitCXXGlobalDtorFunc() { 392205408Srdivacky if (CXXGlobalDtors.empty()) 393205408Srdivacky return; 394205408Srdivacky 395234353Sdim llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 396205408Srdivacky 397205408Srdivacky // Create our global destructor function. 398205408Srdivacky llvm::Function *Fn = 399210299Sed CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 400205408Srdivacky 401234353Sdim CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors); 402205408Srdivacky AddGlobalDtor(Fn); 403205408Srdivacky} 404205408Srdivacky 405218893Sdim/// Emit the code necessary to initialize the given global variable. 406202379Srdivackyvoid CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 407218893Sdim const VarDecl *D, 408234353Sdim llvm::GlobalVariable *Addr, 409234353Sdim bool PerformInit) { 410243830Sdim // Check if we need to emit debug info for variable initializer. 411263508Sdim if (D->hasAttr<NoDebugAttr>()) 412263508Sdim DebugInfo = NULL; // disable debug info indefinitely for this function 413239462Sdim 414239462Sdim StartFunction(GlobalDecl(D), getContext().VoidTy, Fn, 415234353Sdim getTypes().arrangeNullaryFunction(), 416239462Sdim FunctionArgList(), D->getInit()->getExprLoc()); 417202379Srdivacky 418224145Sdim // Use guarded initialization if the global variable is weak. This 419224145Sdim // occurs for, e.g., instantiated static data members and 420224145Sdim // definitions explicitly marked weak. 421224145Sdim if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage || 422224145Sdim Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) { 423234353Sdim EmitCXXGuardedInit(*D, Addr, PerformInit); 424218893Sdim } else { 425234353Sdim EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit); 426218893Sdim } 427202379Srdivacky 428202379Srdivacky FinishFunction(); 429202379Srdivacky} 430202379Srdivacky 431251662Sdimvoid 432251662SdimCodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 433251662Sdim ArrayRef<llvm::Constant *> Decls, 434251662Sdim llvm::GlobalVariable *Guard) { 435221345Sdim StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 436234353Sdim getTypes().arrangeNullaryFunction(), 437221345Sdim FunctionArgList(), SourceLocation()); 438200583Srdivacky 439251662Sdim llvm::BasicBlock *ExitBlock = 0; 440251662Sdim if (Guard) { 441251662Sdim // If we have a guard variable, check whether we've already performed these 442251662Sdim // initializations. This happens for TLS initialization functions. 443251662Sdim llvm::Value *GuardVal = Builder.CreateLoad(Guard); 444251662Sdim llvm::Value *Uninit = Builder.CreateIsNull(GuardVal, "guard.uninitialized"); 445251662Sdim // Mark as initialized before initializing anything else. If the 446251662Sdim // initializers use previously-initialized thread_local vars, that's 447251662Sdim // probably supposed to be OK, but the standard doesn't say. 448251662Sdim Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(), 1), Guard); 449251662Sdim llvm::BasicBlock *InitBlock = createBasicBlock("init"); 450251662Sdim ExitBlock = createBasicBlock("exit"); 451251662Sdim Builder.CreateCondBr(Uninit, InitBlock, ExitBlock); 452251662Sdim EmitBlock(InitBlock); 453251662Sdim } 454251662Sdim 455224145Sdim RunCleanupsScope Scope(*this); 456224145Sdim 457224145Sdim // When building in Objective-C++ ARC mode, create an autorelease pool 458224145Sdim // around the global initializers. 459234353Sdim if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) { 460224145Sdim llvm::Value *token = EmitObjCAutoreleasePoolPush(); 461224145Sdim EmitObjCAutoreleasePoolCleanup(token); 462224145Sdim } 463251662Sdim 464251662Sdim for (unsigned i = 0, e = Decls.size(); i != e; ++i) 465212904Sdim if (Decls[i]) 466249423Sdim EmitRuntimeCall(Decls[i]); 467200583Srdivacky 468224145Sdim Scope.ForceCleanup(); 469251662Sdim 470251662Sdim if (ExitBlock) { 471251662Sdim Builder.CreateBr(ExitBlock); 472251662Sdim EmitBlock(ExitBlock); 473251662Sdim } 474251662Sdim 475200583Srdivacky FinishFunction(); 476200583Srdivacky} 477200583Srdivacky 478234353Sdimvoid CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, 479210299Sed const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 480205408Srdivacky &DtorsAndObjects) { 481221345Sdim StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 482234353Sdim getTypes().arrangeNullaryFunction(), 483221345Sdim FunctionArgList(), SourceLocation()); 484205408Srdivacky 485205408Srdivacky // Emit the dtors, in reverse order from construction. 486207619Srdivacky for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 487210299Sed llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 488207619Srdivacky llvm::CallInst *CI = Builder.CreateCall(Callee, 489207619Srdivacky DtorsAndObjects[e - i - 1].second); 490207619Srdivacky // Make sure the call and the callee agree on calling convention. 491207619Srdivacky if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 492207619Srdivacky CI->setCallingConv(F->getCallingConv()); 493207619Srdivacky } 494205408Srdivacky 495205408Srdivacky FinishFunction(); 496205408Srdivacky} 497205408Srdivacky 498224145Sdim/// generateDestroyHelper - Generates a helper function which, when 499224145Sdim/// invoked, destroys the given object. 500263508Sdimllvm::Function *CodeGenFunction::generateDestroyHelper( 501263508Sdim llvm::Constant *addr, QualType type, Destroyer *destroyer, 502263508Sdim bool useEHCleanupForArray, const VarDecl *VD) { 503221345Sdim FunctionArgList args; 504221345Sdim ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy); 505221345Sdim args.push_back(&dst); 506210299Sed 507210299Sed const CGFunctionInfo &FI = 508234353Sdim CGM.getTypes().arrangeFunctionDeclaration(getContext().VoidTy, args, 509234353Sdim FunctionType::ExtInfo(), 510234353Sdim /*variadic*/ false); 511234353Sdim llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI); 512224145Sdim llvm::Function *fn = 513210299Sed CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 514208600Srdivacky 515263508Sdim StartFunction(VD, getContext().VoidTy, fn, FI, args, SourceLocation()); 516243830Sdim 517224145Sdim emitDestroy(addr, type, destroyer, useEHCleanupForArray); 518208600Srdivacky 519210299Sed FinishFunction(); 520210299Sed 521224145Sdim return fn; 522200583Srdivacky} 523