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