CGDeclCXX.cpp revision 06057cef0bcd7804e80f3ce2bbe352178396c715
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/Frontend/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, Array, 75 DeclPtr); 76 const llvm::Type *Int8PtrTy = 77 llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 78 DeclPtr = llvm::Constant::getNullValue(Int8PtrTy); 79 } else 80 DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete); 81 82 CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr); 83} 84 85void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 86 llvm::Constant *DeclPtr) { 87 88 const Expr *Init = D.getInit(); 89 QualType T = D.getType(); 90 91 if (!T->isReferenceType()) { 92 EmitDeclInit(*this, D, DeclPtr); 93 EmitDeclDestroy(*this, D, DeclPtr); 94 return; 95 } 96 if (Init->isLvalue(getContext()) == Expr::LV_Valid) { 97 RValue RV = EmitReferenceBindingToExpr(Init, /*IsInitializer=*/true); 98 EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, T); 99 return; 100 } 101 ErrorUnsupported(Init, 102 "global variable that binds reference to a non-lvalue"); 103} 104 105void 106CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 107 llvm::Constant *DeclPtr) { 108 // Generate a global destructor entry if not using __cxa_atexit. 109 if (!CGM.getCodeGenOpts().CXAAtExit) { 110 CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 111 return; 112 } 113 114 const llvm::Type *Int8PtrTy = 115 llvm::Type::getInt8Ty(VMContext)->getPointerTo(); 116 117 std::vector<const llvm::Type *> Params; 118 Params.push_back(Int8PtrTy); 119 120 // Get the destructor function type 121 const llvm::Type *DtorFnTy = 122 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Params, false); 123 DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 124 125 Params.clear(); 126 Params.push_back(DtorFnTy); 127 Params.push_back(Int8PtrTy); 128 Params.push_back(Int8PtrTy); 129 130 // Get the __cxa_atexit function type 131 // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 132 const llvm::FunctionType *AtExitFnTy = 133 llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 134 135 llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 136 "__cxa_atexit"); 137 138 llvm::Constant *Handle = CGM.CreateRuntimeVariable(Int8PtrTy, 139 "__dso_handle"); 140 llvm::Value *Args[3] = { llvm::ConstantExpr::getBitCast(DtorFn, DtorFnTy), 141 llvm::ConstantExpr::getBitCast(DeclPtr, Int8PtrTy), 142 llvm::ConstantExpr::getBitCast(Handle, Int8PtrTy) }; 143 Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args)); 144} 145 146static llvm::Function * 147CreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 148 const llvm::FunctionType *FTy, 149 llvm::StringRef Name) { 150 llvm::Function *Fn = 151 llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 152 Name, &CGM.getModule()); 153 154 // Set the section if needed. 155 if (const char *Section = 156 CGM.getContext().Target.getStaticInitSectionSpecifier()) 157 Fn->setSection(Section); 158 159 return Fn; 160} 161 162void 163CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) { 164 const llvm::FunctionType *FTy 165 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 166 false); 167 168 // Create a variable initialization function. 169 llvm::Function *Fn = 170 CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 171 172 CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D); 173 174 CXXGlobalInits.push_back(Fn); 175} 176 177void 178CodeGenModule::EmitCXXGlobalInitFunc() { 179 if (CXXGlobalInits.empty()) 180 return; 181 182 const llvm::FunctionType *FTy 183 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 184 false); 185 186 // Create our global initialization function. 187 llvm::Function *Fn = 188 CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 189 190 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 191 &CXXGlobalInits[0], 192 CXXGlobalInits.size()); 193 AddGlobalCtor(Fn); 194} 195 196void CodeGenModule::AddCXXDtorEntry(llvm::Constant *DtorFn, 197 llvm::Constant *Object) { 198 CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object)); 199} 200 201void CodeGenModule::EmitCXXGlobalDtorFunc() { 202 if (CXXGlobalDtors.empty()) 203 return; 204 205 const llvm::FunctionType *FTy 206 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 207 false); 208 209 // Create our global destructor function. 210 llvm::Function *Fn = 211 CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 212 213 CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 214 AddGlobalDtor(Fn); 215} 216 217void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 218 const VarDecl *D) { 219 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 220 SourceLocation()); 221 222 llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D); 223 EmitCXXGlobalVarDeclInit(*D, DeclPtr); 224 225 FinishFunction(); 226} 227 228void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 229 llvm::Constant **Decls, 230 unsigned NumDecls) { 231 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 232 SourceLocation()); 233 234 for (unsigned i = 0; i != NumDecls; ++i) 235 Builder.CreateCall(Decls[i]); 236 237 FinishFunction(); 238} 239 240void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 241 const std::vector<std::pair<llvm::Constant*, llvm::Constant*> > 242 &DtorsAndObjects) { 243 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(), 244 SourceLocation()); 245 246 // Emit the dtors, in reverse order from construction. 247 for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 248 llvm::Constant *Callee = DtorsAndObjects[e - i - 1].first; 249 llvm::CallInst *CI = Builder.CreateCall(Callee, 250 DtorsAndObjects[e - i - 1].second); 251 // Make sure the call and the callee agree on calling convention. 252 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 253 CI->setCallingConv(F->getCallingConv()); 254 } 255 256 FinishFunction(); 257} 258 259static llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) { 260 // int __cxa_guard_acquire(__int64_t *guard_object); 261 262 const llvm::Type *Int64PtrTy = 263 llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 264 265 std::vector<const llvm::Type*> Args(1, Int64PtrTy); 266 267 const llvm::FunctionType *FTy = 268 llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy), 269 Args, /*isVarArg=*/false); 270 271 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire"); 272} 273 274static llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) { 275 // void __cxa_guard_release(__int64_t *guard_object); 276 277 const llvm::Type *Int64PtrTy = 278 llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 279 280 std::vector<const llvm::Type*> Args(1, Int64PtrTy); 281 282 const llvm::FunctionType *FTy = 283 llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 284 Args, /*isVarArg=*/false); 285 286 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release"); 287} 288 289static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) { 290 // void __cxa_guard_abort(__int64_t *guard_object); 291 292 const llvm::Type *Int64PtrTy = 293 llvm::Type::getInt64PtrTy(CGF.getLLVMContext()); 294 295 std::vector<const llvm::Type*> Args(1, Int64PtrTy); 296 297 const llvm::FunctionType *FTy = 298 llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), 299 Args, /*isVarArg=*/false); 300 301 return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort"); 302} 303 304void 305CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D, 306 llvm::GlobalVariable *GV) { 307 // Bail out early if this initializer isn't reachable. 308 if (!Builder.GetInsertBlock()) return; 309 310 bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics; 311 312 llvm::SmallString<256> GuardVName; 313 CGM.getMangleContext().mangleGuardVariable(&D, GuardVName); 314 315 // Create the guard variable. 316 const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(VMContext); 317 llvm::GlobalValue *GuardVariable = 318 new llvm::GlobalVariable(CGM.getModule(), Int64Ty, 319 false, GV->getLinkage(), 320 llvm::Constant::getNullValue(Int64Ty), 321 GuardVName.str()); 322 323 // Load the first byte of the guard variable. 324 const llvm::Type *PtrTy 325 = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0); 326 llvm::Value *V = 327 Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp"); 328 329 llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check"); 330 llvm::BasicBlock *EndBlock = createBasicBlock("init.end"); 331 332 // Check if the first byte of the guard variable is zero. 333 Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"), 334 InitCheckBlock, EndBlock); 335 336 EmitBlock(InitCheckBlock); 337 338 // Variables used when coping with thread-safe statics and exceptions. 339 llvm::BasicBlock *SavedLandingPad = 0; 340 llvm::BasicBlock *LandingPad = 0; 341 if (ThreadsafeStatics) { 342 // Call __cxa_guard_acquire. 343 V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable); 344 345 llvm::BasicBlock *InitBlock = createBasicBlock("init"); 346 347 Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"), 348 InitBlock, EndBlock); 349 350 if (Exceptions) { 351 SavedLandingPad = getInvokeDest(); 352 LandingPad = createBasicBlock("guard.lpad"); 353 setInvokeDest(LandingPad); 354 } 355 356 EmitBlock(InitBlock); 357 } 358 359 if (D.getType()->isReferenceType()) { 360 QualType T = D.getType(); 361 // We don't want to pass true for IsInitializer here, because a static 362 // reference to a temporary does not extend its lifetime. 363 RValue RV = EmitReferenceBindingToExpr(D.getInit(), 364 /*IsInitializer=*/false); 365 EmitStoreOfScalar(RV.getScalarVal(), GV, /*Volatile=*/false, T); 366 367 } else 368 EmitDeclInit(*this, D, GV); 369 370 if (ThreadsafeStatics) { 371 // Call __cxa_guard_release. 372 Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable); 373 } else { 374 llvm::Value *One = 375 llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1); 376 Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy)); 377 } 378 379 // Register the call to the destructor. 380 if (!D.getType()->isReferenceType()) 381 EmitDeclDestroy(*this, D, GV); 382 383 if (ThreadsafeStatics && Exceptions) { 384 // If an exception is thrown during initialization, call __cxa_guard_abort 385 // along the exceptional edge. 386 EmitBranch(EndBlock); 387 388 // Construct the landing pad. 389 EmitBlock(LandingPad); 390 391 // Personality function and LLVM intrinsics. 392 llvm::Constant *Personality = 393 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty 394 (VMContext), 395 true), 396 "__gxx_personality_v0"); 397 Personality = llvm::ConstantExpr::getBitCast(Personality, PtrToInt8Ty); 398 llvm::Value *llvm_eh_exception = 399 CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 400 llvm::Value *llvm_eh_selector = 401 CGM.getIntrinsic(llvm::Intrinsic::eh_selector); 402 403 // Exception object 404 llvm::Value *Exc = Builder.CreateCall(llvm_eh_exception, "exc"); 405 llvm::Value *RethrowPtr = CreateTempAlloca(Exc->getType(), "_rethrow"); 406 407 // Call the selector function. 408 const llvm::PointerType *PtrToInt8Ty 409 = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext)); 410 llvm::Constant *Null = llvm::ConstantPointerNull::get(PtrToInt8Ty); 411 llvm::Value* SelectorArgs[3] = { Exc, Personality, Null }; 412 Builder.CreateCall(llvm_eh_selector, SelectorArgs, SelectorArgs + 3, 413 "selector"); 414 Builder.CreateStore(Exc, RethrowPtr); 415 416 // Call __cxa_guard_abort along the exceptional edge. 417 Builder.CreateCall(getGuardAbortFn(*this), GuardVariable); 418 419 setInvokeDest(SavedLandingPad); 420 421 // Rethrow the current exception. 422 if (getInvokeDest()) { 423 llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); 424 Builder.CreateInvoke(getUnwindResumeOrRethrowFn(), Cont, 425 getInvokeDest(), 426 Builder.CreateLoad(RethrowPtr)); 427 EmitBlock(Cont); 428 } else 429 Builder.CreateCall(getUnwindResumeOrRethrowFn(), 430 Builder.CreateLoad(RethrowPtr)); 431 432 Builder.CreateUnreachable(); 433 } 434 435 EmitBlock(EndBlock); 436} 437 438/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 439/// invoked, calls the default destructor on array elements in reverse order of 440/// construction. 441llvm::Function * 442CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 443 const ArrayType *Array, 444 llvm::Value *This) { 445 FunctionArgList Args; 446 ImplicitParamDecl *Dst = 447 ImplicitParamDecl::Create(getContext(), 0, 448 SourceLocation(), 0, 449 getContext().getPointerType(getContext().VoidTy)); 450 Args.push_back(std::make_pair(Dst, Dst->getType())); 451 452 const CGFunctionInfo &FI = 453 CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args, 454 FunctionType::ExtInfo()); 455 const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 456 llvm::Function *Fn = 457 CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 458 459 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, Args, SourceLocation()); 460 461 QualType BaseElementTy = getContext().getBaseElementType(Array); 462 const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo(); 463 llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 464 465 EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 466 467 FinishFunction(); 468 469 return Fn; 470} 471