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