CGObjC.cpp revision 208600
1112158Sdas//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 2112158Sdas// 3112158Sdas// The LLVM Compiler Infrastructure 4112158Sdas// 5112158Sdas// This file is distributed under the University of Illinois Open Source 6112158Sdas// License. See LICENSE.TXT for details. 7112158Sdas// 8112158Sdas//===----------------------------------------------------------------------===// 9112158Sdas// 10112158Sdas// This contains code to emit Objective-C code as LLVM code. 11112158Sdas// 12112158Sdas//===----------------------------------------------------------------------===// 13112158Sdas 14112158Sdas#include "CGObjCRuntime.h" 15112158Sdas#include "CodeGenFunction.h" 16112158Sdas#include "CodeGenModule.h" 17112158Sdas#include "clang/AST/ASTContext.h" 18112158Sdas#include "clang/AST/DeclObjC.h" 19112158Sdas#include "clang/AST/StmtObjC.h" 20112158Sdas#include "clang/Basic/Diagnostic.h" 21112158Sdas#include "llvm/ADT/STLExtras.h" 22112158Sdas#include "llvm/Target/TargetData.h" 23112158Sdasusing namespace clang; 24112158Sdasusing namespace CodeGen; 25112158Sdas 26112158Sdas/// Emits an instance of NSConstantString representing the object. 27112158Sdasllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) 28112158Sdas{ 29165743Sdas llvm::Constant *C = 30165743Sdas CGM.getObjCRuntime().GenerateConstantString(E->getString()); 31112158Sdas // FIXME: This bitcast should just be made an invariant on the Runtime. 32112158Sdas return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); 33112158Sdas} 34112158Sdas 35112158Sdas/// Emit a selector. 36112158Sdasllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { 37112158Sdas // Untyped selector. 38112158Sdas // Note that this implementation allows for non-constant strings to be passed 39112158Sdas // as arguments to @selector(). Currently, the only thing preventing this 40112158Sdas // behaviour is the type checking in the front end. 41112158Sdas return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector()); 42112158Sdas} 43112158Sdas 44112158Sdasllvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { 45112158Sdas // FIXME: This should pass the Decl not the name. 46112158Sdas return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol()); 47112158Sdas} 48112158Sdas 49219557Sdas 50112158SdasRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E, 51112158Sdas ReturnValueSlot Return) { 52112158Sdas // Only the lookup mechanism and first two arguments of the method 53112158Sdas // implementation vary between runtimes. We can get the receiver and 54112158Sdas // arguments in generic code. 55112158Sdas 56112158Sdas CGObjCRuntime &Runtime = CGM.getObjCRuntime(); 57112158Sdas bool isSuperMessage = false; 58112158Sdas bool isClassMessage = false; 59112158Sdas ObjCInterfaceDecl *OID = 0; 60112158Sdas // Find the receiver 61165743Sdas llvm::Value *Receiver = 0; 62112158Sdas switch (E->getReceiverKind()) { 63112158Sdas case ObjCMessageExpr::Instance: 64112158Sdas Receiver = EmitScalarExpr(E->getInstanceReceiver()); 65112158Sdas break; 66112158Sdas 67112158Sdas case ObjCMessageExpr::Class: { 68112158Sdas const ObjCObjectType *ObjTy 69112158Sdas = E->getClassReceiver()->getAs<ObjCObjectType>(); 70112158Sdas assert(ObjTy && "Invalid Objective-C class message send"); 71112158Sdas OID = ObjTy->getInterface(); 72112158Sdas assert(OID && "Invalid Objective-C class message send"); 73112158Sdas Receiver = Runtime.GetClass(Builder, OID); 74112158Sdas isClassMessage = true; 75112158Sdas break; 76112158Sdas } 77112158Sdas 78112158Sdas case ObjCMessageExpr::SuperInstance: 79112158Sdas Receiver = LoadObjCSelf(); 80112158Sdas isSuperMessage = true; 81112158Sdas break; 82112158Sdas 83112158Sdas case ObjCMessageExpr::SuperClass: 84112158Sdas Receiver = LoadObjCSelf(); 85112158Sdas isSuperMessage = true; 86112158Sdas isClassMessage = true; 87112158Sdas break; 88112158Sdas } 89112158Sdas 90 CallArgList Args; 91 EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end()); 92 93 if (isSuperMessage) { 94 // super is only valid in an Objective-C method 95 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 96 bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); 97 return Runtime.GenerateMessageSendSuper(*this, Return, E->getType(), 98 E->getSelector(), 99 OMD->getClassInterface(), 100 isCategoryImpl, 101 Receiver, 102 isClassMessage, 103 Args, 104 E->getMethodDecl()); 105 } 106 107 return Runtime.GenerateMessageSend(*this, Return, E->getType(), 108 E->getSelector(), 109 Receiver, Args, OID, 110 E->getMethodDecl()); 111} 112 113/// StartObjCMethod - Begin emission of an ObjCMethod. This generates 114/// the LLVM function and sets the other context used by 115/// CodeGenFunction. 116void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD, 117 const ObjCContainerDecl *CD) { 118 FunctionArgList Args; 119 // Check if we should generate debug info for this method. 120 if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>()) 121 DebugInfo = CGM.getDebugInfo(); 122 123 llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD); 124 125 const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD); 126 CGM.SetInternalFunctionAttributes(OMD, Fn, FI); 127 128 Args.push_back(std::make_pair(OMD->getSelfDecl(), 129 OMD->getSelfDecl()->getType())); 130 Args.push_back(std::make_pair(OMD->getCmdDecl(), 131 OMD->getCmdDecl()->getType())); 132 133 for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 134 E = OMD->param_end(); PI != E; ++PI) 135 Args.push_back(std::make_pair(*PI, (*PI)->getType())); 136 137 StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocStart()); 138} 139 140/// Generate an Objective-C method. An Objective-C method is a C function with 141/// its pointer, name, and types registered in the class struture. 142void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { 143 StartObjCMethod(OMD, OMD->getClassInterface()); 144 EmitStmt(OMD->getBody()); 145 FinishFunction(OMD->getBodyRBrace()); 146} 147 148// FIXME: I wasn't sure about the synthesis approach. If we end up generating an 149// AST for the whole body we can just fall back to having a GenerateFunction 150// which takes the body Stmt. 151 152/// GenerateObjCGetter - Generate an Objective-C property getter 153/// function. The given Decl must be an ObjCImplementationDecl. @synthesize 154/// is illegal within a category. 155void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, 156 const ObjCPropertyImplDecl *PID) { 157 ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 158 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 159 bool IsAtomic = 160 !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic); 161 ObjCMethodDecl *OMD = PD->getGetterMethodDecl(); 162 assert(OMD && "Invalid call to generate getter (empty method)"); 163 StartObjCMethod(OMD, IMP->getClassInterface()); 164 165 // Determine if we should use an objc_getProperty call for 166 // this. Non-atomic properties are directly evaluated. 167 // atomic 'copy' and 'retain' properties are also directly 168 // evaluated in gc-only mode. 169 if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly && 170 IsAtomic && 171 (PD->getSetterKind() == ObjCPropertyDecl::Copy || 172 PD->getSetterKind() == ObjCPropertyDecl::Retain)) { 173 llvm::Value *GetPropertyFn = 174 CGM.getObjCRuntime().GetPropertyGetFunction(); 175 176 if (!GetPropertyFn) { 177 CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy"); 178 FinishFunction(); 179 return; 180 } 181 182 // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true). 183 // FIXME: Can't this be simpler? This might even be worse than the 184 // corresponding gcc code. 185 CodeGenTypes &Types = CGM.getTypes(); 186 ValueDecl *Cmd = OMD->getCmdDecl(); 187 llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd"); 188 QualType IdTy = getContext().getObjCIdType(); 189 llvm::Value *SelfAsId = 190 Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy)); 191 llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar); 192 llvm::Value *True = 193 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1); 194 CallArgList Args; 195 Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy)); 196 Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); 197 Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy)); 198 Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); 199 // FIXME: We shouldn't need to get the function info here, the 200 // runtime already should have computed it to build the function. 201 RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args, 202 FunctionType::ExtInfo()), 203 GetPropertyFn, ReturnValueSlot(), Args); 204 // We need to fix the type here. Ivars with copy & retain are 205 // always objects so we don't need to worry about complex or 206 // aggregates. 207 RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(), 208 Types.ConvertType(PD->getType()))); 209 EmitReturnOfRValue(RV, PD->getType()); 210 } else { 211 if (Ivar->getType()->isAnyComplexType()) { 212 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 213 Ivar, 0); 214 ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(), 215 LV.isVolatileQualified()); 216 StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified()); 217 } 218 else if (hasAggregateLLVMType(Ivar->getType())) { 219 bool IsStrong = false; 220 if ((IsAtomic || (IsStrong = IvarTypeWithAggrGCObjects(Ivar->getType()))) 221 && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect 222 && CGM.getObjCRuntime().GetCopyStructFunction()) { 223 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 224 Ivar, 0); 225 llvm::Value *GetCopyStructFn = 226 CGM.getObjCRuntime().GetCopyStructFunction(); 227 CodeGenTypes &Types = CGM.getTypes(); 228 // objc_copyStruct (ReturnValue, &structIvar, 229 // sizeof (Type of Ivar), isAtomic, false); 230 CallArgList Args; 231 RValue RV = RValue::get(Builder.CreateBitCast(ReturnValue, 232 Types.ConvertType(getContext().VoidPtrTy))); 233 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 234 RV = RValue::get(Builder.CreateBitCast(LV.getAddress(), 235 Types.ConvertType(getContext().VoidPtrTy))); 236 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 237 // sizeof (Type of Ivar) 238 uint64_t Size = getContext().getTypeSize(Ivar->getType()) / 8; 239 llvm::Value *SizeVal = 240 llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), Size); 241 Args.push_back(std::make_pair(RValue::get(SizeVal), 242 getContext().LongTy)); 243 llvm::Value *isAtomic = 244 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 245 IsAtomic ? 1 : 0); 246 Args.push_back(std::make_pair(RValue::get(isAtomic), 247 getContext().BoolTy)); 248 llvm::Value *hasStrong = 249 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 250 IsStrong ? 1 : 0); 251 Args.push_back(std::make_pair(RValue::get(hasStrong), 252 getContext().BoolTy)); 253 EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, 254 FunctionType::ExtInfo()), 255 GetCopyStructFn, ReturnValueSlot(), Args); 256 } 257 else { 258 if (PID->getGetterCXXConstructor()) { 259 ReturnStmt *Stmt = 260 new (getContext()) ReturnStmt(SourceLocation(), 261 PID->getGetterCXXConstructor(), 262 0); 263 EmitReturnStmt(*Stmt); 264 } 265 else { 266 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 267 Ivar, 0); 268 EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType()); 269 } 270 } 271 } else { 272 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 273 Ivar, 0); 274 CodeGenTypes &Types = CGM.getTypes(); 275 RValue RV = EmitLoadOfLValue(LV, Ivar->getType()); 276 RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(), 277 Types.ConvertType(PD->getType()))); 278 EmitReturnOfRValue(RV, PD->getType()); 279 } 280 } 281 282 FinishFunction(); 283} 284 285/// GenerateObjCSetter - Generate an Objective-C property setter 286/// function. The given Decl must be an ObjCImplementationDecl. @synthesize 287/// is illegal within a category. 288void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, 289 const ObjCPropertyImplDecl *PID) { 290 ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 291 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 292 ObjCMethodDecl *OMD = PD->getSetterMethodDecl(); 293 assert(OMD && "Invalid call to generate setter (empty method)"); 294 StartObjCMethod(OMD, IMP->getClassInterface()); 295 296 bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy; 297 bool IsAtomic = 298 !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic); 299 300 // Determine if we should use an objc_setProperty call for 301 // this. Properties with 'copy' semantics always use it, as do 302 // non-atomic properties with 'release' semantics as long as we are 303 // not in gc-only mode. 304 if (IsCopy || 305 (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly && 306 PD->getSetterKind() == ObjCPropertyDecl::Retain)) { 307 llvm::Value *SetPropertyFn = 308 CGM.getObjCRuntime().GetPropertySetFunction(); 309 310 if (!SetPropertyFn) { 311 CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy"); 312 FinishFunction(); 313 return; 314 } 315 316 // Emit objc_setProperty((id) self, _cmd, offset, arg, 317 // <is-atomic>, <is-copy>). 318 // FIXME: Can't this be simpler? This might even be worse than the 319 // corresponding gcc code. 320 CodeGenTypes &Types = CGM.getTypes(); 321 ValueDecl *Cmd = OMD->getCmdDecl(); 322 llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd"); 323 QualType IdTy = getContext().getObjCIdType(); 324 llvm::Value *SelfAsId = 325 Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy)); 326 llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar); 327 llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()]; 328 llvm::Value *ArgAsId = 329 Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"), 330 Types.ConvertType(IdTy)); 331 llvm::Value *True = 332 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1); 333 llvm::Value *False = 334 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0); 335 CallArgList Args; 336 Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy)); 337 Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); 338 Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy)); 339 Args.push_back(std::make_pair(RValue::get(ArgAsId), IdTy)); 340 Args.push_back(std::make_pair(RValue::get(IsAtomic ? True : False), 341 getContext().BoolTy)); 342 Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False), 343 getContext().BoolTy)); 344 // FIXME: We shouldn't need to get the function info here, the runtime 345 // already should have computed it to build the function. 346 EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, 347 FunctionType::ExtInfo()), 348 SetPropertyFn, 349 ReturnValueSlot(), Args); 350 } else if (IsAtomic && hasAggregateLLVMType(Ivar->getType()) && 351 !Ivar->getType()->isAnyComplexType() && 352 IndirectObjCSetterArg(*CurFnInfo) 353 && CGM.getObjCRuntime().GetCopyStructFunction()) { 354 // objc_copyStruct (&structIvar, &Arg, 355 // sizeof (struct something), true, false); 356 llvm::Value *GetCopyStructFn = 357 CGM.getObjCRuntime().GetCopyStructFunction(); 358 CodeGenTypes &Types = CGM.getTypes(); 359 CallArgList Args; 360 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0); 361 RValue RV = RValue::get(Builder.CreateBitCast(LV.getAddress(), 362 Types.ConvertType(getContext().VoidPtrTy))); 363 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 364 llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()]; 365 llvm::Value *ArgAsPtrTy = 366 Builder.CreateBitCast(Arg, 367 Types.ConvertType(getContext().VoidPtrTy)); 368 RV = RValue::get(ArgAsPtrTy); 369 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 370 // sizeof (Type of Ivar) 371 uint64_t Size = getContext().getTypeSize(Ivar->getType()) / 8; 372 llvm::Value *SizeVal = 373 llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), Size); 374 Args.push_back(std::make_pair(RValue::get(SizeVal), 375 getContext().LongTy)); 376 llvm::Value *True = 377 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1); 378 Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); 379 llvm::Value *False = 380 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0); 381 Args.push_back(std::make_pair(RValue::get(False), getContext().BoolTy)); 382 EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, 383 FunctionType::ExtInfo()), 384 GetCopyStructFn, ReturnValueSlot(), Args); 385 } else if (PID->getSetterCXXAssignment()) { 386 EmitAnyExpr(PID->getSetterCXXAssignment(), (llvm::Value *)0, false, true, 387 false); 388 389 } else { 390 // FIXME: Find a clean way to avoid AST node creation. 391 SourceLocation Loc = PD->getLocation(); 392 ValueDecl *Self = OMD->getSelfDecl(); 393 ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 394 DeclRefExpr Base(Self, Self->getType(), Loc); 395 ParmVarDecl *ArgDecl = *OMD->param_begin(); 396 DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc); 397 ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true); 398 399 // The property type can differ from the ivar type in some situations with 400 // Objective-C pointer types, we can always bit cast the RHS in these cases. 401 if (getContext().getCanonicalType(Ivar->getType()) != 402 getContext().getCanonicalType(ArgDecl->getType())) { 403 ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg, 404 CXXBaseSpecifierArray(), false); 405 BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign, 406 Ivar->getType(), Loc); 407 EmitStmt(&Assign); 408 } else { 409 BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign, 410 Ivar->getType(), Loc); 411 EmitStmt(&Assign); 412 } 413 } 414 415 FinishFunction(); 416} 417 418void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, 419 ObjCMethodDecl *MD, 420 bool ctor) { 421 llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> IvarInitializers; 422 MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface()); 423 StartObjCMethod(MD, IMP->getClassInterface()); 424 for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(), 425 E = IMP->init_end(); B != E; ++B) { 426 CXXBaseOrMemberInitializer *Member = (*B); 427 IvarInitializers.push_back(Member); 428 } 429 if (ctor) { 430 for (unsigned I = 0, E = IvarInitializers.size(); I != E; ++I) { 431 CXXBaseOrMemberInitializer *IvarInit = IvarInitializers[I]; 432 FieldDecl *Field = IvarInit->getMember(); 433 QualType FieldType = Field->getType(); 434 ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field); 435 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), 436 LoadObjCSelf(), Ivar, 0); 437 EmitAggExpr(IvarInit->getInit(), LV.getAddress(), 438 LV.isVolatileQualified(), false, true); 439 } 440 // constructor returns 'self'. 441 CodeGenTypes &Types = CGM.getTypes(); 442 QualType IdTy(CGM.getContext().getObjCIdType()); 443 llvm::Value *SelfAsId = 444 Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy)); 445 EmitReturnOfRValue(RValue::get(SelfAsId), IdTy); 446 } else { 447 // dtor 448 for (size_t i = IvarInitializers.size(); i > 0; --i) { 449 FieldDecl *Field = IvarInitializers[i - 1]->getMember(); 450 QualType FieldType = Field->getType(); 451 const ConstantArrayType *Array = 452 getContext().getAsConstantArrayType(FieldType); 453 if (Array) 454 FieldType = getContext().getBaseElementType(FieldType); 455 456 ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field); 457 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), 458 LoadObjCSelf(), Ivar, 0); 459 const RecordType *RT = FieldType->getAs<RecordType>(); 460 CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 461 CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(getContext()); 462 if (!Dtor->isTrivial()) { 463 if (Array) { 464 const llvm::Type *BasePtr = ConvertType(FieldType); 465 BasePtr = llvm::PointerType::getUnqual(BasePtr); 466 llvm::Value *BaseAddrPtr = 467 Builder.CreateBitCast(LV.getAddress(), BasePtr); 468 EmitCXXAggrDestructorCall(Dtor, 469 Array, BaseAddrPtr); 470 } else { 471 EmitCXXDestructorCall(Dtor, 472 Dtor_Complete, /*ForVirtualBase=*/false, 473 LV.getAddress()); 474 } 475 } 476 } 477 } 478 FinishFunction(); 479} 480 481bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) { 482 CGFunctionInfo::const_arg_iterator it = FI.arg_begin(); 483 it++; it++; 484 const ABIArgInfo &AI = it->info; 485 // FIXME. Is this sufficient check? 486 return (AI.getKind() == ABIArgInfo::Indirect); 487} 488 489bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) { 490 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC) 491 return false; 492 if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>()) 493 return FDTTy->getDecl()->hasObjectMember(); 494 return false; 495} 496 497llvm::Value *CodeGenFunction::LoadObjCSelf() { 498 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 499 return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self"); 500} 501 502QualType CodeGenFunction::TypeOfSelfObject() { 503 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 504 ImplicitParamDecl *selfDecl = OMD->getSelfDecl(); 505 const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>( 506 getContext().getCanonicalType(selfDecl->getType())); 507 return PTy->getPointeeType(); 508} 509 510RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp, 511 const Selector &S, 512 ReturnValueSlot Return) { 513 llvm::Value *Receiver = LoadObjCSelf(); 514 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 515 bool isClassMessage = OMD->isClassMethod(); 516 bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); 517 return CGM.getObjCRuntime().GenerateMessageSendSuper(*this, 518 Return, 519 Exp->getType(), 520 S, 521 OMD->getClassInterface(), 522 isCategoryImpl, 523 Receiver, 524 isClassMessage, 525 CallArgList()); 526 527} 528 529RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp, 530 ReturnValueSlot Return) { 531 Exp = Exp->IgnoreParens(); 532 // FIXME: Split it into two separate routines. 533 if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) { 534 Selector S = E->getProperty()->getGetterName(); 535 if (isa<ObjCSuperExpr>(E->getBase())) 536 return EmitObjCSuperPropertyGet(E, S, Return); 537 return CGM.getObjCRuntime(). 538 GenerateMessageSend(*this, Return, Exp->getType(), S, 539 EmitScalarExpr(E->getBase()), 540 CallArgList()); 541 } else { 542 const ObjCImplicitSetterGetterRefExpr *KE = 543 cast<ObjCImplicitSetterGetterRefExpr>(Exp); 544 Selector S = KE->getGetterMethod()->getSelector(); 545 llvm::Value *Receiver; 546 if (KE->getInterfaceDecl()) { 547 const ObjCInterfaceDecl *OID = KE->getInterfaceDecl(); 548 Receiver = CGM.getObjCRuntime().GetClass(Builder, OID); 549 } else if (isa<ObjCSuperExpr>(KE->getBase())) 550 return EmitObjCSuperPropertyGet(KE, S, Return); 551 else 552 Receiver = EmitScalarExpr(KE->getBase()); 553 return CGM.getObjCRuntime(). 554 GenerateMessageSend(*this, Return, Exp->getType(), S, 555 Receiver, 556 CallArgList(), KE->getInterfaceDecl()); 557 } 558} 559 560void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp, 561 const Selector &S, 562 RValue Src) { 563 CallArgList Args; 564 llvm::Value *Receiver = LoadObjCSelf(); 565 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 566 bool isClassMessage = OMD->isClassMethod(); 567 bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); 568 Args.push_back(std::make_pair(Src, Exp->getType())); 569 CGM.getObjCRuntime().GenerateMessageSendSuper(*this, 570 ReturnValueSlot(), 571 Exp->getType(), 572 S, 573 OMD->getClassInterface(), 574 isCategoryImpl, 575 Receiver, 576 isClassMessage, 577 Args); 578 return; 579} 580 581void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp, 582 RValue Src) { 583 // FIXME: Split it into two separate routines. 584 if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) { 585 Selector S = E->getProperty()->getSetterName(); 586 if (isa<ObjCSuperExpr>(E->getBase())) { 587 EmitObjCSuperPropertySet(E, S, Src); 588 return; 589 } 590 CallArgList Args; 591 Args.push_back(std::make_pair(Src, E->getType())); 592 CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), 593 getContext().VoidTy, S, 594 EmitScalarExpr(E->getBase()), 595 Args); 596 } else if (const ObjCImplicitSetterGetterRefExpr *E = 597 dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) { 598 Selector S = E->getSetterMethod()->getSelector(); 599 CallArgList Args; 600 llvm::Value *Receiver; 601 if (E->getInterfaceDecl()) { 602 const ObjCInterfaceDecl *OID = E->getInterfaceDecl(); 603 Receiver = CGM.getObjCRuntime().GetClass(Builder, OID); 604 } else if (isa<ObjCSuperExpr>(E->getBase())) { 605 EmitObjCSuperPropertySet(E, S, Src); 606 return; 607 } else 608 Receiver = EmitScalarExpr(E->getBase()); 609 Args.push_back(std::make_pair(Src, E->getType())); 610 CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), 611 getContext().VoidTy, S, 612 Receiver, 613 Args, E->getInterfaceDecl()); 614 } else 615 assert (0 && "bad expression node in EmitObjCPropertySet"); 616} 617 618void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ 619 llvm::Constant *EnumerationMutationFn = 620 CGM.getObjCRuntime().EnumerationMutationFunction(); 621 llvm::Value *DeclAddress; 622 QualType ElementTy; 623 624 if (!EnumerationMutationFn) { 625 CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime"); 626 return; 627 } 628 629 if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) { 630 EmitStmt(SD); 631 assert(HaveInsertPoint() && "DeclStmt destroyed insert point!"); 632 const Decl* D = SD->getSingleDecl(); 633 ElementTy = cast<ValueDecl>(D)->getType(); 634 DeclAddress = LocalDeclMap[D]; 635 } else { 636 ElementTy = cast<Expr>(S.getElement())->getType(); 637 DeclAddress = 0; 638 } 639 640 // Fast enumeration state. 641 QualType StateTy = getContext().getObjCFastEnumerationStateType(); 642 llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr"); 643 EmitNullInitialization(StatePtr, StateTy); 644 645 // Number of elements in the items array. 646 static const unsigned NumItems = 16; 647 648 // Get selector 649 IdentifierInfo *II[] = { 650 &CGM.getContext().Idents.get("countByEnumeratingWithState"), 651 &CGM.getContext().Idents.get("objects"), 652 &CGM.getContext().Idents.get("count") 653 }; 654 Selector FastEnumSel = 655 CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]); 656 657 QualType ItemsTy = 658 getContext().getConstantArrayType(getContext().getObjCIdType(), 659 llvm::APInt(32, NumItems), 660 ArrayType::Normal, 0); 661 llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr"); 662 663 llvm::Value *Collection = EmitScalarExpr(S.getCollection()); 664 665 CallArgList Args; 666 Args.push_back(std::make_pair(RValue::get(StatePtr), 667 getContext().getPointerType(StateTy))); 668 669 Args.push_back(std::make_pair(RValue::get(ItemsPtr), 670 getContext().getPointerType(ItemsTy))); 671 672 const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy); 673 llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems); 674 Args.push_back(std::make_pair(RValue::get(Count), 675 getContext().UnsignedLongTy)); 676 677 RValue CountRV = 678 CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), 679 getContext().UnsignedLongTy, 680 FastEnumSel, 681 Collection, Args); 682 683 llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy, 684 "limit.ptr"); 685 Builder.CreateStore(CountRV.getScalarVal(), LimitPtr); 686 687 llvm::BasicBlock *NoElements = createBasicBlock("noelements"); 688 llvm::BasicBlock *SetStartMutations = createBasicBlock("setstartmutations"); 689 690 llvm::Value *Limit = Builder.CreateLoad(LimitPtr); 691 llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy); 692 693 llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero"); 694 Builder.CreateCondBr(IsZero, NoElements, SetStartMutations); 695 696 EmitBlock(SetStartMutations); 697 698 llvm::Value *StartMutationsPtr = CreateMemTemp(getContext().UnsignedLongTy); 699 700 llvm::Value *StateMutationsPtrPtr = 701 Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr"); 702 llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, 703 "mutationsptr"); 704 705 llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr, 706 "mutations"); 707 708 Builder.CreateStore(StateMutations, StartMutationsPtr); 709 710 llvm::BasicBlock *LoopStart = createBasicBlock("loopstart"); 711 EmitBlock(LoopStart); 712 713 llvm::Value *CounterPtr = CreateMemTemp(getContext().UnsignedLongTy, 714 "counter.ptr"); 715 Builder.CreateStore(Zero, CounterPtr); 716 717 llvm::BasicBlock *LoopBody = createBasicBlock("loopbody"); 718 EmitBlock(LoopBody); 719 720 StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); 721 StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations"); 722 723 llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr, 724 "mutations"); 725 llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations, 726 StartMutations, 727 "tobool"); 728 729 730 llvm::BasicBlock *WasMutated = createBasicBlock("wasmutated"); 731 llvm::BasicBlock *WasNotMutated = createBasicBlock("wasnotmutated"); 732 733 Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated); 734 735 EmitBlock(WasMutated); 736 llvm::Value *V = 737 Builder.CreateBitCast(Collection, 738 ConvertType(getContext().getObjCIdType()), 739 "tmp"); 740 CallArgList Args2; 741 Args2.push_back(std::make_pair(RValue::get(V), 742 getContext().getObjCIdType())); 743 // FIXME: We shouldn't need to get the function info here, the runtime already 744 // should have computed it to build the function. 745 EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2, 746 FunctionType::ExtInfo()), 747 EnumerationMutationFn, ReturnValueSlot(), Args2); 748 749 EmitBlock(WasNotMutated); 750 751 llvm::Value *StateItemsPtr = 752 Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr"); 753 754 llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter"); 755 756 llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr, 757 "stateitems"); 758 759 llvm::Value *CurrentItemPtr = 760 Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr"); 761 762 llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem"); 763 764 // Cast the item to the right type. 765 CurrentItem = Builder.CreateBitCast(CurrentItem, 766 ConvertType(ElementTy), "tmp"); 767 768 if (!DeclAddress) { 769 LValue LV = EmitLValue(cast<Expr>(S.getElement())); 770 771 // Set the value to null. 772 Builder.CreateStore(CurrentItem, LV.getAddress()); 773 } else 774 Builder.CreateStore(CurrentItem, DeclAddress); 775 776 // Increment the counter. 777 Counter = Builder.CreateAdd(Counter, 778 llvm::ConstantInt::get(UnsignedLongLTy, 1)); 779 Builder.CreateStore(Counter, CounterPtr); 780 781 llvm::BasicBlock *LoopEnd = createBasicBlock("loopend"); 782 llvm::BasicBlock *AfterBody = createBasicBlock("afterbody"); 783 784 BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody)); 785 786 EmitStmt(S.getBody()); 787 788 BreakContinueStack.pop_back(); 789 790 EmitBlock(AfterBody); 791 792 llvm::BasicBlock *FetchMore = createBasicBlock("fetchmore"); 793 794 Counter = Builder.CreateLoad(CounterPtr); 795 Limit = Builder.CreateLoad(LimitPtr); 796 llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless"); 797 Builder.CreateCondBr(IsLess, LoopBody, FetchMore); 798 799 // Fetch more elements. 800 EmitBlock(FetchMore); 801 802 CountRV = 803 CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), 804 getContext().UnsignedLongTy, 805 FastEnumSel, 806 Collection, Args); 807 Builder.CreateStore(CountRV.getScalarVal(), LimitPtr); 808 Limit = Builder.CreateLoad(LimitPtr); 809 810 IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero"); 811 Builder.CreateCondBr(IsZero, NoElements, LoopStart); 812 813 // No more elements. 814 EmitBlock(NoElements); 815 816 if (!DeclAddress) { 817 // If the element was not a declaration, set it to be null. 818 819 LValue LV = EmitLValue(cast<Expr>(S.getElement())); 820 821 // Set the value to null. 822 Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)), 823 LV.getAddress()); 824 } 825 826 EmitBlock(LoopEnd); 827} 828 829void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) { 830 CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S); 831} 832 833void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) { 834 CGM.getObjCRuntime().EmitThrowStmt(*this, S); 835} 836 837void CodeGenFunction::EmitObjCAtSynchronizedStmt( 838 const ObjCAtSynchronizedStmt &S) { 839 CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S); 840} 841 842CGObjCRuntime::~CGObjCRuntime() {} 843