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