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