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