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