CGObjCMac.cpp revision 4c86fdb84ff016ee708e71f563ffe2a1c1b96b26
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) { 4237 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 4238 ASTContext &Ctx = CGM.getContext(); 4239 4240 ShortTy = Types.ConvertType(Ctx.ShortTy); 4241 IntTy = Types.ConvertType(Ctx.IntTy); 4242 LongTy = Types.ConvertType(Ctx.LongTy); 4243 LongLongTy = Types.ConvertType(Ctx.LongLongTy); 4244 Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext); 4245 Int8PtrPtrTy = llvm::PointerType::getUnqual(Int8PtrTy); 4246 4247 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 4248 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); 4249 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 4250 4251 // I'm not sure I like this. The implicit coordination is a bit 4252 // gross. We should solve this in a reasonable fashion because this 4253 // is a pretty common task (match some runtime data structure with 4254 // an LLVM data structure). 4255 4256 // FIXME: This is leaked. 4257 // FIXME: Merge with rewriter code? 4258 4259 // struct _objc_super { 4260 // id self; 4261 // Class cls; 4262 // } 4263 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 4264 Ctx.getTranslationUnitDecl(), 4265 SourceLocation(), SourceLocation(), 4266 &Ctx.Idents.get("_objc_super")); 4267 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4268 Ctx.getObjCIdType(), 0, 0, false, false)); 4269 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4270 Ctx.getObjCClassType(), 0, 0, false, false)); 4271 RD->completeDefinition(); 4272 4273 SuperCTy = Ctx.getTagDeclType(RD); 4274 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 4275 4276 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 4277 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 4278 4279 // struct _prop_t { 4280 // char *name; 4281 // char *attributes; 4282 // } 4283 PropertyTy = llvm::StructType::create("struct._prop_t", 4284 Int8PtrTy, Int8PtrTy, NULL); 4285 4286 // struct _prop_list_t { 4287 // uint32_t entsize; // sizeof(struct _prop_t) 4288 // uint32_t count_of_properties; 4289 // struct _prop_t prop_list[count_of_properties]; 4290 // } 4291 PropertyListTy = 4292 llvm::StructType::create("struct._prop_list_t", IntTy, IntTy, 4293 llvm::ArrayType::get(PropertyTy, 0), NULL); 4294 // struct _prop_list_t * 4295 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 4296 4297 // struct _objc_method { 4298 // SEL _cmd; 4299 // char *method_type; 4300 // char *_imp; 4301 // } 4302 MethodTy = llvm::StructType::create("struct._objc_method", 4303 SelectorPtrTy, Int8PtrTy, Int8PtrTy, 4304 NULL); 4305 4306 // struct _objc_cache * 4307 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache"); 4308 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 4309 4310} 4311 4312ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 4313 : ObjCCommonTypesHelper(cgm) { 4314 // struct _objc_method_description { 4315 // SEL name; 4316 // char *types; 4317 // } 4318 MethodDescriptionTy = 4319 llvm::StructType::create("struct._objc_method_description", 4320 SelectorPtrTy, Int8PtrTy, NULL); 4321 4322 // struct _objc_method_description_list { 4323 // int count; 4324 // struct _objc_method_description[1]; 4325 // } 4326 MethodDescriptionListTy = 4327 llvm::StructType::create("struct._objc_method_description_list", 4328 IntTy, 4329 llvm::ArrayType::get(MethodDescriptionTy, 0),NULL); 4330 4331 // struct _objc_method_description_list * 4332 MethodDescriptionListPtrTy = 4333 llvm::PointerType::getUnqual(MethodDescriptionListTy); 4334 4335 // Protocol description structures 4336 4337 // struct _objc_protocol_extension { 4338 // uint32_t size; // sizeof(struct _objc_protocol_extension) 4339 // struct _objc_method_description_list *optional_instance_methods; 4340 // struct _objc_method_description_list *optional_class_methods; 4341 // struct _objc_property_list *instance_properties; 4342 // const char ** extendedMethodTypes; 4343 // } 4344 ProtocolExtensionTy = 4345 llvm::StructType::create("struct._objc_protocol_extension", 4346 IntTy, MethodDescriptionListPtrTy, 4347 MethodDescriptionListPtrTy, PropertyListPtrTy, 4348 Int8PtrPtrTy, NULL); 4349 4350 // struct _objc_protocol_extension * 4351 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 4352 4353 // Handle recursive construction of Protocol and ProtocolList types 4354 4355 ProtocolTy = 4356 llvm::StructType::create(VMContext, "struct._objc_protocol"); 4357 4358 ProtocolListTy = 4359 llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 4360 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), 4361 LongTy, 4362 llvm::ArrayType::get(ProtocolTy, 0), 4363 NULL); 4364 4365 // struct _objc_protocol { 4366 // struct _objc_protocol_extension *isa; 4367 // char *protocol_name; 4368 // struct _objc_protocol **_objc_protocol_list; 4369 // struct _objc_method_description_list *instance_methods; 4370 // struct _objc_method_description_list *class_methods; 4371 // } 4372 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy, 4373 llvm::PointerType::getUnqual(ProtocolListTy), 4374 MethodDescriptionListPtrTy, 4375 MethodDescriptionListPtrTy, 4376 NULL); 4377 4378 // struct _objc_protocol_list * 4379 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 4380 4381 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 4382 4383 // Class description structures 4384 4385 // struct _objc_ivar { 4386 // char *ivar_name; 4387 // char *ivar_type; 4388 // int ivar_offset; 4389 // } 4390 IvarTy = llvm::StructType::create("struct._objc_ivar", 4391 Int8PtrTy, Int8PtrTy, IntTy, NULL); 4392 4393 // struct _objc_ivar_list * 4394 IvarListTy = 4395 llvm::StructType::create(VMContext, "struct._objc_ivar_list"); 4396 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 4397 4398 // struct _objc_method_list * 4399 MethodListTy = 4400 llvm::StructType::create(VMContext, "struct._objc_method_list"); 4401 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 4402 4403 // struct _objc_class_extension * 4404 ClassExtensionTy = 4405 llvm::StructType::create("struct._objc_class_extension", 4406 IntTy, Int8PtrTy, PropertyListPtrTy, NULL); 4407 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 4408 4409 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class"); 4410 4411 // struct _objc_class { 4412 // Class isa; 4413 // Class super_class; 4414 // char *name; 4415 // long version; 4416 // long info; 4417 // long instance_size; 4418 // struct _objc_ivar_list *ivars; 4419 // struct _objc_method_list *methods; 4420 // struct _objc_cache *cache; 4421 // struct _objc_protocol_list *protocols; 4422 // char *ivar_layout; 4423 // struct _objc_class_ext *ext; 4424 // }; 4425 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy), 4426 llvm::PointerType::getUnqual(ClassTy), 4427 Int8PtrTy, 4428 LongTy, 4429 LongTy, 4430 LongTy, 4431 IvarListPtrTy, 4432 MethodListPtrTy, 4433 CachePtrTy, 4434 ProtocolListPtrTy, 4435 Int8PtrTy, 4436 ClassExtensionPtrTy, 4437 NULL); 4438 4439 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 4440 4441 // struct _objc_category { 4442 // char *category_name; 4443 // char *class_name; 4444 // struct _objc_method_list *instance_method; 4445 // struct _objc_method_list *class_method; 4446 // uint32_t size; // sizeof(struct _objc_category) 4447 // struct _objc_property_list *instance_properties;// category's @property 4448 // } 4449 CategoryTy = 4450 llvm::StructType::create("struct._objc_category", 4451 Int8PtrTy, Int8PtrTy, MethodListPtrTy, 4452 MethodListPtrTy, ProtocolListPtrTy, 4453 IntTy, PropertyListPtrTy, NULL); 4454 4455 // Global metadata structures 4456 4457 // struct _objc_symtab { 4458 // long sel_ref_cnt; 4459 // SEL *refs; 4460 // short cls_def_cnt; 4461 // short cat_def_cnt; 4462 // char *defs[cls_def_cnt + cat_def_cnt]; 4463 // } 4464 SymtabTy = 4465 llvm::StructType::create("struct._objc_symtab", 4466 LongTy, SelectorPtrTy, ShortTy, ShortTy, 4467 llvm::ArrayType::get(Int8PtrTy, 0), NULL); 4468 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 4469 4470 // struct _objc_module { 4471 // long version; 4472 // long size; // sizeof(struct _objc_module) 4473 // char *name; 4474 // struct _objc_symtab* symtab; 4475 // } 4476 ModuleTy = 4477 llvm::StructType::create("struct._objc_module", 4478 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL); 4479 4480 4481 // FIXME: This is the size of the setjmp buffer and should be target 4482 // specific. 18 is what's used on 32-bit X86. 4483 uint64_t SetJmpBufferSize = 18; 4484 4485 // Exceptions 4486 llvm::Type *StackPtrTy = llvm::ArrayType::get( 4487 llvm::Type::getInt8PtrTy(VMContext), 4); 4488 4489 ExceptionDataTy = 4490 llvm::StructType::create("struct._objc_exception_data", 4491 llvm::ArrayType::get(llvm::Type::getInt32Ty(VMContext), 4492 SetJmpBufferSize), 4493 StackPtrTy, NULL); 4494 4495} 4496 4497ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 4498 : ObjCCommonTypesHelper(cgm) { 4499 // struct _method_list_t { 4500 // uint32_t entsize; // sizeof(struct _objc_method) 4501 // uint32_t method_count; 4502 // struct _objc_method method_list[method_count]; 4503 // } 4504 MethodListnfABITy = 4505 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy, 4506 llvm::ArrayType::get(MethodTy, 0), NULL); 4507 // struct method_list_t * 4508 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 4509 4510 // struct _protocol_t { 4511 // id isa; // NULL 4512 // const char * const protocol_name; 4513 // const struct _protocol_list_t * protocol_list; // super protocols 4514 // const struct method_list_t * const instance_methods; 4515 // const struct method_list_t * const class_methods; 4516 // const struct method_list_t *optionalInstanceMethods; 4517 // const struct method_list_t *optionalClassMethods; 4518 // const struct _prop_list_t * properties; 4519 // const uint32_t size; // sizeof(struct _protocol_t) 4520 // const uint32_t flags; // = 0 4521 // const char ** extendedMethodTypes; 4522 // } 4523 4524 // Holder for struct _protocol_list_t * 4525 ProtocolListnfABITy = 4526 llvm::StructType::create(VMContext, "struct._objc_protocol_list"); 4527 4528 ProtocolnfABITy = 4529 llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy, 4530 llvm::PointerType::getUnqual(ProtocolListnfABITy), 4531 MethodListnfABIPtrTy, MethodListnfABIPtrTy, 4532 MethodListnfABIPtrTy, MethodListnfABIPtrTy, 4533 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, 4534 NULL); 4535 4536 // struct _protocol_t* 4537 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy); 4538 4539 // struct _protocol_list_t { 4540 // long protocol_count; // Note, this is 32/64 bit 4541 // struct _protocol_t *[protocol_count]; 4542 // } 4543 ProtocolListnfABITy->setBody(LongTy, 4544 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0), 4545 NULL); 4546 4547 // struct _objc_protocol_list* 4548 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 4549 4550 // struct _ivar_t { 4551 // unsigned long int *offset; // pointer to ivar offset location 4552 // char *name; 4553 // char *type; 4554 // uint32_t alignment; 4555 // uint32_t size; 4556 // } 4557 IvarnfABITy = 4558 llvm::StructType::create("struct._ivar_t", 4559 llvm::PointerType::getUnqual(LongTy), 4560 Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL); 4561 4562 // struct _ivar_list_t { 4563 // uint32 entsize; // sizeof(struct _ivar_t) 4564 // uint32 count; 4565 // struct _iver_t list[count]; 4566 // } 4567 IvarListnfABITy = 4568 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy, 4569 llvm::ArrayType::get(IvarnfABITy, 0), NULL); 4570 4571 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 4572 4573 // struct _class_ro_t { 4574 // uint32_t const flags; 4575 // uint32_t const instanceStart; 4576 // uint32_t const instanceSize; 4577 // uint32_t const reserved; // only when building for 64bit targets 4578 // const uint8_t * const ivarLayout; 4579 // const char *const name; 4580 // const struct _method_list_t * const baseMethods; 4581 // const struct _objc_protocol_list *const baseProtocols; 4582 // const struct _ivar_list_t *const ivars; 4583 // const uint8_t * const weakIvarLayout; 4584 // const struct _prop_list_t * const properties; 4585 // } 4586 4587 // FIXME. Add 'reserved' field in 64bit abi mode! 4588 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t", 4589 IntTy, IntTy, IntTy, Int8PtrTy, 4590 Int8PtrTy, MethodListnfABIPtrTy, 4591 ProtocolListnfABIPtrTy, 4592 IvarListnfABIPtrTy, 4593 Int8PtrTy, PropertyListPtrTy, NULL); 4594 4595 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 4596 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy }; 4597 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false) 4598 ->getPointerTo(); 4599 4600 // struct _class_t { 4601 // struct _class_t *isa; 4602 // struct _class_t * const superclass; 4603 // void *cache; 4604 // IMP *vtable; 4605 // struct class_ro_t *ro; 4606 // } 4607 4608 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t"); 4609 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy), 4610 llvm::PointerType::getUnqual(ClassnfABITy), 4611 CachePtrTy, 4612 llvm::PointerType::getUnqual(ImpnfABITy), 4613 llvm::PointerType::getUnqual(ClassRonfABITy), 4614 NULL); 4615 4616 // LLVM for struct _class_t * 4617 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 4618 4619 // struct _category_t { 4620 // const char * const name; 4621 // struct _class_t *const cls; 4622 // const struct _method_list_t * const instance_methods; 4623 // const struct _method_list_t * const class_methods; 4624 // const struct _protocol_list_t * const protocols; 4625 // const struct _prop_list_t * const properties; 4626 // } 4627 CategorynfABITy = llvm::StructType::create("struct._category_t", 4628 Int8PtrTy, ClassnfABIPtrTy, 4629 MethodListnfABIPtrTy, 4630 MethodListnfABIPtrTy, 4631 ProtocolListnfABIPtrTy, 4632 PropertyListPtrTy, 4633 NULL); 4634 4635 // New types for nonfragile abi messaging. 4636 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 4637 ASTContext &Ctx = CGM.getContext(); 4638 4639 // MessageRefTy - LLVM for: 4640 // struct _message_ref_t { 4641 // IMP messenger; 4642 // SEL name; 4643 // }; 4644 4645 // First the clang type for struct _message_ref_t 4646 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct, 4647 Ctx.getTranslationUnitDecl(), 4648 SourceLocation(), SourceLocation(), 4649 &Ctx.Idents.get("_message_ref_t")); 4650 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4651 Ctx.VoidPtrTy, 0, 0, false, false)); 4652 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0, 4653 Ctx.getObjCSelType(), 0, 0, false, false)); 4654 RD->completeDefinition(); 4655 4656 MessageRefCTy = Ctx.getTagDeclType(RD); 4657 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy); 4658 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy)); 4659 4660 // MessageRefPtrTy - LLVM for struct _message_ref_t* 4661 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy); 4662 4663 // SuperMessageRefTy - LLVM for: 4664 // struct _super_message_ref_t { 4665 // SUPER_IMP messenger; 4666 // SEL name; 4667 // }; 4668 SuperMessageRefTy = 4669 llvm::StructType::create("struct._super_message_ref_t", 4670 ImpnfABITy, SelectorPtrTy, NULL); 4671 4672 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t* 4673 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy); 4674 4675 4676 // struct objc_typeinfo { 4677 // const void** vtable; // objc_ehtype_vtable + 2 4678 // const char* name; // c++ typeinfo string 4679 // Class cls; 4680 // }; 4681 EHTypeTy = 4682 llvm::StructType::create("struct._objc_typeinfo", 4683 llvm::PointerType::getUnqual(Int8PtrTy), 4684 Int8PtrTy, ClassnfABIPtrTy, NULL); 4685 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy); 4686} 4687 4688llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 4689 FinishNonFragileABIModule(); 4690 4691 return NULL; 4692} 4693 4694void CGObjCNonFragileABIMac::AddModuleClassList(const 4695 std::vector<llvm::GlobalValue*> 4696 &Container, 4697 const char *SymbolName, 4698 const char *SectionName) { 4699 unsigned NumClasses = Container.size(); 4700 4701 if (!NumClasses) 4702 return; 4703 4704 std::vector<llvm::Constant*> Symbols(NumClasses); 4705 for (unsigned i=0; i<NumClasses; i++) 4706 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i], 4707 ObjCTypes.Int8PtrTy); 4708 llvm::Constant* Init = 4709 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 4710 NumClasses), 4711 Symbols); 4712 4713 llvm::GlobalVariable *GV = 4714 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 4715 llvm::GlobalValue::InternalLinkage, 4716 Init, 4717 SymbolName); 4718 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 4719 GV->setSection(SectionName); 4720 CGM.AddUsedGlobal(GV); 4721} 4722 4723void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 4724 // nonfragile abi has no module definition. 4725 4726 // Build list of all implemented class addresses in array 4727 // L_OBJC_LABEL_CLASS_$. 4728 AddModuleClassList(DefinedClasses, 4729 "\01L_OBJC_LABEL_CLASS_$", 4730 "__DATA, __objc_classlist, regular, no_dead_strip"); 4731 4732 for (unsigned i = 0; i < DefinedClasses.size(); i++) { 4733 llvm::GlobalValue *IMPLGV = DefinedClasses[i]; 4734 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 4735 continue; 4736 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 4737 } 4738 4739 for (unsigned i = 0; i < DefinedMetaClasses.size(); i++) { 4740 llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i]; 4741 if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage) 4742 continue; 4743 IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage); 4744 } 4745 4746 AddModuleClassList(DefinedNonLazyClasses, 4747 "\01L_OBJC_LABEL_NONLAZY_CLASS_$", 4748 "__DATA, __objc_nlclslist, regular, no_dead_strip"); 4749 4750 // Build list of all implemented category addresses in array 4751 // L_OBJC_LABEL_CATEGORY_$. 4752 AddModuleClassList(DefinedCategories, 4753 "\01L_OBJC_LABEL_CATEGORY_$", 4754 "__DATA, __objc_catlist, regular, no_dead_strip"); 4755 AddModuleClassList(DefinedNonLazyCategories, 4756 "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$", 4757 "__DATA, __objc_nlcatlist, regular, no_dead_strip"); 4758 4759 EmitImageInfo(); 4760} 4761 4762/// isVTableDispatchedSelector - Returns true if SEL is not in the list of 4763/// VTableDispatchMethods; false otherwise. What this means is that 4764/// except for the 19 selectors in the list, we generate 32bit-style 4765/// message dispatch call for all the rest. 4766bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) { 4767 // At various points we've experimented with using vtable-based 4768 // dispatch for all methods. 4769 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) { 4770 case CodeGenOptions::Legacy: 4771 return false; 4772 case CodeGenOptions::NonLegacy: 4773 return true; 4774 case CodeGenOptions::Mixed: 4775 break; 4776 } 4777 4778 // If so, see whether this selector is in the white-list of things which must 4779 // use the new dispatch convention. We lazily build a dense set for this. 4780 if (VTableDispatchMethods.empty()) { 4781 VTableDispatchMethods.insert(GetNullarySelector("alloc")); 4782 VTableDispatchMethods.insert(GetNullarySelector("class")); 4783 VTableDispatchMethods.insert(GetNullarySelector("self")); 4784 VTableDispatchMethods.insert(GetNullarySelector("isFlipped")); 4785 VTableDispatchMethods.insert(GetNullarySelector("length")); 4786 VTableDispatchMethods.insert(GetNullarySelector("count")); 4787 4788 // These are vtable-based if GC is disabled. 4789 // Optimistically use vtable dispatch for hybrid compiles. 4790 if (CGM.getLangOptions().getGC() != LangOptions::GCOnly) { 4791 VTableDispatchMethods.insert(GetNullarySelector("retain")); 4792 VTableDispatchMethods.insert(GetNullarySelector("release")); 4793 VTableDispatchMethods.insert(GetNullarySelector("autorelease")); 4794 } 4795 4796 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone")); 4797 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass")); 4798 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector")); 4799 VTableDispatchMethods.insert(GetUnarySelector("objectForKey")); 4800 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex")); 4801 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString")); 4802 VTableDispatchMethods.insert(GetUnarySelector("isEqual")); 4803 4804 // These are vtable-based if GC is enabled. 4805 // Optimistically use vtable dispatch for hybrid compiles. 4806 if (CGM.getLangOptions().getGC() != LangOptions::NonGC) { 4807 VTableDispatchMethods.insert(GetNullarySelector("hash")); 4808 VTableDispatchMethods.insert(GetUnarySelector("addObject")); 4809 4810 // "countByEnumeratingWithState:objects:count" 4811 IdentifierInfo *KeyIdents[] = { 4812 &CGM.getContext().Idents.get("countByEnumeratingWithState"), 4813 &CGM.getContext().Idents.get("objects"), 4814 &CGM.getContext().Idents.get("count") 4815 }; 4816 VTableDispatchMethods.insert( 4817 CGM.getContext().Selectors.getSelector(3, KeyIdents)); 4818 } 4819 } 4820 4821 return VTableDispatchMethods.count(Sel); 4822} 4823 4824// Metadata flags 4825enum MetaDataDlags { 4826 CLS = 0x0, 4827 CLS_META = 0x1, 4828 CLS_ROOT = 0x2, 4829 OBJC2_CLS_HIDDEN = 0x10, 4830 CLS_EXCEPTION = 0x20, 4831 4832 /// (Obsolete) ARC-specific: this class has a .release_ivars method 4833 CLS_HAS_IVAR_RELEASER = 0x40, 4834 /// class was compiled with -fobjc-arr 4835 CLS_COMPILED_BY_ARC = 0x80 // (1<<7) 4836}; 4837/// BuildClassRoTInitializer - generate meta-data for: 4838/// struct _class_ro_t { 4839/// uint32_t const flags; 4840/// uint32_t const instanceStart; 4841/// uint32_t const instanceSize; 4842/// uint32_t const reserved; // only when building for 64bit targets 4843/// const uint8_t * const ivarLayout; 4844/// const char *const name; 4845/// const struct _method_list_t * const baseMethods; 4846/// const struct _protocol_list_t *const baseProtocols; 4847/// const struct _ivar_list_t *const ivars; 4848/// const uint8_t * const weakIvarLayout; 4849/// const struct _prop_list_t * const properties; 4850/// } 4851/// 4852llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( 4853 unsigned flags, 4854 unsigned InstanceStart, 4855 unsigned InstanceSize, 4856 const ObjCImplementationDecl *ID) { 4857 std::string ClassName = ID->getNameAsString(); 4858 llvm::Constant *Values[10]; // 11 for 64bit targets! 4859 4860 if (CGM.getLangOptions().ObjCAutoRefCount) 4861 flags |= CLS_COMPILED_BY_ARC; 4862 4863 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 4864 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); 4865 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); 4866 // FIXME. For 64bit targets add 0 here. 4867 Values[ 3] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 4868 : BuildIvarLayout(ID, true); 4869 Values[ 4] = GetClassName(ID->getIdentifier()); 4870 // const struct _method_list_t * const baseMethods; 4871 std::vector<llvm::Constant*> Methods; 4872 std::string MethodListName("\01l_OBJC_$_"); 4873 if (flags & CLS_META) { 4874 MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); 4875 for (ObjCImplementationDecl::classmeth_iterator 4876 i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) { 4877 // Class methods should always be defined. 4878 Methods.push_back(GetMethodConstant(*i)); 4879 } 4880 } else { 4881 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); 4882 for (ObjCImplementationDecl::instmeth_iterator 4883 i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) { 4884 // Instance methods should always be defined. 4885 Methods.push_back(GetMethodConstant(*i)); 4886 } 4887 for (ObjCImplementationDecl::propimpl_iterator 4888 i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) { 4889 ObjCPropertyImplDecl *PID = *i; 4890 4891 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){ 4892 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 4893 4894 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 4895 if (llvm::Constant *C = GetMethodConstant(MD)) 4896 Methods.push_back(C); 4897 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 4898 if (llvm::Constant *C = GetMethodConstant(MD)) 4899 Methods.push_back(C); 4900 } 4901 } 4902 } 4903 Values[ 5] = EmitMethodList(MethodListName, 4904 "__DATA, __objc_const", Methods); 4905 4906 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 4907 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer"); 4908 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" 4909 + OID->getName(), 4910 OID->all_referenced_protocol_begin(), 4911 OID->all_referenced_protocol_end()); 4912 4913 if (flags & CLS_META) 4914 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 4915 else 4916 Values[ 7] = EmitIvarList(ID); 4917 Values[ 8] = (flags & CLS_META) ? GetIvarLayoutName(0, ObjCTypes) 4918 : BuildIvarLayout(ID, false); 4919 if (flags & CLS_META) 4920 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 4921 else 4922 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(), 4923 ID, ID->getClassInterface(), ObjCTypes); 4924 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, 4925 Values); 4926 llvm::GlobalVariable *CLASS_RO_GV = 4927 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false, 4928 llvm::GlobalValue::InternalLinkage, 4929 Init, 4930 (flags & CLS_META) ? 4931 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : 4932 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName); 4933 CLASS_RO_GV->setAlignment( 4934 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassRonfABITy)); 4935 CLASS_RO_GV->setSection("__DATA, __objc_const"); 4936 return CLASS_RO_GV; 4937 4938} 4939 4940/// BuildClassMetaData - This routine defines that to-level meta-data 4941/// for the given ClassName for: 4942/// struct _class_t { 4943/// struct _class_t *isa; 4944/// struct _class_t * const superclass; 4945/// void *cache; 4946/// IMP *vtable; 4947/// struct class_ro_t *ro; 4948/// } 4949/// 4950llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( 4951 std::string &ClassName, 4952 llvm::Constant *IsAGV, 4953 llvm::Constant *SuperClassGV, 4954 llvm::Constant *ClassRoGV, 4955 bool HiddenVisibility) { 4956 llvm::Constant *Values[] = { 4957 IsAGV, 4958 SuperClassGV, 4959 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar 4960 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar 4961 ClassRoGV // &CLASS_RO_GV 4962 }; 4963 if (!Values[1]) 4964 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); 4965 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, 4966 Values); 4967 llvm::GlobalVariable *GV = GetClassGlobal(ClassName); 4968 GV->setInitializer(Init); 4969 GV->setSection("__DATA, __objc_data"); 4970 GV->setAlignment( 4971 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ClassnfABITy)); 4972 if (HiddenVisibility) 4973 GV->setVisibility(llvm::GlobalValue::HiddenVisibility); 4974 return GV; 4975} 4976 4977bool 4978CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const { 4979 return OD->getClassMethod(GetNullarySelector("load")) != 0; 4980} 4981 4982void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID, 4983 uint32_t &InstanceStart, 4984 uint32_t &InstanceSize) { 4985 const ASTRecordLayout &RL = 4986 CGM.getContext().getASTObjCImplementationLayout(OID); 4987 4988 // InstanceSize is really instance end. 4989 InstanceSize = RL.getDataSize().getQuantity(); 4990 4991 // If there are no fields, the start is the same as the end. 4992 if (!RL.getFieldCount()) 4993 InstanceStart = InstanceSize; 4994 else 4995 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth(); 4996} 4997 4998void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 4999 std::string ClassName = ID->getNameAsString(); 5000 if (!ObjCEmptyCacheVar) { 5001 ObjCEmptyCacheVar = new llvm::GlobalVariable( 5002 CGM.getModule(), 5003 ObjCTypes.CacheTy, 5004 false, 5005 llvm::GlobalValue::ExternalLinkage, 5006 0, 5007 "_objc_empty_cache"); 5008 5009 ObjCEmptyVtableVar = new llvm::GlobalVariable( 5010 CGM.getModule(), 5011 ObjCTypes.ImpnfABITy, 5012 false, 5013 llvm::GlobalValue::ExternalLinkage, 5014 0, 5015 "_objc_empty_vtable"); 5016 } 5017 assert(ID->getClassInterface() && 5018 "CGObjCNonFragileABIMac::GenerateClass - class is 0"); 5019 // FIXME: Is this correct (that meta class size is never computed)? 5020 uint32_t InstanceStart = 5021 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ClassnfABITy); 5022 uint32_t InstanceSize = InstanceStart; 5023 uint32_t flags = CLS_META; 5024 std::string ObjCMetaClassName(getMetaclassSymbolPrefix()); 5025 std::string ObjCClassName(getClassSymbolPrefix()); 5026 5027 llvm::GlobalVariable *SuperClassGV, *IsAGV; 5028 5029 bool classIsHidden = 5030 ID->getClassInterface()->getVisibility() == HiddenVisibility; 5031 if (classIsHidden) 5032 flags |= OBJC2_CLS_HIDDEN; 5033 if (ID->hasCXXStructors()) 5034 flags |= eClassFlags_ABI2_HasCXXStructors; 5035 if (!ID->getClassInterface()->getSuperClass()) { 5036 // class is root 5037 flags |= CLS_ROOT; 5038 SuperClassGV = GetClassGlobal(ObjCClassName + ClassName); 5039 IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName); 5040 } else { 5041 // Has a root. Current class is not a root. 5042 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 5043 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 5044 Root = Super; 5045 IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString()); 5046 if (Root->isWeakImported()) 5047 IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5048 // work on super class metadata symbol. 5049 std::string SuperClassName = 5050 ObjCMetaClassName + 5051 ID->getClassInterface()->getSuperClass()->getNameAsString(); 5052 SuperClassGV = GetClassGlobal(SuperClassName); 5053 if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 5054 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5055 } 5056 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, 5057 InstanceStart, 5058 InstanceSize,ID); 5059 std::string TClassName = ObjCMetaClassName + ClassName; 5060 llvm::GlobalVariable *MetaTClass = 5061 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, 5062 classIsHidden); 5063 DefinedMetaClasses.push_back(MetaTClass); 5064 5065 // Metadata for the class 5066 flags = CLS; 5067 if (classIsHidden) 5068 flags |= OBJC2_CLS_HIDDEN; 5069 if (ID->hasCXXStructors()) 5070 flags |= eClassFlags_ABI2_HasCXXStructors; 5071 5072 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface())) 5073 flags |= CLS_EXCEPTION; 5074 5075 if (!ID->getClassInterface()->getSuperClass()) { 5076 flags |= CLS_ROOT; 5077 SuperClassGV = 0; 5078 } else { 5079 // Has a root. Current class is not a root. 5080 std::string RootClassName = 5081 ID->getClassInterface()->getSuperClass()->getNameAsString(); 5082 SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName); 5083 if (ID->getClassInterface()->getSuperClass()->isWeakImported()) 5084 SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5085 } 5086 GetClassSizeInfo(ID, InstanceStart, InstanceSize); 5087 CLASS_RO_GV = BuildClassRoTInitializer(flags, 5088 InstanceStart, 5089 InstanceSize, 5090 ID); 5091 5092 TClassName = ObjCClassName + ClassName; 5093 llvm::GlobalVariable *ClassMD = 5094 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, 5095 classIsHidden); 5096 DefinedClasses.push_back(ClassMD); 5097 5098 // Determine if this class is also "non-lazy". 5099 if (ImplementationIsNonLazy(ID)) 5100 DefinedNonLazyClasses.push_back(ClassMD); 5101 5102 // Force the definition of the EHType if necessary. 5103 if (flags & CLS_EXCEPTION) 5104 GetInterfaceEHType(ID->getClassInterface(), true); 5105 // Make sure method definition entries are all clear for next implementation. 5106 MethodDefinitions.clear(); 5107} 5108 5109/// GenerateProtocolRef - This routine is called to generate code for 5110/// a protocol reference expression; as in: 5111/// @code 5112/// @protocol(Proto1); 5113/// @endcode 5114/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1 5115/// which will hold address of the protocol meta-data. 5116/// 5117llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder, 5118 const ObjCProtocolDecl *PD) { 5119 5120 // This routine is called for @protocol only. So, we must build definition 5121 // of protocol's meta-data (not a reference to it!) 5122 // 5123 llvm::Constant *Init = 5124 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD), 5125 ObjCTypes.getExternalProtocolPtrTy()); 5126 5127 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_"); 5128 ProtocolName += PD->getName(); 5129 5130 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); 5131 if (PTGV) 5132 return Builder.CreateLoad(PTGV); 5133 PTGV = new llvm::GlobalVariable( 5134 CGM.getModule(), 5135 Init->getType(), false, 5136 llvm::GlobalValue::WeakAnyLinkage, 5137 Init, 5138 ProtocolName); 5139 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); 5140 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5141 CGM.AddUsedGlobal(PTGV); 5142 return Builder.CreateLoad(PTGV); 5143} 5144 5145/// GenerateCategory - Build metadata for a category implementation. 5146/// struct _category_t { 5147/// const char * const name; 5148/// struct _class_t *const cls; 5149/// const struct _method_list_t * const instance_methods; 5150/// const struct _method_list_t * const class_methods; 5151/// const struct _protocol_list_t * const protocols; 5152/// const struct _prop_list_t * const properties; 5153/// } 5154/// 5155void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 5156 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 5157 const char *Prefix = "\01l_OBJC_$_CATEGORY_"; 5158 std::string ExtCatName(Prefix + Interface->getNameAsString()+ 5159 "_$_" + OCD->getNameAsString()); 5160 std::string ExtClassName(getClassSymbolPrefix() + 5161 Interface->getNameAsString()); 5162 5163 llvm::Constant *Values[6]; 5164 Values[0] = GetClassName(OCD->getIdentifier()); 5165 // meta-class entry symbol 5166 llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName); 5167 if (Interface->isWeakImported()) 5168 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5169 5170 Values[1] = ClassGV; 5171 std::vector<llvm::Constant*> Methods; 5172 std::string MethodListName(Prefix); 5173 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + 5174 "_$_" + OCD->getNameAsString(); 5175 5176 for (ObjCCategoryImplDecl::instmeth_iterator 5177 i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) { 5178 // Instance methods should always be defined. 5179 Methods.push_back(GetMethodConstant(*i)); 5180 } 5181 5182 Values[2] = EmitMethodList(MethodListName, 5183 "__DATA, __objc_const", 5184 Methods); 5185 5186 MethodListName = Prefix; 5187 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + 5188 OCD->getNameAsString(); 5189 Methods.clear(); 5190 for (ObjCCategoryImplDecl::classmeth_iterator 5191 i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) { 5192 // Class methods should always be defined. 5193 Methods.push_back(GetMethodConstant(*i)); 5194 } 5195 5196 Values[3] = EmitMethodList(MethodListName, 5197 "__DATA, __objc_const", 5198 Methods); 5199 const ObjCCategoryDecl *Category = 5200 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 5201 if (Category) { 5202 llvm::SmallString<256> ExtName; 5203 llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_" 5204 << OCD->getName(); 5205 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 5206 + Interface->getName() + "_$_" 5207 + Category->getName(), 5208 Category->protocol_begin(), 5209 Category->protocol_end()); 5210 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(), 5211 OCD, Category, ObjCTypes); 5212 } else { 5213 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 5214 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 5215 } 5216 5217 llvm::Constant *Init = 5218 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 5219 Values); 5220 llvm::GlobalVariable *GCATV 5221 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy, 5222 false, 5223 llvm::GlobalValue::InternalLinkage, 5224 Init, 5225 ExtCatName); 5226 GCATV->setAlignment( 5227 CGM.getTargetData().getABITypeAlignment(ObjCTypes.CategorynfABITy)); 5228 GCATV->setSection("__DATA, __objc_const"); 5229 CGM.AddUsedGlobal(GCATV); 5230 DefinedCategories.push_back(GCATV); 5231 5232 // Determine if this category is also "non-lazy". 5233 if (ImplementationIsNonLazy(OCD)) 5234 DefinedNonLazyCategories.push_back(GCATV); 5235 // method definition entries must be clear for next implementation. 5236 MethodDefinitions.clear(); 5237} 5238 5239/// GetMethodConstant - Return a struct objc_method constant for the 5240/// given method if it has been defined. The result is null if the 5241/// method has not been defined. The return value has type MethodPtrTy. 5242llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( 5243 const ObjCMethodDecl *MD) { 5244 llvm::Function *Fn = GetMethodDefinition(MD); 5245 if (!Fn) 5246 return 0; 5247 5248 llvm::Constant *Method[] = { 5249 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 5250 ObjCTypes.SelectorPtrTy), 5251 GetMethodVarType(MD), 5252 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy) 5253 }; 5254 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 5255} 5256 5257/// EmitMethodList - Build meta-data for method declarations 5258/// struct _method_list_t { 5259/// uint32_t entsize; // sizeof(struct _objc_method) 5260/// uint32_t method_count; 5261/// struct _objc_method method_list[method_count]; 5262/// } 5263/// 5264llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList(Twine Name, 5265 const char *Section, 5266 const ConstantVector &Methods) { 5267 // Return null for empty list. 5268 if (Methods.empty()) 5269 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); 5270 5271 llvm::Constant *Values[3]; 5272 // sizeof(struct _objc_method) 5273 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.MethodTy); 5274 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5275 // method_count 5276 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 5277 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 5278 Methods.size()); 5279 Values[2] = llvm::ConstantArray::get(AT, Methods); 5280 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 5281 5282 llvm::GlobalVariable *GV = 5283 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5284 llvm::GlobalValue::InternalLinkage, Init, Name); 5285 GV->setAlignment(CGM.getTargetData().getABITypeAlignment(Init->getType())); 5286 GV->setSection(Section); 5287 CGM.AddUsedGlobal(GV); 5288 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy); 5289} 5290 5291/// ObjCIvarOffsetVariable - Returns the ivar offset variable for 5292/// the given ivar. 5293llvm::GlobalVariable * 5294CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID, 5295 const ObjCIvarDecl *Ivar) { 5296 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); 5297 std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() + 5298 '.' + Ivar->getNameAsString(); 5299 llvm::GlobalVariable *IvarOffsetGV = 5300 CGM.getModule().getGlobalVariable(Name); 5301 if (!IvarOffsetGV) 5302 IvarOffsetGV = 5303 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy, 5304 false, 5305 llvm::GlobalValue::ExternalLinkage, 5306 0, 5307 Name); 5308 return IvarOffsetGV; 5309} 5310 5311llvm::Constant * 5312CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID, 5313 const ObjCIvarDecl *Ivar, 5314 unsigned long int Offset) { 5315 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar); 5316 IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy, 5317 Offset)); 5318 IvarOffsetGV->setAlignment( 5319 CGM.getTargetData().getABITypeAlignment(ObjCTypes.LongTy)); 5320 5321 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as 5322 // well (i.e., in ObjCIvarOffsetVariable). 5323 if (Ivar->getAccessControl() == ObjCIvarDecl::Private || 5324 Ivar->getAccessControl() == ObjCIvarDecl::Package || 5325 ID->getVisibility() == HiddenVisibility) 5326 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5327 else 5328 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility); 5329 IvarOffsetGV->setSection("__DATA, __objc_ivar"); 5330 return IvarOffsetGV; 5331} 5332 5333/// EmitIvarList - Emit the ivar list for the given 5334/// implementation. The return value has type 5335/// IvarListnfABIPtrTy. 5336/// struct _ivar_t { 5337/// unsigned long int *offset; // pointer to ivar offset location 5338/// char *name; 5339/// char *type; 5340/// uint32_t alignment; 5341/// uint32_t size; 5342/// } 5343/// struct _ivar_list_t { 5344/// uint32 entsize; // sizeof(struct _ivar_t) 5345/// uint32 count; 5346/// struct _iver_t list[count]; 5347/// } 5348/// 5349 5350llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( 5351 const ObjCImplementationDecl *ID) { 5352 5353 std::vector<llvm::Constant*> Ivars; 5354 5355 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 5356 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); 5357 5358 // FIXME. Consolidate this with similar code in GenerateClass. 5359 5360 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin(); 5361 IVD; IVD = IVD->getNextIvar()) { 5362 // Ignore unnamed bit-fields. 5363 if (!IVD->getDeclName()) 5364 continue; 5365 llvm::Constant *Ivar[5]; 5366 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD, 5367 ComputeIvarBaseOffset(CGM, ID, IVD)); 5368 Ivar[1] = GetMethodVarName(IVD->getIdentifier()); 5369 Ivar[2] = GetMethodVarType(IVD); 5370 llvm::Type *FieldTy = 5371 CGM.getTypes().ConvertTypeForMem(IVD->getType()); 5372 unsigned Size = CGM.getTargetData().getTypeAllocSize(FieldTy); 5373 unsigned Align = CGM.getContext().getPreferredTypeAlign( 5374 IVD->getType().getTypePtr()) >> 3; 5375 Align = llvm::Log2_32(Align); 5376 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); 5377 // NOTE. Size of a bitfield does not match gcc's, because of the 5378 // way bitfields are treated special in each. But I am told that 5379 // 'size' for bitfield ivars is ignored by the runtime so it does 5380 // not matter. If it matters, there is enough info to get the 5381 // bitfield right! 5382 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5383 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); 5384 } 5385 // Return null for empty list. 5386 if (Ivars.empty()) 5387 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 5388 5389 llvm::Constant *Values[3]; 5390 unsigned Size = CGM.getTargetData().getTypeAllocSize(ObjCTypes.IvarnfABITy); 5391 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5392 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 5393 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, 5394 Ivars.size()); 5395 Values[2] = llvm::ConstantArray::get(AT, Ivars); 5396 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 5397 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; 5398 llvm::GlobalVariable *GV = 5399 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5400 llvm::GlobalValue::InternalLinkage, 5401 Init, 5402 Prefix + OID->getName()); 5403 GV->setAlignment( 5404 CGM.getTargetData().getABITypeAlignment(Init->getType())); 5405 GV->setSection("__DATA, __objc_const"); 5406 5407 CGM.AddUsedGlobal(GV); 5408 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy); 5409} 5410 5411llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( 5412 const ObjCProtocolDecl *PD) { 5413 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 5414 5415 if (!Entry) { 5416 // We use the initializer as a marker of whether this is a forward 5417 // reference or not. At module finalization we add the empty 5418 // contents for protocols which were referenced but never defined. 5419 Entry = 5420 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false, 5421 llvm::GlobalValue::ExternalLinkage, 5422 0, 5423 "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 5424 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 5425 } 5426 5427 return Entry; 5428} 5429 5430/// GetOrEmitProtocol - Generate the protocol meta-data: 5431/// @code 5432/// struct _protocol_t { 5433/// id isa; // NULL 5434/// const char * const protocol_name; 5435/// const struct _protocol_list_t * protocol_list; // super protocols 5436/// const struct method_list_t * const instance_methods; 5437/// const struct method_list_t * const class_methods; 5438/// const struct method_list_t *optionalInstanceMethods; 5439/// const struct method_list_t *optionalClassMethods; 5440/// const struct _prop_list_t * properties; 5441/// const uint32_t size; // sizeof(struct _protocol_t) 5442/// const uint32_t flags; // = 0 5443/// const char ** extendedMethodTypes; 5444/// } 5445/// @endcode 5446/// 5447 5448llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( 5449 const ObjCProtocolDecl *PD) { 5450 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 5451 5452 // Early exit if a defining object has already been generated. 5453 if (Entry && Entry->hasInitializer()) 5454 return Entry; 5455 5456 // Use the protocol definition, if there is one. 5457 if (const ObjCProtocolDecl *Def = PD->getDefinition()) 5458 PD = Def; 5459 5460 // Construct method lists. 5461 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 5462 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 5463 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt; 5464 for (ObjCProtocolDecl::instmeth_iterator 5465 i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) { 5466 ObjCMethodDecl *MD = *i; 5467 llvm::Constant *C = GetMethodDescriptionConstant(MD); 5468 if (!C) 5469 return GetOrEmitProtocolRef(PD); 5470 5471 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 5472 OptInstanceMethods.push_back(C); 5473 OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 5474 } else { 5475 InstanceMethods.push_back(C); 5476 MethodTypesExt.push_back(GetMethodVarType(MD, true)); 5477 } 5478 } 5479 5480 for (ObjCProtocolDecl::classmeth_iterator 5481 i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) { 5482 ObjCMethodDecl *MD = *i; 5483 llvm::Constant *C = GetMethodDescriptionConstant(MD); 5484 if (!C) 5485 return GetOrEmitProtocolRef(PD); 5486 5487 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 5488 OptClassMethods.push_back(C); 5489 OptMethodTypesExt.push_back(GetMethodVarType(MD, true)); 5490 } else { 5491 ClassMethods.push_back(C); 5492 MethodTypesExt.push_back(GetMethodVarType(MD, true)); 5493 } 5494 } 5495 5496 MethodTypesExt.insert(MethodTypesExt.end(), 5497 OptMethodTypesExt.begin(), OptMethodTypesExt.end()); 5498 5499 llvm::Constant *Values[11]; 5500 // isa is NULL 5501 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); 5502 Values[1] = GetClassName(PD->getIdentifier()); 5503 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(), 5504 PD->protocol_begin(), 5505 PD->protocol_end()); 5506 5507 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_" 5508 + PD->getName(), 5509 "__DATA, __objc_const", 5510 InstanceMethods); 5511 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" 5512 + PD->getName(), 5513 "__DATA, __objc_const", 5514 ClassMethods); 5515 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_" 5516 + PD->getName(), 5517 "__DATA, __objc_const", 5518 OptInstanceMethods); 5519 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" 5520 + PD->getName(), 5521 "__DATA, __objc_const", 5522 OptClassMethods); 5523 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(), 5524 0, PD, ObjCTypes); 5525 uint32_t Size = 5526 CGM.getTargetData().getTypeAllocSize(ObjCTypes.ProtocolnfABITy); 5527 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 5528 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy); 5529 Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_" 5530 + PD->getName(), 5531 MethodTypesExt, ObjCTypes); 5532 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy, 5533 Values); 5534 5535 if (Entry) { 5536 // Already created, fix the linkage and update the initializer. 5537 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage); 5538 Entry->setInitializer(Init); 5539 } else { 5540 Entry = 5541 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, 5542 false, llvm::GlobalValue::WeakAnyLinkage, Init, 5543 "\01l_OBJC_PROTOCOL_$_" + PD->getName()); 5544 Entry->setAlignment( 5545 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy)); 5546 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 5547 } 5548 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 5549 CGM.AddUsedGlobal(Entry); 5550 5551 // Use this protocol meta-data to build protocol list table in section 5552 // __DATA, __objc_protolist 5553 llvm::GlobalVariable *PTGV = 5554 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy, 5555 false, llvm::GlobalValue::WeakAnyLinkage, Entry, 5556 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName()); 5557 PTGV->setAlignment( 5558 CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)); 5559 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); 5560 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 5561 CGM.AddUsedGlobal(PTGV); 5562 return Entry; 5563} 5564 5565/// EmitProtocolList - Generate protocol list meta-data: 5566/// @code 5567/// struct _protocol_list_t { 5568/// long protocol_count; // Note, this is 32/64 bit 5569/// struct _protocol_t[protocol_count]; 5570/// } 5571/// @endcode 5572/// 5573llvm::Constant * 5574CGObjCNonFragileABIMac::EmitProtocolList(Twine Name, 5575 ObjCProtocolDecl::protocol_iterator begin, 5576 ObjCProtocolDecl::protocol_iterator end) { 5577 std::vector<llvm::Constant*> ProtocolRefs; 5578 5579 // Just return null for empty protocol lists 5580 if (begin == end) 5581 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 5582 5583 // FIXME: We shouldn't need to do this lookup here, should we? 5584 llvm::SmallString<256> TmpName; 5585 Name.toVector(TmpName); 5586 llvm::GlobalVariable *GV = 5587 CGM.getModule().getGlobalVariable(TmpName.str(), true); 5588 if (GV) 5589 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); 5590 5591 for (; begin != end; ++begin) 5592 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented??? 5593 5594 // This list is null terminated. 5595 ProtocolRefs.push_back(llvm::Constant::getNullValue( 5596 ObjCTypes.ProtocolnfABIPtrTy)); 5597 5598 llvm::Constant *Values[2]; 5599 Values[0] = 5600 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 5601 Values[1] = 5602 llvm::ConstantArray::get( 5603 llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy, 5604 ProtocolRefs.size()), 5605 ProtocolRefs); 5606 5607 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values); 5608 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, 5609 llvm::GlobalValue::InternalLinkage, 5610 Init, Name); 5611 GV->setSection("__DATA, __objc_const"); 5612 GV->setAlignment( 5613 CGM.getTargetData().getABITypeAlignment(Init->getType())); 5614 CGM.AddUsedGlobal(GV); 5615 return llvm::ConstantExpr::getBitCast(GV, 5616 ObjCTypes.ProtocolListnfABIPtrTy); 5617} 5618 5619/// GetMethodDescriptionConstant - This routine build following meta-data: 5620/// struct _objc_method { 5621/// SEL _cmd; 5622/// char *method_type; 5623/// char *_imp; 5624/// } 5625 5626llvm::Constant * 5627CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 5628 llvm::Constant *Desc[3]; 5629 Desc[0] = 5630 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 5631 ObjCTypes.SelectorPtrTy); 5632 Desc[1] = GetMethodVarType(MD); 5633 if (!Desc[1]) 5634 return 0; 5635 5636 // Protocol methods have no implementation. So, this entry is always NULL. 5637 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 5638 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); 5639} 5640 5641/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference. 5642/// This code gen. amounts to generating code for: 5643/// @code 5644/// (type *)((char *)base + _OBJC_IVAR_$_.ivar; 5645/// @encode 5646/// 5647LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar( 5648 CodeGen::CodeGenFunction &CGF, 5649 QualType ObjectTy, 5650 llvm::Value *BaseValue, 5651 const ObjCIvarDecl *Ivar, 5652 unsigned CVRQualifiers) { 5653 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface(); 5654 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers, 5655 EmitIvarOffset(CGF, ID, Ivar)); 5656} 5657 5658llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset( 5659 CodeGen::CodeGenFunction &CGF, 5660 const ObjCInterfaceDecl *Interface, 5661 const ObjCIvarDecl *Ivar) { 5662 return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar"); 5663} 5664 5665static void appendSelectorForMessageRefTable(std::string &buffer, 5666 Selector selector) { 5667 if (selector.isUnarySelector()) { 5668 buffer += selector.getNameForSlot(0); 5669 return; 5670 } 5671 5672 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) { 5673 buffer += selector.getNameForSlot(i); 5674 buffer += '_'; 5675 } 5676} 5677 5678/// Emit a "v-table" message send. We emit a weak hidden-visibility 5679/// struct, initially containing the selector pointer and a pointer to 5680/// a "fixup" variant of the appropriate objc_msgSend. To call, we 5681/// load and call the function pointer, passing the address of the 5682/// struct as the second parameter. The runtime determines whether 5683/// the selector is currently emitted using vtable dispatch; if so, it 5684/// substitutes a stub function which simply tail-calls through the 5685/// appropriate vtable slot, and if not, it substitues a stub function 5686/// which tail-calls objc_msgSend. Both stubs adjust the selector 5687/// argument to correctly point to the selector. 5688RValue 5689CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF, 5690 ReturnValueSlot returnSlot, 5691 QualType resultType, 5692 Selector selector, 5693 llvm::Value *arg0, 5694 QualType arg0Type, 5695 bool isSuper, 5696 const CallArgList &formalArgs, 5697 const ObjCMethodDecl *method) { 5698 // Compute the actual arguments. 5699 CallArgList args; 5700 5701 // First argument: the receiver / super-call structure. 5702 if (!isSuper) 5703 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy); 5704 args.add(RValue::get(arg0), arg0Type); 5705 5706 // Second argument: a pointer to the message ref structure. Leave 5707 // the actual argument value blank for now. 5708 args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy); 5709 5710 args.insert(args.end(), formalArgs.begin(), formalArgs.end()); 5711 5712 const CGFunctionInfo &fnInfo = 5713 CGM.getTypes().getFunctionInfo(resultType, args, 5714 FunctionType::ExtInfo()); 5715 5716 NullReturnState nullReturn; 5717 5718 // Find the function to call and the mangled name for the message 5719 // ref structure. Using a different mangled name wouldn't actually 5720 // be a problem; it would just be a waste. 5721 // 5722 // The runtime currently never uses vtable dispatch for anything 5723 // except normal, non-super message-sends. 5724 // FIXME: don't use this for that. 5725 llvm::Constant *fn = 0; 5726 std::string messageRefName("\01l_"); 5727 if (CGM.ReturnTypeUsesSRet(fnInfo)) { 5728 if (isSuper) { 5729 fn = ObjCTypes.getMessageSendSuper2StretFixupFn(); 5730 messageRefName += "objc_msgSendSuper2_stret_fixup"; 5731 } else { 5732 nullReturn.init(CGF, arg0); 5733 fn = ObjCTypes.getMessageSendStretFixupFn(); 5734 messageRefName += "objc_msgSend_stret_fixup"; 5735 } 5736 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) { 5737 fn = ObjCTypes.getMessageSendFpretFixupFn(); 5738 messageRefName += "objc_msgSend_fpret_fixup"; 5739 } else { 5740 if (isSuper) { 5741 fn = ObjCTypes.getMessageSendSuper2FixupFn(); 5742 messageRefName += "objc_msgSendSuper2_fixup"; 5743 } else { 5744 fn = ObjCTypes.getMessageSendFixupFn(); 5745 messageRefName += "objc_msgSend_fixup"; 5746 } 5747 } 5748 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend"); 5749 messageRefName += '_'; 5750 5751 // Append the selector name, except use underscores anywhere we 5752 // would have used colons. 5753 appendSelectorForMessageRefTable(messageRefName, selector); 5754 5755 llvm::GlobalVariable *messageRef 5756 = CGM.getModule().getGlobalVariable(messageRefName); 5757 if (!messageRef) { 5758 // Build the message ref structure. 5759 llvm::Constant *values[] = { fn, GetMethodVarName(selector) }; 5760 llvm::Constant *init = llvm::ConstantStruct::getAnon(values); 5761 messageRef = new llvm::GlobalVariable(CGM.getModule(), 5762 init->getType(), 5763 /*constant*/ false, 5764 llvm::GlobalValue::WeakAnyLinkage, 5765 init, 5766 messageRefName); 5767 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility); 5768 messageRef->setAlignment(16); 5769 messageRef->setSection("__DATA, __objc_msgrefs, coalesced"); 5770 } 5771 llvm::Value *mref = 5772 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy); 5773 5774 // Update the message ref argument. 5775 args[1].RV = RValue::get(mref); 5776 5777 // Load the function to call from the message ref table. 5778 llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0); 5779 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn"); 5780 5781 bool variadic = method ? method->isVariadic() : false; 5782 llvm::FunctionType *fnType = 5783 CGF.getTypes().GetFunctionType(fnInfo, variadic); 5784 callee = CGF.Builder.CreateBitCast(callee, 5785 llvm::PointerType::getUnqual(fnType)); 5786 5787 RValue result = CGF.EmitCall(fnInfo, callee, returnSlot, args); 5788 return nullReturn.complete(CGF, result, resultType); 5789} 5790 5791/// Generate code for a message send expression in the nonfragile abi. 5792CodeGen::RValue 5793CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 5794 ReturnValueSlot Return, 5795 QualType ResultType, 5796 Selector Sel, 5797 llvm::Value *Receiver, 5798 const CallArgList &CallArgs, 5799 const ObjCInterfaceDecl *Class, 5800 const ObjCMethodDecl *Method) { 5801 return isVTableDispatchedSelector(Sel) 5802 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 5803 Receiver, CGF.getContext().getObjCIdType(), 5804 false, CallArgs, Method) 5805 : EmitMessageSend(CGF, Return, ResultType, 5806 EmitSelector(CGF.Builder, Sel), 5807 Receiver, CGF.getContext().getObjCIdType(), 5808 false, CallArgs, Method, ObjCTypes); 5809} 5810 5811llvm::GlobalVariable * 5812CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) { 5813 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 5814 5815 if (!GV) { 5816 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy, 5817 false, llvm::GlobalValue::ExternalLinkage, 5818 0, Name); 5819 } 5820 5821 return GV; 5822} 5823 5824llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CGBuilderTy &Builder, 5825 IdentifierInfo *II) { 5826 llvm::GlobalVariable *&Entry = ClassReferences[II]; 5827 5828 if (!Entry) { 5829 std::string ClassName(getClassSymbolPrefix() + II->getName().str()); 5830 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5831 Entry = 5832 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 5833 false, llvm::GlobalValue::InternalLinkage, 5834 ClassGV, 5835 "\01L_OBJC_CLASSLIST_REFERENCES_$_"); 5836 Entry->setAlignment( 5837 CGM.getTargetData().getABITypeAlignment( 5838 ObjCTypes.ClassnfABIPtrTy)); 5839 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip"); 5840 CGM.AddUsedGlobal(Entry); 5841 } 5842 5843 return Builder.CreateLoad(Entry); 5844} 5845 5846llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CGBuilderTy &Builder, 5847 const ObjCInterfaceDecl *ID) { 5848 return EmitClassRefFromId(Builder, ID->getIdentifier()); 5849} 5850 5851llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef( 5852 CGBuilderTy &Builder) { 5853 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool"); 5854 return EmitClassRefFromId(Builder, II); 5855} 5856 5857llvm::Value * 5858CGObjCNonFragileABIMac::EmitSuperClassRef(CGBuilderTy &Builder, 5859 const ObjCInterfaceDecl *ID) { 5860 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()]; 5861 5862 if (!Entry) { 5863 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5864 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5865 Entry = 5866 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, 5867 false, llvm::GlobalValue::InternalLinkage, 5868 ClassGV, 5869 "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 5870 Entry->setAlignment( 5871 CGM.getTargetData().getABITypeAlignment( 5872 ObjCTypes.ClassnfABIPtrTy)); 5873 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5874 CGM.AddUsedGlobal(Entry); 5875 } 5876 5877 return Builder.CreateLoad(Entry); 5878} 5879 5880/// EmitMetaClassRef - Return a Value * of the address of _class_t 5881/// meta-data 5882/// 5883llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CGBuilderTy &Builder, 5884 const ObjCInterfaceDecl *ID) { 5885 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()]; 5886 if (Entry) 5887 return Builder.CreateLoad(Entry); 5888 5889 std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString()); 5890 llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName); 5891 Entry = 5892 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false, 5893 llvm::GlobalValue::InternalLinkage, 5894 MetaClassGV, 5895 "\01L_OBJC_CLASSLIST_SUP_REFS_$_"); 5896 Entry->setAlignment( 5897 CGM.getTargetData().getABITypeAlignment( 5898 ObjCTypes.ClassnfABIPtrTy)); 5899 5900 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); 5901 CGM.AddUsedGlobal(Entry); 5902 5903 return Builder.CreateLoad(Entry); 5904} 5905 5906/// GetClass - Return a reference to the class for the given interface 5907/// decl. 5908llvm::Value *CGObjCNonFragileABIMac::GetClass(CGBuilderTy &Builder, 5909 const ObjCInterfaceDecl *ID) { 5910 if (ID->isWeakImported()) { 5911 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 5912 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName); 5913 ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage); 5914 } 5915 5916 return EmitClassRef(Builder, ID); 5917} 5918 5919/// Generates a message send where the super is the receiver. This is 5920/// a message send to self with special delivery semantics indicating 5921/// which class's method should be called. 5922CodeGen::RValue 5923CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 5924 ReturnValueSlot Return, 5925 QualType ResultType, 5926 Selector Sel, 5927 const ObjCInterfaceDecl *Class, 5928 bool isCategoryImpl, 5929 llvm::Value *Receiver, 5930 bool IsClassMessage, 5931 const CodeGen::CallArgList &CallArgs, 5932 const ObjCMethodDecl *Method) { 5933 // ... 5934 // Create and init a super structure; this is a (receiver, class) 5935 // pair we will pass to objc_msgSendSuper. 5936 llvm::Value *ObjCSuper = 5937 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super"); 5938 5939 llvm::Value *ReceiverAsObject = 5940 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 5941 CGF.Builder.CreateStore(ReceiverAsObject, 5942 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 5943 5944 // If this is a class message the metaclass is passed as the target. 5945 llvm::Value *Target; 5946 if (IsClassMessage) { 5947 if (isCategoryImpl) { 5948 // Message sent to "super' in a class method defined in 5949 // a category implementation. 5950 Target = EmitClassRef(CGF.Builder, Class); 5951 Target = CGF.Builder.CreateStructGEP(Target, 0); 5952 Target = CGF.Builder.CreateLoad(Target); 5953 } else 5954 Target = EmitMetaClassRef(CGF.Builder, Class); 5955 } else 5956 Target = EmitSuperClassRef(CGF.Builder, Class); 5957 5958 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and 5959 // ObjCTypes types. 5960 llvm::Type *ClassTy = 5961 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 5962 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 5963 CGF.Builder.CreateStore(Target, 5964 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 5965 5966 return (isVTableDispatchedSelector(Sel)) 5967 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel, 5968 ObjCSuper, ObjCTypes.SuperPtrCTy, 5969 true, CallArgs, Method) 5970 : EmitMessageSend(CGF, Return, ResultType, 5971 EmitSelector(CGF.Builder, Sel), 5972 ObjCSuper, ObjCTypes.SuperPtrCTy, 5973 true, CallArgs, Method, ObjCTypes); 5974} 5975 5976llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CGBuilderTy &Builder, 5977 Selector Sel, bool lval) { 5978 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 5979 5980 if (!Entry) { 5981 llvm::Constant *Casted = 5982 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 5983 ObjCTypes.SelectorPtrTy); 5984 Entry = 5985 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false, 5986 llvm::GlobalValue::InternalLinkage, 5987 Casted, "\01L_OBJC_SELECTOR_REFERENCES_"); 5988 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); 5989 CGM.AddUsedGlobal(Entry); 5990 } 5991 5992 if (lval) 5993 return Entry; 5994 llvm::LoadInst* LI = Builder.CreateLoad(Entry); 5995 5996 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"), 5997 llvm::MDNode::get(VMContext, 5998 ArrayRef<llvm::Value*>())); 5999 return LI; 6000} 6001/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 6002/// objc_assign_ivar (id src, id *dst, ptrdiff_t) 6003/// 6004void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 6005 llvm::Value *src, 6006 llvm::Value *dst, 6007 llvm::Value *ivarOffset) { 6008 llvm::Type * SrcTy = src->getType(); 6009 if (!isa<llvm::PointerType>(SrcTy)) { 6010 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 6011 assert(Size <= 8 && "does not support size > 8"); 6012 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 6013 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 6014 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 6015 } 6016 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 6017 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 6018 CGF.Builder.CreateCall3(ObjCTypes.getGcAssignIvarFn(), 6019 src, dst, ivarOffset); 6020 return; 6021} 6022 6023/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 6024/// objc_assign_strongCast (id src, id *dst) 6025/// 6026void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign( 6027 CodeGen::CodeGenFunction &CGF, 6028 llvm::Value *src, llvm::Value *dst) { 6029 llvm::Type * SrcTy = src->getType(); 6030 if (!isa<llvm::PointerType>(SrcTy)) { 6031 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 6032 assert(Size <= 8 && "does not support size > 8"); 6033 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 6034 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 6035 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 6036 } 6037 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 6038 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 6039 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignStrongCastFn(), 6040 src, dst, "weakassign"); 6041 return; 6042} 6043 6044void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable( 6045 CodeGen::CodeGenFunction &CGF, 6046 llvm::Value *DestPtr, 6047 llvm::Value *SrcPtr, 6048 llvm::Value *Size) { 6049 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy); 6050 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy); 6051 CGF.Builder.CreateCall3(ObjCTypes.GcMemmoveCollectableFn(), 6052 DestPtr, SrcPtr, Size); 6053 return; 6054} 6055 6056/// EmitObjCWeakRead - Code gen for loading value of a __weak 6057/// object: objc_read_weak (id *src) 6058/// 6059llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead( 6060 CodeGen::CodeGenFunction &CGF, 6061 llvm::Value *AddrWeakObj) { 6062 llvm::Type* DestTy = 6063 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType(); 6064 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 6065 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.getGcReadWeakFn(), 6066 AddrWeakObj, "weakread"); 6067 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy); 6068 return read_weak; 6069} 6070 6071/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 6072/// objc_assign_weak (id src, id *dst) 6073/// 6074void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 6075 llvm::Value *src, llvm::Value *dst) { 6076 llvm::Type * SrcTy = src->getType(); 6077 if (!isa<llvm::PointerType>(SrcTy)) { 6078 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 6079 assert(Size <= 8 && "does not support size > 8"); 6080 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 6081 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 6082 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 6083 } 6084 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 6085 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 6086 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignWeakFn(), 6087 src, dst, "weakassign"); 6088 return; 6089} 6090 6091/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 6092/// objc_assign_global (id src, id *dst) 6093/// 6094void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 6095 llvm::Value *src, llvm::Value *dst, 6096 bool threadlocal) { 6097 llvm::Type * SrcTy = src->getType(); 6098 if (!isa<llvm::PointerType>(SrcTy)) { 6099 unsigned Size = CGM.getTargetData().getTypeAllocSize(SrcTy); 6100 assert(Size <= 8 && "does not support size > 8"); 6101 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy) 6102 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy)); 6103 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy); 6104 } 6105 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 6106 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 6107 if (!threadlocal) 6108 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignGlobalFn(), 6109 src, dst, "globalassign"); 6110 else 6111 CGF.Builder.CreateCall2(ObjCTypes.getGcAssignThreadLocalFn(), 6112 src, dst, "threadlocalassign"); 6113 return; 6114} 6115 6116void 6117CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 6118 const ObjCAtSynchronizedStmt &S) { 6119 EmitAtSynchronizedStmt(CGF, S, 6120 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()), 6121 cast<llvm::Function>(ObjCTypes.getSyncExitFn())); 6122} 6123 6124llvm::Constant * 6125CGObjCNonFragileABIMac::GetEHType(QualType T) { 6126 // There's a particular fixed type info for 'id'. 6127 if (T->isObjCIdType() || 6128 T->isObjCQualifiedIdType()) { 6129 llvm::Constant *IDEHType = 6130 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id"); 6131 if (!IDEHType) 6132 IDEHType = 6133 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, 6134 false, 6135 llvm::GlobalValue::ExternalLinkage, 6136 0, "OBJC_EHTYPE_id"); 6137 return IDEHType; 6138 } 6139 6140 // All other types should be Objective-C interface pointer types. 6141 const ObjCObjectPointerType *PT = 6142 T->getAs<ObjCObjectPointerType>(); 6143 assert(PT && "Invalid @catch type."); 6144 const ObjCInterfaceType *IT = PT->getInterfaceType(); 6145 assert(IT && "Invalid @catch type."); 6146 return GetInterfaceEHType(IT->getDecl(), false); 6147} 6148 6149void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 6150 const ObjCAtTryStmt &S) { 6151 EmitTryCatchStmt(CGF, S, 6152 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()), 6153 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()), 6154 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn())); 6155} 6156 6157/// EmitThrowStmt - Generate code for a throw statement. 6158void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 6159 const ObjCAtThrowStmt &S) { 6160 if (const Expr *ThrowExpr = S.getThrowExpr()) { 6161 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr); 6162 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy); 6163 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception) 6164 .setDoesNotReturn(); 6165 } else { 6166 CGF.EmitCallOrInvoke(ObjCTypes.getExceptionRethrowFn()) 6167 .setDoesNotReturn(); 6168 } 6169 6170 CGF.Builder.CreateUnreachable(); 6171 CGF.Builder.ClearInsertionPoint(); 6172} 6173 6174llvm::Constant * 6175CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID, 6176 bool ForDefinition) { 6177 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()]; 6178 6179 // If we don't need a definition, return the entry if found or check 6180 // if we use an external reference. 6181 if (!ForDefinition) { 6182 if (Entry) 6183 return Entry; 6184 6185 // If this type (or a super class) has the __objc_exception__ 6186 // attribute, emit an external reference. 6187 if (hasObjCExceptionAttribute(CGM.getContext(), ID)) 6188 return Entry = 6189 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 6190 llvm::GlobalValue::ExternalLinkage, 6191 0, 6192 ("OBJC_EHTYPE_$_" + 6193 ID->getIdentifier()->getName())); 6194 } 6195 6196 // Otherwise we need to either make a new entry or fill in the 6197 // initializer. 6198 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition"); 6199 std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString()); 6200 std::string VTableName = "objc_ehtype_vtable"; 6201 llvm::GlobalVariable *VTableGV = 6202 CGM.getModule().getGlobalVariable(VTableName); 6203 if (!VTableGV) 6204 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, 6205 false, 6206 llvm::GlobalValue::ExternalLinkage, 6207 0, VTableName); 6208 6209 llvm::Value *VTableIdx = 6210 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 2); 6211 6212 llvm::Constant *Values[] = { 6213 llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx), 6214 GetClassName(ID->getIdentifier()), 6215 GetClassGlobal(ClassName) 6216 }; 6217 llvm::Constant *Init = 6218 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values); 6219 6220 if (Entry) { 6221 Entry->setInitializer(Init); 6222 } else { 6223 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false, 6224 llvm::GlobalValue::WeakAnyLinkage, 6225 Init, 6226 ("OBJC_EHTYPE_$_" + 6227 ID->getIdentifier()->getName())); 6228 } 6229 6230 if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility) 6231 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); 6232 Entry->setAlignment(CGM.getTargetData().getABITypeAlignment( 6233 ObjCTypes.EHTypeTy)); 6234 6235 if (ForDefinition) { 6236 Entry->setSection("__DATA,__objc_const"); 6237 Entry->setLinkage(llvm::GlobalValue::ExternalLinkage); 6238 } else { 6239 Entry->setSection("__DATA,__datacoal_nt,coalesced"); 6240 } 6241 6242 return Entry; 6243} 6244 6245/* *** */ 6246 6247CodeGen::CGObjCRuntime * 6248CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 6249 if (CGM.getLangOptions().ObjCNonFragileABI) 6250 return new CGObjCNonFragileABIMac(CGM); 6251 return new CGObjCMac(CGM); 6252} 6253