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