CGDeclCXX.cpp revision e67d1512f299e7f32182553f9941d61dae4f433e
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 20using namespace clang; 21using namespace CodeGen; 22 23static 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, true)); 50 } 51} 52 53/// Emit code to cause the destruction of the given variable with 54/// static storage duration. 55static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, 56 llvm::Constant *DeclPtr) { 57 CodeGenModule &CGM = CGF.CGM; 58 ASTContext &Context = CGF.getContext(); 59 60 QualType T = D.getType(); 61 62 // Drill down past array types. 63 const ConstantArrayType *Array = Context.getAsConstantArrayType(T); 64 if (Array) 65 T = Context.getBaseElementType(Array); 66 67 /// If that's not a record, we're done. 68 /// FIXME: __attribute__((cleanup)) ? 69 const RecordType *RT = T->getAs<RecordType>(); 70 if (!RT) 71 return; 72 73 CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 74 if (RD->hasTrivialDestructor()) 75 return; 76 77 CXXDestructorDecl *Dtor = RD->getDestructor(); 78 79 llvm::Constant *DtorFn; 80 if (Array) { 81 DtorFn = 82 CodeGenFunction(CGM).GenerateCXXAggrDestructorHelper(Dtor, Array, 83 DeclPtr); 84 const llvm::Type *Int8PtrTy = 85 llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); 86 DeclPtr = llvm::Constant::getNullValue(Int8PtrTy); 87 } else 88 DtorFn = CGM.GetAddrOfCXXDestructor(Dtor, Dtor_Complete); 89 90 CGF.EmitCXXGlobalDtorRegistration(DtorFn, DeclPtr); 91} 92 93void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, 94 llvm::Constant *DeclPtr) { 95 96 const Expr *Init = D.getInit(); 97 QualType T = D.getType(); 98 99 if (!T->isReferenceType()) { 100 EmitDeclInit(*this, D, DeclPtr); 101 EmitDeclDestroy(*this, D, DeclPtr); 102 return; 103 } 104 105 unsigned Alignment = getContext().getDeclAlign(&D).getQuantity(); 106 RValue RV = EmitReferenceBindingToExpr(Init, &D); 107 EmitStoreOfScalar(RV.getScalarVal(), DeclPtr, false, Alignment, T); 108} 109 110void 111CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, 112 llvm::Constant *DeclPtr) { 113 // Generate a global destructor entry if not using __cxa_atexit. 114 if (!CGM.getCodeGenOpts().CXAAtExit) { 115 CGM.AddCXXDtorEntry(DtorFn, DeclPtr); 116 return; 117 } 118 119 // Get the destructor function type 120 const llvm::Type *DtorFnTy = 121 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 122 Int8PtrTy, false); 123 DtorFnTy = llvm::PointerType::getUnqual(DtorFnTy); 124 125 const llvm::Type *Params[] = { DtorFnTy, Int8PtrTy, Int8PtrTy }; 126 127 // Get the __cxa_atexit function type 128 // extern "C" int __cxa_atexit ( void (*f)(void *), void *p, void *d ); 129 const llvm::FunctionType *AtExitFnTy = 130 llvm::FunctionType::get(ConvertType(getContext().IntTy), Params, false); 131 132 llvm::Constant *AtExitFn = CGM.CreateRuntimeFunction(AtExitFnTy, 133 "__cxa_atexit"); 134 if (llvm::Function *Fn = dyn_cast<llvm::Function>(AtExitFn)) 135 Fn->setDoesNotThrow(); 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 145void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, 146 llvm::GlobalVariable *DeclPtr) { 147 // If we've been asked to forbid guard variables, emit an error now. 148 // This diagnostic is hard-coded for Darwin's use case; we can find 149 // better phrasing if someone else needs it. 150 if (CGM.getCodeGenOpts().ForbidGuardVariables) 151 CGM.Error(D.getLocation(), 152 "this initialization requires a guard variable, which " 153 "the kernel does not support"); 154 155 CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr); 156} 157 158static llvm::Function * 159CreateGlobalInitOrDestructFunction(CodeGenModule &CGM, 160 const llvm::FunctionType *FTy, 161 llvm::StringRef Name) { 162 llvm::Function *Fn = 163 llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, 164 Name, &CGM.getModule()); 165 if (!CGM.getContext().getLangOptions().AppleKext) { 166 // Set the section if needed. 167 if (const char *Section = 168 CGM.getContext().Target.getStaticInitSectionSpecifier()) 169 Fn->setSection(Section); 170 } 171 172 if (!CGM.getLangOptions().Exceptions) 173 Fn->setDoesNotThrow(); 174 175 return Fn; 176} 177 178void 179CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 180 llvm::GlobalVariable *Addr) { 181 const llvm::FunctionType *FTy 182 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 183 false); 184 185 // Create a variable initialization function. 186 llvm::Function *Fn = 187 CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init"); 188 189 CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr); 190 191 if (D->hasAttr<InitPriorityAttr>()) { 192 unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority(); 193 OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size()); 194 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); 195 DelayedCXXInitPosition.erase(D); 196 } 197 else { 198 llvm::DenseMap<const Decl *, unsigned>::iterator I = 199 DelayedCXXInitPosition.find(D); 200 if (I == DelayedCXXInitPosition.end()) { 201 CXXGlobalInits.push_back(Fn); 202 } else { 203 assert(CXXGlobalInits[I->second] == 0); 204 CXXGlobalInits[I->second] = Fn; 205 DelayedCXXInitPosition.erase(I); 206 } 207 } 208} 209 210void 211CodeGenModule::EmitCXXGlobalInitFunc() { 212 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) 213 CXXGlobalInits.pop_back(); 214 215 if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()) 216 return; 217 218 const llvm::FunctionType *FTy 219 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 220 false); 221 222 // Create our global initialization function. 223 llvm::Function *Fn = 224 CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); 225 226 if (!PrioritizedCXXGlobalInits.empty()) { 227 llvm::SmallVector<llvm::Constant*, 8> LocalCXXGlobalInits; 228 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), 229 PrioritizedCXXGlobalInits.end()); 230 for (unsigned i = 0; i < PrioritizedCXXGlobalInits.size(); i++) { 231 llvm::Function *Fn = PrioritizedCXXGlobalInits[i].second; 232 LocalCXXGlobalInits.push_back(Fn); 233 } 234 LocalCXXGlobalInits.append(CXXGlobalInits.begin(), CXXGlobalInits.end()); 235 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 236 &LocalCXXGlobalInits[0], 237 LocalCXXGlobalInits.size()); 238 } 239 else 240 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, 241 &CXXGlobalInits[0], 242 CXXGlobalInits.size()); 243 AddGlobalCtor(Fn); 244 CXXGlobalInits.clear(); 245 PrioritizedCXXGlobalInits.clear(); 246} 247 248void CodeGenModule::EmitCXXGlobalDtorFunc() { 249 if (CXXGlobalDtors.empty()) 250 return; 251 252 const llvm::FunctionType *FTy 253 = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 254 false); 255 256 // Create our global destructor function. 257 llvm::Function *Fn = 258 CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a"); 259 260 CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors); 261 AddGlobalDtor(Fn); 262} 263 264/// Emit the code necessary to initialize the given global variable. 265void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, 266 const VarDecl *D, 267 llvm::GlobalVariable *Addr) { 268 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 269 getTypes().getNullaryFunctionInfo(), 270 FunctionArgList(), SourceLocation()); 271 272 // Use guarded initialization if the global variable is weak. This 273 // occurs for, e.g., instantiated static data members and 274 // definitions explicitly marked weak. 275 if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage || 276 Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) { 277 EmitCXXGuardedInit(*D, Addr); 278 } else { 279 EmitCXXGlobalVarDeclInit(*D, Addr); 280 } 281 282 FinishFunction(); 283} 284 285void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, 286 llvm::Constant **Decls, 287 unsigned NumDecls) { 288 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 289 getTypes().getNullaryFunctionInfo(), 290 FunctionArgList(), SourceLocation()); 291 292 RunCleanupsScope Scope(*this); 293 294 // When building in Objective-C++ ARC mode, create an autorelease pool 295 // around the global initializers. 296 if (getLangOptions().ObjCAutoRefCount && getLangOptions().CPlusPlus) { 297 llvm::Value *token = EmitObjCAutoreleasePoolPush(); 298 EmitObjCAutoreleasePoolCleanup(token); 299 } 300 301 for (unsigned i = 0; i != NumDecls; ++i) 302 if (Decls[i]) 303 Builder.CreateCall(Decls[i]); 304 305 Scope.ForceCleanup(); 306 307 FinishFunction(); 308} 309 310void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn, 311 const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> > 312 &DtorsAndObjects) { 313 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, 314 getTypes().getNullaryFunctionInfo(), 315 FunctionArgList(), SourceLocation()); 316 317 // Emit the dtors, in reverse order from construction. 318 for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) { 319 llvm::Value *Callee = DtorsAndObjects[e - i - 1].first; 320 llvm::CallInst *CI = Builder.CreateCall(Callee, 321 DtorsAndObjects[e - i - 1].second); 322 // Make sure the call and the callee agree on calling convention. 323 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) 324 CI->setCallingConv(F->getCallingConv()); 325 } 326 327 FinishFunction(); 328} 329 330/// GenerateCXXAggrDestructorHelper - Generates a helper function which when 331/// invoked, calls the default destructor on array elements in reverse order of 332/// construction. 333llvm::Function * 334CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, 335 const ArrayType *Array, 336 llvm::Value *This) { 337 FunctionArgList args; 338 ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy); 339 args.push_back(&dst); 340 341 const CGFunctionInfo &FI = 342 CGM.getTypes().getFunctionInfo(getContext().VoidTy, args, 343 FunctionType::ExtInfo()); 344 const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); 345 llvm::Function *Fn = 346 CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor"); 347 348 StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FI, args, 349 SourceLocation()); 350 351 QualType BaseElementTy = getContext().getBaseElementType(Array); 352 const llvm::Type *BasePtr = ConvertType(BaseElementTy)->getPointerTo(); 353 llvm::Value *BaseAddrPtr = Builder.CreateBitCast(This, BasePtr); 354 355 EmitCXXAggrDestructorCall(D, Array, BaseAddrPtr); 356 357 FinishFunction(); 358 359 return Fn; 360} 361