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