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