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