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