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