1 //===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This contains code dealing with code generation of C++ declarations 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CodeGenFunction.h" 15 #include "CGObjCRuntime.h" 16 #include "CGCXXABI.h" 17 #include "clang/Frontend/CodeGenOptions.h" 18 #include "llvm/Intrinsics.h" 19 20 using namespace clang; 21 using namespace CodeGen; 22 23 static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, 24 llvm::Constant *DeclPtr) { 25 assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); 26 assert(!D.getType()->isReferenceType() && 27 "Should not call EmitDeclInit on a reference!"); 28 29 ASTContext &Context = CGF.getContext(); 30 31 unsigned alignment = Context.getDeclAlign(&D).getQuantity(); 32 QualType type = D.getType(); 33 LValue lv = CGF.MakeAddrLValue(DeclPtr, type, alignment); 34 35 const Expr *Init = D.getInit(); 36 if (!CGF.hasAggregateLLVMType(type)) { 37 CodeGenModule &CGM = CGF.CGM; 38 if (lv.isObjCStrong()) 39 CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init), 40 DeclPtr, D.isThreadSpecified()); 41 else if (lv.isObjCWeak()) 42 CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init), 43 DeclPtr); 44 else 45 CGF.EmitScalarInit(Init, &D, lv, false); 46 } else if (type->isAnyComplexType()) { 47 CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile()); 48 } else { 49 CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed, 50 AggValueSlot::DoesNotNeedGCBarriers, 51 AggValueSlot::IsNotAliased)); 52 } 53 } 54 55 /// Emit code to cause the destruction of the given variable with 56 /// static storage duration. 57 static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 58 llvm::Constant *addr) { 59 CodeGenModule &CGM = CGF.CGM; 60 61 // FIXME: __attribute__((cleanup)) ? 62 63 QualType type = D.getType(); 64 QualType::DestructionKind dtorKind = type.isDestructedType(); 65 66 switch (dtorKind) { 67 case QualType::DK_none: 68 return; 69 70 case QualType::DK_cxx_destructor: 71 break; 72 73 case QualType::DK_objc_strong_lifetime: 74 case QualType::DK_objc_weak_lifetime: 75 // We don't care about releasing objects during process teardown. 76 return; 77 } 78 79 llvm::Constant *function; 80 llvm::Constant *argument; 81 82 // Special-case non-array C++ destructors, where there's a function 83 // with the right signature that we can just call. 84 const CXXRecordDecl *record = 0; 85 if (dtorKind == QualType::DK_cxx_destructor && 86 (record = type->getAsCXXRecordDecl())) { 87 assert(!record->hasTrivialDestructor()); 88 CXXDestructorDecl *dtor = record->getDestructor(); 89 90 function = CGM.GetAddrOfCXXDestructor(dtor, Dtor_Complete); 91 argument = addr; 92 93 // Otherwise, the standard logic requires a helper function. 94 } else { 95 function = CodeGenFunction(CGM).generateDestroyHelper(addr, type, 96 CGF.getDestroyer(dtorKind), 97 CGF.needsEHCleanup(dtorKind)); 98 argument = llvm::Constant::getNullValue(CGF.Int8PtrTy); 99 } 100 101 CGF.EmitCXXGlobalDtorRegistration(function, argument); 102 } 103 104 void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 105 llvm::Constant *DeclPtr) { 106 107 const Expr *Init = D.getInit(); 108 QualType T = D.getType(); 109 110 if (!T->isReferenceType()) { 111 EmitDeclInit(*this, D, DeclPtr); 112 EmitDeclDestroy(*this, D, DeclPtr); 113 return; 114 } 115 116 unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 117 RValue RV = EmitReferenceBindingToExpr(Init, &D); 118 EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); 119 } 120 121 void 122 CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 123 llvm::Constant *DeclPtr) { 124 // Generate a global destructor entry if not using __cxa_atexit. 125 if (!CGM.getCodeGenOpts().CXAAtExit) { 126 CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 127 return; 128 } 129 130 // Get the destructor function type 131 llvm::Type *DtorFnTy = 132 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 133 Int8PtrTy, false); 134 DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 135 136 llvm::Type *Params[] = { DtorFnTy, Int8PtrTy, Int8PtrTy }; 137 138 // Get the __cxa_atexit function type 139 // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 140 llvm::FunctionType *AtExitFnTy = 141 llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 142 143 llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 144 "__cxa_atexit"); 145 if (llvm::Function *Fn = dyn_cast<llvm::Function>(AtExitFn)) 146 Fn->setDoesNotThrow(); 147 148 llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, 149 "__dso_handle"); 150 llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), 151 llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), 152 llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; 153 Builder.CreateCall(AtExitFn, Args); 154 } 155 156 void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, 157 llvm::GlobalVariable *DeclPtr) { 158 // If we've been asked to forbid guard variables, emit an error now. 159 // This diagnostic is hard-coded for Darwin's use case; we can find 160 // better phrasing if someone else needs it. 161 if (CGM.getCodeGenOpts().ForbidGuardVariables) 162 CGM.Error(D.getLocation(), 163 "this initialization requires a guard variable, which " 164 "the kernel does not support"); 165 166 CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr); 167 } 168 169 static llvm::Function * 170 CreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 171 llvm::FunctionType *FTy, 172 StringRef Name) { 173 llvm::Function *Fn = 174 llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 175 Name, &CGM.getModule()); 176 if (!CGM.getContext().getLangOptions().AppleKext) { 177 // Set the section if needed. 178 if (const char *Section = 179 CGM.getContext().getTargetInfo().getStaticInitSectionSpecifier()) 180 Fn->setSection(Section); 181 } 182 183 if (!CGM.getLangOptions().Exceptions) 184 Fn->setDoesNotThrow(); 185 186 return Fn; 187 } 188 189 void 190 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 191 llvm::GlobalVariable *Addr) { 192 llvm::FunctionType *FTy 193 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 194 false); 195 196 // Create a variable initialization function. 197 llvm::Function *Fn = 198 CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 199 200 CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr); 201 202 if (D->hasAttr<InitPriorityAttr>()) { 203 unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 204 OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 205 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 206 DelayedCXXInitPosition.erase(D); 207 } 208 else { 209 llvm::DenseMap<const Decl *, unsigned>::iterator I = 210 DelayedCXXInitPosition.find(D); 211 if (I == DelayedCXXInitPosition.end()) { 212 CXXGlobalInits.push_back(Fn); 213 } else { 214 assert(CXXGlobalInits[I->second] == 0); 215 CXXGlobalInits[I->second] = Fn; 216 DelayedCXXInitPosition.erase(I); 217 } 218 } 219 } 220 221 void 222 CodeGenModule::EmitCXXGlobalInitFunc() { 223 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 224 CXXGlobalInits.pop_back(); 225 226 if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 227 return; 228 229 llvm::FunctionType *FTy 230 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 231 false); 232 233 // Create our global initialization function. 234 llvm::Function *Fn = 235 CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 236 237 if (!PrioritizedCXXGlobalInits.empty()) { 238 SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 239 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 240 PrioritizedCXXGlobalInits.end()); 241 for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) { 242 llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; 243 LocalCXXGlobalInits.push_back(Fn); 244 } 245 LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); 246 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 247 &LocalCXXGlobalInits[0], 248 LocalCXXGlobalInits.size()); 249 } 250 else 251 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 252 &CXXGlobalInits[0], 253 CXXGlobalInits.size()); 254 AddGlobalCtor(Fn); 255 CXXGlobalInits.clear(); 256 PrioritizedCXXGlobalInits.clear(); 257 } 258 259 void CodeGenModule::EmitCXXGlobalDtorFunc() { 260 if (CXXGlobalDtors.empty()) 261 return; 262 263 llvm::FunctionType *FTy 264 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 265 false); 266 267 // Create our global destructor function. 268 llvm::Function *Fn = 269 CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 270 271 CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 272 AddGlobalDtor(Fn); 273 } 274 275 /// Emit the code necessary to initialize the given global variable. 276 void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 277 const VarDecl *D, 278 llvm::GlobalVariable *Addr) { 279 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 280 getTypes().getNullaryFunctionInfo(), 281 FunctionArgList(), SourceLocation()); 282 283 // Use guarded initialization if the global variable is weak. This 284 // occurs for, e.g., instantiated static data members and 285 // definitions explicitly marked weak. 286 if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage || 287 Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) { 288 EmitCXXGuardedInit(*D, Addr); 289 } else { 290 EmitCXXGlobalVarDeclInit(*D, Addr); 291 } 292 293 FinishFunction(); 294 } 295 296 void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 297 llvm::Constant **Decls, 298 unsigned NumDecls) { 299 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 300 getTypes().getNullaryFunctionInfo(), 301 FunctionArgList(), SourceLocation()); 302 303 RunCleanupsScope Scope(*this); 304 305 // When building in Objective-C++ ARC mode, create an autorelease pool 306 // around the global initializers. 307 if (getLangOptions().ObjCAutoRefCount && getLangOptions().CPlusPlus) { 308 llvm::Value *token = EmitObjCAutoreleasePoolPush(); 309 EmitObjCAutoreleasePoolCleanup(token); 310 } 311 312 for (unsigned i = 0; i != NumDecls; ++i) 313 if (Decls[i]) 314 Builder.CreateCall(Decls[i]); 315 316 Scope.ForceCleanup(); 317 318 FinishFunction(); 319 } 320 321 void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 322 const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 323 &DtorsAndObjects) { 324 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 325 getTypes().getNullaryFunctionInfo(), 326 FunctionArgList(), SourceLocation()); 327 328 // Emit the dtors, in reverse order from construction. 329 for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 330 llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 331 llvm::CallInst *CI = Builder.CreateCall(Callee, 332 DtorsAndObjects[e - i - 1].second); 333 // Make sure the call and the callee agree on calling convention. 334 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 335 CI->setCallingConv(F->getCallingConv()); 336 } 337 338 FinishFunction(); 339 } 340 341 /// generateDestroyHelper - Generates a helper function which, when 342 /// invoked, destroys the given object. 343 llvm::Function * 344 CodeGenFunction::generateDestroyHelper(llvm::Constant *addr, 345 QualType type, 346 Destroyer &destroyer, 347 bool useEHCleanupForArray) { 348 FunctionArgList args; 349 ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy); 350 args.push_back(&dst); 351 352 const CGFunctionInfo &FI = 353 CGM.getTypes().getFunctionInfo(getContext().VoidTy, args, 354 FunctionType::ExtInfo()); 355 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 356 llvm::Function *fn = 357 CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 358 359 StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args, 360 SourceLocation()); 361 362 emitDestroy(addr, type, destroyer, useEHCleanupForArray); 363 364 FinishFunction(); 365 366 return fn; 367 } 368 369