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