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