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