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