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