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