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