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