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