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