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