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