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