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