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