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