1 //===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===// 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 provides Objective-C code generation targetting the Apple runtime. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CGObjCRuntime.h" 15 16 #include "CodeGenModule.h" 17 #include "CodeGenFunction.h" 18 #include "clang/AST/ASTContext.h" 19 #include "clang/AST/Decl.h" 20 #include "clang/AST/DeclObjC.h" 21 #include "clang/AST/RecordLayout.h" 22 #include "clang/AST/StmtObjC.h" 23 #include "clang/Basic/LangOptions.h" 24 25 #include "llvm/Intrinsics.h" 26 #include "llvm/Module.h" 27 #include "llvm/ADT/DenseSet.h" 28 #include "llvm/Target/TargetData.h" 29 #include <sstream> 30 31 using namespace clang; 32 using namespace CodeGen; 33 34 // Common CGObjCRuntime functions, these don't belong here, but they 35 // don't belong in CGObjCRuntime either so we will live with it for 36 // now. 37 38 /// FindIvarInterface - Find the interface containing the ivar. 39 /// 40 /// FIXME: We shouldn't need to do this, the containing context should 41 /// be fixed. 42 static const ObjCInterfaceDecl *FindIvarInterface(ASTContext &Context, 43 const ObjCInterfaceDecl *OID, 44 const ObjCIvarDecl *OIVD, 45 unsigned &Index) { 46 // FIXME: The index here is closely tied to how 47 // ASTContext::getObjCLayout is implemented. This should be fixed to 48 // get the information from the layout directly. 49 Index = 0; 50 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 51 Context.ShallowCollectObjCIvars(OID, Ivars); 52 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) { 53 if (OIVD == Ivars[k]) 54 return OID; 55 ++Index; 56 } 57 58 // Otherwise check in the super class. 59 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 60 return FindIvarInterface(Context, Super, OIVD, Index); 61 62 return 0; 63 } 64 65 static uint64_t LookupFieldBitOffset(CodeGen::CodeGenModule &CGM, 66 const ObjCInterfaceDecl *OID, 67 const ObjCImplementationDecl *ID, 68 const ObjCIvarDecl *Ivar) { 69 unsigned Index; 70 const ObjCInterfaceDecl *Container = 71 FindIvarInterface(CGM.getContext(), OID, Ivar, Index); 72 assert(Container && "Unable to find ivar container"); 73 74 // If we know have an implementation (and the ivar is in it) then 75 // look up in the implementation layout. 76 const ASTRecordLayout *RL; 77 if (ID && ID->getClassInterface() == Container) 78 RL = &CGM.getContext().getASTObjCImplementationLayout(ID); 79 else 80 RL = &CGM.getContext().getASTObjCInterfaceLayout(Container); 81 return RL->getFieldOffset(Index); 82 } 83 84 uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, 85 const ObjCInterfaceDecl *OID, 86 const ObjCIvarDecl *Ivar) { 87 return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 8; 88 } 89 90 uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM, 91 const ObjCImplementationDecl *OID, 92 const ObjCIvarDecl *Ivar) { 93 return LookupFieldBitOffset(CGM, OID->getClassInterface(), OID, Ivar) / 8; 94 } 95 96 LValue CGObjCRuntime::EmitValueForIvarAtOffset(CodeGen::CodeGenFunction &CGF, 97 const ObjCInterfaceDecl *OID, 98 llvm::Value *BaseValue, 99 const ObjCIvarDecl *Ivar, 100 unsigned CVRQualifiers, 101 llvm::Value *Offset) { 102 // Compute (type*) ( (char *) BaseValue + Offset) 103 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 104 QualType IvarTy = Ivar->getType(); 105 const llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy); 106 llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, I8Ptr); 107 V = CGF.Builder.CreateGEP(V, Offset, "add.ptr"); 108 V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy)); 109 110 if (Ivar->isBitField()) { 111 // We need to compute the bit offset for the bit-field, the offset 112 // is to the byte. Note, there is a subtle invariant here: we can 113 // only call this routine on non-sythesized ivars but we may be 114 // called for synthesized ivars. However, a synthesized ivar can 115 // never be a bit-field so this is safe. 116 uint64_t BitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar) % 8; 117 118 uint64_t BitFieldSize = 119 Ivar->getBitWidth()->EvaluateAsInt(CGF.getContext()).getZExtValue(); 120 return LValue::MakeBitfield(V, BitOffset, BitFieldSize, 121 IvarTy->isSignedIntegerType(), 122 IvarTy.getCVRQualifiers()|CVRQualifiers); 123 } 124 125 LValue LV = LValue::MakeAddr(V, IvarTy.getCVRQualifiers()|CVRQualifiers, 126 CGF.CGM.getContext().getObjCGCAttrKind(IvarTy)); 127 LValue::SetObjCIvar(LV, true); 128 return LV; 129 } 130 131 /// 132 133 namespace { 134 135 typedef std::vector<llvm::Constant*> ConstantVector; 136 137 // FIXME: We should find a nicer way to make the labels for metadata, string 138 // concatenation is lame. 139 140 class ObjCCommonTypesHelper { 141 private: 142 llvm::Constant *getMessageSendFn() const { 143 // id objc_msgSend (id, SEL, ...) 144 std::vector<const llvm::Type*> Params; 145 Params.push_back(ObjectPtrTy); 146 Params.push_back(SelectorPtrTy); 147 return 148 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 149 Params, true), 150 "objc_msgSend"); 151 } 152 153 llvm::Constant *getMessageSendStretFn() const { 154 // id objc_msgSend_stret (id, SEL, ...) 155 std::vector<const llvm::Type*> Params; 156 Params.push_back(ObjectPtrTy); 157 Params.push_back(SelectorPtrTy); 158 return 159 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 160 Params, true), 161 "objc_msgSend_stret"); 162 163 } 164 165 llvm::Constant *getMessageSendFpretFn() const { 166 // FIXME: This should be long double on x86_64? 167 // [double | long double] objc_msgSend_fpret(id self, SEL op, ...) 168 std::vector<const llvm::Type*> Params; 169 Params.push_back(ObjectPtrTy); 170 Params.push_back(SelectorPtrTy); 171 return 172 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::DoubleTy, 173 Params, 174 true), 175 "objc_msgSend_fpret"); 176 177 } 178 179 llvm::Constant *getMessageSendSuperFn() const { 180 // id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 181 const char *SuperName = "objc_msgSendSuper"; 182 std::vector<const llvm::Type*> Params; 183 Params.push_back(SuperPtrTy); 184 Params.push_back(SelectorPtrTy); 185 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 186 Params, true), 187 SuperName); 188 } 189 190 llvm::Constant *getMessageSendSuperFn2() const { 191 // id objc_msgSendSuper2(struct objc_super *super, SEL op, ...) 192 const char *SuperName = "objc_msgSendSuper2"; 193 std::vector<const llvm::Type*> Params; 194 Params.push_back(SuperPtrTy); 195 Params.push_back(SelectorPtrTy); 196 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 197 Params, true), 198 SuperName); 199 } 200 201 llvm::Constant *getMessageSendSuperStretFn() const { 202 // void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super, 203 // SEL op, ...) 204 std::vector<const llvm::Type*> Params; 205 Params.push_back(Int8PtrTy); 206 Params.push_back(SuperPtrTy); 207 Params.push_back(SelectorPtrTy); 208 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 209 Params, true), 210 "objc_msgSendSuper_stret"); 211 } 212 213 llvm::Constant *getMessageSendSuperStretFn2() const { 214 // void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super, 215 // SEL op, ...) 216 std::vector<const llvm::Type*> Params; 217 Params.push_back(Int8PtrTy); 218 Params.push_back(SuperPtrTy); 219 Params.push_back(SelectorPtrTy); 220 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 221 Params, true), 222 "objc_msgSendSuper2_stret"); 223 } 224 225 llvm::Constant *getMessageSendSuperFpretFn() const { 226 // There is no objc_msgSendSuper_fpret? How can that work? 227 return getMessageSendSuperFn(); 228 } 229 230 llvm::Constant *getMessageSendSuperFpretFn2() const { 231 // There is no objc_msgSendSuper_fpret? How can that work? 232 return getMessageSendSuperFn2(); 233 } 234 235 protected: 236 CodeGen::CodeGenModule &CGM; 237 238 public: 239 const llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy; 240 const llvm::Type *Int8PtrTy; 241 242 /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 243 const llvm::Type *ObjectPtrTy; 244 245 /// PtrObjectPtrTy - LLVM type for id * 246 const llvm::Type *PtrObjectPtrTy; 247 248 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 249 const llvm::Type *SelectorPtrTy; 250 /// ProtocolPtrTy - LLVM type for external protocol handles 251 /// (typeof(Protocol)) 252 const llvm::Type *ExternalProtocolPtrTy; 253 254 // SuperCTy - clang type for struct objc_super. 255 QualType SuperCTy; 256 // SuperPtrCTy - clang type for struct objc_super *. 257 QualType SuperPtrCTy; 258 259 /// SuperTy - LLVM type for struct objc_super. 260 const llvm::StructType *SuperTy; 261 /// SuperPtrTy - LLVM type for struct objc_super *. 262 const llvm::Type *SuperPtrTy; 263 264 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t 265 /// in GCC parlance). 266 const llvm::StructType *PropertyTy; 267 268 /// PropertyListTy - LLVM type for struct objc_property_list 269 /// (_prop_list_t in GCC parlance). 270 const llvm::StructType *PropertyListTy; 271 /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 272 const llvm::Type *PropertyListPtrTy; 273 274 // MethodTy - LLVM type for struct objc_method. 275 const llvm::StructType *MethodTy; 276 277 /// CacheTy - LLVM type for struct objc_cache. 278 const llvm::Type *CacheTy; 279 /// CachePtrTy - LLVM type for struct objc_cache *. 280 const llvm::Type *CachePtrTy; 281 282 llvm::Constant *getGetPropertyFn() { 283 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 284 ASTContext &Ctx = CGM.getContext(); 285 // id objc_getProperty (id, SEL, ptrdiff_t, bool) 286 llvm::SmallVector<QualType,16> Params; 287 QualType IdType = Ctx.getObjCIdType(); 288 QualType SelType = Ctx.getObjCSelType(); 289 Params.push_back(IdType); 290 Params.push_back(SelType); 291 Params.push_back(Ctx.LongTy); 292 Params.push_back(Ctx.BoolTy); 293 const llvm::FunctionType *FTy = 294 Types.GetFunctionType(Types.getFunctionInfo(IdType, Params), false); 295 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); 296 } 297 298 llvm::Constant *getSetPropertyFn() { 299 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 300 ASTContext &Ctx = CGM.getContext(); 301 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 302 llvm::SmallVector<QualType,16> Params; 303 QualType IdType = Ctx.getObjCIdType(); 304 QualType SelType = Ctx.getObjCSelType(); 305 Params.push_back(IdType); 306 Params.push_back(SelType); 307 Params.push_back(Ctx.LongTy); 308 Params.push_back(IdType); 309 Params.push_back(Ctx.BoolTy); 310 Params.push_back(Ctx.BoolTy); 311 const llvm::FunctionType *FTy = 312 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false); 313 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); 314 } 315 316 llvm::Constant *getEnumerationMutationFn() { 317 // void objc_enumerationMutation (id) 318 std::vector<const llvm::Type*> Args; 319 Args.push_back(ObjectPtrTy); 320 llvm::FunctionType *FTy = 321 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 322 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 323 } 324 325 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. 326 llvm::Constant *getGcReadWeakFn() { 327 // id objc_read_weak (id *) 328 std::vector<const llvm::Type*> Args; 329 Args.push_back(ObjectPtrTy->getPointerTo()); 330 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, Args, false); 331 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak"); 332 } 333 334 /// GcAssignWeakFn -- LLVM objc_assign_weak function. 335 llvm::Constant *getGcAssignWeakFn() { 336 // id objc_assign_weak (id, id *) 337 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 338 Args.push_back(ObjectPtrTy->getPointerTo()); 339 llvm::FunctionType *FTy = 340 llvm::FunctionType::get(ObjectPtrTy, Args, false); 341 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak"); 342 } 343 344 /// GcAssignGlobalFn -- LLVM objc_assign_global function. 345 llvm::Constant *getGcAssignGlobalFn() { 346 // id objc_assign_global(id, id *) 347 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 348 Args.push_back(ObjectPtrTy->getPointerTo()); 349 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, Args, false); 350 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global"); 351 } 352 353 /// GcAssignIvarFn -- LLVM objc_assign_ivar function. 354 llvm::Constant *getGcAssignIvarFn() { 355 // id objc_assign_ivar(id, id *) 356 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 357 Args.push_back(ObjectPtrTy->getPointerTo()); 358 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, Args, false); 359 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); 360 } 361 362 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. 363 llvm::Constant *getGcAssignStrongCastFn() { 364 // id objc_assign_global(id, id *) 365 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 366 Args.push_back(ObjectPtrTy->getPointerTo()); 367 llvm::FunctionType *FTy = llvm::FunctionType::get(ObjectPtrTy, Args, false); 368 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast"); 369 } 370 371 /// ExceptionThrowFn - LLVM objc_exception_throw function. 372 llvm::Constant *getExceptionThrowFn() { 373 // void objc_exception_throw(id) 374 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 375 llvm::FunctionType *FTy = 376 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 377 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 378 } 379 380 /// SyncEnterFn - LLVM object_sync_enter function. 381 llvm::Constant *getSyncEnterFn() { 382 // void objc_sync_enter (id) 383 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 384 llvm::FunctionType *FTy = 385 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 386 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 387 } 388 389 /// SyncExitFn - LLVM object_sync_exit function. 390 llvm::Constant *getSyncExitFn() { 391 // void objc_sync_exit (id) 392 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 393 llvm::FunctionType *FTy = 394 llvm::FunctionType::get(llvm::Type::VoidTy, Args, false); 395 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 396 } 397 398 llvm::Constant *getSendFn(bool IsSuper) const { 399 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn(); 400 } 401 402 llvm::Constant *getSendFn2(bool IsSuper) const { 403 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn(); 404 } 405 406 llvm::Constant *getSendStretFn(bool IsSuper) const { 407 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn(); 408 } 409 410 llvm::Constant *getSendStretFn2(bool IsSuper) const { 411 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn(); 412 } 413 414 llvm::Constant *getSendFpretFn(bool IsSuper) const { 415 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn(); 416 } 417 418 llvm::Constant *getSendFpretFn2(bool IsSuper) const { 419 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn(); 420 } 421 422 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); 423 ~ObjCCommonTypesHelper(){} 424 }; 425 426 /// ObjCTypesHelper - Helper class that encapsulates lazy 427 /// construction of varies types used during ObjC generation. 428 class ObjCTypesHelper : public ObjCCommonTypesHelper { 429 public: 430 /// SymtabTy - LLVM type for struct objc_symtab. 431 const llvm::StructType *SymtabTy; 432 /// SymtabPtrTy - LLVM type for struct objc_symtab *. 433 const llvm::Type *SymtabPtrTy; 434 /// ModuleTy - LLVM type for struct objc_module. 435 const llvm::StructType *ModuleTy; 436 437 /// ProtocolTy - LLVM type for struct objc_protocol. 438 const llvm::StructType *ProtocolTy; 439 /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 440 const llvm::Type *ProtocolPtrTy; 441 /// ProtocolExtensionTy - LLVM type for struct 442 /// objc_protocol_extension. 443 const llvm::StructType *ProtocolExtensionTy; 444 /// ProtocolExtensionTy - LLVM type for struct 445 /// objc_protocol_extension *. 446 const llvm::Type *ProtocolExtensionPtrTy; 447 /// MethodDescriptionTy - LLVM type for struct 448 /// objc_method_description. 449 const llvm::StructType *MethodDescriptionTy; 450 /// MethodDescriptionListTy - LLVM type for struct 451 /// objc_method_description_list. 452 const llvm::StructType *MethodDescriptionListTy; 453 /// MethodDescriptionListPtrTy - LLVM type for struct 454 /// objc_method_description_list *. 455 const llvm::Type *MethodDescriptionListPtrTy; 456 /// ProtocolListTy - LLVM type for struct objc_property_list. 457 const llvm::Type *ProtocolListTy; 458 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 459 const llvm::Type *ProtocolListPtrTy; 460 /// CategoryTy - LLVM type for struct objc_category. 461 const llvm::StructType *CategoryTy; 462 /// ClassTy - LLVM type for struct objc_class. 463 const llvm::StructType *ClassTy; 464 /// ClassPtrTy - LLVM type for struct objc_class *. 465 const llvm::Type *ClassPtrTy; 466 /// ClassExtensionTy - LLVM type for struct objc_class_ext. 467 const llvm::StructType *ClassExtensionTy; 468 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. 469 const llvm::Type *ClassExtensionPtrTy; 470 // IvarTy - LLVM type for struct objc_ivar. 471 const llvm::StructType *IvarTy; 472 /// IvarListTy - LLVM type for struct objc_ivar_list. 473 const llvm::Type *IvarListTy; 474 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. 475 const llvm::Type *IvarListPtrTy; 476 /// MethodListTy - LLVM type for struct objc_method_list. 477 const llvm::Type *MethodListTy; 478 /// MethodListPtrTy - LLVM type for struct objc_method_list *. 479 const llvm::Type *MethodListPtrTy; 480 481 /// ExceptionDataTy - LLVM type for struct _objc_exception_data. 482 const llvm::Type *ExceptionDataTy; 483 484 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. 485 llvm::Constant *getExceptionTryEnterFn() { 486 std::vector<const llvm::Type*> Params; 487 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 488 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 489 Params, false), 490 "objc_exception_try_enter"); 491 } 492 493 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. 494 llvm::Constant *getExceptionTryExitFn() { 495 std::vector<const llvm::Type*> Params; 496 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 497 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 498 Params, false), 499 "objc_exception_try_exit"); 500 } 501 502 /// ExceptionExtractFn - LLVM objc_exception_extract function. 503 llvm::Constant *getExceptionExtractFn() { 504 std::vector<const llvm::Type*> Params; 505 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 506 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 507 Params, false), 508 "objc_exception_extract"); 509 510 } 511 512 /// ExceptionMatchFn - LLVM objc_exception_match function. 513 llvm::Constant *getExceptionMatchFn() { 514 std::vector<const llvm::Type*> Params; 515 Params.push_back(ClassPtrTy); 516 Params.push_back(ObjectPtrTy); 517 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty, 518 Params, false), 519 "objc_exception_match"); 520 521 } 522 523 /// SetJmpFn - LLVM _setjmp function. 524 llvm::Constant *getSetJmpFn() { 525 std::vector<const llvm::Type*> Params; 526 Params.push_back(llvm::PointerType::getUnqual(llvm::Type::Int32Ty)); 527 return 528 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty, 529 Params, false), 530 "_setjmp"); 531 532 } 533 534 public: 535 ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 536 ~ObjCTypesHelper() {} 537 }; 538 539 /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's 540 /// modern abi 541 class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { 542 public: 543 544 // MethodListnfABITy - LLVM for struct _method_list_t 545 const llvm::StructType *MethodListnfABITy; 546 547 // MethodListnfABIPtrTy - LLVM for struct _method_list_t* 548 const llvm::Type *MethodListnfABIPtrTy; 549 550 // ProtocolnfABITy = LLVM for struct _protocol_t 551 const llvm::StructType *ProtocolnfABITy; 552 553 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t* 554 const llvm::Type *ProtocolnfABIPtrTy; 555 556 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list 557 const llvm::StructType *ProtocolListnfABITy; 558 559 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* 560 const llvm::Type *ProtocolListnfABIPtrTy; 561 562 // ClassnfABITy - LLVM for struct _class_t 563 const llvm::StructType *ClassnfABITy; 564 565 // ClassnfABIPtrTy - LLVM for struct _class_t* 566 const llvm::Type *ClassnfABIPtrTy; 567 568 // IvarnfABITy - LLVM for struct _ivar_t 569 const llvm::StructType *IvarnfABITy; 570 571 // IvarListnfABITy - LLVM for struct _ivar_list_t 572 const llvm::StructType *IvarListnfABITy; 573 574 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* 575 const llvm::Type *IvarListnfABIPtrTy; 576 577 // ClassRonfABITy - LLVM for struct _class_ro_t 578 const llvm::StructType *ClassRonfABITy; 579 580 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 581 const llvm::Type *ImpnfABITy; 582 583 // CategorynfABITy - LLVM for struct _category_t 584 const llvm::StructType *CategorynfABITy; 585 586 // New types for nonfragile abi messaging. 587 588 // MessageRefTy - LLVM for: 589 // struct _message_ref_t { 590 // IMP messenger; 591 // SEL name; 592 // }; 593 const llvm::StructType *MessageRefTy; 594 // MessageRefCTy - clang type for struct _message_ref_t 595 QualType MessageRefCTy; 596 597 // MessageRefPtrTy - LLVM for struct _message_ref_t* 598 const llvm::Type *MessageRefPtrTy; 599 // MessageRefCPtrTy - clang type for struct _message_ref_t* 600 QualType MessageRefCPtrTy; 601 602 // MessengerTy - Type of the messenger (shown as IMP above) 603 const llvm::FunctionType *MessengerTy; 604 605 // SuperMessageRefTy - LLVM for: 606 // struct _super_message_ref_t { 607 // SUPER_IMP messenger; 608 // SEL name; 609 // }; 610 const llvm::StructType *SuperMessageRefTy; 611 612 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 613 const llvm::Type *SuperMessageRefPtrTy; 614 615 llvm::Constant *getMessageSendFixupFn() { 616 // id objc_msgSend_fixup(id, struct message_ref_t*, ...) 617 std::vector<const llvm::Type*> Params; 618 Params.push_back(ObjectPtrTy); 619 Params.push_back(MessageRefPtrTy); 620 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 621 Params, true), 622 "objc_msgSend_fixup"); 623 } 624 625 llvm::Constant *getMessageSendFpretFixupFn() { 626 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...) 627 std::vector<const llvm::Type*> Params; 628 Params.push_back(ObjectPtrTy); 629 Params.push_back(MessageRefPtrTy); 630 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 631 Params, true), 632 "objc_msgSend_fpret_fixup"); 633 } 634 635 llvm::Constant *getMessageSendStretFixupFn() { 636 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...) 637 std::vector<const llvm::Type*> Params; 638 Params.push_back(ObjectPtrTy); 639 Params.push_back(MessageRefPtrTy); 640 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 641 Params, true), 642 "objc_msgSend_stret_fixup"); 643 } 644 645 llvm::Constant *getMessageSendIdFixupFn() { 646 // id objc_msgSendId_fixup(id, struct message_ref_t*, ...) 647 std::vector<const llvm::Type*> Params; 648 Params.push_back(ObjectPtrTy); 649 Params.push_back(MessageRefPtrTy); 650 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 651 Params, true), 652 "objc_msgSendId_fixup"); 653 } 654 655 llvm::Constant *getMessageSendIdStretFixupFn() { 656 // id objc_msgSendId_stret_fixup(id, struct message_ref_t*, ...) 657 std::vector<const llvm::Type*> Params; 658 Params.push_back(ObjectPtrTy); 659 Params.push_back(MessageRefPtrTy); 660 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 661 Params, true), 662 "objc_msgSendId_stret_fixup"); 663 } 664 llvm::Constant *getMessageSendSuper2FixupFn() { 665 // id objc_msgSendSuper2_fixup (struct objc_super *, 666 // struct _super_message_ref_t*, ...) 667 std::vector<const llvm::Type*> Params; 668 Params.push_back(SuperPtrTy); 669 Params.push_back(SuperMessageRefPtrTy); 670 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 671 Params, true), 672 "objc_msgSendSuper2_fixup"); 673 } 674 675 llvm::Constant *getMessageSendSuper2StretFixupFn() { 676 // id objc_msgSendSuper2_stret_fixup(struct objc_super *, 677 // struct _super_message_ref_t*, ...) 678 std::vector<const llvm::Type*> Params; 679 Params.push_back(SuperPtrTy); 680 Params.push_back(SuperMessageRefPtrTy); 681 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 682 Params, true), 683 "objc_msgSendSuper2_stret_fixup"); 684 } 685 686 687 688 /// EHPersonalityPtr - LLVM value for an i8* to the Objective-C 689 /// exception personality function. 690 llvm::Value *getEHPersonalityPtr() { 691 llvm::Constant *Personality = 692 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty, 693 std::vector<const llvm::Type*>(), 694 true), 695 "__objc_personality_v0"); 696 return llvm::ConstantExpr::getBitCast(Personality, Int8PtrTy); 697 } 698 699 llvm::Constant *getUnwindResumeOrRethrowFn() { 700 std::vector<const llvm::Type*> Params; 701 Params.push_back(Int8PtrTy); 702 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 703 Params, false), 704 "_Unwind_Resume_or_Rethrow"); 705 } 706 707 llvm::Constant *getObjCEndCatchFn() { 708 std::vector<const llvm::Type*> Params; 709 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 710 Params, false), 711 "objc_end_catch"); 712 713 } 714 715 llvm::Constant *getObjCBeginCatchFn() { 716 std::vector<const llvm::Type*> Params; 717 Params.push_back(Int8PtrTy); 718 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy, 719 Params, false), 720 "objc_begin_catch"); 721 } 722 723 const llvm::StructType *EHTypeTy; 724 const llvm::Type *EHTypePtrTy; 725 726 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); 727 ~ObjCNonFragileABITypesHelper(){} 728 }; 729 730 class CGObjCCommonMac : public CodeGen::CGObjCRuntime { 731 public: 732 // FIXME - accessibility 733 class GC_IVAR { 734 public: 735 unsigned ivar_bytepos; 736 unsigned ivar_size; 737 GC_IVAR(unsigned bytepos = 0, unsigned size = 0) 738 : ivar_bytepos(bytepos), ivar_size(size) {} 739 740 // Allow sorting based on byte pos. 741 bool operator<(const GC_IVAR &b) const { 742 return ivar_bytepos < b.ivar_bytepos; 743 } 744 }; 745 746 class SKIP_SCAN { 747 public: 748 unsigned skip; 749 unsigned scan; 750 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0) 751 : skip(_skip), scan(_scan) {} 752 }; 753 754 protected: 755 CodeGen::CodeGenModule &CGM; 756 // FIXME! May not be needing this after all. 757 unsigned ObjCABI; 758 759 // gc ivar layout bitmap calculation helper caches. 760 llvm::SmallVector<GC_IVAR, 16> SkipIvars; 761 llvm::SmallVector<GC_IVAR, 16> IvarsInfo; 762 763 /// LazySymbols - Symbols to generate a lazy reference for. See 764 /// DefinedSymbols and FinishModule(). 765 std::set<IdentifierInfo*> LazySymbols; 766 767 /// DefinedSymbols - External symbols which are defined by this 768 /// module. The symbols in this list and LazySymbols are used to add 769 /// special linker symbols which ensure that Objective-C modules are 770 /// linked properly. 771 std::set<IdentifierInfo*> DefinedSymbols; 772 773 /// ClassNames - uniqued class names. 774 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 775 776 /// MethodVarNames - uniqued method variable names. 777 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 778 779 /// MethodVarTypes - uniqued method type signatures. We have to use 780 /// a StringMap here because have no other unique reference. 781 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 782 783 /// MethodDefinitions - map of methods which have been defined in 784 /// this translation unit. 785 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 786 787 /// PropertyNames - uniqued method variable names. 788 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 789 790 /// ClassReferences - uniqued class references. 791 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 792 793 /// SelectorReferences - uniqued selector references. 794 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 795 796 /// Protocols - Protocols for which an objc_protocol structure has 797 /// been emitted. Forward declarations are handled by creating an 798 /// empty structure whose initializer is filled in when/if defined. 799 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 800 801 /// DefinedProtocols - Protocols which have actually been 802 /// defined. We should not need this, see FIXME in GenerateProtocol. 803 llvm::DenseSet<IdentifierInfo*> DefinedProtocols; 804 805 /// DefinedClasses - List of defined classes. 806 std::vector<llvm::GlobalValue*> DefinedClasses; 807 808 /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 809 std::vector<llvm::GlobalValue*> DefinedNonLazyClasses; 810 811 /// DefinedCategories - List of defined categories. 812 std::vector<llvm::GlobalValue*> DefinedCategories; 813 814 /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 815 std::vector<llvm::GlobalValue*> DefinedNonLazyCategories; 816 817 /// UsedGlobals - List of globals to pack into the llvm.used metadata 818 /// to prevent them from being clobbered. 819 std::vector<llvm::GlobalVariable*> UsedGlobals; 820 821 /// GetNameForMethod - Return a name for the given method. 822 /// \param[out] NameOut - The return value. 823 void GetNameForMethod(const ObjCMethodDecl *OMD, 824 const ObjCContainerDecl *CD, 825 std::string &NameOut); 826 827 /// GetMethodVarName - Return a unique constant for the given 828 /// selector's name. The return value has type char *. 829 llvm::Constant *GetMethodVarName(Selector Sel); 830 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 831 llvm::Constant *GetMethodVarName(const std::string &Name); 832 833 /// GetMethodVarType - Return a unique constant for the given 834 /// selector's name. The return value has type char *. 835 836 // FIXME: This is a horrible name. 837 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D); 838 llvm::Constant *GetMethodVarType(const FieldDecl *D); 839 840 /// GetPropertyName - Return a unique constant for the given 841 /// name. The return value has type char *. 842 llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 843 844 // FIXME: This can be dropped once string functions are unified. 845 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 846 const Decl *Container); 847 848 /// GetClassName - Return a unique constant for the given selector's 849 /// name. The return value has type char *. 850 llvm::Constant *GetClassName(IdentifierInfo *Ident); 851 852 /// BuildIvarLayout - Builds ivar layout bitmap for the class 853 /// implementation for the __strong or __weak case. 854 /// 855 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, 856 bool ForStrongLayout); 857 858 void BuildAggrIvarRecordLayout(const RecordType *RT, 859 unsigned int BytePos, bool ForStrongLayout, 860 bool &HasUnion); 861 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 862 const llvm::StructLayout *Layout, 863 const RecordDecl *RD, 864 const llvm::SmallVectorImpl<FieldDecl*> &RecFields, 865 unsigned int BytePos, bool ForStrongLayout, 866 bool &HasUnion); 867 868 /// GetIvarLayoutName - Returns a unique constant for the given 869 /// ivar layout bitmap. 870 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, 871 const ObjCCommonTypesHelper &ObjCTypes); 872 873 /// EmitPropertyList - Emit the given property list. The return 874 /// value has type PropertyListPtrTy. 875 llvm::Constant *EmitPropertyList(const std::string &Name, 876 const Decl *Container, 877 const ObjCContainerDecl *OCD, 878 const ObjCCommonTypesHelper &ObjCTypes); 879 880 /// GetProtocolRef - Return a reference to the internal protocol 881 /// description, creating an empty one if it has not been 882 /// defined. The return value has type ProtocolPtrTy. 883 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); 884 885 /// CreateMetadataVar - Create a global variable with internal 886 /// linkage for use by the Objective-C runtime. 887 /// 888 /// This is a convenience wrapper which not only creates the 889 /// variable, but also sets the section and alignment and adds the 890 /// global to the UsedGlobals list. 891 /// 892 /// \param Name - The variable name. 893 /// \param Init - The variable initializer; this is also used to 894 /// define the type of the variable. 895 /// \param Section - The section the variable should go into, or 0. 896 /// \param Align - The alignment for the variable, or 0. 897 /// \param AddToUsed - Whether the variable should be added to 898 /// "llvm.used". 899 llvm::GlobalVariable *CreateMetadataVar(const std::string &Name, 900 llvm::Constant *Init, 901 const char *Section, 902 unsigned Align, 903 bool AddToUsed); 904 905 CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF, 906 QualType ResultType, 907 llvm::Value *Sel, 908 llvm::Value *Arg0, 909 QualType Arg0Ty, 910 bool IsSuper, 911 const CallArgList &CallArgs, 912 const ObjCCommonTypesHelper &ObjCTypes); 913 914 public: 915 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) 916 { } 917 918 virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *SL); 919 920 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 921 const ObjCContainerDecl *CD=0); 922 923 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 924 925 /// GetOrEmitProtocol - Get the protocol object for the given 926 /// declaration, emitting it if necessary. The return value has type 927 /// ProtocolPtrTy. 928 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0; 929 930 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 931 /// object for the given declaration, emitting it if needed. These 932 /// forward references will be filled in with empty bodies if no 933 /// definition is seen. The return value has type ProtocolPtrTy. 934 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0; 935 }; 936 937 class CGObjCMac : public CGObjCCommonMac { 938 private: 939 ObjCTypesHelper ObjCTypes; 940 /// EmitImageInfo - Emit the image info marker used to encode some module 941 /// level information. 942 void EmitImageInfo(); 943 944 /// EmitModuleInfo - Another marker encoding module level 945 /// information. 946 void EmitModuleInfo(); 947 948 /// EmitModuleSymols - Emit module symbols, the list of defined 949 /// classes and categories. The result has type SymtabPtrTy. 950 llvm::Constant *EmitModuleSymbols(); 951 952 /// FinishModule - Write out global data structures at the end of 953 /// processing a translation unit. 954 void FinishModule(); 955 956 /// EmitClassExtension - Generate the class extension structure used 957 /// to store the weak ivar layout and properties. The return value 958 /// has type ClassExtensionPtrTy. 959 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 960 961 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 962 /// for the given class. 963 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 964 const ObjCInterfaceDecl *ID); 965 966 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 967 QualType ResultType, 968 Selector Sel, 969 llvm::Value *Arg0, 970 QualType Arg0Ty, 971 bool IsSuper, 972 const CallArgList &CallArgs); 973 974 /// EmitIvarList - Emit the ivar list for the given 975 /// implementation. If ForClass is true the list of class ivars 976 /// (i.e. metaclass ivars) is emitted, otherwise the list of 977 /// interface ivars will be emitted. The return value has type 978 /// IvarListPtrTy. 979 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 980 bool ForClass); 981 982 /// EmitMetaClass - Emit a forward reference to the class structure 983 /// for the metaclass of the given interface. The return value has 984 /// type ClassPtrTy. 985 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 986 987 /// EmitMetaClass - Emit a class structure for the metaclass of the 988 /// given implementation. The return value has type ClassPtrTy. 989 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 990 llvm::Constant *Protocols, 991 const ConstantVector &Methods); 992 993 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 994 995 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 996 997 /// EmitMethodList - Emit the method list for the given 998 /// implementation. The return value has type MethodListPtrTy. 999 llvm::Constant *EmitMethodList(const std::string &Name, 1000 const char *Section, 1001 const ConstantVector &Methods); 1002 1003 /// EmitMethodDescList - Emit a method description list for a list of 1004 /// method declarations. 1005 /// - TypeName: The name for the type containing the methods. 1006 /// - IsProtocol: True iff these methods are for a protocol. 1007 /// - ClassMethds: True iff these are class methods. 1008 /// - Required: When true, only "required" methods are 1009 /// listed. Similarly, when false only "optional" methods are 1010 /// listed. For classes this should always be true. 1011 /// - begin, end: The method list to output. 1012 /// 1013 /// The return value has type MethodDescriptionListPtrTy. 1014 llvm::Constant *EmitMethodDescList(const std::string &Name, 1015 const char *Section, 1016 const ConstantVector &Methods); 1017 1018 /// GetOrEmitProtocol - Get the protocol object for the given 1019 /// declaration, emitting it if necessary. The return value has type 1020 /// ProtocolPtrTy. 1021 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 1022 1023 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1024 /// object for the given declaration, emitting it if needed. These 1025 /// forward references will be filled in with empty bodies if no 1026 /// definition is seen. The return value has type ProtocolPtrTy. 1027 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 1028 1029 /// EmitProtocolExtension - Generate the protocol extension 1030 /// structure used to store optional instance and class methods, and 1031 /// protocol properties. The return value has type 1032 /// ProtocolExtensionPtrTy. 1033 llvm::Constant * 1034 EmitProtocolExtension(const ObjCProtocolDecl *PD, 1035 const ConstantVector &OptInstanceMethods, 1036 const ConstantVector &OptClassMethods); 1037 1038 /// EmitProtocolList - Generate the list of referenced 1039 /// protocols. The return value has type ProtocolListPtrTy. 1040 llvm::Constant *EmitProtocolList(const std::string &Name, 1041 ObjCProtocolDecl::protocol_iterator begin, 1042 ObjCProtocolDecl::protocol_iterator end); 1043 1044 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 1045 /// for the given selector. 1046 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel); 1047 1048 public: 1049 CGObjCMac(CodeGen::CodeGenModule &cgm); 1050 1051 virtual llvm::Function *ModuleInitFunction(); 1052 1053 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1054 QualType ResultType, 1055 Selector Sel, 1056 llvm::Value *Receiver, 1057 bool IsClassMessage, 1058 const CallArgList &CallArgs, 1059 const ObjCMethodDecl *Method); 1060 1061 virtual CodeGen::RValue 1062 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1063 QualType ResultType, 1064 Selector Sel, 1065 const ObjCInterfaceDecl *Class, 1066 bool isCategoryImpl, 1067 llvm::Value *Receiver, 1068 bool IsClassMessage, 1069 const CallArgList &CallArgs); 1070 1071 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 1072 const ObjCInterfaceDecl *ID); 1073 1074 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); 1075 1076 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1077 /// untyped one. 1078 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1079 const ObjCMethodDecl *Method); 1080 1081 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 1082 1083 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1084 1085 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1086 const ObjCProtocolDecl *PD); 1087 1088 virtual llvm::Constant *GetPropertyGetFunction(); 1089 virtual llvm::Constant *GetPropertySetFunction(); 1090 virtual llvm::Constant *EnumerationMutationFunction(); 1091 1092 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1093 const Stmt &S); 1094 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1095 const ObjCAtThrowStmt &S); 1096 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1097 llvm::Value *AddrWeakObj); 1098 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1099 llvm::Value *src, llvm::Value *dst); 1100 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1101 llvm::Value *src, llvm::Value *dest); 1102 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1103 llvm::Value *src, llvm::Value *dest); 1104 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1105 llvm::Value *src, llvm::Value *dest); 1106 1107 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1108 QualType ObjectTy, 1109 llvm::Value *BaseValue, 1110 const ObjCIvarDecl *Ivar, 1111 unsigned CVRQualifiers); 1112 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1113 const ObjCInterfaceDecl *Interface, 1114 const ObjCIvarDecl *Ivar); 1115 }; 1116 1117 class CGObjCNonFragileABIMac : public CGObjCCommonMac { 1118 private: 1119 ObjCNonFragileABITypesHelper ObjCTypes; 1120 llvm::GlobalVariable* ObjCEmptyCacheVar; 1121 llvm::GlobalVariable* ObjCEmptyVtableVar; 1122 1123 /// SuperClassReferences - uniqued super class references. 1124 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences; 1125 1126 /// MetaClassReferences - uniqued meta class references. 1127 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences; 1128 1129 /// EHTypeReferences - uniqued class ehtype references. 1130 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences; 1131 1132 /// NonLegacyDispatchMethods - List of methods for which we do *not* generate 1133 /// legacy messaging dispatch. 1134 llvm::DenseSet<Selector> NonLegacyDispatchMethods; 1135 1136 /// LegacyDispatchedSelector - Returns true if SEL is not in the list of 1137 /// NonLegacyDispatchMethods; false otherwise. 1138 bool LegacyDispatchedSelector(Selector Sel); 1139 1140 /// FinishNonFragileABIModule - Write out global data structures at the end of 1141 /// processing a translation unit. 1142 void FinishNonFragileABIModule(); 1143 1144 /// AddModuleClassList - Add the given list of class pointers to the 1145 /// module with the provided symbol and section names. 1146 void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container, 1147 const char *SymbolName, 1148 const char *SectionName); 1149 1150 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 1151 unsigned InstanceStart, 1152 unsigned InstanceSize, 1153 const ObjCImplementationDecl *ID); 1154 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, 1155 llvm::Constant *IsAGV, 1156 llvm::Constant *SuperClassGV, 1157 llvm::Constant *ClassRoGV, 1158 bool HiddenVisibility); 1159 1160 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 1161 1162 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 1163 1164 /// EmitMethodList - Emit the method list for the given 1165 /// implementation. The return value has type MethodListnfABITy. 1166 llvm::Constant *EmitMethodList(const std::string &Name, 1167 const char *Section, 1168 const ConstantVector &Methods); 1169 /// EmitIvarList - Emit the ivar list for the given 1170 /// implementation. If ForClass is true the list of class ivars 1171 /// (i.e. metaclass ivars) is emitted, otherwise the list of 1172 /// interface ivars will be emitted. The return value has type 1173 /// IvarListnfABIPtrTy. 1174 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); 1175 1176 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 1177 const ObjCIvarDecl *Ivar, 1178 unsigned long int offset); 1179 1180 /// GetOrEmitProtocol - Get the protocol object for the given 1181 /// declaration, emitting it if necessary. The return value has type 1182 /// ProtocolPtrTy. 1183 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 1184 1185 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1186 /// object for the given declaration, emitting it if needed. These 1187 /// forward references will be filled in with empty bodies if no 1188 /// definition is seen. The return value has type ProtocolPtrTy. 1189 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 1190 1191 /// EmitProtocolList - Generate the list of referenced 1192 /// protocols. The return value has type ProtocolListPtrTy. 1193 llvm::Constant *EmitProtocolList(const std::string &Name, 1194 ObjCProtocolDecl::protocol_iterator begin, 1195 ObjCProtocolDecl::protocol_iterator end); 1196 1197 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 1198 QualType ResultType, 1199 Selector Sel, 1200 llvm::Value *Receiver, 1201 QualType Arg0Ty, 1202 bool IsSuper, 1203 const CallArgList &CallArgs); 1204 1205 /// GetClassGlobal - Return the global variable for the Objective-C 1206 /// class of the given name. 1207 llvm::GlobalVariable *GetClassGlobal(const std::string &Name); 1208 1209 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 1210 /// for the given class reference. 1211 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 1212 const ObjCInterfaceDecl *ID); 1213 1214 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 1215 /// for the given super class reference. 1216 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder, 1217 const ObjCInterfaceDecl *ID); 1218 1219 /// EmitMetaClassRef - Return a Value * of the address of _class_t 1220 /// meta-data 1221 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder, 1222 const ObjCInterfaceDecl *ID); 1223 1224 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 1225 /// the given ivar. 1226 /// 1227 llvm::GlobalVariable * ObjCIvarOffsetVariable( 1228 const ObjCInterfaceDecl *ID, 1229 const ObjCIvarDecl *Ivar); 1230 1231 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 1232 /// for the given selector. 1233 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel); 1234 1235 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C 1236 /// interface. The return value has type EHTypePtrTy. 1237 llvm::Value *GetInterfaceEHType(const ObjCInterfaceDecl *ID, 1238 bool ForDefinition); 1239 1240 const char *getMetaclassSymbolPrefix() const { 1241 return "OBJC_METACLASS_$_"; 1242 } 1243 1244 const char *getClassSymbolPrefix() const { 1245 return "OBJC_CLASS_$_"; 1246 } 1247 1248 void GetClassSizeInfo(const ObjCImplementationDecl *OID, 1249 uint32_t &InstanceStart, 1250 uint32_t &InstanceSize); 1251 1252 // Shamelessly stolen from Analysis/CFRefCount.cpp 1253 Selector GetNullarySelector(const char* name) const { 1254 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 1255 return CGM.getContext().Selectors.getSelector(0, &II); 1256 } 1257 1258 Selector GetUnarySelector(const char* name) const { 1259 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 1260 return CGM.getContext().Selectors.getSelector(1, &II); 1261 } 1262 1263 /// ImplementationIsNonLazy - Check whether the given category or 1264 /// class implementation is "non-lazy". 1265 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const; 1266 1267 public: 1268 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); 1269 // FIXME. All stubs for now! 1270 virtual llvm::Function *ModuleInitFunction(); 1271 1272 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1273 QualType ResultType, 1274 Selector Sel, 1275 llvm::Value *Receiver, 1276 bool IsClassMessage, 1277 const CallArgList &CallArgs, 1278 const ObjCMethodDecl *Method); 1279 1280 virtual CodeGen::RValue 1281 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1282 QualType ResultType, 1283 Selector Sel, 1284 const ObjCInterfaceDecl *Class, 1285 bool isCategoryImpl, 1286 llvm::Value *Receiver, 1287 bool IsClassMessage, 1288 const CallArgList &CallArgs); 1289 1290 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 1291 const ObjCInterfaceDecl *ID); 1292 1293 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel) 1294 { return EmitSelector(Builder, Sel); } 1295 1296 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1297 /// untyped one. 1298 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1299 const ObjCMethodDecl *Method) 1300 { return EmitSelector(Builder, Method->getSelector()); } 1301 1302 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 1303 1304 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1305 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1306 const ObjCProtocolDecl *PD); 1307 1308 virtual llvm::Constant *GetPropertyGetFunction() { 1309 return ObjCTypes.getGetPropertyFn(); 1310 } 1311 virtual llvm::Constant *GetPropertySetFunction() { 1312 return ObjCTypes.getSetPropertyFn(); 1313 } 1314 virtual llvm::Constant *EnumerationMutationFunction() { 1315 return ObjCTypes.getEnumerationMutationFn(); 1316 } 1317 1318 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1319 const Stmt &S); 1320 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1321 const ObjCAtThrowStmt &S); 1322 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1323 llvm::Value *AddrWeakObj); 1324 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1325 llvm::Value *src, llvm::Value *dst); 1326 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1327 llvm::Value *src, llvm::Value *dest); 1328 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1329 llvm::Value *src, llvm::Value *dest); 1330 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1331 llvm::Value *src, llvm::Value *dest); 1332 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1333 QualType ObjectTy, 1334 llvm::Value *BaseValue, 1335 const ObjCIvarDecl *Ivar, 1336 unsigned CVRQualifiers); 1337 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1338 const ObjCInterfaceDecl *Interface, 1339 const ObjCIvarDecl *Ivar); 1340 }; 1341 1342 } // end anonymous namespace 1343 1344 /* *** Helper Functions *** */ 1345 1346 /// getConstantGEP() - Help routine to construct simple GEPs. 1347 static llvm::Constant *getConstantGEP(llvm::Constant *C, 1348 unsigned idx0, 1349 unsigned idx1) { 1350 llvm::Value *Idxs[] = { 1351 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0), 1352 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1) 1353 }; 1354 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2); 1355 } 1356 1357 /// hasObjCExceptionAttribute - Return true if this class or any super 1358 /// class has the __objc_exception__ attribute. 1359 static bool hasObjCExceptionAttribute(const ObjCInterfaceDecl *OID) { 1360 if (OID->hasAttr<ObjCExceptionAttr>()) 1361 return true; 1362 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 1363 return hasObjCExceptionAttribute(Super); 1364 return false; 1365 } 1366 1367 /* *** CGObjCMac Public Interface *** */ 1368 1369 CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), 1370 ObjCTypes(cgm) 1371 { 1372 ObjCABI = 1; 1373 EmitImageInfo(); 1374 } 1375 1376 /// GetClass - Return a reference to the class for the given interface 1377 /// decl. 1378 llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder, 1379 const ObjCInterfaceDecl *ID) { 1380 return EmitClassRef(Builder, ID); 1381 } 1382 1383 /// GetSelector - Return the pointer to the unique'd string for this selector. 1384 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) { 1385 return EmitSelector(Builder, Sel); 1386 } 1387 llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 1388 *Method) { 1389 return EmitSelector(Builder, Method->getSelector()); 1390 } 1391 1392 /// Generate a constant CFString object. 1393 /* 1394 struct __builtin_CFString { 1395 const int *isa; // point to __CFConstantStringClassReference 1396 int flags; 1397 const char *str; 1398 long length; 1399 }; 1400 */ 1401 1402 llvm::Constant *CGObjCCommonMac::GenerateConstantString( 1403 const ObjCStringLiteral *SL) { 1404 return CGM.GetAddrOfConstantCFString(SL->getString()); 1405 } 1406 1407 /// Generates a message send where the super is the receiver. This is 1408 /// a message send to self with special delivery semantics indicating 1409 /// which class's method should be called. 1410 CodeGen::RValue 1411 CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1412 QualType ResultType, 1413 Selector Sel, 1414 const ObjCInterfaceDecl *Class, 1415 bool isCategoryImpl, 1416 llvm::Value *Receiver, 1417 bool IsClassMessage, 1418 const CodeGen::CallArgList &CallArgs) { 1419 // Create and init a super structure; this is a (receiver, class) 1420 // pair we will pass to objc_msgSendSuper. 1421 llvm::Value *ObjCSuper = 1422 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super"); 1423 llvm::Value *ReceiverAsObject = 1424 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 1425 CGF.Builder.CreateStore(ReceiverAsObject, 1426 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 1427 1428 // If this is a class message the metaclass is passed as the target. 1429 llvm::Value *Target; 1430 if (IsClassMessage) { 1431 if (isCategoryImpl) { 1432 // Message sent to 'super' in a class method defined in a category 1433 // implementation requires an odd treatment. 1434 // If we are in a class method, we must retrieve the 1435 // _metaclass_ for the current class, pointed at by 1436 // the class's "isa" pointer. The following assumes that 1437 // isa" is the first ivar in a class (which it must be). 1438 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1439 Target = CGF.Builder.CreateStructGEP(Target, 0); 1440 Target = CGF.Builder.CreateLoad(Target); 1441 } 1442 else { 1443 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 1444 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 1445 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 1446 Target = Super; 1447 } 1448 } else { 1449 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1450 } 1451 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 1452 // ObjCTypes types. 1453 const llvm::Type *ClassTy = 1454 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 1455 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 1456 CGF.Builder.CreateStore(Target, 1457 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 1458 return EmitLegacyMessageSend(CGF, ResultType, 1459 EmitSelector(CGF.Builder, Sel), 1460 ObjCSuper, ObjCTypes.SuperPtrCTy, 1461 true, CallArgs, ObjCTypes); 1462 } 1463 1464 /// Generate code for a message send expression. 1465 CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1466 QualType ResultType, 1467 Selector Sel, 1468 llvm::Value *Receiver, 1469 bool IsClassMessage, 1470 const CallArgList &CallArgs, 1471 const ObjCMethodDecl *Method) { 1472 return EmitLegacyMessageSend(CGF, ResultType, 1473 EmitSelector(CGF.Builder, Sel), 1474 Receiver, CGF.getContext().getObjCIdType(), 1475 false, CallArgs, ObjCTypes); 1476 } 1477 1478 CodeGen::RValue CGObjCCommonMac::EmitLegacyMessageSend( 1479 CodeGen::CodeGenFunction &CGF, 1480 QualType ResultType, 1481 llvm::Value *Sel, 1482 llvm::Value *Arg0, 1483 QualType Arg0Ty, 1484 bool IsSuper, 1485 const CallArgList &CallArgs, 1486 const ObjCCommonTypesHelper &ObjCTypes) { 1487 CallArgList ActualArgs; 1488 if (!IsSuper) 1489 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp"); 1490 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); 1491 ActualArgs.push_back(std::make_pair(RValue::get(Sel), 1492 CGF.getContext().getObjCSelType())); 1493 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 1494 1495 CodeGenTypes &Types = CGM.getTypes(); 1496 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); 1497 // In 64bit ABI, type must be assumed VARARG. In 32bit abi, 1498 // it seems not to matter. 1499 const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo, (ObjCABI == 2)); 1500 1501 llvm::Constant *Fn = NULL; 1502 if (CGM.ReturnTypeUsesSret(FnInfo)) { 1503 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) 1504 : ObjCTypes.getSendStretFn(IsSuper); 1505 } else if (ResultType->isFloatingType()) { 1506 if (ObjCABI == 2) { 1507 if (const BuiltinType *BT = ResultType->getAsBuiltinType()) { 1508 BuiltinType::Kind k = BT->getKind(); 1509 Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper) 1510 : ObjCTypes.getSendFn2(IsSuper); 1511 } else { 1512 Fn = ObjCTypes.getSendFn2(IsSuper); 1513 } 1514 } 1515 else 1516 // FIXME. This currently matches gcc's API for x86-32. May need to change 1517 // for others if we have their API. 1518 Fn = ObjCTypes.getSendFpretFn(IsSuper); 1519 } else { 1520 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper) 1521 : ObjCTypes.getSendFn(IsSuper); 1522 } 1523 assert(Fn && "EmitLegacyMessageSend - unknown API"); 1524 Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy)); 1525 return CGF.EmitCall(FnInfo, Fn, ActualArgs); 1526 } 1527 1528 llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, 1529 const ObjCProtocolDecl *PD) { 1530 // FIXME: I don't understand why gcc generates this, or where it is 1531 // resolved. Investigate. Its also wasteful to look this up over and over. 1532 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1533 1534 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 1535 ObjCTypes.ExternalProtocolPtrTy); 1536 } 1537 1538 void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 1539 // FIXME: We shouldn't need this, the protocol decl should contain enough 1540 // information to tell us whether this was a declaration or a definition. 1541 DefinedProtocols.insert(PD->getIdentifier()); 1542 1543 // If we have generated a forward reference to this protocol, emit 1544 // it now. Otherwise do nothing, the protocol objects are lazily 1545 // emitted. 1546 if (Protocols.count(PD->getIdentifier())) 1547 GetOrEmitProtocol(PD); 1548 } 1549 1550 llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 1551 if (DefinedProtocols.count(PD->getIdentifier())) 1552 return GetOrEmitProtocol(PD); 1553 return GetOrEmitProtocolRef(PD); 1554 } 1555 1556 /* 1557 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 1558 struct _objc_protocol { 1559 struct _objc_protocol_extension *isa; 1560 char *protocol_name; 1561 struct _objc_protocol_list *protocol_list; 1562 struct _objc__method_prototype_list *instance_methods; 1563 struct _objc__method_prototype_list *class_methods 1564 }; 1565 1566 See EmitProtocolExtension(). 1567 */ 1568 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { 1569 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 1570 1571 // Early exit if a defining object has already been generated. 1572 if (Entry && Entry->hasInitializer()) 1573 return Entry; 1574 1575 // FIXME: I don't understand why gcc generates this, or where it is 1576 // resolved. Investigate. Its also wasteful to look this up over and over. 1577 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1578 1579 const char *ProtocolName = PD->getNameAsCString(); 1580 1581 // Construct method lists. 1582 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1583 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 1584 for (ObjCProtocolDecl::instmeth_iterator 1585 i = PD->instmeth_begin(CGM.getContext()), 1586 e = PD->instmeth_end(CGM.getContext()); i != e; ++i) { 1587 ObjCMethodDecl *MD = *i; 1588 llvm::Constant *C = GetMethodDescriptionConstant(MD); 1589 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1590 OptInstanceMethods.push_back(C); 1591 } else { 1592 InstanceMethods.push_back(C); 1593 } 1594 } 1595 1596 for (ObjCProtocolDecl::classmeth_iterator 1597 i = PD->classmeth_begin(CGM.getContext()), 1598 e = PD->classmeth_end(CGM.getContext()); i != e; ++i) { 1599 ObjCMethodDecl *MD = *i; 1600 llvm::Constant *C = GetMethodDescriptionConstant(MD); 1601 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1602 OptClassMethods.push_back(C); 1603 } else { 1604 ClassMethods.push_back(C); 1605 } 1606 } 1607 1608 std::vector<llvm::Constant*> Values(5); 1609 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods); 1610 Values[1] = GetClassName(PD->getIdentifier()); 1611 Values[2] = 1612 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getNameAsString(), 1613 PD->protocol_begin(), 1614 PD->protocol_end()); 1615 Values[3] = 1616 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" 1617 + PD->getNameAsString(), 1618 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1619 InstanceMethods); 1620 Values[4] = 1621 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" 1622 + PD->getNameAsString(), 1623 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1624 ClassMethods); 1625 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 1626 Values); 1627 1628 if (Entry) { 1629 // Already created, fix the linkage and update the initializer. 1630 Entry->setLinkage(llvm::GlobalValue::InternalLinkage); 1631 Entry->setInitializer(Init); 1632 } else { 1633 Entry = 1634 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 1635 llvm::GlobalValue::InternalLinkage, 1636 Init, 1637 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName, 1638 &CGM.getModule()); 1639 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 1640 Entry->setAlignment(4); 1641 UsedGlobals.push_back(Entry); 1642 // FIXME: Is this necessary? Why only for protocol? 1643 Entry->setAlignment(4); 1644 } 1645 1646 return Entry; 1647 } 1648 1649 llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { 1650 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 1651 1652 if (!Entry) { 1653 // We use the initializer as a marker of whether this is a forward 1654 // reference or not. At module finalization we add the empty 1655 // contents for protocols which were referenced but never defined. 1656 Entry = 1657 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 1658 llvm::GlobalValue::ExternalLinkage, 1659 0, 1660 "\01L_OBJC_PROTOCOL_" + PD->getNameAsString(), 1661 &CGM.getModule()); 1662 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 1663 Entry->setAlignment(4); 1664 UsedGlobals.push_back(Entry); 1665 // FIXME: Is this necessary? Why only for protocol? 1666 Entry->setAlignment(4); 1667 } 1668 1669 return Entry; 1670 } 1671 1672 /* 1673 struct _objc_protocol_extension { 1674 uint32_t size; 1675 struct objc_method_description_list *optional_instance_methods; 1676 struct objc_method_description_list *optional_class_methods; 1677 struct objc_property_list *instance_properties; 1678 }; 1679 */ 1680 llvm::Constant * 1681 CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 1682 const ConstantVector &OptInstanceMethods, 1683 const ConstantVector &OptClassMethods) { 1684 uint64_t Size = 1685 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy); 1686 std::vector<llvm::Constant*> Values(4); 1687 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1688 Values[1] = 1689 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" 1690 + PD->getNameAsString(), 1691 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1692 OptInstanceMethods); 1693 Values[2] = 1694 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" 1695 + PD->getNameAsString(), 1696 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1697 OptClassMethods); 1698 Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + 1699 PD->getNameAsString(), 1700 0, PD, ObjCTypes); 1701 1702 // Return null if no extension bits are used. 1703 if (Values[1]->isNullValue() && Values[2]->isNullValue() && 1704 Values[3]->isNullValue()) 1705 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 1706 1707 llvm::Constant *Init = 1708 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 1709 1710 // No special section, but goes in llvm.used 1711 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getNameAsString(), 1712 Init, 1713 0, 0, true); 1714 } 1715 1716 /* 1717 struct objc_protocol_list { 1718 struct objc_protocol_list *next; 1719 long count; 1720 Protocol *list[]; 1721 }; 1722 */ 1723 llvm::Constant * 1724 CGObjCMac::EmitProtocolList(const std::string &Name, 1725 ObjCProtocolDecl::protocol_iterator begin, 1726 ObjCProtocolDecl::protocol_iterator end) { 1727 std::vector<llvm::Constant*> ProtocolRefs; 1728 1729 for (; begin != end; ++begin) 1730 ProtocolRefs.push_back(GetProtocolRef(*begin)); 1731 1732 // Just return null for empty protocol lists 1733 if (ProtocolRefs.empty()) 1734 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1735 1736 // This list is null terminated. 1737 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 1738 1739 std::vector<llvm::Constant*> Values(3); 1740 // This field is only used by the runtime. 1741 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1742 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 1743 Values[2] = 1744 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 1745 ProtocolRefs.size()), 1746 ProtocolRefs); 1747 1748 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1749 llvm::GlobalVariable *GV = 1750 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1751 4, false); 1752 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 1753 } 1754 1755 /* 1756 struct _objc_property { 1757 const char * const name; 1758 const char * const attributes; 1759 }; 1760 1761 struct _objc_property_list { 1762 uint32_t entsize; // sizeof (struct _objc_property) 1763 uint32_t prop_count; 1764 struct _objc_property[prop_count]; 1765 }; 1766 */ 1767 llvm::Constant *CGObjCCommonMac::EmitPropertyList(const std::string &Name, 1768 const Decl *Container, 1769 const ObjCContainerDecl *OCD, 1770 const ObjCCommonTypesHelper &ObjCTypes) { 1771 std::vector<llvm::Constant*> Properties, Prop(2); 1772 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(CGM.getContext()), 1773 E = OCD->prop_end(CGM.getContext()); I != E; ++I) { 1774 const ObjCPropertyDecl *PD = *I; 1775 Prop[0] = GetPropertyName(PD->getIdentifier()); 1776 Prop[1] = GetPropertyTypeString(PD, Container); 1777 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 1778 Prop)); 1779 } 1780 1781 // Return null for empty list. 1782 if (Properties.empty()) 1783 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 1784 1785 unsigned PropertySize = 1786 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy); 1787 std::vector<llvm::Constant*> Values(3); 1788 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 1789 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 1790 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 1791 Properties.size()); 1792 Values[2] = llvm::ConstantArray::get(AT, Properties); 1793 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1794 1795 llvm::GlobalVariable *GV = 1796 CreateMetadataVar(Name, Init, 1797 (ObjCABI == 2) ? "__DATA, __objc_const" : 1798 "__OBJC,__property,regular,no_dead_strip", 1799 (ObjCABI == 2) ? 8 : 4, 1800 true); 1801 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy); 1802 } 1803 1804 /* 1805 struct objc_method_description_list { 1806 int count; 1807 struct objc_method_description list[]; 1808 }; 1809 */ 1810 llvm::Constant * 1811 CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 1812 std::vector<llvm::Constant*> Desc(2); 1813 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 1814 ObjCTypes.SelectorPtrTy); 1815 Desc[1] = GetMethodVarType(MD); 1816 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 1817 Desc); 1818 } 1819 1820 llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name, 1821 const char *Section, 1822 const ConstantVector &Methods) { 1823 // Return null for empty list. 1824 if (Methods.empty()) 1825 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 1826 1827 std::vector<llvm::Constant*> Values(2); 1828 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 1829 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 1830 Methods.size()); 1831 Values[1] = llvm::ConstantArray::get(AT, Methods); 1832 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1833 1834 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 1835 return llvm::ConstantExpr::getBitCast(GV, 1836 ObjCTypes.MethodDescriptionListPtrTy); 1837 } 1838 1839 /* 1840 struct _objc_category { 1841 char *category_name; 1842 char *class_name; 1843 struct _objc_method_list *instance_methods; 1844 struct _objc_method_list *class_methods; 1845 struct _objc_protocol_list *protocols; 1846 uint32_t size; // <rdar://4585769> 1847 struct _objc_property_list *instance_properties; 1848 }; 1849 */ 1850 void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 1851 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy); 1852 1853 // FIXME: This is poor design, the OCD should have a pointer to the category 1854 // decl. Additionally, note that Category can be null for the @implementation 1855 // w/o an @interface case. Sema should just create one for us as it does for 1856 // @implementation so everyone else can live life under a clear blue sky. 1857 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 1858 const ObjCCategoryDecl *Category = 1859 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 1860 std::string ExtName(Interface->getNameAsString() + "_" + 1861 OCD->getNameAsString()); 1862 1863 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1864 for (ObjCCategoryImplDecl::instmeth_iterator 1865 i = OCD->instmeth_begin(CGM.getContext()), 1866 e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) { 1867 // Instance methods should always be defined. 1868 InstanceMethods.push_back(GetMethodConstant(*i)); 1869 } 1870 for (ObjCCategoryImplDecl::classmeth_iterator 1871 i = OCD->classmeth_begin(CGM.getContext()), 1872 e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) { 1873 // Class methods should always be defined. 1874 ClassMethods.push_back(GetMethodConstant(*i)); 1875 } 1876 1877 std::vector<llvm::Constant*> Values(7); 1878 Values[0] = GetClassName(OCD->getIdentifier()); 1879 Values[1] = GetClassName(Interface->getIdentifier()); 1880 LazySymbols.insert(Interface->getIdentifier()); 1881 Values[2] = 1882 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") + 1883 ExtName, 1884 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1885 InstanceMethods); 1886 Values[3] = 1887 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName, 1888 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1889 ClassMethods); 1890 if (Category) { 1891 Values[4] = 1892 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName, 1893 Category->protocol_begin(), 1894 Category->protocol_end()); 1895 } else { 1896 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1897 } 1898 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1899 1900 // If there is no category @interface then there can be no properties. 1901 if (Category) { 1902 Values[6] = EmitPropertyList(std::string("\01l_OBJC_$_PROP_LIST_") + ExtName, 1903 OCD, Category, ObjCTypes); 1904 } else { 1905 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 1906 } 1907 1908 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 1909 Values); 1910 1911 llvm::GlobalVariable *GV = 1912 CreateMetadataVar(std::string("\01L_OBJC_CATEGORY_")+ExtName, Init, 1913 "__OBJC,__category,regular,no_dead_strip", 1914 4, true); 1915 DefinedCategories.push_back(GV); 1916 } 1917 1918 // FIXME: Get from somewhere? 1919 enum ClassFlags { 1920 eClassFlags_Factory = 0x00001, 1921 eClassFlags_Meta = 0x00002, 1922 // <rdr://5142207> 1923 eClassFlags_HasCXXStructors = 0x02000, 1924 eClassFlags_Hidden = 0x20000, 1925 eClassFlags_ABI2_Hidden = 0x00010, 1926 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 1927 }; 1928 1929 /* 1930 struct _objc_class { 1931 Class isa; 1932 Class super_class; 1933 const char *name; 1934 long version; 1935 long info; 1936 long instance_size; 1937 struct _objc_ivar_list *ivars; 1938 struct _objc_method_list *methods; 1939 struct _objc_cache *cache; 1940 struct _objc_protocol_list *protocols; 1941 // Objective-C 1.0 extensions (<rdr://4585769>) 1942 const char *ivar_layout; 1943 struct _objc_class_ext *ext; 1944 }; 1945 1946 See EmitClassExtension(); 1947 */ 1948 void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 1949 DefinedSymbols.insert(ID->getIdentifier()); 1950 1951 std::string ClassName = ID->getNameAsString(); 1952 // FIXME: Gross 1953 ObjCInterfaceDecl *Interface = 1954 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 1955 llvm::Constant *Protocols = 1956 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getNameAsString(), 1957 Interface->protocol_begin(), 1958 Interface->protocol_end()); 1959 unsigned Flags = eClassFlags_Factory; 1960 unsigned Size = 1961 CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8; 1962 1963 // FIXME: Set CXX-structors flag. 1964 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) 1965 Flags |= eClassFlags_Hidden; 1966 1967 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1968 for (ObjCImplementationDecl::instmeth_iterator 1969 i = ID->instmeth_begin(CGM.getContext()), 1970 e = ID->instmeth_end(CGM.getContext()); i != e; ++i) { 1971 // Instance methods should always be defined. 1972 InstanceMethods.push_back(GetMethodConstant(*i)); 1973 } 1974 for (ObjCImplementationDecl::classmeth_iterator 1975 i = ID->classmeth_begin(CGM.getContext()), 1976 e = ID->classmeth_end(CGM.getContext()); i != e; ++i) { 1977 // Class methods should always be defined. 1978 ClassMethods.push_back(GetMethodConstant(*i)); 1979 } 1980 1981 for (ObjCImplementationDecl::propimpl_iterator 1982 i = ID->propimpl_begin(CGM.getContext()), 1983 e = ID->propimpl_end(CGM.getContext()); i != e; ++i) { 1984 ObjCPropertyImplDecl *PID = *i; 1985 1986 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 1987 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1988 1989 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 1990 if (llvm::Constant *C = GetMethodConstant(MD)) 1991 InstanceMethods.push_back(C); 1992 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 1993 if (llvm::Constant *C = GetMethodConstant(MD)) 1994 InstanceMethods.push_back(C); 1995 } 1996 } 1997 1998 std::vector<llvm::Constant*> Values(12); 1999 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods); 2000 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 2001 // Record a reference to the super class. 2002 LazySymbols.insert(Super->getIdentifier()); 2003 2004 Values[ 1] = 2005 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 2006 ObjCTypes.ClassPtrTy); 2007 } else { 2008 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 2009 } 2010 Values[ 2] = GetClassName(ID->getIdentifier()); 2011 // Version is always 0. 2012 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2013 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 2014 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2015 Values[ 6] = EmitIvarList(ID, false); 2016 Values[ 7] = 2017 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getNameAsString(), 2018 "__OBJC,__inst_meth,regular,no_dead_strip", 2019 InstanceMethods); 2020 // cache is always NULL. 2021 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 2022 Values[ 9] = Protocols; 2023 Values[10] = BuildIvarLayout(ID, true); 2024 Values[11] = EmitClassExtension(ID); 2025 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 2026 Values); 2027 2028 llvm::GlobalVariable *GV = 2029 CreateMetadataVar(std::string("\01L_OBJC_CLASS_")+ClassName, Init, 2030 "__OBJC,__class,regular,no_dead_strip", 2031 4, true); 2032 DefinedClasses.push_back(GV); 2033 } 2034 2035 llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 2036 llvm::Constant *Protocols, 2037 const ConstantVector &Methods) { 2038 unsigned Flags = eClassFlags_Meta; 2039 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy); 2040 2041 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) 2042 Flags |= eClassFlags_Hidden; 2043 2044 std::vector<llvm::Constant*> Values(12); 2045 // The isa for the metaclass is the root of the hierarchy. 2046 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 2047 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 2048 Root = Super; 2049 Values[ 0] = 2050 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 2051 ObjCTypes.ClassPtrTy); 2052 // The super class for the metaclass is emitted as the name of the 2053 // super class. The runtime fixes this up to point to the 2054 // *metaclass* for the super class. 2055 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 2056 Values[ 1] = 2057 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 2058 ObjCTypes.ClassPtrTy); 2059 } else { 2060 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 2061 } 2062 Values[ 2] = GetClassName(ID->getIdentifier()); 2063 // Version is always 0. 2064 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2065 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 2066 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2067 Values[ 6] = EmitIvarList(ID, true); 2068 Values[ 7] = 2069 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), 2070 "__OBJC,__cls_meth,regular,no_dead_strip", 2071 Methods); 2072 // cache is always NULL. 2073 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 2074 Values[ 9] = Protocols; 2075 // ivar_layout for metaclass is always NULL. 2076 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 2077 // The class extension is always unused for metaclasses. 2078 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 2079 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 2080 Values); 2081 2082 std::string Name("\01L_OBJC_METACLASS_"); 2083 Name += ID->getNameAsCString(); 2084 2085 // Check for a forward reference. 2086 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2087 if (GV) { 2088 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2089 "Forward metaclass reference has incorrect type."); 2090 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2091 GV->setInitializer(Init); 2092 } else { 2093 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 2094 llvm::GlobalValue::InternalLinkage, 2095 Init, Name, 2096 &CGM.getModule()); 2097 } 2098 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 2099 GV->setAlignment(4); 2100 UsedGlobals.push_back(GV); 2101 2102 return GV; 2103 } 2104 2105 llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 2106 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString(); 2107 2108 // FIXME: Should we look these up somewhere other than the module. Its a bit 2109 // silly since we only generate these while processing an implementation, so 2110 // exactly one pointer would work if know when we entered/exitted an 2111 // implementation block. 2112 2113 // Check for an existing forward reference. 2114 // Previously, metaclass with internal linkage may have been defined. 2115 // pass 'true' as 2nd argument so it is returned. 2116 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true)) { 2117 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2118 "Forward metaclass reference has incorrect type."); 2119 return GV; 2120 } else { 2121 // Generate as an external reference to keep a consistent 2122 // module. This will be patched up when we emit the metaclass. 2123 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 2124 llvm::GlobalValue::ExternalLinkage, 2125 0, 2126 Name, 2127 &CGM.getModule()); 2128 } 2129 } 2130 2131 /* 2132 struct objc_class_ext { 2133 uint32_t size; 2134 const char *weak_ivar_layout; 2135 struct _objc_property_list *properties; 2136 }; 2137 */ 2138 llvm::Constant * 2139 CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 2140 uint64_t Size = 2141 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy); 2142 2143 std::vector<llvm::Constant*> Values(3); 2144 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 2145 Values[1] = BuildIvarLayout(ID, false); 2146 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getNameAsString(), 2147 ID, ID->getClassInterface(), ObjCTypes); 2148 2149 // Return null if no extension bits are used. 2150 if (Values[1]->isNullValue() && Values[2]->isNullValue()) 2151 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 2152 2153 llvm::Constant *Init = 2154 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 2155 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getNameAsString(), 2156 Init, "__OBJC,__class_ext,regular,no_dead_strip", 2157 4, true); 2158 } 2159 2160 /* 2161 struct objc_ivar { 2162 char *ivar_name; 2163 char *ivar_type; 2164 int ivar_offset; 2165 }; 2166 2167 struct objc_ivar_list { 2168 int ivar_count; 2169 struct objc_ivar list[count]; 2170 }; 2171 */ 2172 llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 2173 bool ForClass) { 2174 std::vector<llvm::Constant*> Ivars, Ivar(3); 2175 2176 // When emitting the root class GCC emits ivar entries for the 2177 // actual class structure. It is not clear if we need to follow this 2178 // behavior; for now lets try and get away with not doing it. If so, 2179 // the cleanest solution would be to make up an ObjCInterfaceDecl 2180 // for the class. 2181 if (ForClass) 2182 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 2183 2184 ObjCInterfaceDecl *OID = 2185 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 2186 2187 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars; 2188 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars); 2189 2190 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) { 2191 ObjCIvarDecl *IVD = OIvars[i]; 2192 // Ignore unnamed bit-fields. 2193 if (!IVD->getDeclName()) 2194 continue; 2195 Ivar[0] = GetMethodVarName(IVD->getIdentifier()); 2196 Ivar[1] = GetMethodVarType(IVD); 2197 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, 2198 ComputeIvarBaseOffset(CGM, OID, IVD)); 2199 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); 2200 } 2201 2202 // Return null for empty list. 2203 if (Ivars.empty()) 2204 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 2205 2206 std::vector<llvm::Constant*> Values(2); 2207 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 2208 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 2209 Ivars.size()); 2210 Values[1] = llvm::ConstantArray::get(AT, Ivars); 2211 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 2212 2213 llvm::GlobalVariable *GV; 2214 if (ForClass) 2215 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getNameAsString(), 2216 Init, "__OBJC,__class_vars,regular,no_dead_strip", 2217 4, true); 2218 else 2219 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" 2220 + ID->getNameAsString(), 2221 Init, "__OBJC,__instance_vars,regular,no_dead_strip", 2222 4, true); 2223 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy); 2224 } 2225 2226 /* 2227 struct objc_method { 2228 SEL method_name; 2229 char *method_types; 2230 void *method; 2231 }; 2232 2233 struct objc_method_list { 2234 struct objc_method_list *obsolete; 2235 int count; 2236 struct objc_method methods_list[count]; 2237 }; 2238 */ 2239 2240 /// GetMethodConstant - Return a struct objc_method constant for the 2241 /// given method if it has been defined. The result is null if the 2242 /// method has not been defined. The return value has type MethodPtrTy. 2243 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 2244 // FIXME: Use DenseMap::lookup 2245 llvm::Function *Fn = MethodDefinitions[MD]; 2246 if (!Fn) 2247 return 0; 2248 2249 std::vector<llvm::Constant*> Method(3); 2250 Method[0] = 2251 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 2252 ObjCTypes.SelectorPtrTy); 2253 Method[1] = GetMethodVarType(MD); 2254 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 2255 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 2256 } 2257 2258 llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name, 2259 const char *Section, 2260 const ConstantVector &Methods) { 2261 // Return null for empty list. 2262 if (Methods.empty()) 2263 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 2264 2265 std::vector<llvm::Constant*> Values(3); 2266 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 2267 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 2268 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 2269 Methods.size()); 2270 Values[2] = llvm::ConstantArray::get(AT, Methods); 2271 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 2272 2273 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 2274 return llvm::ConstantExpr::getBitCast(GV, 2275 ObjCTypes.MethodListPtrTy); 2276 } 2277 2278 llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, 2279 const ObjCContainerDecl *CD) { 2280 std::string Name; 2281 GetNameForMethod(OMD, CD, Name); 2282 2283 CodeGenTypes &Types = CGM.getTypes(); 2284 const llvm::FunctionType *MethodTy = 2285 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 2286 llvm::Function *Method = 2287 llvm::Function::Create(MethodTy, 2288 llvm::GlobalValue::InternalLinkage, 2289 Name, 2290 &CGM.getModule()); 2291 MethodDefinitions.insert(std::make_pair(OMD, Method)); 2292 2293 return Method; 2294 } 2295 2296 llvm::GlobalVariable * 2297 CGObjCCommonMac::CreateMetadataVar(const std::string &Name, 2298 llvm::Constant *Init, 2299 const char *Section, 2300 unsigned Align, 2301 bool AddToUsed) { 2302 const llvm::Type *Ty = Init->getType(); 2303 llvm::GlobalVariable *GV = 2304 new llvm::GlobalVariable(Ty, false, 2305 llvm::GlobalValue::InternalLinkage, 2306 Init, 2307 Name, 2308 &CGM.getModule()); 2309 if (Section) 2310 GV->setSection(Section); 2311 if (Align) 2312 GV->setAlignment(Align); 2313 if (AddToUsed) 2314 UsedGlobals.push_back(GV); 2315 return GV; 2316 } 2317 2318 llvm::Function *CGObjCMac::ModuleInitFunction() { 2319 // Abuse this interface function as a place to finalize. 2320 FinishModule(); 2321 2322 return NULL; 2323 } 2324 2325 llvm::Constant *CGObjCMac::GetPropertyGetFunction() { 2326 return ObjCTypes.getGetPropertyFn(); 2327 } 2328 2329 llvm::Constant *CGObjCMac::GetPropertySetFunction() { 2330 return ObjCTypes.getSetPropertyFn(); 2331 } 2332 2333 llvm::Constant *CGObjCMac::EnumerationMutationFunction() { 2334 return ObjCTypes.getEnumerationMutationFn(); 2335 } 2336 2337 /* 2338 2339 Objective-C setjmp-longjmp (sjlj) Exception Handling 2340 -- 2341 2342 The basic framework for a @try-catch-finally is as follows: 2343 { 2344 objc_exception_data d; 2345 id _rethrow = null; 2346 bool _call_try_exit = true; 2347 2348 objc_exception_try_enter(&d); 2349 if (!setjmp(d.jmp_buf)) { 2350 ... try body ... 2351 } else { 2352 // exception path 2353 id _caught = objc_exception_extract(&d); 2354 2355 // enter new try scope for handlers 2356 if (!setjmp(d.jmp_buf)) { 2357 ... match exception and execute catch blocks ... 2358 2359 // fell off end, rethrow. 2360 _rethrow = _caught; 2361 ... jump-through-finally to finally_rethrow ... 2362 } else { 2363 // exception in catch block 2364 _rethrow = objc_exception_extract(&d); 2365 _call_try_exit = false; 2366 ... jump-through-finally to finally_rethrow ... 2367 } 2368 } 2369 ... jump-through-finally to finally_end ... 2370 2371 finally: 2372 if (_call_try_exit) 2373 objc_exception_try_exit(&d); 2374 2375 ... finally block .... 2376 ... dispatch to finally destination ... 2377 2378 finally_rethrow: 2379 objc_exception_throw(_rethrow); 2380 2381 finally_end: 2382 } 2383 2384 This framework differs slightly from the one gcc uses, in that gcc 2385 uses _rethrow to determine if objc_exception_try_exit should be called 2386 and if the object should be rethrown. This breaks in the face of 2387 throwing nil and introduces unnecessary branches. 2388 2389 We specialize this framework for a few particular circumstances: 2390 2391 - If there are no catch blocks, then we avoid emitting the second 2392 exception handling context. 2393 2394 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id 2395 e)) we avoid emitting the code to rethrow an uncaught exception. 2396 2397 - FIXME: If there is no @finally block we can do a few more 2398 simplifications. 2399 2400 Rethrows and Jumps-Through-Finally 2401 -- 2402 2403 Support for implicit rethrows and jumping through the finally block is 2404 handled by storing the current exception-handling context in 2405 ObjCEHStack. 2406 2407 In order to implement proper @finally semantics, we support one basic 2408 mechanism for jumping through the finally block to an arbitrary 2409 destination. Constructs which generate exits from a @try or @catch 2410 block use this mechanism to implement the proper semantics by chaining 2411 jumps, as necessary. 2412 2413 This mechanism works like the one used for indirect goto: we 2414 arbitrarily assign an ID to each destination and store the ID for the 2415 destination in a variable prior to entering the finally block. At the 2416 end of the finally block we simply create a switch to the proper 2417 destination. 2418 2419 Code gen for @synchronized(expr) stmt; 2420 Effectively generating code for: 2421 objc_sync_enter(expr); 2422 @try stmt @finally { objc_sync_exit(expr); } 2423 */ 2424 2425 void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 2426 const Stmt &S) { 2427 bool isTry = isa<ObjCAtTryStmt>(S); 2428 // Create various blocks we refer to for handling @finally. 2429 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 2430 llvm::BasicBlock *FinallyExit = CGF.createBasicBlock("finally.exit"); 2431 llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit"); 2432 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 2433 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 2434 2435 // For @synchronized, call objc_sync_enter(sync.expr). The 2436 // evaluation of the expression must occur before we enter the 2437 // @synchronized. We can safely avoid a temp here because jumps into 2438 // @synchronized are illegal & this will dominate uses. 2439 llvm::Value *SyncArg = 0; 2440 if (!isTry) { 2441 SyncArg = 2442 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 2443 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 2444 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg); 2445 } 2446 2447 // Push an EH context entry, used for handling rethrows and jumps 2448 // through finally. 2449 CGF.PushCleanupBlock(FinallyBlock); 2450 2451 CGF.ObjCEHValueStack.push_back(0); 2452 2453 // Allocate memory for the exception data and rethrow pointer. 2454 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 2455 "exceptiondata.ptr"); 2456 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy, 2457 "_rethrow"); 2458 llvm::Value *CallTryExitPtr = CGF.CreateTempAlloca(llvm::Type::Int1Ty, 2459 "_call_try_exit"); 2460 CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(), CallTryExitPtr); 2461 2462 // Enter a new try block and call setjmp. 2463 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData); 2464 llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0, 2465 "jmpbufarray"); 2466 JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp"); 2467 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), 2468 JmpBufPtr, "result"); 2469 2470 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 2471 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 2472 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"), 2473 TryHandler, TryBlock); 2474 2475 // Emit the @try block. 2476 CGF.EmitBlock(TryBlock); 2477 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 2478 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 2479 CGF.EmitBranchThroughCleanup(FinallyEnd); 2480 2481 // Emit the "exception in @try" block. 2482 CGF.EmitBlock(TryHandler); 2483 2484 // Retrieve the exception object. We may emit multiple blocks but 2485 // nothing can cross this so the value is already in SSA form. 2486 llvm::Value *Caught = 2487 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 2488 ExceptionData, "caught"); 2489 CGF.ObjCEHValueStack.back() = Caught; 2490 if (!isTry) 2491 { 2492 CGF.Builder.CreateStore(Caught, RethrowPtr); 2493 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(), CallTryExitPtr); 2494 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2495 } 2496 else if (const ObjCAtCatchStmt* CatchStmt = 2497 cast<ObjCAtTryStmt>(S).getCatchStmts()) 2498 { 2499 // Enter a new exception try block (in case a @catch block throws 2500 // an exception). 2501 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData); 2502 2503 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), 2504 JmpBufPtr, "result"); 2505 llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"); 2506 2507 llvm::BasicBlock *CatchBlock = CGF.createBasicBlock("catch"); 2508 llvm::BasicBlock *CatchHandler = CGF.createBasicBlock("catch.handler"); 2509 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock); 2510 2511 CGF.EmitBlock(CatchBlock); 2512 2513 // Handle catch list. As a special case we check if everything is 2514 // matched and avoid generating code for falling off the end if 2515 // so. 2516 bool AllMatched = false; 2517 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 2518 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch"); 2519 2520 const ParmVarDecl *CatchParam = CatchStmt->getCatchParamDecl(); 2521 const PointerType *PT = 0; 2522 2523 // catch(...) always matches. 2524 if (!CatchParam) { 2525 AllMatched = true; 2526 } else { 2527 PT = CatchParam->getType()->getAsPointerType(); 2528 2529 // catch(id e) always matches. 2530 // FIXME: For the time being we also match id<X>; this should 2531 // be rejected by Sema instead. 2532 if ((PT && CGF.getContext().isObjCIdStructType(PT->getPointeeType())) || 2533 CatchParam->getType()->isObjCQualifiedIdType()) 2534 AllMatched = true; 2535 } 2536 2537 if (AllMatched) { 2538 if (CatchParam) { 2539 CGF.EmitLocalBlockVarDecl(*CatchParam); 2540 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 2541 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); 2542 } 2543 2544 CGF.EmitStmt(CatchStmt->getCatchBody()); 2545 CGF.EmitBranchThroughCleanup(FinallyEnd); 2546 break; 2547 } 2548 2549 assert(PT && "Unexpected non-pointer type in @catch"); 2550 QualType T = PT->getPointeeType(); 2551 const ObjCInterfaceType *ObjCType = T->getAsObjCInterfaceType(); 2552 assert(ObjCType && "Catch parameter must have Objective-C type!"); 2553 2554 // Check if the @catch block matches the exception object. 2555 llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl()); 2556 2557 llvm::Value *Match = 2558 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(), 2559 Class, Caught, "match"); 2560 2561 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("matched"); 2562 2563 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"), 2564 MatchedBlock, NextCatchBlock); 2565 2566 // Emit the @catch block. 2567 CGF.EmitBlock(MatchedBlock); 2568 CGF.EmitLocalBlockVarDecl(*CatchParam); 2569 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 2570 2571 llvm::Value *Tmp = 2572 CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(CatchParam->getType()), 2573 "tmp"); 2574 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); 2575 2576 CGF.EmitStmt(CatchStmt->getCatchBody()); 2577 CGF.EmitBranchThroughCleanup(FinallyEnd); 2578 2579 CGF.EmitBlock(NextCatchBlock); 2580 } 2581 2582 if (!AllMatched) { 2583 // None of the handlers caught the exception, so store it to be 2584 // rethrown at the end of the @finally block. 2585 CGF.Builder.CreateStore(Caught, RethrowPtr); 2586 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2587 } 2588 2589 // Emit the exception handler for the @catch blocks. 2590 CGF.EmitBlock(CatchHandler); 2591 CGF.Builder.CreateStore( 2592 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 2593 ExceptionData), 2594 RethrowPtr); 2595 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(), CallTryExitPtr); 2596 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2597 } else { 2598 CGF.Builder.CreateStore(Caught, RethrowPtr); 2599 CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(), CallTryExitPtr); 2600 CGF.EmitBranchThroughCleanup(FinallyRethrow); 2601 } 2602 2603 // Pop the exception-handling stack entry. It is important to do 2604 // this now, because the code in the @finally block is not in this 2605 // context. 2606 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 2607 2608 CGF.ObjCEHValueStack.pop_back(); 2609 2610 // Emit the @finally block. 2611 CGF.EmitBlock(FinallyBlock); 2612 llvm::Value* CallTryExit = CGF.Builder.CreateLoad(CallTryExitPtr, "tmp"); 2613 2614 CGF.Builder.CreateCondBr(CallTryExit, FinallyExit, FinallyNoExit); 2615 2616 CGF.EmitBlock(FinallyExit); 2617 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData); 2618 2619 CGF.EmitBlock(FinallyNoExit); 2620 if (isTry) { 2621 if (const ObjCAtFinallyStmt* FinallyStmt = 2622 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 2623 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 2624 } else { 2625 // Emit objc_sync_exit(expr); as finally's sole statement for 2626 // @synchronized. 2627 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg); 2628 } 2629 2630 // Emit the switch block 2631 if (Info.SwitchBlock) 2632 CGF.EmitBlock(Info.SwitchBlock); 2633 if (Info.EndBlock) 2634 CGF.EmitBlock(Info.EndBlock); 2635 2636 CGF.EmitBlock(FinallyRethrow); 2637 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), 2638 CGF.Builder.CreateLoad(RethrowPtr)); 2639 CGF.Builder.CreateUnreachable(); 2640 2641 CGF.EmitBlock(FinallyEnd); 2642 } 2643 2644 void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 2645 const ObjCAtThrowStmt &S) { 2646 llvm::Value *ExceptionAsObject; 2647 2648 if (const Expr *ThrowExpr = S.getThrowExpr()) { 2649 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 2650 ExceptionAsObject = 2651 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp"); 2652 } else { 2653 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 2654 "Unexpected rethrow outside @catch block."); 2655 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 2656 } 2657 2658 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject); 2659 CGF.Builder.CreateUnreachable(); 2660 2661 // Clear the insertion point to indicate we are in unreachable code. 2662 CGF.Builder.ClearInsertionPoint(); 2663 } 2664 2665 /// EmitObjCWeakRead - Code gen for loading value of a __weak 2666 /// object: objc_read_weak (id *src) 2667 /// 2668 llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 2669 llvm::Value *AddrWeakObj) 2670 { 2671 const llvm::Type* DestTy = 2672 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 2673 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 2674 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 2675 AddrWeakObj, "weakread"); 2676 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 2677 return read_weak; 2678 } 2679 2680 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 2681 /// objc_assign_weak (id src, id *dst) 2682 /// 2683 void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 2684 llvm::Value *src, llvm::Value *dst) 2685 { 2686 const llvm::Type * SrcTy = src->getType(); 2687 if (!isa<llvm::PointerType>(SrcTy)) { 2688 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2689 assert(Size <= 8 && "does not support size > 8"); 2690 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2691 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2692 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2693 } 2694 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2695 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2696 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 2697 src, dst, "weakassign"); 2698 return; 2699 } 2700 2701 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 2702 /// objc_assign_global (id src, id *dst) 2703 /// 2704 void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 2705 llvm::Value *src, llvm::Value *dst) 2706 { 2707 const llvm::Type * SrcTy = src->getType(); 2708 if (!isa<llvm::PointerType>(SrcTy)) { 2709 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2710 assert(Size <= 8 && "does not support size > 8"); 2711 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2712 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2713 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2714 } 2715 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2716 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2717 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 2718 src, dst, "globalassign"); 2719 return; 2720 } 2721 2722 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 2723 /// objc_assign_ivar (id src, id *dst) 2724 /// 2725 void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 2726 llvm::Value *src, llvm::Value *dst) 2727 { 2728 const llvm::Type * SrcTy = src->getType(); 2729 if (!isa<llvm::PointerType>(SrcTy)) { 2730 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2731 assert(Size <= 8 && "does not support size > 8"); 2732 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2733 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2734 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2735 } 2736 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2737 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2738 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignIvarFn(), 2739 src, dst, "assignivar"); 2740 return; 2741 } 2742 2743 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 2744 /// objc_assign_strongCast (id src, id *dst) 2745 /// 2746 void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 2747 llvm::Value *src, llvm::Value *dst) 2748 { 2749 const llvm::Type * SrcTy = src->getType(); 2750 if (!isa<llvm::PointerType>(SrcTy)) { 2751 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 2752 assert(Size <= 8 && "does not support size > 8"); 2753 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 2754 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 2755 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 2756 } 2757 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2758 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2759 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 2760 src, dst, "weakassign"); 2761 return; 2762 } 2763 2764 /// EmitObjCValueForIvar - Code Gen for ivar reference. 2765 /// 2766 LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 2767 QualType ObjectTy, 2768 llvm::Value *BaseValue, 2769 const ObjCIvarDecl *Ivar, 2770 unsigned CVRQualifiers) { 2771 const ObjCInterfaceDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl(); 2772 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 2773 EmitIvarOffset(CGF, ID, Ivar)); 2774 } 2775 2776 llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 2777 const ObjCInterfaceDecl *Interface, 2778 const ObjCIvarDecl *Ivar) { 2779 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); 2780 return llvm::ConstantInt::get( 2781 CGM.getTypes().ConvertType(CGM.getContext().LongTy), 2782 Offset); 2783 } 2784 2785 /* *** Private Interface *** */ 2786 2787 /// EmitImageInfo - Emit the image info marker used to encode some module 2788 /// level information. 2789 /// 2790 /// See: <rdr://4810609&4810587&4810587> 2791 /// struct IMAGE_INFO { 2792 /// unsigned version; 2793 /// unsigned flags; 2794 /// }; 2795 enum ImageInfoFlags { 2796 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what 2797 // this implies. 2798 eImageInfo_GarbageCollected = (1 << 1), 2799 eImageInfo_GCOnly = (1 << 2), 2800 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set. 2801 2802 // A flag indicating that the module has no instances of an 2803 // @synthesize of a superclass variable. <rdar://problem/6803242> 2804 eImageInfo_CorrectedSynthesize = (1 << 4) 2805 }; 2806 2807 void CGObjCMac::EmitImageInfo() { 2808 unsigned version = 0; // Version is unused? 2809 unsigned flags = 0; 2810 2811 // FIXME: Fix and continue? 2812 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 2813 flags |= eImageInfo_GarbageCollected; 2814 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 2815 flags |= eImageInfo_GCOnly; 2816 2817 // We never allow @synthesize of a superclass property. 2818 flags |= eImageInfo_CorrectedSynthesize; 2819 2820 // Emitted as int[2]; 2821 llvm::Constant *values[2] = { 2822 llvm::ConstantInt::get(llvm::Type::Int32Ty, version), 2823 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags) 2824 }; 2825 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2); 2826 2827 const char *Section; 2828 if (ObjCABI == 1) 2829 Section = "__OBJC, __image_info,regular"; 2830 else 2831 Section = "__DATA, __objc_imageinfo, regular, no_dead_strip"; 2832 llvm::GlobalVariable *GV = 2833 CreateMetadataVar("\01L_OBJC_IMAGE_INFO", 2834 llvm::ConstantArray::get(AT, values, 2), 2835 Section, 2836 0, 2837 true); 2838 GV->setConstant(true); 2839 } 2840 2841 2842 // struct objc_module { 2843 // unsigned long version; 2844 // unsigned long size; 2845 // const char *name; 2846 // Symtab symtab; 2847 // }; 2848 2849 // FIXME: Get from somewhere 2850 static const int ModuleVersion = 7; 2851 2852 void CGObjCMac::EmitModuleInfo() { 2853 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy); 2854 2855 std::vector<llvm::Constant*> Values(4); 2856 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion); 2857 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2858 // This used to be the filename, now it is unused. <rdr://4327263> 2859 Values[2] = GetClassName(&CGM.getContext().Idents.get("")); 2860 Values[3] = EmitModuleSymbols(); 2861 CreateMetadataVar("\01L_OBJC_MODULES", 2862 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values), 2863 "__OBJC,__module_info,regular,no_dead_strip", 2864 4, true); 2865 } 2866 2867 llvm::Constant *CGObjCMac::EmitModuleSymbols() { 2868 unsigned NumClasses = DefinedClasses.size(); 2869 unsigned NumCategories = DefinedCategories.size(); 2870 2871 // Return null if no symbols were defined. 2872 if (!NumClasses && !NumCategories) 2873 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 2874 2875 std::vector<llvm::Constant*> Values(5); 2876 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2877 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 2878 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 2879 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 2880 2881 // The runtime expects exactly the list of defined classes followed 2882 // by the list of defined categories, in a single array. 2883 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories); 2884 for (unsigned i=0; i<NumClasses; i++) 2885 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 2886 ObjCTypes.Int8PtrTy); 2887 for (unsigned i=0; i<NumCategories; i++) 2888 Symbols[NumClasses + i] = 2889 llvm::ConstantExpr::getBitCast(DefinedCategories[i], 2890 ObjCTypes.Int8PtrTy); 2891 2892 Values[4] = 2893 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 2894 NumClasses + NumCategories), 2895 Symbols); 2896 2897 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 2898 2899 llvm::GlobalVariable *GV = 2900 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init, 2901 "__OBJC,__symbols,regular,no_dead_strip", 2902 4, true); 2903 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 2904 } 2905 2906 llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder, 2907 const ObjCInterfaceDecl *ID) { 2908 LazySymbols.insert(ID->getIdentifier()); 2909 2910 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; 2911 2912 if (!Entry) { 2913 llvm::Constant *Casted = 2914 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()), 2915 ObjCTypes.ClassPtrTy); 2916 Entry = 2917 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted, 2918 "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 2919 4, true); 2920 } 2921 2922 return Builder.CreateLoad(Entry, false, "tmp"); 2923 } 2924 2925 llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) { 2926 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 2927 2928 if (!Entry) { 2929 llvm::Constant *Casted = 2930 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 2931 ObjCTypes.SelectorPtrTy); 2932 Entry = 2933 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted, 2934 "__OBJC,__message_refs,literal_pointers,no_dead_strip", 2935 4, true); 2936 } 2937 2938 return Builder.CreateLoad(Entry, false, "tmp"); 2939 } 2940 2941 llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 2942 llvm::GlobalVariable *&Entry = ClassNames[Ident]; 2943 2944 if (!Entry) 2945 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 2946 llvm::ConstantArray::get(Ident->getName()), 2947 "__TEXT,__cstring,cstring_literals", 2948 1, true); 2949 2950 return getConstantGEP(Entry, 0, 0); 2951 } 2952 2953 /// GetIvarLayoutName - Returns a unique constant for the given 2954 /// ivar layout bitmap. 2955 llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, 2956 const ObjCCommonTypesHelper &ObjCTypes) { 2957 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 2958 } 2959 2960 static QualType::GCAttrTypes GetGCAttrTypeForType(ASTContext &Ctx, 2961 QualType FQT) { 2962 if (FQT.isObjCGCStrong()) 2963 return QualType::Strong; 2964 2965 if (FQT.isObjCGCWeak()) 2966 return QualType::Weak; 2967 2968 if (Ctx.isObjCObjectPointerType(FQT)) 2969 return QualType::Strong; 2970 2971 if (const PointerType *PT = FQT->getAsPointerType()) 2972 return GetGCAttrTypeForType(Ctx, PT->getPointeeType()); 2973 2974 return QualType::GCNone; 2975 } 2976 2977 void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, 2978 unsigned int BytePos, 2979 bool ForStrongLayout, 2980 bool &HasUnion) { 2981 const RecordDecl *RD = RT->getDecl(); 2982 // FIXME - Use iterator. 2983 llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(CGM.getContext()), 2984 RD->field_end(CGM.getContext())); 2985 const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); 2986 const llvm::StructLayout *RecLayout = 2987 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty)); 2988 2989 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos, 2990 ForStrongLayout, HasUnion); 2991 } 2992 2993 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 2994 const llvm::StructLayout *Layout, 2995 const RecordDecl *RD, 2996 const llvm::SmallVectorImpl<FieldDecl*> &RecFields, 2997 unsigned int BytePos, bool ForStrongLayout, 2998 bool &HasUnion) { 2999 bool IsUnion = (RD && RD->isUnion()); 3000 uint64_t MaxUnionIvarSize = 0; 3001 uint64_t MaxSkippedUnionIvarSize = 0; 3002 FieldDecl *MaxField = 0; 3003 FieldDecl *MaxSkippedField = 0; 3004 FieldDecl *LastFieldBitfield = 0; 3005 uint64_t MaxFieldOffset = 0; 3006 uint64_t MaxSkippedFieldOffset = 0; 3007 uint64_t LastBitfieldOffset = 0; 3008 3009 if (RecFields.empty()) 3010 return; 3011 unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0); 3012 unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth(); 3013 3014 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { 3015 FieldDecl *Field = RecFields[i]; 3016 uint64_t FieldOffset; 3017 if (RD) 3018 FieldOffset = 3019 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field)); 3020 else 3021 FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)); 3022 3023 // Skip over unnamed or bitfields 3024 if (!Field->getIdentifier() || Field->isBitField()) { 3025 LastFieldBitfield = Field; 3026 LastBitfieldOffset = FieldOffset; 3027 continue; 3028 } 3029 3030 LastFieldBitfield = 0; 3031 QualType FQT = Field->getType(); 3032 if (FQT->isRecordType() || FQT->isUnionType()) { 3033 if (FQT->isUnionType()) 3034 HasUnion = true; 3035 3036 BuildAggrIvarRecordLayout(FQT->getAsRecordType(), 3037 BytePos + FieldOffset, 3038 ForStrongLayout, HasUnion); 3039 continue; 3040 } 3041 3042 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3043 const ConstantArrayType *CArray = 3044 dyn_cast_or_null<ConstantArrayType>(Array); 3045 uint64_t ElCount = CArray->getSize().getZExtValue(); 3046 assert(CArray && "only array with known element size is supported"); 3047 FQT = CArray->getElementType(); 3048 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3049 const ConstantArrayType *CArray = 3050 dyn_cast_or_null<ConstantArrayType>(Array); 3051 ElCount *= CArray->getSize().getZExtValue(); 3052 FQT = CArray->getElementType(); 3053 } 3054 3055 assert(!FQT->isUnionType() && 3056 "layout for array of unions not supported"); 3057 if (FQT->isRecordType()) { 3058 int OldIndex = IvarsInfo.size() - 1; 3059 int OldSkIndex = SkipIvars.size() -1; 3060 3061 const RecordType *RT = FQT->getAsRecordType(); 3062 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset, 3063 ForStrongLayout, HasUnion); 3064 3065 // Replicate layout information for each array element. Note that 3066 // one element is already done. 3067 uint64_t ElIx = 1; 3068 for (int FirstIndex = IvarsInfo.size() - 1, 3069 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { 3070 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; 3071 for (int i = OldIndex+1; i <= FirstIndex; ++i) 3072 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, 3073 IvarsInfo[i].ivar_size)); 3074 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) 3075 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx, 3076 SkipIvars[i].ivar_size)); 3077 } 3078 continue; 3079 } 3080 } 3081 // At this point, we are done with Record/Union and array there of. 3082 // For other arrays we are down to its element type. 3083 QualType::GCAttrTypes GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); 3084 3085 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); 3086 if ((ForStrongLayout && GCAttr == QualType::Strong) 3087 || (!ForStrongLayout && GCAttr == QualType::Weak)) { 3088 if (IsUnion) { 3089 uint64_t UnionIvarSize = FieldSize / WordSizeInBits; 3090 if (UnionIvarSize > MaxUnionIvarSize) { 3091 MaxUnionIvarSize = UnionIvarSize; 3092 MaxField = Field; 3093 MaxFieldOffset = FieldOffset; 3094 } 3095 } else { 3096 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, 3097 FieldSize / WordSizeInBits)); 3098 } 3099 } else if ((ForStrongLayout && 3100 (GCAttr == QualType::GCNone || GCAttr == QualType::Weak)) 3101 || (!ForStrongLayout && GCAttr != QualType::Weak)) { 3102 if (IsUnion) { 3103 // FIXME: Why the asymmetry? We divide by word size in bits on other 3104 // side. 3105 uint64_t UnionIvarSize = FieldSize; 3106 if (UnionIvarSize > MaxSkippedUnionIvarSize) { 3107 MaxSkippedUnionIvarSize = UnionIvarSize; 3108 MaxSkippedField = Field; 3109 MaxSkippedFieldOffset = FieldOffset; 3110 } 3111 } else { 3112 // FIXME: Why the asymmetry, we divide by byte size in bits here? 3113 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, 3114 FieldSize / ByteSizeInBits)); 3115 } 3116 } 3117 } 3118 3119 if (LastFieldBitfield) { 3120 // Last field was a bitfield. Must update skip info. 3121 Expr *BitWidth = LastFieldBitfield->getBitWidth(); 3122 uint64_t BitFieldSize = 3123 BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue(); 3124 GC_IVAR skivar; 3125 skivar.ivar_bytepos = BytePos + LastBitfieldOffset; 3126 skivar.ivar_size = (BitFieldSize / ByteSizeInBits) 3127 + ((BitFieldSize % ByteSizeInBits) != 0); 3128 SkipIvars.push_back(skivar); 3129 } 3130 3131 if (MaxField) 3132 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset, 3133 MaxUnionIvarSize)); 3134 if (MaxSkippedField) 3135 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset, 3136 MaxSkippedUnionIvarSize)); 3137 } 3138 3139 /// BuildIvarLayout - Builds ivar layout bitmap for the class 3140 /// implementation for the __strong or __weak case. 3141 /// The layout map displays which words in ivar list must be skipped 3142 /// and which must be scanned by GC (see below). String is built of bytes. 3143 /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count 3144 /// of words to skip and right nibble is count of words to scan. So, each 3145 /// nibble represents up to 15 workds to skip or scan. Skipping the rest is 3146 /// represented by a 0x00 byte which also ends the string. 3147 /// 1. when ForStrongLayout is true, following ivars are scanned: 3148 /// - id, Class 3149 /// - object * 3150 /// - __strong anything 3151 /// 3152 /// 2. When ForStrongLayout is false, following ivars are scanned: 3153 /// - __weak anything 3154 /// 3155 llvm::Constant *CGObjCCommonMac::BuildIvarLayout( 3156 const ObjCImplementationDecl *OMD, 3157 bool ForStrongLayout) { 3158 bool hasUnion = false; 3159 3160 unsigned int WordsToScan, WordsToSkip; 3161 const llvm::Type *PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 3162 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC) 3163 return llvm::Constant::getNullValue(PtrTy); 3164 3165 llvm::SmallVector<FieldDecl*, 32> RecFields; 3166 const ObjCInterfaceDecl *OI = OMD->getClassInterface(); 3167 CGM.getContext().CollectObjCIvars(OI, RecFields); 3168 3169 // Add this implementations synthesized ivars. 3170 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 3171 CGM.getContext().CollectSynthesizedIvars(OI, Ivars); 3172 for (unsigned k = 0, e = Ivars.size(); k != e; ++k) 3173 RecFields.push_back(cast<FieldDecl>(Ivars[k])); 3174 3175 if (RecFields.empty()) 3176 return llvm::Constant::getNullValue(PtrTy); 3177 3178 SkipIvars.clear(); 3179 IvarsInfo.clear(); 3180 3181 BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion); 3182 if (IvarsInfo.empty()) 3183 return llvm::Constant::getNullValue(PtrTy); 3184 3185 // Sort on byte position in case we encounterred a union nested in 3186 // the ivar list. 3187 if (hasUnion && !IvarsInfo.empty()) 3188 std::sort(IvarsInfo.begin(), IvarsInfo.end()); 3189 if (hasUnion && !SkipIvars.empty()) 3190 std::sort(SkipIvars.begin(), SkipIvars.end()); 3191 3192 // Build the string of skip/scan nibbles 3193 llvm::SmallVector<SKIP_SCAN, 32> SkipScanIvars; 3194 unsigned int WordSize = 3195 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy); 3196 if (IvarsInfo[0].ivar_bytepos == 0) { 3197 WordsToSkip = 0; 3198 WordsToScan = IvarsInfo[0].ivar_size; 3199 } else { 3200 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; 3201 WordsToScan = IvarsInfo[0].ivar_size; 3202 } 3203 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { 3204 unsigned int TailPrevGCObjC = 3205 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; 3206 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { 3207 // consecutive 'scanned' object pointers. 3208 WordsToScan += IvarsInfo[i].ivar_size; 3209 } else { 3210 // Skip over 'gc'able object pointer which lay over each other. 3211 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) 3212 continue; 3213 // Must skip over 1 or more words. We save current skip/scan values 3214 // and start a new pair. 3215 SKIP_SCAN SkScan; 3216 SkScan.skip = WordsToSkip; 3217 SkScan.scan = WordsToScan; 3218 SkipScanIvars.push_back(SkScan); 3219 3220 // Skip the hole. 3221 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize; 3222 SkScan.scan = 0; 3223 SkipScanIvars.push_back(SkScan); 3224 WordsToSkip = 0; 3225 WordsToScan = IvarsInfo[i].ivar_size; 3226 } 3227 } 3228 if (WordsToScan > 0) { 3229 SKIP_SCAN SkScan; 3230 SkScan.skip = WordsToSkip; 3231 SkScan.scan = WordsToScan; 3232 SkipScanIvars.push_back(SkScan); 3233 } 3234 3235 bool BytesSkipped = false; 3236 if (!SkipIvars.empty()) { 3237 unsigned int LastIndex = SkipIvars.size()-1; 3238 int LastByteSkipped = 3239 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; 3240 LastIndex = IvarsInfo.size()-1; 3241 int LastByteScanned = 3242 IvarsInfo[LastIndex].ivar_bytepos + 3243 IvarsInfo[LastIndex].ivar_size * WordSize; 3244 BytesSkipped = (LastByteSkipped > LastByteScanned); 3245 // Compute number of bytes to skip at the tail end of the last ivar scanned. 3246 if (BytesSkipped) { 3247 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; 3248 SKIP_SCAN SkScan; 3249 SkScan.skip = TotalWords - (LastByteScanned/WordSize); 3250 SkScan.scan = 0; 3251 SkipScanIvars.push_back(SkScan); 3252 } 3253 } 3254 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced 3255 // as 0xMN. 3256 int SkipScan = SkipScanIvars.size()-1; 3257 for (int i = 0; i <= SkipScan; i++) { 3258 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0 3259 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) { 3260 // 0xM0 followed by 0x0N detected. 3261 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan; 3262 for (int j = i+1; j < SkipScan; j++) 3263 SkipScanIvars[j] = SkipScanIvars[j+1]; 3264 --SkipScan; 3265 } 3266 } 3267 3268 // Generate the string. 3269 std::string BitMap; 3270 for (int i = 0; i <= SkipScan; i++) { 3271 unsigned char byte; 3272 unsigned int skip_small = SkipScanIvars[i].skip % 0xf; 3273 unsigned int scan_small = SkipScanIvars[i].scan % 0xf; 3274 unsigned int skip_big = SkipScanIvars[i].skip / 0xf; 3275 unsigned int scan_big = SkipScanIvars[i].scan / 0xf; 3276 3277 if (skip_small > 0 || skip_big > 0) 3278 BytesSkipped = true; 3279 // first skip big. 3280 for (unsigned int ix = 0; ix < skip_big; ix++) 3281 BitMap += (unsigned char)(0xf0); 3282 3283 // next (skip small, scan) 3284 if (skip_small) { 3285 byte = skip_small << 4; 3286 if (scan_big > 0) { 3287 byte |= 0xf; 3288 --scan_big; 3289 } else if (scan_small) { 3290 byte |= scan_small; 3291 scan_small = 0; 3292 } 3293 BitMap += byte; 3294 } 3295 // next scan big 3296 for (unsigned int ix = 0; ix < scan_big; ix++) 3297 BitMap += (unsigned char)(0x0f); 3298 // last scan small 3299 if (scan_small) { 3300 byte = scan_small; 3301 BitMap += byte; 3302 } 3303 } 3304 // null terminate string. 3305 unsigned char zero = 0; 3306 BitMap += zero; 3307 3308 if (CGM.getLangOptions().ObjCGCBitmapPrint) { 3309 printf("\n%s ivar layout for class '%s': ", 3310 ForStrongLayout ? "strong" : "weak", 3311 OMD->getClassInterface()->getNameAsCString()); 3312 const unsigned char *s = (unsigned char*)BitMap.c_str(); 3313 for (unsigned i = 0; i < BitMap.size(); i++) 3314 if (!(s[i] & 0xf0)) 3315 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 3316 else 3317 printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 3318 printf("\n"); 3319 } 3320 3321 // if ivar_layout bitmap is all 1 bits (nothing skipped) then use NULL as 3322 // final layout. 3323 if (ForStrongLayout && !BytesSkipped) 3324 return llvm::Constant::getNullValue(PtrTy); 3325 llvm::GlobalVariable * Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 3326 llvm::ConstantArray::get(BitMap.c_str()), 3327 "__TEXT,__cstring,cstring_literals", 3328 1, true); 3329 return getConstantGEP(Entry, 0, 0); 3330 } 3331 3332 llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 3333 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 3334 3335 // FIXME: Avoid std::string copying. 3336 if (!Entry) 3337 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_", 3338 llvm::ConstantArray::get(Sel.getAsString()), 3339 "__TEXT,__cstring,cstring_literals", 3340 1, true); 3341 3342 return getConstantGEP(Entry, 0, 0); 3343 } 3344 3345 // FIXME: Merge into a single cstring creation function. 3346 llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 3347 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 3348 } 3349 3350 // FIXME: Merge into a single cstring creation function. 3351 llvm::Constant *CGObjCCommonMac::GetMethodVarName(const std::string &Name) { 3352 return GetMethodVarName(&CGM.getContext().Idents.get(Name)); 3353 } 3354 3355 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) { 3356 std::string TypeStr; 3357 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 3358 3359 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 3360 3361 if (!Entry) 3362 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 3363 llvm::ConstantArray::get(TypeStr), 3364 "__TEXT,__cstring,cstring_literals", 3365 1, true); 3366 3367 return getConstantGEP(Entry, 0, 0); 3368 } 3369 3370 llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) { 3371 std::string TypeStr; 3372 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D), 3373 TypeStr); 3374 3375 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 3376 3377 if (!Entry) 3378 Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_", 3379 llvm::ConstantArray::get(TypeStr), 3380 "__TEXT,__cstring,cstring_literals", 3381 1, true); 3382 3383 return getConstantGEP(Entry, 0, 0); 3384 } 3385 3386 // FIXME: Merge into a single cstring creation function. 3387 llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 3388 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 3389 3390 if (!Entry) 3391 Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_", 3392 llvm::ConstantArray::get(Ident->getName()), 3393 "__TEXT,__cstring,cstring_literals", 3394 1, true); 3395 3396 return getConstantGEP(Entry, 0, 0); 3397 } 3398 3399 // FIXME: Merge into a single cstring creation function. 3400 // FIXME: This Decl should be more precise. 3401 llvm::Constant * 3402 CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 3403 const Decl *Container) { 3404 std::string TypeStr; 3405 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr); 3406 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 3407 } 3408 3409 void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 3410 const ObjCContainerDecl *CD, 3411 std::string &NameOut) { 3412 NameOut = '\01'; 3413 NameOut += (D->isInstanceMethod() ? '-' : '+'); 3414 NameOut += '['; 3415 assert (CD && "Missing container decl in GetNameForMethod"); 3416 NameOut += CD->getNameAsString(); 3417 if (const ObjCCategoryImplDecl *CID = 3418 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext())) { 3419 NameOut += '('; 3420 NameOut += CID->getNameAsString(); 3421 NameOut+= ')'; 3422 } 3423 NameOut += ' '; 3424 NameOut += D->getSelector().getAsString(); 3425 NameOut += ']'; 3426 } 3427 3428 void CGObjCMac::FinishModule() { 3429 EmitModuleInfo(); 3430 3431 // Emit the dummy bodies for any protocols which were referenced but 3432 // never defined. 3433 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator 3434 i = Protocols.begin(), e = Protocols.end(); i != e; ++i) { 3435 if (i->second->hasInitializer()) 3436 continue; 3437 3438 std::vector<llvm::Constant*> Values(5); 3439 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 3440 Values[1] = GetClassName(i->first); 3441 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 3442 Values[3] = Values[4] = 3443 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 3444 i->second->setLinkage(llvm::GlobalValue::InternalLinkage); 3445 i->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 3446 Values)); 3447 } 3448 3449 std::vector<llvm::Constant*> Used; 3450 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), 3451 e = UsedGlobals.end(); i != e; ++i) { 3452 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); 3453 } 3454 3455 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); 3456 llvm::GlobalValue *GV = 3457 new llvm::GlobalVariable(AT, false, 3458 llvm::GlobalValue::AppendingLinkage, 3459 llvm::ConstantArray::get(AT, Used), 3460 "llvm.used", 3461 &CGM.getModule()); 3462 3463 GV->setSection("llvm.metadata"); 3464 3465 // Add assembler directives to add lazy undefined symbol references 3466 // for classes which are referenced but not defined. This is 3467 // important for correct linker interaction. 3468 3469 // FIXME: Uh, this isn't particularly portable. 3470 std::stringstream s; 3471 3472 if (!CGM.getModule().getModuleInlineAsm().empty()) 3473 s << "\n"; 3474 3475 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(), 3476 e = LazySymbols.end(); i != e; ++i) { 3477 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n"; 3478 } 3479 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(), 3480 e = DefinedSymbols.end(); i != e; ++i) { 3481 s << "\t.objc_class_name_" << (*i)->getName() << "=0\n" 3482 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n"; 3483 } 3484 3485 CGM.getModule().appendModuleInlineAsm(s.str()); 3486 } 3487 3488 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 3489 : CGObjCCommonMac(cgm), 3490 ObjCTypes(cgm) 3491 { 3492 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL; 3493 ObjCABI = 2; 3494 } 3495 3496 /* *** */ 3497 3498 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 3499 : CGM(cgm) 3500 { 3501 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 3502 ASTContext &Ctx = CGM.getContext(); 3503 3504 ShortTy = Types.ConvertType(Ctx.ShortTy); 3505 IntTy = Types.ConvertType(Ctx.IntTy); 3506 LongTy = Types.ConvertType(Ctx.LongTy); 3507 LongLongTy = Types.ConvertType(Ctx.LongLongTy); 3508 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 3509 3510 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 3511 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); 3512 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 3513 3514 // FIXME: It would be nice to unify this with the opaque type, so that the IR 3515 // comes out a bit cleaner. 3516 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 3517 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 3518 3519 // I'm not sure I like this. The implicit coordination is a bit 3520 // gross. We should solve this in a reasonable fashion because this 3521 // is a pretty common task (match some runtime data structure with 3522 // an LLVM data structure). 3523 3524 // FIXME: This is leaked. 3525 // FIXME: Merge with rewriter code? 3526 3527 // struct _objc_super { 3528 // id self; 3529 // Class cls; 3530 // } 3531 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, 3532 SourceLocation(), 3533 &Ctx.Idents.get("_objc_super")); 3534 RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 3535 Ctx.getObjCIdType(), 0, false)); 3536 RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 3537 Ctx.getObjCClassType(), 0, false)); 3538 RD->completeDefinition(Ctx); 3539 3540 SuperCTy = Ctx.getTagDeclType(RD); 3541 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 3542 3543 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 3544 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 3545 3546 // struct _prop_t { 3547 // char *name; 3548 // char *attributes; 3549 // } 3550 PropertyTy = llvm::StructType::get(Int8PtrTy, Int8PtrTy, NULL); 3551 CGM.getModule().addTypeName("struct._prop_t", 3552 PropertyTy); 3553 3554 // struct _prop_list_t { 3555 // uint32_t entsize; // sizeof(struct _prop_t) 3556 // uint32_t count_of_properties; 3557 // struct _prop_t prop_list[count_of_properties]; 3558 // } 3559 PropertyListTy = llvm::StructType::get(IntTy, 3560 IntTy, 3561 llvm::ArrayType::get(PropertyTy, 0), 3562 NULL); 3563 CGM.getModule().addTypeName("struct._prop_list_t", 3564 PropertyListTy); 3565 // struct _prop_list_t * 3566 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 3567 3568 // struct _objc_method { 3569 // SEL _cmd; 3570 // char *method_type; 3571 // char *_imp; 3572 // } 3573 MethodTy = llvm::StructType::get(SelectorPtrTy, 3574 Int8PtrTy, 3575 Int8PtrTy, 3576 NULL); 3577 CGM.getModule().addTypeName("struct._objc_method", MethodTy); 3578 3579 // struct _objc_cache * 3580 CacheTy = llvm::OpaqueType::get(); 3581 CGM.getModule().addTypeName("struct._objc_cache", CacheTy); 3582 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 3583 } 3584 3585 ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 3586 : ObjCCommonTypesHelper(cgm) 3587 { 3588 // struct _objc_method_description { 3589 // SEL name; 3590 // char *types; 3591 // } 3592 MethodDescriptionTy = 3593 llvm::StructType::get(SelectorPtrTy, 3594 Int8PtrTy, 3595 NULL); 3596 CGM.getModule().addTypeName("struct._objc_method_description", 3597 MethodDescriptionTy); 3598 3599 // struct _objc_method_description_list { 3600 // int count; 3601 // struct _objc_method_description[1]; 3602 // } 3603 MethodDescriptionListTy = 3604 llvm::StructType::get(IntTy, 3605 llvm::ArrayType::get(MethodDescriptionTy, 0), 3606 NULL); 3607 CGM.getModule().addTypeName("struct._objc_method_description_list", 3608 MethodDescriptionListTy); 3609 3610 // struct _objc_method_description_list * 3611 MethodDescriptionListPtrTy = 3612 llvm::PointerType::getUnqual(MethodDescriptionListTy); 3613 3614 // Protocol description structures 3615 3616 // struct _objc_protocol_extension { 3617 // uint32_t size; // sizeof(struct _objc_protocol_extension) 3618 // struct _objc_method_description_list *optional_instance_methods; 3619 // struct _objc_method_description_list *optional_class_methods; 3620 // struct _objc_property_list *instance_properties; 3621 // } 3622 ProtocolExtensionTy = 3623 llvm::StructType::get(IntTy, 3624 MethodDescriptionListPtrTy, 3625 MethodDescriptionListPtrTy, 3626 PropertyListPtrTy, 3627 NULL); 3628 CGM.getModule().addTypeName("struct._objc_protocol_extension", 3629 ProtocolExtensionTy); 3630 3631 // struct _objc_protocol_extension * 3632 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 3633 3634 // Handle recursive construction of Protocol and ProtocolList types 3635 3636 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(); 3637 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); 3638 3639 const llvm::Type *T = 3640 llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder), 3641 LongTy, 3642 llvm::ArrayType::get(ProtocolTyHolder, 0), 3643 NULL); 3644 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T); 3645 3646 // struct _objc_protocol { 3647 // struct _objc_protocol_extension *isa; 3648 // char *protocol_name; 3649 // struct _objc_protocol **_objc_protocol_list; 3650 // struct _objc_method_description_list *instance_methods; 3651 // struct _objc_method_description_list *class_methods; 3652 // } 3653 T = llvm::StructType::get(ProtocolExtensionPtrTy, 3654 Int8PtrTy, 3655 llvm::PointerType::getUnqual(ProtocolListTyHolder), 3656 MethodDescriptionListPtrTy, 3657 MethodDescriptionListPtrTy, 3658 NULL); 3659 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T); 3660 3661 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get()); 3662 CGM.getModule().addTypeName("struct._objc_protocol_list", 3663 ProtocolListTy); 3664 // struct _objc_protocol_list * 3665 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 3666 3667 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get()); 3668 CGM.getModule().addTypeName("struct._objc_protocol", ProtocolTy); 3669 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 3670 3671 // Class description structures 3672 3673 // struct _objc_ivar { 3674 // char *ivar_name; 3675 // char *ivar_type; 3676 // int ivar_offset; 3677 // } 3678 IvarTy = llvm::StructType::get(Int8PtrTy, 3679 Int8PtrTy, 3680 IntTy, 3681 NULL); 3682 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy); 3683 3684 // struct _objc_ivar_list * 3685 IvarListTy = llvm::OpaqueType::get(); 3686 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy); 3687 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 3688 3689 // struct _objc_method_list * 3690 MethodListTy = llvm::OpaqueType::get(); 3691 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy); 3692 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 3693 3694 // struct _objc_class_extension * 3695 ClassExtensionTy = 3696 llvm::StructType::get(IntTy, 3697 Int8PtrTy, 3698 PropertyListPtrTy, 3699 NULL); 3700 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy); 3701 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 3702 3703 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(); 3704 3705 // struct _objc_class { 3706 // Class isa; 3707 // Class super_class; 3708 // char *name; 3709 // long version; 3710 // long info; 3711 // long instance_size; 3712 // struct _objc_ivar_list *ivars; 3713 // struct _objc_method_list *methods; 3714 // struct _objc_cache *cache; 3715 // struct _objc_protocol_list *protocols; 3716 // char *ivar_layout; 3717 // struct _objc_class_ext *ext; 3718 // }; 3719 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder), 3720 llvm::PointerType::getUnqual(ClassTyHolder), 3721 Int8PtrTy, 3722 LongTy, 3723 LongTy, 3724 LongTy, 3725 IvarListPtrTy, 3726 MethodListPtrTy, 3727 CachePtrTy, 3728 ProtocolListPtrTy, 3729 Int8PtrTy, 3730 ClassExtensionPtrTy, 3731 NULL); 3732 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T); 3733 3734 ClassTy = cast<llvm::StructType>(ClassTyHolder.get()); 3735 CGM.getModule().addTypeName("struct._objc_class", ClassTy); 3736 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 3737 3738 // struct _objc_category { 3739 // char *category_name; 3740 // char *class_name; 3741 // struct _objc_method_list *instance_method; 3742 // struct _objc_method_list *class_method; 3743 // uint32_t size; // sizeof(struct _objc_category) 3744 // struct _objc_property_list *instance_properties;// category's @property 3745 // } 3746 CategoryTy = llvm::StructType::get(Int8PtrTy, 3747 Int8PtrTy, 3748 MethodListPtrTy, 3749 MethodListPtrTy, 3750 ProtocolListPtrTy, 3751 IntTy, 3752 PropertyListPtrTy, 3753 NULL); 3754 CGM.getModule().addTypeName("struct._objc_category", CategoryTy); 3755 3756 // Global metadata structures 3757 3758 // struct _objc_symtab { 3759 // long sel_ref_cnt; 3760 // SEL *refs; 3761 // short cls_def_cnt; 3762 // short cat_def_cnt; 3763 // char *defs[cls_def_cnt + cat_def_cnt]; 3764 // } 3765 SymtabTy = llvm::StructType::get(LongTy, 3766 SelectorPtrTy, 3767 ShortTy, 3768 ShortTy, 3769 llvm::ArrayType::get(Int8PtrTy, 0), 3770 NULL); 3771 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy); 3772 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 3773 3774 // struct _objc_module { 3775 // long version; 3776 // long size; // sizeof(struct _objc_module) 3777 // char *name; 3778 // struct _objc_symtab* symtab; 3779 // } 3780 ModuleTy = 3781 llvm::StructType::get(LongTy, 3782 LongTy, 3783 Int8PtrTy, 3784 SymtabPtrTy, 3785 NULL); 3786 CGM.getModule().addTypeName("struct._objc_module", ModuleTy); 3787 3788 3789 // FIXME: This is the size of the setjmp buffer and should be target 3790 // specific. 18 is what's used on 32-bit X86. 3791 uint64_t SetJmpBufferSize = 18; 3792 3793 // Exceptions 3794 const llvm::Type *StackPtrTy = 3795 llvm::ArrayType::get(llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 4); 3796 3797 ExceptionDataTy = 3798 llvm::StructType::get(llvm::ArrayType::get(llvm::Type::Int32Ty, 3799 SetJmpBufferSize), 3800 StackPtrTy, NULL); 3801 CGM.getModule().addTypeName("struct._objc_exception_data", 3802 ExceptionDataTy); 3803 3804 } 3805 3806 ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 3807 : ObjCCommonTypesHelper(cgm) 3808 { 3809 // struct _method_list_t { 3810 // uint32_t entsize; // sizeof(struct _objc_method) 3811 // uint32_t method_count; 3812 // struct _objc_method method_list[method_count]; 3813 // } 3814 MethodListnfABITy = llvm::StructType::get(IntTy, 3815 IntTy, 3816 llvm::ArrayType::get(MethodTy, 0), 3817 NULL); 3818 CGM.getModule().addTypeName("struct.__method_list_t", 3819 MethodListnfABITy); 3820 // struct method_list_t * 3821 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 3822 3823 // struct _protocol_t { 3824 // id isa; // NULL 3825 // const char * const protocol_name; 3826 // const struct _protocol_list_t * protocol_list; // super protocols 3827 // const struct method_list_t * const instance_methods; 3828 // const struct method_list_t * const class_methods; 3829 // const struct method_list_t *optionalInstanceMethods; 3830 // const struct method_list_t *optionalClassMethods; 3831 // const struct _prop_list_t * properties; 3832 // const uint32_t size; // sizeof(struct _protocol_t) 3833 // const uint32_t flags; // = 0 3834 // } 3835 3836 // Holder for struct _protocol_list_t * 3837 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); 3838 3839 ProtocolnfABITy = llvm::StructType::get(ObjectPtrTy, 3840 Int8PtrTy, 3841 llvm::PointerType::getUnqual( 3842 ProtocolListTyHolder), 3843 MethodListnfABIPtrTy, 3844 MethodListnfABIPtrTy, 3845 MethodListnfABIPtrTy, 3846 MethodListnfABIPtrTy, 3847 PropertyListPtrTy, 3848 IntTy, 3849 IntTy, 3850 NULL); 3851 CGM.getModule().addTypeName("struct._protocol_t", 3852 ProtocolnfABITy); 3853 3854 // struct _protocol_t* 3855 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 3856 3857 // struct _protocol_list_t { 3858 // long protocol_count; // Note, this is 32/64 bit 3859 // struct _protocol_t *[protocol_count]; 3860 // } 3861 ProtocolListnfABITy = llvm::StructType::get(LongTy, 3862 llvm::ArrayType::get( 3863 ProtocolnfABIPtrTy, 0), 3864 NULL); 3865 CGM.getModule().addTypeName("struct._objc_protocol_list", 3866 ProtocolListnfABITy); 3867 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo( 3868 ProtocolListnfABITy); 3869 3870 // struct _objc_protocol_list* 3871 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 3872 3873 // struct _ivar_t { 3874 // unsigned long int *offset; // pointer to ivar offset location 3875 // char *name; 3876 // char *type; 3877 // uint32_t alignment; 3878 // uint32_t size; 3879 // } 3880 IvarnfABITy = llvm::StructType::get(llvm::PointerType::getUnqual(LongTy), 3881 Int8PtrTy, 3882 Int8PtrTy, 3883 IntTy, 3884 IntTy, 3885 NULL); 3886 CGM.getModule().addTypeName("struct._ivar_t", IvarnfABITy); 3887 3888 // struct _ivar_list_t { 3889 // uint32 entsize; // sizeof(struct _ivar_t) 3890 // uint32 count; 3891 // struct _iver_t list[count]; 3892 // } 3893 IvarListnfABITy = llvm::StructType::get(IntTy, 3894 IntTy, 3895 llvm::ArrayType::get( 3896 IvarnfABITy, 0), 3897 NULL); 3898 CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABITy); 3899 3900 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 3901 3902 // struct _class_ro_t { 3903 // uint32_t const flags; 3904 // uint32_t const instanceStart; 3905 // uint32_t const instanceSize; 3906 // uint32_t const reserved; // only when building for 64bit targets 3907 // const uint8_t * const ivarLayout; 3908 // const char *const name; 3909 // const struct _method_list_t * const baseMethods; 3910 // const struct _objc_protocol_list *const baseProtocols; 3911 // const struct _ivar_list_t *const ivars; 3912 // const uint8_t * const weakIvarLayout; 3913 // const struct _prop_list_t * const properties; 3914 // } 3915 3916 // FIXME. Add 'reserved' field in 64bit abi mode! 3917 ClassRonfABITy = llvm::StructType::get(IntTy, 3918 IntTy, 3919 IntTy, 3920 Int8PtrTy, 3921 Int8PtrTy, 3922 MethodListnfABIPtrTy, 3923 ProtocolListnfABIPtrTy, 3924 IvarListnfABIPtrTy, 3925 Int8PtrTy, 3926 PropertyListPtrTy, 3927 NULL); 3928 CGM.getModule().addTypeName("struct._class_ro_t", 3929 ClassRonfABITy); 3930 3931 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 3932 std::vector<const llvm::Type*> Params; 3933 Params.push_back(ObjectPtrTy); 3934 Params.push_back(SelectorPtrTy); 3935 ImpnfABITy = llvm::PointerType::getUnqual( 3936 llvm::FunctionType::get(ObjectPtrTy, Params, false)); 3937 3938 // struct _class_t { 3939 // struct _class_t *isa; 3940 // struct _class_t * const superclass; 3941 // void *cache; 3942 // IMP *vtable; 3943 // struct class_ro_t *ro; 3944 // } 3945 3946 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(); 3947 ClassnfABITy = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder), 3948 llvm::PointerType::getUnqual(ClassTyHolder), 3949 CachePtrTy, 3950 llvm::PointerType::getUnqual(ImpnfABITy), 3951 llvm::PointerType::getUnqual( 3952 ClassRonfABITy), 3953 NULL); 3954 CGM.getModule().addTypeName("struct._class_t", ClassnfABITy); 3955 3956 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo( 3957 ClassnfABITy); 3958 3959 // LLVM for struct _class_t * 3960 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 3961 3962 // struct _category_t { 3963 // const char * const name; 3964 // struct _class_t *const cls; 3965 // const struct _method_list_t * const instance_methods; 3966 // const struct _method_list_t * const class_methods; 3967 // const struct _protocol_list_t * const protocols; 3968 // const struct _prop_list_t * const properties; 3969 // } 3970 CategorynfABITy = llvm::StructType::get(Int8PtrTy, 3971 ClassnfABIPtrTy, 3972 MethodListnfABIPtrTy, 3973 MethodListnfABIPtrTy, 3974 ProtocolListnfABIPtrTy, 3975 PropertyListPtrTy, 3976 NULL); 3977 CGM.getModule().addTypeName("struct._category_t", CategorynfABITy); 3978 3979 // New types for nonfragile abi messaging. 3980 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 3981 ASTContext &Ctx = CGM.getContext(); 3982 3983 // MessageRefTy - LLVM for: 3984 // struct _message_ref_t { 3985 // IMP messenger; 3986 // SEL name; 3987 // }; 3988 3989 // First the clang type for struct _message_ref_t 3990 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, 3991 SourceLocation(), 3992 &Ctx.Idents.get("_message_ref_t")); 3993 RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 3994 Ctx.VoidPtrTy, 0, false)); 3995 RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 3996 Ctx.getObjCSelType(), 0, false)); 3997 RD->completeDefinition(Ctx); 3998 3999 MessageRefCTy = Ctx.getTagDeclType(RD); 4000 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 4001 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 4002 4003 // MessageRefPtrTy - LLVM for struct _message_ref_t* 4004 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 4005 4006 // SuperMessageRefTy - LLVM for: 4007 // struct _super_message_ref_t { 4008 // SUPER_IMP messenger; 4009 // SEL name; 4010 // }; 4011 SuperMessageRefTy = llvm::StructType::get(ImpnfABITy, 4012 SelectorPtrTy, 4013 NULL); 4014 CGM.getModule().addTypeName("struct._super_message_ref_t", SuperMessageRefTy); 4015 4016 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 4017 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 4018 4019 4020 // struct objc_typeinfo { 4021 // const void** vtable; // objc_ehtype_vtable + 2 4022 // const char* name; // c++ typeinfo string 4023 // Class cls; 4024 // }; 4025 EHTypeTy = llvm::StructType::get(llvm::PointerType::getUnqual(Int8PtrTy), 4026 Int8PtrTy, 4027 ClassnfABIPtrTy, 4028 NULL); 4029 CGM.getModule().addTypeName("struct._objc_typeinfo", EHTypeTy); 4030 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 4031 } 4032 4033 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 4034 FinishNonFragileABIModule(); 4035 4036 return NULL; 4037 } 4038 4039 void CGObjCNonFragileABIMac::AddModuleClassList(const 4040 std::vector<llvm::GlobalValue*> 4041 &Container, 4042 const char *SymbolName, 4043 const char *SectionName) { 4044 unsigned NumClasses = Container.size(); 4045 4046 if (!NumClasses) 4047 return; 4048 4049 std::vector<llvm::Constant*> Symbols(NumClasses); 4050 for (unsigned i=0; i<NumClasses; i++) 4051 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 4052 ObjCTypes.Int8PtrTy); 4053 llvm::Constant* Init = 4054 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 4055 NumClasses), 4056 Symbols); 4057 4058 llvm::GlobalVariable *GV = 4059 new llvm::GlobalVariable(Init->getType(), false, 4060 llvm::GlobalValue::InternalLinkage, 4061 Init, 4062 SymbolName, 4063 &CGM.getModule()); 4064 GV->setAlignment(8); 4065 GV->setSection(SectionName); 4066 UsedGlobals.push_back(GV); 4067 } 4068 4069 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 4070 // nonfragile abi has no module definition. 4071 4072 // Build list of all implemented class addresses in array 4073 // L_OBJC_LABEL_CLASS_$. 4074 AddModuleClassList(DefinedClasses, 4075 "\01L_OBJC_LABEL_CLASS_$", 4076 "__DATA, __objc_classlist, regular, no_dead_strip"); 4077 AddModuleClassList(DefinedNonLazyClasses, 4078 "\01L_OBJC_LABEL_NONLAZY_CLASS_$", 4079 "__DATA, __objc_nlclslist, regular, no_dead_strip"); 4080 4081 // Build list of all implemented category addresses in array 4082 // L_OBJC_LABEL_CATEGORY_$. 4083 AddModuleClassList(DefinedCategories, 4084 "\01L_OBJC_LABEL_CATEGORY_$", 4085 "__DATA, __objc_catlist, regular, no_dead_strip"); 4086 AddModuleClassList(DefinedNonLazyCategories, 4087 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$", 4088 "__DATA, __objc_nlcatlist, regular, no_dead_strip"); 4089 4090 // static int L_OBJC_IMAGE_INFO[2] = { 0, flags }; 4091 // FIXME. flags can be 0 | 1 | 2 | 6. For now just use 0 4092 std::vector<llvm::Constant*> Values(2); 4093 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); 4094 unsigned int flags = 0; 4095 // FIXME: Fix and continue? 4096 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 4097 flags |= eImageInfo_GarbageCollected; 4098 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 4099 flags |= eImageInfo_GCOnly; 4100 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 4101 llvm::Constant* Init = llvm::ConstantArray::get( 4102 llvm::ArrayType::get(ObjCTypes.IntTy, 2), 4103 Values); 4104 llvm::GlobalVariable *IMGV = 4105 new llvm::GlobalVariable(Init->getType(), false, 4106 llvm::GlobalValue::InternalLinkage, 4107 Init, 4108 "\01L_OBJC_IMAGE_INFO", 4109 &CGM.getModule()); 4110 IMGV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); 4111 IMGV->setConstant(true); 4112 UsedGlobals.push_back(IMGV); 4113 4114 std::vector<llvm::Constant*> Used; 4115 4116 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), 4117 e = UsedGlobals.end(); i != e; ++i) { 4118 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); 4119 } 4120 4121 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); 4122 llvm::GlobalValue *GV = 4123 new llvm::GlobalVariable(AT, false, 4124 llvm::GlobalValue::AppendingLinkage, 4125 llvm::ConstantArray::get(AT, Used), 4126 "llvm.used", 4127 &CGM.getModule()); 4128 4129 GV->setSection("llvm.metadata"); 4130 4131 } 4132 4133 /// LegacyDispatchedSelector - Returns true if SEL is not in the list of 4134 /// NonLegacyDispatchMethods; false otherwise. What this means is that 4135 /// except for the 19 selectors in the list, we generate 32bit-style 4136 /// message dispatch call for all the rest. 4137 /// 4138 bool CGObjCNonFragileABIMac::LegacyDispatchedSelector(Selector Sel) { 4139 if (NonLegacyDispatchMethods.empty()) { 4140 NonLegacyDispatchMethods.insert(GetNullarySelector("alloc")); 4141 NonLegacyDispatchMethods.insert(GetNullarySelector("class")); 4142 NonLegacyDispatchMethods.insert(GetNullarySelector("self")); 4143 NonLegacyDispatchMethods.insert(GetNullarySelector("isFlipped")); 4144 NonLegacyDispatchMethods.insert(GetNullarySelector("length")); 4145 NonLegacyDispatchMethods.insert(GetNullarySelector("count")); 4146 NonLegacyDispatchMethods.insert(GetNullarySelector("retain")); 4147 NonLegacyDispatchMethods.insert(GetNullarySelector("release")); 4148 NonLegacyDispatchMethods.insert(GetNullarySelector("autorelease")); 4149 NonLegacyDispatchMethods.insert(GetNullarySelector("hash")); 4150 4151 NonLegacyDispatchMethods.insert(GetUnarySelector("allocWithZone")); 4152 NonLegacyDispatchMethods.insert(GetUnarySelector("isKindOfClass")); 4153 NonLegacyDispatchMethods.insert(GetUnarySelector("respondsToSelector")); 4154 NonLegacyDispatchMethods.insert(GetUnarySelector("objectForKey")); 4155 NonLegacyDispatchMethods.insert(GetUnarySelector("objectAtIndex")); 4156 NonLegacyDispatchMethods.insert(GetUnarySelector("isEqualToString")); 4157 NonLegacyDispatchMethods.insert(GetUnarySelector("isEqual")); 4158 NonLegacyDispatchMethods.insert(GetUnarySelector("addObject")); 4159 // "countByEnumeratingWithState:objects:count" 4160 IdentifierInfo *KeyIdents[] = { 4161 &CGM.getContext().Idents.get("countByEnumeratingWithState"), 4162 &CGM.getContext().Idents.get("objects"), 4163 &CGM.getContext().Idents.get("count") 4164 }; 4165 NonLegacyDispatchMethods.insert( 4166 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 4167 } 4168 return (NonLegacyDispatchMethods.count(Sel) == 0); 4169 } 4170 4171 // Metadata flags 4172 enum MetaDataDlags { 4173 CLS = 0x0, 4174 CLS_META = 0x1, 4175 CLS_ROOT = 0x2, 4176 OBJC2_CLS_HIDDEN = 0x10, 4177 CLS_EXCEPTION = 0x20 4178 }; 4179 /// BuildClassRoTInitializer - generate meta-data for: 4180 /// struct _class_ro_t { 4181 /// uint32_t const flags; 4182 /// uint32_t const instanceStart; 4183 /// uint32_t const instanceSize; 4184 /// uint32_t const reserved; // only when building for 64bit targets 4185 /// const uint8_t * const ivarLayout; 4186 /// const char *const name; 4187 /// const struct _method_list_t * const baseMethods; 4188 /// const struct _protocol_list_t *const baseProtocols; 4189 /// const struct _ivar_list_t *const ivars; 4190 /// const uint8_t * const weakIvarLayout; 4191 /// const struct _prop_list_t * const properties; 4192 /// } 4193 /// 4194 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( 4195 unsigned flags, 4196 unsigned InstanceStart, 4197 unsigned InstanceSize, 4198 const ObjCImplementationDecl *ID) { 4199 std::string ClassName = ID->getNameAsString(); 4200 std::vector<llvm::Constant*> Values(10); // 11 for 64bit targets! 4201 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 4202 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); 4203 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); 4204 // FIXME. For 64bit targets add 0 here. 4205 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 4206 : BuildIvarLayout(ID, true); 4207 Values[ 4] = GetClassName(ID->getIdentifier()); 4208 // const struct _method_list_t * const baseMethods; 4209 std::vector<llvm::Constant*> Methods; 4210 std::string MethodListName("\01l_OBJC_$_"); 4211 if (flags & CLS_META) { 4212 MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); 4213 for (ObjCImplementationDecl::classmeth_iterator 4214 i = ID->classmeth_begin(CGM.getContext()), 4215 e = ID->classmeth_end(CGM.getContext()); i != e; ++i) { 4216 // Class methods should always be defined. 4217 Methods.push_back(GetMethodConstant(*i)); 4218 } 4219 } else { 4220 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); 4221 for (ObjCImplementationDecl::instmeth_iterator 4222 i = ID->instmeth_begin(CGM.getContext()), 4223 e = ID->instmeth_end(CGM.getContext()); i != e; ++i) { 4224 // Instance methods should always be defined. 4225 Methods.push_back(GetMethodConstant(*i)); 4226 } 4227 for (ObjCImplementationDecl::propimpl_iterator 4228 i = ID->propimpl_begin(CGM.getContext()), 4229 e = ID->propimpl_end(CGM.getContext()); i != e; ++i) { 4230 ObjCPropertyImplDecl *PID = *i; 4231 4232 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){ 4233 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 4234 4235 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 4236 if (llvm::Constant *C = GetMethodConstant(MD)) 4237 Methods.push_back(C); 4238 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 4239 if (llvm::Constant *C = GetMethodConstant(MD)) 4240 Methods.push_back(C); 4241 } 4242 } 4243 } 4244 Values[ 5] = EmitMethodList(MethodListName, 4245 "__DATA, __objc_const", Methods); 4246 4247 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 4248 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer"); 4249 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" 4250 + OID->getNameAsString(), 4251 OID->protocol_begin(), 4252 OID->protocol_end()); 4253 4254 if (flags & CLS_META) 4255 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 4256 else 4257 Values[ 7] = EmitIvarList(ID); 4258 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 4259 : BuildIvarLayout(ID, false); 4260 if (flags & CLS_META) 4261 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 4262 else 4263 Values[ 9] = 4264 EmitPropertyList( 4265 "\01l_OBJC_$_PROP_LIST_" + ID->getNameAsString(), 4266 ID, ID->getClassInterface(), ObjCTypes); 4267 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, 4268 Values); 4269 llvm::GlobalVariable *CLASS_RO_GV = 4270 new llvm::GlobalVariable(ObjCTypes.ClassRonfABITy, false, 4271 llvm::GlobalValue::InternalLinkage, 4272 Init, 4273 (flags & CLS_META) ? 4274 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : 4275 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, 4276 &CGM.getModule()); 4277 CLASS_RO_GV->setAlignment( 4278 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassRonfABITy)); 4279 CLASS_RO_GV->setSection("__DATA, __objc_const"); 4280 return CLASS_RO_GV; 4281 4282 } 4283 4284 /// BuildClassMetaData - This routine defines that to-level meta-data 4285 /// for the given ClassName for: 4286 /// struct _class_t { 4287 /// struct _class_t *isa; 4288 /// struct _class_t * const superclass; 4289 /// void *cache; 4290 /// IMP *vtable; 4291 /// struct class_ro_t *ro; 4292 /// } 4293 /// 4294 llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( 4295 std::string &ClassName, 4296 llvm::Constant *IsAGV, 4297 llvm::Constant *SuperClassGV, 4298 llvm::Constant *ClassRoGV, 4299 bool HiddenVisibility) { 4300 std::vector<llvm::Constant*> Values(5); 4301 Values[0] = IsAGV; 4302 Values[1] = SuperClassGV 4303 ? SuperClassGV 4304 : llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); 4305 Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar 4306 Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar 4307 Values[4] = ClassRoGV; // &CLASS_RO_GV 4308 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, 4309 Values); 4310 llvm::GlobalVariable *GV = GetClassGlobal(ClassName); 4311 GV->setInitializer(Init); 4312 GV->setSection("__DATA, __objc_data"); 4313 GV->setAlignment( 4314 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassnfABITy)); 4315 if (HiddenVisibility) 4316 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4317 return GV; 4318 } 4319 4320 bool 4321 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 4322 return OD->getClassMethod(CGM.getContext(), GetNullarySelector("load")) != 0; 4323 } 4324 4325 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 4326 uint32_t &InstanceStart, 4327 uint32_t &InstanceSize) { 4328 const ASTRecordLayout &RL = 4329 CGM.getContext().getASTObjCImplementationLayout(OID); 4330 4331 // InstanceSize is really instance end. 4332 InstanceSize = llvm::RoundUpToAlignment(RL.getNextOffset(), 8) / 8; 4333 4334 // If there are no fields, the start is the same as the end. 4335 if (!RL.getFieldCount()) 4336 InstanceStart = InstanceSize; 4337 else 4338 InstanceStart = RL.getFieldOffset(0) / 8; 4339 } 4340 4341 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 4342 std::string ClassName = ID->getNameAsString(); 4343 if (!ObjCEmptyCacheVar) { 4344 ObjCEmptyCacheVar = new llvm::GlobalVariable( 4345 ObjCTypes.CacheTy, 4346 false, 4347 llvm::GlobalValue::ExternalLinkage, 4348 0, 4349 "_objc_empty_cache", 4350 &CGM.getModule()); 4351 4352 ObjCEmptyVtableVar = new llvm::GlobalVariable( 4353 ObjCTypes.ImpnfABITy, 4354 false, 4355 llvm::GlobalValue::ExternalLinkage, 4356 0, 4357 "_objc_empty_vtable", 4358 &CGM.getModule()); 4359 } 4360 assert(ID->getClassInterface() && 4361 "CGObjCNonFragileABIMac::GenerateClass - class is 0"); 4362 // FIXME: Is this correct (that meta class size is never computed)? 4363 uint32_t InstanceStart = 4364 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy); 4365 uint32_t InstanceSize = InstanceStart; 4366 uint32_t flags = CLS_META; 4367 std::string ObjCMetaClassName(getMetaclassSymbolPrefix()); 4368 std::string ObjCClassName(getClassSymbolPrefix()); 4369 4370 llvm::GlobalVariable *SuperClassGV, *IsAGV; 4371 4372 bool classIsHidden = 4373 CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden; 4374 if (classIsHidden) 4375 flags |= OBJC2_CLS_HIDDEN; 4376 if (!ID->getClassInterface()->getSuperClass()) { 4377 // class is root 4378 flags |= CLS_ROOT; 4379 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName); 4380 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName); 4381 } else { 4382 // Has a root. Current class is not a root. 4383 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 4384 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 4385 Root = Super; 4386 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); 4387 // work on super class metadata symbol. 4388 std::string SuperClassName = 4389 ObjCMetaClassName + ID->getClassInterface()->getSuperClass()->getNameAsString(); 4390 SuperClassGV = GetClassGlobal(SuperClassName); 4391 } 4392 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, 4393 InstanceStart, 4394 InstanceSize,ID); 4395 std::string TClassName = ObjCMetaClassName + ClassName; 4396 llvm::GlobalVariable *MetaTClass = 4397 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, 4398 classIsHidden); 4399 4400 // Metadata for the class 4401 flags = CLS; 4402 if (classIsHidden) 4403 flags |= OBJC2_CLS_HIDDEN; 4404 4405 if (hasObjCExceptionAttribute(ID->getClassInterface())) 4406 flags |= CLS_EXCEPTION; 4407 4408 if (!ID->getClassInterface()->getSuperClass()) { 4409 flags |= CLS_ROOT; 4410 SuperClassGV = 0; 4411 } else { 4412 // Has a root. Current class is not a root. 4413 std::string RootClassName = 4414 ID->getClassInterface()->getSuperClass()->getNameAsString(); 4415 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName); 4416 } 4417 GetClassSizeInfo(ID, InstanceStart, InstanceSize); 4418 CLASS_RO_GV = BuildClassRoTInitializer(flags, 4419 InstanceStart, 4420 InstanceSize, 4421 ID); 4422 4423 TClassName = ObjCClassName + ClassName; 4424 llvm::GlobalVariable *ClassMD = 4425 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, 4426 classIsHidden); 4427 DefinedClasses.push_back(ClassMD); 4428 4429 // Determine if this class is also "non-lazy". 4430 if (ImplementationIsNonLazy(ID)) 4431 DefinedNonLazyClasses.push_back(ClassMD); 4432 4433 // Force the definition of the EHType if necessary. 4434 if (flags & CLS_EXCEPTION) 4435 GetInterfaceEHType(ID->getClassInterface(), true); 4436 } 4437 4438 /// GenerateProtocolRef - This routine is called to generate code for 4439 /// a protocol reference expression; as in: 4440 /// @code 4441 /// @protocol(Proto1); 4442 /// @endcode 4443 /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1 4444 /// which will hold address of the protocol meta-data. 4445 /// 4446 llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder, 4447 const ObjCProtocolDecl *PD) { 4448 4449 // This routine is called for @protocol only. So, we must build definition 4450 // of protocol's meta-data (not a reference to it!) 4451 // 4452 llvm::Constant *Init = llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD), 4453 ObjCTypes.ExternalProtocolPtrTy); 4454 4455 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_"); 4456 ProtocolName += PD->getNameAsCString(); 4457 4458 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); 4459 if (PTGV) 4460 return Builder.CreateLoad(PTGV, false, "tmp"); 4461 PTGV = new llvm::GlobalVariable( 4462 Init->getType(), false, 4463 llvm::GlobalValue::WeakAnyLinkage, 4464 Init, 4465 ProtocolName, 4466 &CGM.getModule()); 4467 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); 4468 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4469 UsedGlobals.push_back(PTGV); 4470 return Builder.CreateLoad(PTGV, false, "tmp"); 4471 } 4472 4473 /// GenerateCategory - Build metadata for a category implementation. 4474 /// struct _category_t { 4475 /// const char * const name; 4476 /// struct _class_t *const cls; 4477 /// const struct _method_list_t * const instance_methods; 4478 /// const struct _method_list_t * const class_methods; 4479 /// const struct _protocol_list_t * const protocols; 4480 /// const struct _prop_list_t * const properties; 4481 /// } 4482 /// 4483 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 4484 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 4485 const char *Prefix = "\01l_OBJC_$_CATEGORY_"; 4486 std::string ExtCatName(Prefix + Interface->getNameAsString()+ 4487 "_$_" + OCD->getNameAsString()); 4488 std::string ExtClassName(getClassSymbolPrefix() + 4489 Interface->getNameAsString()); 4490 4491 std::vector<llvm::Constant*> Values(6); 4492 Values[0] = GetClassName(OCD->getIdentifier()); 4493 // meta-class entry symbol 4494 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName); 4495 Values[1] = ClassGV; 4496 std::vector<llvm::Constant*> Methods; 4497 std::string MethodListName(Prefix); 4498 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + 4499 "_$_" + OCD->getNameAsString(); 4500 4501 for (ObjCCategoryImplDecl::instmeth_iterator 4502 i = OCD->instmeth_begin(CGM.getContext()), 4503 e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) { 4504 // Instance methods should always be defined. 4505 Methods.push_back(GetMethodConstant(*i)); 4506 } 4507 4508 Values[2] = EmitMethodList(MethodListName, 4509 "__DATA, __objc_const", 4510 Methods); 4511 4512 MethodListName = Prefix; 4513 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + 4514 OCD->getNameAsString(); 4515 Methods.clear(); 4516 for (ObjCCategoryImplDecl::classmeth_iterator 4517 i = OCD->classmeth_begin(CGM.getContext()), 4518 e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) { 4519 // Class methods should always be defined. 4520 Methods.push_back(GetMethodConstant(*i)); 4521 } 4522 4523 Values[3] = EmitMethodList(MethodListName, 4524 "__DATA, __objc_const", 4525 Methods); 4526 const ObjCCategoryDecl *Category = 4527 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 4528 if (Category) { 4529 std::string ExtName(Interface->getNameAsString() + "_$_" + 4530 OCD->getNameAsString()); 4531 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 4532 + Interface->getNameAsString() + "_$_" 4533 + Category->getNameAsString(), 4534 Category->protocol_begin(), 4535 Category->protocol_end()); 4536 Values[5] = 4537 EmitPropertyList(std::string("\01l_OBJC_$_PROP_LIST_") + ExtName, 4538 OCD, Category, ObjCTypes); 4539 } 4540 else { 4541 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 4542 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 4543 } 4544 4545 llvm::Constant *Init = 4546 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 4547 Values); 4548 llvm::GlobalVariable *GCATV 4549 = new llvm::GlobalVariable(ObjCTypes.CategorynfABITy, 4550 false, 4551 llvm::GlobalValue::InternalLinkage, 4552 Init, 4553 ExtCatName, 4554 &CGM.getModule()); 4555 GCATV->setAlignment( 4556 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.CategorynfABITy)); 4557 GCATV->setSection("__DATA, __objc_const"); 4558 UsedGlobals.push_back(GCATV); 4559 DefinedCategories.push_back(GCATV); 4560 4561 // Determine if this category is also "non-lazy". 4562 if (ImplementationIsNonLazy(OCD)) 4563 DefinedNonLazyCategories.push_back(GCATV); 4564 } 4565 4566 /// GetMethodConstant - Return a struct objc_method constant for the 4567 /// given method if it has been defined. The result is null if the 4568 /// method has not been defined. The return value has type MethodPtrTy. 4569 llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( 4570 const ObjCMethodDecl *MD) { 4571 // FIXME: Use DenseMap::lookup 4572 llvm::Function *Fn = MethodDefinitions[MD]; 4573 if (!Fn) 4574 return 0; 4575 4576 std::vector<llvm::Constant*> Method(3); 4577 Method[0] = 4578 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 4579 ObjCTypes.SelectorPtrTy); 4580 Method[1] = GetMethodVarType(MD); 4581 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 4582 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 4583 } 4584 4585 /// EmitMethodList - Build meta-data for method declarations 4586 /// struct _method_list_t { 4587 /// uint32_t entsize; // sizeof(struct _objc_method) 4588 /// uint32_t method_count; 4589 /// struct _objc_method method_list[method_count]; 4590 /// } 4591 /// 4592 llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( 4593 const std::string &Name, 4594 const char *Section, 4595 const ConstantVector &Methods) { 4596 // Return null for empty list. 4597 if (Methods.empty()) 4598 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); 4599 4600 std::vector<llvm::Constant*> Values(3); 4601 // sizeof(struct _objc_method) 4602 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy); 4603 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4604 // method_count 4605 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 4606 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 4607 Methods.size()); 4608 Values[2] = llvm::ConstantArray::get(AT, Methods); 4609 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 4610 4611 llvm::GlobalVariable *GV = 4612 new llvm::GlobalVariable(Init->getType(), false, 4613 llvm::GlobalValue::InternalLinkage, 4614 Init, 4615 Name, 4616 &CGM.getModule()); 4617 GV->setAlignment( 4618 CGM.getTargetData().getPrefTypeAlignment(Init->getType())); 4619 GV->setSection(Section); 4620 UsedGlobals.push_back(GV); 4621 return llvm::ConstantExpr::getBitCast(GV, 4622 ObjCTypes.MethodListnfABIPtrTy); 4623 } 4624 4625 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 4626 /// the given ivar. 4627 llvm::GlobalVariable * CGObjCNonFragileABIMac::ObjCIvarOffsetVariable( 4628 const ObjCInterfaceDecl *ID, 4629 const ObjCIvarDecl *Ivar) { 4630 // FIXME: We shouldn't need to do this lookup. 4631 unsigned Index; 4632 const ObjCInterfaceDecl *Container = 4633 FindIvarInterface(CGM.getContext(), ID, Ivar, Index); 4634 assert(Container && "Unable to find ivar container!"); 4635 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + 4636 '.' + Ivar->getNameAsString(); 4637 llvm::GlobalVariable *IvarOffsetGV = 4638 CGM.getModule().getGlobalVariable(Name); 4639 if (!IvarOffsetGV) 4640 IvarOffsetGV = 4641 new llvm::GlobalVariable(ObjCTypes.LongTy, 4642 false, 4643 llvm::GlobalValue::ExternalLinkage, 4644 0, 4645 Name, 4646 &CGM.getModule()); 4647 return IvarOffsetGV; 4648 } 4649 4650 llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( 4651 const ObjCInterfaceDecl *ID, 4652 const ObjCIvarDecl *Ivar, 4653 unsigned long int Offset) { 4654 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); 4655 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, 4656 Offset)); 4657 IvarOffsetGV->setAlignment( 4658 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy)); 4659 4660 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as 4661 // well (i.e., in ObjCIvarOffsetVariable). 4662 if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 4663 Ivar->getAccessControl() == ObjCIvarDecl::Package || 4664 CGM.getDeclVisibilityMode(ID) == LangOptions::Hidden) 4665 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4666 else 4667 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); 4668 IvarOffsetGV->setSection("__DATA, __objc_const"); 4669 return IvarOffsetGV; 4670 } 4671 4672 /// EmitIvarList - Emit the ivar list for the given 4673 /// implementation. The return value has type 4674 /// IvarListnfABIPtrTy. 4675 /// struct _ivar_t { 4676 /// unsigned long int *offset; // pointer to ivar offset location 4677 /// char *name; 4678 /// char *type; 4679 /// uint32_t alignment; 4680 /// uint32_t size; 4681 /// } 4682 /// struct _ivar_list_t { 4683 /// uint32 entsize; // sizeof(struct _ivar_t) 4684 /// uint32 count; 4685 /// struct _iver_t list[count]; 4686 /// } 4687 /// 4688 4689 llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( 4690 const ObjCImplementationDecl *ID) { 4691 4692 std::vector<llvm::Constant*> Ivars, Ivar(5); 4693 4694 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 4695 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); 4696 4697 // FIXME. Consolidate this with similar code in GenerateClass. 4698 4699 // Collect declared and synthesized ivars in a small vector. 4700 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars; 4701 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars); 4702 4703 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) { 4704 ObjCIvarDecl *IVD = OIvars[i]; 4705 // Ignore unnamed bit-fields. 4706 if (!IVD->getDeclName()) 4707 continue; 4708 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD, 4709 ComputeIvarBaseOffset(CGM, ID, IVD)); 4710 Ivar[1] = GetMethodVarName(IVD->getIdentifier()); 4711 Ivar[2] = GetMethodVarType(IVD); 4712 const llvm::Type *FieldTy = 4713 CGM.getTypes().ConvertTypeForMem(IVD->getType()); 4714 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy); 4715 unsigned Align = CGM.getContext().getPreferredTypeAlign( 4716 IVD->getType().getTypePtr()) >> 3; 4717 Align = llvm::Log2_32(Align); 4718 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); 4719 // NOTE. Size of a bitfield does not match gcc's, because of the 4720 // way bitfields are treated special in each. But I am told that 4721 // 'size' for bitfield ivars is ignored by the runtime so it does 4722 // not matter. If it matters, there is enough info to get the 4723 // bitfield right! 4724 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4725 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); 4726 } 4727 // Return null for empty list. 4728 if (Ivars.empty()) 4729 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 4730 std::vector<llvm::Constant*> Values(3); 4731 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy); 4732 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4733 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 4734 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, 4735 Ivars.size()); 4736 Values[2] = llvm::ConstantArray::get(AT, Ivars); 4737 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 4738 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; 4739 llvm::GlobalVariable *GV = 4740 new llvm::GlobalVariable(Init->getType(), false, 4741 llvm::GlobalValue::InternalLinkage, 4742 Init, 4743 Prefix + OID->getNameAsString(), 4744 &CGM.getModule()); 4745 GV->setAlignment( 4746 CGM.getTargetData().getPrefTypeAlignment(Init->getType())); 4747 GV->setSection("__DATA, __objc_const"); 4748 4749 UsedGlobals.push_back(GV); 4750 return llvm::ConstantExpr::getBitCast(GV, 4751 ObjCTypes.IvarListnfABIPtrTy); 4752 } 4753 4754 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( 4755 const ObjCProtocolDecl *PD) { 4756 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 4757 4758 if (!Entry) { 4759 // We use the initializer as a marker of whether this is a forward 4760 // reference or not. At module finalization we add the empty 4761 // contents for protocols which were referenced but never defined. 4762 Entry = 4763 new llvm::GlobalVariable(ObjCTypes.ProtocolnfABITy, false, 4764 llvm::GlobalValue::ExternalLinkage, 4765 0, 4766 "\01l_OBJC_PROTOCOL_$_" + PD->getNameAsString(), 4767 &CGM.getModule()); 4768 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 4769 UsedGlobals.push_back(Entry); 4770 } 4771 4772 return Entry; 4773 } 4774 4775 /// GetOrEmitProtocol - Generate the protocol meta-data: 4776 /// @code 4777 /// struct _protocol_t { 4778 /// id isa; // NULL 4779 /// const char * const protocol_name; 4780 /// const struct _protocol_list_t * protocol_list; // super protocols 4781 /// const struct method_list_t * const instance_methods; 4782 /// const struct method_list_t * const class_methods; 4783 /// const struct method_list_t *optionalInstanceMethods; 4784 /// const struct method_list_t *optionalClassMethods; 4785 /// const struct _prop_list_t * properties; 4786 /// const uint32_t size; // sizeof(struct _protocol_t) 4787 /// const uint32_t flags; // = 0 4788 /// } 4789 /// @endcode 4790 /// 4791 4792 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( 4793 const ObjCProtocolDecl *PD) { 4794 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 4795 4796 // Early exit if a defining object has already been generated. 4797 if (Entry && Entry->hasInitializer()) 4798 return Entry; 4799 4800 const char *ProtocolName = PD->getNameAsCString(); 4801 4802 // Construct method lists. 4803 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 4804 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 4805 for (ObjCProtocolDecl::instmeth_iterator 4806 i = PD->instmeth_begin(CGM.getContext()), 4807 e = PD->instmeth_end(CGM.getContext()); 4808 i != e; ++i) { 4809 ObjCMethodDecl *MD = *i; 4810 llvm::Constant *C = GetMethodDescriptionConstant(MD); 4811 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 4812 OptInstanceMethods.push_back(C); 4813 } else { 4814 InstanceMethods.push_back(C); 4815 } 4816 } 4817 4818 for (ObjCProtocolDecl::classmeth_iterator 4819 i = PD->classmeth_begin(CGM.getContext()), 4820 e = PD->classmeth_end(CGM.getContext()); 4821 i != e; ++i) { 4822 ObjCMethodDecl *MD = *i; 4823 llvm::Constant *C = GetMethodDescriptionConstant(MD); 4824 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 4825 OptClassMethods.push_back(C); 4826 } else { 4827 ClassMethods.push_back(C); 4828 } 4829 } 4830 4831 std::vector<llvm::Constant*> Values(10); 4832 // isa is NULL 4833 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); 4834 Values[1] = GetClassName(PD->getIdentifier()); 4835 Values[2] = EmitProtocolList( 4836 "\01l_OBJC_$_PROTOCOL_REFS_" + PD->getNameAsString(), 4837 PD->protocol_begin(), 4838 PD->protocol_end()); 4839 4840 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_" 4841 + PD->getNameAsString(), 4842 "__DATA, __objc_const", 4843 InstanceMethods); 4844 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" 4845 + PD->getNameAsString(), 4846 "__DATA, __objc_const", 4847 ClassMethods); 4848 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_" 4849 + PD->getNameAsString(), 4850 "__DATA, __objc_const", 4851 OptInstanceMethods); 4852 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" 4853 + PD->getNameAsString(), 4854 "__DATA, __objc_const", 4855 OptClassMethods); 4856 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getNameAsString(), 4857 0, PD, ObjCTypes); 4858 uint32_t Size = 4859 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); 4860 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 4861 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy); 4862 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy, 4863 Values); 4864 4865 if (Entry) { 4866 // Already created, fix the linkage and update the initializer. 4867 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 4868 Entry->setInitializer(Init); 4869 } else { 4870 Entry = 4871 new llvm::GlobalVariable(ObjCTypes.ProtocolnfABITy, false, 4872 llvm::GlobalValue::WeakAnyLinkage, 4873 Init, 4874 std::string("\01l_OBJC_PROTOCOL_$_")+ProtocolName, 4875 &CGM.getModule()); 4876 Entry->setAlignment( 4877 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABITy)); 4878 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 4879 } 4880 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 4881 4882 // Use this protocol meta-data to build protocol list table in section 4883 // __DATA, __objc_protolist 4884 llvm::GlobalVariable *PTGV = new llvm::GlobalVariable( 4885 ObjCTypes.ProtocolnfABIPtrTy, false, 4886 llvm::GlobalValue::WeakAnyLinkage, 4887 Entry, 4888 std::string("\01l_OBJC_LABEL_PROTOCOL_$_") 4889 +ProtocolName, 4890 &CGM.getModule()); 4891 PTGV->setAlignment( 4892 CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)); 4893 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); 4894 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4895 UsedGlobals.push_back(PTGV); 4896 return Entry; 4897 } 4898 4899 /// EmitProtocolList - Generate protocol list meta-data: 4900 /// @code 4901 /// struct _protocol_list_t { 4902 /// long protocol_count; // Note, this is 32/64 bit 4903 /// struct _protocol_t[protocol_count]; 4904 /// } 4905 /// @endcode 4906 /// 4907 llvm::Constant * 4908 CGObjCNonFragileABIMac::EmitProtocolList(const std::string &Name, 4909 ObjCProtocolDecl::protocol_iterator begin, 4910 ObjCProtocolDecl::protocol_iterator end) { 4911 std::vector<llvm::Constant*> ProtocolRefs; 4912 4913 // Just return null for empty protocol lists 4914 if (begin == end) 4915 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 4916 4917 // FIXME: We shouldn't need to do this lookup here, should we? 4918 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true); 4919 if (GV) 4920 return llvm::ConstantExpr::getBitCast(GV, 4921 ObjCTypes.ProtocolListnfABIPtrTy); 4922 4923 for (; begin != end; ++begin) 4924 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented??? 4925 4926 // This list is null terminated. 4927 ProtocolRefs.push_back(llvm::Constant::getNullValue( 4928 ObjCTypes.ProtocolnfABIPtrTy)); 4929 4930 std::vector<llvm::Constant*> Values(2); 4931 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 4932 Values[1] = 4933 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy, 4934 ProtocolRefs.size()), 4935 ProtocolRefs); 4936 4937 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 4938 GV = new llvm::GlobalVariable(Init->getType(), false, 4939 llvm::GlobalValue::InternalLinkage, 4940 Init, 4941 Name, 4942 &CGM.getModule()); 4943 GV->setSection("__DATA, __objc_const"); 4944 GV->setAlignment( 4945 CGM.getTargetData().getPrefTypeAlignment(Init->getType())); 4946 UsedGlobals.push_back(GV); 4947 return llvm::ConstantExpr::getBitCast(GV, 4948 ObjCTypes.ProtocolListnfABIPtrTy); 4949 } 4950 4951 /// GetMethodDescriptionConstant - This routine build following meta-data: 4952 /// struct _objc_method { 4953 /// SEL _cmd; 4954 /// char *method_type; 4955 /// char *_imp; 4956 /// } 4957 4958 llvm::Constant * 4959 CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 4960 std::vector<llvm::Constant*> Desc(3); 4961 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 4962 ObjCTypes.SelectorPtrTy); 4963 Desc[1] = GetMethodVarType(MD); 4964 // Protocol methods have no implementation. So, this entry is always NULL. 4965 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 4966 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); 4967 } 4968 4969 /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference. 4970 /// This code gen. amounts to generating code for: 4971 /// @code 4972 /// (type *)((char *)base + _OBJC_IVAR_$_.ivar; 4973 /// @encode 4974 /// 4975 LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( 4976 CodeGen::CodeGenFunction &CGF, 4977 QualType ObjectTy, 4978 llvm::Value *BaseValue, 4979 const ObjCIvarDecl *Ivar, 4980 unsigned CVRQualifiers) { 4981 const ObjCInterfaceDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl(); 4982 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 4983 EmitIvarOffset(CGF, ID, Ivar)); 4984 } 4985 4986 llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset( 4987 CodeGen::CodeGenFunction &CGF, 4988 const ObjCInterfaceDecl *Interface, 4989 const ObjCIvarDecl *Ivar) { 4990 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar), 4991 false, "ivar"); 4992 } 4993 4994 CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend( 4995 CodeGen::CodeGenFunction &CGF, 4996 QualType ResultType, 4997 Selector Sel, 4998 llvm::Value *Receiver, 4999 QualType Arg0Ty, 5000 bool IsSuper, 5001 const CallArgList &CallArgs) { 5002 // FIXME. Even though IsSuper is passes. This function doese not handle calls 5003 // to 'super' receivers. 5004 CodeGenTypes &Types = CGM.getTypes(); 5005 llvm::Value *Arg0 = Receiver; 5006 if (!IsSuper) 5007 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp"); 5008 5009 // Find the message function name. 5010 // FIXME. This is too much work to get the ABI-specific result type needed to 5011 // find the message name. 5012 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, 5013 llvm::SmallVector<QualType, 16>()); 5014 llvm::Constant *Fn = 0; 5015 std::string Name("\01l_"); 5016 if (CGM.ReturnTypeUsesSret(FnInfo)) { 5017 #if 0 5018 // unlike what is documented. gcc never generates this API!! 5019 if (Receiver->getType() == ObjCTypes.ObjectPtrTy) { 5020 Fn = ObjCTypes.getMessageSendIdStretFixupFn(); 5021 // FIXME. Is there a better way of getting these names. 5022 // They are available in RuntimeFunctions vector pair. 5023 Name += "objc_msgSendId_stret_fixup"; 5024 } 5025 else 5026 #endif 5027 if (IsSuper) { 5028 Fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); 5029 Name += "objc_msgSendSuper2_stret_fixup"; 5030 } 5031 else 5032 { 5033 Fn = ObjCTypes.getMessageSendStretFixupFn(); 5034 Name += "objc_msgSend_stret_fixup"; 5035 } 5036 } 5037 else if (!IsSuper && ResultType->isFloatingType()) { 5038 if (const BuiltinType *BT = ResultType->getAsBuiltinType()) { 5039 BuiltinType::Kind k = BT->getKind(); 5040 if (k == BuiltinType::LongDouble) { 5041 Fn = ObjCTypes.getMessageSendFpretFixupFn(); 5042 Name += "objc_msgSend_fpret_fixup"; 5043 } 5044 else { 5045 Fn = ObjCTypes.getMessageSendFixupFn(); 5046 Name += "objc_msgSend_fixup"; 5047 } 5048 } 5049 } 5050 else { 5051 #if 0 5052 // unlike what is documented. gcc never generates this API!! 5053 if (Receiver->getType() == ObjCTypes.ObjectPtrTy) { 5054 Fn = ObjCTypes.getMessageSendIdFixupFn(); 5055 Name += "objc_msgSendId_fixup"; 5056 } 5057 else 5058 #endif 5059 if (IsSuper) { 5060 Fn = ObjCTypes.getMessageSendSuper2FixupFn(); 5061 Name += "objc_msgSendSuper2_fixup"; 5062 } 5063 else 5064 { 5065 Fn = ObjCTypes.getMessageSendFixupFn(); 5066 Name += "objc_msgSend_fixup"; 5067 } 5068 } 5069 assert(Fn && "CGObjCNonFragileABIMac::EmitMessageSend"); 5070 Name += '_'; 5071 std::string SelName(Sel.getAsString()); 5072 // Replace all ':' in selector name with '_' ouch! 5073 for(unsigned i = 0; i < SelName.size(); i++) 5074 if (SelName[i] == ':') 5075 SelName[i] = '_'; 5076 Name += SelName; 5077 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 5078 if (!GV) { 5079 // Build message ref table entry. 5080 std::vector<llvm::Constant*> Values(2); 5081 Values[0] = Fn; 5082 Values[1] = GetMethodVarName(Sel); 5083 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 5084 GV = new llvm::GlobalVariable(Init->getType(), false, 5085 llvm::GlobalValue::WeakAnyLinkage, 5086 Init, 5087 Name, 5088 &CGM.getModule()); 5089 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5090 GV->setAlignment(16); 5091 GV->setSection("__DATA, __objc_msgrefs, coalesced"); 5092 } 5093 llvm::Value *Arg1 = CGF.Builder.CreateBitCast(GV, ObjCTypes.MessageRefPtrTy); 5094 5095 CallArgList ActualArgs; 5096 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); 5097 ActualArgs.push_back(std::make_pair(RValue::get(Arg1), 5098 ObjCTypes.MessageRefCPtrTy)); 5099 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 5100 const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs); 5101 llvm::Value *Callee = CGF.Builder.CreateStructGEP(Arg1, 0); 5102 Callee = CGF.Builder.CreateLoad(Callee); 5103 const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true); 5104 Callee = CGF.Builder.CreateBitCast(Callee, 5105 llvm::PointerType::getUnqual(FTy)); 5106 return CGF.EmitCall(FnInfo1, Callee, ActualArgs); 5107 } 5108 5109 /// Generate code for a message send expression in the nonfragile abi. 5110 CodeGen::RValue CGObjCNonFragileABIMac::GenerateMessageSend( 5111 CodeGen::CodeGenFunction &CGF, 5112 QualType ResultType, 5113 Selector Sel, 5114 llvm::Value *Receiver, 5115 bool IsClassMessage, 5116 const CallArgList &CallArgs, 5117 const ObjCMethodDecl *Method) { 5118 return LegacyDispatchedSelector(Sel) 5119 ? EmitLegacyMessageSend(CGF, ResultType, EmitSelector(CGF.Builder, Sel), 5120 Receiver, CGF.getContext().getObjCIdType(), 5121 false, CallArgs, ObjCTypes) 5122 : EmitMessageSend(CGF, ResultType, Sel, 5123 Receiver, CGF.getContext().getObjCIdType(), 5124 false, CallArgs); 5125 } 5126 5127 llvm::GlobalVariable * 5128 CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) { 5129 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 5130 5131 if (!GV) { 5132 GV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, 5133 llvm::GlobalValue::ExternalLinkage, 5134 0, Name, &CGM.getModule()); 5135 } 5136 5137 return GV; 5138 } 5139 5140 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder, 5141 const ObjCInterfaceDecl *ID) { 5142 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; 5143 5144 if (!Entry) { 5145 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5146 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5147 Entry = 5148 new llvm::GlobalVariable(ObjCTypes.ClassnfABIPtrTy, false, 5149 llvm::GlobalValue::InternalLinkage, 5150 ClassGV, 5151 "\01L_OBJC_CLASSLIST_REFERENCES_$_", 5152 &CGM.getModule()); 5153 Entry->setAlignment( 5154 CGM.getTargetData().getPrefTypeAlignment( 5155 ObjCTypes.ClassnfABIPtrTy)); 5156 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip"); 5157 UsedGlobals.push_back(Entry); 5158 } 5159 5160 return Builder.CreateLoad(Entry, false, "tmp"); 5161 } 5162 5163 llvm::Value * 5164 CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder, 5165 const ObjCInterfaceDecl *ID) { 5166 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()]; 5167 5168 if (!Entry) { 5169 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5170 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5171 Entry = 5172 new llvm::GlobalVariable(ObjCTypes.ClassnfABIPtrTy, false, 5173 llvm::GlobalValue::InternalLinkage, 5174 ClassGV, 5175 "\01L_OBJC_CLASSLIST_SUP_REFS_$_", 5176 &CGM.getModule()); 5177 Entry->setAlignment( 5178 CGM.getTargetData().getPrefTypeAlignment( 5179 ObjCTypes.ClassnfABIPtrTy)); 5180 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5181 UsedGlobals.push_back(Entry); 5182 } 5183 5184 return Builder.CreateLoad(Entry, false, "tmp"); 5185 } 5186 5187 /// EmitMetaClassRef - Return a Value * of the address of _class_t 5188 /// meta-data 5189 /// 5190 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder, 5191 const ObjCInterfaceDecl *ID) { 5192 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()]; 5193 if (Entry) 5194 return Builder.CreateLoad(Entry, false, "tmp"); 5195 5196 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString()); 5197 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName); 5198 Entry = 5199 new llvm::GlobalVariable(ObjCTypes.ClassnfABIPtrTy, false, 5200 llvm::GlobalValue::InternalLinkage, 5201 MetaClassGV, 5202 "\01L_OBJC_CLASSLIST_SUP_REFS_$_", 5203 &CGM.getModule()); 5204 Entry->setAlignment( 5205 CGM.getTargetData().getPrefTypeAlignment( 5206 ObjCTypes.ClassnfABIPtrTy)); 5207 5208 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5209 UsedGlobals.push_back(Entry); 5210 5211 return Builder.CreateLoad(Entry, false, "tmp"); 5212 } 5213 5214 /// GetClass - Return a reference to the class for the given interface 5215 /// decl. 5216 llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder, 5217 const ObjCInterfaceDecl *ID) { 5218 return EmitClassRef(Builder, ID); 5219 } 5220 5221 /// Generates a message send where the super is the receiver. This is 5222 /// a message send to self with special delivery semantics indicating 5223 /// which class's method should be called. 5224 CodeGen::RValue 5225 CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 5226 QualType ResultType, 5227 Selector Sel, 5228 const ObjCInterfaceDecl *Class, 5229 bool isCategoryImpl, 5230 llvm::Value *Receiver, 5231 bool IsClassMessage, 5232 const CodeGen::CallArgList &CallArgs) { 5233 // ... 5234 // Create and init a super structure; this is a (receiver, class) 5235 // pair we will pass to objc_msgSendSuper. 5236 llvm::Value *ObjCSuper = 5237 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super"); 5238 5239 llvm::Value *ReceiverAsObject = 5240 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 5241 CGF.Builder.CreateStore(ReceiverAsObject, 5242 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 5243 5244 // If this is a class message the metaclass is passed as the target. 5245 llvm::Value *Target; 5246 if (IsClassMessage) { 5247 if (isCategoryImpl) { 5248 // Message sent to "super' in a class method defined in 5249 // a category implementation. 5250 Target = EmitClassRef(CGF.Builder, Class); 5251 Target = CGF.Builder.CreateStructGEP(Target, 0); 5252 Target = CGF.Builder.CreateLoad(Target); 5253 } 5254 else 5255 Target = EmitMetaClassRef(CGF.Builder, Class); 5256 } 5257 else 5258 Target = EmitSuperClassRef(CGF.Builder, Class); 5259 5260 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 5261 // ObjCTypes types. 5262 const llvm::Type *ClassTy = 5263 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 5264 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 5265 CGF.Builder.CreateStore(Target, 5266 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 5267 5268 return (LegacyDispatchedSelector(Sel)) 5269 ? EmitLegacyMessageSend(CGF, ResultType,EmitSelector(CGF.Builder, Sel), 5270 ObjCSuper, ObjCTypes.SuperPtrCTy, 5271 true, CallArgs, 5272 ObjCTypes) 5273 : EmitMessageSend(CGF, ResultType, Sel, 5274 ObjCSuper, ObjCTypes.SuperPtrCTy, 5275 true, CallArgs); 5276 } 5277 5278 llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder, 5279 Selector Sel) { 5280 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5281 5282 if (!Entry) { 5283 llvm::Constant *Casted = 5284 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 5285 ObjCTypes.SelectorPtrTy); 5286 Entry = 5287 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false, 5288 llvm::GlobalValue::InternalLinkage, 5289 Casted, "\01L_OBJC_SELECTOR_REFERENCES_", 5290 &CGM.getModule()); 5291 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); 5292 UsedGlobals.push_back(Entry); 5293 } 5294 5295 return Builder.CreateLoad(Entry, false, "tmp"); 5296 } 5297 /// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 5298 /// objc_assign_ivar (id src, id *dst) 5299 /// 5300 void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 5301 llvm::Value *src, llvm::Value *dst) 5302 { 5303 const llvm::Type * SrcTy = src->getType(); 5304 if (!isa<llvm::PointerType>(SrcTy)) { 5305 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5306 assert(Size <= 8 && "does not support size > 8"); 5307 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5308 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5309 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5310 } 5311 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5312 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5313 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignIvarFn(), 5314 src, dst, "assignivar"); 5315 return; 5316 } 5317 5318 /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 5319 /// objc_assign_strongCast (id src, id *dst) 5320 /// 5321 void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( 5322 CodeGen::CodeGenFunction &CGF, 5323 llvm::Value *src, llvm::Value *dst) 5324 { 5325 const llvm::Type * SrcTy = src->getType(); 5326 if (!isa<llvm::PointerType>(SrcTy)) { 5327 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5328 assert(Size <= 8 && "does not support size > 8"); 5329 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5330 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5331 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5332 } 5333 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5334 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5335 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 5336 src, dst, "weakassign"); 5337 return; 5338 } 5339 5340 /// EmitObjCWeakRead - Code gen for loading value of a __weak 5341 /// object: objc_read_weak (id *src) 5342 /// 5343 llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( 5344 CodeGen::CodeGenFunction &CGF, 5345 llvm::Value *AddrWeakObj) 5346 { 5347 const llvm::Type* DestTy = 5348 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 5349 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 5350 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 5351 AddrWeakObj, "weakread"); 5352 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 5353 return read_weak; 5354 } 5355 5356 /// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 5357 /// objc_assign_weak (id src, id *dst) 5358 /// 5359 void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 5360 llvm::Value *src, llvm::Value *dst) 5361 { 5362 const llvm::Type * SrcTy = src->getType(); 5363 if (!isa<llvm::PointerType>(SrcTy)) { 5364 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5365 assert(Size <= 8 && "does not support size > 8"); 5366 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5367 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5368 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5369 } 5370 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5371 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5372 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 5373 src, dst, "weakassign"); 5374 return; 5375 } 5376 5377 /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 5378 /// objc_assign_global (id src, id *dst) 5379 /// 5380 void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 5381 llvm::Value *src, llvm::Value *dst) 5382 { 5383 const llvm::Type * SrcTy = src->getType(); 5384 if (!isa<llvm::PointerType>(SrcTy)) { 5385 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 5386 assert(Size <= 8 && "does not support size > 8"); 5387 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 5388 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 5389 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 5390 } 5391 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 5392 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 5393 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 5394 src, dst, "globalassign"); 5395 return; 5396 } 5397 5398 void 5399 CGObjCNonFragileABIMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 5400 const Stmt &S) { 5401 bool isTry = isa<ObjCAtTryStmt>(S); 5402 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 5403 llvm::BasicBlock *PrevLandingPad = CGF.getInvokeDest(); 5404 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 5405 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 5406 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 5407 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 5408 5409 // For @synchronized, call objc_sync_enter(sync.expr). The 5410 // evaluation of the expression must occur before we enter the 5411 // @synchronized. We can safely avoid a temp here because jumps into 5412 // @synchronized are illegal & this will dominate uses. 5413 llvm::Value *SyncArg = 0; 5414 if (!isTry) { 5415 SyncArg = 5416 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 5417 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 5418 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg); 5419 } 5420 5421 // Push an EH context entry, used for handling rethrows and jumps 5422 // through finally. 5423 CGF.PushCleanupBlock(FinallyBlock); 5424 5425 CGF.setInvokeDest(TryHandler); 5426 5427 CGF.EmitBlock(TryBlock); 5428 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 5429 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 5430 CGF.EmitBranchThroughCleanup(FinallyEnd); 5431 5432 // Emit the exception handler. 5433 5434 CGF.EmitBlock(TryHandler); 5435 5436 llvm::Value *llvm_eh_exception = 5437 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception); 5438 llvm::Value *llvm_eh_selector_i64 = 5439 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i64); 5440 llvm::Value *llvm_eh_typeid_for_i64 = 5441 CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i64); 5442 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 5443 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(Exc->getType(), "_rethrow"); 5444 5445 llvm::SmallVector<llvm::Value*, 8> SelectorArgs; 5446 SelectorArgs.push_back(Exc); 5447 SelectorArgs.push_back(ObjCTypes.getEHPersonalityPtr()); 5448 5449 // Construct the lists of (type, catch body) to handle. 5450 llvm::SmallVector<std::pair<const ParmVarDecl*, const Stmt*>, 8> Handlers; 5451 bool HasCatchAll = false; 5452 if (isTry) { 5453 if (const ObjCAtCatchStmt* CatchStmt = 5454 cast<ObjCAtTryStmt>(S).getCatchStmts()) { 5455 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 5456 const ParmVarDecl *CatchDecl = CatchStmt->getCatchParamDecl(); 5457 Handlers.push_back(std::make_pair(CatchDecl, CatchStmt->getCatchBody())); 5458 5459 // catch(...) always matches. 5460 if (!CatchDecl) { 5461 // Use i8* null here to signal this is a catch all, not a cleanup. 5462 llvm::Value *Null = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 5463 SelectorArgs.push_back(Null); 5464 HasCatchAll = true; 5465 break; 5466 } 5467 5468 if (CGF.getContext().isObjCIdType(CatchDecl->getType()) || 5469 CatchDecl->getType()->isObjCQualifiedIdType()) { 5470 llvm::Value *IDEHType = 5471 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); 5472 if (!IDEHType) 5473 IDEHType = 5474 new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false, 5475 llvm::GlobalValue::ExternalLinkage, 5476 0, "OBJC_EHTYPE_id", &CGM.getModule()); 5477 SelectorArgs.push_back(IDEHType); 5478 HasCatchAll = true; 5479 break; 5480 } 5481 5482 // All other types should be Objective-C interface pointer types. 5483 const PointerType *PT = CatchDecl->getType()->getAsPointerType(); 5484 assert(PT && "Invalid @catch type."); 5485 const ObjCInterfaceType *IT = 5486 PT->getPointeeType()->getAsObjCInterfaceType(); 5487 assert(IT && "Invalid @catch type."); 5488 llvm::Value *EHType = GetInterfaceEHType(IT->getDecl(), false); 5489 SelectorArgs.push_back(EHType); 5490 } 5491 } 5492 } 5493 5494 // We use a cleanup unless there was already a catch all. 5495 if (!HasCatchAll) { 5496 SelectorArgs.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 0)); 5497 Handlers.push_back(std::make_pair((const ParmVarDecl*) 0, (const Stmt*) 0)); 5498 } 5499 5500 llvm::Value *Selector = 5501 CGF.Builder.CreateCall(llvm_eh_selector_i64, 5502 SelectorArgs.begin(), SelectorArgs.end(), 5503 "selector"); 5504 for (unsigned i = 0, e = Handlers.size(); i != e; ++i) { 5505 const ParmVarDecl *CatchParam = Handlers[i].first; 5506 const Stmt *CatchBody = Handlers[i].second; 5507 5508 llvm::BasicBlock *Next = 0; 5509 5510 // The last handler always matches. 5511 if (i + 1 != e) { 5512 assert(CatchParam && "Only last handler can be a catch all."); 5513 5514 llvm::BasicBlock *Match = CGF.createBasicBlock("match"); 5515 Next = CGF.createBasicBlock("catch.next"); 5516 llvm::Value *Id = 5517 CGF.Builder.CreateCall(llvm_eh_typeid_for_i64, 5518 CGF.Builder.CreateBitCast(SelectorArgs[i+2], 5519 ObjCTypes.Int8PtrTy)); 5520 CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(Selector, Id), 5521 Match, Next); 5522 5523 CGF.EmitBlock(Match); 5524 } 5525 5526 if (CatchBody) { 5527 llvm::BasicBlock *MatchEnd = CGF.createBasicBlock("match.end"); 5528 llvm::BasicBlock *MatchHandler = CGF.createBasicBlock("match.handler"); 5529 5530 // Cleanups must call objc_end_catch. 5531 // 5532 // FIXME: It seems incorrect for objc_begin_catch to be inside this 5533 // context, but this matches gcc. 5534 CGF.PushCleanupBlock(MatchEnd); 5535 CGF.setInvokeDest(MatchHandler); 5536 5537 llvm::Value *ExcObject = 5538 CGF.Builder.CreateCall(ObjCTypes.getObjCBeginCatchFn(), Exc); 5539 5540 // Bind the catch parameter if it exists. 5541 if (CatchParam) { 5542 ExcObject = 5543 CGF.Builder.CreateBitCast(ExcObject, 5544 CGF.ConvertType(CatchParam->getType())); 5545 // CatchParam is a ParmVarDecl because of the grammar 5546 // construction used to handle this, but for codegen purposes 5547 // we treat this as a local decl. 5548 CGF.EmitLocalBlockVarDecl(*CatchParam); 5549 CGF.Builder.CreateStore(ExcObject, CGF.GetAddrOfLocalVar(CatchParam)); 5550 } 5551 5552 CGF.ObjCEHValueStack.push_back(ExcObject); 5553 CGF.EmitStmt(CatchBody); 5554 CGF.ObjCEHValueStack.pop_back(); 5555 5556 CGF.EmitBranchThroughCleanup(FinallyEnd); 5557 5558 CGF.EmitBlock(MatchHandler); 5559 5560 llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 5561 // We are required to emit this call to satisfy LLVM, even 5562 // though we don't use the result. 5563 llvm::SmallVector<llvm::Value*, 8> Args; 5564 Args.push_back(Exc); 5565 Args.push_back(ObjCTypes.getEHPersonalityPtr()); 5566 Args.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 5567 0)); 5568 CGF.Builder.CreateCall(llvm_eh_selector_i64, Args.begin(), Args.end()); 5569 CGF.Builder.CreateStore(Exc, RethrowPtr); 5570 CGF.EmitBranchThroughCleanup(FinallyRethrow); 5571 5572 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 5573 5574 CGF.EmitBlock(MatchEnd); 5575 5576 // Unfortunately, we also have to generate another EH frame here 5577 // in case this throws. 5578 llvm::BasicBlock *MatchEndHandler = 5579 CGF.createBasicBlock("match.end.handler"); 5580 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont"); 5581 CGF.Builder.CreateInvoke(ObjCTypes.getObjCEndCatchFn(), 5582 Cont, MatchEndHandler, 5583 Args.begin(), Args.begin()); 5584 5585 CGF.EmitBlock(Cont); 5586 if (Info.SwitchBlock) 5587 CGF.EmitBlock(Info.SwitchBlock); 5588 if (Info.EndBlock) 5589 CGF.EmitBlock(Info.EndBlock); 5590 5591 CGF.EmitBlock(MatchEndHandler); 5592 Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc"); 5593 // We are required to emit this call to satisfy LLVM, even 5594 // though we don't use the result. 5595 Args.clear(); 5596 Args.push_back(Exc); 5597 Args.push_back(ObjCTypes.getEHPersonalityPtr()); 5598 Args.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty, 5599 0)); 5600 CGF.Builder.CreateCall(llvm_eh_selector_i64, Args.begin(), Args.end()); 5601 CGF.Builder.CreateStore(Exc, RethrowPtr); 5602 CGF.EmitBranchThroughCleanup(FinallyRethrow); 5603 5604 if (Next) 5605 CGF.EmitBlock(Next); 5606 } else { 5607 assert(!Next && "catchup should be last handler."); 5608 5609 CGF.Builder.CreateStore(Exc, RethrowPtr); 5610 CGF.EmitBranchThroughCleanup(FinallyRethrow); 5611 } 5612 } 5613 5614 // Pop the cleanup entry, the @finally is outside this cleanup 5615 // scope. 5616 CodeGenFunction::CleanupBlockInfo Info = CGF.PopCleanupBlock(); 5617 CGF.setInvokeDest(PrevLandingPad); 5618 5619 CGF.EmitBlock(FinallyBlock); 5620 5621 if (isTry) { 5622 if (const ObjCAtFinallyStmt* FinallyStmt = 5623 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 5624 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 5625 } else { 5626 // Emit 'objc_sync_exit(expr)' as finally's sole statement for 5627 // @synchronized. 5628 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg); 5629 } 5630 5631 if (Info.SwitchBlock) 5632 CGF.EmitBlock(Info.SwitchBlock); 5633 if (Info.EndBlock) 5634 CGF.EmitBlock(Info.EndBlock); 5635 5636 // Branch around the rethrow code. 5637 CGF.EmitBranch(FinallyEnd); 5638 5639 CGF.EmitBlock(FinallyRethrow); 5640 CGF.Builder.CreateCall(ObjCTypes.getUnwindResumeOrRethrowFn(), 5641 CGF.Builder.CreateLoad(RethrowPtr)); 5642 CGF.Builder.CreateUnreachable(); 5643 5644 CGF.EmitBlock(FinallyEnd); 5645 } 5646 5647 /// EmitThrowStmt - Generate code for a throw statement. 5648 void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 5649 const ObjCAtThrowStmt &S) { 5650 llvm::Value *Exception; 5651 if (const Expr *ThrowExpr = S.getThrowExpr()) { 5652 Exception = CGF.EmitScalarExpr(ThrowExpr); 5653 } else { 5654 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 5655 "Unexpected rethrow outside @catch block."); 5656 Exception = CGF.ObjCEHValueStack.back(); 5657 } 5658 5659 llvm::Value *ExceptionAsObject = 5660 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp"); 5661 llvm::BasicBlock *InvokeDest = CGF.getInvokeDest(); 5662 if (InvokeDest) { 5663 llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont"); 5664 CGF.Builder.CreateInvoke(ObjCTypes.getExceptionThrowFn(), 5665 Cont, InvokeDest, 5666 &ExceptionAsObject, &ExceptionAsObject + 1); 5667 CGF.EmitBlock(Cont); 5668 } else 5669 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject); 5670 CGF.Builder.CreateUnreachable(); 5671 5672 // Clear the insertion point to indicate we are in unreachable code. 5673 CGF.Builder.ClearInsertionPoint(); 5674 } 5675 5676 llvm::Value * 5677 CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, 5678 bool ForDefinition) { 5679 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()]; 5680 5681 // If we don't need a definition, return the entry if found or check 5682 // if we use an external reference. 5683 if (!ForDefinition) { 5684 if (Entry) 5685 return Entry; 5686 5687 // If this type (or a super class) has the __objc_exception__ 5688 // attribute, emit an external reference. 5689 if (hasObjCExceptionAttribute(ID)) 5690 return Entry = 5691 new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false, 5692 llvm::GlobalValue::ExternalLinkage, 5693 0, 5694 (std::string("OBJC_EHTYPE_$_") + 5695 ID->getIdentifier()->getName()), 5696 &CGM.getModule()); 5697 } 5698 5699 // Otherwise we need to either make a new entry or fill in the 5700 // initializer. 5701 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition"); 5702 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5703 std::string VTableName = "objc_ehtype_vtable"; 5704 llvm::GlobalVariable *VTableGV = 5705 CGM.getModule().getGlobalVariable(VTableName); 5706 if (!VTableGV) 5707 VTableGV = new llvm::GlobalVariable(ObjCTypes.Int8PtrTy, false, 5708 llvm::GlobalValue::ExternalLinkage, 5709 0, VTableName, &CGM.getModule()); 5710 5711 llvm::Value *VTableIdx = llvm::ConstantInt::get(llvm::Type::Int32Ty, 2); 5712 5713 std::vector<llvm::Constant*> Values(3); 5714 Values[0] = llvm::ConstantExpr::getGetElementPtr(VTableGV, &VTableIdx, 1); 5715 Values[1] = GetClassName(ID->getIdentifier()); 5716 Values[2] = GetClassGlobal(ClassName); 5717 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); 5718 5719 if (Entry) { 5720 Entry->setInitializer(Init); 5721 } else { 5722 Entry = new llvm::GlobalVariable(ObjCTypes.EHTypeTy, false, 5723 llvm::GlobalValue::WeakAnyLinkage, 5724 Init, 5725 (std::string("OBJC_EHTYPE_$_") + 5726 ID->getIdentifier()->getName()), 5727 &CGM.getModule()); 5728 } 5729 5730 if (CGM.getLangOptions().getVisibilityMode() == LangOptions::Hidden) 5731 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 5732 Entry->setAlignment(8); 5733 5734 if (ForDefinition) { 5735 Entry->setSection("__DATA,__objc_const"); 5736 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage); 5737 } else { 5738 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 5739 } 5740 5741 return Entry; 5742 } 5743 5744 /* *** */ 5745 5746 CodeGen::CGObjCRuntime * 5747 CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 5748 return new CGObjCMac(CGM); 5749 } 5750 5751 CodeGen::CGObjCRuntime * 5752 CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) { 5753 return new CGObjCNonFragileABIMac(CGM); 5754 } 5755