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