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