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