CGDeclCXX.cpp revision 208954
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 "clang/CodeGen/CodeGenOptions.h" 16#include "llvm/Intrinsics.h" 17 18using namespace clang; 19using namespace CodeGen; 20 21static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, 22 llvm::Constant *DeclPtr) { 23 assert(D.hasGlobalStorage() && "VarDecl must have global storage!"); 24 assert(!D.getType()->isReferenceType() && 25 "Should not call EmitDeclInit on a reference!"); 26 27 ASTContext &Context = CGF.getContext(); 28 29 const Expr *Init = D.getInit(); 30 QualType T = D.getType(); 31 bool isVolatile = Context.getCanonicalType(T).isVolatileQualified(); 32 33 if (!CGF.hasAggregateLLVMType(T)) { 34 llvm::Value *V = CGF.EmitScalarExpr(Init); 35 CGF.EmitStoreOfScalar(V, DeclPtr, isVolatile, T); 36 } else if (T->isAnyComplexType()) { 37 CGF.EmitComplexExprIntoAddr(Init, DeclPtr, isVolatile); 38 } else { 39 CGF.EmitAggExpr(Init, DeclPtr, isVolatile); 40 } 41} 42 43static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 44 llvm::Constant *DeclPtr) { 45 CodeGenModule &CGM = CGF.CGM; 46 ASTContext &Context = CGF.getContext(); 47 48 const Expr *Init = D.getInit(); 49 QualType T = D.getType(); 50 if (!CGF.hasAggregateLLVMType(T) || T->isAnyComplexType()) 51 return; 52 53 // Avoid generating destructor(s) for initialized objects. 54 if (!isa<CXXConstructExpr>(Init)) 55 return; 56 57 const ConstantArrayType *Array = Context.getAsConstantArrayType(T); 58 if (Array) 59 T = Context.getBaseElementType(Array); 60 61 const RecordType *RT = T->getAs<RecordType>(); 62 if (!RT) 63 return; 64 65 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 66 if (RD->hasTrivialDestructor()) 67 return; 68 69 CXXDestructorDecl *Dtor = RD->getDestructor(Context); 70 71 llvm::Constant *DtorFn; 72 if (Array) { 73 DtorFn = 74 CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, 75 Array, 76 DeclPtr); 77 const llvm::Type *Int8PtrTy = 78 llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 79 DeclPtr = llvm::Constant::getNullValue(Int8PtrTy); 80 } else 81 DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete); 82 83 CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr); 84} 85 86void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 87 llvm::Constant *DeclPtr) { 88 89 const Expr *Init = D.getInit(); 90 QualType T = D.getType(); 91 92 if (!T->isReferenceType()) { 93 EmitDeclInit(*this, D, DeclPtr); 94 EmitDeclDestroy(*this, D, DeclPtr); 95 return; 96 } 97 if (Init->isLvalue(getContext()) == Expr::LV_Valid) { 98 RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true); 99 EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T); 100 return; 101 } 102 ErrorUnsupported(Init, 103 "global variable that binds reference to a non-lvalue"); 104} 105 106void 107CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 108 llvm::Constant *DeclPtr) { 109 // Generate a global destructor entry if not using __cxa_atexit. 110 if (!CGM.getCodeGenOpts().CXAAtExit) { 111 CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 112 return; 113 } 114 115 const llvm::Type *Int8PtrTy = 116 llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 117 118 std::vector<const llvm::Type *> Params; 119 Params.push_back(Int8PtrTy); 120 121 // Get the destructor function type 122 const llvm::Type *DtorFnTy = 123 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); 124 DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 125 126 Params.clear(); 127 Params.push_back(DtorFnTy); 128 Params.push_back(Int8PtrTy); 129 Params.push_back(Int8PtrTy); 130 131 // Get the __cxa_atexit function type 132 // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 133 const llvm::FunctionType *AtExitFnTy = 134 llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 135 136 llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 137 "__cxa_atexit"); 138 139 llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, 140 "__dso_handle"); 141 llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), 142 llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), 143 llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; 144 Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args)); 145} 146 147void 148CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) { 149 const llvm::FunctionType *FTy 150 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 151 false); 152 153 // Create a variable initialization function. 154 llvm::Function *Fn = 155 llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 156 "__cxx_global_var_init", &TheModule); 157 158 CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D); 159 160 CXXGlobalInits.push_back(Fn); 161} 162 163void 164CodeGenModule::EmitCXXGlobalInitFunc() { 165 if (CXXGlobalInits.empty()) 166 return; 167 168 const llvm::FunctionType *FTy 169 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 170 false); 171 172 // Create our global initialization function. 173 llvm::Function *Fn = 174 llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 175 "_GLOBAL__I_a", &TheModule); 176 177 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 178 &CXXGlobalInits[0], 179 CXXGlobalInits.size()); 180 AddGlobalCtor(Fn); 181} 182 183void CodeGenModule::AddCXXDtorEntry(llvm::Constant *DtorFn, 184 llvm::Constant *Object) { 185 CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object)); 186} 187 188void CodeGenModule::EmitCXXGlobalDtorFunc() { 189 if (CXXGlobalDtors.empty()) 190 return; 191 192 const llvm::FunctionType *FTy 193 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 194 false); 195 196 // Create our global destructor function. 197 llvm::Function *Fn = 198 llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 199 "_GLOBAL__D_a", &TheModule); 200 201 CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 202 AddGlobalDtor(Fn); 203} 204 205void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 206 const VarDecl *D) { 207 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 208 SourceLocation()); 209 210 llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D); 211 EmitCXXGlobalVarDeclInit(*D, DeclPtr); 212 213 FinishFunction(); 214} 215 216void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 217 llvm::Constant **Decls, 218 unsigned NumDecls) { 219 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 220 SourceLocation()); 221 222 for (unsigned i = 0; i != NumDecls; ++i) 223 Builder.CreateCall(Decls[i]); 224 225 FinishFunction(); 226} 227 228void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 229 const std::vector<std::pair<llvm::Constant*, llvm::Constant*> > 230 &DtorsAndObjects) { 231 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 232 SourceLocation()); 233 234 // Emit the dtors, in reverse order from construction. 235 for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 236 llvm::Constant *Callee = DtorsAndObjects[e - i - 1].first; 237 llvm::CallInst *CI = Builder.CreateCall(Callee, 238 DtorsAndObjects[e - i - 1].second); 239 // Make sure the call and the callee agree on calling convention. 240 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 241 CI->setCallingConv(F->getCallingConv()); 242 } 243 244 FinishFunction(); 245} 246 247static llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) { 248 // int __cxa_guard_acquire(__int64_t *guard_object); 249 250 const llvm::Type *Int64PtrTy = 251 llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 252 253 std::vector<const llvm::Type*> Args(1, Int64PtrTy); 254 255 const llvm::FunctionType *FTy = 256 llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy), 257 Args, /*isVarArg=*/false); 258 259 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire"); 260} 261 262static llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) { 263 // void __cxa_guard_release(__int64_t *guard_object); 264 265 const llvm::Type *Int64PtrTy = 266 llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 267 268 std::vector<const llvm::Type*> Args(1, Int64PtrTy); 269 270 const llvm::FunctionType *FTy = 271 llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 272 Args, /*isVarArg=*/false); 273 274 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release"); 275} 276 277static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) { 278 // void __cxa_guard_abort(__int64_t *guard_object); 279 280 const llvm::Type *Int64PtrTy = 281 llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 282 283 std::vector<const llvm::Type*> Args(1, Int64PtrTy); 284 285 const llvm::FunctionType *FTy = 286 llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 287 Args, /*isVarArg=*/false); 288 289 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort"); 290} 291 292void 293CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, 294 llvm::GlobalVariable *GV) { 295 // Bail out early if this initializer isn't reachable. 296 if (!Builder.GetInsertBlock()) return; 297 298 bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics; 299 300 llvm::SmallString<256> GuardVName; 301 CGM.getMangleContext().mangleGuardVariable(&D, GuardVName); 302 303 // Create the guard variable. 304 const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(VMContext); 305 llvm::GlobalValue *GuardVariable = 306 new llvm::GlobalVariable(CGM.getModule(), Int64Ty, 307 false, GV->getLinkage(), 308 llvm::Constant::getNullValue(Int64Ty), 309 GuardVName.str()); 310 311 // Load the first byte of the guard variable. 312 const llvm::Type *PtrTy 313 = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 314 llvm::Value *V = 315 Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp"); 316 317 llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check"); 318 llvm::BasicBlock *EndBlock = createBasicBlock("init.end"); 319 320 // Check if the first byte of the guard variable is zero. 321 Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"), 322 InitCheckBlock, EndBlock); 323 324 EmitBlock(InitCheckBlock); 325 326 // Variables used when coping with thread-safe statics and exceptions. 327 llvm::BasicBlock *SavedLandingPad = 0; 328 llvm::BasicBlock *LandingPad = 0; 329 if (ThreadsafeStatics) { 330 // Call __cxa_guard_acquire. 331 V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable); 332 333 llvm::BasicBlock *InitBlock = createBasicBlock("init"); 334 335 Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), 336 InitBlock, EndBlock); 337 338 if (Exceptions) { 339 SavedLandingPad = getInvokeDest(); 340 LandingPad = createBasicBlock("guard.lpad"); 341 setInvokeDest(LandingPad); 342 } 343 344 EmitBlock(InitBlock); 345 } 346 347 if (D.getType()->isReferenceType()) { 348 QualType T = D.getType(); 349 // We don't want to pass true for IsInitializer here, because a static 350 // reference to a temporary does not extend its lifetime. 351 RValue RV = EmitReferenceBindingToExpr(D.getInit(), 352 /*IsInitializer=*/false); 353 EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T); 354 355 } else 356 EmitDeclInit(*this, D, GV); 357 358 if (ThreadsafeStatics) { 359 // Call __cxa_guard_release. 360 Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable); 361 } else { 362 llvm::Value *One = 363 llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1); 364 Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy)); 365 } 366 367 // Register the call to the destructor. 368 if (!D.getType()->isReferenceType()) 369 EmitDeclDestroy(*this, D, GV); 370 371 if (ThreadsafeStatics && Exceptions) { 372 // If an exception is thrown during initialization, call __cxa_guard_abort 373 // along the exceptional edge. 374 EmitBranch(EndBlock); 375 376 // Construct the landing pad. 377 EmitBlock(LandingPad); 378 379 // Personality function and LLVM intrinsics. 380 llvm::Constant *Personality = 381 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 382 (VMContext), 383 true), 384 "__gxx_personality_v0"); 385 Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); 386 llvm::Value *llvm_eh_exception = 387 CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 388 llvm::Value *llvm_eh_selector = 389 CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 390 391 // Exception object 392 llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 393 llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow"); 394 395 // Call the selector function. 396 const llvm::PointerType *PtrToInt8Ty 397 = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext)); 398 llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty); 399 llvm::Value* SelectorArgs[3] = { Exc, Personality, Null }; 400 Builder.CreateCall(llvm_eh_selector, SelectorArgs, SelectorArgs + 3, 401 "selector"); 402 Builder.CreateStore(Exc, RethrowPtr); 403 404 // Call __cxa_guard_abort along the exceptional edge. 405 Builder.CreateCall(getGuardAbortFn(*this), GuardVariable); 406 407 setInvokeDest(SavedLandingPad); 408 409 // Rethrow the current exception. 410 if (getInvokeDest()) { 411 llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 412 Builder.CreateInvoke(getUnwindResumeOrRethrowFn(), Cont, 413 getInvokeDest(), 414 Builder.CreateLoad(RethrowPtr)); 415 EmitBlock(Cont); 416 } else 417 Builder.CreateCall(getUnwindResumeOrRethrowFn(), 418 Builder.CreateLoad(RethrowPtr)); 419 420 Builder.CreateUnreachable(); 421 } 422 423 EmitBlock(EndBlock); 424} 425