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