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