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 "CGDebugInfo.h" 15 #include "CGObjCRuntime.h" 16 #include "CodeGenFunction.h" 17 #include "CodeGenModule.h" 18 #include "clang/AST/ASTContext.h" 19 #include "clang/AST/DeclObjC.h" 20 #include "clang/AST/StmtObjC.h" 21 #include "clang/Basic/Diagnostic.h" 22 #include "llvm/ADT/STLExtras.h" 23 #include "llvm/Target/TargetData.h" 24 using namespace clang; 25 using namespace CodeGen; 26 27 /// Emits an instance of NSConstantString representing the object. 28 llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) 29 { 30 llvm::Constant *C = 31 CGM.getObjCRuntime().GenerateConstantString(E->getString()); 32 // FIXME: This bitcast should just be made an invariant on the Runtime. 33 return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); 34 } 35 36 /// Emit a selector. 37 llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) { 38 // Untyped selector. 39 // Note that this implementation allows for non-constant strings to be passed 40 // as arguments to @selector(). Currently, the only thing preventing this 41 // behaviour is the type checking in the front end. 42 return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector()); 43 } 44 45 llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) { 46 // FIXME: This should pass the Decl not the name. 47 return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol()); 48 } 49 50 51 RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E, 52 ReturnValueSlot Return) { 53 // Only the lookup mechanism and first two arguments of the method 54 // implementation vary between runtimes. We can get the receiver and 55 // arguments in generic code. 56 57 CGObjCRuntime &Runtime = CGM.getObjCRuntime(); 58 bool isSuperMessage = false; 59 bool isClassMessage = false; 60 ObjCInterfaceDecl *OID = 0; 61 // Find the receiver 62 llvm::Value *Receiver = 0; 63 switch (E->getReceiverKind()) { 64 case ObjCMessageExpr::Instance: 65 Receiver = EmitScalarExpr(E->getInstanceReceiver()); 66 break; 67 68 case ObjCMessageExpr::Class: { 69 const ObjCObjectType *ObjTy 70 = E->getClassReceiver()->getAs<ObjCObjectType>(); 71 assert(ObjTy && "Invalid Objective-C class message send"); 72 OID = ObjTy->getInterface(); 73 assert(OID && "Invalid Objective-C class message send"); 74 Receiver = Runtime.GetClass(Builder, OID); 75 isClassMessage = true; 76 break; 77 } 78 79 case ObjCMessageExpr::SuperInstance: 80 Receiver = LoadObjCSelf(); 81 isSuperMessage = true; 82 break; 83 84 case ObjCMessageExpr::SuperClass: 85 Receiver = LoadObjCSelf(); 86 isSuperMessage = true; 87 isClassMessage = true; 88 break; 89 } 90 91 CallArgList Args; 92 EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end()); 93 94 QualType ResultType = 95 E->getMethodDecl() ? E->getMethodDecl()->getResultType() : E->getType(); 96 97 if (isSuperMessage) { 98 // super is only valid in an Objective-C method 99 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 100 bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); 101 return Runtime.GenerateMessageSendSuper(*this, Return, ResultType, 102 E->getSelector(), 103 OMD->getClassInterface(), 104 isCategoryImpl, 105 Receiver, 106 isClassMessage, 107 Args, 108 E->getMethodDecl()); 109 } 110 111 return Runtime.GenerateMessageSend(*this, Return, ResultType, 112 E->getSelector(), 113 Receiver, Args, OID, 114 E->getMethodDecl()); 115 } 116 117 /// StartObjCMethod - Begin emission of an ObjCMethod. This generates 118 /// the LLVM function and sets the other context used by 119 /// CodeGenFunction. 120 void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD, 121 const ObjCContainerDecl *CD) { 122 FunctionArgList args; 123 // Check if we should generate debug info for this method. 124 if (CGM.getModuleDebugInfo() && !OMD->hasAttr<NoDebugAttr>()) 125 DebugInfo = CGM.getModuleDebugInfo(); 126 127 llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD); 128 129 const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD); 130 CGM.SetInternalFunctionAttributes(OMD, Fn, FI); 131 132 args.push_back(OMD->getSelfDecl()); 133 args.push_back(OMD->getCmdDecl()); 134 135 for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 136 E = OMD->param_end(); PI != E; ++PI) 137 args.push_back(*PI); 138 139 CurGD = OMD; 140 141 StartFunction(OMD, OMD->getResultType(), Fn, FI, args, OMD->getLocStart()); 142 } 143 144 void CodeGenFunction::GenerateObjCGetterBody(ObjCIvarDecl *Ivar, 145 bool IsAtomic, bool IsStrong) { 146 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 147 Ivar, 0); 148 llvm::Value *GetCopyStructFn = 149 CGM.getObjCRuntime().GetGetStructFunction(); 150 CodeGenTypes &Types = CGM.getTypes(); 151 // objc_copyStruct (ReturnValue, &structIvar, 152 // sizeof (Type of Ivar), isAtomic, false); 153 CallArgList Args; 154 RValue RV = RValue::get(Builder.CreateBitCast(ReturnValue, 155 Types.ConvertType(getContext().VoidPtrTy))); 156 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 157 RV = RValue::get(Builder.CreateBitCast(LV.getAddress(), 158 Types.ConvertType(getContext().VoidPtrTy))); 159 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 160 // sizeof (Type of Ivar) 161 CharUnits Size = getContext().getTypeSizeInChars(Ivar->getType()); 162 llvm::Value *SizeVal = 163 llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), 164 Size.getQuantity()); 165 Args.push_back(std::make_pair(RValue::get(SizeVal), 166 getContext().LongTy)); 167 llvm::Value *isAtomic = 168 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 169 IsAtomic ? 1 : 0); 170 Args.push_back(std::make_pair(RValue::get(isAtomic), 171 getContext().BoolTy)); 172 llvm::Value *hasStrong = 173 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 174 IsStrong ? 1 : 0); 175 Args.push_back(std::make_pair(RValue::get(hasStrong), 176 getContext().BoolTy)); 177 EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, 178 FunctionType::ExtInfo()), 179 GetCopyStructFn, ReturnValueSlot(), Args); 180 } 181 182 /// Generate an Objective-C method. An Objective-C method is a C function with 183 /// its pointer, name, and types registered in the class struture. 184 void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) { 185 StartObjCMethod(OMD, OMD->getClassInterface()); 186 EmitStmt(OMD->getBody()); 187 FinishFunction(OMD->getBodyRBrace()); 188 } 189 190 // FIXME: I wasn't sure about the synthesis approach. If we end up generating an 191 // AST for the whole body we can just fall back to having a GenerateFunction 192 // which takes the body Stmt. 193 194 /// GenerateObjCGetter - Generate an Objective-C property getter 195 /// function. The given Decl must be an ObjCImplementationDecl. @synthesize 196 /// is illegal within a category. 197 void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, 198 const ObjCPropertyImplDecl *PID) { 199 ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 200 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 201 bool IsAtomic = 202 !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic); 203 ObjCMethodDecl *OMD = PD->getGetterMethodDecl(); 204 assert(OMD && "Invalid call to generate getter (empty method)"); 205 StartObjCMethod(OMD, IMP->getClassInterface()); 206 207 // Determine if we should use an objc_getProperty call for 208 // this. Non-atomic properties are directly evaluated. 209 // atomic 'copy' and 'retain' properties are also directly 210 // evaluated in gc-only mode. 211 if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly && 212 IsAtomic && 213 (PD->getSetterKind() == ObjCPropertyDecl::Copy || 214 PD->getSetterKind() == ObjCPropertyDecl::Retain)) { 215 llvm::Value *GetPropertyFn = 216 CGM.getObjCRuntime().GetPropertyGetFunction(); 217 218 if (!GetPropertyFn) { 219 CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy"); 220 FinishFunction(); 221 return; 222 } 223 224 // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true). 225 // FIXME: Can't this be simpler? This might even be worse than the 226 // corresponding gcc code. 227 CodeGenTypes &Types = CGM.getTypes(); 228 ValueDecl *Cmd = OMD->getCmdDecl(); 229 llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd"); 230 QualType IdTy = getContext().getObjCIdType(); 231 llvm::Value *SelfAsId = 232 Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy)); 233 llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar); 234 llvm::Value *True = 235 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1); 236 CallArgList Args; 237 Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy)); 238 Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); 239 Args.push_back(std::make_pair(RValue::get(Offset), 240 getContext().getPointerDiffType())); 241 Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); 242 // FIXME: We shouldn't need to get the function info here, the 243 // runtime already should have computed it to build the function. 244 RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args, 245 FunctionType::ExtInfo()), 246 GetPropertyFn, ReturnValueSlot(), Args); 247 // We need to fix the type here. Ivars with copy & retain are 248 // always objects so we don't need to worry about complex or 249 // aggregates. 250 RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(), 251 Types.ConvertType(PD->getType()))); 252 EmitReturnOfRValue(RV, PD->getType()); 253 } else { 254 const llvm::Triple &Triple = getContext().Target.getTriple(); 255 QualType IVART = Ivar->getType(); 256 if (IsAtomic && 257 IVART->isScalarType() && 258 (Triple.getArch() == llvm::Triple::arm || 259 Triple.getArch() == llvm::Triple::thumb) && 260 (getContext().getTypeSizeInChars(IVART) 261 > CharUnits::fromQuantity(4)) && 262 CGM.getObjCRuntime().GetGetStructFunction()) { 263 GenerateObjCGetterBody(Ivar, true, false); 264 } 265 else if (IsAtomic && 266 (IVART->isScalarType() && !IVART->isRealFloatingType()) && 267 Triple.getArch() == llvm::Triple::x86 && 268 (getContext().getTypeSizeInChars(IVART) 269 > CharUnits::fromQuantity(4)) && 270 CGM.getObjCRuntime().GetGetStructFunction()) { 271 GenerateObjCGetterBody(Ivar, true, false); 272 } 273 else if (IsAtomic && 274 (IVART->isScalarType() && !IVART->isRealFloatingType()) && 275 Triple.getArch() == llvm::Triple::x86_64 && 276 (getContext().getTypeSizeInChars(IVART) 277 > CharUnits::fromQuantity(8)) && 278 CGM.getObjCRuntime().GetGetStructFunction()) { 279 GenerateObjCGetterBody(Ivar, true, false); 280 } 281 else if (IVART->isAnyComplexType()) { 282 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 283 Ivar, 0); 284 ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(), 285 LV.isVolatileQualified()); 286 StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified()); 287 } 288 else if (hasAggregateLLVMType(IVART)) { 289 bool IsStrong = false; 290 if ((IsStrong = IvarTypeWithAggrGCObjects(IVART)) 291 && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect 292 && CGM.getObjCRuntime().GetGetStructFunction()) { 293 GenerateObjCGetterBody(Ivar, IsAtomic, IsStrong); 294 } 295 else { 296 const CXXRecordDecl *classDecl = IVART->getAsCXXRecordDecl(); 297 298 if (PID->getGetterCXXConstructor() && 299 classDecl && !classDecl->hasTrivialConstructor()) { 300 ReturnStmt *Stmt = 301 new (getContext()) ReturnStmt(SourceLocation(), 302 PID->getGetterCXXConstructor(), 303 0); 304 EmitReturnStmt(*Stmt); 305 } else if (IsAtomic && 306 !IVART->isAnyComplexType() && 307 Triple.getArch() == llvm::Triple::x86 && 308 (getContext().getTypeSizeInChars(IVART) 309 > CharUnits::fromQuantity(4)) && 310 CGM.getObjCRuntime().GetGetStructFunction()) { 311 GenerateObjCGetterBody(Ivar, true, false); 312 } 313 else if (IsAtomic && 314 !IVART->isAnyComplexType() && 315 Triple.getArch() == llvm::Triple::x86_64 && 316 (getContext().getTypeSizeInChars(IVART) 317 > CharUnits::fromQuantity(8)) && 318 CGM.getObjCRuntime().GetGetStructFunction()) { 319 GenerateObjCGetterBody(Ivar, true, false); 320 } 321 else { 322 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 323 Ivar, 0); 324 EmitAggregateCopy(ReturnValue, LV.getAddress(), IVART); 325 } 326 } 327 } 328 else { 329 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 330 Ivar, 0); 331 if (PD->getType()->isReferenceType()) { 332 RValue RV = RValue::get(LV.getAddress()); 333 EmitReturnOfRValue(RV, PD->getType()); 334 } 335 else { 336 CodeGenTypes &Types = CGM.getTypes(); 337 RValue RV = EmitLoadOfLValue(LV, IVART); 338 RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(), 339 Types.ConvertType(PD->getType()))); 340 EmitReturnOfRValue(RV, PD->getType()); 341 } 342 } 343 } 344 345 FinishFunction(); 346 } 347 348 void CodeGenFunction::GenerateObjCAtomicSetterBody(ObjCMethodDecl *OMD, 349 ObjCIvarDecl *Ivar) { 350 // objc_copyStruct (&structIvar, &Arg, 351 // sizeof (struct something), true, false); 352 llvm::Value *GetCopyStructFn = 353 CGM.getObjCRuntime().GetSetStructFunction(); 354 CodeGenTypes &Types = CGM.getTypes(); 355 CallArgList Args; 356 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0); 357 RValue RV = 358 RValue::get(Builder.CreateBitCast(LV.getAddress(), 359 Types.ConvertType(getContext().VoidPtrTy))); 360 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 361 llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()]; 362 llvm::Value *ArgAsPtrTy = 363 Builder.CreateBitCast(Arg, 364 Types.ConvertType(getContext().VoidPtrTy)); 365 RV = RValue::get(ArgAsPtrTy); 366 Args.push_back(std::make_pair(RV, getContext().VoidPtrTy)); 367 // sizeof (Type of Ivar) 368 CharUnits Size = getContext().getTypeSizeInChars(Ivar->getType()); 369 llvm::Value *SizeVal = 370 llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), 371 Size.getQuantity()); 372 Args.push_back(std::make_pair(RValue::get(SizeVal), 373 getContext().LongTy)); 374 llvm::Value *True = 375 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1); 376 Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); 377 llvm::Value *False = 378 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0); 379 Args.push_back(std::make_pair(RValue::get(False), getContext().BoolTy)); 380 EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, 381 FunctionType::ExtInfo()), 382 GetCopyStructFn, ReturnValueSlot(), Args); 383 } 384 385 static bool 386 IvarAssignHasTrvialAssignment(const ObjCPropertyImplDecl *PID, 387 QualType IvarT) { 388 bool HasTrvialAssignment = true; 389 if (PID->getSetterCXXAssignment()) { 390 const CXXRecordDecl *classDecl = IvarT->getAsCXXRecordDecl(); 391 HasTrvialAssignment = 392 (!classDecl || classDecl->hasTrivialCopyAssignment()); 393 } 394 return HasTrvialAssignment; 395 } 396 397 /// GenerateObjCSetter - Generate an Objective-C property setter 398 /// function. The given Decl must be an ObjCImplementationDecl. @synthesize 399 /// is illegal within a category. 400 void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, 401 const ObjCPropertyImplDecl *PID) { 402 ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 403 const ObjCPropertyDecl *PD = PID->getPropertyDecl(); 404 ObjCMethodDecl *OMD = PD->getSetterMethodDecl(); 405 assert(OMD && "Invalid call to generate setter (empty method)"); 406 StartObjCMethod(OMD, IMP->getClassInterface()); 407 const llvm::Triple &Triple = getContext().Target.getTriple(); 408 QualType IVART = Ivar->getType(); 409 bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy; 410 bool IsAtomic = 411 !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic); 412 413 // Determine if we should use an objc_setProperty call for 414 // this. Properties with 'copy' semantics always use it, as do 415 // non-atomic properties with 'release' semantics as long as we are 416 // not in gc-only mode. 417 if (IsCopy || 418 (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly && 419 PD->getSetterKind() == ObjCPropertyDecl::Retain)) { 420 llvm::Value *SetPropertyFn = 421 CGM.getObjCRuntime().GetPropertySetFunction(); 422 423 if (!SetPropertyFn) { 424 CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy"); 425 FinishFunction(); 426 return; 427 } 428 429 // Emit objc_setProperty((id) self, _cmd, offset, arg, 430 // <is-atomic>, <is-copy>). 431 // FIXME: Can't this be simpler? This might even be worse than the 432 // corresponding gcc code. 433 CodeGenTypes &Types = CGM.getTypes(); 434 ValueDecl *Cmd = OMD->getCmdDecl(); 435 llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd"); 436 QualType IdTy = getContext().getObjCIdType(); 437 llvm::Value *SelfAsId = 438 Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy)); 439 llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar); 440 llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()]; 441 llvm::Value *ArgAsId = 442 Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"), 443 Types.ConvertType(IdTy)); 444 llvm::Value *True = 445 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1); 446 llvm::Value *False = 447 llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0); 448 CallArgList Args; 449 Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy)); 450 Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); 451 Args.push_back(std::make_pair(RValue::get(Offset), 452 getContext().getPointerDiffType())); 453 Args.push_back(std::make_pair(RValue::get(ArgAsId), IdTy)); 454 Args.push_back(std::make_pair(RValue::get(IsAtomic ? True : False), 455 getContext().BoolTy)); 456 Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False), 457 getContext().BoolTy)); 458 // FIXME: We shouldn't need to get the function info here, the runtime 459 // already should have computed it to build the function. 460 EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, 461 FunctionType::ExtInfo()), 462 SetPropertyFn, 463 ReturnValueSlot(), Args); 464 } else if (IsAtomic && hasAggregateLLVMType(IVART) && 465 !IVART->isAnyComplexType() && 466 IvarAssignHasTrvialAssignment(PID, IVART) && 467 ((Triple.getArch() == llvm::Triple::x86 && 468 (getContext().getTypeSizeInChars(IVART) 469 > CharUnits::fromQuantity(4))) || 470 (Triple.getArch() == llvm::Triple::x86_64 && 471 (getContext().getTypeSizeInChars(IVART) 472 > CharUnits::fromQuantity(8)))) 473 && CGM.getObjCRuntime().GetSetStructFunction()) { 474 // objc_copyStruct (&structIvar, &Arg, 475 // sizeof (struct something), true, false); 476 GenerateObjCAtomicSetterBody(OMD, Ivar); 477 } else if (PID->getSetterCXXAssignment()) { 478 EmitIgnoredExpr(PID->getSetterCXXAssignment()); 479 } else { 480 if (IsAtomic && 481 IVART->isScalarType() && 482 (Triple.getArch() == llvm::Triple::arm || 483 Triple.getArch() == llvm::Triple::thumb) && 484 (getContext().getTypeSizeInChars(IVART) 485 > CharUnits::fromQuantity(4)) && 486 CGM.getObjCRuntime().GetGetStructFunction()) { 487 GenerateObjCAtomicSetterBody(OMD, Ivar); 488 } 489 else if (IsAtomic && 490 (IVART->isScalarType() && !IVART->isRealFloatingType()) && 491 Triple.getArch() == llvm::Triple::x86 && 492 (getContext().getTypeSizeInChars(IVART) 493 > CharUnits::fromQuantity(4)) && 494 CGM.getObjCRuntime().GetGetStructFunction()) { 495 GenerateObjCAtomicSetterBody(OMD, Ivar); 496 } 497 else if (IsAtomic && 498 (IVART->isScalarType() && !IVART->isRealFloatingType()) && 499 Triple.getArch() == llvm::Triple::x86_64 && 500 (getContext().getTypeSizeInChars(IVART) 501 > CharUnits::fromQuantity(8)) && 502 CGM.getObjCRuntime().GetGetStructFunction()) { 503 GenerateObjCAtomicSetterBody(OMD, Ivar); 504 } 505 else { 506 // FIXME: Find a clean way to avoid AST node creation. 507 SourceLocation Loc = PD->getLocation(); 508 ValueDecl *Self = OMD->getSelfDecl(); 509 ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); 510 DeclRefExpr Base(Self, Self->getType(), VK_RValue, Loc); 511 ParmVarDecl *ArgDecl = *OMD->param_begin(); 512 QualType T = ArgDecl->getType(); 513 if (T->isReferenceType()) 514 T = cast<ReferenceType>(T)->getPointeeType(); 515 DeclRefExpr Arg(ArgDecl, T, VK_LValue, Loc); 516 ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true); 517 518 // The property type can differ from the ivar type in some situations with 519 // Objective-C pointer types, we can always bit cast the RHS in these cases. 520 if (getContext().getCanonicalType(Ivar->getType()) != 521 getContext().getCanonicalType(ArgDecl->getType())) { 522 ImplicitCastExpr ArgCasted(ImplicitCastExpr::OnStack, 523 Ivar->getType(), CK_BitCast, &Arg, 524 VK_RValue); 525 BinaryOperator Assign(&IvarRef, &ArgCasted, BO_Assign, 526 Ivar->getType(), VK_RValue, OK_Ordinary, Loc); 527 EmitStmt(&Assign); 528 } else { 529 BinaryOperator Assign(&IvarRef, &Arg, BO_Assign, 530 Ivar->getType(), VK_RValue, OK_Ordinary, Loc); 531 EmitStmt(&Assign); 532 } 533 } 534 } 535 536 FinishFunction(); 537 } 538 539 // FIXME: these are stolen from CGClass.cpp, which is lame. 540 namespace { 541 struct CallArrayIvarDtor : EHScopeStack::Cleanup { 542 const ObjCIvarDecl *ivar; 543 llvm::Value *self; 544 CallArrayIvarDtor(const ObjCIvarDecl *ivar, llvm::Value *self) 545 : ivar(ivar), self(self) {} 546 547 void Emit(CodeGenFunction &CGF, bool IsForEH) { 548 LValue lvalue = 549 CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), self, ivar, 0); 550 551 QualType type = ivar->getType(); 552 const ConstantArrayType *arrayType 553 = CGF.getContext().getAsConstantArrayType(type); 554 QualType baseType = CGF.getContext().getBaseElementType(arrayType); 555 const CXXRecordDecl *classDecl = baseType->getAsCXXRecordDecl(); 556 557 llvm::Value *base 558 = CGF.Builder.CreateBitCast(lvalue.getAddress(), 559 CGF.ConvertType(baseType)->getPointerTo()); 560 CGF.EmitCXXAggrDestructorCall(classDecl->getDestructor(), 561 arrayType, base); 562 } 563 }; 564 565 struct CallIvarDtor : EHScopeStack::Cleanup { 566 const ObjCIvarDecl *ivar; 567 llvm::Value *self; 568 CallIvarDtor(const ObjCIvarDecl *ivar, llvm::Value *self) 569 : ivar(ivar), self(self) {} 570 571 void Emit(CodeGenFunction &CGF, bool IsForEH) { 572 LValue lvalue = 573 CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), self, ivar, 0); 574 575 QualType type = ivar->getType(); 576 const CXXRecordDecl *classDecl = type->getAsCXXRecordDecl(); 577 578 CGF.EmitCXXDestructorCall(classDecl->getDestructor(), 579 Dtor_Complete, /*ForVirtualBase=*/false, 580 lvalue.getAddress()); 581 } 582 }; 583 } 584 585 static void emitCXXDestructMethod(CodeGenFunction &CGF, 586 ObjCImplementationDecl *impl) { 587 CodeGenFunction::RunCleanupsScope scope(CGF); 588 589 llvm::Value *self = CGF.LoadObjCSelf(); 590 591 ObjCInterfaceDecl *iface 592 = const_cast<ObjCInterfaceDecl*>(impl->getClassInterface()); 593 for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin(); 594 ivar; ivar = ivar->getNextIvar()) { 595 QualType type = ivar->getType(); 596 597 // Drill down to the base element type. 598 QualType baseType = type; 599 const ConstantArrayType *arrayType = 600 CGF.getContext().getAsConstantArrayType(baseType); 601 if (arrayType) baseType = CGF.getContext().getBaseElementType(arrayType); 602 603 // Check whether the ivar is a destructible type. 604 QualType::DestructionKind destructKind = baseType.isDestructedType(); 605 assert(destructKind == type.isDestructedType()); 606 607 switch (destructKind) { 608 case QualType::DK_none: 609 continue; 610 611 case QualType::DK_cxx_destructor: 612 if (arrayType) 613 CGF.EHStack.pushCleanup<CallArrayIvarDtor>(NormalAndEHCleanup, 614 ivar, self); 615 else 616 CGF.EHStack.pushCleanup<CallIvarDtor>(NormalAndEHCleanup, 617 ivar, self); 618 break; 619 } 620 } 621 622 assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?"); 623 } 624 625 void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP, 626 ObjCMethodDecl *MD, 627 bool ctor) { 628 MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface()); 629 StartObjCMethod(MD, IMP->getClassInterface()); 630 631 // Emit .cxx_construct. 632 if (ctor) { 633 llvm::SmallVector<CXXCtorInitializer *, 8> IvarInitializers; 634 for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(), 635 E = IMP->init_end(); B != E; ++B) { 636 CXXCtorInitializer *IvarInit = (*B); 637 FieldDecl *Field = IvarInit->getAnyMember(); 638 ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field); 639 LValue LV = EmitLValueForIvar(TypeOfSelfObject(), 640 LoadObjCSelf(), Ivar, 0); 641 EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, true)); 642 } 643 // constructor returns 'self'. 644 CodeGenTypes &Types = CGM.getTypes(); 645 QualType IdTy(CGM.getContext().getObjCIdType()); 646 llvm::Value *SelfAsId = 647 Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy)); 648 EmitReturnOfRValue(RValue::get(SelfAsId), IdTy); 649 650 // Emit .cxx_destruct. 651 } else { 652 emitCXXDestructMethod(*this, IMP); 653 } 654 FinishFunction(); 655 } 656 657 bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) { 658 CGFunctionInfo::const_arg_iterator it = FI.arg_begin(); 659 it++; it++; 660 const ABIArgInfo &AI = it->info; 661 // FIXME. Is this sufficient check? 662 return (AI.getKind() == ABIArgInfo::Indirect); 663 } 664 665 bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) { 666 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC) 667 return false; 668 if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>()) 669 return FDTTy->getDecl()->hasObjectMember(); 670 return false; 671 } 672 673 llvm::Value *CodeGenFunction::LoadObjCSelf() { 674 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 675 return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self"); 676 } 677 678 QualType CodeGenFunction::TypeOfSelfObject() { 679 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); 680 ImplicitParamDecl *selfDecl = OMD->getSelfDecl(); 681 const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>( 682 getContext().getCanonicalType(selfDecl->getType())); 683 return PTy->getPointeeType(); 684 } 685 686 LValue 687 CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) { 688 // This is a special l-value that just issues sends when we load or 689 // store through it. 690 691 // For certain base kinds, we need to emit the base immediately. 692 llvm::Value *Base; 693 if (E->isSuperReceiver()) 694 Base = LoadObjCSelf(); 695 else if (E->isClassReceiver()) 696 Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver()); 697 else 698 Base = EmitScalarExpr(E->getBase()); 699 return LValue::MakePropertyRef(E, Base); 700 } 701 702 static RValue GenerateMessageSendSuper(CodeGenFunction &CGF, 703 ReturnValueSlot Return, 704 QualType ResultType, 705 Selector S, 706 llvm::Value *Receiver, 707 const CallArgList &CallArgs) { 708 const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl); 709 bool isClassMessage = OMD->isClassMethod(); 710 bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); 711 return CGF.CGM.getObjCRuntime() 712 .GenerateMessageSendSuper(CGF, Return, ResultType, 713 S, OMD->getClassInterface(), 714 isCategoryImpl, Receiver, 715 isClassMessage, CallArgs); 716 } 717 718 RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV, 719 ReturnValueSlot Return) { 720 const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr(); 721 QualType ResultType = E->getGetterResultType(); 722 Selector S; 723 if (E->isExplicitProperty()) { 724 const ObjCPropertyDecl *Property = E->getExplicitProperty(); 725 S = Property->getGetterName(); 726 } else { 727 const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter(); 728 S = Getter->getSelector(); 729 } 730 731 llvm::Value *Receiver = LV.getPropertyRefBaseAddr(); 732 733 // Accesses to 'super' follow a different code path. 734 if (E->isSuperReceiver()) 735 return GenerateMessageSendSuper(*this, Return, ResultType, 736 S, Receiver, CallArgList()); 737 738 const ObjCInterfaceDecl *ReceiverClass 739 = (E->isClassReceiver() ? E->getClassReceiver() : 0); 740 return CGM.getObjCRuntime(). 741 GenerateMessageSend(*this, Return, ResultType, S, 742 Receiver, CallArgList(), ReceiverClass); 743 } 744 745 void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src, 746 LValue Dst) { 747 const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr(); 748 Selector S = E->getSetterSelector(); 749 QualType ArgType = E->getSetterArgType(); 750 751 // FIXME. Other than scalars, AST is not adequate for setter and 752 // getter type mismatches which require conversion. 753 if (Src.isScalar()) { 754 llvm::Value *SrcVal = Src.getScalarVal(); 755 QualType DstType = getContext().getCanonicalType(ArgType); 756 const llvm::Type *DstTy = ConvertType(DstType); 757 if (SrcVal->getType() != DstTy) 758 Src = 759 RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType)); 760 } 761 762 CallArgList Args; 763 Args.push_back(std::make_pair(Src, ArgType)); 764 765 llvm::Value *Receiver = Dst.getPropertyRefBaseAddr(); 766 QualType ResultType = getContext().VoidTy; 767 768 if (E->isSuperReceiver()) { 769 GenerateMessageSendSuper(*this, ReturnValueSlot(), 770 ResultType, S, Receiver, Args); 771 return; 772 } 773 774 const ObjCInterfaceDecl *ReceiverClass 775 = (E->isClassReceiver() ? E->getClassReceiver() : 0); 776 777 CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), 778 ResultType, S, Receiver, Args, 779 ReceiverClass); 780 } 781 782 void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ 783 llvm::Constant *EnumerationMutationFn = 784 CGM.getObjCRuntime().EnumerationMutationFunction(); 785 786 if (!EnumerationMutationFn) { 787 CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime"); 788 return; 789 } 790 791 // The local variable comes into scope immediately. 792 AutoVarEmission variable = AutoVarEmission::invalid(); 793 if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) 794 variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl())); 795 796 CGDebugInfo *DI = getDebugInfo(); 797 if (DI) { 798 DI->setLocation(S.getSourceRange().getBegin()); 799 DI->EmitRegionStart(Builder); 800 } 801 802 JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end"); 803 JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next"); 804 805 // Fast enumeration state. 806 QualType StateTy = getContext().getObjCFastEnumerationStateType(); 807 llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr"); 808 EmitNullInitialization(StatePtr, StateTy); 809 810 // Number of elements in the items array. 811 static const unsigned NumItems = 16; 812 813 // Fetch the countByEnumeratingWithState:objects:count: selector. 814 IdentifierInfo *II[] = { 815 &CGM.getContext().Idents.get("countByEnumeratingWithState"), 816 &CGM.getContext().Idents.get("objects"), 817 &CGM.getContext().Idents.get("count") 818 }; 819 Selector FastEnumSel = 820 CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]); 821 822 QualType ItemsTy = 823 getContext().getConstantArrayType(getContext().getObjCIdType(), 824 llvm::APInt(32, NumItems), 825 ArrayType::Normal, 0); 826 llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr"); 827 828 // Emit the collection pointer. 829 llvm::Value *Collection = EmitScalarExpr(S.getCollection()); 830 831 // Send it our message: 832 CallArgList Args; 833 834 // The first argument is a temporary of the enumeration-state type. 835 Args.push_back(std::make_pair(RValue::get(StatePtr), 836 getContext().getPointerType(StateTy))); 837 838 // The second argument is a temporary array with space for NumItems 839 // pointers. We'll actually be loading elements from the array 840 // pointer written into the control state; this buffer is so that 841 // collections that *aren't* backed by arrays can still queue up 842 // batches of elements. 843 Args.push_back(std::make_pair(RValue::get(ItemsPtr), 844 getContext().getPointerType(ItemsTy))); 845 846 // The third argument is the capacity of that temporary array. 847 const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy); 848 llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems); 849 Args.push_back(std::make_pair(RValue::get(Count), 850 getContext().UnsignedLongTy)); 851 852 // Start the enumeration. 853 RValue CountRV = 854 CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), 855 getContext().UnsignedLongTy, 856 FastEnumSel, 857 Collection, Args); 858 859 // The initial number of objects that were returned in the buffer. 860 llvm::Value *initialBufferLimit = CountRV.getScalarVal(); 861 862 llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty"); 863 llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit"); 864 865 llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy); 866 867 // If the limit pointer was zero to begin with, the collection is 868 // empty; skip all this. 869 Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"), 870 EmptyBB, LoopInitBB); 871 872 // Otherwise, initialize the loop. 873 EmitBlock(LoopInitBB); 874 875 // Save the initial mutations value. This is the value at an 876 // address that was written into the state object by 877 // countByEnumeratingWithState:objects:count:. 878 llvm::Value *StateMutationsPtrPtr = 879 Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr"); 880 llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, 881 "mutationsptr"); 882 883 llvm::Value *initialMutations = 884 Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations"); 885 886 // Start looping. This is the point we return to whenever we have a 887 // fresh, non-empty batch of objects. 888 llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody"); 889 EmitBlock(LoopBodyBB); 890 891 // The current index into the buffer. 892 llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index"); 893 index->addIncoming(zero, LoopInitBB); 894 895 // The current buffer size. 896 llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count"); 897 count->addIncoming(initialBufferLimit, LoopInitBB); 898 899 // Check whether the mutations value has changed from where it was 900 // at start. StateMutationsPtr should actually be invariant between 901 // refreshes. 902 StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); 903 llvm::Value *currentMutations 904 = Builder.CreateLoad(StateMutationsPtr, "statemutations"); 905 906 llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated"); 907 llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated"); 908 909 Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations), 910 WasNotMutatedBB, WasMutatedBB); 911 912 // If so, call the enumeration-mutation function. 913 EmitBlock(WasMutatedBB); 914 llvm::Value *V = 915 Builder.CreateBitCast(Collection, 916 ConvertType(getContext().getObjCIdType()), 917 "tmp"); 918 CallArgList Args2; 919 Args2.push_back(std::make_pair(RValue::get(V), 920 getContext().getObjCIdType())); 921 // FIXME: We shouldn't need to get the function info here, the runtime already 922 // should have computed it to build the function. 923 EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2, 924 FunctionType::ExtInfo()), 925 EnumerationMutationFn, ReturnValueSlot(), Args2); 926 927 // Otherwise, or if the mutation function returns, just continue. 928 EmitBlock(WasNotMutatedBB); 929 930 // Initialize the element variable. 931 RunCleanupsScope elementVariableScope(*this); 932 bool elementIsVariable; 933 LValue elementLValue; 934 QualType elementType; 935 if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) { 936 // Initialize the variable, in case it's a __block variable or something. 937 EmitAutoVarInit(variable); 938 939 const VarDecl* D = cast<VarDecl>(SD->getSingleDecl()); 940 DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(), 941 VK_LValue, SourceLocation()); 942 elementLValue = EmitLValue(&tempDRE); 943 elementType = D->getType(); 944 elementIsVariable = true; 945 } else { 946 elementLValue = LValue(); // suppress warning 947 elementType = cast<Expr>(S.getElement())->getType(); 948 elementIsVariable = false; 949 } 950 const llvm::Type *convertedElementType = ConvertType(elementType); 951 952 // Fetch the buffer out of the enumeration state. 953 // TODO: this pointer should actually be invariant between 954 // refreshes, which would help us do certain loop optimizations. 955 llvm::Value *StateItemsPtr = 956 Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr"); 957 llvm::Value *EnumStateItems = 958 Builder.CreateLoad(StateItemsPtr, "stateitems"); 959 960 // Fetch the value at the current index from the buffer. 961 llvm::Value *CurrentItemPtr = 962 Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr"); 963 llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr); 964 965 // Cast that value to the right type. 966 CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType, 967 "currentitem"); 968 969 // Make sure we have an l-value. Yes, this gets evaluated every 970 // time through the loop. 971 if (!elementIsVariable) 972 elementLValue = EmitLValue(cast<Expr>(S.getElement())); 973 974 EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue, elementType); 975 976 // If we do have an element variable, this assignment is the end of 977 // its initialization. 978 if (elementIsVariable) 979 EmitAutoVarCleanups(variable); 980 981 // Perform the loop body, setting up break and continue labels. 982 BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody)); 983 { 984 RunCleanupsScope Scope(*this); 985 EmitStmt(S.getBody()); 986 } 987 BreakContinueStack.pop_back(); 988 989 // Destroy the element variable now. 990 elementVariableScope.ForceCleanup(); 991 992 // Check whether there are more elements. 993 EmitBlock(AfterBody.getBlock()); 994 995 llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch"); 996 997 // First we check in the local buffer. 998 llvm::Value *indexPlusOne 999 = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1)); 1000 1001 // If we haven't overrun the buffer yet, we can continue. 1002 Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count), 1003 LoopBodyBB, FetchMoreBB); 1004 1005 index->addIncoming(indexPlusOne, AfterBody.getBlock()); 1006 count->addIncoming(count, AfterBody.getBlock()); 1007 1008 // Otherwise, we have to fetch more elements. 1009 EmitBlock(FetchMoreBB); 1010 1011 CountRV = 1012 CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), 1013 getContext().UnsignedLongTy, 1014 FastEnumSel, 1015 Collection, Args); 1016 1017 // If we got a zero count, we're done. 1018 llvm::Value *refetchCount = CountRV.getScalarVal(); 1019 1020 // (note that the message send might split FetchMoreBB) 1021 index->addIncoming(zero, Builder.GetInsertBlock()); 1022 count->addIncoming(refetchCount, Builder.GetInsertBlock()); 1023 1024 Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero), 1025 EmptyBB, LoopBodyBB); 1026 1027 // No more elements. 1028 EmitBlock(EmptyBB); 1029 1030 if (!elementIsVariable) { 1031 // If the element was not a declaration, set it to be null. 1032 1033 llvm::Value *null = llvm::Constant::getNullValue(convertedElementType); 1034 elementLValue = EmitLValue(cast<Expr>(S.getElement())); 1035 EmitStoreThroughLValue(RValue::get(null), elementLValue, elementType); 1036 } 1037 1038 if (DI) { 1039 DI->setLocation(S.getSourceRange().getEnd()); 1040 DI->EmitRegionEnd(Builder); 1041 } 1042 1043 EmitBlock(LoopEnd.getBlock()); 1044 } 1045 1046 void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) { 1047 CGM.getObjCRuntime().EmitTryStmt(*this, S); 1048 } 1049 1050 void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) { 1051 CGM.getObjCRuntime().EmitThrowStmt(*this, S); 1052 } 1053 1054 void CodeGenFunction::EmitObjCAtSynchronizedStmt( 1055 const ObjCAtSynchronizedStmt &S) { 1056 CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S); 1057 } 1058 1059 CGObjCRuntime::~CGObjCRuntime() {} 1060