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