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