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