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