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