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