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