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