CGObjCMac.cpp revision 5de14dc87966ab98730cfacffe0b7d3198a91a62
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 // MethodListnfABITy - LLVM for struct _method_list_t 220 const llvm::StructType *MethodListnfABITy; 221 222 // MethodListnfABIPtrTy - LLVM for struct _method_list_t* 223 const llvm::Type *MethodListnfABIPtrTy; 224 225 // ProtocolnfABITy = LLVM for struct _protocol_t 226 const llvm::StructType *ProtocolnfABITy; 227 228 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list 229 const llvm::StructType *ProtocolListnfABITy; 230 231 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* 232 const llvm::Type *ProtocolListnfABIPtrTy; 233 234 // ClassnfABITy - LLVM for struct _class_t 235 const llvm::StructType *ClassnfABITy; 236 237 // ClassnfABIPtrTy - LLVM for struct _class_t* 238 const llvm::Type *ClassnfABIPtrTy; 239 240 // IvarnfABITy - LLVM for struct _ivar_t 241 const llvm::StructType *IvarnfABITy; 242 243 // IvarListnfABITy - LLVM for struct _ivar_list_t 244 const llvm::StructType *IvarListnfABITy; 245 246 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* 247 const llvm::Type *IvarListnfABIPtrTy; 248 249 // ClassRonfABITy - LLVM for struct _class_ro_t 250 const llvm::StructType *ClassRonfABITy; 251 252 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 253 const llvm::Type *ImpnfABITy; 254 255 // CategorynfABITy - LLVM for struct _category_t 256 const llvm::StructType *CategorynfABITy; 257 258 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); 259 ~ObjCNonFragileABITypesHelper(){} 260}; 261 262class CGObjCCommonMac : public CodeGen::CGObjCRuntime { 263protected: 264 CodeGen::CodeGenModule &CGM; 265 // FIXME! May not be needing this after all. 266 unsigned ObjCABI; 267 268 /// LazySymbols - Symbols to generate a lazy reference for. See 269 /// DefinedSymbols and FinishModule(). 270 std::set<IdentifierInfo*> LazySymbols; 271 272 /// DefinedSymbols - External symbols which are defined by this 273 /// module. The symbols in this list and LazySymbols are used to add 274 /// special linker symbols which ensure that Objective-C modules are 275 /// linked properly. 276 std::set<IdentifierInfo*> DefinedSymbols; 277 278 /// ClassNames - uniqued class names. 279 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 280 281 /// MethodVarNames - uniqued method variable names. 282 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 283 284 /// MethodVarTypes - uniqued method type signatures. We have to use 285 /// a StringMap here because have no other unique reference. 286 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 287 288 /// MethodDefinitions - map of methods which have been defined in 289 /// this translation unit. 290 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 291 292 /// PropertyNames - uniqued method variable names. 293 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 294 295 /// ClassReferences - uniqued class references. 296 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 297 298 /// SelectorReferences - uniqued selector references. 299 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 300 301 /// Protocols - Protocols for which an objc_protocol structure has 302 /// been emitted. Forward declarations are handled by creating an 303 /// empty structure whose initializer is filled in when/if defined. 304 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 305 306 /// DefinedProtocols - Protocols which have actually been 307 /// defined. We should not need this, see FIXME in GenerateProtocol. 308 llvm::DenseSet<IdentifierInfo*> DefinedProtocols; 309 310 /// DefinedClasses - List of defined classes. 311 std::vector<llvm::GlobalValue*> DefinedClasses; 312 313 /// DefinedCategories - List of defined categories. 314 std::vector<llvm::GlobalValue*> DefinedCategories; 315 316 /// UsedGlobals - List of globals to pack into the llvm.used metadata 317 /// to prevent them from being clobbered. 318 std::vector<llvm::GlobalVariable*> UsedGlobals; 319 320 /// GetNameForMethod - Return a name for the given method. 321 /// \param[out] NameOut - The return value. 322 void GetNameForMethod(const ObjCMethodDecl *OMD, 323 const ObjCContainerDecl *CD, 324 std::string &NameOut); 325 326 /// GetMethodVarName - Return a unique constant for the given 327 /// selector's name. The return value has type char *. 328 llvm::Constant *GetMethodVarName(Selector Sel); 329 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 330 llvm::Constant *GetMethodVarName(const std::string &Name); 331 332 /// GetMethodVarType - Return a unique constant for the given 333 /// selector's name. The return value has type char *. 334 335 // FIXME: This is a horrible name. 336 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D); 337 llvm::Constant *GetMethodVarType(const std::string &Name); 338 339 /// GetPropertyName - Return a unique constant for the given 340 /// name. The return value has type char *. 341 llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 342 343 // FIXME: This can be dropped once string functions are unified. 344 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 345 const Decl *Container); 346 347 /// GetClassName - Return a unique constant for the given selector's 348 /// name. The return value has type char *. 349 llvm::Constant *GetClassName(IdentifierInfo *Ident); 350 351 const RecordDecl *GetFirstIvarInRecord(const ObjCInterfaceDecl *OID, 352 RecordDecl::field_iterator &FIV, 353 RecordDecl::field_iterator &PIV); 354 /// EmitPropertyList - Emit the given property list. The return 355 /// value has type PropertyListPtrTy. 356 llvm::Constant *EmitPropertyList(const std::string &Name, 357 const Decl *Container, 358 const ObjCContainerDecl *OCD, 359 const ObjCCommonTypesHelper &ObjCTypes); 360 361public: 362 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) 363 { } 364 365 virtual llvm::Constant *GenerateConstantString(const std::string &String); 366 367 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, 368 const ObjCContainerDecl *CD=0); 369}; 370 371class CGObjCMac : public CGObjCCommonMac { 372private: 373 ObjCTypesHelper ObjCTypes; 374 /// EmitImageInfo - Emit the image info marker used to encode some module 375 /// level information. 376 void EmitImageInfo(); 377 378 /// EmitModuleInfo - Another marker encoding module level 379 /// information. 380 void EmitModuleInfo(); 381 382 /// EmitModuleSymols - Emit module symbols, the list of defined 383 /// classes and categories. The result has type SymtabPtrTy. 384 llvm::Constant *EmitModuleSymbols(); 385 386 /// FinishModule - Write out global data structures at the end of 387 /// processing a translation unit. 388 void FinishModule(); 389 390 /// EmitClassExtension - Generate the class extension structure used 391 /// to store the weak ivar layout and properties. The return value 392 /// has type ClassExtensionPtrTy. 393 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 394 395 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 396 /// for the given class. 397 llvm::Value *EmitClassRef(CGBuilderTy &Builder, 398 const ObjCInterfaceDecl *ID); 399 400 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 401 QualType ResultType, 402 Selector Sel, 403 llvm::Value *Arg0, 404 QualType Arg0Ty, 405 bool IsSuper, 406 const CallArgList &CallArgs); 407 408 /// EmitIvarList - Emit the ivar list for the given 409 /// implementation. If ForClass is true the list of class ivars 410 /// (i.e. metaclass ivars) is emitted, otherwise the list of 411 /// interface ivars will be emitted. The return value has type 412 /// IvarListPtrTy. 413 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 414 bool ForClass); 415 416 /// EmitMetaClass - Emit a forward reference to the class structure 417 /// for the metaclass of the given interface. The return value has 418 /// type ClassPtrTy. 419 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 420 421 /// EmitMetaClass - Emit a class structure for the metaclass of the 422 /// given implementation. The return value has type ClassPtrTy. 423 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 424 llvm::Constant *Protocols, 425 const llvm::Type *InterfaceTy, 426 const ConstantVector &Methods); 427 428 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 429 430 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 431 432 /// EmitMethodList - Emit the method list for the given 433 /// implementation. The return value has type MethodListPtrTy. 434 llvm::Constant *EmitMethodList(const std::string &Name, 435 const char *Section, 436 const ConstantVector &Methods); 437 438 /// EmitMethodDescList - Emit a method description list for a list of 439 /// method declarations. 440 /// - TypeName: The name for the type containing the methods. 441 /// - IsProtocol: True iff these methods are for a protocol. 442 /// - ClassMethds: True iff these are class methods. 443 /// - Required: When true, only "required" methods are 444 /// listed. Similarly, when false only "optional" methods are 445 /// listed. For classes this should always be true. 446 /// - begin, end: The method list to output. 447 /// 448 /// The return value has type MethodDescriptionListPtrTy. 449 llvm::Constant *EmitMethodDescList(const std::string &Name, 450 const char *Section, 451 const ConstantVector &Methods); 452 453 /// GetOrEmitProtocol - Get the protocol object for the given 454 /// declaration, emitting it if necessary. The return value has type 455 /// ProtocolPtrTy. 456 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD); 457 458 /// GetOrEmitProtocolRef - Get a forward reference to the protocol 459 /// object for the given declaration, emitting it if needed. These 460 /// forward references will be filled in with empty bodies if no 461 /// definition is seen. The return value has type ProtocolPtrTy. 462 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD); 463 464 /// EmitProtocolExtension - Generate the protocol extension 465 /// structure used to store optional instance and class methods, and 466 /// protocol properties. The return value has type 467 /// ProtocolExtensionPtrTy. 468 llvm::Constant * 469 EmitProtocolExtension(const ObjCProtocolDecl *PD, 470 const ConstantVector &OptInstanceMethods, 471 const ConstantVector &OptClassMethods); 472 473 /// EmitProtocolList - Generate the list of referenced 474 /// protocols. The return value has type ProtocolListPtrTy. 475 llvm::Constant *EmitProtocolList(const std::string &Name, 476 ObjCProtocolDecl::protocol_iterator begin, 477 ObjCProtocolDecl::protocol_iterator end); 478 479 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 480 /// for the given selector. 481 llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel); 482 483 /// GetProtocolRef - Return a reference to the internal protocol 484 /// description, creating an empty one if it has not been 485 /// defined. The return value has type ProtocolPtrTy. 486 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); 487 488public: 489 CGObjCMac(CodeGen::CodeGenModule &cgm); 490 491 virtual llvm::Function *ModuleInitFunction(); 492 493 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 494 QualType ResultType, 495 Selector Sel, 496 llvm::Value *Receiver, 497 bool IsClassMessage, 498 const CallArgList &CallArgs); 499 500 virtual CodeGen::RValue 501 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 502 QualType ResultType, 503 Selector Sel, 504 const ObjCInterfaceDecl *Class, 505 llvm::Value *Receiver, 506 bool IsClassMessage, 507 const CallArgList &CallArgs); 508 509 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 510 const ObjCInterfaceDecl *ID); 511 512 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); 513 514 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 515 516 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 517 518 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 519 const ObjCProtocolDecl *PD); 520 521 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 522 523 virtual llvm::Function *GetPropertyGetFunction(); 524 virtual llvm::Function *GetPropertySetFunction(); 525 virtual llvm::Function *EnumerationMutationFunction(); 526 527 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 528 const Stmt &S); 529 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 530 const ObjCAtThrowStmt &S); 531 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 532 llvm::Value *AddrWeakObj); 533 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 534 llvm::Value *src, llvm::Value *dst); 535 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 536 llvm::Value *src, llvm::Value *dest); 537 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 538 llvm::Value *src, llvm::Value *dest); 539 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 540 llvm::Value *src, llvm::Value *dest); 541}; 542 543class CGObjCNonFragileABIMac : public CGObjCCommonMac { 544private: 545 ObjCNonFragileABITypesHelper ObjCTypes; 546 llvm::GlobalVariable* ObjCEmptyCacheVar; 547 llvm::GlobalVariable* ObjCEmptyVtableVar; 548 549 /// FinishNonFragileABIModule - Write out global data structures at the end of 550 /// processing a translation unit. 551 void FinishNonFragileABIModule(); 552 553 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, 554 unsigned InstanceStart, 555 unsigned InstanceSize, 556 const ObjCImplementationDecl *ID); 557 llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, 558 llvm::Constant *IsAGV, 559 llvm::Constant *SuperClassGV, 560 llvm::Constant *ClassRoGV); 561 562 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 563 564 /// EmitMethodList - Emit the method list for the given 565 /// implementation. The return value has type MethodListnfABITy. 566 llvm::Constant *EmitMethodList(const std::string &Name, 567 const char *Section, 568 const ConstantVector &Methods); 569 /// EmitIvarList - Emit the ivar list for the given 570 /// implementation. If ForClass is true the list of class ivars 571 /// (i.e. metaclass ivars) is emitted, otherwise the list of 572 /// interface ivars will be emitted. The return value has type 573 /// IvarListnfABIPtrTy. 574 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); 575 576 llvm::Constant *EmitIvarOffsetVar(const ObjCImplementationDecl *ID, 577 const ObjCIvarDecl *Ivar, 578 unsigned long int offset); 579 580public: 581 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); 582 // FIXME. All stubs for now! 583 virtual llvm::Function *ModuleInitFunction(); 584 585 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 586 QualType ResultType, 587 Selector Sel, 588 llvm::Value *Receiver, 589 bool IsClassMessage, 590 const CallArgList &CallArgs) 591 {return RValue::get(0);} 592 593 virtual CodeGen::RValue 594 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 595 QualType ResultType, 596 Selector Sel, 597 const ObjCInterfaceDecl *Class, 598 llvm::Value *Receiver, 599 bool IsClassMessage, 600 const CallArgList &CallArgs){ return RValue::get(0);} 601 602 virtual llvm::Value *GetClass(CGBuilderTy &Builder, 603 const ObjCInterfaceDecl *ID){ return 0; } 604 605 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel) 606 { return 0; } 607 608 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 609 610 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 611 612 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, 613 const ObjCProtocolDecl *PD) 614 { return 0; } 615 616 virtual void GenerateProtocol(const ObjCProtocolDecl *PD){ return; } 617 618 virtual llvm::Function *GetPropertyGetFunction(){ return 0; } 619 virtual llvm::Function *GetPropertySetFunction() 620 { return 0; } 621 virtual llvm::Function *EnumerationMutationFunction() 622 { return 0; } 623 624 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 625 const Stmt &S) 626 { return; } 627 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 628 const ObjCAtThrowStmt &S) 629 { return; } 630 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 631 llvm::Value *AddrWeakObj) 632 { return 0; } 633 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 634 llvm::Value *src, llvm::Value *dst) 635 { return; } 636 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 637 llvm::Value *src, llvm::Value *dest) 638 { return; } 639 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 640 llvm::Value *src, llvm::Value *dest) 641 { return; } 642 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 643 llvm::Value *src, llvm::Value *dest) 644 { return; } 645}; 646 647} // end anonymous namespace 648 649/* *** Helper Functions *** */ 650 651/// getConstantGEP() - Help routine to construct simple GEPs. 652static llvm::Constant *getConstantGEP(llvm::Constant *C, 653 unsigned idx0, 654 unsigned idx1) { 655 llvm::Value *Idxs[] = { 656 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0), 657 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1) 658 }; 659 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2); 660} 661 662/* *** CGObjCMac Public Interface *** */ 663 664CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), 665 ObjCTypes(cgm) 666{ 667 ObjCABI = 1; 668 EmitImageInfo(); 669} 670 671/// GetClass - Return a reference to the class for the given interface 672/// decl. 673llvm::Value *CGObjCMac::GetClass(CGBuilderTy &Builder, 674 const ObjCInterfaceDecl *ID) { 675 return EmitClassRef(Builder, ID); 676} 677 678/// GetSelector - Return the pointer to the unique'd string for this selector. 679llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) { 680 return EmitSelector(Builder, Sel); 681} 682 683/// Generate a constant CFString object. 684/* 685 struct __builtin_CFString { 686 const int *isa; // point to __CFConstantStringClassReference 687 int flags; 688 const char *str; 689 long length; 690 }; 691*/ 692 693llvm::Constant *CGObjCCommonMac::GenerateConstantString( 694 const std::string &String) { 695 return CGM.GetAddrOfConstantCFString(String); 696} 697 698/// Generates a message send where the super is the receiver. This is 699/// a message send to self with special delivery semantics indicating 700/// which class's method should be called. 701CodeGen::RValue 702CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 703 QualType ResultType, 704 Selector Sel, 705 const ObjCInterfaceDecl *Class, 706 llvm::Value *Receiver, 707 bool IsClassMessage, 708 const CodeGen::CallArgList &CallArgs) { 709 // Create and init a super structure; this is a (receiver, class) 710 // pair we will pass to objc_msgSendSuper. 711 llvm::Value *ObjCSuper = 712 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super"); 713 llvm::Value *ReceiverAsObject = 714 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 715 CGF.Builder.CreateStore(ReceiverAsObject, 716 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 717 718 // If this is a class message the metaclass is passed as the target. 719 llvm::Value *Target; 720 if (IsClassMessage) { 721 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 722 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 723 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 724 Target = Super; 725 } else { 726 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 727 } 728 // FIXME: We shouldn't need to do this cast, rectify the ASTContext 729 // and ObjCTypes types. 730 const llvm::Type *ClassTy = 731 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 732 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 733 CGF.Builder.CreateStore(Target, 734 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 735 736 return EmitMessageSend(CGF, ResultType, Sel, 737 ObjCSuper, ObjCTypes.SuperPtrCTy, 738 true, CallArgs); 739} 740 741/// Generate code for a message send expression. 742CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 743 QualType ResultType, 744 Selector Sel, 745 llvm::Value *Receiver, 746 bool IsClassMessage, 747 const CallArgList &CallArgs) { 748 llvm::Value *Arg0 = 749 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp"); 750 return EmitMessageSend(CGF, ResultType, Sel, 751 Arg0, CGF.getContext().getObjCIdType(), 752 false, CallArgs); 753} 754 755CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, 756 QualType ResultType, 757 Selector Sel, 758 llvm::Value *Arg0, 759 QualType Arg0Ty, 760 bool IsSuper, 761 const CallArgList &CallArgs) { 762 CallArgList ActualArgs; 763 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); 764 ActualArgs.push_back(std::make_pair(RValue::get(EmitSelector(CGF.Builder, 765 Sel)), 766 CGF.getContext().getObjCSelType())); 767 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 768 769 const llvm::FunctionType *FTy = 770 CGM.getTypes().GetFunctionType(CGCallInfo(ResultType, ActualArgs), 771 false); 772 773 llvm::Constant *Fn; 774 if (CGM.ReturnTypeUsesSret(ResultType)) { 775 Fn = ObjCTypes.getSendStretFn(IsSuper); 776 } else if (ResultType->isFloatingType()) { 777 // FIXME: Sadly, this is wrong. This actually depends on the 778 // architecture. This happens to be right for x86-32 though. 779 Fn = ObjCTypes.getSendFpretFn(IsSuper); 780 } else { 781 Fn = ObjCTypes.getSendFn(IsSuper); 782 } 783 Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy)); 784 return CGF.EmitCall(Fn, ResultType, ActualArgs); 785} 786 787llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, 788 const ObjCProtocolDecl *PD) { 789 // FIXME: I don't understand why gcc generates this, or where it is 790 // resolved. Investigate. Its also wasteful to look this up over and 791 // over. 792 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 793 794 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 795 ObjCTypes.ExternalProtocolPtrTy); 796} 797 798void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 799 // FIXME: We shouldn't need this, the protocol decl should contain 800 // enough information to tell us whether this was a declaration or a 801 // definition. 802 DefinedProtocols.insert(PD->getIdentifier()); 803 804 // If we have generated a forward reference to this protocol, emit 805 // it now. Otherwise do nothing, the protocol objects are lazily 806 // emitted. 807 if (Protocols.count(PD->getIdentifier())) 808 GetOrEmitProtocol(PD); 809} 810 811llvm::Constant *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 812 if (DefinedProtocols.count(PD->getIdentifier())) 813 return GetOrEmitProtocol(PD); 814 return GetOrEmitProtocolRef(PD); 815} 816 817/* 818 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 819 struct _objc_protocol { 820 struct _objc_protocol_extension *isa; 821 char *protocol_name; 822 struct _objc_protocol_list *protocol_list; 823 struct _objc__method_prototype_list *instance_methods; 824 struct _objc__method_prototype_list *class_methods 825 }; 826 827 See EmitProtocolExtension(). 828*/ 829llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { 830 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 831 832 // Early exit if a defining object has already been generated. 833 if (Entry && Entry->hasInitializer()) 834 return Entry; 835 836 // FIXME: I don't understand why gcc generates this, or where it is 837 // resolved. Investigate. Its also wasteful to look this up over and 838 // over. 839 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 840 841 const char *ProtocolName = PD->getNameAsCString(); 842 843 // Construct method lists. 844 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 845 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 846 for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(), 847 e = PD->instmeth_end(); i != e; ++i) { 848 ObjCMethodDecl *MD = *i; 849 llvm::Constant *C = GetMethodDescriptionConstant(MD); 850 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 851 OptInstanceMethods.push_back(C); 852 } else { 853 InstanceMethods.push_back(C); 854 } 855 } 856 857 for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(), 858 e = PD->classmeth_end(); i != e; ++i) { 859 ObjCMethodDecl *MD = *i; 860 llvm::Constant *C = GetMethodDescriptionConstant(MD); 861 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 862 OptClassMethods.push_back(C); 863 } else { 864 ClassMethods.push_back(C); 865 } 866 } 867 868 std::vector<llvm::Constant*> Values(5); 869 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods); 870 Values[1] = GetClassName(PD->getIdentifier()); 871 Values[2] = 872 EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getNameAsString(), 873 PD->protocol_begin(), 874 PD->protocol_end()); 875 Values[3] = 876 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" 877 + PD->getNameAsString(), 878 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 879 InstanceMethods); 880 Values[4] = 881 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" 882 + PD->getNameAsString(), 883 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 884 ClassMethods); 885 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 886 Values); 887 888 if (Entry) { 889 // Already created, fix the linkage and update the initializer. 890 Entry->setLinkage(llvm::GlobalValue::InternalLinkage); 891 Entry->setInitializer(Init); 892 } else { 893 Entry = 894 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 895 llvm::GlobalValue::InternalLinkage, 896 Init, 897 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName, 898 &CGM.getModule()); 899 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 900 UsedGlobals.push_back(Entry); 901 // FIXME: Is this necessary? Why only for protocol? 902 Entry->setAlignment(4); 903 } 904 905 return Entry; 906} 907 908llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) { 909 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 910 911 if (!Entry) { 912 // We use the initializer as a marker of whether this is a forward 913 // reference or not. At module finalization we add the empty 914 // contents for protocols which were referenced but never defined. 915 Entry = 916 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 917 llvm::GlobalValue::ExternalLinkage, 918 0, 919 "\01L_OBJC_PROTOCOL_" + PD->getNameAsString(), 920 &CGM.getModule()); 921 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 922 UsedGlobals.push_back(Entry); 923 // FIXME: Is this necessary? Why only for protocol? 924 Entry->setAlignment(4); 925 } 926 927 return Entry; 928} 929 930/* 931 struct _objc_protocol_extension { 932 uint32_t size; 933 struct objc_method_description_list *optional_instance_methods; 934 struct objc_method_description_list *optional_class_methods; 935 struct objc_property_list *instance_properties; 936 }; 937*/ 938llvm::Constant * 939CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 940 const ConstantVector &OptInstanceMethods, 941 const ConstantVector &OptClassMethods) { 942 uint64_t Size = 943 CGM.getTargetData().getTypePaddedSize(ObjCTypes.ProtocolExtensionTy); 944 std::vector<llvm::Constant*> Values(4); 945 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 946 Values[1] = 947 EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" 948 + PD->getNameAsString(), 949 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 950 OptInstanceMethods); 951 Values[2] = 952 EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" 953 + PD->getNameAsString(), 954 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 955 OptClassMethods); 956 Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + 957 PD->getNameAsString(), 958 0, PD, ObjCTypes); 959 960 // Return null if no extension bits are used. 961 if (Values[1]->isNullValue() && Values[2]->isNullValue() && 962 Values[3]->isNullValue()) 963 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 964 965 llvm::Constant *Init = 966 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 967 llvm::GlobalVariable *GV = 968 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false, 969 llvm::GlobalValue::InternalLinkage, 970 Init, 971 "\01L_OBJC_PROTOCOLEXT_" + PD->getNameAsString(), 972 &CGM.getModule()); 973 // No special section, but goes in llvm.used 974 UsedGlobals.push_back(GV); 975 976 return GV; 977} 978 979/* 980 struct objc_protocol_list { 981 struct objc_protocol_list *next; 982 long count; 983 Protocol *list[]; 984 }; 985*/ 986llvm::Constant * 987CGObjCMac::EmitProtocolList(const std::string &Name, 988 ObjCProtocolDecl::protocol_iterator begin, 989 ObjCProtocolDecl::protocol_iterator end) { 990 std::vector<llvm::Constant*> ProtocolRefs; 991 992 for (; begin != end; ++begin) 993 ProtocolRefs.push_back(GetProtocolRef(*begin)); 994 995 // Just return null for empty protocol lists 996 if (ProtocolRefs.empty()) 997 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 998 999 // This list is null terminated. 1000 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 1001 1002 std::vector<llvm::Constant*> Values(3); 1003 // This field is only used by the runtime. 1004 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1005 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 1006 Values[2] = 1007 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 1008 ProtocolRefs.size()), 1009 ProtocolRefs); 1010 1011 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1012 llvm::GlobalVariable *GV = 1013 new llvm::GlobalVariable(Init->getType(), false, 1014 llvm::GlobalValue::InternalLinkage, 1015 Init, 1016 Name, 1017 &CGM.getModule()); 1018 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip"); 1019 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 1020} 1021 1022/* 1023 struct _objc_property { 1024 const char * const name; 1025 const char * const attributes; 1026 }; 1027 1028 struct _objc_property_list { 1029 uint32_t entsize; // sizeof (struct _objc_property) 1030 uint32_t prop_count; 1031 struct _objc_property[prop_count]; 1032 }; 1033*/ 1034llvm::Constant *CGObjCCommonMac::EmitPropertyList(const std::string &Name, 1035 const Decl *Container, 1036 const ObjCContainerDecl *OCD, 1037 const ObjCCommonTypesHelper &ObjCTypes) { 1038 std::vector<llvm::Constant*> Properties, Prop(2); 1039 for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), 1040 E = OCD->prop_end(); I != E; ++I) { 1041 const ObjCPropertyDecl *PD = *I; 1042 Prop[0] = GetPropertyName(PD->getIdentifier()); 1043 Prop[1] = GetPropertyTypeString(PD, Container); 1044 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 1045 Prop)); 1046 } 1047 1048 // Return null for empty list. 1049 if (Properties.empty()) 1050 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 1051 1052 unsigned PropertySize = 1053 CGM.getTargetData().getTypePaddedSize(ObjCTypes.PropertyTy); 1054 std::vector<llvm::Constant*> Values(3); 1055 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 1056 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 1057 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 1058 Properties.size()); 1059 Values[2] = llvm::ConstantArray::get(AT, Properties); 1060 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1061 1062 llvm::GlobalVariable *GV = 1063 new llvm::GlobalVariable(Init->getType(), false, 1064 llvm::GlobalValue::InternalLinkage, 1065 Init, 1066 Name, 1067 &CGM.getModule()); 1068 if (ObjCABI == 2) 1069 GV->setSection("__DATA, __objc_const"); 1070 // No special section on property lists? 1071 UsedGlobals.push_back(GV); 1072 return llvm::ConstantExpr::getBitCast(GV, 1073 ObjCTypes.PropertyListPtrTy); 1074 1075} 1076 1077/* 1078 struct objc_method_description_list { 1079 int count; 1080 struct objc_method_description list[]; 1081 }; 1082*/ 1083llvm::Constant * 1084CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 1085 std::vector<llvm::Constant*> Desc(2); 1086 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 1087 ObjCTypes.SelectorPtrTy); 1088 Desc[1] = GetMethodVarType(MD); 1089 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 1090 Desc); 1091} 1092 1093llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name, 1094 const char *Section, 1095 const ConstantVector &Methods) { 1096 // Return null for empty list. 1097 if (Methods.empty()) 1098 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 1099 1100 std::vector<llvm::Constant*> Values(2); 1101 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 1102 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 1103 Methods.size()); 1104 Values[1] = llvm::ConstantArray::get(AT, Methods); 1105 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1106 1107 llvm::GlobalVariable *GV = 1108 new llvm::GlobalVariable(Init->getType(), false, 1109 llvm::GlobalValue::InternalLinkage, 1110 Init, Name, &CGM.getModule()); 1111 GV->setSection(Section); 1112 UsedGlobals.push_back(GV); 1113 return llvm::ConstantExpr::getBitCast(GV, 1114 ObjCTypes.MethodDescriptionListPtrTy); 1115} 1116 1117/* 1118 struct _objc_category { 1119 char *category_name; 1120 char *class_name; 1121 struct _objc_method_list *instance_methods; 1122 struct _objc_method_list *class_methods; 1123 struct _objc_protocol_list *protocols; 1124 uint32_t size; // <rdar://4585769> 1125 struct _objc_property_list *instance_properties; 1126 }; 1127 */ 1128void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 1129 unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.CategoryTy); 1130 1131 // FIXME: This is poor design, the OCD should have a pointer to the 1132 // category decl. Additionally, note that Category can be null for 1133 // the @implementation w/o an @interface case. Sema should just 1134 // create one for us as it does for @implementation so everyone else 1135 // can live life under a clear blue sky. 1136 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 1137 const ObjCCategoryDecl *Category = 1138 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 1139 std::string ExtName(Interface->getNameAsString() + "_" + 1140 OCD->getNameAsString()); 1141 1142 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1143 for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(), 1144 e = OCD->instmeth_end(); i != e; ++i) { 1145 // Instance methods should always be defined. 1146 InstanceMethods.push_back(GetMethodConstant(*i)); 1147 } 1148 for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(), 1149 e = OCD->classmeth_end(); i != e; ++i) { 1150 // Class methods should always be defined. 1151 ClassMethods.push_back(GetMethodConstant(*i)); 1152 } 1153 1154 std::vector<llvm::Constant*> Values(7); 1155 Values[0] = GetClassName(OCD->getIdentifier()); 1156 Values[1] = GetClassName(Interface->getIdentifier()); 1157 Values[2] = 1158 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") + 1159 ExtName, 1160 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 1161 InstanceMethods); 1162 Values[3] = 1163 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName, 1164 "__OBJC,__cat_class_meth,regular,no_dead_strip", 1165 ClassMethods); 1166 if (Category) { 1167 Values[4] = 1168 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName, 1169 Category->protocol_begin(), 1170 Category->protocol_end()); 1171 } else { 1172 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 1173 } 1174 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1175 1176 // If there is no category @interface then there can be no properties. 1177 if (Category) { 1178 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName, 1179 OCD, Category, ObjCTypes); 1180 } else { 1181 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 1182 } 1183 1184 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 1185 Values); 1186 1187 llvm::GlobalVariable *GV = 1188 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false, 1189 llvm::GlobalValue::InternalLinkage, 1190 Init, 1191 std::string("\01L_OBJC_CATEGORY_")+ExtName, 1192 &CGM.getModule()); 1193 GV->setSection("__OBJC,__category,regular,no_dead_strip"); 1194 UsedGlobals.push_back(GV); 1195 DefinedCategories.push_back(GV); 1196} 1197 1198// FIXME: Get from somewhere? 1199enum ClassFlags { 1200 eClassFlags_Factory = 0x00001, 1201 eClassFlags_Meta = 0x00002, 1202 // <rdr://5142207> 1203 eClassFlags_HasCXXStructors = 0x02000, 1204 eClassFlags_Hidden = 0x20000, 1205 eClassFlags_ABI2_Hidden = 0x00010, 1206 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 1207}; 1208 1209// <rdr://5142207&4705298&4843145> 1210static bool IsClassHidden(const ObjCInterfaceDecl *ID) { 1211 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) { 1212 // FIXME: Support -fvisibility 1213 switch (attr->getVisibility()) { 1214 default: 1215 assert(0 && "Unknown visibility"); 1216 return false; 1217 case VisibilityAttr::DefaultVisibility: 1218 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here? 1219 return false; 1220 case VisibilityAttr::HiddenVisibility: 1221 return true; 1222 } 1223 } else { 1224 return false; // FIXME: Support -fvisibility 1225 } 1226} 1227 1228/* 1229 struct _objc_class { 1230 Class isa; 1231 Class super_class; 1232 const char *name; 1233 long version; 1234 long info; 1235 long instance_size; 1236 struct _objc_ivar_list *ivars; 1237 struct _objc_method_list *methods; 1238 struct _objc_cache *cache; 1239 struct _objc_protocol_list *protocols; 1240 // Objective-C 1.0 extensions (<rdr://4585769>) 1241 const char *ivar_layout; 1242 struct _objc_class_ext *ext; 1243 }; 1244 1245 See EmitClassExtension(); 1246 */ 1247void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 1248 DefinedSymbols.insert(ID->getIdentifier()); 1249 1250 std::string ClassName = ID->getNameAsString(); 1251 // FIXME: Gross 1252 ObjCInterfaceDecl *Interface = 1253 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 1254 llvm::Constant *Protocols = 1255 EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getNameAsString(), 1256 Interface->protocol_begin(), 1257 Interface->protocol_end()); 1258 const llvm::Type *InterfaceTy = 1259 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface)); 1260 unsigned Flags = eClassFlags_Factory; 1261 unsigned Size = CGM.getTargetData().getTypePaddedSize(InterfaceTy); 1262 1263 // FIXME: Set CXX-structors flag. 1264 if (IsClassHidden(ID->getClassInterface())) 1265 Flags |= eClassFlags_Hidden; 1266 1267 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1268 for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(), 1269 e = ID->instmeth_end(); i != e; ++i) { 1270 // Instance methods should always be defined. 1271 InstanceMethods.push_back(GetMethodConstant(*i)); 1272 } 1273 for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(), 1274 e = ID->classmeth_end(); i != e; ++i) { 1275 // Class methods should always be defined. 1276 ClassMethods.push_back(GetMethodConstant(*i)); 1277 } 1278 1279 for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(), 1280 e = ID->propimpl_end(); i != e; ++i) { 1281 ObjCPropertyImplDecl *PID = *i; 1282 1283 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 1284 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1285 1286 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 1287 if (llvm::Constant *C = GetMethodConstant(MD)) 1288 InstanceMethods.push_back(C); 1289 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 1290 if (llvm::Constant *C = GetMethodConstant(MD)) 1291 InstanceMethods.push_back(C); 1292 } 1293 } 1294 1295 std::vector<llvm::Constant*> Values(12); 1296 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods); 1297 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 1298 // Record a reference to the super class. 1299 LazySymbols.insert(Super->getIdentifier()); 1300 1301 Values[ 1] = 1302 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 1303 ObjCTypes.ClassPtrTy); 1304 } else { 1305 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 1306 } 1307 Values[ 2] = GetClassName(ID->getIdentifier()); 1308 // Version is always 0. 1309 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 1310 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 1311 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 1312 Values[ 6] = EmitIvarList(ID, false); 1313 Values[ 7] = 1314 EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getNameAsString(), 1315 "__OBJC,__inst_meth,regular,no_dead_strip", 1316 InstanceMethods); 1317 // cache is always NULL. 1318 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 1319 Values[ 9] = Protocols; 1320 // FIXME: Set ivar_layout 1321 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1322 Values[11] = EmitClassExtension(ID); 1323 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 1324 Values); 1325 1326 llvm::GlobalVariable *GV = 1327 new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 1328 llvm::GlobalValue::InternalLinkage, 1329 Init, 1330 std::string("\01L_OBJC_CLASS_")+ClassName, 1331 &CGM.getModule()); 1332 GV->setSection("__OBJC,__class,regular,no_dead_strip"); 1333 UsedGlobals.push_back(GV); 1334 // FIXME: Why? 1335 GV->setAlignment(32); 1336 DefinedClasses.push_back(GV); 1337} 1338 1339llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 1340 llvm::Constant *Protocols, 1341 const llvm::Type *InterfaceTy, 1342 const ConstantVector &Methods) { 1343 unsigned Flags = eClassFlags_Meta; 1344 unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.ClassTy); 1345 1346 if (IsClassHidden(ID->getClassInterface())) 1347 Flags |= eClassFlags_Hidden; 1348 1349 std::vector<llvm::Constant*> Values(12); 1350 // The isa for the metaclass is the root of the hierarchy. 1351 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 1352 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 1353 Root = Super; 1354 Values[ 0] = 1355 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 1356 ObjCTypes.ClassPtrTy); 1357 // The super class for the metaclass is emitted as the name of the 1358 // super class. The runtime fixes this up to point to the 1359 // *metaclass* for the super class. 1360 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 1361 Values[ 1] = 1362 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 1363 ObjCTypes.ClassPtrTy); 1364 } else { 1365 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 1366 } 1367 Values[ 2] = GetClassName(ID->getIdentifier()); 1368 // Version is always 0. 1369 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 1370 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 1371 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 1372 Values[ 6] = EmitIvarList(ID, true); 1373 Values[ 7] = 1374 EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), 1375 "__OBJC,__inst_meth,regular,no_dead_strip", 1376 Methods); 1377 // cache is always NULL. 1378 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 1379 Values[ 9] = Protocols; 1380 // ivar_layout for metaclass is always NULL. 1381 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1382 // The class extension is always unused for metaclasses. 1383 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 1384 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 1385 Values); 1386 1387 std::string Name("\01L_OBJC_METACLASS_"); 1388 Name += ID->getNameAsCString(); 1389 1390 // Check for a forward reference. 1391 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 1392 if (GV) { 1393 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 1394 "Forward metaclass reference has incorrect type."); 1395 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 1396 GV->setInitializer(Init); 1397 } else { 1398 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 1399 llvm::GlobalValue::InternalLinkage, 1400 Init, Name, 1401 &CGM.getModule()); 1402 } 1403 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 1404 UsedGlobals.push_back(GV); 1405 // FIXME: Why? 1406 GV->setAlignment(32); 1407 1408 return GV; 1409} 1410 1411llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 1412 std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString(); 1413 1414 // FIXME: Should we look these up somewhere other than the 1415 // module. Its a bit silly since we only generate these while 1416 // processing an implementation, so exactly one pointer would work 1417 // if know when we entered/exitted an implementation block. 1418 1419 // Check for an existing forward reference. 1420 // Previously, metaclass with internal linkage may have been defined. 1421 // pass 'true' as 2nd argument so it is returned. 1422 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true)) { 1423 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 1424 "Forward metaclass reference has incorrect type."); 1425 return GV; 1426 } else { 1427 // Generate as an external reference to keep a consistent 1428 // module. This will be patched up when we emit the metaclass. 1429 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 1430 llvm::GlobalValue::ExternalLinkage, 1431 0, 1432 Name, 1433 &CGM.getModule()); 1434 } 1435} 1436 1437/* 1438 struct objc_class_ext { 1439 uint32_t size; 1440 const char *weak_ivar_layout; 1441 struct _objc_property_list *properties; 1442 }; 1443*/ 1444llvm::Constant * 1445CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 1446 uint64_t Size = 1447 CGM.getTargetData().getTypePaddedSize(ObjCTypes.ClassExtensionTy); 1448 1449 std::vector<llvm::Constant*> Values(3); 1450 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1451 // FIXME: Output weak_ivar_layout string. 1452 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1453 Values[2] = EmitPropertyList("\01L_OBJC_$_PROP_LIST_" + ID->getNameAsString(), 1454 ID, ID->getClassInterface(), ObjCTypes); 1455 1456 // Return null if no extension bits are used. 1457 if (Values[1]->isNullValue() && Values[2]->isNullValue()) 1458 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 1459 1460 llvm::Constant *Init = 1461 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 1462 llvm::GlobalVariable *GV = 1463 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false, 1464 llvm::GlobalValue::InternalLinkage, 1465 Init, 1466 "\01L_OBJC_CLASSEXT_" + ID->getNameAsString(), 1467 &CGM.getModule()); 1468 // No special section, but goes in llvm.used 1469 UsedGlobals.push_back(GV); 1470 1471 return GV; 1472} 1473 1474/// countInheritedIvars - count number of ivars in class and its super class(s) 1475/// 1476static int countInheritedIvars(const ObjCInterfaceDecl *OI) { 1477 int count = 0; 1478 if (!OI) 1479 return 0; 1480 const ObjCInterfaceDecl *SuperClass = OI->getSuperClass(); 1481 if (SuperClass) 1482 count += countInheritedIvars(SuperClass); 1483 for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(), 1484 E = OI->ivar_end(); I != E; ++I) 1485 ++count; 1486 return count; 1487} 1488 1489/* 1490 struct objc_ivar { 1491 char *ivar_name; 1492 char *ivar_type; 1493 int ivar_offset; 1494 }; 1495 1496 struct objc_ivar_list { 1497 int ivar_count; 1498 struct objc_ivar list[count]; 1499 }; 1500 */ 1501llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 1502 bool ForClass) { 1503 std::vector<llvm::Constant*> Ivars, Ivar(3); 1504 1505 // When emitting the root class GCC emits ivar entries for the 1506 // actual class structure. It is not clear if we need to follow this 1507 // behavior; for now lets try and get away with not doing it. If so, 1508 // the cleanest solution would be to make up an ObjCInterfaceDecl 1509 // for the class. 1510 if (ForClass) 1511 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 1512 1513 ObjCInterfaceDecl *OID = 1514 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 1515 const llvm::Type *InterfaceTy = 1516 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(OID)); 1517 const llvm::StructLayout *Layout = 1518 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy)); 1519 1520 RecordDecl::field_iterator ifield, pfield; 1521 const RecordDecl *RD = GetFirstIvarInRecord(OID, ifield, pfield); 1522 for (RecordDecl::field_iterator e = RD->field_end(); ifield != e; ++ifield) { 1523 FieldDecl *Field = *ifield; 1524 unsigned Offset = Layout->getElementOffset(CGM.getTypes(). 1525 getLLVMFieldNo(Field)); 1526 if (Field->getIdentifier()) 1527 Ivar[0] = GetMethodVarName(Field->getIdentifier()); 1528 else 1529 Ivar[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1530 std::string TypeStr; 1531 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 1532 Ivar[1] = GetMethodVarType(TypeStr); 1533 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset); 1534 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar)); 1535 } 1536 1537 // Return null for empty list. 1538 if (Ivars.empty()) 1539 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 1540 1541 std::vector<llvm::Constant*> Values(2); 1542 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 1543 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 1544 Ivars.size()); 1545 Values[1] = llvm::ConstantArray::get(AT, Ivars); 1546 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1547 1548 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" : 1549 "\01L_OBJC_INSTANCE_VARIABLES_"); 1550 llvm::GlobalVariable *GV = 1551 new llvm::GlobalVariable(Init->getType(), false, 1552 llvm::GlobalValue::InternalLinkage, 1553 Init, 1554 Prefix + ID->getNameAsString(), 1555 &CGM.getModule()); 1556 if (ForClass) { 1557 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip"); 1558 // FIXME: Why is this only here? 1559 GV->setAlignment(32); 1560 } else { 1561 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip"); 1562 } 1563 UsedGlobals.push_back(GV); 1564 return llvm::ConstantExpr::getBitCast(GV, 1565 ObjCTypes.IvarListPtrTy); 1566} 1567 1568/* 1569 struct objc_method { 1570 SEL method_name; 1571 char *method_types; 1572 void *method; 1573 }; 1574 1575 struct objc_method_list { 1576 struct objc_method_list *obsolete; 1577 int count; 1578 struct objc_method methods_list[count]; 1579 }; 1580*/ 1581 1582/// GetMethodConstant - Return a struct objc_method constant for the 1583/// given method if it has been defined. The result is null if the 1584/// method has not been defined. The return value has type MethodPtrTy. 1585llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 1586 // FIXME: Use DenseMap::lookup 1587 llvm::Function *Fn = MethodDefinitions[MD]; 1588 if (!Fn) 1589 return 0; 1590 1591 std::vector<llvm::Constant*> Method(3); 1592 Method[0] = 1593 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 1594 ObjCTypes.SelectorPtrTy); 1595 Method[1] = GetMethodVarType(MD); 1596 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 1597 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 1598} 1599 1600llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name, 1601 const char *Section, 1602 const ConstantVector &Methods) { 1603 // Return null for empty list. 1604 if (Methods.empty()) 1605 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 1606 1607 std::vector<llvm::Constant*> Values(3); 1608 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1609 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 1610 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 1611 Methods.size()); 1612 Values[2] = llvm::ConstantArray::get(AT, Methods); 1613 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1614 1615 llvm::GlobalVariable *GV = 1616 new llvm::GlobalVariable(Init->getType(), false, 1617 llvm::GlobalValue::InternalLinkage, 1618 Init, 1619 Name, 1620 &CGM.getModule()); 1621 GV->setSection(Section); 1622 UsedGlobals.push_back(GV); 1623 return llvm::ConstantExpr::getBitCast(GV, 1624 ObjCTypes.MethodListPtrTy); 1625} 1626 1627llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, 1628 const ObjCContainerDecl *CD) { 1629 std::string Name; 1630 GetNameForMethod(OMD, CD, Name); 1631 1632 const llvm::FunctionType *MethodTy = 1633 CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext())); 1634 llvm::Function *Method = 1635 llvm::Function::Create(MethodTy, 1636 llvm::GlobalValue::InternalLinkage, 1637 Name, 1638 &CGM.getModule()); 1639 MethodDefinitions.insert(std::make_pair(OMD, Method)); 1640 1641 return Method; 1642} 1643 1644llvm::Function *CGObjCMac::ModuleInitFunction() { 1645 // Abuse this interface function as a place to finalize. 1646 FinishModule(); 1647 1648 return NULL; 1649} 1650 1651llvm::Function *CGObjCMac::GetPropertyGetFunction() { 1652 return ObjCTypes.GetPropertyFn; 1653} 1654 1655llvm::Function *CGObjCMac::GetPropertySetFunction() { 1656 return ObjCTypes.SetPropertyFn; 1657} 1658 1659llvm::Function *CGObjCMac::EnumerationMutationFunction() 1660{ 1661 return ObjCTypes.EnumerationMutationFn; 1662} 1663 1664/* 1665 1666Objective-C setjmp-longjmp (sjlj) Exception Handling 1667-- 1668 1669The basic framework for a @try-catch-finally is as follows: 1670{ 1671 objc_exception_data d; 1672 id _rethrow = null; 1673 1674 objc_exception_try_enter(&d); 1675 if (!setjmp(d.jmp_buf)) { 1676 ... try body ... 1677 } else { 1678 // exception path 1679 id _caught = objc_exception_extract(&d); 1680 1681 // enter new try scope for handlers 1682 if (!setjmp(d.jmp_buf)) { 1683 ... match exception and execute catch blocks ... 1684 1685 // fell off end, rethrow. 1686 _rethrow = _caught; 1687 ... jump-through-finally to finally_rethrow ... 1688 } else { 1689 // exception in catch block 1690 _rethrow = objc_exception_extract(&d); 1691 ... jump-through-finally_no_exit to finally_rethrow ... 1692 } 1693 } 1694 ... jump-through-finally to finally_end ... 1695 1696finally: 1697 // match either the initial try_enter or the catch try_enter, 1698 // depending on the path followed. 1699 objc_exception_try_exit(&d); 1700finally_no_exit: 1701 ... finally block .... 1702 ... dispatch to finally destination ... 1703 1704finally_rethrow: 1705 objc_exception_throw(_rethrow); 1706 1707finally_end: 1708} 1709 1710This framework differs slightly from the one gcc uses, in that gcc 1711uses _rethrow to determine if objc_exception_try_exit should be called 1712and if the object should be rethrown. This breaks in the face of 1713throwing nil and introduces unnecessary branches. 1714 1715We specialize this framework for a few particular circumstances: 1716 1717 - If there are no catch blocks, then we avoid emitting the second 1718 exception handling context. 1719 1720 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id 1721 e)) we avoid emitting the code to rethrow an uncaught exception. 1722 1723 - FIXME: If there is no @finally block we can do a few more 1724 simplifications. 1725 1726Rethrows and Jumps-Through-Finally 1727-- 1728 1729Support for implicit rethrows and jumping through the finally block is 1730handled by storing the current exception-handling context in 1731ObjCEHStack. 1732 1733In order to implement proper @finally semantics, we support one basic 1734mechanism for jumping through the finally block to an arbitrary 1735destination. Constructs which generate exits from a @try or @catch 1736block use this mechanism to implement the proper semantics by chaining 1737jumps, as necessary. 1738 1739This mechanism works like the one used for indirect goto: we 1740arbitrarily assign an ID to each destination and store the ID for the 1741destination in a variable prior to entering the finally block. At the 1742end of the finally block we simply create a switch to the proper 1743destination. 1744 1745Code gen for @synchronized(expr) stmt; 1746Effectively generating code for: 1747objc_sync_enter(expr); 1748@try stmt @finally { objc_sync_exit(expr); } 1749*/ 1750 1751void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, 1752 const Stmt &S) { 1753 bool isTry = isa<ObjCAtTryStmt>(S); 1754 // Create various blocks we refer to for handling @finally. 1755 llvm::BasicBlock *FinallyBlock = CGF.createBasicBlock("finally"); 1756 llvm::BasicBlock *FinallyNoExit = CGF.createBasicBlock("finally.noexit"); 1757 llvm::BasicBlock *FinallyRethrow = CGF.createBasicBlock("finally.throw"); 1758 llvm::BasicBlock *FinallyEnd = CGF.createBasicBlock("finally.end"); 1759 llvm::Value *DestCode = 1760 CGF.CreateTempAlloca(llvm::Type::Int32Ty, "finally.dst"); 1761 1762 // Generate jump code. Done here so we can directly add things to 1763 // the switch instruction. 1764 llvm::BasicBlock *FinallyJump = CGF.createBasicBlock("finally.jump"); 1765 llvm::SwitchInst *FinallySwitch = 1766 llvm::SwitchInst::Create(new llvm::LoadInst(DestCode, "", FinallyJump), 1767 FinallyEnd, 10, FinallyJump); 1768 1769 // Push an EH context entry, used for handling rethrows and jumps 1770 // through finally. 1771 CodeGenFunction::ObjCEHEntry EHEntry(FinallyBlock, FinallyNoExit, 1772 FinallySwitch, DestCode); 1773 CGF.ObjCEHStack.push_back(&EHEntry); 1774 1775 // Allocate memory for the exception data and rethrow pointer. 1776 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 1777 "exceptiondata.ptr"); 1778 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy, 1779 "_rethrow"); 1780 if (!isTry) { 1781 // For @synchronized, call objc_sync_enter(sync.expr) 1782 llvm::Value *Arg = CGF.EmitScalarExpr( 1783 cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1784 Arg = CGF.Builder.CreateBitCast(Arg, ObjCTypes.ObjectPtrTy); 1785 CGF.Builder.CreateCall(ObjCTypes.SyncEnterFn, Arg); 1786 } 1787 1788 // Enter a new try block and call setjmp. 1789 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData); 1790 llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0, 1791 "jmpbufarray"); 1792 JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp"); 1793 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn, 1794 JmpBufPtr, "result"); 1795 1796 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try"); 1797 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler"); 1798 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"), 1799 TryHandler, TryBlock); 1800 1801 // Emit the @try block. 1802 CGF.EmitBlock(TryBlock); 1803 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody() 1804 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody()); 1805 CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd); 1806 1807 // Emit the "exception in @try" block. 1808 CGF.EmitBlock(TryHandler); 1809 1810 // Retrieve the exception object. We may emit multiple blocks but 1811 // nothing can cross this so the value is already in SSA form. 1812 llvm::Value *Caught = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, 1813 ExceptionData, 1814 "caught"); 1815 EHEntry.Exception = Caught; 1816 if (!isTry) 1817 { 1818 CGF.Builder.CreateStore(Caught, RethrowPtr); 1819 CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false); 1820 } 1821 else if (const ObjCAtCatchStmt* CatchStmt = 1822 cast<ObjCAtTryStmt>(S).getCatchStmts()) 1823 { 1824 // Enter a new exception try block (in case a @catch block throws 1825 // an exception). 1826 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData); 1827 1828 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn, 1829 JmpBufPtr, "result"); 1830 llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"); 1831 1832 llvm::BasicBlock *CatchBlock = CGF.createBasicBlock("catch"); 1833 llvm::BasicBlock *CatchHandler = CGF.createBasicBlock("catch.handler"); 1834 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock); 1835 1836 CGF.EmitBlock(CatchBlock); 1837 1838 // Handle catch list. As a special case we check if everything is 1839 // matched and avoid generating code for falling off the end if 1840 // so. 1841 bool AllMatched = false; 1842 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 1843 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch"); 1844 1845 const DeclStmt *CatchParam = 1846 cast_or_null<DeclStmt>(CatchStmt->getCatchParamStmt()); 1847 const VarDecl *VD = 0; 1848 const PointerType *PT = 0; 1849 1850 // catch(...) always matches. 1851 if (!CatchParam) { 1852 AllMatched = true; 1853 } else { 1854 VD = cast<VarDecl>(CatchParam->getSolitaryDecl()); 1855 PT = VD->getType()->getAsPointerType(); 1856 1857 // catch(id e) always matches. 1858 // FIXME: For the time being we also match id<X>; this should 1859 // be rejected by Sema instead. 1860 if ((PT && CGF.getContext().isObjCIdType(PT->getPointeeType())) || 1861 VD->getType()->isObjCQualifiedIdType()) 1862 AllMatched = true; 1863 } 1864 1865 if (AllMatched) { 1866 if (CatchParam) { 1867 CGF.EmitStmt(CatchParam); 1868 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 1869 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(VD)); 1870 } 1871 1872 CGF.EmitStmt(CatchStmt->getCatchBody()); 1873 CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd); 1874 break; 1875 } 1876 1877 assert(PT && "Unexpected non-pointer type in @catch"); 1878 QualType T = PT->getPointeeType(); 1879 const ObjCInterfaceType *ObjCType = T->getAsObjCInterfaceType(); 1880 assert(ObjCType && "Catch parameter must have Objective-C type!"); 1881 1882 // Check if the @catch block matches the exception object. 1883 llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl()); 1884 1885 llvm::Value *Match = CGF.Builder.CreateCall2(ObjCTypes.ExceptionMatchFn, 1886 Class, Caught, "match"); 1887 1888 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("matched"); 1889 1890 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"), 1891 MatchedBlock, NextCatchBlock); 1892 1893 // Emit the @catch block. 1894 CGF.EmitBlock(MatchedBlock); 1895 CGF.EmitStmt(CatchParam); 1896 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?"); 1897 1898 llvm::Value *Tmp = 1899 CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()), 1900 "tmp"); 1901 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(VD)); 1902 1903 CGF.EmitStmt(CatchStmt->getCatchBody()); 1904 CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd); 1905 1906 CGF.EmitBlock(NextCatchBlock); 1907 } 1908 1909 if (!AllMatched) { 1910 // None of the handlers caught the exception, so store it to be 1911 // rethrown at the end of the @finally block. 1912 CGF.Builder.CreateStore(Caught, RethrowPtr); 1913 CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow); 1914 } 1915 1916 // Emit the exception handler for the @catch blocks. 1917 CGF.EmitBlock(CatchHandler); 1918 CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, 1919 ExceptionData), 1920 RethrowPtr); 1921 CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false); 1922 } else { 1923 CGF.Builder.CreateStore(Caught, RethrowPtr); 1924 CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false); 1925 } 1926 1927 // Pop the exception-handling stack entry. It is important to do 1928 // this now, because the code in the @finally block is not in this 1929 // context. 1930 CGF.ObjCEHStack.pop_back(); 1931 1932 // Emit the @finally block. 1933 CGF.EmitBlock(FinallyBlock); 1934 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); 1935 1936 CGF.EmitBlock(FinallyNoExit); 1937 if (isTry) { 1938 if (const ObjCAtFinallyStmt* FinallyStmt = 1939 cast<ObjCAtTryStmt>(S).getFinallyStmt()) 1940 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 1941 } 1942 else { 1943 // For @synchronized objc_sync_exit(expr); As finally's sole statement. 1944 // For @synchronized, call objc_sync_enter(sync.expr) 1945 llvm::Value *Arg = CGF.EmitScalarExpr( 1946 cast<ObjCAtSynchronizedStmt>(S).getSynchExpr()); 1947 Arg = CGF.Builder.CreateBitCast(Arg, ObjCTypes.ObjectPtrTy); 1948 CGF.Builder.CreateCall(ObjCTypes.SyncExitFn, Arg); 1949 } 1950 1951 CGF.EmitBlock(FinallyJump); 1952 1953 CGF.EmitBlock(FinallyRethrow); 1954 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, 1955 CGF.Builder.CreateLoad(RethrowPtr)); 1956 CGF.Builder.CreateUnreachable(); 1957 1958 CGF.EmitBlock(FinallyEnd); 1959} 1960 1961void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1962 const ObjCAtThrowStmt &S) { 1963 llvm::Value *ExceptionAsObject; 1964 1965 if (const Expr *ThrowExpr = S.getThrowExpr()) { 1966 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 1967 ExceptionAsObject = 1968 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp"); 1969 } else { 1970 assert((!CGF.ObjCEHStack.empty() && CGF.ObjCEHStack.back()->Exception) && 1971 "Unexpected rethrow outside @catch block."); 1972 ExceptionAsObject = CGF.ObjCEHStack.back()->Exception; 1973 } 1974 1975 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, ExceptionAsObject); 1976 CGF.Builder.CreateUnreachable(); 1977 1978 // Clear the insertion point to indicate we are in unreachable code. 1979 CGF.Builder.ClearInsertionPoint(); 1980} 1981 1982void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E, 1983 llvm::BasicBlock *Dst, 1984 bool ExecuteTryExit) { 1985 if (!HaveInsertPoint()) 1986 return; 1987 1988 // Find the destination code for this block. We always use 0 for the 1989 // fallthrough block (default destination). 1990 llvm::SwitchInst *SI = E->FinallySwitch; 1991 llvm::ConstantInt *ID; 1992 if (Dst == SI->getDefaultDest()) { 1993 ID = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); 1994 } else { 1995 ID = SI->findCaseDest(Dst); 1996 if (!ID) { 1997 // No code found, get a new unique one by just using the number 1998 // of switch successors. 1999 ID = llvm::ConstantInt::get(llvm::Type::Int32Ty, SI->getNumSuccessors()); 2000 SI->addCase(ID, Dst); 2001 } 2002 } 2003 2004 // Set the destination code and branch. 2005 Builder.CreateStore(ID, E->DestCode); 2006 EmitBranch(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit); 2007} 2008 2009/// EmitObjCWeakRead - Code gen for loading value of a __weak 2010/// object: objc_read_weak (id *src) 2011/// 2012llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, 2013 llvm::Value *AddrWeakObj) 2014{ 2015 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy); 2016 llvm::Value *read_weak = CGF.Builder.CreateCall(ObjCTypes.GcReadWeakFn, 2017 AddrWeakObj, "weakread"); 2018 return read_weak; 2019} 2020 2021/// EmitObjCWeakAssign - Code gen for assigning to a __weak object. 2022/// objc_assign_weak (id src, id *dst) 2023/// 2024void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, 2025 llvm::Value *src, llvm::Value *dst) 2026{ 2027 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2028 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2029 CGF.Builder.CreateCall2(ObjCTypes.GcAssignWeakFn, 2030 src, dst, "weakassign"); 2031 return; 2032} 2033 2034/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object. 2035/// objc_assign_global (id src, id *dst) 2036/// 2037void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, 2038 llvm::Value *src, llvm::Value *dst) 2039{ 2040 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2041 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2042 CGF.Builder.CreateCall2(ObjCTypes.GcAssignGlobalFn, 2043 src, dst, "globalassign"); 2044 return; 2045} 2046 2047/// EmitObjCIvarAssign - Code gen for assigning to a __strong object. 2048/// objc_assign_ivar (id src, id *dst) 2049/// 2050void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, 2051 llvm::Value *src, llvm::Value *dst) 2052{ 2053 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2054 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2055 CGF.Builder.CreateCall2(ObjCTypes.GcAssignIvarFn, 2056 src, dst, "assignivar"); 2057 return; 2058} 2059 2060/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object. 2061/// objc_assign_strongCast (id src, id *dst) 2062/// 2063void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, 2064 llvm::Value *src, llvm::Value *dst) 2065{ 2066 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy); 2067 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy); 2068 CGF.Builder.CreateCall2(ObjCTypes.GcAssignStrongCastFn, 2069 src, dst, "weakassign"); 2070 return; 2071} 2072 2073/* *** Private Interface *** */ 2074 2075/// EmitImageInfo - Emit the image info marker used to encode some module 2076/// level information. 2077/// 2078/// See: <rdr://4810609&4810587&4810587> 2079/// struct IMAGE_INFO { 2080/// unsigned version; 2081/// unsigned flags; 2082/// }; 2083enum ImageInfoFlags { 2084 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies 2085 eImageInfo_GarbageCollected = (1 << 1), 2086 eImageInfo_GCOnly = (1 << 2) 2087}; 2088 2089void CGObjCMac::EmitImageInfo() { 2090 unsigned version = 0; // Version is unused? 2091 unsigned flags = 0; 2092 2093 // FIXME: Fix and continue? 2094 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 2095 flags |= eImageInfo_GarbageCollected; 2096 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 2097 flags |= eImageInfo_GCOnly; 2098 2099 // Emitted as int[2]; 2100 llvm::Constant *values[2] = { 2101 llvm::ConstantInt::get(llvm::Type::Int32Ty, version), 2102 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags) 2103 }; 2104 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2); 2105 llvm::GlobalVariable *GV = 2106 new llvm::GlobalVariable(AT, true, 2107 llvm::GlobalValue::InternalLinkage, 2108 llvm::ConstantArray::get(AT, values, 2), 2109 "\01L_OBJC_IMAGE_INFO", 2110 &CGM.getModule()); 2111 2112 if (ObjCABI == 1) { 2113 GV->setSection("__OBJC, __image_info,regular"); 2114 } else { 2115 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); 2116 } 2117 2118 UsedGlobals.push_back(GV); 2119} 2120 2121 2122// struct objc_module { 2123// unsigned long version; 2124// unsigned long size; 2125// const char *name; 2126// Symtab symtab; 2127// }; 2128 2129// FIXME: Get from somewhere 2130static const int ModuleVersion = 7; 2131 2132void CGObjCMac::EmitModuleInfo() { 2133 uint64_t Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.ModuleTy); 2134 2135 std::vector<llvm::Constant*> Values(4); 2136 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion); 2137 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 2138 // This used to be the filename, now it is unused. <rdr://4327263> 2139 Values[2] = GetClassName(&CGM.getContext().Idents.get("")); 2140 Values[3] = EmitModuleSymbols(); 2141 2142 llvm::GlobalVariable *GV = 2143 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false, 2144 llvm::GlobalValue::InternalLinkage, 2145 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, 2146 Values), 2147 "\01L_OBJC_MODULES", 2148 &CGM.getModule()); 2149 GV->setSection("__OBJC,__module_info,regular,no_dead_strip"); 2150 UsedGlobals.push_back(GV); 2151} 2152 2153llvm::Constant *CGObjCMac::EmitModuleSymbols() { 2154 unsigned NumClasses = DefinedClasses.size(); 2155 unsigned NumCategories = DefinedCategories.size(); 2156 2157 // Return null if no symbols were defined. 2158 if (!NumClasses && !NumCategories) 2159 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 2160 2161 std::vector<llvm::Constant*> Values(5); 2162 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 2163 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 2164 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 2165 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 2166 2167 // The runtime expects exactly the list of defined classes followed 2168 // by the list of defined categories, in a single array. 2169 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories); 2170 for (unsigned i=0; i<NumClasses; i++) 2171 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 2172 ObjCTypes.Int8PtrTy); 2173 for (unsigned i=0; i<NumCategories; i++) 2174 Symbols[NumClasses + i] = 2175 llvm::ConstantExpr::getBitCast(DefinedCategories[i], 2176 ObjCTypes.Int8PtrTy); 2177 2178 Values[4] = 2179 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 2180 NumClasses + NumCategories), 2181 Symbols); 2182 2183 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 2184 2185 llvm::GlobalVariable *GV = 2186 new llvm::GlobalVariable(Init->getType(), false, 2187 llvm::GlobalValue::InternalLinkage, 2188 Init, 2189 "\01L_OBJC_SYMBOLS", 2190 &CGM.getModule()); 2191 GV->setSection("__OBJC,__symbols,regular,no_dead_strip"); 2192 UsedGlobals.push_back(GV); 2193 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 2194} 2195 2196llvm::Value *CGObjCMac::EmitClassRef(CGBuilderTy &Builder, 2197 const ObjCInterfaceDecl *ID) { 2198 LazySymbols.insert(ID->getIdentifier()); 2199 2200 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; 2201 2202 if (!Entry) { 2203 llvm::Constant *Casted = 2204 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()), 2205 ObjCTypes.ClassPtrTy); 2206 Entry = 2207 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false, 2208 llvm::GlobalValue::InternalLinkage, 2209 Casted, "\01L_OBJC_CLASS_REFERENCES_", 2210 &CGM.getModule()); 2211 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip"); 2212 UsedGlobals.push_back(Entry); 2213 } 2214 2215 return Builder.CreateLoad(Entry, false, "tmp"); 2216} 2217 2218llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) { 2219 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 2220 2221 if (!Entry) { 2222 llvm::Constant *Casted = 2223 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 2224 ObjCTypes.SelectorPtrTy); 2225 Entry = 2226 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false, 2227 llvm::GlobalValue::InternalLinkage, 2228 Casted, "\01L_OBJC_SELECTOR_REFERENCES_", 2229 &CGM.getModule()); 2230 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip"); 2231 UsedGlobals.push_back(Entry); 2232 } 2233 2234 return Builder.CreateLoad(Entry, false, "tmp"); 2235} 2236 2237llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { 2238 llvm::GlobalVariable *&Entry = ClassNames[Ident]; 2239 2240 if (!Entry) { 2241 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName()); 2242 Entry = 2243 new llvm::GlobalVariable(C->getType(), false, 2244 llvm::GlobalValue::InternalLinkage, 2245 C, "\01L_OBJC_CLASS_NAME_", 2246 &CGM.getModule()); 2247 Entry->setSection("__TEXT,__cstring,cstring_literals"); 2248 UsedGlobals.push_back(Entry); 2249 } 2250 2251 return getConstantGEP(Entry, 0, 0); 2252} 2253 2254llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) { 2255 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 2256 2257 if (!Entry) { 2258 // FIXME: Avoid std::string copying. 2259 llvm::Constant *C = llvm::ConstantArray::get(Sel.getAsString()); 2260 Entry = 2261 new llvm::GlobalVariable(C->getType(), false, 2262 llvm::GlobalValue::InternalLinkage, 2263 C, "\01L_OBJC_METH_VAR_NAME_", 2264 &CGM.getModule()); 2265 Entry->setSection("__TEXT,__cstring,cstring_literals"); 2266 UsedGlobals.push_back(Entry); 2267 } 2268 2269 return getConstantGEP(Entry, 0, 0); 2270} 2271 2272// FIXME: Merge into a single cstring creation function. 2273llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) { 2274 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 2275} 2276 2277// FIXME: Merge into a single cstring creation function. 2278llvm::Constant *CGObjCCommonMac::GetMethodVarName(const std::string &Name) { 2279 return GetMethodVarName(&CGM.getContext().Idents.get(Name)); 2280} 2281 2282llvm::Constant *CGObjCCommonMac::GetMethodVarType(const std::string &Name) { 2283 llvm::GlobalVariable *&Entry = MethodVarTypes[Name]; 2284 2285 if (!Entry) { 2286 llvm::Constant *C = llvm::ConstantArray::get(Name); 2287 Entry = 2288 new llvm::GlobalVariable(C->getType(), false, 2289 llvm::GlobalValue::InternalLinkage, 2290 C, "\01L_OBJC_METH_VAR_TYPE_", 2291 &CGM.getModule()); 2292 Entry->setSection("__TEXT,__cstring,cstring_literals"); 2293 UsedGlobals.push_back(Entry); 2294 } 2295 2296 return getConstantGEP(Entry, 0, 0); 2297} 2298 2299// FIXME: Merge into a single cstring creation function. 2300llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D) { 2301 std::string TypeStr; 2302 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D), 2303 TypeStr); 2304 return GetMethodVarType(TypeStr); 2305} 2306 2307// FIXME: Merge into a single cstring creation function. 2308llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) { 2309 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 2310 2311 if (!Entry) { 2312 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName()); 2313 Entry = 2314 new llvm::GlobalVariable(C->getType(), false, 2315 llvm::GlobalValue::InternalLinkage, 2316 C, "\01L_OBJC_PROP_NAME_ATTR_", 2317 &CGM.getModule()); 2318 Entry->setSection("__TEXT,__cstring,cstring_literals"); 2319 UsedGlobals.push_back(Entry); 2320 } 2321 2322 return getConstantGEP(Entry, 0, 0); 2323} 2324 2325// FIXME: Merge into a single cstring creation function. 2326// FIXME: This Decl should be more precise. 2327llvm::Constant *CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 2328 const Decl *Container) { 2329 std::string TypeStr; 2330 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr); 2331 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 2332} 2333 2334void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, 2335 const ObjCContainerDecl *CD, 2336 std::string &NameOut) { 2337 // FIXME: Find the mangling GCC uses. 2338 NameOut = (D->isInstanceMethod() ? "-" : "+"); 2339 NameOut += '['; 2340 assert (CD && "Missing container decl in GetNameForMethod"); 2341 NameOut += CD->getNameAsString(); 2342 // FIXME. For a method in a category, (CAT_NAME) is inserted here. 2343 // Right now! there is not enough info. to do this. 2344 NameOut += ' '; 2345 NameOut += D->getSelector().getAsString(); 2346 NameOut += ']'; 2347} 2348 2349/// GetFirstIvarInRecord - This routine returns the record for the 2350/// implementation of the fiven class OID. It also returns field 2351/// corresponding to the first ivar in the class in FIV. It also 2352/// returns the one before the first ivar. 2353/// 2354const RecordDecl *CGObjCCommonMac::GetFirstIvarInRecord( 2355 const ObjCInterfaceDecl *OID, 2356 RecordDecl::field_iterator &FIV, 2357 RecordDecl::field_iterator &PIV) { 2358 int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); 2359 const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); 2360 RecordDecl::field_iterator ifield = RD->field_begin(); 2361 RecordDecl::field_iterator pfield = RD->field_end(); 2362 while (countSuperClassIvars-- > 0) { 2363 pfield = ifield; 2364 ++ifield; 2365 } 2366 FIV = ifield; 2367 PIV = pfield; 2368 return RD; 2369} 2370 2371void CGObjCMac::FinishModule() { 2372 EmitModuleInfo(); 2373 2374 // Emit the dummy bodies for any protocols which were referenced but 2375 // never defined. 2376 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator 2377 i = Protocols.begin(), e = Protocols.end(); i != e; ++i) { 2378 if (i->second->hasInitializer()) 2379 continue; 2380 2381 std::vector<llvm::Constant*> Values(5); 2382 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 2383 Values[1] = GetClassName(i->first); 2384 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 2385 Values[3] = Values[4] = 2386 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 2387 i->second->setLinkage(llvm::GlobalValue::InternalLinkage); 2388 i->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 2389 Values)); 2390 } 2391 2392 std::vector<llvm::Constant*> Used; 2393 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), 2394 e = UsedGlobals.end(); i != e; ++i) { 2395 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); 2396 } 2397 2398 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); 2399 llvm::GlobalValue *GV = 2400 new llvm::GlobalVariable(AT, false, 2401 llvm::GlobalValue::AppendingLinkage, 2402 llvm::ConstantArray::get(AT, Used), 2403 "llvm.used", 2404 &CGM.getModule()); 2405 2406 GV->setSection("llvm.metadata"); 2407 2408 // Add assembler directives to add lazy undefined symbol references 2409 // for classes which are referenced but not defined. This is 2410 // important for correct linker interaction. 2411 2412 // FIXME: Uh, this isn't particularly portable. 2413 std::stringstream s; 2414 2415 if (!CGM.getModule().getModuleInlineAsm().empty()) 2416 s << "\n"; 2417 2418 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(), 2419 e = LazySymbols.end(); i != e; ++i) { 2420 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n"; 2421 } 2422 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(), 2423 e = DefinedSymbols.end(); i != e; ++i) { 2424 s << "\t.objc_class_name_" << (*i)->getName() << "=0\n" 2425 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n"; 2426 } 2427 2428 CGM.getModule().appendModuleInlineAsm(s.str()); 2429} 2430 2431CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) 2432 : CGObjCCommonMac(cgm), 2433 ObjCTypes(cgm) 2434{ 2435 ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL; 2436 ObjCABI = 2; 2437} 2438 2439/* *** */ 2440 2441ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) 2442: CGM(cgm) 2443{ 2444 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 2445 ASTContext &Ctx = CGM.getContext(); 2446 2447 ShortTy = Types.ConvertType(Ctx.ShortTy); 2448 IntTy = Types.ConvertType(Ctx.IntTy); 2449 LongTy = Types.ConvertType(Ctx.LongTy); 2450 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 2451 2452 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 2453 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy); 2454 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 2455 2456 // FIXME: It would be nice to unify this with the opaque type, so 2457 // that the IR comes out a bit cleaner. 2458 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 2459 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 2460 2461 // I'm not sure I like this. The implicit coordination is a bit 2462 // gross. We should solve this in a reasonable fashion because this 2463 // is a pretty common task (match some runtime data structure with 2464 // an LLVM data structure). 2465 2466 // FIXME: This is leaked. 2467 // FIXME: Merge with rewriter code? 2468 2469 // struct _objc_super { 2470 // id self; 2471 // Class cls; 2472 // } 2473 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, 2474 SourceLocation(), 2475 &Ctx.Idents.get("_objc_super")); 2476 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 2477 Ctx.getObjCIdType(), 0, false)); 2478 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0, 2479 Ctx.getObjCClassType(), 0, false)); 2480 RD->completeDefinition(Ctx); 2481 2482 SuperCTy = Ctx.getTagDeclType(RD); 2483 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 2484 2485 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 2486 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 2487 2488 // struct _prop_t { 2489 // char *name; 2490 // char *attributes; 2491 // } 2492 PropertyTy = llvm::StructType::get(Int8PtrTy, 2493 Int8PtrTy, 2494 NULL); 2495 CGM.getModule().addTypeName("struct._prop_t", 2496 PropertyTy); 2497 2498 // struct _prop_list_t { 2499 // uint32_t entsize; // sizeof(struct _prop_t) 2500 // uint32_t count_of_properties; 2501 // struct _prop_t prop_list[count_of_properties]; 2502 // } 2503 PropertyListTy = llvm::StructType::get(IntTy, 2504 IntTy, 2505 llvm::ArrayType::get(PropertyTy, 0), 2506 NULL); 2507 CGM.getModule().addTypeName("struct._prop_list_t", 2508 PropertyListTy); 2509 // struct _prop_list_t * 2510 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 2511 2512 // struct _objc_method { 2513 // SEL _cmd; 2514 // char *method_type; 2515 // char *_imp; 2516 // } 2517 MethodTy = llvm::StructType::get(SelectorPtrTy, 2518 Int8PtrTy, 2519 Int8PtrTy, 2520 NULL); 2521 CGM.getModule().addTypeName("struct._objc_method", MethodTy); 2522 2523 // struct _objc_cache * 2524 CacheTy = llvm::OpaqueType::get(); 2525 CGM.getModule().addTypeName("struct._objc_cache", CacheTy); 2526 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 2527 2528 // Property manipulation functions. 2529 2530 // id objc_getProperty (id, SEL, ptrdiff_t, bool) 2531 std::vector<const llvm::Type*> Params; 2532 Params.push_back(ObjectPtrTy); 2533 Params.push_back(SelectorPtrTy); 2534 Params.push_back(LongTy); 2535 Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy)); 2536 GetPropertyFn = 2537 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2538 Params, 2539 false), 2540 "objc_getProperty"); 2541 2542 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) 2543 Params.clear(); 2544 Params.push_back(ObjectPtrTy); 2545 Params.push_back(SelectorPtrTy); 2546 Params.push_back(LongTy); 2547 Params.push_back(ObjectPtrTy); 2548 Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy)); 2549 Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy)); 2550 SetPropertyFn = 2551 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2552 Params, 2553 false), 2554 "objc_setProperty"); 2555 // Enumeration mutation. 2556 2557 Params.clear(); 2558 Params.push_back(ObjectPtrTy); 2559 EnumerationMutationFn = 2560 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2561 Params, 2562 false), 2563 "objc_enumerationMutation"); 2564 2565 // gc's API 2566 // id objc_read_weak (id *) 2567 Params.clear(); 2568 Params.push_back(PtrObjectPtrTy); 2569 GcReadWeakFn = 2570 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2571 Params, 2572 false), 2573 "objc_read_weak"); 2574 // id objc_assign_weak (id, id *) 2575 Params.clear(); 2576 Params.push_back(ObjectPtrTy); 2577 Params.push_back(PtrObjectPtrTy); 2578 GcAssignWeakFn = 2579 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2580 Params, 2581 false), 2582 "objc_assign_weak"); 2583 GcAssignGlobalFn = 2584 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2585 Params, 2586 false), 2587 "objc_assign_global"); 2588 GcAssignIvarFn = 2589 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2590 Params, 2591 false), 2592 "objc_assign_ivar"); 2593 GcAssignStrongCastFn = 2594 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2595 Params, 2596 false), 2597 "objc_assign_strongCast"); 2598} 2599 2600ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 2601 : ObjCCommonTypesHelper(cgm) 2602{ 2603 // struct _objc_method_description { 2604 // SEL name; 2605 // char *types; 2606 // } 2607 MethodDescriptionTy = 2608 llvm::StructType::get(SelectorPtrTy, 2609 Int8PtrTy, 2610 NULL); 2611 CGM.getModule().addTypeName("struct._objc_method_description", 2612 MethodDescriptionTy); 2613 2614 // struct _objc_method_description_list { 2615 // int count; 2616 // struct _objc_method_description[1]; 2617 // } 2618 MethodDescriptionListTy = 2619 llvm::StructType::get(IntTy, 2620 llvm::ArrayType::get(MethodDescriptionTy, 0), 2621 NULL); 2622 CGM.getModule().addTypeName("struct._objc_method_description_list", 2623 MethodDescriptionListTy); 2624 2625 // struct _objc_method_description_list * 2626 MethodDescriptionListPtrTy = 2627 llvm::PointerType::getUnqual(MethodDescriptionListTy); 2628 2629 // Protocol description structures 2630 2631 // struct _objc_protocol_extension { 2632 // uint32_t size; // sizeof(struct _objc_protocol_extension) 2633 // struct _objc_method_description_list *optional_instance_methods; 2634 // struct _objc_method_description_list *optional_class_methods; 2635 // struct _objc_property_list *instance_properties; 2636 // } 2637 ProtocolExtensionTy = 2638 llvm::StructType::get(IntTy, 2639 MethodDescriptionListPtrTy, 2640 MethodDescriptionListPtrTy, 2641 PropertyListPtrTy, 2642 NULL); 2643 CGM.getModule().addTypeName("struct._objc_protocol_extension", 2644 ProtocolExtensionTy); 2645 2646 // struct _objc_protocol_extension * 2647 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 2648 2649 // Handle recursive construction of Protocol and ProtocolList types 2650 2651 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(); 2652 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); 2653 2654 const llvm::Type *T = 2655 llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder), 2656 LongTy, 2657 llvm::ArrayType::get(ProtocolTyHolder, 0), 2658 NULL); 2659 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T); 2660 2661 // struct _objc_protocol { 2662 // struct _objc_protocol_extension *isa; 2663 // char *protocol_name; 2664 // struct _objc_protocol **_objc_protocol_list; 2665 // struct _objc_method_description_list *instance_methods; 2666 // struct _objc_method_description_list *class_methods; 2667 // } 2668 T = llvm::StructType::get(ProtocolExtensionPtrTy, 2669 Int8PtrTy, 2670 llvm::PointerType::getUnqual(ProtocolListTyHolder), 2671 MethodDescriptionListPtrTy, 2672 MethodDescriptionListPtrTy, 2673 NULL); 2674 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T); 2675 2676 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get()); 2677 CGM.getModule().addTypeName("struct._objc_protocol_list", 2678 ProtocolListTy); 2679 // struct _objc_protocol_list * 2680 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 2681 2682 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get()); 2683 CGM.getModule().addTypeName("struct._objc_protocol", ProtocolTy); 2684 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 2685 2686 // Class description structures 2687 2688 // struct _objc_ivar { 2689 // char *ivar_name; 2690 // char *ivar_type; 2691 // int ivar_offset; 2692 // } 2693 IvarTy = llvm::StructType::get(Int8PtrTy, 2694 Int8PtrTy, 2695 IntTy, 2696 NULL); 2697 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy); 2698 2699 // struct _objc_ivar_list * 2700 IvarListTy = llvm::OpaqueType::get(); 2701 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy); 2702 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 2703 2704 // struct _objc_method_list * 2705 MethodListTy = llvm::OpaqueType::get(); 2706 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy); 2707 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 2708 2709 // struct _objc_class_extension * 2710 ClassExtensionTy = 2711 llvm::StructType::get(IntTy, 2712 Int8PtrTy, 2713 PropertyListPtrTy, 2714 NULL); 2715 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy); 2716 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 2717 2718 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(); 2719 2720 // struct _objc_class { 2721 // Class isa; 2722 // Class super_class; 2723 // char *name; 2724 // long version; 2725 // long info; 2726 // long instance_size; 2727 // struct _objc_ivar_list *ivars; 2728 // struct _objc_method_list *methods; 2729 // struct _objc_cache *cache; 2730 // struct _objc_protocol_list *protocols; 2731 // char *ivar_layout; 2732 // struct _objc_class_ext *ext; 2733 // }; 2734 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder), 2735 llvm::PointerType::getUnqual(ClassTyHolder), 2736 Int8PtrTy, 2737 LongTy, 2738 LongTy, 2739 LongTy, 2740 IvarListPtrTy, 2741 MethodListPtrTy, 2742 CachePtrTy, 2743 ProtocolListPtrTy, 2744 Int8PtrTy, 2745 ClassExtensionPtrTy, 2746 NULL); 2747 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T); 2748 2749 ClassTy = cast<llvm::StructType>(ClassTyHolder.get()); 2750 CGM.getModule().addTypeName("struct._objc_class", ClassTy); 2751 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 2752 2753 // struct _objc_category { 2754 // char *category_name; 2755 // char *class_name; 2756 // struct _objc_method_list *instance_method; 2757 // struct _objc_method_list *class_method; 2758 // uint32_t size; // sizeof(struct _objc_category) 2759 // struct _objc_property_list *instance_properties;// category's @property 2760 // } 2761 CategoryTy = llvm::StructType::get(Int8PtrTy, 2762 Int8PtrTy, 2763 MethodListPtrTy, 2764 MethodListPtrTy, 2765 ProtocolListPtrTy, 2766 IntTy, 2767 PropertyListPtrTy, 2768 NULL); 2769 CGM.getModule().addTypeName("struct._objc_category", CategoryTy); 2770 2771 // Global metadata structures 2772 2773 // struct _objc_symtab { 2774 // long sel_ref_cnt; 2775 // SEL *refs; 2776 // short cls_def_cnt; 2777 // short cat_def_cnt; 2778 // char *defs[cls_def_cnt + cat_def_cnt]; 2779 // } 2780 SymtabTy = llvm::StructType::get(LongTy, 2781 SelectorPtrTy, 2782 ShortTy, 2783 ShortTy, 2784 llvm::ArrayType::get(Int8PtrTy, 0), 2785 NULL); 2786 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy); 2787 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 2788 2789 // struct _objc_module { 2790 // long version; 2791 // long size; // sizeof(struct _objc_module) 2792 // char *name; 2793 // struct _objc_symtab* symtab; 2794 // } 2795 ModuleTy = 2796 llvm::StructType::get(LongTy, 2797 LongTy, 2798 Int8PtrTy, 2799 SymtabPtrTy, 2800 NULL); 2801 CGM.getModule().addTypeName("struct._objc_module", ModuleTy); 2802 2803 // Message send functions. 2804 2805 // id objc_msgSend (id, SEL, ...) 2806 std::vector<const llvm::Type*> Params; 2807 Params.push_back(ObjectPtrTy); 2808 Params.push_back(SelectorPtrTy); 2809 MessageSendFn = 2810 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2811 Params, 2812 true), 2813 "objc_msgSend"); 2814 2815 // id objc_msgSend_stret (id, SEL, ...) 2816 Params.clear(); 2817 Params.push_back(ObjectPtrTy); 2818 Params.push_back(SelectorPtrTy); 2819 MessageSendStretFn = 2820 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2821 Params, 2822 true), 2823 "objc_msgSend_stret"); 2824 2825 // 2826 Params.clear(); 2827 Params.push_back(ObjectPtrTy); 2828 Params.push_back(SelectorPtrTy); 2829 // FIXME: This should be long double on x86_64? 2830 // [double | long double] objc_msgSend_fpret(id self, SEL op, ...) 2831 MessageSendFpretFn = 2832 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::DoubleTy, 2833 Params, 2834 true), 2835 "objc_msgSend_fpret"); 2836 2837 // id objc_msgSendSuper(struct objc_super *super, SEL op, ...) 2838 Params.clear(); 2839 Params.push_back(SuperPtrTy); 2840 Params.push_back(SelectorPtrTy); 2841 MessageSendSuperFn = 2842 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2843 Params, 2844 true), 2845 "objc_msgSendSuper"); 2846 2847 // void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super, 2848 // SEL op, ...) 2849 Params.clear(); 2850 Params.push_back(Int8PtrTy); 2851 Params.push_back(SuperPtrTy); 2852 Params.push_back(SelectorPtrTy); 2853 MessageSendSuperStretFn = 2854 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2855 Params, 2856 true), 2857 "objc_msgSendSuper_stret"); 2858 2859 // There is no objc_msgSendSuper_fpret? How can that work? 2860 MessageSendSuperFpretFn = MessageSendSuperFn; 2861 2862 // FIXME: This is the size of the setjmp buffer and should be 2863 // target specific. 18 is what's used on 32-bit X86. 2864 uint64_t SetJmpBufferSize = 18; 2865 2866 // Exceptions 2867 const llvm::Type *StackPtrTy = 2868 llvm::ArrayType::get(llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 4); 2869 2870 ExceptionDataTy = 2871 llvm::StructType::get(llvm::ArrayType::get(llvm::Type::Int32Ty, 2872 SetJmpBufferSize), 2873 StackPtrTy, NULL); 2874 CGM.getModule().addTypeName("struct._objc_exception_data", 2875 ExceptionDataTy); 2876 2877 Params.clear(); 2878 Params.push_back(ObjectPtrTy); 2879 ExceptionThrowFn = 2880 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2881 Params, 2882 false), 2883 "objc_exception_throw"); 2884 2885 Params.clear(); 2886 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 2887 ExceptionTryEnterFn = 2888 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2889 Params, 2890 false), 2891 "objc_exception_try_enter"); 2892 ExceptionTryExitFn = 2893 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2894 Params, 2895 false), 2896 "objc_exception_try_exit"); 2897 ExceptionExtractFn = 2898 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy, 2899 Params, 2900 false), 2901 "objc_exception_extract"); 2902 2903 Params.clear(); 2904 Params.push_back(ClassPtrTy); 2905 Params.push_back(ObjectPtrTy); 2906 ExceptionMatchFn = 2907 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty, 2908 Params, 2909 false), 2910 "objc_exception_match"); 2911 2912 // synchronized APIs 2913 // void objc_sync_enter (id) 2914 Params.clear(); 2915 Params.push_back(ObjectPtrTy); 2916 SyncEnterFn = 2917 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2918 Params, 2919 false), 2920 "objc_sync_enter"); 2921 // void objc_sync_exit (id) 2922 SyncExitFn = 2923 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy, 2924 Params, 2925 false), 2926 "objc_sync_exit"); 2927 2928 2929 Params.clear(); 2930 Params.push_back(llvm::PointerType::getUnqual(llvm::Type::Int32Ty)); 2931 SetJmpFn = 2932 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty, 2933 Params, 2934 false), 2935 "_setjmp"); 2936 2937} 2938 2939ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) 2940: ObjCCommonTypesHelper(cgm) 2941{ 2942 // struct _method_list_t { 2943 // uint32_t entsize; // sizeof(struct _objc_method) 2944 // uint32_t method_count; 2945 // struct _objc_method method_list[method_count]; 2946 // } 2947 MethodListnfABITy = llvm::StructType::get(IntTy, 2948 IntTy, 2949 llvm::ArrayType::get(MethodTy, 0), 2950 NULL); 2951 CGM.getModule().addTypeName("struct.__method_list_t", 2952 MethodListnfABITy); 2953 // struct method_list_t * 2954 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); 2955 2956 // struct _protocol_t { 2957 // id isa; // NULL 2958 // const char * const protocol_name; 2959 // const struct _protocol_list_t * protocol_list; // super protocols 2960 // const struct method_list_t * const instance_methods; 2961 // const struct method_list_t * const class_methods; 2962 // const struct method_list_t *optionalInstanceMethods; 2963 // const struct method_list_t *optionalClassMethods; 2964 // const struct _prop_list_t * properties; 2965 // const uint32_t size; // sizeof(struct _protocol_t) 2966 // const uint32_t flags; // = 0 2967 // } 2968 2969 // Holder for struct _protocol_list_t * 2970 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); 2971 2972 ProtocolnfABITy = llvm::StructType::get(ObjectPtrTy, 2973 Int8PtrTy, 2974 llvm::PointerType::getUnqual( 2975 ProtocolListTyHolder), 2976 MethodListnfABIPtrTy, 2977 MethodListnfABIPtrTy, 2978 MethodListnfABIPtrTy, 2979 MethodListnfABIPtrTy, 2980 PropertyListPtrTy, 2981 IntTy, 2982 IntTy, 2983 NULL); 2984 CGM.getModule().addTypeName("struct._protocol_t", 2985 ProtocolnfABITy); 2986 2987 // struct _objc_protocol_list { 2988 // long protocol_count; // Note, this is 32/64 bit 2989 // struct _protocol_t[protocol_count]; 2990 // } 2991 ProtocolListnfABITy = llvm::StructType::get(LongTy, 2992 llvm::ArrayType::get( 2993 ProtocolnfABITy, 0), 2994 NULL); 2995 CGM.getModule().addTypeName("struct._objc_protocol_list", 2996 ProtocolListnfABITy); 2997 2998 // struct _objc_protocol_list* 2999 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); 3000 3001 // FIXME! Is this doing the right thing? 3002 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo( 3003 ProtocolListnfABIPtrTy); 3004 3005 // struct _ivar_t { 3006 // unsigned long int *offset; // pointer to ivar offset location 3007 // char *name; 3008 // char *type; 3009 // uint32_t alignment; 3010 // uint32_t size; 3011 // } 3012 IvarnfABITy = llvm::StructType::get(llvm::PointerType::getUnqual(LongTy), 3013 Int8PtrTy, 3014 Int8PtrTy, 3015 IntTy, 3016 IntTy, 3017 NULL); 3018 CGM.getModule().addTypeName("struct._ivar_t", IvarnfABITy); 3019 3020 // struct _ivar_list_t { 3021 // uint32 entsize; // sizeof(struct _ivar_t) 3022 // uint32 count; 3023 // struct _iver_t list[count]; 3024 // } 3025 IvarListnfABITy = llvm::StructType::get(IntTy, 3026 IntTy, 3027 llvm::ArrayType::get( 3028 IvarnfABITy, 0), 3029 NULL); 3030 CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABITy); 3031 3032 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); 3033 3034 // struct _class_ro_t { 3035 // uint32_t const flags; 3036 // uint32_t const instanceStart; 3037 // uint32_t const instanceSize; 3038 // uint32_t const reserved; // only when building for 64bit targets 3039 // const uint8_t * const ivarLayout; 3040 // const char *const name; 3041 // const struct _method_list_t * const baseMethods; 3042 // const struct _objc_protocol_list *const baseProtocols; 3043 // const struct _ivar_list_t *const ivars; 3044 // const uint8_t * const weakIvarLayout; 3045 // const struct _prop_list_t * const properties; 3046 // } 3047 3048 // FIXME. Add 'reserved' field in 64bit abi mode! 3049 ClassRonfABITy = llvm::StructType::get(IntTy, 3050 IntTy, 3051 IntTy, 3052 Int8PtrTy, 3053 Int8PtrTy, 3054 MethodListnfABIPtrTy, 3055 ProtocolListnfABIPtrTy, 3056 IvarListnfABIPtrTy, 3057 Int8PtrTy, 3058 PropertyListPtrTy, 3059 NULL); 3060 CGM.getModule().addTypeName("struct._class_ro_t", 3061 ClassRonfABITy); 3062 3063 // ImpnfABITy - LLVM for id (*)(id, SEL, ...) 3064 std::vector<const llvm::Type*> Params; 3065 Params.push_back(ObjectPtrTy); 3066 Params.push_back(SelectorPtrTy); 3067 ImpnfABITy = llvm::PointerType::getUnqual( 3068 llvm::FunctionType::get(ObjectPtrTy, Params, false)); 3069 3070 // struct _class_t { 3071 // struct _class_t *isa; 3072 // struct _class_t * const superclass; 3073 // void *cache; 3074 // IMP *vtable; 3075 // struct class_ro_t *ro; 3076 // } 3077 3078 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(); 3079 ClassnfABITy = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder), 3080 llvm::PointerType::getUnqual(ClassTyHolder), 3081 CachePtrTy, 3082 llvm::PointerType::getUnqual(ImpnfABITy), 3083 llvm::PointerType::getUnqual( 3084 ClassRonfABITy), 3085 NULL); 3086 CGM.getModule().addTypeName("struct._class_t", ClassnfABITy); 3087 3088 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo( 3089 ClassnfABITy); 3090 3091 // LLVM for struct _class_t * 3092 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); 3093 3094 // struct _category_t { 3095 // const char * const name; 3096 // struct _class_t *const cls; 3097 // const struct _method_list_t * const instance_methods; 3098 // const struct _method_list_t * const class_methods; 3099 // const struct _protocol_list_t * const protocols; 3100 // const struct _prop_list_t * const properties; 3101 // } 3102 CategorynfABITy = llvm::StructType::get(Int8PtrTy, 3103 ClassnfABIPtrTy, 3104 MethodListnfABIPtrTy, 3105 MethodListnfABIPtrTy, 3106 ProtocolListnfABIPtrTy, 3107 PropertyListPtrTy, 3108 NULL); 3109 CGM.getModule().addTypeName("struct._category_t", CategorynfABITy); 3110 3111} 3112 3113llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { 3114 FinishNonFragileABIModule(); 3115 3116 return NULL; 3117} 3118 3119void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { 3120 // nonfragile abi has no module definition. 3121 std::vector<llvm::Constant*> Used; 3122 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), 3123 e = UsedGlobals.end(); i != e; ++i) { 3124 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); 3125 } 3126 3127 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); 3128 llvm::GlobalValue *GV = 3129 new llvm::GlobalVariable(AT, false, 3130 llvm::GlobalValue::AppendingLinkage, 3131 llvm::ConstantArray::get(AT, Used), 3132 "llvm.used", 3133 &CGM.getModule()); 3134 3135 GV->setSection("llvm.metadata"); 3136 3137} 3138 3139// Metadata flags 3140enum MetaDataDlags { 3141 CLS = 0x0, 3142 CLS_META = 0x1, 3143 CLS_ROOT = 0x2, 3144 OBJC2_CLS_HIDDEN = 0x10, 3145 CLS_EXCEPTION = 0x20 3146}; 3147/// BuildClassRoTInitializer - generate meta-data for: 3148/// struct _class_ro_t { 3149/// uint32_t const flags; 3150/// uint32_t const instanceStart; 3151/// uint32_t const instanceSize; 3152/// uint32_t const reserved; // only when building for 64bit targets 3153/// const uint8_t * const ivarLayout; 3154/// const char *const name; 3155/// const struct _method_list_t * const baseMethods; 3156/// const struct _objc_protocol_list *const baseProtocols; 3157/// const struct _ivar_list_t *const ivars; 3158/// const uint8_t * const weakIvarLayout; 3159/// const struct _prop_list_t * const properties; 3160/// } 3161/// 3162llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( 3163 unsigned flags, 3164 unsigned InstanceStart, 3165 unsigned InstanceSize, 3166 const ObjCImplementationDecl *ID) { 3167 std::string ClassName = ID->getNameAsString(); 3168 std::vector<llvm::Constant*> Values(10); // 11 for 64bit targets! 3169 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); 3170 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); 3171 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); 3172 // FIXME. For 64bit targets add 0 here. 3173 Values[ 3] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 3174 Values[ 4] = GetClassName(ID->getIdentifier()); 3175 // const struct _method_list_t * const baseMethods; 3176 std::vector<llvm::Constant*> Methods; 3177 std::string MethodListName("\01l_OBJC_$_"); 3178 if (flags & CLS_META) { 3179 MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); 3180 for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(), 3181 e = ID->classmeth_end(); i != e; ++i) { 3182 // Class methods should always be defined. 3183 Methods.push_back(GetMethodConstant(*i)); 3184 } 3185 } else { 3186 MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); 3187 for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(), 3188 e = ID->instmeth_end(); i != e; ++i) { 3189 // Instance methods should always be defined. 3190 Methods.push_back(GetMethodConstant(*i)); 3191 } 3192 } 3193 // FIXME. Section may always be .data 3194 Values[ 5] = EmitMethodList(MethodListName, 3195 "__DATA, __objc_const", Methods); 3196 Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 3197 if (flags & CLS_META) 3198 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 3199 else 3200 Values[ 7] = EmitIvarList(ID); 3201 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 3202 if (flags & CLS_META) 3203 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 3204 else 3205 Values[ 9] = 3206 EmitPropertyList( 3207 "\01l_OBJC_$_PROP_LIST_" + ID->getNameAsString(), 3208 ID, ID->getClassInterface(), ObjCTypes); 3209 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, 3210 Values); 3211 llvm::GlobalVariable *CLASS_RO_GV = 3212 new llvm::GlobalVariable(ObjCTypes.ClassRonfABITy, false, 3213 llvm::GlobalValue::InternalLinkage, 3214 Init, 3215 (flags & CLS_META) ? 3216 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : 3217 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, 3218 &CGM.getModule()); 3219 CLASS_RO_GV->setSection("__DATA, __objc_const"); 3220 UsedGlobals.push_back(CLASS_RO_GV); 3221 return CLASS_RO_GV; 3222 3223} 3224 3225/// BuildClassMetaData - This routine defines that to-level meta-data 3226/// for the given ClassName for: 3227/// struct _class_t { 3228/// struct _class_t *isa; 3229/// struct _class_t * const superclass; 3230/// void *cache; 3231/// IMP *vtable; 3232/// struct class_ro_t *ro; 3233/// } 3234/// 3235llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( 3236 std::string &ClassName, 3237 llvm::Constant *IsAGV, 3238 llvm::Constant *SuperClassGV, 3239 llvm::Constant *ClassRoGV) { 3240 std::vector<llvm::Constant*> Values(5); 3241 Values[0] = IsAGV; 3242 Values[1] = SuperClassGV 3243 ? SuperClassGV 3244 : llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); 3245 Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar 3246 Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar 3247 Values[4] = ClassRoGV; // &CLASS_RO_GV 3248 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, 3249 Values); 3250 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(ClassName); 3251 if (GV) 3252 GV->setInitializer(Init); 3253 else 3254 GV = 3255 new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, 3256 llvm::GlobalValue::ExternalLinkage, 3257 Init, 3258 ClassName, 3259 &CGM.getModule()); 3260 GV->setSection("__DATA, __objc_const"); 3261 UsedGlobals.push_back(GV); 3262 // FIXME! why? 3263 GV->setAlignment(32); 3264 return GV; 3265} 3266 3267void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { 3268 std::string ClassName = ID->getNameAsString(); 3269 if (!ObjCEmptyCacheVar) { 3270 ObjCEmptyCacheVar = new llvm::GlobalVariable( 3271 ObjCTypes.CachePtrTy, 3272 false, 3273 llvm::GlobalValue::ExternalLinkage, 3274 0, 3275 "\01_objc_empty_cache", 3276 &CGM.getModule()); 3277 UsedGlobals.push_back(ObjCEmptyCacheVar); 3278 3279 ObjCEmptyVtableVar = new llvm::GlobalVariable( 3280 llvm::PointerType::getUnqual( 3281 ObjCTypes.ImpnfABITy), 3282 false, 3283 llvm::GlobalValue::ExternalLinkage, 3284 0, 3285 "\01_objc_empty_vtable", 3286 &CGM.getModule()); 3287 UsedGlobals.push_back(ObjCEmptyVtableVar); 3288 } 3289 assert(ID->getClassInterface() && 3290 "CGObjCNonFragileABIMac::GenerateClass - class is 0"); 3291 uint32_t InstanceStart = 3292 CGM.getTargetData().getTypePaddedSize(ObjCTypes.ClassnfABITy); 3293 uint32_t InstanceSize = InstanceStart; 3294 uint32_t flags = CLS_META; 3295 std::string ObjCMetaClassName("\01_OBJC_METACLASS_$_"); 3296 std::string ObjCClassName("\01_OBJC_CLASS_$_"); 3297 3298 llvm::GlobalVariable *SuperClassGV, *IsAGV; 3299 3300 if (IsClassHidden(ID->getClassInterface())) 3301 flags |= OBJC2_CLS_HIDDEN; 3302 if (!ID->getClassInterface()->getSuperClass()) { 3303 // class is root 3304 flags |= CLS_ROOT; 3305 std::string SuperClassName = ObjCClassName + ClassName; 3306 SuperClassGV = CGM.getModule().getGlobalVariable(SuperClassName); 3307 if (!SuperClassGV) 3308 SuperClassGV = 3309 new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, 3310 llvm::GlobalValue::ExternalLinkage, 3311 0, 3312 SuperClassName, 3313 &CGM.getModule()); 3314 UsedGlobals.push_back(SuperClassGV); 3315 std::string IsAClassName = ObjCMetaClassName + ClassName; 3316 IsAGV = CGM.getModule().getGlobalVariable(IsAClassName); 3317 if (!IsAGV) 3318 IsAGV = 3319 new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, 3320 llvm::GlobalValue::ExternalLinkage, 3321 0, 3322 IsAClassName, 3323 &CGM.getModule()); 3324 UsedGlobals.push_back(IsAGV); 3325 } else { 3326 // Has a root. Current class is not a root. 3327 std::string RootClassName = 3328 ID->getClassInterface()->getSuperClass()->getNameAsString(); 3329 std::string SuperClassName = ObjCMetaClassName + RootClassName; 3330 SuperClassGV = CGM.getModule().getGlobalVariable(SuperClassName); 3331 if (!SuperClassGV) 3332 SuperClassGV = 3333 new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, 3334 llvm::GlobalValue::ExternalLinkage, 3335 0, 3336 SuperClassName, 3337 &CGM.getModule()); 3338 UsedGlobals.push_back(SuperClassGV); 3339 IsAGV = SuperClassGV; 3340 } 3341 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, 3342 InstanceStart, 3343 InstanceSize,ID); 3344 std::string TClassName = ObjCMetaClassName + ClassName; 3345 llvm::GlobalVariable *MetaTClass = 3346 BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV); 3347 3348 // Metadata for the class 3349 flags = CLS; 3350 if (IsClassHidden(ID->getClassInterface())) 3351 flags |= OBJC2_CLS_HIDDEN; 3352 if (!ID->getClassInterface()->getSuperClass()) { 3353 flags |= CLS_ROOT; 3354 SuperClassGV = 0; 3355 } 3356 else { 3357 // Has a root. Current class is not a root. 3358 std::string RootClassName = 3359 ID->getClassInterface()->getSuperClass()->getNameAsString(); 3360 std::string SuperClassName = ObjCClassName + RootClassName; 3361 SuperClassGV = CGM.getModule().getGlobalVariable(SuperClassName); 3362 if (!SuperClassGV) 3363 SuperClassGV = 3364 new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, 3365 llvm::GlobalValue::ExternalLinkage, 3366 0, 3367 SuperClassName, 3368 &CGM.getModule()); 3369 UsedGlobals.push_back(SuperClassGV); 3370 3371 } 3372 3373 InstanceStart = InstanceSize = 0; 3374 if (ObjCInterfaceDecl *OID = 3375 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface())) { 3376 // FIXME. Share this with the one in EmitIvarList. 3377 const llvm::Type *InterfaceTy = 3378 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(OID)); 3379 const llvm::StructLayout *Layout = 3380 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy)); 3381 3382 RecordDecl::field_iterator firstField, lastField; 3383 const RecordDecl *RD = GetFirstIvarInRecord(OID, firstField, lastField); 3384 3385 for (RecordDecl::field_iterator e = RD->field_end(), 3386 ifield = firstField; ifield != e; ++ifield) 3387 lastField = ifield; 3388 3389 if (lastField != RD->field_end()) { 3390 FieldDecl *Field = *lastField; 3391 const llvm::Type *FieldTy = 3392 CGM.getTypes().ConvertTypeForMem(Field->getType()); 3393 unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy); 3394 InstanceSize = Layout->getElementOffset( 3395 CGM.getTypes().getLLVMFieldNo(Field)) + 3396 Size; 3397 if (firstField == RD->field_end()) 3398 InstanceStart = InstanceSize; 3399 else 3400 InstanceStart = Layout->getElementOffset(CGM.getTypes(). 3401 getLLVMFieldNo(*firstField)); 3402 } 3403 } 3404 CLASS_RO_GV = BuildClassRoTInitializer(flags, 3405 InstanceStart, 3406 InstanceSize, 3407 ID); 3408 3409 TClassName = ObjCClassName + ClassName; 3410 BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); 3411} 3412 3413/// GenerateCategory - Build metadata for a category implementation. 3414/// struct _category_t { 3415/// const char * const name; 3416/// struct _class_t *const cls; 3417/// const struct _method_list_t * const instance_methods; 3418/// const struct _method_list_t * const class_methods; 3419/// const struct _protocol_list_t * const protocols; 3420/// const struct _prop_list_t * const properties; 3421/// } 3422/// 3423void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) 3424{ 3425 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 3426 const char *Prefix = "\01l_OBJC_$_CATEGORY_"; 3427 std::string ExtCatName(Prefix + Interface->getNameAsString()+ 3428 "_$_" + OCD->getNameAsString()); 3429 std::string ExtClassName("\01_OBJC_CLASS_$_" + Interface->getNameAsString()); 3430 3431 std::vector<llvm::Constant*> Values(6); 3432 Values[0] = GetClassName(OCD->getIdentifier()); 3433 // meta-class entry symbol 3434 llvm::GlobalVariable *ClassGV = 3435 CGM.getModule().getGlobalVariable(ExtClassName); 3436 if (!ClassGV) 3437 ClassGV = 3438 new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, 3439 llvm::GlobalValue::ExternalLinkage, 3440 0, 3441 ExtClassName, 3442 &CGM.getModule()); 3443 UsedGlobals.push_back(ClassGV); 3444 Values[1] = ClassGV; 3445 std::vector<llvm::Constant*> Methods; 3446 std::string MethodListName(Prefix); 3447 MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + 3448 "_$_" + OCD->getNameAsString(); 3449 3450 for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(), 3451 e = OCD->instmeth_end(); i != e; ++i) { 3452 // Instance methods should always be defined. 3453 Methods.push_back(GetMethodConstant(*i)); 3454 } 3455 3456 Values[2] = EmitMethodList(MethodListName, 3457 "__DATA, __objc_const", 3458 Methods); 3459 3460 MethodListName = Prefix; 3461 MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + 3462 OCD->getNameAsString(); 3463 Methods.clear(); 3464 for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(), 3465 e = OCD->classmeth_end(); i != e; ++i) { 3466 // Class methods should always be defined. 3467 Methods.push_back(GetMethodConstant(*i)); 3468 } 3469 3470 Values[3] = EmitMethodList(MethodListName, 3471 "__DATA, __objc_const", 3472 Methods); 3473 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); 3474 const ObjCCategoryDecl *Category = 3475 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 3476 std::string ExtName(Interface->getNameAsString() + "_$_" + 3477 OCD->getNameAsString()); 3478 Values[5] = 3479 EmitPropertyList(std::string("\01l_OBJC_$_PROP_LIST_") + ExtName, 3480 OCD, Category, ObjCTypes); 3481 llvm::Constant *Init = 3482 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 3483 Values); 3484 llvm::GlobalVariable *GCATV 3485 = new llvm::GlobalVariable(ObjCTypes.CategorynfABITy, 3486 false, 3487 llvm::GlobalValue::InternalLinkage, 3488 Init, 3489 ExtCatName, 3490 &CGM.getModule()); 3491 GCATV->setSection("__DATA, __objc_const"); 3492 UsedGlobals.push_back(GCATV); 3493 DefinedCategories.push_back(GCATV); 3494} 3495 3496/// GetMethodConstant - Return a struct objc_method constant for the 3497/// given method if it has been defined. The result is null if the 3498/// method has not been defined. The return value has type MethodPtrTy. 3499llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( 3500 const ObjCMethodDecl *MD) { 3501 // FIXME: Use DenseMap::lookup 3502 llvm::Function *Fn = MethodDefinitions[MD]; 3503 if (!Fn) 3504 return 0; 3505 3506 std::vector<llvm::Constant*> Method(3); 3507 Method[0] = 3508 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 3509 ObjCTypes.SelectorPtrTy); 3510 Method[1] = GetMethodVarType(MD); 3511 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 3512 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 3513} 3514 3515/// EmitMethodList - Build meta-data for method declarations 3516/// struct _method_list_t { 3517/// uint32_t entsize; // sizeof(struct _objc_method) 3518/// uint32_t method_count; 3519/// struct _objc_method method_list[method_count]; 3520/// } 3521/// 3522llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( 3523 const std::string &Name, 3524 const char *Section, 3525 const ConstantVector &Methods) { 3526 // Return null for empty list. 3527 if (Methods.empty()) 3528 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); 3529 3530 std::vector<llvm::Constant*> Values(3); 3531 // sizeof(struct _objc_method) 3532 unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.MethodTy); 3533 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 3534 // method_count 3535 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 3536 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 3537 Methods.size()); 3538 Values[2] = llvm::ConstantArray::get(AT, Methods); 3539 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 3540 3541 llvm::GlobalVariable *GV = 3542 new llvm::GlobalVariable(Init->getType(), false, 3543 llvm::GlobalValue::InternalLinkage, 3544 Init, 3545 Name, 3546 &CGM.getModule()); 3547 GV->setSection(Section); 3548 UsedGlobals.push_back(GV); 3549 return llvm::ConstantExpr::getBitCast(GV, 3550 ObjCTypes.MethodListnfABIPtrTy); 3551} 3552 3553llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( 3554 const ObjCImplementationDecl *ID, 3555 const ObjCIvarDecl *Ivar, 3556 unsigned long int Offset) { 3557 3558 std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.' 3559 + Ivar->getNameAsString()); 3560 llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset); 3561 3562 llvm::GlobalVariable *IvarOffsetGV = 3563 CGM.getModule().getGlobalVariable(ExternalName); 3564 if (IvarOffsetGV) { 3565 // ivar offset symbol already built due to user code referencing it. 3566 IvarOffsetGV->setInitializer(Init); 3567 UsedGlobals.push_back(IvarOffsetGV); 3568 return IvarOffsetGV; 3569 } 3570 3571 IvarOffsetGV = 3572 new llvm::GlobalVariable(Init->getType(), 3573 false, 3574 llvm::GlobalValue::ExternalLinkage, 3575 Init, 3576 ExternalName, 3577 &CGM.getModule()); 3578 // @private and @package have hidden visibility. 3579 bool globalVisibility = (Ivar->getAccessControl() == ObjCIvarDecl::Public || 3580 Ivar->getAccessControl() == ObjCIvarDecl::Protected); 3581 if (!globalVisibility) 3582 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); 3583 IvarOffsetGV->setSection("__DATA, __objc_const"); 3584 UsedGlobals.push_back(IvarOffsetGV); 3585 3586 return llvm::ConstantExpr::getBitCast( 3587 IvarOffsetGV, 3588 llvm::PointerType::getUnqual(ObjCTypes.LongTy)); 3589} 3590 3591/// EmitIvarList - Emit the ivar list for the given 3592/// implementation. If ForClass is true the list of class ivars 3593/// (i.e. metaclass ivars) is emitted, otherwise the list of 3594/// interface ivars will be emitted. The return value has type 3595/// IvarListnfABIPtrTy. 3596/// struct _ivar_t { 3597/// unsigned long int *offset; // pointer to ivar offset location 3598/// char *name; 3599/// char *type; 3600/// uint32_t alignment; 3601/// uint32_t size; 3602/// } 3603/// struct _ivar_list_t { 3604/// uint32 entsize; // sizeof(struct _ivar_t) 3605/// uint32 count; 3606/// struct _iver_t list[count]; 3607/// } 3608/// 3609llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( 3610 const ObjCImplementationDecl *ID) { 3611 3612 std::vector<llvm::Constant*> Ivars, Ivar(5); 3613 3614 const ObjCInterfaceDecl *OID = ID->getClassInterface(); 3615 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); 3616 3617 // FIXME. Consolidate this with similar code in GenerateClass. 3618 const llvm::Type *InterfaceTy = 3619 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType( 3620 const_cast<ObjCInterfaceDecl*>(OID))); 3621 const llvm::StructLayout *Layout = 3622 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy)); 3623 3624 RecordDecl::field_iterator i,p; 3625 const RecordDecl *RD = GetFirstIvarInRecord(OID, i,p); 3626 ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(); 3627 3628 for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) { 3629 FieldDecl *Field = *i; 3630 unsigned long offset = Layout->getElementOffset(CGM.getTypes(). 3631 getLLVMFieldNo(Field)); 3632 const ObjCIvarDecl *ivarDecl = *I++; 3633 Ivar[0] = EmitIvarOffsetVar(ID, ivarDecl, offset); 3634 if (Field->getIdentifier()) 3635 Ivar[1] = GetMethodVarName(Field->getIdentifier()); 3636 else 3637 Ivar[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 3638 std::string TypeStr; 3639 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); 3640 Ivar[2] = GetMethodVarType(TypeStr); 3641 const llvm::Type *FieldTy = 3642 CGM.getTypes().ConvertTypeForMem(Field->getType()); 3643 unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy); 3644 unsigned Align = CGM.getContext().getPreferredTypeAlign( 3645 Field->getType().getTypePtr()) >> 3; 3646 Align = llvm::Log2_32(Align); 3647 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); 3648 // NOTE. Size of a bitfield does not match gcc's, because of the way 3649 // bitfields are treated special in each. But I am told that 'size' 3650 // for bitfield ivars is ignored by the runtime so it does not matter. 3651 // (even if it matters, some day, there is enough info. to get the bitfield 3652 // right! 3653 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 3654 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); 3655 } 3656 // Return null for empty list. 3657 if (Ivars.empty()) 3658 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); 3659 std::vector<llvm::Constant*> Values(3); 3660 unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.IvarnfABITy); 3661 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 3662 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 3663 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, 3664 Ivars.size()); 3665 Values[2] = llvm::ConstantArray::get(AT, Ivars); 3666 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 3667 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; 3668 llvm::GlobalVariable *GV = 3669 new llvm::GlobalVariable(Init->getType(), false, 3670 llvm::GlobalValue::InternalLinkage, 3671 Init, 3672 Prefix + OID->getNameAsString(), 3673 &CGM.getModule()); 3674 3675 GV->setSection("__DATA, __objc_const"); 3676 3677 UsedGlobals.push_back(GV); 3678 return llvm::ConstantExpr::getBitCast(GV, 3679 ObjCTypes.IvarListnfABIPtrTy); 3680} 3681/* *** */ 3682 3683CodeGen::CGObjCRuntime * 3684CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 3685 return new CGObjCMac(CGM); 3686} 3687 3688CodeGen::CGObjCRuntime * 3689CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) { 3690 return new CGObjCNonFragileABIMac(CGM); 3691} 3692