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