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