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