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