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