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