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