CGObjCMac.cpp revision 9b7d6701dabc24387cc152e4d13bf9aec6aa461a
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 Qualifiers Quals = CGF.MakeQualifiers(IvarTy); 111 Quals.addCVRQualifiers(CVRQualifiers); 112 113 if (!Ivar->isBitField()) 114 return LValue::MakeAddr(V, Quals); 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 return LValue::MakeBitfield(V, *Info, Quals.getCVRQualifiers()); 148} 149 150/// 151 152namespace { 153 154typedef std::vector<llvm::Constant*> ConstantVector; 155 156// FIXME: We should find a nicer way to make the labels for metadata, string 157// concatenation is lame. 158 159class ObjCCommonTypesHelper { 160protected: 161 llvm::LLVMContext &VMContext; 162 163private: 164 llvm::Constant *getMessageSendFn() const { 165 // id objc_msgSend (id, SEL, ...) 166 std::vector<const llvm::Type*> Params; 167 Params.push_back(ObjectPtrTy); 168 Params.push_back(SelectorPtrTy); 169 return 170 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 171 Params, true), 172 "objc_msgSend"); 173 } 174 175 llvm::Constant *getMessageSendStretFn() const { 176 // id objc_msgSend_stret (id, SEL, ...) 177 std::vector<const llvm::Type*> Params; 178 Params.push_back(ObjectPtrTy); 179 Params.push_back(SelectorPtrTy); 180 return 181 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 182 Params, true), 183 "objc_msgSend_stret"); 184 185 } 186 187 llvm::Constant *getMessageSendFpretFn() const { 188 // FIXME: This should be long double on x86_64? 189 // [double | long double] objc_msgSend_fpret(id self, SEL op, ...) 190 std::vector<const llvm::Type*> Params; 191 Params.push_back(ObjectPtrTy); 192 Params.push_back(SelectorPtrTy); 193 return 194 CGM.CreateRuntimeFunction(llvm::FunctionType::get( 195 llvm::Type::getDoubleTy(VMContext), 196 Params, 197 true), 198 "objc_msgSend_fpret"); 199 200 } 201 202 llvm::Constant *getMessageSendSuperFn() const { 203 // id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 204 const char *SuperName = "objc_msgSendSuper"; 205 std::vector<const llvm::Type*> Params; 206 Params.push_back(SuperPtrTy); 207 Params.push_back(SelectorPtrTy); 208 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 209 Params, true), 210 SuperName); 211 } 212 213 llvm::Constant *getMessageSendSuperFn2() const { 214 // id objc_msgSendSuper2(struct objc_super *super, SEL op, ...) 215 const char *SuperName = "objc_msgSendSuper2"; 216 std::vector<const llvm::Type*> Params; 217 Params.push_back(SuperPtrTy); 218 Params.push_back(SelectorPtrTy); 219 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 220 Params, true), 221 SuperName); 222 } 223 224 llvm::Constant *getMessageSendSuperStretFn() const { 225 // void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super, 226 // SEL op, ...) 227 std::vector<const llvm::Type*> Params; 228 Params.push_back(Int8PtrTy); 229 Params.push_back(SuperPtrTy); 230 Params.push_back(SelectorPtrTy); 231 return CGM.CreateRuntimeFunction( 232 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 233 Params, true), 234 "objc_msgSendSuper_stret"); 235 } 236 237 llvm::Constant *getMessageSendSuperStretFn2() const { 238 // void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super, 239 // SEL op, ...) 240 std::vector<const llvm::Type*> Params; 241 Params.push_back(Int8PtrTy); 242 Params.push_back(SuperPtrTy); 243 Params.push_back(SelectorPtrTy); 244 return CGM.CreateRuntimeFunction( 245 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 246 Params, true), 247 "objc_msgSendSuper2_stret"); 248 } 249 250 llvm::Constant *getMessageSendSuperFpretFn() const { 251 // There is no objc_msgSendSuper_fpret? How can that work? 252 return getMessageSendSuperFn(); 253 } 254 255 llvm::Constant *getMessageSendSuperFpretFn2() const { 256 // There is no objc_msgSendSuper_fpret? How can that work? 257 return getMessageSendSuperFn2(); 258 } 259 260protected: 261 CodeGen::CodeGenModule &CGM; 262 263public: 264 const llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy; 265 const llvm::Type *Int8PtrTy; 266 267 /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 268 const llvm::Type *ObjectPtrTy; 269 270 /// PtrObjectPtrTy - LLVM type for id * 271 const llvm::Type *PtrObjectPtrTy; 272 273 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 274 const llvm::Type *SelectorPtrTy; 275 /// ProtocolPtrTy - LLVM type for external protocol handles 276 /// (typeof(Protocol)) 277 const llvm::Type *ExternalProtocolPtrTy; 278 279 // SuperCTy - clang type for struct objc_super. 280 QualType SuperCTy; 281 // SuperPtrCTy - clang type for struct objc_super *. 282 QualType SuperPtrCTy; 283 284 /// SuperTy - LLVM type for struct objc_super. 285 const llvm::StructType *SuperTy; 286 /// SuperPtrTy - LLVM type for struct objc_super *. 287 const llvm::Type *SuperPtrTy; 288 289 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t 290 /// in GCC parlance). 291 const llvm::StructType *PropertyTy; 292 293 /// PropertyListTy - LLVM type for struct objc_property_list 294 /// (_prop_list_t in GCC parlance). 295 const llvm::StructType *PropertyListTy; 296 /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 297 const llvm::Type *PropertyListPtrTy; 298 299 // MethodTy - LLVM type for struct objc_method. 300 const llvm::StructType *MethodTy; 301 302 /// CacheTy - LLVM type for struct objc_cache. 303 const llvm::Type *CacheTy; 304 /// CachePtrTy - LLVM type for struct objc_cache *. 305 const llvm::Type *CachePtrTy; 306 307 llvm::Constant *getGetPropertyFn() { 308 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 309 ASTContext &Ctx = CGM.getContext(); 310 // id objc_getProperty (id, SEL, ptrdiff_t, bool) 311 llvm::SmallVector<CanQualType,4> Params; 312 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 313 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 314 Params.push_back(IdType); 315 Params.push_back(SelType); 316 Params.push_back(Ctx.LongTy); 317 Params.push_back(Ctx.BoolTy); 318 const llvm::FunctionType *FTy = 319 Types.GetFunctionType(Types.getFunctionInfo(IdType, Params, 320 FunctionType::ExtInfo()), 321 false); 322 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); 323 } 324 325 llvm::Constant *getSetPropertyFn() { 326 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 327 ASTContext &Ctx = CGM.getContext(); 328 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 329 llvm::SmallVector<CanQualType,6> Params; 330 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); 331 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); 332 Params.push_back(IdType); 333 Params.push_back(SelType); 334 Params.push_back(Ctx.LongTy); 335 Params.push_back(IdType); 336 Params.push_back(Ctx.BoolTy); 337 Params.push_back(Ctx.BoolTy); 338 const llvm::FunctionType *FTy = 339 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, 340 FunctionType::ExtInfo()), 341 false); 342 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); 343 } 344 345 346 llvm::Constant *getCopyStructFn() { 347 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 348 ASTContext &Ctx = CGM.getContext(); 349 // void objc_copyStruct (void *, const void *, size_t, bool, bool) 350 llvm::SmallVector<CanQualType,5> Params; 351 Params.push_back(Ctx.VoidPtrTy); 352 Params.push_back(Ctx.VoidPtrTy); 353 Params.push_back(Ctx.LongTy); 354 Params.push_back(Ctx.BoolTy); 355 Params.push_back(Ctx.BoolTy); 356 const llvm::FunctionType *FTy = 357 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, 358 FunctionType::ExtInfo()), 359 false); 360 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct"); 361 } 362 363 llvm::Constant *getEnumerationMutationFn() { 364 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 365 ASTContext &Ctx = CGM.getContext(); 366 // void objc_enumerationMutation (id) 367 llvm::SmallVector<CanQualType,1> Params; 368 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType())); 369 const llvm::FunctionType *FTy = 370 Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, 371 FunctionType::ExtInfo()), 372 false); 373 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); 374 } 375 376 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function. 377 llvm::Constant *getGcReadWeakFn() { 378 // id objc_read_weak (id *) 379 std::vector<const llvm::Type*> Args; 380 Args.push_back(ObjectPtrTy->getPointerTo()); 381 llvm::FunctionType *FTy = 382 llvm::FunctionType::get(ObjectPtrTy, Args, false); 383 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak"); 384 } 385 386 /// GcAssignWeakFn -- LLVM objc_assign_weak function. 387 llvm::Constant *getGcAssignWeakFn() { 388 // id objc_assign_weak (id, id *) 389 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 390 Args.push_back(ObjectPtrTy->getPointerTo()); 391 llvm::FunctionType *FTy = 392 llvm::FunctionType::get(ObjectPtrTy, Args, false); 393 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak"); 394 } 395 396 /// GcAssignGlobalFn -- LLVM objc_assign_global function. 397 llvm::Constant *getGcAssignGlobalFn() { 398 // id objc_assign_global(id, id *) 399 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 400 Args.push_back(ObjectPtrTy->getPointerTo()); 401 llvm::FunctionType *FTy = 402 llvm::FunctionType::get(ObjectPtrTy, Args, false); 403 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global"); 404 } 405 406 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function. 407 llvm::Constant *getGcAssignThreadLocalFn() { 408 // id objc_assign_threadlocal(id src, id * dest) 409 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 410 Args.push_back(ObjectPtrTy->getPointerTo()); 411 llvm::FunctionType *FTy = 412 llvm::FunctionType::get(ObjectPtrTy, Args, false); 413 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal"); 414 } 415 416 /// GcAssignIvarFn -- LLVM objc_assign_ivar function. 417 llvm::Constant *getGcAssignIvarFn() { 418 // id objc_assign_ivar(id, id *, ptrdiff_t) 419 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 420 Args.push_back(ObjectPtrTy->getPointerTo()); 421 Args.push_back(LongTy); 422 llvm::FunctionType *FTy = 423 llvm::FunctionType::get(ObjectPtrTy, Args, false); 424 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar"); 425 } 426 427 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function. 428 llvm::Constant *GcMemmoveCollectableFn() { 429 // void *objc_memmove_collectable(void *dst, const void *src, size_t size) 430 std::vector<const llvm::Type*> Args(1, Int8PtrTy); 431 Args.push_back(Int8PtrTy); 432 Args.push_back(LongTy); 433 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false); 434 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable"); 435 } 436 437 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function. 438 llvm::Constant *getGcAssignStrongCastFn() { 439 // id objc_assign_strongCast(id, id *) 440 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 441 Args.push_back(ObjectPtrTy->getPointerTo()); 442 llvm::FunctionType *FTy = 443 llvm::FunctionType::get(ObjectPtrTy, Args, false); 444 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast"); 445 } 446 447 /// ExceptionThrowFn - LLVM objc_exception_throw function. 448 llvm::Constant *getExceptionThrowFn() { 449 // void objc_exception_throw(id) 450 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 451 llvm::FunctionType *FTy = 452 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 453 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw"); 454 } 455 456 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function. 457 llvm::Constant *getExceptionRethrowFn() { 458 // void objc_exception_rethrow(void) 459 std::vector<const llvm::Type*> Args; 460 llvm::FunctionType *FTy = 461 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, true); 462 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow"); 463 } 464 465 /// SyncEnterFn - LLVM object_sync_enter function. 466 llvm::Constant *getSyncEnterFn() { 467 // void objc_sync_enter (id) 468 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 469 llvm::FunctionType *FTy = 470 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 471 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter"); 472 } 473 474 /// SyncExitFn - LLVM object_sync_exit function. 475 llvm::Constant *getSyncExitFn() { 476 // void objc_sync_exit (id) 477 std::vector<const llvm::Type*> Args(1, ObjectPtrTy); 478 llvm::FunctionType *FTy = 479 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), Args, false); 480 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit"); 481 } 482 483 llvm::Constant *getSendFn(bool IsSuper) const { 484 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn(); 485 } 486 487 llvm::Constant *getSendFn2(bool IsSuper) const { 488 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn(); 489 } 490 491 llvm::Constant *getSendStretFn(bool IsSuper) const { 492 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn(); 493 } 494 495 llvm::Constant *getSendStretFn2(bool IsSuper) const { 496 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn(); 497 } 498 499 llvm::Constant *getSendFpretFn(bool IsSuper) const { 500 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn(); 501 } 502 503 llvm::Constant *getSendFpretFn2(bool IsSuper) const { 504 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn(); 505 } 506 507 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm); 508 ~ObjCCommonTypesHelper(){} 509}; 510 511/// ObjCTypesHelper - Helper class that encapsulates lazy 512/// construction of varies types used during ObjC generation. 513class ObjCTypesHelper : public ObjCCommonTypesHelper { 514public: 515 /// SymtabTy - LLVM type for struct objc_symtab. 516 const llvm::StructType *SymtabTy; 517 /// SymtabPtrTy - LLVM type for struct objc_symtab *. 518 const llvm::Type *SymtabPtrTy; 519 /// ModuleTy - LLVM type for struct objc_module. 520 const llvm::StructType *ModuleTy; 521 522 /// ProtocolTy - LLVM type for struct objc_protocol. 523 const llvm::StructType *ProtocolTy; 524 /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 525 const llvm::Type *ProtocolPtrTy; 526 /// ProtocolExtensionTy - LLVM type for struct 527 /// objc_protocol_extension. 528 const llvm::StructType *ProtocolExtensionTy; 529 /// ProtocolExtensionTy - LLVM type for struct 530 /// objc_protocol_extension *. 531 const llvm::Type *ProtocolExtensionPtrTy; 532 /// MethodDescriptionTy - LLVM type for struct 533 /// objc_method_description. 534 const llvm::StructType *MethodDescriptionTy; 535 /// MethodDescriptionListTy - LLVM type for struct 536 /// objc_method_description_list. 537 const llvm::StructType *MethodDescriptionListTy; 538 /// MethodDescriptionListPtrTy - LLVM type for struct 539 /// objc_method_description_list *. 540 const llvm::Type *MethodDescriptionListPtrTy; 541 /// ProtocolListTy - LLVM type for struct objc_property_list. 542 const llvm::Type *ProtocolListTy; 543 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 544 const llvm::Type *ProtocolListPtrTy; 545 /// CategoryTy - LLVM type for struct objc_category. 546 const llvm::StructType *CategoryTy; 547 /// ClassTy - LLVM type for struct objc_class. 548 const llvm::StructType *ClassTy; 549 /// ClassPtrTy - LLVM type for struct objc_class *. 550 const llvm::Type *ClassPtrTy; 551 /// ClassExtensionTy - LLVM type for struct objc_class_ext. 552 const llvm::StructType *ClassExtensionTy; 553 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. 554 const llvm::Type *ClassExtensionPtrTy; 555 // IvarTy - LLVM type for struct objc_ivar. 556 const llvm::StructType *IvarTy; 557 /// IvarListTy - LLVM type for struct objc_ivar_list. 558 const llvm::Type *IvarListTy; 559 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. 560 const llvm::Type *IvarListPtrTy; 561 /// MethodListTy - LLVM type for struct objc_method_list. 562 const llvm::Type *MethodListTy; 563 /// MethodListPtrTy - LLVM type for struct objc_method_list *. 564 const llvm::Type *MethodListPtrTy; 565 566 /// ExceptionDataTy - LLVM type for struct _objc_exception_data. 567 const llvm::Type *ExceptionDataTy; 568 569 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. 570 llvm::Constant *getExceptionTryEnterFn() { 571 std::vector<const llvm::Type*> Params; 572 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 573 return CGM.CreateRuntimeFunction( 574 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 575 Params, false), 576 "objc_exception_try_enter"); 577 } 578 579 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. 580 llvm::Constant *getExceptionTryExitFn() { 581 std::vector<const llvm::Type*> Params; 582 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 583 return CGM.CreateRuntimeFunction( 584 llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 585 Params, false), 586 "objc_exception_try_exit"); 587 } 588 589 /// ExceptionExtractFn - LLVM objc_exception_extract function. 590 llvm::Constant *getExceptionExtractFn() { 591 std::vector<const llvm::Type*> Params; 592 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 593 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 594 Params, false), 595 "objc_exception_extract"); 596 597 } 598 599 /// ExceptionMatchFn - LLVM objc_exception_match function. 600 llvm::Constant *getExceptionMatchFn() { 601 std::vector<const llvm::Type*> Params; 602 Params.push_back(ClassPtrTy); 603 Params.push_back(ObjectPtrTy); 604 return CGM.CreateRuntimeFunction( 605 llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext), 606 Params, false), 607 "objc_exception_match"); 608 609 } 610 611 /// SetJmpFn - LLVM _setjmp function. 612 llvm::Constant *getSetJmpFn() { 613 std::vector<const llvm::Type*> Params; 614 Params.push_back(llvm::Type::getInt32PtrTy(VMContext)); 615 return 616 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getInt32Ty(VMContext), 617 Params, false), 618 "_setjmp"); 619 620 } 621 622public: 623 ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 624 ~ObjCTypesHelper() {} 625}; 626 627/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's 628/// modern abi 629class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { 630public: 631 632 // MethodListnfABITy - LLVM for struct _method_list_t 633 const llvm::StructType *MethodListnfABITy; 634 635 // MethodListnfABIPtrTy - LLVM for struct _method_list_t* 636 const llvm::Type *MethodListnfABIPtrTy; 637 638 // ProtocolnfABITy = LLVM for struct _protocol_t 639 const llvm::StructType *ProtocolnfABITy; 640 641 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t* 642 const llvm::Type *ProtocolnfABIPtrTy; 643 644 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list 645 const llvm::StructType *ProtocolListnfABITy; 646 647 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* 648 const llvm::Type *ProtocolListnfABIPtrTy; 649 650 // ClassnfABITy - LLVM for struct _class_t 651 const llvm::StructType *ClassnfABITy; 652 653 // ClassnfABIPtrTy - LLVM for struct _class_t* 654 const llvm::Type *ClassnfABIPtrTy; 655 656 // IvarnfABITy - LLVM for struct _ivar_t 657 const llvm::StructType *IvarnfABITy; 658 659 // IvarListnfABITy - LLVM for struct _ivar_list_t 660 const llvm::StructType *IvarListnfABITy; 661 662 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* 663 const llvm::Type *IvarListnfABIPtrTy; 664 665 // ClassRonfABITy - LLVM for struct _class_ro_t 666 const llvm::StructType *ClassRonfABITy; 667 668 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 669 const llvm::Type *ImpnfABITy; 670 671 // CategorynfABITy - LLVM for struct _category_t 672 const llvm::StructType *CategorynfABITy; 673 674 // New types for nonfragile abi messaging. 675 676 // MessageRefTy - LLVM for: 677 // struct _message_ref_t { 678 // IMP messenger; 679 // SEL name; 680 // }; 681 const llvm::StructType *MessageRefTy; 682 // MessageRefCTy - clang type for struct _message_ref_t 683 QualType MessageRefCTy; 684 685 // MessageRefPtrTy - LLVM for struct _message_ref_t* 686 const llvm::Type *MessageRefPtrTy; 687 // MessageRefCPtrTy - clang type for struct _message_ref_t* 688 QualType MessageRefCPtrTy; 689 690 // MessengerTy - Type of the messenger (shown as IMP above) 691 const llvm::FunctionType *MessengerTy; 692 693 // SuperMessageRefTy - LLVM for: 694 // struct _super_message_ref_t { 695 // SUPER_IMP messenger; 696 // SEL name; 697 // }; 698 const llvm::StructType *SuperMessageRefTy; 699 700 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 701 const llvm::Type *SuperMessageRefPtrTy; 702 703 llvm::Constant *getMessageSendFixupFn() { 704 // id objc_msgSend_fixup(id, struct message_ref_t*, ...) 705 std::vector<const llvm::Type*> Params; 706 Params.push_back(ObjectPtrTy); 707 Params.push_back(MessageRefPtrTy); 708 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 709 Params, true), 710 "objc_msgSend_fixup"); 711 } 712 713 llvm::Constant *getMessageSendFpretFixupFn() { 714 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...) 715 std::vector<const llvm::Type*> Params; 716 Params.push_back(ObjectPtrTy); 717 Params.push_back(MessageRefPtrTy); 718 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 719 Params, true), 720 "objc_msgSend_fpret_fixup"); 721 } 722 723 llvm::Constant *getMessageSendStretFixupFn() { 724 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...) 725 std::vector<const llvm::Type*> Params; 726 Params.push_back(ObjectPtrTy); 727 Params.push_back(MessageRefPtrTy); 728 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 729 Params, true), 730 "objc_msgSend_stret_fixup"); 731 } 732 733 llvm::Constant *getMessageSendSuper2FixupFn() { 734 // id objc_msgSendSuper2_fixup (struct objc_super *, 735 // struct _super_message_ref_t*, ...) 736 std::vector<const llvm::Type*> Params; 737 Params.push_back(SuperPtrTy); 738 Params.push_back(SuperMessageRefPtrTy); 739 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 740 Params, true), 741 "objc_msgSendSuper2_fixup"); 742 } 743 744 llvm::Constant *getMessageSendSuper2StretFixupFn() { 745 // id objc_msgSendSuper2_stret_fixup(struct objc_super *, 746 // struct _super_message_ref_t*, ...) 747 std::vector<const llvm::Type*> Params; 748 Params.push_back(SuperPtrTy); 749 Params.push_back(SuperMessageRefPtrTy); 750 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 751 Params, true), 752 "objc_msgSendSuper2_stret_fixup"); 753 } 754 755 llvm::Constant *getObjCEndCatchFn() { 756 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext), 757 false), 758 "objc_end_catch"); 759 760 } 761 762 llvm::Constant *getObjCBeginCatchFn() { 763 std::vector<const llvm::Type*> Params; 764 Params.push_back(Int8PtrTy); 765 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy, 766 Params, false), 767 "objc_begin_catch"); 768 } 769 770 const llvm::StructType *EHTypeTy; 771 const llvm::Type *EHTypePtrTy; 772 773 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); 774 ~ObjCNonFragileABITypesHelper(){} 775}; 776 777class CGObjCCommonMac : public CodeGen::CGObjCRuntime { 778public: 779 // FIXME - accessibility 780 class GC_IVAR { 781 public: 782 unsigned ivar_bytepos; 783 unsigned ivar_size; 784 GC_IVAR(unsigned bytepos = 0, unsigned size = 0) 785 : ivar_bytepos(bytepos), ivar_size(size) {} 786 787 // Allow sorting based on byte pos. 788 bool operator<(const GC_IVAR &b) const { 789 return ivar_bytepos < b.ivar_bytepos; 790 } 791 }; 792 793 class SKIP_SCAN { 794 public: 795 unsigned skip; 796 unsigned scan; 797 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0) 798 : skip(_skip), scan(_scan) {} 799 }; 800 801protected: 802 CodeGen::CodeGenModule &CGM; 803 llvm::LLVMContext &VMContext; 804 // FIXME! May not be needing this after all. 805 unsigned ObjCABI; 806 807 // gc ivar layout bitmap calculation helper caches. 808 llvm::SmallVector<GC_IVAR, 16> SkipIvars; 809 llvm::SmallVector<GC_IVAR, 16> IvarsInfo; 810 811 /// LazySymbols - Symbols to generate a lazy reference for. See 812 /// DefinedSymbols and FinishModule(). 813 llvm::SetVector<IdentifierInfo*> LazySymbols; 814 815 /// DefinedSymbols - External symbols which are defined by this 816 /// module. The symbols in this list and LazySymbols are used to add 817 /// special linker symbols which ensure that Objective-C modules are 818 /// linked properly. 819 llvm::SetVector<IdentifierInfo*> DefinedSymbols; 820 821 /// ClassNames - uniqued class names. 822 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 823 824 /// MethodVarNames - uniqued method variable names. 825 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 826 827 /// DefinedCategoryNames - list of category names in form Class_Category. 828 llvm::SetVector<std::string> DefinedCategoryNames; 829 830 /// MethodVarTypes - uniqued method type signatures. We have to use 831 /// a StringMap here because have no other unique reference. 832 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 833 834 /// MethodDefinitions - map of methods which have been defined in 835 /// this translation unit. 836 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 837 838 /// PropertyNames - uniqued method variable names. 839 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 840 841 /// ClassReferences - uniqued class references. 842 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 843 844 /// SelectorReferences - uniqued selector references. 845 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 846 847 /// Protocols - Protocols for which an objc_protocol structure has 848 /// been emitted. Forward declarations are handled by creating an 849 /// empty structure whose initializer is filled in when/if defined. 850 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 851 852 /// DefinedProtocols - Protocols which have actually been 853 /// defined. We should not need this, see FIXME in GenerateProtocol. 854 llvm::DenseSet<IdentifierInfo*> DefinedProtocols; 855 856 /// DefinedClasses - List of defined classes. 857 std::vector<llvm::GlobalValue*> DefinedClasses; 858 859 /// DefinedNonLazyClasses - List of defined "non-lazy" classes. 860 std::vector<llvm::GlobalValue*> DefinedNonLazyClasses; 861 862 /// DefinedCategories - List of defined categories. 863 std::vector<llvm::GlobalValue*> DefinedCategories; 864 865 /// DefinedNonLazyCategories - List of defined "non-lazy" categories. 866 std::vector<llvm::GlobalValue*> DefinedNonLazyCategories; 867 868 /// GetNameForMethod - Return a name for the given method. 869 /// \param[out] NameOut - The return value. 870 void GetNameForMethod(const ObjCMethodDecl *OMD, 871 const ObjCContainerDecl *CD, 872 llvm::SmallVectorImpl<char> &NameOut); 873 874 /// GetMethodVarName - Return a unique constant for the given 875 /// selector's name. The return value has type char *. 876 llvm::Constant *GetMethodVarName(Selector Sel); 877 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 878 879 /// GetMethodVarType - Return a unique constant for the given 880 /// selector's name. The return value has type char *. 881 882 // FIXME: This is a horrible name. 883 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D); 884 llvm::Constant *GetMethodVarType(const FieldDecl *D); 885 886 /// GetPropertyName - Return a unique constant for the given 887 /// name. The return value has type char *. 888 llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 889 890 // FIXME: This can be dropped once string functions are unified. 891 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 892 const Decl *Container); 893 894 /// GetClassName - Return a unique constant for the given selector's 895 /// name. The return value has type char *. 896 llvm::Constant *GetClassName(IdentifierInfo *Ident); 897 898 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD); 899 900 /// BuildIvarLayout - Builds ivar layout bitmap for the class 901 /// implementation for the __strong or __weak case. 902 /// 903 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI, 904 bool ForStrongLayout); 905 906 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap); 907 908 void BuildAggrIvarRecordLayout(const RecordType *RT, 909 unsigned int BytePos, bool ForStrongLayout, 910 bool &HasUnion); 911 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 912 const llvm::StructLayout *Layout, 913 const RecordDecl *RD, 914 const llvm::SmallVectorImpl<FieldDecl*> &RecFields, 915 unsigned int BytePos, bool ForStrongLayout, 916 bool &HasUnion); 917 918 /// GetIvarLayoutName - Returns a unique constant for the given 919 /// ivar layout bitmap. 920 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident, 921 const ObjCCommonTypesHelper &ObjCTypes); 922 923 /// EmitPropertyList - Emit the given property list. The return 924 /// value has type PropertyListPtrTy. 925 llvm::Constant *EmitPropertyList(llvm::Twine Name, 926 const Decl *Container, 927 const ObjCContainerDecl *OCD, 928 const ObjCCommonTypesHelper &ObjCTypes); 929 930 /// PushProtocolProperties - Push protocol's property on the input stack. 931 void PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 932 std::vector<llvm::Constant*> &Properties, 933 const Decl *Container, 934 const ObjCProtocolDecl *PROTO, 935 const ObjCCommonTypesHelper &ObjCTypes); 936 937 /// GetProtocolRef - Return a reference to the internal protocol 938 /// description, creating an empty one if it has not been 939 /// defined. The return value has type ProtocolPtrTy. 940 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); 941 942 /// CreateMetadataVar - Create a global variable with internal 943 /// linkage for use by the Objective-C runtime. 944 /// 945 /// This is a convenience wrapper which not only creates the 946 /// variable, but also sets the section and alignment and adds the 947 /// global to the "llvm.used" list. 948 /// 949 /// \param Name - The variable name. 950 /// \param Init - The variable initializer; this is also used to 951 /// define the type of the variable. 952 /// \param Section - The section the variable should go into, or 0. 953 /// \param Align - The alignment for the variable, or 0. 954 /// \param AddToUsed - Whether the variable should be added to 955 /// "llvm.used". 956 llvm::GlobalVariable *CreateMetadataVar(llvm::Twine Name, 957 llvm::Constant *Init, 958 const char *Section, 959 unsigned Align, 960 bool AddToUsed); 961 962 CodeGen::RValue EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF, 963 ReturnValueSlot Return, 964 QualType ResultType, 965 llvm::Value *Sel, 966 llvm::Value *Arg0, 967 QualType Arg0Ty, 968 bool IsSuper, 969 const CallArgList &CallArgs, 970 const ObjCMethodDecl *OMD, 971 const ObjCCommonTypesHelper &ObjCTypes); 972 973 /// EmitImageInfo - Emit the image info marker used to encode some module 974 /// level information. 975 void EmitImageInfo(); 976 977public: 978 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : 979 CGM(cgm), VMContext(cgm.getLLVMContext()) { } 980 981 virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL); 982 983 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 984 const ObjCContainerDecl *CD=0); 985 986 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 987 988 /// GetOrEmitProtocol - Get the protocol object for the given 989 /// declaration, emitting it if necessary. The return value has type 990 /// ProtocolPtrTy. 991 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0; 992 993 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 994 /// object for the given declaration, emitting it if needed. These 995 /// forward references will be filled in with empty bodies if no 996 /// definition is seen. The return value has type ProtocolPtrTy. 997 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0; 998 virtual llvm::Constant *GCBlockLayout(CodeGen::CodeGenFunction &CGF, 999 const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &); 1000 1001}; 1002 1003class CGObjCMac : public CGObjCCommonMac { 1004private: 1005 ObjCTypesHelper ObjCTypes; 1006 1007 /// EmitModuleInfo - Another marker encoding module level 1008 /// information. 1009 void EmitModuleInfo(); 1010 1011 /// EmitModuleSymols - Emit module symbols, the list of defined 1012 /// classes and categories. The result has type SymtabPtrTy. 1013 llvm::Constant *EmitModuleSymbols(); 1014 1015 /// FinishModule - Write out global data structures at the end of 1016 /// processing a translation unit. 1017 void FinishModule(); 1018 1019 /// EmitClassExtension - Generate the class extension structure used 1020 /// to store the weak ivar layout and properties. The return value 1021 /// has type ClassExtensionPtrTy. 1022 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 1023 1024 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 1025 /// for the given class. 1026 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 1027 const ObjCInterfaceDecl *ID); 1028 1029 /// EmitSuperClassRef - Emits reference to class's main metadata class. 1030 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID); 1031 1032 /// EmitIvarList - Emit the ivar list for the given 1033 /// implementation. If ForClass is true the list of class ivars 1034 /// (i.e. metaclass ivars) is emitted, otherwise the list of 1035 /// interface ivars will be emitted. The return value has type 1036 /// IvarListPtrTy. 1037 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 1038 bool ForClass); 1039 1040 /// EmitMetaClass - Emit a forward reference to the class structure 1041 /// for the metaclass of the given interface. The return value has 1042 /// type ClassPtrTy. 1043 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 1044 1045 /// EmitMetaClass - Emit a class structure for the metaclass of the 1046 /// given implementation. The return value has type ClassPtrTy. 1047 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 1048 llvm::Constant *Protocols, 1049 const ConstantVector &Methods); 1050 1051 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 1052 1053 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 1054 1055 /// EmitMethodList - Emit the method list for the given 1056 /// implementation. The return value has type MethodListPtrTy. 1057 llvm::Constant *EmitMethodList(llvm::Twine Name, 1058 const char *Section, 1059 const ConstantVector &Methods); 1060 1061 /// EmitMethodDescList - Emit a method description list for a list of 1062 /// method declarations. 1063 /// - TypeName: The name for the type containing the methods. 1064 /// - IsProtocol: True iff these methods are for a protocol. 1065 /// - ClassMethds: True iff these are class methods. 1066 /// - Required: When true, only "required" methods are 1067 /// listed. Similarly, when false only "optional" methods are 1068 /// listed. For classes this should always be true. 1069 /// - begin, end: The method list to output. 1070 /// 1071 /// The return value has type MethodDescriptionListPtrTy. 1072 llvm::Constant *EmitMethodDescList(llvm::Twine Name, 1073 const char *Section, 1074 const ConstantVector &Methods); 1075 1076 /// GetOrEmitProtocol - Get the protocol object for the given 1077 /// declaration, emitting it if necessary. The return value has type 1078 /// ProtocolPtrTy. 1079 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 1080 1081 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1082 /// object for the given declaration, emitting it if needed. These 1083 /// forward references will be filled in with empty bodies if no 1084 /// definition is seen. The return value has type ProtocolPtrTy. 1085 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 1086 1087 /// EmitProtocolExtension - Generate the protocol extension 1088 /// structure used to store optional instance and class methods, and 1089 /// protocol properties. The return value has type 1090 /// ProtocolExtensionPtrTy. 1091 llvm::Constant * 1092 EmitProtocolExtension(const ObjCProtocolDecl *PD, 1093 const ConstantVector &OptInstanceMethods, 1094 const ConstantVector &OptClassMethods); 1095 1096 /// EmitProtocolList - Generate the list of referenced 1097 /// protocols. The return value has type ProtocolListPtrTy. 1098 llvm::Constant *EmitProtocolList(llvm::Twine Name, 1099 ObjCProtocolDecl::protocol_iterator begin, 1100 ObjCProtocolDecl::protocol_iterator end); 1101 1102 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 1103 /// for the given selector. 1104 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 1105 bool lval=false); 1106 1107public: 1108 CGObjCMac(CodeGen::CodeGenModule &cgm); 1109 1110 virtual llvm::Function *ModuleInitFunction(); 1111 1112 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1113 ReturnValueSlot Return, 1114 QualType ResultType, 1115 Selector Sel, 1116 llvm::Value *Receiver, 1117 const CallArgList &CallArgs, 1118 const ObjCInterfaceDecl *Class, 1119 const ObjCMethodDecl *Method); 1120 1121 virtual CodeGen::RValue 1122 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1123 ReturnValueSlot Return, 1124 QualType ResultType, 1125 Selector Sel, 1126 const ObjCInterfaceDecl *Class, 1127 bool isCategoryImpl, 1128 llvm::Value *Receiver, 1129 bool IsClassMessage, 1130 const CallArgList &CallArgs, 1131 const ObjCMethodDecl *Method); 1132 1133 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 1134 const ObjCInterfaceDecl *ID); 1135 1136 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 1137 bool lval = false); 1138 1139 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1140 /// untyped one. 1141 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1142 const ObjCMethodDecl *Method); 1143 1144 virtual llvm::Constant *GetEHType(QualType T); 1145 1146 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 1147 1148 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1149 1150 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1151 const ObjCProtocolDecl *PD); 1152 1153 virtual llvm::Constant *GetPropertyGetFunction(); 1154 virtual llvm::Constant *GetPropertySetFunction(); 1155 virtual llvm::Constant *GetCopyStructFunction(); 1156 virtual llvm::Constant *EnumerationMutationFunction(); 1157 1158 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 1159 const ObjCAtTryStmt &S); 1160 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1161 const ObjCAtSynchronizedStmt &S); 1162 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S); 1163 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1164 const ObjCAtThrowStmt &S); 1165 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1166 llvm::Value *AddrWeakObj); 1167 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1168 llvm::Value *src, llvm::Value *dst); 1169 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1170 llvm::Value *src, llvm::Value *dest, 1171 bool threadlocal = false); 1172 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1173 llvm::Value *src, llvm::Value *dest, 1174 llvm::Value *ivarOffset); 1175 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1176 llvm::Value *src, llvm::Value *dest); 1177 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1178 llvm::Value *dest, llvm::Value *src, 1179 llvm::Value *size); 1180 1181 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1182 QualType ObjectTy, 1183 llvm::Value *BaseValue, 1184 const ObjCIvarDecl *Ivar, 1185 unsigned CVRQualifiers); 1186 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1187 const ObjCInterfaceDecl *Interface, 1188 const ObjCIvarDecl *Ivar); 1189}; 1190 1191class CGObjCNonFragileABIMac : public CGObjCCommonMac { 1192private: 1193 ObjCNonFragileABITypesHelper ObjCTypes; 1194 llvm::GlobalVariable* ObjCEmptyCacheVar; 1195 llvm::GlobalVariable* ObjCEmptyVtableVar; 1196 1197 /// SuperClassReferences - uniqued super class references. 1198 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences; 1199 1200 /// MetaClassReferences - uniqued meta class references. 1201 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences; 1202 1203 /// EHTypeReferences - uniqued class ehtype references. 1204 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences; 1205 1206 /// NonLegacyDispatchMethods - List of methods for which we do *not* generate 1207 /// legacy messaging dispatch. 1208 llvm::DenseSet<Selector> NonLegacyDispatchMethods; 1209 1210 /// DefinedMetaClasses - List of defined meta-classes. 1211 std::vector<llvm::GlobalValue*> DefinedMetaClasses; 1212 1213 /// LegacyDispatchedSelector - Returns true if SEL is not in the list of 1214 /// NonLegacyDispatchMethods; false otherwise. 1215 bool LegacyDispatchedSelector(Selector Sel); 1216 1217 /// FinishNonFragileABIModule - Write out global data structures at the end of 1218 /// processing a translation unit. 1219 void FinishNonFragileABIModule(); 1220 1221 /// AddModuleClassList - Add the given list of class pointers to the 1222 /// module with the provided symbol and section names. 1223 void AddModuleClassList(const std::vector<llvm::GlobalValue*> &Container, 1224 const char *SymbolName, 1225 const char *SectionName); 1226 1227 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 1228 unsigned InstanceStart, 1229 unsigned InstanceSize, 1230 const ObjCImplementationDecl *ID); 1231 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, 1232 llvm::Constant *IsAGV, 1233 llvm::Constant *SuperClassGV, 1234 llvm::Constant *ClassRoGV, 1235 bool HiddenVisibility); 1236 1237 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 1238 1239 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 1240 1241 /// EmitMethodList - Emit the method list for the given 1242 /// implementation. The return value has type MethodListnfABITy. 1243 llvm::Constant *EmitMethodList(llvm::Twine Name, 1244 const char *Section, 1245 const ConstantVector &Methods); 1246 /// EmitIvarList - Emit the ivar list for the given 1247 /// implementation. If ForClass is true the list of class ivars 1248 /// (i.e. metaclass ivars) is emitted, otherwise the list of 1249 /// interface ivars will be emitted. The return value has type 1250 /// IvarListnfABIPtrTy. 1251 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); 1252 1253 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 1254 const ObjCIvarDecl *Ivar, 1255 unsigned long int offset); 1256 1257 /// GetOrEmitProtocol - Get the protocol object for the given 1258 /// declaration, emitting it if necessary. The return value has type 1259 /// ProtocolPtrTy. 1260 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 1261 1262 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 1263 /// object for the given declaration, emitting it if needed. These 1264 /// forward references will be filled in with empty bodies if no 1265 /// definition is seen. The return value has type ProtocolPtrTy. 1266 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 1267 1268 /// EmitProtocolList - Generate the list of referenced 1269 /// protocols. The return value has type ProtocolListPtrTy. 1270 llvm::Constant *EmitProtocolList(llvm::Twine Name, 1271 ObjCProtocolDecl::protocol_iterator begin, 1272 ObjCProtocolDecl::protocol_iterator end); 1273 1274 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 1275 ReturnValueSlot Return, 1276 QualType ResultType, 1277 Selector Sel, 1278 llvm::Value *Receiver, 1279 QualType Arg0Ty, 1280 bool IsSuper, 1281 const CallArgList &CallArgs); 1282 1283 /// GetClassGlobal - Return the global variable for the Objective-C 1284 /// class of the given name. 1285 llvm::GlobalVariable *GetClassGlobal(const std::string &Name); 1286 1287 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 1288 /// for the given class reference. 1289 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 1290 const ObjCInterfaceDecl *ID); 1291 1292 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 1293 /// for the given super class reference. 1294 llvm::Value *EmitSuperClassRef(CGBuilderTy &Builder, 1295 const ObjCInterfaceDecl *ID); 1296 1297 /// EmitMetaClassRef - Return a Value * of the address of _class_t 1298 /// meta-data 1299 llvm::Value *EmitMetaClassRef(CGBuilderTy &Builder, 1300 const ObjCInterfaceDecl *ID); 1301 1302 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for 1303 /// the given ivar. 1304 /// 1305 llvm::GlobalVariable * ObjCIvarOffsetVariable( 1306 const ObjCInterfaceDecl *ID, 1307 const ObjCIvarDecl *Ivar); 1308 1309 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 1310 /// for the given selector. 1311 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel, 1312 bool lval=false); 1313 1314 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C 1315 /// interface. The return value has type EHTypePtrTy. 1316 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID, 1317 bool ForDefinition); 1318 1319 const char *getMetaclassSymbolPrefix() const { 1320 return "OBJC_METACLASS_$_"; 1321 } 1322 1323 const char *getClassSymbolPrefix() const { 1324 return "OBJC_CLASS_$_"; 1325 } 1326 1327 void GetClassSizeInfo(const ObjCImplementationDecl *OID, 1328 uint32_t &InstanceStart, 1329 uint32_t &InstanceSize); 1330 1331 // Shamelessly stolen from Analysis/CFRefCount.cpp 1332 Selector GetNullarySelector(const char* name) const { 1333 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 1334 return CGM.getContext().Selectors.getSelector(0, &II); 1335 } 1336 1337 Selector GetUnarySelector(const char* name) const { 1338 IdentifierInfo* II = &CGM.getContext().Idents.get(name); 1339 return CGM.getContext().Selectors.getSelector(1, &II); 1340 } 1341 1342 /// ImplementationIsNonLazy - Check whether the given category or 1343 /// class implementation is "non-lazy". 1344 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const; 1345 1346public: 1347 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); 1348 // FIXME. All stubs for now! 1349 virtual llvm::Function *ModuleInitFunction(); 1350 1351 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1352 ReturnValueSlot Return, 1353 QualType ResultType, 1354 Selector Sel, 1355 llvm::Value *Receiver, 1356 const CallArgList &CallArgs, 1357 const ObjCInterfaceDecl *Class, 1358 const ObjCMethodDecl *Method); 1359 1360 virtual CodeGen::RValue 1361 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1362 ReturnValueSlot Return, 1363 QualType ResultType, 1364 Selector Sel, 1365 const ObjCInterfaceDecl *Class, 1366 bool isCategoryImpl, 1367 llvm::Value *Receiver, 1368 bool IsClassMessage, 1369 const CallArgList &CallArgs, 1370 const ObjCMethodDecl *Method); 1371 1372 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 1373 const ObjCInterfaceDecl *ID); 1374 1375 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel, 1376 bool lvalue = false) 1377 { return EmitSelector(Builder, Sel, lvalue); } 1378 1379 /// The NeXT/Apple runtimes do not support typed selectors; just emit an 1380 /// untyped one. 1381 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, 1382 const ObjCMethodDecl *Method) 1383 { return EmitSelector(Builder, Method->getSelector()); } 1384 1385 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 1386 1387 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 1388 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 1389 const ObjCProtocolDecl *PD); 1390 1391 virtual llvm::Constant *GetEHType(QualType T); 1392 1393 virtual llvm::Constant *GetPropertyGetFunction() { 1394 return ObjCTypes.getGetPropertyFn(); 1395 } 1396 virtual llvm::Constant *GetPropertySetFunction() { 1397 return ObjCTypes.getSetPropertyFn(); 1398 } 1399 1400 virtual llvm::Constant *GetCopyStructFunction() { 1401 return ObjCTypes.getCopyStructFn(); 1402 } 1403 1404 virtual llvm::Constant *EnumerationMutationFunction() { 1405 return ObjCTypes.getEnumerationMutationFn(); 1406 } 1407 1408 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 1409 const ObjCAtTryStmt &S); 1410 virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1411 const ObjCAtSynchronizedStmt &S); 1412 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1413 const ObjCAtThrowStmt &S); 1414 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 1415 llvm::Value *AddrWeakObj); 1416 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 1417 llvm::Value *src, llvm::Value *dst); 1418 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 1419 llvm::Value *src, llvm::Value *dest, 1420 bool threadlocal = false); 1421 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 1422 llvm::Value *src, llvm::Value *dest, 1423 llvm::Value *ivarOffset); 1424 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 1425 llvm::Value *src, llvm::Value *dest); 1426 virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 1427 llvm::Value *dest, llvm::Value *src, 1428 llvm::Value *size); 1429 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 1430 QualType ObjectTy, 1431 llvm::Value *BaseValue, 1432 const ObjCIvarDecl *Ivar, 1433 unsigned CVRQualifiers); 1434 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 1435 const ObjCInterfaceDecl *Interface, 1436 const ObjCIvarDecl *Ivar); 1437}; 1438 1439} // end anonymous namespace 1440 1441/* *** Helper Functions *** */ 1442 1443/// getConstantGEP() - Help routine to construct simple GEPs. 1444static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext, 1445 llvm::Constant *C, 1446 unsigned idx0, 1447 unsigned idx1) { 1448 llvm::Value *Idxs[] = { 1449 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0), 1450 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1) 1451 }; 1452 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2); 1453} 1454 1455/// hasObjCExceptionAttribute - Return true if this class or any super 1456/// class has the __objc_exception__ attribute. 1457static bool hasObjCExceptionAttribute(ASTContext &Context, 1458 const ObjCInterfaceDecl *OID) { 1459 if (OID->hasAttr<ObjCExceptionAttr>()) 1460 return true; 1461 if (const ObjCInterfaceDecl *Super = OID->getSuperClass()) 1462 return hasObjCExceptionAttribute(Context, Super); 1463 return false; 1464} 1465 1466/* *** CGObjCMac Public Interface *** */ 1467 1468CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), 1469 ObjCTypes(cgm) { 1470 ObjCABI = 1; 1471 EmitImageInfo(); 1472} 1473 1474/// GetClass - Return a reference to the class for the given interface 1475/// decl. 1476llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder, 1477 const ObjCInterfaceDecl *ID) { 1478 return EmitClassRef(Builder, ID); 1479} 1480 1481/// GetSelector - Return the pointer to the unique'd string for this selector. 1482llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel, 1483 bool lval) { 1484 return EmitSelector(Builder, Sel, lval); 1485} 1486llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl 1487 *Method) { 1488 return EmitSelector(Builder, Method->getSelector()); 1489} 1490 1491llvm::Constant *CGObjCMac::GetEHType(QualType T) { 1492 llvm_unreachable("asking for catch type for ObjC type in fragile runtime"); 1493 return 0; 1494} 1495 1496/// Generate a constant CFString object. 1497/* 1498 struct __builtin_CFString { 1499 const int *isa; // point to __CFConstantStringClassReference 1500 int flags; 1501 const char *str; 1502 long length; 1503 }; 1504*/ 1505 1506/// or Generate a constant NSString object. 1507/* 1508 struct __builtin_NSString { 1509 const int *isa; // point to __NSConstantStringClassReference 1510 const char *str; 1511 unsigned int length; 1512 }; 1513*/ 1514 1515llvm::Constant *CGObjCCommonMac::GenerateConstantString( 1516 const StringLiteral *SL) { 1517 return (CGM.getLangOptions().NoConstantCFStrings == 0 ? 1518 CGM.GetAddrOfConstantCFString(SL) : 1519 CGM.GetAddrOfConstantNSString(SL)); 1520} 1521 1522/// Generates a message send where the super is the receiver. This is 1523/// a message send to self with special delivery semantics indicating 1524/// which class's method should be called. 1525CodeGen::RValue 1526CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 1527 ReturnValueSlot Return, 1528 QualType ResultType, 1529 Selector Sel, 1530 const ObjCInterfaceDecl *Class, 1531 bool isCategoryImpl, 1532 llvm::Value *Receiver, 1533 bool IsClassMessage, 1534 const CodeGen::CallArgList &CallArgs, 1535 const ObjCMethodDecl *Method) { 1536 // Create and init a super structure; this is a (receiver, class) 1537 // pair we will pass to objc_msgSendSuper. 1538 llvm::Value *ObjCSuper = 1539 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super"); 1540 llvm::Value *ReceiverAsObject = 1541 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 1542 CGF.Builder.CreateStore(ReceiverAsObject, 1543 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 1544 1545 // If this is a class message the metaclass is passed as the target. 1546 llvm::Value *Target; 1547 if (IsClassMessage) { 1548 if (isCategoryImpl) { 1549 // Message sent to 'super' in a class method defined in a category 1550 // implementation requires an odd treatment. 1551 // If we are in a class method, we must retrieve the 1552 // _metaclass_ for the current class, pointed at by 1553 // the class's "isa" pointer. The following assumes that 1554 // isa" is the first ivar in a class (which it must be). 1555 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1556 Target = CGF.Builder.CreateStructGEP(Target, 0); 1557 Target = CGF.Builder.CreateLoad(Target); 1558 } else { 1559 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 1560 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 1561 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 1562 Target = Super; 1563 } 1564 } 1565 else if (isCategoryImpl) 1566 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 1567 else { 1568 llvm::Value *ClassPtr = EmitSuperClassRef(Class); 1569 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1); 1570 Target = CGF.Builder.CreateLoad(ClassPtr); 1571 } 1572 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 1573 // ObjCTypes types. 1574 const llvm::Type *ClassTy = 1575 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 1576 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 1577 CGF.Builder.CreateStore(Target, 1578 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 1579 return EmitLegacyMessageSend(CGF, Return, ResultType, 1580 EmitSelector(CGF.Builder, Sel), 1581 ObjCSuper, ObjCTypes.SuperPtrCTy, 1582 true, CallArgs, Method, ObjCTypes); 1583} 1584 1585/// Generate code for a message send expression. 1586CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 1587 ReturnValueSlot Return, 1588 QualType ResultType, 1589 Selector Sel, 1590 llvm::Value *Receiver, 1591 const CallArgList &CallArgs, 1592 const ObjCInterfaceDecl *Class, 1593 const ObjCMethodDecl *Method) { 1594 return EmitLegacyMessageSend(CGF, Return, ResultType, 1595 EmitSelector(CGF.Builder, Sel), 1596 Receiver, CGF.getContext().getObjCIdType(), 1597 false, CallArgs, Method, ObjCTypes); 1598} 1599 1600CodeGen::RValue 1601CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF, 1602 ReturnValueSlot Return, 1603 QualType ResultType, 1604 llvm::Value *Sel, 1605 llvm::Value *Arg0, 1606 QualType Arg0Ty, 1607 bool IsSuper, 1608 const CallArgList &CallArgs, 1609 const ObjCMethodDecl *Method, 1610 const ObjCCommonTypesHelper &ObjCTypes) { 1611 CallArgList ActualArgs; 1612 if (!IsSuper) 1613 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy, "tmp"); 1614 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); 1615 ActualArgs.push_back(std::make_pair(RValue::get(Sel), 1616 CGF.getContext().getObjCSelType())); 1617 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 1618 1619 CodeGenTypes &Types = CGM.getTypes(); 1620 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs, 1621 FunctionType::ExtInfo()); 1622 const llvm::FunctionType *FTy = 1623 Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); 1624 1625 if (Method) 1626 assert(CGM.getContext().getCanonicalType(Method->getResultType()) == 1627 CGM.getContext().getCanonicalType(ResultType) && 1628 "Result type mismatch!"); 1629 1630 llvm::Constant *Fn = NULL; 1631 if (CGM.ReturnTypeUsesSRet(FnInfo)) { 1632 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper) 1633 : ObjCTypes.getSendStretFn(IsSuper); 1634 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) { 1635 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper) 1636 : ObjCTypes.getSendFpretFn(IsSuper); 1637 } else { 1638 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper) 1639 : ObjCTypes.getSendFn(IsSuper); 1640 } 1641 Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy)); 1642 return CGF.EmitCall(FnInfo, Fn, Return, ActualArgs); 1643} 1644 1645static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) { 1646 if (FQT.isObjCGCStrong()) 1647 return Qualifiers::Strong; 1648 1649 if (FQT.isObjCGCWeak()) 1650 return Qualifiers::Weak; 1651 1652 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType()) 1653 return Qualifiers::Strong; 1654 1655 if (const PointerType *PT = FQT->getAs<PointerType>()) 1656 return GetGCAttrTypeForType(Ctx, PT->getPointeeType()); 1657 1658 return Qualifiers::GCNone; 1659} 1660 1661llvm::Constant *CGObjCCommonMac::GCBlockLayout(CodeGen::CodeGenFunction &CGF, 1662 const llvm::SmallVectorImpl<const BlockDeclRefExpr *> &DeclRefs) { 1663 llvm::Constant *NullPtr = 1664 llvm::Constant::getNullValue(llvm::Type::getInt8PtrTy(VMContext)); 1665 if ((CGM.getLangOptions().getGCMode() == LangOptions::NonGC) || 1666 DeclRefs.empty()) 1667 return NullPtr; 1668 bool hasUnion = false; 1669 SkipIvars.clear(); 1670 IvarsInfo.clear(); 1671 unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0); 1672 unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth(); 1673 1674 for (size_t i = 0; i < DeclRefs.size(); ++i) { 1675 const BlockDeclRefExpr *BDRE = DeclRefs[i]; 1676 const ValueDecl *VD = BDRE->getDecl(); 1677 CharUnits Offset = CGF.BlockDecls[VD]; 1678 uint64_t FieldOffset = Offset.getQuantity(); 1679 QualType Ty = VD->getType(); 1680 assert(!Ty->isArrayType() && 1681 "Array block variable should have been caught"); 1682 if ((Ty->isRecordType() || Ty->isUnionType()) && !BDRE->isByRef()) { 1683 BuildAggrIvarRecordLayout(Ty->getAs<RecordType>(), 1684 FieldOffset, 1685 true, 1686 hasUnion); 1687 continue; 1688 } 1689 1690 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), Ty); 1691 unsigned FieldSize = CGM.getContext().getTypeSize(Ty); 1692 // __block variables are passed by their descriptior address. So, size 1693 // must reflect this. 1694 if (BDRE->isByRef()) 1695 FieldSize = WordSizeInBits; 1696 if (GCAttr == Qualifiers::Strong || BDRE->isByRef()) 1697 IvarsInfo.push_back(GC_IVAR(FieldOffset, 1698 FieldSize / WordSizeInBits)); 1699 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak) 1700 SkipIvars.push_back(GC_IVAR(FieldOffset, 1701 FieldSize / ByteSizeInBits)); 1702 } 1703 1704 if (IvarsInfo.empty()) 1705 return NullPtr; 1706 // Sort on byte position in case we encounterred a union nested in 1707 // block variable type's aggregate type. 1708 if (hasUnion && !IvarsInfo.empty()) 1709 std::sort(IvarsInfo.begin(), IvarsInfo.end()); 1710 if (hasUnion && !SkipIvars.empty()) 1711 std::sort(SkipIvars.begin(), SkipIvars.end()); 1712 1713 std::string BitMap; 1714 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap); 1715 if (CGM.getLangOptions().ObjCGCBitmapPrint) { 1716 printf("\n block variable layout for block: "); 1717 const unsigned char *s = (unsigned char*)BitMap.c_str(); 1718 for (unsigned i = 0; i < BitMap.size(); i++) 1719 if (!(s[i] & 0xf0)) 1720 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : ""); 1721 else 1722 printf("0x%x%s", s[i], s[i] != 0 ? ", " : ""); 1723 printf("\n"); 1724 } 1725 1726 return C; 1727} 1728 1729llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, 1730 const ObjCProtocolDecl *PD) { 1731 // FIXME: I don't understand why gcc generates this, or where it is 1732 // resolved. Investigate. Its also wasteful to look this up over and over. 1733 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1734 1735 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 1736 ObjCTypes.ExternalProtocolPtrTy); 1737} 1738 1739void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 1740 // FIXME: We shouldn't need this, the protocol decl should contain enough 1741 // information to tell us whether this was a declaration or a definition. 1742 DefinedProtocols.insert(PD->getIdentifier()); 1743 1744 // If we have generated a forward reference to this protocol, emit 1745 // it now. Otherwise do nothing, the protocol objects are lazily 1746 // emitted. 1747 if (Protocols.count(PD->getIdentifier())) 1748 GetOrEmitProtocol(PD); 1749} 1750 1751llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 1752 if (DefinedProtocols.count(PD->getIdentifier())) 1753 return GetOrEmitProtocol(PD); 1754 return GetOrEmitProtocolRef(PD); 1755} 1756 1757/* 1758// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 1759struct _objc_protocol { 1760struct _objc_protocol_extension *isa; 1761char *protocol_name; 1762struct _objc_protocol_list *protocol_list; 1763struct _objc__method_prototype_list *instance_methods; 1764struct _objc__method_prototype_list *class_methods 1765}; 1766 1767See EmitProtocolExtension(). 1768*/ 1769llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { 1770 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 1771 1772 // Early exit if a defining object has already been generated. 1773 if (Entry && Entry->hasInitializer()) 1774 return Entry; 1775 1776 // FIXME: I don't understand why gcc generates this, or where it is 1777 // resolved. Investigate. Its also wasteful to look this up over and over. 1778 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 1779 1780 // Construct method lists. 1781 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1782 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 1783 for (ObjCProtocolDecl::instmeth_iterator 1784 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 1785 ObjCMethodDecl *MD = *i; 1786 llvm::Constant *C = GetMethodDescriptionConstant(MD); 1787 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1788 OptInstanceMethods.push_back(C); 1789 } else { 1790 InstanceMethods.push_back(C); 1791 } 1792 } 1793 1794 for (ObjCProtocolDecl::classmeth_iterator 1795 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 1796 ObjCMethodDecl *MD = *i; 1797 llvm::Constant *C = GetMethodDescriptionConstant(MD); 1798 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 1799 OptClassMethods.push_back(C); 1800 } else { 1801 ClassMethods.push_back(C); 1802 } 1803 } 1804 1805 std::vector<llvm::Constant*> Values(5); 1806 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods); 1807 Values[1] = GetClassName(PD->getIdentifier()); 1808 Values[2] = 1809 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(), 1810 PD->protocol_begin(), 1811 PD->protocol_end()); 1812 Values[3] = 1813 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(), 1814 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1815 InstanceMethods); 1816 Values[4] = 1817 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(), 1818 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1819 ClassMethods); 1820 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 1821 Values); 1822 1823 if (Entry) { 1824 // Already created, fix the linkage and update the initializer. 1825 Entry->setLinkage(llvm::GlobalValue::InternalLinkage); 1826 Entry->setInitializer(Init); 1827 } else { 1828 Entry = 1829 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 1830 llvm::GlobalValue::InternalLinkage, 1831 Init, 1832 "\01L_OBJC_PROTOCOL_" + PD->getName()); 1833 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 1834 // FIXME: Is this necessary? Why only for protocol? 1835 Entry->setAlignment(4); 1836 } 1837 CGM.AddUsedGlobal(Entry); 1838 1839 return Entry; 1840} 1841 1842llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { 1843 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 1844 1845 if (!Entry) { 1846 // We use the initializer as a marker of whether this is a forward 1847 // reference or not. At module finalization we add the empty 1848 // contents for protocols which were referenced but never defined. 1849 Entry = 1850 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false, 1851 llvm::GlobalValue::ExternalLinkage, 1852 0, 1853 "\01L_OBJC_PROTOCOL_" + PD->getName()); 1854 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 1855 // FIXME: Is this necessary? Why only for protocol? 1856 Entry->setAlignment(4); 1857 } 1858 1859 return Entry; 1860} 1861 1862/* 1863 struct _objc_protocol_extension { 1864 uint32_t size; 1865 struct objc_method_description_list *optional_instance_methods; 1866 struct objc_method_description_list *optional_class_methods; 1867 struct objc_property_list *instance_properties; 1868 }; 1869*/ 1870llvm::Constant * 1871CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 1872 const ConstantVector &OptInstanceMethods, 1873 const ConstantVector &OptClassMethods) { 1874 uint64_t Size = 1875 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy); 1876 std::vector<llvm::Constant*> Values(4); 1877 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1878 Values[1] = 1879 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" 1880 + PD->getName(), 1881 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1882 OptInstanceMethods); 1883 Values[2] = 1884 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(), 1885 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1886 OptClassMethods); 1887 Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 1888 0, PD, ObjCTypes); 1889 1890 // Return null if no extension bits are used. 1891 if (Values[1]->isNullValue() && Values[2]->isNullValue() && 1892 Values[3]->isNullValue()) 1893 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 1894 1895 llvm::Constant *Init = 1896 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 1897 1898 // No special section, but goes in llvm.used 1899 return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(), 1900 Init, 1901 0, 0, true); 1902} 1903 1904/* 1905 struct objc_protocol_list { 1906 struct objc_protocol_list *next; 1907 long count; 1908 Protocol *list[]; 1909 }; 1910*/ 1911llvm::Constant * 1912CGObjCMac::EmitProtocolList(llvm::Twine Name, 1913 ObjCProtocolDecl::protocol_iterator begin, 1914 ObjCProtocolDecl::protocol_iterator end) { 1915 std::vector<llvm::Constant*> ProtocolRefs; 1916 1917 for (; begin != end; ++begin) 1918 ProtocolRefs.push_back(GetProtocolRef(*begin)); 1919 1920 // Just return null for empty protocol lists 1921 if (ProtocolRefs.empty()) 1922 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1923 1924 // This list is null terminated. 1925 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 1926 1927 std::vector<llvm::Constant*> Values(3); 1928 // This field is only used by the runtime. 1929 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1930 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, 1931 ProtocolRefs.size() - 1); 1932 Values[2] = 1933 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 1934 ProtocolRefs.size()), 1935 ProtocolRefs); 1936 1937 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 1938 llvm::GlobalVariable *GV = 1939 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip", 1940 4, false); 1941 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 1942} 1943 1944void CGObjCCommonMac::PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet, 1945 std::vector<llvm::Constant*> &Properties, 1946 const Decl *Container, 1947 const ObjCProtocolDecl *PROTO, 1948 const ObjCCommonTypesHelper &ObjCTypes) { 1949 std::vector<llvm::Constant*> Prop(2); 1950 for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(), 1951 E = PROTO->protocol_end(); P != E; ++P) 1952 PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes); 1953 for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(), 1954 E = PROTO->prop_end(); I != E; ++I) { 1955 const ObjCPropertyDecl *PD = *I; 1956 if (!PropertySet.insert(PD->getIdentifier())) 1957 continue; 1958 Prop[0] = GetPropertyName(PD->getIdentifier()); 1959 Prop[1] = GetPropertyTypeString(PD, Container); 1960 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop)); 1961 } 1962} 1963 1964/* 1965 struct _objc_property { 1966 const char * const name; 1967 const char * const attributes; 1968 }; 1969 1970 struct _objc_property_list { 1971 uint32_t entsize; // sizeof (struct _objc_property) 1972 uint32_t prop_count; 1973 struct _objc_property[prop_count]; 1974 }; 1975*/ 1976llvm::Constant *CGObjCCommonMac::EmitPropertyList(llvm::Twine Name, 1977 const Decl *Container, 1978 const ObjCContainerDecl *OCD, 1979 const ObjCCommonTypesHelper &ObjCTypes) { 1980 std::vector<llvm::Constant*> Properties, Prop(2); 1981 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet; 1982 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), 1983 E = OCD->prop_end(); I != E; ++I) { 1984 const ObjCPropertyDecl *PD = *I; 1985 PropertySet.insert(PD->getIdentifier()); 1986 Prop[0] = GetPropertyName(PD->getIdentifier()); 1987 Prop[1] = GetPropertyTypeString(PD, Container); 1988 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 1989 Prop)); 1990 } 1991 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) { 1992 for (ObjCInterfaceDecl::protocol_iterator P = OID->protocol_begin(), 1993 E = OID->protocol_end(); P != E; ++P) 1994 PushProtocolProperties(PropertySet, Properties, Container, (*P), 1995 ObjCTypes); 1996 } 1997 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) { 1998 for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(), 1999 E = CD->protocol_end(); P != E; ++P) 2000 PushProtocolProperties(PropertySet, Properties, Container, (*P), 2001 ObjCTypes); 2002 } 2003 2004 // Return null for empty list. 2005 if (Properties.empty()) 2006 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 2007 2008 unsigned PropertySize = 2009 CGM.getTargetData().getTypeAllocSize(ObjCTypes.PropertyTy); 2010 std::vector<llvm::Constant*> Values(3); 2011 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 2012 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 2013 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 2014 Properties.size()); 2015 Values[2] = llvm::ConstantArray::get(AT, Properties); 2016 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 2017 2018 llvm::GlobalVariable *GV = 2019 CreateMetadataVar(Name, Init, 2020 (ObjCABI == 2) ? "__DATA, __objc_const" : 2021 "__OBJC,__property,regular,no_dead_strip", 2022 (ObjCABI == 2) ? 8 : 4, 2023 true); 2024 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy); 2025} 2026 2027/* 2028 struct objc_method_description_list { 2029 int count; 2030 struct objc_method_description list[]; 2031 }; 2032*/ 2033llvm::Constant * 2034CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 2035 std::vector<llvm::Constant*> Desc(2); 2036 Desc[0] = 2037 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 2038 ObjCTypes.SelectorPtrTy); 2039 Desc[1] = GetMethodVarType(MD); 2040 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 2041 Desc); 2042} 2043 2044llvm::Constant *CGObjCMac::EmitMethodDescList(llvm::Twine Name, 2045 const char *Section, 2046 const ConstantVector &Methods) { 2047 // Return null for empty list. 2048 if (Methods.empty()) 2049 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 2050 2051 std::vector<llvm::Constant*> Values(2); 2052 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 2053 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 2054 Methods.size()); 2055 Values[1] = llvm::ConstantArray::get(AT, Methods); 2056 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 2057 2058 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 2059 return llvm::ConstantExpr::getBitCast(GV, 2060 ObjCTypes.MethodDescriptionListPtrTy); 2061} 2062 2063/* 2064 struct _objc_category { 2065 char *category_name; 2066 char *class_name; 2067 struct _objc_method_list *instance_methods; 2068 struct _objc_method_list *class_methods; 2069 struct _objc_protocol_list *protocols; 2070 uint32_t size; // <rdar://4585769> 2071 struct _objc_property_list *instance_properties; 2072 }; 2073*/ 2074void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 2075 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.CategoryTy); 2076 2077 // FIXME: This is poor design, the OCD should have a pointer to the category 2078 // decl. Additionally, note that Category can be null for the @implementation 2079 // w/o an @interface case. Sema should just create one for us as it does for 2080 // @implementation so everyone else can live life under a clear blue sky. 2081 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 2082 const ObjCCategoryDecl *Category = 2083 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 2084 2085 llvm::SmallString<256> ExtName; 2086 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_' 2087 << OCD->getName(); 2088 2089 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 2090 for (ObjCCategoryImplDecl::instmeth_iterator 2091 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 2092 // Instance methods should always be defined. 2093 InstanceMethods.push_back(GetMethodConstant(*i)); 2094 } 2095 for (ObjCCategoryImplDecl::classmeth_iterator 2096 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 2097 // Class methods should always be defined. 2098 ClassMethods.push_back(GetMethodConstant(*i)); 2099 } 2100 2101 std::vector<llvm::Constant*> Values(7); 2102 Values[0] = GetClassName(OCD->getIdentifier()); 2103 Values[1] = GetClassName(Interface->getIdentifier()); 2104 LazySymbols.insert(Interface->getIdentifier()); 2105 Values[2] = 2106 EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(), 2107 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 2108 InstanceMethods); 2109 Values[3] = 2110 EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(), 2111 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 2112 ClassMethods); 2113 if (Category) { 2114 Values[4] = 2115 EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(), 2116 Category->protocol_begin(), 2117 Category->protocol_end()); 2118 } else { 2119 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 2120 } 2121 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 2122 2123 // If there is no category @interface then there can be no properties. 2124 if (Category) { 2125 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 2126 OCD, Category, ObjCTypes); 2127 } else { 2128 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 2129 } 2130 2131 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 2132 Values); 2133 2134 llvm::GlobalVariable *GV = 2135 CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init, 2136 "__OBJC,__category,regular,no_dead_strip", 2137 4, true); 2138 DefinedCategories.push_back(GV); 2139 DefinedCategoryNames.insert(ExtName.str()); 2140} 2141 2142// FIXME: Get from somewhere? 2143enum ClassFlags { 2144 eClassFlags_Factory = 0x00001, 2145 eClassFlags_Meta = 0x00002, 2146 // <rdr://5142207> 2147 eClassFlags_HasCXXStructors = 0x02000, 2148 eClassFlags_Hidden = 0x20000, 2149 eClassFlags_ABI2_Hidden = 0x00010, 2150 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 2151}; 2152 2153/* 2154 struct _objc_class { 2155 Class isa; 2156 Class super_class; 2157 const char *name; 2158 long version; 2159 long info; 2160 long instance_size; 2161 struct _objc_ivar_list *ivars; 2162 struct _objc_method_list *methods; 2163 struct _objc_cache *cache; 2164 struct _objc_protocol_list *protocols; 2165 // Objective-C 1.0 extensions (<rdr://4585769>) 2166 const char *ivar_layout; 2167 struct _objc_class_ext *ext; 2168 }; 2169 2170 See EmitClassExtension(); 2171*/ 2172void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 2173 DefinedSymbols.insert(ID->getIdentifier()); 2174 2175 std::string ClassName = ID->getNameAsString(); 2176 // FIXME: Gross 2177 ObjCInterfaceDecl *Interface = 2178 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 2179 llvm::Constant *Protocols = 2180 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(), 2181 Interface->protocol_begin(), 2182 Interface->protocol_end()); 2183 unsigned Flags = eClassFlags_Factory; 2184 if (ID->getNumIvarInitializers()) 2185 Flags |= eClassFlags_HasCXXStructors; 2186 unsigned Size = 2187 CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8; 2188 2189 // FIXME: Set CXX-structors flag. 2190 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) 2191 Flags |= eClassFlags_Hidden; 2192 2193 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 2194 for (ObjCImplementationDecl::instmeth_iterator 2195 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 2196 // Instance methods should always be defined. 2197 InstanceMethods.push_back(GetMethodConstant(*i)); 2198 } 2199 for (ObjCImplementationDecl::classmeth_iterator 2200 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 2201 // Class methods should always be defined. 2202 ClassMethods.push_back(GetMethodConstant(*i)); 2203 } 2204 2205 for (ObjCImplementationDecl::propimpl_iterator 2206 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 2207 ObjCPropertyImplDecl *PID = *i; 2208 2209 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 2210 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 2211 2212 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 2213 if (llvm::Constant *C = GetMethodConstant(MD)) 2214 InstanceMethods.push_back(C); 2215 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 2216 if (llvm::Constant *C = GetMethodConstant(MD)) 2217 InstanceMethods.push_back(C); 2218 } 2219 } 2220 2221 std::vector<llvm::Constant*> Values(12); 2222 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods); 2223 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 2224 // Record a reference to the super class. 2225 LazySymbols.insert(Super->getIdentifier()); 2226 2227 Values[ 1] = 2228 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 2229 ObjCTypes.ClassPtrTy); 2230 } else { 2231 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 2232 } 2233 Values[ 2] = GetClassName(ID->getIdentifier()); 2234 // Version is always 0. 2235 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2236 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 2237 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2238 Values[ 6] = EmitIvarList(ID, false); 2239 Values[ 7] = 2240 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(), 2241 "__OBJC,__inst_meth,regular,no_dead_strip", 2242 InstanceMethods); 2243 // cache is always NULL. 2244 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 2245 Values[ 9] = Protocols; 2246 Values[10] = BuildIvarLayout(ID, true); 2247 Values[11] = EmitClassExtension(ID); 2248 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 2249 Values); 2250 std::string Name("\01L_OBJC_CLASS_"); 2251 Name += ClassName; 2252 const char *Section = "__OBJC,__class,regular,no_dead_strip"; 2253 // Check for a forward reference. 2254 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2255 if (GV) { 2256 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2257 "Forward metaclass reference has incorrect type."); 2258 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2259 GV->setInitializer(Init); 2260 GV->setSection(Section); 2261 GV->setAlignment(4); 2262 CGM.AddUsedGlobal(GV); 2263 } 2264 else 2265 GV = CreateMetadataVar(Name, Init, Section, 4, true); 2266 DefinedClasses.push_back(GV); 2267} 2268 2269llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 2270 llvm::Constant *Protocols, 2271 const ConstantVector &Methods) { 2272 unsigned Flags = eClassFlags_Meta; 2273 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassTy); 2274 2275 if (CGM.getDeclVisibilityMode(ID->getClassInterface()) == LangOptions::Hidden) 2276 Flags |= eClassFlags_Hidden; 2277 2278 std::vector<llvm::Constant*> Values(12); 2279 // The isa for the metaclass is the root of the hierarchy. 2280 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 2281 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 2282 Root = Super; 2283 Values[ 0] = 2284 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 2285 ObjCTypes.ClassPtrTy); 2286 // The super class for the metaclass is emitted as the name of the 2287 // super class. The runtime fixes this up to point to the 2288 // *metaclass* for the super class. 2289 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 2290 Values[ 1] = 2291 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 2292 ObjCTypes.ClassPtrTy); 2293 } else { 2294 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 2295 } 2296 Values[ 2] = GetClassName(ID->getIdentifier()); 2297 // Version is always 0. 2298 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2299 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 2300 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2301 Values[ 6] = EmitIvarList(ID, true); 2302 Values[ 7] = 2303 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), 2304 "__OBJC,__cls_meth,regular,no_dead_strip", 2305 Methods); 2306 // cache is always NULL. 2307 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 2308 Values[ 9] = Protocols; 2309 // ivar_layout for metaclass is always NULL. 2310 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 2311 // The class extension is always unused for metaclasses. 2312 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 2313 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 2314 Values); 2315 2316 std::string Name("\01L_OBJC_METACLASS_"); 2317 Name += ID->getNameAsCString(); 2318 2319 // Check for a forward reference. 2320 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 2321 if (GV) { 2322 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2323 "Forward metaclass reference has incorrect type."); 2324 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 2325 GV->setInitializer(Init); 2326 } else { 2327 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2328 llvm::GlobalValue::InternalLinkage, 2329 Init, Name); 2330 } 2331 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 2332 GV->setAlignment(4); 2333 CGM.AddUsedGlobal(GV); 2334 2335 return GV; 2336} 2337 2338llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 2339 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString(); 2340 2341 // FIXME: Should we look these up somewhere other than the module. Its a bit 2342 // silly since we only generate these while processing an implementation, so 2343 // exactly one pointer would work if know when we entered/exitted an 2344 // implementation block. 2345 2346 // Check for an existing forward reference. 2347 // Previously, metaclass with internal linkage may have been defined. 2348 // pass 'true' as 2nd argument so it is returned. 2349 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 2350 true)) { 2351 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2352 "Forward metaclass reference has incorrect type."); 2353 return GV; 2354 } else { 2355 // Generate as an external reference to keep a consistent 2356 // module. This will be patched up when we emit the metaclass. 2357 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2358 llvm::GlobalValue::ExternalLinkage, 2359 0, 2360 Name); 2361 } 2362} 2363 2364llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) { 2365 std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString(); 2366 2367 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, 2368 true)) { 2369 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 2370 "Forward class metadata reference has incorrect type."); 2371 return GV; 2372 } else { 2373 return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false, 2374 llvm::GlobalValue::ExternalLinkage, 2375 0, 2376 Name); 2377 } 2378} 2379 2380/* 2381 struct objc_class_ext { 2382 uint32_t size; 2383 const char *weak_ivar_layout; 2384 struct _objc_property_list *properties; 2385 }; 2386*/ 2387llvm::Constant * 2388CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 2389 uint64_t Size = 2390 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassExtensionTy); 2391 2392 std::vector<llvm::Constant*> Values(3); 2393 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 2394 Values[1] = BuildIvarLayout(ID, false); 2395 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 2396 ID, ID->getClassInterface(), ObjCTypes); 2397 2398 // Return null if no extension bits are used. 2399 if (Values[1]->isNullValue() && Values[2]->isNullValue()) 2400 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 2401 2402 llvm::Constant *Init = 2403 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 2404 return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(), 2405 Init, "__OBJC,__class_ext,regular,no_dead_strip", 2406 4, true); 2407} 2408 2409/* 2410 struct objc_ivar { 2411 char *ivar_name; 2412 char *ivar_type; 2413 int ivar_offset; 2414 }; 2415 2416 struct objc_ivar_list { 2417 int ivar_count; 2418 struct objc_ivar list[count]; 2419 }; 2420*/ 2421llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 2422 bool ForClass) { 2423 std::vector<llvm::Constant*> Ivars, Ivar(3); 2424 2425 // When emitting the root class GCC emits ivar entries for the 2426 // actual class structure. It is not clear if we need to follow this 2427 // behavior; for now lets try and get away with not doing it. If so, 2428 // the cleanest solution would be to make up an ObjCInterfaceDecl 2429 // for the class. 2430 if (ForClass) 2431 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 2432 2433 ObjCInterfaceDecl *OID = 2434 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 2435 2436 llvm::SmallVector<ObjCIvarDecl*, 16> OIvars; 2437 CGM.getContext().ShallowCollectObjCIvars(OID, OIvars); 2438 2439 for (unsigned i = 0, e = OIvars.size(); i != e; ++i) { 2440 ObjCIvarDecl *IVD = OIvars[i]; 2441 // Ignore unnamed bit-fields. 2442 if (!IVD->getDeclName()) 2443 continue; 2444 Ivar[0] = GetMethodVarName(IVD->getIdentifier()); 2445 Ivar[1] = GetMethodVarType(IVD); 2446 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, 2447 ComputeIvarBaseOffset(CGM, OID, IVD)); 2448 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); 2449 } 2450 2451 // Return null for empty list. 2452 if (Ivars.empty()) 2453 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 2454 2455 std::vector<llvm::Constant*> Values(2); 2456 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 2457 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 2458 Ivars.size()); 2459 Values[1] = llvm::ConstantArray::get(AT, Ivars); 2460 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 2461 2462 llvm::GlobalVariable *GV; 2463 if (ForClass) 2464 GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(), 2465 Init, "__OBJC,__class_vars,regular,no_dead_strip", 2466 4, true); 2467 else 2468 GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(), 2469 Init, "__OBJC,__instance_vars,regular,no_dead_strip", 2470 4, true); 2471 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy); 2472} 2473 2474/* 2475 struct objc_method { 2476 SEL method_name; 2477 char *method_types; 2478 void *method; 2479 }; 2480 2481 struct objc_method_list { 2482 struct objc_method_list *obsolete; 2483 int count; 2484 struct objc_method methods_list[count]; 2485 }; 2486*/ 2487 2488/// GetMethodConstant - Return a struct objc_method constant for the 2489/// given method if it has been defined. The result is null if the 2490/// method has not been defined. The return value has type MethodPtrTy. 2491llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 2492 llvm::Function *Fn = GetMethodDefinition(MD); 2493 if (!Fn) 2494 return 0; 2495 2496 std::vector<llvm::Constant*> Method(3); 2497 Method[0] = 2498 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 2499 ObjCTypes.SelectorPtrTy); 2500 Method[1] = GetMethodVarType(MD); 2501 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 2502 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 2503} 2504 2505llvm::Constant *CGObjCMac::EmitMethodList(llvm::Twine Name, 2506 const char *Section, 2507 const ConstantVector &Methods) { 2508 // Return null for empty list. 2509 if (Methods.empty()) 2510 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 2511 2512 std::vector<llvm::Constant*> Values(3); 2513 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 2514 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 2515 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 2516 Methods.size()); 2517 Values[2] = llvm::ConstantArray::get(AT, Methods); 2518 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 2519 2520 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true); 2521 return llvm::ConstantExpr::getBitCast(GV, 2522 ObjCTypes.MethodListPtrTy); 2523} 2524 2525llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, 2526 const ObjCContainerDecl *CD) { 2527 llvm::SmallString<256> Name; 2528 GetNameForMethod(OMD, CD, Name); 2529 2530 CodeGenTypes &Types = CGM.getTypes(); 2531 const llvm::FunctionType *MethodTy = 2532 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); 2533 llvm::Function *Method = 2534 llvm::Function::Create(MethodTy, 2535 llvm::GlobalValue::InternalLinkage, 2536 Name.str(), 2537 &CGM.getModule()); 2538 MethodDefinitions.insert(std::make_pair(OMD, Method)); 2539 2540 return Method; 2541} 2542 2543llvm::GlobalVariable * 2544CGObjCCommonMac::CreateMetadataVar(llvm::Twine Name, 2545 llvm::Constant *Init, 2546 const char *Section, 2547 unsigned Align, 2548 bool AddToUsed) { 2549 const llvm::Type *Ty = Init->getType(); 2550 llvm::GlobalVariable *GV = 2551 new llvm::GlobalVariable(CGM.getModule(), Ty, false, 2552 llvm::GlobalValue::InternalLinkage, Init, Name); 2553 if (Section) 2554 GV->setSection(Section); 2555 if (Align) 2556 GV->setAlignment(Align); 2557 if (AddToUsed) 2558 CGM.AddUsedGlobal(GV); 2559 return GV; 2560} 2561 2562llvm::Function *CGObjCMac::ModuleInitFunction() { 2563 // Abuse this interface function as a place to finalize. 2564 FinishModule(); 2565 return NULL; 2566} 2567 2568llvm::Constant *CGObjCMac::GetPropertyGetFunction() { 2569 return ObjCTypes.getGetPropertyFn(); 2570} 2571 2572llvm::Constant *CGObjCMac::GetPropertySetFunction() { 2573 return ObjCTypes.getSetPropertyFn(); 2574} 2575 2576llvm::Constant *CGObjCMac::GetCopyStructFunction() { 2577 return ObjCTypes.getCopyStructFn(); 2578} 2579 2580llvm::Constant *CGObjCMac::EnumerationMutationFunction() { 2581 return ObjCTypes.getEnumerationMutationFn(); 2582} 2583 2584void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) { 2585 return EmitTryOrSynchronizedStmt(CGF, S); 2586} 2587 2588void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF, 2589 const ObjCAtSynchronizedStmt &S) { 2590 return EmitTryOrSynchronizedStmt(CGF, S); 2591} 2592 2593namespace { 2594 struct PerformFragileFinally : EHScopeStack::Cleanup { 2595 const Stmt &S; 2596 llvm::Value *SyncArgSlot; 2597 llvm::Value *CallTryExitVar; 2598 llvm::Value *ExceptionData; 2599 ObjCTypesHelper &ObjCTypes; 2600 PerformFragileFinally(const Stmt *S, 2601 llvm::Value *SyncArgSlot, 2602 llvm::Value *CallTryExitVar, 2603 llvm::Value *ExceptionData, 2604 ObjCTypesHelper *ObjCTypes) 2605 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar), 2606 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {} 2607 2608 void Emit(CodeGenFunction &CGF, bool IsForEH) { 2609 // Check whether we need to call objc_exception_try_exit. 2610 // In optimized code, this branch will always be folded. 2611 llvm::BasicBlock *FinallyCallExit = 2612 CGF.createBasicBlock("finally.call_exit"); 2613 llvm::BasicBlock *FinallyNoCallExit = 2614 CGF.createBasicBlock("finally.no_call_exit"); 2615 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar), 2616 FinallyCallExit, FinallyNoCallExit); 2617 2618 CGF.EmitBlock(FinallyCallExit); 2619 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryExitFn(), ExceptionData) 2620 ->setDoesNotThrow(); 2621 2622 CGF.EmitBlock(FinallyNoCallExit); 2623 2624 if (isa<ObjCAtTryStmt>(S)) { 2625 if (const ObjCAtFinallyStmt* FinallyStmt = 2626 cast<ObjCAtTryStmt>(S).getFinallyStmt()) { 2627 // Save the current cleanup destination in case there's 2628 // control flow inside the finally statement. 2629 llvm::Value *CurCleanupDest = 2630 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot()); 2631 2632 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 2633 2634 if (CGF.HaveInsertPoint()) { 2635 CGF.Builder.CreateStore(CurCleanupDest, 2636 CGF.getNormalCleanupDestSlot()); 2637 } else { 2638 // Currently, the end of the cleanup must always exist. 2639 CGF.EnsureInsertPoint(); 2640 } 2641 } 2642 } else { 2643 // Emit objc_sync_exit(expr); as finally's sole statement for 2644 // @synchronized. 2645 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot); 2646 CGF.Builder.CreateCall(ObjCTypes.getSyncExitFn(), SyncArg) 2647 ->setDoesNotThrow(); 2648 } 2649 } 2650 }; 2651 2652 class FragileHazards { 2653 CodeGenFunction &CGF; 2654 llvm::SmallVector<llvm::Value*, 20> Locals; 2655 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry; 2656 2657 llvm::InlineAsm *ReadHazard; 2658 llvm::InlineAsm *WriteHazard; 2659 2660 llvm::FunctionType *GetAsmFnType(); 2661 2662 void collectLocals(); 2663 void emitReadHazard(CGBuilderTy &Builder); 2664 2665 public: 2666 FragileHazards(CodeGenFunction &CGF); 2667 2668 void emitWriteHazard(); 2669 void emitHazardsInNewBlocks(); 2670 }; 2671} 2672 2673/// Create the fragile-ABI read and write hazards based on the current 2674/// state of the function, which is presumed to be immediately prior 2675/// to a @try block. These hazards are used to maintain correct 2676/// semantics in the face of optimization and the fragile ABI's 2677/// cavalier use of setjmp/longjmp. 2678FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) { 2679 collectLocals(); 2680 2681 if (Locals.empty()) return; 2682 2683 // Collect all the blocks in the function. 2684 for (llvm::Function::iterator 2685 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I) 2686 BlocksBeforeTry.insert(&*I); 2687 2688 llvm::FunctionType *AsmFnTy = GetAsmFnType(); 2689 2690 // Create a read hazard for the allocas. This inhibits dead-store 2691 // optimizations and forces the values to memory. This hazard is 2692 // inserted before any 'throwing' calls in the protected scope to 2693 // reflect the possibility that the variables might be read from the 2694 // catch block if the call throws. 2695 { 2696 std::string Constraint; 2697 for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 2698 if (I) Constraint += ','; 2699 Constraint += "*m"; 2700 } 2701 2702 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 2703 } 2704 2705 // Create a write hazard for the allocas. This inhibits folding 2706 // loads across the hazard. This hazard is inserted at the 2707 // beginning of the catch path to reflect the possibility that the 2708 // variables might have been written within the protected scope. 2709 { 2710 std::string Constraint; 2711 for (unsigned I = 0, E = Locals.size(); I != E; ++I) { 2712 if (I) Constraint += ','; 2713 Constraint += "=*m"; 2714 } 2715 2716 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false); 2717 } 2718} 2719 2720/// Emit a write hazard at the current location. 2721void FragileHazards::emitWriteHazard() { 2722 if (Locals.empty()) return; 2723 2724 CGF.Builder.CreateCall(WriteHazard, Locals.begin(), Locals.end()) 2725 ->setDoesNotThrow(); 2726} 2727 2728void FragileHazards::emitReadHazard(CGBuilderTy &Builder) { 2729 assert(!Locals.empty()); 2730 Builder.CreateCall(ReadHazard, Locals.begin(), Locals.end()) 2731 ->setDoesNotThrow(); 2732} 2733 2734/// Emit read hazards in all the protected blocks, i.e. all the blocks 2735/// which have been inserted since the beginning of the try. 2736void FragileHazards::emitHazardsInNewBlocks() { 2737 if (Locals.empty()) return; 2738 2739 CGBuilderTy Builder(CGF.getLLVMContext()); 2740 2741 // Iterate through all blocks, skipping those prior to the try. 2742 for (llvm::Function::iterator 2743 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) { 2744 llvm::BasicBlock &BB = *FI; 2745 if (BlocksBeforeTry.count(&BB)) continue; 2746 2747 // Walk through all the calls in the block. 2748 for (llvm::BasicBlock::iterator 2749 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) { 2750 llvm::Instruction &I = *BI; 2751 2752 // Ignore instructions that aren't non-intrinsic calls. 2753 // These are the only calls that can possibly call longjmp. 2754 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue; 2755 if (isa<llvm::IntrinsicInst>(I)) 2756 continue; 2757 2758 // Ignore call sites marked nounwind. This may be questionable, 2759 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'. 2760 llvm::CallSite CS(&I); 2761 if (CS.doesNotThrow()) continue; 2762 2763 // Insert a read hazard before the call. This will ensure that 2764 // any writes to the locals are performed before making the 2765 // call. If the call throws, then this is sufficient to 2766 // guarantee correctness as long as it doesn't also write to any 2767 // locals. 2768 Builder.SetInsertPoint(&BB, BI); 2769 emitReadHazard(Builder); 2770 } 2771 } 2772} 2773 2774static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) { 2775 if (V) S.insert(V); 2776} 2777 2778void FragileHazards::collectLocals() { 2779 // Compute a set of allocas to ignore. 2780 llvm::DenseSet<llvm::Value*> AllocasToIgnore; 2781 addIfPresent(AllocasToIgnore, CGF.ReturnValue); 2782 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest); 2783 addIfPresent(AllocasToIgnore, CGF.EHCleanupDest); 2784 2785 // Collect all the allocas currently in the function. This is 2786 // probably way too aggressive. 2787 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock(); 2788 for (llvm::BasicBlock::iterator 2789 I = Entry.begin(), E = Entry.end(); I != E; ++I) 2790 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I)) 2791 Locals.push_back(&*I); 2792} 2793 2794llvm::FunctionType *FragileHazards::GetAsmFnType() { 2795 std::vector<const llvm::Type *> Tys(Locals.size()); 2796 for (unsigned I = 0, E = Locals.size(); I != E; ++I) 2797 Tys[I] = Locals[I]->getType(); 2798 return llvm::FunctionType::get(CGF.Builder.getVoidTy(), Tys, false); 2799} 2800 2801/* 2802 2803 Objective-C setjmp-longjmp (sjlj) Exception Handling 2804 -- 2805 2806 A catch buffer is a setjmp buffer plus: 2807 - a pointer to the exception that was caught 2808 - a pointer to the previous exception data buffer 2809 - two pointers of reserved storage 2810 Therefore catch buffers form a stack, with a pointer to the top 2811 of the stack kept in thread-local storage. 2812 2813 objc_exception_try_enter pushes a catch buffer onto the EH stack. 2814 objc_exception_try_exit pops the given catch buffer, which is 2815 required to be the top of the EH stack. 2816 objc_exception_throw pops the top of the EH stack, writes the 2817 thrown exception into the appropriate field, and longjmps 2818 to the setjmp buffer. It crashes the process (with a printf 2819 and an abort()) if there are no catch buffers on the stack. 2820 objc_exception_extract just reads the exception pointer out of the 2821 catch buffer. 2822 2823 There's no reason an implementation couldn't use a light-weight 2824 setjmp here --- something like __builtin_setjmp, but API-compatible 2825 with the heavyweight setjmp. This will be more important if we ever 2826 want to implement correct ObjC/C++ exception interactions for the 2827 fragile ABI. 2828 2829 Note that for this use of setjmp/longjmp to be correct, we may need 2830 to mark some local variables volatile: if a non-volatile local 2831 variable is modified between the setjmp and the longjmp, it has 2832 indeterminate value. For the purposes of LLVM IR, it may be 2833 sufficient to make loads and stores within the @try (to variables 2834 declared outside the @try) volatile. This is necessary for 2835 optimized correctness, but is not currently being done; this is 2836 being tracked as rdar://problem/8160285 2837 2838 The basic framework for a @try-catch-finally is as follows: 2839 { 2840 objc_exception_data d; 2841 id _rethrow = null; 2842 bool _call_try_exit = true; 2843 2844 objc_exception_try_enter(&d); 2845 if (!setjmp(d.jmp_buf)) { 2846 ... try body ... 2847 } else { 2848 // exception path 2849 id _caught = objc_exception_extract(&d); 2850 2851 // enter new try scope for handlers 2852 if (!setjmp(d.jmp_buf)) { 2853 ... match exception and execute catch blocks ... 2854 2855 // fell off end, rethrow. 2856 _rethrow = _caught; 2857 ... jump-through-finally to finally_rethrow ... 2858 } else { 2859 // exception in catch block 2860 _rethrow = objc_exception_extract(&d); 2861 _call_try_exit = false; 2862 ... jump-through-finally to finally_rethrow ... 2863 } 2864 } 2865 ... jump-through-finally to finally_end ... 2866 2867 finally: 2868 if (_call_try_exit) 2869 objc_exception_try_exit(&d); 2870 2871 ... finally block .... 2872 ... dispatch to finally destination ... 2873 2874 finally_rethrow: 2875 objc_exception_throw(_rethrow); 2876 2877 finally_end: 2878 } 2879 2880 This framework differs slightly from the one gcc uses, in that gcc 2881 uses _rethrow to determine if objc_exception_try_exit should be called 2882 and if the object should be rethrown. This breaks in the face of 2883 throwing nil and introduces unnecessary branches. 2884 2885 We specialize this framework for a few particular circumstances: 2886 2887 - If there are no catch blocks, then we avoid emitting the second 2888 exception handling context. 2889 2890 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id 2891 e)) we avoid emitting the code to rethrow an uncaught exception. 2892 2893 - FIXME: If there is no @finally block we can do a few more 2894 simplifications. 2895 2896 Rethrows and Jumps-Through-Finally 2897 -- 2898 2899 '@throw;' is supported by pushing the currently-caught exception 2900 onto ObjCEHStack while the @catch blocks are emitted. 2901 2902 Branches through the @finally block are handled with an ordinary 2903 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC 2904 exceptions are not compatible with C++ exceptions, and this is 2905 hardly the only place where this will go wrong. 2906 2907 @synchronized(expr) { stmt; } is emitted as if it were: 2908 id synch_value = expr; 2909 objc_sync_enter(synch_value); 2910 @try { stmt; } @finally { objc_sync_exit(synch_value); } 2911*/ 2912 2913void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 2914 const Stmt &S) { 2915 bool isTry = isa<ObjCAtTryStmt>(S); 2916 2917 // A destination for the fall-through edges of the catch handlers to 2918 // jump to. 2919 CodeGenFunction::JumpDest FinallyEnd = 2920 CGF.getJumpDestInCurrentScope("finally.end"); 2921 2922 // A destination for the rethrow edge of the catch handlers to jump 2923 // to. 2924 CodeGenFunction::JumpDest FinallyRethrow = 2925 CGF.getJumpDestInCurrentScope("finally.rethrow"); 2926 2927 // For @synchronized, call objc_sync_enter(sync.expr). The 2928 // evaluation of the expression must occur before we enter the 2929 // @synchronized. We can't avoid a temp here because we need the 2930 // value to be preserved. If the backend ever does liveness 2931 // correctly after setjmp, this will be unnecessary. 2932 llvm::Value *SyncArgSlot = 0; 2933 if (!isTry) { 2934 llvm::Value *SyncArg = 2935 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 2936 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy); 2937 CGF.Builder.CreateCall(ObjCTypes.getSyncEnterFn(), SyncArg) 2938 ->setDoesNotThrow(); 2939 2940 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg"); 2941 CGF.Builder.CreateStore(SyncArg, SyncArgSlot); 2942 } 2943 2944 // Allocate memory for the setjmp buffer. This needs to be kept 2945 // live throughout the try and catch blocks. 2946 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 2947 "exceptiondata.ptr"); 2948 2949 // Create the fragile hazards. Note that this will not capture any 2950 // of the allocas required for exception processing, but will 2951 // capture the current basic block (which extends all the way to the 2952 // setjmp call) as "before the @try". 2953 FragileHazards Hazards(CGF); 2954 2955 // Create a flag indicating whether the cleanup needs to call 2956 // objc_exception_try_exit. This is true except when 2957 // - no catches match and we're branching through the cleanup 2958 // just to rethrow the exception, or 2959 // - a catch matched and we're falling out of the catch handler. 2960 // The setjmp-safety rule here is that we should always store to this 2961 // variable in a place that dominates the branch through the cleanup 2962 // without passing through any setjmps. 2963 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), 2964 "_call_try_exit"); 2965 2966 // Push a normal cleanup to leave the try scope. 2967 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalCleanup, &S, 2968 SyncArgSlot, 2969 CallTryExitVar, 2970 ExceptionData, 2971 &ObjCTypes); 2972 2973 // Enter a try block: 2974 // - Call objc_exception_try_enter to push ExceptionData on top of 2975 // the EH stack. 2976 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 2977 ->setDoesNotThrow(); 2978 2979 // - Call setjmp on the exception data buffer. 2980 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0); 2981 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero }; 2982 llvm::Value *SetJmpBuffer = 2983 CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, GEPIndexes+3, "setjmp_buffer"); 2984 llvm::CallInst *SetJmpResult = 2985 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result"); 2986 SetJmpResult->setDoesNotThrow(); 2987 2988 // If setjmp returned 0, enter the protected block; otherwise, 2989 // branch to the handler. 2990 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 2991 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 2992 llvm::Value *DidCatch = 2993 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 2994 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock); 2995 2996 // Emit the protected block. 2997 CGF.EmitBlock(TryBlock); 2998 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 2999 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 3000 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 3001 3002 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP(); 3003 3004 // Emit the exception handler block. 3005 CGF.EmitBlock(TryHandler); 3006 3007 // Don't optimize loads of the in-scope locals across this point. 3008 Hazards.emitWriteHazard(); 3009 3010 // For a @synchronized (or a @try with no catches), just branch 3011 // through the cleanup to the rethrow block. 3012 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) { 3013 // Tell the cleanup not to re-pop the exit. 3014 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 3015 CGF.EmitBranchThroughCleanup(FinallyRethrow); 3016 3017 // Otherwise, we have to match against the caught exceptions. 3018 } else { 3019 // Retrieve the exception object. We may emit multiple blocks but 3020 // nothing can cross this so the value is already in SSA form. 3021 llvm::CallInst *Caught = 3022 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 3023 ExceptionData, "caught"); 3024 Caught->setDoesNotThrow(); 3025 3026 // Push the exception to rethrow onto the EH value stack for the 3027 // benefit of any @throws in the handlers. 3028 CGF.ObjCEHValueStack.push_back(Caught); 3029 3030 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S); 3031 3032 bool HasFinally = (AtTryStmt->getFinallyStmt() != 0); 3033 3034 llvm::BasicBlock *CatchBlock = 0; 3035 llvm::BasicBlock *CatchHandler = 0; 3036 if (HasFinally) { 3037 // Enter a new exception try block (in case a @catch block 3038 // throws an exception). 3039 CGF.Builder.CreateCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData) 3040 ->setDoesNotThrow(); 3041 3042 llvm::CallInst *SetJmpResult = 3043 CGF.Builder.CreateCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, 3044 "setjmp.result"); 3045 SetJmpResult->setDoesNotThrow(); 3046 3047 llvm::Value *Threw = 3048 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception"); 3049 3050 CatchBlock = CGF.createBasicBlock("catch"); 3051 CatchHandler = CGF.createBasicBlock("catch_for_catch"); 3052 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock); 3053 3054 CGF.EmitBlock(CatchBlock); 3055 } 3056 3057 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar); 3058 3059 // Handle catch list. As a special case we check if everything is 3060 // matched and avoid generating code for falling off the end if 3061 // so. 3062 bool AllMatched = false; 3063 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) { 3064 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I); 3065 3066 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl(); 3067 const ObjCObjectPointerType *OPT = 0; 3068 3069 // catch(...) always matches. 3070 if (!CatchParam) { 3071 AllMatched = true; 3072 } else { 3073 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>(); 3074 3075 // catch(id e) always matches under this ABI, since only 3076 // ObjC exceptions end up here in the first place. 3077 // FIXME: For the time being we also match id<X>; this should 3078 // be rejected by Sema instead. 3079 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())) 3080 AllMatched = true; 3081 } 3082 3083 // If this is a catch-all, we don't need to test anything. 3084 if (AllMatched) { 3085 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 3086 3087 if (CatchParam) { 3088 CGF.EmitLocalBlockVarDecl(*CatchParam); 3089 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 3090 3091 // These types work out because ConvertType(id) == i8*. 3092 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam)); 3093 } 3094 3095 CGF.EmitStmt(CatchStmt->getCatchBody()); 3096 3097 // The scope of the catch variable ends right here. 3098 CatchVarCleanups.ForceCleanup(); 3099 3100 CGF.EmitBranchThroughCleanup(FinallyEnd); 3101 break; 3102 } 3103 3104 assert(OPT && "Unexpected non-object pointer type in @catch"); 3105 const ObjCObjectType *ObjTy = OPT->getObjectType(); 3106 3107 // FIXME: @catch (Class c) ? 3108 ObjCInterfaceDecl *IDecl = ObjTy->getInterface(); 3109 assert(IDecl && "Catch parameter must have Objective-C type!"); 3110 3111 // Check if the @catch block matches the exception object. 3112 llvm::Value *Class = EmitClassRef(CGF.Builder, IDecl); 3113 3114 llvm::CallInst *Match = 3115 CGF.Builder.CreateCall2(ObjCTypes.getExceptionMatchFn(), 3116 Class, Caught, "match"); 3117 Match->setDoesNotThrow(); 3118 3119 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match"); 3120 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next"); 3121 3122 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"), 3123 MatchedBlock, NextCatchBlock); 3124 3125 // Emit the @catch block. 3126 CGF.EmitBlock(MatchedBlock); 3127 3128 // Collect any cleanups for the catch variable. The scope lasts until 3129 // the end of the catch body. 3130 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF); 3131 3132 CGF.EmitLocalBlockVarDecl(*CatchParam); 3133 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 3134 3135 // Initialize the catch variable. 3136 llvm::Value *Tmp = 3137 CGF.Builder.CreateBitCast(Caught, 3138 CGF.ConvertType(CatchParam->getType()), 3139 "tmp"); 3140 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam)); 3141 3142 CGF.EmitStmt(CatchStmt->getCatchBody()); 3143 3144 // We're done with the catch variable. 3145 CatchVarCleanups.ForceCleanup(); 3146 3147 CGF.EmitBranchThroughCleanup(FinallyEnd); 3148 3149 CGF.EmitBlock(NextCatchBlock); 3150 } 3151 3152 CGF.ObjCEHValueStack.pop_back(); 3153 3154 // If nothing wanted anything to do with the caught exception, 3155 // kill the extract call. 3156 if (Caught->use_empty()) 3157 Caught->eraseFromParent(); 3158 3159 if (!AllMatched) 3160 CGF.EmitBranchThroughCleanup(FinallyRethrow); 3161 3162 if (HasFinally) { 3163 // Emit the exception handler for the @catch blocks. 3164 CGF.EmitBlock(CatchHandler); 3165 3166 // In theory we might now need a write hazard, but actually it's 3167 // unnecessary because there's no local-accessing code between 3168 // the try's write hazard and here. 3169 //Hazards.emitWriteHazard(); 3170 3171 // Don't pop the catch handler; the throw already did. 3172 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar); 3173 CGF.EmitBranchThroughCleanup(FinallyRethrow); 3174 } 3175 } 3176 3177 // Insert read hazards as required in the new blocks. 3178 Hazards.emitHazardsInNewBlocks(); 3179 3180 // Pop the cleanup. 3181 CGF.Builder.restoreIP(TryFallthroughIP); 3182 if (CGF.HaveInsertPoint()) 3183 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar); 3184 CGF.PopCleanupBlock(); 3185 CGF.EmitBlock(FinallyEnd.getBlock(), true); 3186 3187 // Emit the rethrow block. 3188 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP(); 3189 CGF.EmitBlock(FinallyRethrow.getBlock(), true); 3190 if (CGF.HaveInsertPoint()) { 3191 // Just look in the buffer for the exception to throw. 3192 llvm::CallInst *Caught = 3193 CGF.Builder.CreateCall(ObjCTypes.getExceptionExtractFn(), 3194 ExceptionData); 3195 Caught->setDoesNotThrow(); 3196 3197 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), Caught) 3198 ->setDoesNotThrow(); 3199 CGF.Builder.CreateUnreachable(); 3200 } 3201 3202 CGF.Builder.restoreIP(SavedIP); 3203} 3204 3205void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 3206 const ObjCAtThrowStmt &S) { 3207 llvm::Value *ExceptionAsObject; 3208 3209 if (const Expr *ThrowExpr = S.getThrowExpr()) { 3210 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 3211 ExceptionAsObject = 3212 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp"); 3213 } else { 3214 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) && 3215 "Unexpected rethrow outside @catch block."); 3216 ExceptionAsObject = CGF.ObjCEHValueStack.back(); 3217 } 3218 3219 CGF.Builder.CreateCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject) 3220 ->setDoesNotReturn(); 3221 CGF.Builder.CreateUnreachable(); 3222 3223 // Clear the insertion point to indicate we are in unreachable code. 3224 CGF.Builder.ClearInsertionPoint(); 3225} 3226 3227/// EmitObjCWeakRead - Code gen for loading value of a __weak 3228/// object: objc_read_weak (id *src) 3229/// 3230llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 3231 llvm::Value *AddrWeakObj) { 3232 const llvm::Type* DestTy = 3233 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 3234 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, 3235 ObjCTypes.PtrObjectPtrTy); 3236 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 3237 AddrWeakObj, "weakread"); 3238 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 3239 return read_weak; 3240} 3241 3242/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 3243/// objc_assign_weak (id src, id *dst) 3244/// 3245void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 3246 llvm::Value *src, llvm::Value *dst) { 3247 const llvm::Type * SrcTy = src->getType(); 3248 if (!isa<llvm::PointerType>(SrcTy)) { 3249 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 3250 assert(Size <= 8 && "does not support size > 8"); 3251 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 3252 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 3253 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 3254 } 3255 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3256 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3257 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 3258 src, dst, "weakassign"); 3259 return; 3260} 3261 3262/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 3263/// objc_assign_global (id src, id *dst) 3264/// 3265void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 3266 llvm::Value *src, llvm::Value *dst, 3267 bool threadlocal) { 3268 const llvm::Type * SrcTy = src->getType(); 3269 if (!isa<llvm::PointerType>(SrcTy)) { 3270 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 3271 assert(Size <= 8 && "does not support size > 8"); 3272 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 3273 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 3274 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 3275 } 3276 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3277 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3278 if (!threadlocal) 3279 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 3280 src, dst, "globalassign"); 3281 else 3282 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 3283 src, dst, "threadlocalassign"); 3284 return; 3285} 3286 3287/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 3288/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset) 3289/// 3290void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 3291 llvm::Value *src, llvm::Value *dst, 3292 llvm::Value *ivarOffset) { 3293 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL"); 3294 const llvm::Type * SrcTy = src->getType(); 3295 if (!isa<llvm::PointerType>(SrcTy)) { 3296 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 3297 assert(Size <= 8 && "does not support size > 8"); 3298 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 3299 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 3300 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 3301 } 3302 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3303 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3304 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 3305 src, dst, ivarOffset); 3306 return; 3307} 3308 3309/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 3310/// objc_assign_strongCast (id src, id *dst) 3311/// 3312void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 3313 llvm::Value *src, llvm::Value *dst) { 3314 const llvm::Type * SrcTy = src->getType(); 3315 if (!isa<llvm::PointerType>(SrcTy)) { 3316 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 3317 assert(Size <= 8 && "does not support size > 8"); 3318 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 3319 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy); 3320 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 3321 } 3322 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 3323 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 3324 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 3325 src, dst, "weakassign"); 3326 return; 3327} 3328 3329void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF, 3330 llvm::Value *DestPtr, 3331 llvm::Value *SrcPtr, 3332 llvm::Value *size) { 3333 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 3334 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 3335 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 3336 DestPtr, SrcPtr, size); 3337 return; 3338} 3339 3340/// EmitObjCValueForIvar - Code Gen for ivar reference. 3341/// 3342LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, 3343 QualType ObjectTy, 3344 llvm::Value *BaseValue, 3345 const ObjCIvarDecl *Ivar, 3346 unsigned CVRQualifiers) { 3347 const ObjCInterfaceDecl *ID = 3348 ObjectTy->getAs<ObjCObjectType>()->getInterface(); 3349 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 3350 EmitIvarOffset(CGF, ID, Ivar)); 3351} 3352 3353llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF, 3354 const ObjCInterfaceDecl *Interface, 3355 const ObjCIvarDecl *Ivar) { 3356 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar); 3357 return llvm::ConstantInt::get( 3358 CGM.getTypes().ConvertType(CGM.getContext().LongTy), 3359 Offset); 3360} 3361 3362/* *** Private Interface *** */ 3363 3364/// EmitImageInfo - Emit the image info marker used to encode some module 3365/// level information. 3366/// 3367/// See: <rdr://4810609&4810587&4810587> 3368/// struct IMAGE_INFO { 3369/// unsigned version; 3370/// unsigned flags; 3371/// }; 3372enum ImageInfoFlags { 3373 eImageInfo_FixAndContinue = (1 << 0), 3374 eImageInfo_GarbageCollected = (1 << 1), 3375 eImageInfo_GCOnly = (1 << 2), 3376 eImageInfo_OptimizedByDyld = (1 << 3), // FIXME: When is this set. 3377 3378 // A flag indicating that the module has no instances of a @synthesize of a 3379 // superclass variable. <rdar://problem/6803242> 3380 eImageInfo_CorrectedSynthesize = (1 << 4) 3381}; 3382 3383void CGObjCCommonMac::EmitImageInfo() { 3384 unsigned version = 0; // Version is unused? 3385 unsigned flags = 0; 3386 3387 // FIXME: Fix and continue? 3388 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 3389 flags |= eImageInfo_GarbageCollected; 3390 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 3391 flags |= eImageInfo_GCOnly; 3392 3393 // We never allow @synthesize of a superclass property. 3394 flags |= eImageInfo_CorrectedSynthesize; 3395 3396 const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext); 3397 3398 // Emitted as int[2]; 3399 llvm::Constant *values[2] = { 3400 llvm::ConstantInt::get(Int32Ty, version), 3401 llvm::ConstantInt::get(Int32Ty, flags) 3402 }; 3403 llvm::ArrayType *AT = llvm::ArrayType::get(Int32Ty, 2); 3404 3405 const char *Section; 3406 if (ObjCABI == 1) 3407 Section = "__OBJC, __image_info,regular"; 3408 else 3409 Section = "__DATA, __objc_imageinfo, regular, no_dead_strip"; 3410 llvm::GlobalVariable *GV = 3411 CreateMetadataVar("\01L_OBJC_IMAGE_INFO", 3412 llvm::ConstantArray::get(AT, values, 2), 3413 Section, 3414 0, 3415 true); 3416 GV->setConstant(true); 3417} 3418 3419 3420// struct objc_module { 3421// unsigned long version; 3422// unsigned long size; 3423// const char *name; 3424// Symtab symtab; 3425// }; 3426 3427// FIXME: Get from somewhere 3428static const int ModuleVersion = 7; 3429 3430void CGObjCMac::EmitModuleInfo() { 3431 uint64_t Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.ModuleTy); 3432 3433 std::vector<llvm::Constant*> Values(4); 3434 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion); 3435 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 3436 // This used to be the filename, now it is unused. <rdr://4327263> 3437 Values[2] = GetClassName(&CGM.getContext().Idents.get("")); 3438 Values[3] = EmitModuleSymbols(); 3439 CreateMetadataVar("\01L_OBJC_MODULES", 3440 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values), 3441 "__OBJC,__module_info,regular,no_dead_strip", 3442 4, true); 3443} 3444 3445llvm::Constant *CGObjCMac::EmitModuleSymbols() { 3446 unsigned NumClasses = DefinedClasses.size(); 3447 unsigned NumCategories = DefinedCategories.size(); 3448 3449 // Return null if no symbols were defined. 3450 if (!NumClasses && !NumCategories) 3451 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 3452 3453 std::vector<llvm::Constant*> Values(5); 3454 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 3455 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 3456 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 3457 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 3458 3459 // The runtime expects exactly the list of defined classes followed 3460 // by the list of defined categories, in a single array. 3461 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories); 3462 for (unsigned i=0; i<NumClasses; i++) 3463 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 3464 ObjCTypes.Int8PtrTy); 3465 for (unsigned i=0; i<NumCategories; i++) 3466 Symbols[NumClasses + i] = 3467 llvm::ConstantExpr::getBitCast(DefinedCategories[i], 3468 ObjCTypes.Int8PtrTy); 3469 3470 Values[4] = 3471 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 3472 NumClasses + NumCategories), 3473 Symbols); 3474 3475 llvm::Constant *Init = llvm::ConstantStruct::get(VMContext, Values, false); 3476 3477 llvm::GlobalVariable *GV = 3478 CreateMetadataVar("\01L_OBJC_SYMBOLS", Init, 3479 "__OBJC,__symbols,regular,no_dead_strip", 3480 4, true); 3481 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 3482} 3483 3484llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder, 3485 const ObjCInterfaceDecl *ID) { 3486 LazySymbols.insert(ID->getIdentifier()); 3487 3488 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; 3489 3490 if (!Entry) { 3491 llvm::Constant *Casted = 3492 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()), 3493 ObjCTypes.ClassPtrTy); 3494 Entry = 3495 CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted, 3496 "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 3497 4, true); 3498 } 3499 3500 return Builder.CreateLoad(Entry, "tmp"); 3501} 3502 3503llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel, 3504 bool lvalue) { 3505 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 3506 3507 if (!Entry) { 3508 llvm::Constant *Casted = 3509 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 3510 ObjCTypes.SelectorPtrTy); 3511 Entry = 3512 CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted, 3513 "__OBJC,__message_refs,literal_pointers,no_dead_strip", 3514 4, true); 3515 } 3516 3517 if (lvalue) 3518 return Entry; 3519 return Builder.CreateLoad(Entry, "tmp"); 3520} 3521 3522llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 3523 llvm::GlobalVariable *&Entry = ClassNames[Ident]; 3524 3525 if (!Entry) 3526 Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 3527 llvm::ConstantArray::get(VMContext, 3528 Ident->getNameStart()), 3529 "__TEXT,__cstring,cstring_literals", 3530 1, true); 3531 3532 return getConstantGEP(VMContext, Entry, 0, 0); 3533} 3534 3535llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) { 3536 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator 3537 I = MethodDefinitions.find(MD); 3538 if (I != MethodDefinitions.end()) 3539 return I->second; 3540 3541 if (MD->hasBody() && MD->getPCHLevel() > 0) { 3542 // MD isn't emitted yet because it comes from PCH. 3543 CGM.EmitTopLevelDecl(const_cast<ObjCMethodDecl*>(MD)); 3544 assert(MethodDefinitions[MD] && "EmitTopLevelDecl didn't emit the method!"); 3545 return MethodDefinitions[MD]; 3546 } 3547 3548 return NULL; 3549} 3550 3551/// GetIvarLayoutName - Returns a unique constant for the given 3552/// ivar layout bitmap. 3553llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident, 3554 const ObjCCommonTypesHelper &ObjCTypes) { 3555 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 3556} 3557 3558void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT, 3559 unsigned int BytePos, 3560 bool ForStrongLayout, 3561 bool &HasUnion) { 3562 const RecordDecl *RD = RT->getDecl(); 3563 // FIXME - Use iterator. 3564 llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end()); 3565 const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0)); 3566 const llvm::StructLayout *RecLayout = 3567 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty)); 3568 3569 BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos, 3570 ForStrongLayout, HasUnion); 3571} 3572 3573void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI, 3574 const llvm::StructLayout *Layout, 3575 const RecordDecl *RD, 3576 const llvm::SmallVectorImpl<FieldDecl*> &RecFields, 3577 unsigned int BytePos, bool ForStrongLayout, 3578 bool &HasUnion) { 3579 bool IsUnion = (RD && RD->isUnion()); 3580 uint64_t MaxUnionIvarSize = 0; 3581 uint64_t MaxSkippedUnionIvarSize = 0; 3582 FieldDecl *MaxField = 0; 3583 FieldDecl *MaxSkippedField = 0; 3584 FieldDecl *LastFieldBitfield = 0; 3585 uint64_t MaxFieldOffset = 0; 3586 uint64_t MaxSkippedFieldOffset = 0; 3587 uint64_t LastBitfieldOffset = 0; 3588 3589 if (RecFields.empty()) 3590 return; 3591 unsigned WordSizeInBits = CGM.getContext().Target.getPointerWidth(0); 3592 unsigned ByteSizeInBits = CGM.getContext().Target.getCharWidth(); 3593 3594 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { 3595 FieldDecl *Field = RecFields[i]; 3596 uint64_t FieldOffset; 3597 if (RD) { 3598 // Note that 'i' here is actually the field index inside RD of Field, 3599 // although this dependency is hidden. 3600 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD); 3601 FieldOffset = RL.getFieldOffset(i) / 8; 3602 } else 3603 FieldOffset = ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)); 3604 3605 // Skip over unnamed or bitfields 3606 if (!Field->getIdentifier() || Field->isBitField()) { 3607 LastFieldBitfield = Field; 3608 LastBitfieldOffset = FieldOffset; 3609 continue; 3610 } 3611 3612 LastFieldBitfield = 0; 3613 QualType FQT = Field->getType(); 3614 if (FQT->isRecordType() || FQT->isUnionType()) { 3615 if (FQT->isUnionType()) 3616 HasUnion = true; 3617 3618 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(), 3619 BytePos + FieldOffset, 3620 ForStrongLayout, HasUnion); 3621 continue; 3622 } 3623 3624 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3625 const ConstantArrayType *CArray = 3626 dyn_cast_or_null<ConstantArrayType>(Array); 3627 uint64_t ElCount = CArray->getSize().getZExtValue(); 3628 assert(CArray && "only array with known element size is supported"); 3629 FQT = CArray->getElementType(); 3630 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { 3631 const ConstantArrayType *CArray = 3632 dyn_cast_or_null<ConstantArrayType>(Array); 3633 ElCount *= CArray->getSize().getZExtValue(); 3634 FQT = CArray->getElementType(); 3635 } 3636 3637 assert(!FQT->isUnionType() && 3638 "layout for array of unions not supported"); 3639 if (FQT->isRecordType()) { 3640 int OldIndex = IvarsInfo.size() - 1; 3641 int OldSkIndex = SkipIvars.size() -1; 3642 3643 const RecordType *RT = FQT->getAs<RecordType>(); 3644 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset, 3645 ForStrongLayout, HasUnion); 3646 3647 // Replicate layout information for each array element. Note that 3648 // one element is already done. 3649 uint64_t ElIx = 1; 3650 for (int FirstIndex = IvarsInfo.size() - 1, 3651 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) { 3652 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits; 3653 for (int i = OldIndex+1; i <= FirstIndex; ++i) 3654 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx, 3655 IvarsInfo[i].ivar_size)); 3656 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i) 3657 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx, 3658 SkipIvars[i].ivar_size)); 3659 } 3660 continue; 3661 } 3662 } 3663 // At this point, we are done with Record/Union and array there of. 3664 // For other arrays we are down to its element type. 3665 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT); 3666 3667 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType()); 3668 if ((ForStrongLayout && GCAttr == Qualifiers::Strong) 3669 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) { 3670 if (IsUnion) { 3671 uint64_t UnionIvarSize = FieldSize / WordSizeInBits; 3672 if (UnionIvarSize > MaxUnionIvarSize) { 3673 MaxUnionIvarSize = UnionIvarSize; 3674 MaxField = Field; 3675 MaxFieldOffset = FieldOffset; 3676 } 3677 } else { 3678 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset, 3679 FieldSize / WordSizeInBits)); 3680 } 3681 } else if ((ForStrongLayout && 3682 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)) 3683 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) { 3684 if (IsUnion) { 3685 // FIXME: Why the asymmetry? We divide by word size in bits on other 3686 // side. 3687 uint64_t UnionIvarSize = FieldSize; 3688 if (UnionIvarSize > MaxSkippedUnionIvarSize) { 3689 MaxSkippedUnionIvarSize = UnionIvarSize; 3690 MaxSkippedField = Field; 3691 MaxSkippedFieldOffset = FieldOffset; 3692 } 3693 } else { 3694 // FIXME: Why the asymmetry, we divide by byte size in bits here? 3695 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset, 3696 FieldSize / ByteSizeInBits)); 3697 } 3698 } 3699 } 3700 3701 if (LastFieldBitfield) { 3702 // Last field was a bitfield. Must update skip info. 3703 Expr *BitWidth = LastFieldBitfield->getBitWidth(); 3704 uint64_t BitFieldSize = 3705 BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue(); 3706 GC_IVAR skivar; 3707 skivar.ivar_bytepos = BytePos + LastBitfieldOffset; 3708 skivar.ivar_size = (BitFieldSize / ByteSizeInBits) 3709 + ((BitFieldSize % ByteSizeInBits) != 0); 3710 SkipIvars.push_back(skivar); 3711 } 3712 3713 if (MaxField) 3714 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset, 3715 MaxUnionIvarSize)); 3716 if (MaxSkippedField) 3717 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset, 3718 MaxSkippedUnionIvarSize)); 3719} 3720 3721/// BuildIvarLayoutBitmap - This routine is the horsework for doing all 3722/// the computations and returning the layout bitmap (for ivar or blocks) in 3723/// the given argument BitMap string container. Routine reads 3724/// two containers, IvarsInfo and SkipIvars which are assumed to be 3725/// filled already by the caller. 3726llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string& BitMap) { 3727 unsigned int WordsToScan, WordsToSkip; 3728 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 3729 3730 // Build the string of skip/scan nibbles 3731 llvm::SmallVector<SKIP_SCAN, 32> SkipScanIvars; 3732 unsigned int WordSize = 3733 CGM.getTypes().getTargetData().getTypeAllocSize(PtrTy); 3734 if (IvarsInfo[0].ivar_bytepos == 0) { 3735 WordsToSkip = 0; 3736 WordsToScan = IvarsInfo[0].ivar_size; 3737 } else { 3738 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize; 3739 WordsToScan = IvarsInfo[0].ivar_size; 3740 } 3741 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) { 3742 unsigned int TailPrevGCObjC = 3743 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize; 3744 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) { 3745 // consecutive 'scanned' object pointers. 3746 WordsToScan += IvarsInfo[i].ivar_size; 3747 } else { 3748 // Skip over 'gc'able object pointer which lay over each other. 3749 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos) 3750 continue; 3751 // Must skip over 1 or more words. We save current skip/scan values 3752 // and start a new pair. 3753 SKIP_SCAN SkScan; 3754 SkScan.skip = WordsToSkip; 3755 SkScan.scan = WordsToScan; 3756 SkipScanIvars.push_back(SkScan); 3757 3758 // Skip the hole. 3759 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize; 3760 SkScan.scan = 0; 3761 SkipScanIvars.push_back(SkScan); 3762 WordsToSkip = 0; 3763 WordsToScan = IvarsInfo[i].ivar_size; 3764 } 3765 } 3766 if (WordsToScan > 0) { 3767 SKIP_SCAN SkScan; 3768 SkScan.skip = WordsToSkip; 3769 SkScan.scan = WordsToScan; 3770 SkipScanIvars.push_back(SkScan); 3771 } 3772 3773 if (!SkipIvars.empty()) { 3774 unsigned int LastIndex = SkipIvars.size()-1; 3775 int LastByteSkipped = 3776 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size; 3777 LastIndex = IvarsInfo.size()-1; 3778 int LastByteScanned = 3779 IvarsInfo[LastIndex].ivar_bytepos + 3780 IvarsInfo[LastIndex].ivar_size * WordSize; 3781 // Compute number of bytes to skip at the tail end of the last ivar scanned. 3782 if (LastByteSkipped > LastByteScanned) { 3783 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize; 3784 SKIP_SCAN SkScan; 3785 SkScan.skip = TotalWords - (LastByteScanned/WordSize); 3786 SkScan.scan = 0; 3787 SkipScanIvars.push_back(SkScan); 3788 } 3789 } 3790 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced 3791 // as 0xMN. 3792 int SkipScan = SkipScanIvars.size()-1; 3793 for (int i = 0; i <= SkipScan; i++) { 3794 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0 3795 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) { 3796 // 0xM0 followed by 0x0N detected. 3797 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan; 3798 for (int j = i+1; j < SkipScan; j++) 3799 SkipScanIvars[j] = SkipScanIvars[j+1]; 3800 --SkipScan; 3801 } 3802 } 3803 3804 // Generate the string. 3805 for (int i = 0; i <= SkipScan; i++) { 3806 unsigned char byte; 3807 unsigned int skip_small = SkipScanIvars[i].skip % 0xf; 3808 unsigned int scan_small = SkipScanIvars[i].scan % 0xf; 3809 unsigned int skip_big = SkipScanIvars[i].skip / 0xf; 3810 unsigned int scan_big = SkipScanIvars[i].scan / 0xf; 3811 3812 // first skip big. 3813 for (unsigned int ix = 0; ix < skip_big; ix++) 3814 BitMap += (unsigned char)(0xf0); 3815 3816 // next (skip small, scan) 3817 if (skip_small) { 3818 byte = skip_small << 4; 3819 if (scan_big > 0) { 3820 byte |= 0xf; 3821 --scan_big; 3822 } else if (scan_small) { 3823 byte |= scan_small; 3824 scan_small = 0; 3825 } 3826 BitMap += byte; 3827 } 3828 // next scan big 3829 for (unsigned int ix = 0; ix < scan_big; ix++) 3830 BitMap += (unsigned char)(0x0f); 3831 // last scan small 3832 if (scan_small) { 3833 byte = scan_small; 3834 BitMap += byte; 3835 } 3836 } 3837 // null terminate string. 3838 unsigned char zero = 0; 3839 BitMap += zero; 3840 3841 llvm::GlobalVariable * Entry = 3842 CreateMetadataVar("\01L_OBJC_CLASS_NAME_", 3843 llvm::ConstantArray::get(VMContext, BitMap.c_str()), 3844 "__TEXT,__cstring,cstring_literals", 3845 1, true); 3846 return getConstantGEP(VMContext, Entry, 0, 0); 3847} 3848 3849/// BuildIvarLayout - Builds ivar layout bitmap for the class 3850/// implementation for the __strong or __weak case. 3851/// The layout map displays which words in ivar list must be skipped 3852/// and which must be scanned by GC (see below). String is built of bytes. 3853/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count 3854/// of words to skip and right nibble is count of words to scan. So, each 3855/// nibble represents up to 15 workds to skip or scan. Skipping the rest is 3856/// represented by a 0x00 byte which also ends the string. 3857/// 1. when ForStrongLayout is true, following ivars are scanned: 3858/// - id, Class 3859/// - object * 3860/// - __strong anything 3861/// 3862/// 2. When ForStrongLayout is false, following ivars are scanned: 3863/// - __weak anything 3864/// 3865llvm::Constant *CGObjCCommonMac::BuildIvarLayout( 3866 const ObjCImplementationDecl *OMD, 3867 bool ForStrongLayout) { 3868 bool hasUnion = false; 3869 3870 const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(VMContext); 3871 if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC) 3872 return llvm::Constant::getNullValue(PtrTy); 3873 3874 llvm::SmallVector<FieldDecl*, 32> RecFields; 3875 const ObjCInterfaceDecl *OI = OMD->getClassInterface(); 3876 CGM.getContext().CollectObjCIvars(OI, RecFields); 3877 3878 // Add this implementations synthesized ivars. 3879 llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 3880 CGM.getContext().CollectNonClassIvars(OI, Ivars); 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