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