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