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