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