CGObjCMac.cpp revision b768807c49a1c7085def099b848631856af766fa
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/Module.h" 24#include "llvm/Support/IRBuilder.h" 25#include "llvm/Target/TargetData.h" 26#include <sstream> 27 28using namespace clang; 29using namespace CodeGen; 30 31namespace { 32 33 typedef std::vector<llvm::Constant*> ConstantVector; 34 35 // FIXME: We should find a nicer way to make the labels for 36 // metadata, string concatenation is lame. 37 38/// ObjCTypesHelper - Helper class that encapsulates lazy 39/// construction of varies types used during ObjC generation. 40class ObjCTypesHelper { 41private: 42 CodeGen::CodeGenModule &CGM; 43 44 llvm::Function *MessageSendFn, *MessageSendStretFn; 45 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn; 46 47public: 48 const llvm::Type *ShortTy, *IntTy, *LongTy; 49 const llvm::Type *Int8PtrTy; 50 51 /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 52 const llvm::Type *ObjectPtrTy; 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 /// SymtabTy - LLVM type for struct objc_symtab. 70 const llvm::StructType *SymtabTy; 71 /// SymtabPtrTy - LLVM type for struct objc_symtab *. 72 const llvm::Type *SymtabPtrTy; 73 /// ModuleTy - LLVM type for struct objc_module. 74 const llvm::StructType *ModuleTy; 75 76 /// ProtocolTy - LLVM type for struct objc_protocol. 77 const llvm::StructType *ProtocolTy; 78 /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 79 const llvm::Type *ProtocolPtrTy; 80 /// ProtocolExtensionTy - LLVM type for struct 81 /// objc_protocol_extension. 82 const llvm::StructType *ProtocolExtensionTy; 83 /// ProtocolExtensionTy - LLVM type for struct 84 /// objc_protocol_extension *. 85 const llvm::Type *ProtocolExtensionPtrTy; 86 /// MethodDescriptionTy - LLVM type for struct 87 /// objc_method_description. 88 const llvm::StructType *MethodDescriptionTy; 89 /// MethodDescriptionListTy - LLVM type for struct 90 /// objc_method_description_list. 91 const llvm::StructType *MethodDescriptionListTy; 92 /// MethodDescriptionListPtrTy - LLVM type for struct 93 /// objc_method_description_list *. 94 const llvm::Type *MethodDescriptionListPtrTy; 95 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t 96 /// in GCC parlance). 97 const llvm::StructType *PropertyTy; 98 /// PropertyListTy - LLVM type for struct objc_property_list 99 /// (_prop_list_t in GCC parlance). 100 const llvm::StructType *PropertyListTy; 101 /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 102 const llvm::Type *PropertyListPtrTy; 103 /// ProtocolListTy - LLVM type for struct objc_property_list. 104 const llvm::Type *ProtocolListTy; 105 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 106 const llvm::Type *ProtocolListPtrTy; 107 /// CategoryTy - LLVM type for struct objc_category. 108 const llvm::StructType *CategoryTy; 109 /// ClassTy - LLVM type for struct objc_class. 110 const llvm::StructType *ClassTy; 111 /// ClassPtrTy - LLVM type for struct objc_class *. 112 const llvm::Type *ClassPtrTy; 113 /// ClassExtensionTy - LLVM type for struct objc_class_ext. 114 const llvm::StructType *ClassExtensionTy; 115 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. 116 const llvm::Type *ClassExtensionPtrTy; 117 /// CacheTy - LLVM type for struct objc_cache. 118 const llvm::Type *CacheTy; 119 /// CachePtrTy - LLVM type for struct objc_cache *. 120 const llvm::Type *CachePtrTy; 121 // IvarTy - LLVM type for struct objc_ivar. 122 const llvm::StructType *IvarTy; 123 /// IvarListTy - LLVM type for struct objc_ivar_list. 124 const llvm::Type *IvarListTy; 125 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. 126 const llvm::Type *IvarListPtrTy; 127 // MethodTy - LLVM type for struct objc_method. 128 const llvm::StructType *MethodTy; 129 /// MethodListTy - LLVM type for struct objc_method_list. 130 const llvm::Type *MethodListTy; 131 /// MethodListPtrTy - LLVM type for struct objc_method_list *. 132 const llvm::Type *MethodListPtrTy; 133 134 llvm::Function *EnumerationMutationFn; 135 136 /// ExceptionDataTy - LLVM type for struct _objc_exception_data. 137 const llvm::Type *ExceptionDataTy; 138 139 /// ExceptionThrowFn - LLVM objc_exception_throw function. 140 llvm::Function *ExceptionThrowFn; 141 142 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function. 143 llvm::Function *ExceptionTryEnterFn; 144 145 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function. 146 llvm::Function *ExceptionTryExitFn; 147 148 /// ExceptionExtractFn - LLVM objc_exception_extract function. 149 llvm::Function *ExceptionExtractFn; 150 151 /// ExceptionMatchFn - LLVM objc_exception_match function. 152 llvm::Function *ExceptionMatchFn; 153 154 /// SetJmpFn - LLVM _setjmp function. 155 llvm::Function *SetJmpFn; 156 157public: 158 ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 159 ~ObjCTypesHelper(); 160 161 llvm::Value *getMessageSendFn(bool IsSuper, bool isStret, 162 const llvm::Type *ReturnTy); 163}; 164 165class CGObjCMac : public CodeGen::CGObjCRuntime { 166private: 167 CodeGen::CodeGenModule &CGM; 168 ObjCTypesHelper ObjCTypes; 169 /// ObjCABI - FIXME: Not sure yet. 170 unsigned ObjCABI; 171 172 /// LazySymbols - Symbols to generate a lazy reference for. See 173 /// DefinedSymbols and FinishModule(). 174 std::set<IdentifierInfo*> LazySymbols; 175 176 /// DefinedSymbols - External symbols which are defined by this 177 /// module. The symbols in this list and LazySymbols are used to add 178 /// special linker symbols which ensure that Objective-C modules are 179 /// linked properly. 180 std::set<IdentifierInfo*> DefinedSymbols; 181 182 /// ClassNames - uniqued class names. 183 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 184 185 /// MethodVarNames - uniqued method variable names. 186 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 187 188 /// MethodVarTypes - uniqued method type signatures. We have to use 189 /// a StringMap here because have no other unique reference. 190 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 191 192 /// MethodDefinitions - map of methods which have been defined in 193 /// this translation unit. 194 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions; 195 196 /// PropertyNames - uniqued method variable names. 197 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames; 198 199 /// ClassReferences - uniqued class references. 200 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences; 201 202 /// SelectorReferences - uniqued selector references. 203 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 204 205 /// Protocols - Protocols for which an objc_protocol structure has 206 /// been emitted. Forward declarations are handled by creating an 207 /// empty structure whose initializer is filled in when/if defined. 208 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 209 210 /// DefinedClasses - List of defined classes. 211 std::vector<llvm::GlobalValue*> DefinedClasses; 212 213 /// DefinedCategories - List of defined categories. 214 std::vector<llvm::GlobalValue*> DefinedCategories; 215 216 /// UsedGlobals - List of globals to pack into the llvm.used metadata 217 /// to prevent them from being clobbered. 218 std::vector<llvm::GlobalVariable*> UsedGlobals; 219 220 /// EmitImageInfo - Emit the image info marker used to encode some module 221 /// level information. 222 void EmitImageInfo(); 223 224 /// EmitModuleInfo - Another marker encoding module level 225 /// information. 226 void EmitModuleInfo(); 227 228 /// EmitModuleSymols - Emit module symbols, the list of defined 229 /// classes and categories. The result has type SymtabPtrTy. 230 llvm::Constant *EmitModuleSymbols(); 231 232 /// FinishModule - Write out global data structures at the end of 233 /// processing a translation unit. 234 void FinishModule(); 235 236 /// EmitClassExtension - Generate the class extension structure used 237 /// to store the weak ivar layout and properties. The return value 238 /// has type ClassExtensionPtrTy. 239 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID); 240 241 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy, 242 /// for the given class. 243 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder, 244 const ObjCInterfaceDecl *ID); 245 246 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF, 247 QualType ResultType, 248 Selector Sel, 249 llvm::Value *Arg0, 250 QualType Arg0Ty, 251 bool IsSuper, 252 const CallArgList &CallArgs); 253 254 /// EmitIvarList - Emit the ivar list for the given 255 /// implementation. If ForClass is true the list of class ivars 256 /// (i.e. metaclass ivars) is emitted, otherwise the list of 257 /// interface ivars will be emitted. The return value has type 258 /// IvarListPtrTy. 259 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, 260 bool ForClass, 261 const llvm::Type *InterfaceTy); 262 263 /// EmitMetaClass - Emit a forward reference to the class structure 264 /// for the metaclass of the given interface. The return value has 265 /// type ClassPtrTy. 266 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID); 267 268 /// EmitMetaClass - Emit a class structure for the metaclass of the 269 /// given implementation. The return value has type ClassPtrTy. 270 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID, 271 llvm::Constant *Protocols, 272 const llvm::Type *InterfaceTy, 273 const ConstantVector &Methods); 274 275 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); 276 277 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); 278 279 /// EmitMethodList - Emit the method list for the given 280 /// implementation. The return value has type MethodListPtrTy. 281 llvm::Constant *EmitMethodList(const std::string &Name, 282 const char *Section, 283 const ConstantVector &Methods); 284 285 /// EmitMethodDescList - Emit a method description list for a list of 286 /// method declarations. 287 /// - TypeName: The name for the type containing the methods. 288 /// - IsProtocol: True iff these methods are for a protocol. 289 /// - ClassMethds: True iff these are class methods. 290 /// - Required: When true, only "required" methods are 291 /// listed. Similarly, when false only "optional" methods are 292 /// listed. For classes this should always be true. 293 /// - begin, end: The method list to output. 294 /// 295 /// The return value has type MethodDescriptionListPtrTy. 296 llvm::Constant *EmitMethodDescList(const std::string &Name, 297 const char *Section, 298 const ConstantVector &Methods); 299 300 /// EmitPropertyList - Emit the given property list. The return 301 /// value has type PropertyListPtrTy. 302 llvm::Constant *EmitPropertyList(const std::string &Name, 303 const Decl *Container, 304 ObjCPropertyDecl * const *begin, 305 ObjCPropertyDecl * const *end); 306 307 /// EmitProtocolExtension - Generate the protocol extension 308 /// structure used to store optional instance and class methods, and 309 /// protocol properties. The return value has type 310 /// ProtocolExtensionPtrTy. 311 llvm::Constant * 312 EmitProtocolExtension(const ObjCProtocolDecl *PD, 313 const ConstantVector &OptInstanceMethods, 314 const ConstantVector &OptClassMethods); 315 316 /// EmitProtocolList - Generate the list of referenced 317 /// protocols. The return value has type ProtocolListPtrTy. 318 llvm::Constant *EmitProtocolList(const std::string &Name, 319 ObjCProtocolDecl::protocol_iterator begin, 320 ObjCProtocolDecl::protocol_iterator end); 321 322 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 323 /// for the given selector. 324 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel); 325 326 /// GetProtocolRef - Return a reference to the internal protocol 327 /// description, creating an empty one if it has not been 328 /// defined. The return value has type pointer-to ProtocolTy. 329 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD); 330 331 /// GetClassName - Return a unique constant for the given selector's 332 /// name. The return value has type char *. 333 llvm::Constant *GetClassName(IdentifierInfo *Ident); 334 335 /// GetMethodVarName - Return a unique constant for the given 336 /// selector's name. The return value has type char *. 337 llvm::Constant *GetMethodVarName(Selector Sel); 338 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident); 339 llvm::Constant *GetMethodVarName(const std::string &Name); 340 341 /// GetMethodVarType - Return a unique constant for the given 342 /// selector's name. The return value has type char *. 343 344 // FIXME: This is a horrible name. 345 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D); 346 llvm::Constant *GetMethodVarType(const std::string &Name); 347 348 /// GetPropertyName - Return a unique constant for the given 349 /// name. The return value has type char *. 350 llvm::Constant *GetPropertyName(IdentifierInfo *Ident); 351 352 // FIXME: This can be dropped once string functions are unified. 353 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, 354 const Decl *Container); 355 356 /// GetNameForMethod - Return a name for the given method. 357 /// \param[out] NameOut - The return value. 358 void GetNameForMethod(const ObjCMethodDecl *OMD, 359 std::string &NameOut); 360 361public: 362 CGObjCMac(CodeGen::CodeGenModule &cgm); 363 virtual llvm::Constant *GenerateConstantString(const std::string &String); 364 365 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 366 QualType ResultType, 367 Selector Sel, 368 llvm::Value *Receiver, 369 bool IsClassMessage, 370 const CallArgList &CallArgs); 371 372 virtual CodeGen::RValue 373 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 374 QualType ResultType, 375 Selector Sel, 376 const ObjCInterfaceDecl *Class, 377 llvm::Value *Receiver, 378 bool IsClassMessage, 379 const CallArgList &CallArgs); 380 381 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder, 382 const ObjCInterfaceDecl *ID); 383 384 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel); 385 386 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD); 387 388 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); 389 390 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); 391 392 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder, 393 const ObjCProtocolDecl *PD); 394 395 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 396 397 virtual llvm::Function *ModuleInitFunction(); 398 virtual llvm::Function *EnumerationMutationFunction(); 399 400 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF, 401 const ObjCAtTryStmt &S); 402 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 403 const ObjCAtThrowStmt &S); 404 405}; 406} // end anonymous namespace 407 408/* *** Helper Functions *** */ 409 410/// getConstantGEP() - Help routine to construct simple GEPs. 411static llvm::Constant *getConstantGEP(llvm::Constant *C, 412 unsigned idx0, 413 unsigned idx1) { 414 llvm::Value *Idxs[] = { 415 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0), 416 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1) 417 }; 418 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2); 419} 420 421/* *** CGObjCMac Public Interface *** */ 422 423CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) 424 : CGM(cgm), 425 ObjCTypes(cgm), 426 ObjCABI(1) 427{ 428 // FIXME: How does this get set in GCC? And what does it even mean? 429 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy)) 430 ObjCABI = 2; 431 432 EmitImageInfo(); 433} 434 435/// GetClass - Return a reference to the class for the given interface 436/// decl. 437llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder, 438 const ObjCInterfaceDecl *ID) { 439 return EmitClassRef(Builder, ID); 440} 441 442/// GetSelector - Return the pointer to the unique'd string for this selector. 443llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) { 444 return EmitSelector(Builder, Sel); 445} 446 447/// Generate a constant CFString object. 448/* 449 struct __builtin_CFString { 450 const int *isa; // point to __CFConstantStringClassReference 451 int flags; 452 const char *str; 453 long length; 454 }; 455*/ 456 457llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) { 458 return CGM.GetAddrOfConstantCFString(String); 459} 460 461/// Generates a message send where the super is the receiver. This is 462/// a message send to self with special delivery semantics indicating 463/// which class's method should be called. 464CodeGen::RValue 465CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, 466 QualType ResultType, 467 Selector Sel, 468 const ObjCInterfaceDecl *Class, 469 llvm::Value *Receiver, 470 bool IsClassMessage, 471 const CodeGen::CallArgList &CallArgs) { 472 // Create and init a super structure; this is a (receiver, class) 473 // pair we will pass to objc_msgSendSuper. 474 llvm::Value *ObjCSuper = 475 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super"); 476 llvm::Value *ReceiverAsObject = 477 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy); 478 CGF.Builder.CreateStore(ReceiverAsObject, 479 CGF.Builder.CreateStructGEP(ObjCSuper, 0)); 480 481 // If this is a class message the metaclass is passed as the target. 482 llvm::Value *Target; 483 if (IsClassMessage) { 484 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class); 485 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1); 486 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr); 487 Target = Super; 488 } else { 489 Target = EmitClassRef(CGF.Builder, Class->getSuperClass()); 490 } 491 // FIXME: We shouldn't need to do this cast, rectify the ASTContext 492 // and ObjCTypes types. 493 const llvm::Type *ClassTy = 494 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType()); 495 Target = CGF.Builder.CreateBitCast(Target, ClassTy); 496 CGF.Builder.CreateStore(Target, 497 CGF.Builder.CreateStructGEP(ObjCSuper, 1)); 498 499 return EmitMessageSend(CGF, ResultType, Sel, 500 ObjCSuper, ObjCTypes.SuperPtrCTy, 501 true, CallArgs); 502} 503 504/// Generate code for a message send expression. 505CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, 506 QualType ResultType, 507 Selector Sel, 508 llvm::Value *Receiver, 509 bool IsClassMessage, 510 const CallArgList &CallArgs) { 511 llvm::Value *Arg0 = 512 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp"); 513 return EmitMessageSend(CGF, ResultType, Sel, 514 Arg0, CGF.getContext().getObjCIdType(), 515 false, CallArgs); 516} 517 518CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, 519 QualType ResultType, 520 Selector Sel, 521 llvm::Value *Arg0, 522 QualType Arg0Ty, 523 bool IsSuper, 524 const CallArgList &CallArgs) { 525 CallArgList ActualArgs; 526 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty)); 527 ActualArgs.push_back(std::make_pair(RValue::get(EmitSelector(CGF.Builder, 528 Sel)), 529 CGF.getContext().getObjCSelType())); 530 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); 531 532 llvm::Value *Fn = 533 ObjCTypes.getMessageSendFn(IsSuper, 534 CGM.ReturnTypeUsesSret(ResultType), 535 CGM.getTypes().ConvertType(ResultType)); 536 return CGF.EmitCall(Fn, ResultType, ActualArgs); 537} 538 539llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder, 540 const ObjCProtocolDecl *PD) { 541 // FIXME: I don't understand why gcc generates this, or where it is 542 // resolved. Investigate. Its also wasteful to look this up over and 543 // over. 544 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 545 546 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 547 ObjCTypes.ExternalProtocolPtrTy); 548} 549 550/* 551 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 552 struct _objc_protocol { 553 struct _objc_protocol_extension *isa; 554 char *protocol_name; 555 struct _objc_protocol_list *protocol_list; 556 struct _objc__method_prototype_list *instance_methods; 557 struct _objc__method_prototype_list *class_methods 558 }; 559 560 See EmitProtocolExtension(). 561*/ 562void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 563 // FIXME: I don't understand why gcc generates this, or where it is 564 // resolved. Investigate. Its also wasteful to look this up over and 565 // over. 566 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol")); 567 568 const char *ProtocolName = PD->getName(); 569 570 // Construct method lists. 571 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 572 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods; 573 for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(), 574 e = PD->instmeth_end(); i != e; ++i) { 575 ObjCMethodDecl *MD = *i; 576 llvm::Constant *C = GetMethodDescriptionConstant(MD); 577 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 578 OptInstanceMethods.push_back(C); 579 } else { 580 InstanceMethods.push_back(C); 581 } 582 } 583 584 for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(), 585 e = PD->classmeth_end(); i != e; ++i) { 586 ObjCMethodDecl *MD = *i; 587 llvm::Constant *C = GetMethodDescriptionConstant(MD); 588 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) { 589 OptClassMethods.push_back(C); 590 } else { 591 ClassMethods.push_back(C); 592 } 593 } 594 595 std::vector<llvm::Constant*> Values(5); 596 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods); 597 Values[1] = GetClassName(PD->getIdentifier()); 598 Values[2] = 599 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(), 600 PD->protocol_begin(), 601 PD->protocol_end()); 602 Values[3] = 603 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_") 604 + PD->getName(), 605 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 606 InstanceMethods); 607 Values[4] = 608 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_") 609 + PD->getName(), 610 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 611 ClassMethods); 612 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 613 Values); 614 615 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 616 if (Entry) { 617 // Already created, just update the initializer 618 Entry->setInitializer(Init); 619 } else { 620 Entry = 621 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 622 llvm::GlobalValue::InternalLinkage, 623 Init, 624 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName, 625 &CGM.getModule()); 626 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 627 UsedGlobals.push_back(Entry); 628 // FIXME: Is this necessary? Why only for protocol? 629 Entry->setAlignment(4); 630 } 631} 632 633llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 634 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 635 636 if (!Entry) { 637 std::vector<llvm::Constant*> Values(5); 638 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 639 Values[1] = GetClassName(PD->getIdentifier()); 640 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 641 Values[3] = Values[4] = 642 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 643 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 644 Values); 645 646 Entry = 647 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 648 llvm::GlobalValue::InternalLinkage, 649 Init, 650 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(), 651 &CGM.getModule()); 652 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 653 UsedGlobals.push_back(Entry); 654 // FIXME: Is this necessary? Why only for protocol? 655 Entry->setAlignment(4); 656 } 657 658 return Entry; 659} 660 661/* 662 struct _objc_protocol_extension { 663 uint32_t size; 664 struct objc_method_description_list *optional_instance_methods; 665 struct objc_method_description_list *optional_class_methods; 666 struct objc_property_list *instance_properties; 667 }; 668*/ 669llvm::Constant * 670CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD, 671 const ConstantVector &OptInstanceMethods, 672 const ConstantVector &OptClassMethods) { 673 uint64_t Size = 674 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy); 675 std::vector<llvm::Constant*> Values(4); 676 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 677 Values[1] = 678 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_") 679 + PD->getName(), 680 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 681 OptInstanceMethods); 682 Values[2] = 683 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_") 684 + PD->getName(), 685 "__OBJC,__cat_cls_meth,regular,no_dead_strip", 686 OptClassMethods); 687 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") + 688 PD->getName(), 689 0, 690 PD->classprop_begin(), 691 PD->classprop_end()); 692 693 // Return null if no extension bits are used. 694 if (Values[1]->isNullValue() && Values[2]->isNullValue() && 695 Values[3]->isNullValue()) 696 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 697 698 llvm::Constant *Init = 699 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 700 llvm::GlobalVariable *GV = 701 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false, 702 llvm::GlobalValue::InternalLinkage, 703 Init, 704 (std::string("\01L_OBJC_PROTOCOLEXT_") + 705 PD->getName()), 706 &CGM.getModule()); 707 // No special section, but goes in llvm.used 708 UsedGlobals.push_back(GV); 709 710 return GV; 711} 712 713/* 714 struct objc_protocol_list { 715 struct objc_protocol_list *next; 716 long count; 717 Protocol *list[]; 718 }; 719*/ 720llvm::Constant * 721CGObjCMac::EmitProtocolList(const std::string &Name, 722 ObjCProtocolDecl::protocol_iterator begin, 723 ObjCProtocolDecl::protocol_iterator end) { 724 std::vector<llvm::Constant*> ProtocolRefs; 725 726 for (; begin != end; ++begin) 727 ProtocolRefs.push_back(GetProtocolRef(*begin)); 728 729 // Just return null for empty protocol lists 730 if (ProtocolRefs.empty()) 731 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 732 733 // This list is null terminated. 734 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 735 736 std::vector<llvm::Constant*> Values(3); 737 // This field is only used by the runtime. 738 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 739 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 740 Values[2] = 741 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 742 ProtocolRefs.size()), 743 ProtocolRefs); 744 745 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 746 llvm::GlobalVariable *GV = 747 new llvm::GlobalVariable(Init->getType(), false, 748 llvm::GlobalValue::InternalLinkage, 749 Init, 750 Name, 751 &CGM.getModule()); 752 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip"); 753 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 754} 755 756/* 757 struct _objc_property { 758 const char * const name; 759 const char * const attributes; 760 }; 761 762 struct _objc_property_list { 763 uint32_t entsize; // sizeof (struct _objc_property) 764 uint32_t prop_count; 765 struct _objc_property[prop_count]; 766 }; 767*/ 768llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name, 769 const Decl *Container, 770 ObjCPropertyDecl * const *begin, 771 ObjCPropertyDecl * const *end) { 772 std::vector<llvm::Constant*> Properties, Prop(2); 773 for (; begin != end; ++begin) { 774 const ObjCPropertyDecl *PD = *begin; 775 Prop[0] = GetPropertyName(PD->getIdentifier()); 776 Prop[1] = GetPropertyTypeString(PD, Container); 777 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, 778 Prop)); 779 } 780 781 // Return null for empty list. 782 if (Properties.empty()) 783 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 784 785 unsigned PropertySize = 786 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy); 787 std::vector<llvm::Constant*> Values(3); 788 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize); 789 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size()); 790 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy, 791 Properties.size()); 792 Values[2] = llvm::ConstantArray::get(AT, Properties); 793 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 794 795 llvm::GlobalVariable *GV = 796 new llvm::GlobalVariable(Init->getType(), false, 797 llvm::GlobalValue::InternalLinkage, 798 Init, 799 Name, 800 &CGM.getModule()); 801 // No special section on property lists? 802 UsedGlobals.push_back(GV); 803 return llvm::ConstantExpr::getBitCast(GV, 804 ObjCTypes.PropertyListPtrTy); 805 806} 807 808/* 809 struct objc_method_description_list { 810 int count; 811 struct objc_method_description list[]; 812 }; 813*/ 814llvm::Constant * 815CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { 816 std::vector<llvm::Constant*> Desc(2); 817 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 818 ObjCTypes.SelectorPtrTy); 819 Desc[1] = GetMethodVarType(MD); 820 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 821 Desc); 822} 823 824llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name, 825 const char *Section, 826 const ConstantVector &Methods) { 827 // Return null for empty list. 828 if (Methods.empty()) 829 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 830 831 std::vector<llvm::Constant*> Values(2); 832 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 833 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 834 Methods.size()); 835 Values[1] = llvm::ConstantArray::get(AT, Methods); 836 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 837 838 llvm::GlobalVariable *GV = 839 new llvm::GlobalVariable(Init->getType(), false, 840 llvm::GlobalValue::InternalLinkage, 841 Init, Name, &CGM.getModule()); 842 GV->setSection(Section); 843 UsedGlobals.push_back(GV); 844 return llvm::ConstantExpr::getBitCast(GV, 845 ObjCTypes.MethodDescriptionListPtrTy); 846} 847 848/* 849 struct _objc_category { 850 char *category_name; 851 char *class_name; 852 struct _objc_method_list *instance_methods; 853 struct _objc_method_list *class_methods; 854 struct _objc_protocol_list *protocols; 855 uint32_t size; // <rdar://4585769> 856 struct _objc_property_list *instance_properties; 857 }; 858 */ 859void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { 860 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy); 861 862 // FIXME: This is poor design, the OCD should have a pointer to the 863 // category decl. Additionally, note that Category can be null for 864 // the @implementation w/o an @interface case. Sema should just 865 // create one for us as it does for @implementation so everyone else 866 // can live life under a clear blue sky. 867 const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); 868 const ObjCCategoryDecl *Category = 869 Interface->FindCategoryDeclaration(OCD->getIdentifier()); 870 std::string ExtName(std::string(Interface->getName()) + 871 "_" + 872 OCD->getName()); 873 874 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 875 for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(), 876 e = OCD->instmeth_end(); i != e; ++i) { 877 // Instance methods should always be defined. 878 InstanceMethods.push_back(GetMethodConstant(*i)); 879 } 880 for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(), 881 e = OCD->classmeth_end(); i != e; ++i) { 882 // Class methods should always be defined. 883 ClassMethods.push_back(GetMethodConstant(*i)); 884 } 885 886 std::vector<llvm::Constant*> Values(7); 887 Values[0] = GetClassName(OCD->getIdentifier()); 888 Values[1] = GetClassName(Interface->getIdentifier()); 889 Values[2] = 890 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") + 891 ExtName, 892 "__OBJC,__cat_inst_meth,regular,no_dead_strip", 893 InstanceMethods); 894 Values[3] = 895 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName, 896 "__OBJC,__cat_class_meth,regular,no_dead_strip", 897 ClassMethods); 898 if (Category) { 899 Values[4] = 900 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName, 901 Category->protocol_begin(), 902 Category->protocol_end()); 903 } else { 904 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 905 } 906 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 907 908 // If there is no category @interface then there can be no properties. 909 if (Category) { 910 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName, 911 OCD, 912 Category->classprop_begin(), 913 Category->classprop_end()); 914 } else { 915 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 916 } 917 918 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy, 919 Values); 920 921 llvm::GlobalVariable *GV = 922 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false, 923 llvm::GlobalValue::InternalLinkage, 924 Init, 925 std::string("\01L_OBJC_CATEGORY_")+ExtName, 926 &CGM.getModule()); 927 GV->setSection("__OBJC,__category,regular,no_dead_strip"); 928 UsedGlobals.push_back(GV); 929 DefinedCategories.push_back(GV); 930} 931 932// FIXME: Get from somewhere? 933enum ClassFlags { 934 eClassFlags_Factory = 0x00001, 935 eClassFlags_Meta = 0x00002, 936 // <rdr://5142207> 937 eClassFlags_HasCXXStructors = 0x02000, 938 eClassFlags_Hidden = 0x20000, 939 eClassFlags_ABI2_Hidden = 0x00010, 940 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634> 941}; 942 943// <rdr://5142207&4705298&4843145> 944static bool IsClassHidden(const ObjCInterfaceDecl *ID) { 945 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) { 946 // FIXME: Support -fvisibility 947 switch (attr->getVisibility()) { 948 default: 949 assert(0 && "Unknown visibility"); 950 return false; 951 case VisibilityAttr::DefaultVisibility: 952 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here? 953 return false; 954 case VisibilityAttr::HiddenVisibility: 955 return true; 956 } 957 } else { 958 return false; // FIXME: Support -fvisibility 959 } 960} 961 962/* 963 struct _objc_class { 964 Class isa; 965 Class super_class; 966 const char *name; 967 long version; 968 long info; 969 long instance_size; 970 struct _objc_ivar_list *ivars; 971 struct _objc_method_list *methods; 972 struct _objc_cache *cache; 973 struct _objc_protocol_list *protocols; 974 // Objective-C 1.0 extensions (<rdr://4585769>) 975 const char *ivar_layout; 976 struct _objc_class_ext *ext; 977 }; 978 979 See EmitClassExtension(); 980 */ 981void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { 982 DefinedSymbols.insert(ID->getIdentifier()); 983 984 const char *ClassName = ID->getName(); 985 // FIXME: Gross 986 ObjCInterfaceDecl *Interface = 987 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface()); 988 llvm::Constant *Protocols = 989 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(), 990 Interface->protocol_begin(), 991 Interface->protocol_end()); 992 const llvm::Type *InterfaceTy = 993 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface)); 994 unsigned Flags = eClassFlags_Factory; 995 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy); 996 997 // FIXME: Set CXX-structors flag. 998 if (IsClassHidden(ID->getClassInterface())) 999 Flags |= eClassFlags_Hidden; 1000 1001 std::vector<llvm::Constant*> InstanceMethods, ClassMethods; 1002 for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(), 1003 e = ID->instmeth_end(); i != e; ++i) { 1004 // Instance methods should always be defined. 1005 InstanceMethods.push_back(GetMethodConstant(*i)); 1006 } 1007 for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(), 1008 e = ID->classmeth_end(); i != e; ++i) { 1009 // Class methods should always be defined. 1010 ClassMethods.push_back(GetMethodConstant(*i)); 1011 } 1012 1013 for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(), 1014 e = ID->propimpl_end(); i != e; ++i) { 1015 ObjCPropertyImplDecl *PID = *i; 1016 1017 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) { 1018 ObjCPropertyDecl *PD = PID->getPropertyDecl(); 1019 1020 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) 1021 if (llvm::Constant *C = GetMethodConstant(MD)) 1022 InstanceMethods.push_back(C); 1023 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) 1024 if (llvm::Constant *C = GetMethodConstant(MD)) 1025 InstanceMethods.push_back(C); 1026 } 1027 } 1028 1029 std::vector<llvm::Constant*> Values(12); 1030 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods); 1031 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) { 1032 // Record a reference to the super class. 1033 LazySymbols.insert(Super->getIdentifier()); 1034 1035 Values[ 1] = 1036 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 1037 ObjCTypes.ClassPtrTy); 1038 } else { 1039 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 1040 } 1041 Values[ 2] = GetClassName(ID->getIdentifier()); 1042 // Version is always 0. 1043 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 1044 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 1045 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 1046 Values[ 6] = EmitIvarList(ID, false, InterfaceTy); 1047 Values[ 7] = 1048 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(), 1049 "__OBJC,__inst_meth,regular,no_dead_strip", 1050 InstanceMethods); 1051 // cache is always NULL. 1052 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 1053 Values[ 9] = Protocols; 1054 // FIXME: Set ivar_layout 1055 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1056 Values[11] = EmitClassExtension(ID); 1057 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 1058 Values); 1059 1060 llvm::GlobalVariable *GV = 1061 new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 1062 llvm::GlobalValue::InternalLinkage, 1063 Init, 1064 std::string("\01L_OBJC_CLASS_")+ClassName, 1065 &CGM.getModule()); 1066 GV->setSection("__OBJC,__class,regular,no_dead_strip"); 1067 UsedGlobals.push_back(GV); 1068 // FIXME: Why? 1069 GV->setAlignment(32); 1070 DefinedClasses.push_back(GV); 1071} 1072 1073llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, 1074 llvm::Constant *Protocols, 1075 const llvm::Type *InterfaceTy, 1076 const ConstantVector &Methods) { 1077 const char *ClassName = ID->getName(); 1078 unsigned Flags = eClassFlags_Meta; 1079 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy); 1080 1081 if (IsClassHidden(ID->getClassInterface())) 1082 Flags |= eClassFlags_Hidden; 1083 1084 std::vector<llvm::Constant*> Values(12); 1085 // The isa for the metaclass is the root of the hierarchy. 1086 const ObjCInterfaceDecl *Root = ID->getClassInterface(); 1087 while (const ObjCInterfaceDecl *Super = Root->getSuperClass()) 1088 Root = Super; 1089 Values[ 0] = 1090 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()), 1091 ObjCTypes.ClassPtrTy); 1092 // The super class for the metaclass is emitted as the name of the 1093 // super class. The runtime fixes this up to point to the 1094 // *metaclass* for the super class. 1095 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) { 1096 Values[ 1] = 1097 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()), 1098 ObjCTypes.ClassPtrTy); 1099 } else { 1100 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy); 1101 } 1102 Values[ 2] = GetClassName(ID->getIdentifier()); 1103 // Version is always 0. 1104 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 1105 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); 1106 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 1107 Values[ 6] = EmitIvarList(ID, true, InterfaceTy); 1108 Values[ 7] = 1109 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(), 1110 "__OBJC,__inst_meth,regular,no_dead_strip", 1111 Methods); 1112 // cache is always NULL. 1113 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy); 1114 Values[ 9] = Protocols; 1115 // ivar_layout for metaclass is always NULL. 1116 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1117 // The class extension is always unused for metaclasses. 1118 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 1119 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy, 1120 Values); 1121 1122 std::string Name("\01L_OBJC_METACLASS_"); 1123 Name += ClassName; 1124 1125 // Check for a forward reference. 1126 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name); 1127 if (GV) { 1128 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 1129 "Forward metaclass reference has incorrect type."); 1130 GV->setLinkage(llvm::GlobalValue::InternalLinkage); 1131 GV->setInitializer(Init); 1132 } else { 1133 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 1134 llvm::GlobalValue::InternalLinkage, 1135 Init, Name, 1136 &CGM.getModule()); 1137 } 1138 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); 1139 UsedGlobals.push_back(GV); 1140 // FIXME: Why? 1141 GV->setAlignment(32); 1142 1143 return GV; 1144} 1145 1146llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { 1147 std::string Name("\01L_OBJC_METACLASS_"); 1148 Name += ID->getName(); 1149 1150 // FIXME: Should we look these up somewhere other than the 1151 // module. Its a bit silly since we only generate these while 1152 // processing an implementation, so exactly one pointer would work 1153 // if know when we entered/exitted an implementation block. 1154 1155 // Check for an existing forward reference. 1156 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) { 1157 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && 1158 "Forward metaclass reference has incorrect type."); 1159 return GV; 1160 } else { 1161 // Generate as an external reference to keep a consistent 1162 // module. This will be patched up when we emit the metaclass. 1163 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false, 1164 llvm::GlobalValue::ExternalLinkage, 1165 0, 1166 Name, 1167 &CGM.getModule()); 1168 } 1169} 1170 1171/* 1172 struct objc_class_ext { 1173 uint32_t size; 1174 const char *weak_ivar_layout; 1175 struct _objc_property_list *properties; 1176 }; 1177*/ 1178llvm::Constant * 1179CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) { 1180 uint64_t Size = 1181 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy); 1182 1183 std::vector<llvm::Constant*> Values(3); 1184 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 1185 // FIXME: Output weak_ivar_layout string. 1186 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1187 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + 1188 ID->getName(), 1189 ID, 1190 ID->getClassInterface()->classprop_begin(), 1191 ID->getClassInterface()->classprop_end()); 1192 1193 // Return null if no extension bits are used. 1194 if (Values[1]->isNullValue() && Values[2]->isNullValue()) 1195 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy); 1196 1197 llvm::Constant *Init = 1198 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values); 1199 llvm::GlobalVariable *GV = 1200 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false, 1201 llvm::GlobalValue::InternalLinkage, 1202 Init, 1203 (std::string("\01L_OBJC_CLASSEXT_") + 1204 ID->getName()), 1205 &CGM.getModule()); 1206 // No special section, but goes in llvm.used 1207 UsedGlobals.push_back(GV); 1208 1209 return GV; 1210} 1211 1212/* 1213 struct objc_ivar { 1214 char *ivar_name; 1215 char *ivar_type; 1216 int ivar_offset; 1217 }; 1218 1219 struct objc_ivar_list { 1220 int ivar_count; 1221 struct objc_ivar list[count]; 1222 }; 1223 */ 1224llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, 1225 bool ForClass, 1226 const llvm::Type *InterfaceTy) { 1227 std::vector<llvm::Constant*> Ivars, Ivar(3); 1228 1229 // When emitting the root class GCC emits ivar entries for the 1230 // actual class structure. It is not clear if we need to follow this 1231 // behavior; for now lets try and get away with not doing it. If so, 1232 // the cleanest solution would be to make up an ObjCInterfaceDecl 1233 // for the class. 1234 if (ForClass) 1235 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 1236 1237 const llvm::StructLayout *Layout = 1238 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy)); 1239 for (ObjCInterfaceDecl::ivar_iterator 1240 i = ID->getClassInterface()->ivar_begin(), 1241 e = ID->getClassInterface()->ivar_end(); i != e; ++i) { 1242 ObjCIvarDecl *V = *i; 1243 unsigned Offset = 1244 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V)); 1245 std::string TypeStr; 1246 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes; 1247 Ivar[0] = GetMethodVarName(V->getIdentifier()); 1248 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, 1249 EncodingRecordTypes); 1250 Ivar[1] = GetMethodVarType(TypeStr); 1251 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset); 1252 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, 1253 Ivar)); 1254 } 1255 1256 // Return null for empty list. 1257 if (Ivars.empty()) 1258 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); 1259 1260 std::vector<llvm::Constant*> Values(2); 1261 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); 1262 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy, 1263 Ivars.size()); 1264 Values[1] = llvm::ConstantArray::get(AT, Ivars); 1265 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1266 1267 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" : 1268 "\01L_OBJC_INSTANCE_VARIABLES_"); 1269 llvm::GlobalVariable *GV = 1270 new llvm::GlobalVariable(Init->getType(), false, 1271 llvm::GlobalValue::InternalLinkage, 1272 Init, 1273 std::string(Prefix) + ID->getName(), 1274 &CGM.getModule()); 1275 if (ForClass) { 1276 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip"); 1277 // FIXME: Why is this only here? 1278 GV->setAlignment(32); 1279 } else { 1280 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip"); 1281 } 1282 UsedGlobals.push_back(GV); 1283 return llvm::ConstantExpr::getBitCast(GV, 1284 ObjCTypes.IvarListPtrTy); 1285} 1286 1287/* 1288 struct objc_method { 1289 SEL method_name; 1290 char *method_types; 1291 void *method; 1292 }; 1293 1294 struct objc_method_list { 1295 struct objc_method_list *obsolete; 1296 int count; 1297 struct objc_method methods_list[count]; 1298 }; 1299*/ 1300 1301/// GetMethodConstant - Return a struct objc_method constant for the 1302/// given method if it has been defined. The result is null if the 1303/// method has not been defined. The return value has type MethodPtrTy. 1304llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) { 1305 // FIXME: Use DenseMap::lookup 1306 llvm::Function *Fn = MethodDefinitions[MD]; 1307 if (!Fn) 1308 return 0; 1309 1310 std::vector<llvm::Constant*> Method(3); 1311 Method[0] = 1312 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), 1313 ObjCTypes.SelectorPtrTy); 1314 Method[1] = GetMethodVarType(MD); 1315 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); 1316 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); 1317} 1318 1319llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name, 1320 const char *Section, 1321 const ConstantVector &Methods) { 1322 // Return null for empty list. 1323 if (Methods.empty()) 1324 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy); 1325 1326 std::vector<llvm::Constant*> Values(3); 1327 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); 1328 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 1329 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, 1330 Methods.size()); 1331 Values[2] = llvm::ConstantArray::get(AT, Methods); 1332 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1333 1334 llvm::GlobalVariable *GV = 1335 new llvm::GlobalVariable(Init->getType(), false, 1336 llvm::GlobalValue::InternalLinkage, 1337 Init, 1338 Name, 1339 &CGM.getModule()); 1340 GV->setSection(Section); 1341 UsedGlobals.push_back(GV); 1342 return llvm::ConstantExpr::getBitCast(GV, 1343 ObjCTypes.MethodListPtrTy); 1344} 1345 1346llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) { 1347 const llvm::Type *ReturnTy = 1348 CGM.getTypes().ConvertReturnType(OMD->getResultType()); 1349 const llvm::Type *SelfTy = 1350 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType()); 1351 1352 std::vector<const llvm::Type*> ArgTys; 1353 ArgTys.reserve(1 + 2 + OMD->param_size()); 1354 1355 // FIXME: This is not something we should have to be dealing with 1356 // here. 1357 bool useStructRet = 1358 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType()); 1359 if (useStructRet) { 1360 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy)); 1361 ReturnTy = llvm::Type::VoidTy; 1362 } 1363 1364 // Implicit arguments 1365 ArgTys.push_back(SelfTy); 1366 ArgTys.push_back(ObjCTypes.SelectorPtrTy); 1367 1368 for (ObjCMethodDecl::param_const_iterator 1369 i = OMD->param_begin(), e = OMD->param_end(); 1370 i != e; ++i) { 1371 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType()); 1372 if (Ty->isSingleValueType()) { 1373 ArgTys.push_back(Ty); 1374 } else { 1375 ArgTys.push_back(llvm::PointerType::getUnqual(Ty)); 1376 } 1377 } 1378 1379 std::string Name; 1380 GetNameForMethod(OMD, Name); 1381 1382 llvm::Function *Method = 1383 llvm::Function::Create(llvm::FunctionType::get(ReturnTy, 1384 ArgTys, 1385 OMD->isVariadic()), 1386 llvm::GlobalValue::InternalLinkage, 1387 Name, 1388 &CGM.getModule()); 1389 MethodDefinitions.insert(std::make_pair(OMD, Method)); 1390 1391 unsigned Offset = 3; // Return plus self and selector implicit args. 1392 if (useStructRet) { 1393 Method->addParamAttr(1, llvm::ParamAttr::StructRet); 1394 ++Offset; 1395 } 1396 1397 // FIXME: This is horrible, we need to be reusing the machinery in 1398 // CodeGenModule.cpp (SetFunctionAttributes). 1399 for (ObjCMethodDecl::param_const_iterator 1400 i = OMD->param_begin(), e = OMD->param_end(); 1401 i != e; ++i, ++Offset) { 1402 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType()); 1403 if (!Ty->isSingleValueType()) 1404 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal); 1405 } 1406 1407 return Method; 1408} 1409 1410llvm::Function *CGObjCMac::ModuleInitFunction() { 1411 // Abuse this interface function as a place to finalize. 1412 FinishModule(); 1413 1414 return NULL; 1415} 1416 1417llvm::Function *CGObjCMac::EnumerationMutationFunction() 1418{ 1419 return ObjCTypes.EnumerationMutationFn; 1420} 1421 1422void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, 1423 const ObjCAtTryStmt &S) 1424{ 1425 // Allocate exception data. 1426 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy, 1427 "exceptiondata.ptr"); 1428 1429 // Allocate memory for the rethrow pointer. 1430 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy); 1431 CGF.Builder.CreateStore(llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy), 1432 RethrowPtr); 1433 1434 // Enter a new try block and call setjmp. 1435 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData); 1436 llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0, 1437 "jmpbufarray"); 1438 JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp"); 1439 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn, 1440 JmpBufPtr, "result"); 1441 1442 1443 llvm::BasicBlock *FinallyBlock = llvm::BasicBlock::Create("finally"); 1444 1445 llvm::BasicBlock *TryBlock = llvm::BasicBlock::Create("try"); 1446 llvm::BasicBlock *ExceptionInTryBlock = 1447 llvm::BasicBlock::Create("exceptionintry"); 1448 1449 // If setjmp returns 1, there was an exception in the @try block. 1450 llvm::Value *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty); 1451 llvm::Value *IsZero = CGF.Builder.CreateICmpEQ(SetJmpResult, Zero, "iszero"); 1452 CGF.Builder.CreateCondBr(IsZero, TryBlock, ExceptionInTryBlock); 1453 1454 // Emit the @try block. 1455 CGF.EmitBlock(TryBlock); 1456 CGF.EmitStmt(S.getTryBody()); 1457 CGF.Builder.CreateBr(FinallyBlock); 1458 1459 // Emit the "exception in @try" block. 1460 CGF.EmitBlock(ExceptionInTryBlock); 1461 1462 if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) { 1463 // Allocate memory for the caught exception and extract it from the 1464 // exception data. 1465 llvm::Value *CaughtPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy); 1466 llvm::Value *Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, 1467 ExceptionData); 1468 CGF.Builder.CreateStore(Extract, CaughtPtr); 1469 1470 // Enter a new exception try block 1471 // (in case a @catch block throws an exception). 1472 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData); 1473 1474 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn, 1475 JmpBufPtr, "result"); 1476 1477 1478 llvm::Value *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty); 1479 llvm::Value *IsZero = CGF.Builder.CreateICmpEQ(SetJmpResult, Zero, 1480 "iszero"); 1481 1482 llvm::BasicBlock *CatchBlock = llvm::BasicBlock::Create("catch"); 1483 llvm::BasicBlock *ExceptionInCatchBlock = 1484 llvm::BasicBlock::Create("exceptionincatch"); 1485 CGF.Builder.CreateCondBr(IsZero, CatchBlock, ExceptionInCatchBlock); 1486 1487 CGF.EmitBlock(CatchBlock); 1488 1489 // Handle catch list 1490 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { 1491 llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("nextcatch"); 1492 1493 QualType T; 1494 bool MatchesAll = false; 1495 1496 // catch(...) always matches. 1497 if (CatchStmt->hasEllipsis()) 1498 MatchesAll = true; 1499 else { 1500 const DeclStmt *DS = cast<DeclStmt>(CatchStmt->getCatchParamStmt()); 1501 QualType PT = cast<ValueDecl>(DS->getDecl())->getType(); 1502 T = PT->getAsPointerType()->getPointeeType(); 1503 1504 // catch(id e) always matches. 1505 if (CGF.getContext().isObjCIdType(T)) 1506 MatchesAll = true; 1507 } 1508 1509 if (MatchesAll) { 1510 CGF.EmitStmt(CatchStmt->getCatchBody()); 1511 CGF.Builder.CreateBr(FinallyBlock); 1512 1513 CGF.EmitBlock(NextCatchBlock); 1514 break; 1515 } 1516 1517 const ObjCInterfaceType *ObjCType = T->getAsPointerToObjCInterfaceType(); 1518 assert(ObjCType && "Catch parameter must have Objective-C type!"); 1519 1520 // Check if the @catch block matches the exception object. 1521 llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl()); 1522 1523 llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught"); 1524 llvm::Value *Match = CGF.Builder.CreateCall2(ObjCTypes.ExceptionMatchFn, 1525 Class, Caught, "match"); 1526 1527 llvm::Value *DidMatch = CGF.Builder.CreateICmpNE(Match, Zero, "iszero"); 1528 1529 llvm::BasicBlock *MatchedBlock = llvm::BasicBlock::Create("matched"); 1530 1531 CGF.Builder.CreateCondBr(DidMatch, MatchedBlock, NextCatchBlock); 1532 1533 // Emit the @catch block. 1534 CGF.EmitBlock(MatchedBlock); 1535 CGF.EmitStmt(CatchStmt->getCatchBody()); 1536 CGF.Builder.CreateBr(FinallyBlock); 1537 1538 CGF.EmitBlock(NextCatchBlock); 1539 } 1540 1541 // None of the handlers caught the exception, so store it and rethrow 1542 // it later. 1543 llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught"); 1544 CGF.Builder.CreateStore(Caught, RethrowPtr); 1545 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, 1546 ExceptionData); 1547 1548 CGF.Builder.CreateBr(FinallyBlock); 1549 1550 CGF.EmitBlock(ExceptionInCatchBlock); 1551 1552 Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, 1553 ExceptionData); 1554 CGF.Builder.CreateStore(Extract, RethrowPtr); 1555 } 1556 1557 // Emit the @finally block. 1558 CGF.EmitBlock(FinallyBlock); 1559 1560 llvm::Value *Rethrow = CGF.Builder.CreateLoad(RethrowPtr); 1561 llvm::Value *ZeroPtr = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); 1562 1563 llvm::Value *RethrowIsZero = CGF.Builder.CreateICmpEQ(Rethrow, ZeroPtr); 1564 1565 llvm::BasicBlock *TryExitBlock = llvm::BasicBlock::Create("tryexit"); 1566 llvm::BasicBlock *AfterTryExitBlock = 1567 llvm::BasicBlock::Create("aftertryexit"); 1568 1569 CGF.Builder.CreateCondBr(RethrowIsZero, TryExitBlock, AfterTryExitBlock); 1570 CGF.EmitBlock(TryExitBlock); 1571 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); 1572 CGF.EmitBlock(AfterTryExitBlock); 1573 1574 if (const ObjCAtFinallyStmt* FinallyStmt = S.getFinallyStmt()) 1575 CGF.EmitStmt(FinallyStmt->getFinallyBody()); 1576 1577 llvm::Value *RethrowIsNotZero = CGF.Builder.CreateICmpNE(Rethrow, ZeroPtr); 1578 1579 llvm::BasicBlock *RethrowBlock = llvm::BasicBlock::Create("rethrow"); 1580 llvm::BasicBlock *FinallyEndBlock = llvm::BasicBlock::Create("finallyend"); 1581 1582 // If necessary, rethrow the exception. 1583 CGF.Builder.CreateCondBr(RethrowIsNotZero, RethrowBlock, FinallyEndBlock); 1584 CGF.EmitBlock(RethrowBlock); 1585 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, Rethrow); 1586 CGF.EmitBlock(FinallyEndBlock); 1587} 1588 1589void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF, 1590 const ObjCAtThrowStmt &S) 1591{ 1592 llvm::Value *ExceptionAsObject; 1593 1594 if (const Expr *ThrowExpr = S.getThrowExpr()) { 1595 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr); 1596 ExceptionAsObject = 1597 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp"); 1598 } else { 1599 assert(0 && "FIXME: rethrows not supported!"); 1600 } 1601 1602 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, ExceptionAsObject); 1603 CGF.Builder.CreateUnreachable(); 1604 CGF.EmitBlock(llvm::BasicBlock::Create("bb")); 1605} 1606 1607/* *** Private Interface *** */ 1608 1609/// EmitImageInfo - Emit the image info marker used to encode some module 1610/// level information. 1611/// 1612/// See: <rdr://4810609&4810587&4810587> 1613/// struct IMAGE_INFO { 1614/// unsigned version; 1615/// unsigned flags; 1616/// }; 1617enum ImageInfoFlags { 1618 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies 1619 eImageInfo_GarbageCollected = (1 << 1), 1620 eImageInfo_GCOnly = (1 << 2) 1621}; 1622 1623void CGObjCMac::EmitImageInfo() { 1624 unsigned version = 0; // Version is unused? 1625 unsigned flags = 0; 1626 1627 // FIXME: Fix and continue? 1628 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 1629 flags |= eImageInfo_GarbageCollected; 1630 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 1631 flags |= eImageInfo_GCOnly; 1632 1633 // Emitted as int[2]; 1634 llvm::Constant *values[2] = { 1635 llvm::ConstantInt::get(llvm::Type::Int32Ty, version), 1636 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags) 1637 }; 1638 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2); 1639 llvm::GlobalVariable *GV = 1640 new llvm::GlobalVariable(AT, true, 1641 llvm::GlobalValue::InternalLinkage, 1642 llvm::ConstantArray::get(AT, values, 2), 1643 "\01L_OBJC_IMAGE_INFO", 1644 &CGM.getModule()); 1645 1646 if (ObjCABI == 1) { 1647 GV->setSection("__OBJC, __image_info,regular"); 1648 } else { 1649 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); 1650 } 1651 1652 UsedGlobals.push_back(GV); 1653} 1654 1655 1656// struct objc_module { 1657// unsigned long version; 1658// unsigned long size; 1659// const char *name; 1660// Symtab symtab; 1661// }; 1662 1663// FIXME: Get from somewhere 1664static const int ModuleVersion = 7; 1665 1666void CGObjCMac::EmitModuleInfo() { 1667 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy); 1668 1669 std::vector<llvm::Constant*> Values(4); 1670 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion); 1671 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 1672 // This used to be the filename, now it is unused. <rdr://4327263> 1673 Values[2] = GetClassName(&CGM.getContext().Idents.get("")); 1674 Values[3] = EmitModuleSymbols(); 1675 1676 llvm::GlobalVariable *GV = 1677 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false, 1678 llvm::GlobalValue::InternalLinkage, 1679 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, 1680 Values), 1681 "\01L_OBJC_MODULES", 1682 &CGM.getModule()); 1683 GV->setSection("__OBJC,__module_info,regular,no_dead_strip"); 1684 UsedGlobals.push_back(GV); 1685} 1686 1687llvm::Constant *CGObjCMac::EmitModuleSymbols() { 1688 unsigned NumClasses = DefinedClasses.size(); 1689 unsigned NumCategories = DefinedCategories.size(); 1690 1691 // Return null if no symbols were defined. 1692 if (!NumClasses && !NumCategories) 1693 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy); 1694 1695 std::vector<llvm::Constant*> Values(5); 1696 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); 1697 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy); 1698 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses); 1699 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories); 1700 1701 // The runtime expects exactly the list of defined classes followed 1702 // by the list of defined categories, in a single array. 1703 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories); 1704 for (unsigned i=0; i<NumClasses; i++) 1705 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i], 1706 ObjCTypes.Int8PtrTy); 1707 for (unsigned i=0; i<NumCategories; i++) 1708 Symbols[NumClasses + i] = 1709 llvm::ConstantExpr::getBitCast(DefinedCategories[i], 1710 ObjCTypes.Int8PtrTy); 1711 1712 Values[4] = 1713 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy, 1714 NumClasses + NumCategories), 1715 Symbols); 1716 1717 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 1718 1719 llvm::GlobalVariable *GV = 1720 new llvm::GlobalVariable(Init->getType(), false, 1721 llvm::GlobalValue::InternalLinkage, 1722 Init, 1723 "\01L_OBJC_SYMBOLS", 1724 &CGM.getModule()); 1725 GV->setSection("__OBJC,__symbols,regular,no_dead_strip"); 1726 UsedGlobals.push_back(GV); 1727 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy); 1728} 1729 1730llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder, 1731 const ObjCInterfaceDecl *ID) { 1732 LazySymbols.insert(ID->getIdentifier()); 1733 1734 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()]; 1735 1736 if (!Entry) { 1737 llvm::Constant *Casted = 1738 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()), 1739 ObjCTypes.ClassPtrTy); 1740 Entry = 1741 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false, 1742 llvm::GlobalValue::InternalLinkage, 1743 Casted, "\01L_OBJC_CLASS_REFERENCES_", 1744 &CGM.getModule()); 1745 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip"); 1746 UsedGlobals.push_back(Entry); 1747 } 1748 1749 return Builder.CreateLoad(Entry, false, "tmp"); 1750} 1751 1752llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) { 1753 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 1754 1755 if (!Entry) { 1756 llvm::Constant *Casted = 1757 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 1758 ObjCTypes.SelectorPtrTy); 1759 Entry = 1760 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false, 1761 llvm::GlobalValue::InternalLinkage, 1762 Casted, "\01L_OBJC_SELECTOR_REFERENCES_", 1763 &CGM.getModule()); 1764 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip"); 1765 UsedGlobals.push_back(Entry); 1766 } 1767 1768 return Builder.CreateLoad(Entry, false, "tmp"); 1769} 1770 1771llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) { 1772 llvm::GlobalVariable *&Entry = ClassNames[Ident]; 1773 1774 if (!Entry) { 1775 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName()); 1776 Entry = 1777 new llvm::GlobalVariable(C->getType(), false, 1778 llvm::GlobalValue::InternalLinkage, 1779 C, "\01L_OBJC_CLASS_NAME_", 1780 &CGM.getModule()); 1781 Entry->setSection("__TEXT,__cstring,cstring_literals"); 1782 UsedGlobals.push_back(Entry); 1783 } 1784 1785 return getConstantGEP(Entry, 0, 0); 1786} 1787 1788llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) { 1789 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 1790 1791 if (!Entry) { 1792 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName()); 1793 Entry = 1794 new llvm::GlobalVariable(C->getType(), false, 1795 llvm::GlobalValue::InternalLinkage, 1796 C, "\01L_OBJC_METH_VAR_NAME_", 1797 &CGM.getModule()); 1798 Entry->setSection("__TEXT,__cstring,cstring_literals"); 1799 UsedGlobals.push_back(Entry); 1800 } 1801 1802 return getConstantGEP(Entry, 0, 0); 1803} 1804 1805// FIXME: Merge into a single cstring creation function. 1806llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) { 1807 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID)); 1808} 1809 1810// FIXME: Merge into a single cstring creation function. 1811llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) { 1812 return GetMethodVarName(&CGM.getContext().Idents.get(Name)); 1813} 1814 1815llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) { 1816 llvm::GlobalVariable *&Entry = MethodVarTypes[Name]; 1817 1818 if (!Entry) { 1819 llvm::Constant *C = llvm::ConstantArray::get(Name); 1820 Entry = 1821 new llvm::GlobalVariable(C->getType(), false, 1822 llvm::GlobalValue::InternalLinkage, 1823 C, "\01L_OBJC_METH_VAR_TYPE_", 1824 &CGM.getModule()); 1825 Entry->setSection("__TEXT,__cstring,cstring_literals"); 1826 UsedGlobals.push_back(Entry); 1827 } 1828 1829 return getConstantGEP(Entry, 0, 0); 1830} 1831 1832// FIXME: Merge into a single cstring creation function. 1833llvm::Constant *CGObjCMac::GetMethodVarType(const ObjCMethodDecl *D) { 1834 std::string TypeStr; 1835 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D), 1836 TypeStr); 1837 return GetMethodVarType(TypeStr); 1838} 1839 1840// FIXME: Merge into a single cstring creation function. 1841llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) { 1842 llvm::GlobalVariable *&Entry = PropertyNames[Ident]; 1843 1844 if (!Entry) { 1845 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName()); 1846 Entry = 1847 new llvm::GlobalVariable(C->getType(), false, 1848 llvm::GlobalValue::InternalLinkage, 1849 C, "\01L_OBJC_PROP_NAME_ATTR_", 1850 &CGM.getModule()); 1851 Entry->setSection("__TEXT,__cstring,cstring_literals"); 1852 UsedGlobals.push_back(Entry); 1853 } 1854 1855 return getConstantGEP(Entry, 0, 0); 1856} 1857 1858// FIXME: Merge into a single cstring creation function. 1859// FIXME: This Decl should be more precise. 1860llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD, 1861 const Decl *Container) { 1862 std::string TypeStr; 1863 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr); 1864 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr)); 1865} 1866 1867void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D, 1868 std::string &NameOut) { 1869 // FIXME: Find the mangling GCC uses. 1870 std::stringstream s; 1871 s << (D->isInstance() ? "-" : "+"); 1872 s << "["; 1873 s << D->getClassInterface()->getName(); 1874 s << " "; 1875 s << D->getSelector().getName(); 1876 s << "]"; 1877 NameOut = s.str(); 1878} 1879 1880void CGObjCMac::FinishModule() { 1881 EmitModuleInfo(); 1882 1883 std::vector<llvm::Constant*> Used; 1884 1885 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), 1886 e = UsedGlobals.end(); i != e; ++i) { 1887 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); 1888 } 1889 1890 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); 1891 llvm::GlobalValue *GV = 1892 new llvm::GlobalVariable(AT, false, 1893 llvm::GlobalValue::AppendingLinkage, 1894 llvm::ConstantArray::get(AT, Used), 1895 "llvm.used", 1896 &CGM.getModule()); 1897 1898 GV->setSection("llvm.metadata"); 1899 1900 // Add assembler directives to add lazy undefined symbol references 1901 // for classes which are referenced but not defined. This is 1902 // important for correct linker interaction. 1903 1904 // FIXME: Uh, this isn't particularly portable. 1905 std::stringstream s; 1906 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(), 1907 e = LazySymbols.end(); i != e; ++i) { 1908 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n"; 1909 } 1910 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(), 1911 e = DefinedSymbols.end(); i != e; ++i) { 1912 s << "\t.objc_class_name_" << (*i)->getName() << "=0\n" 1913 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n"; 1914 } 1915 CGM.getModule().appendModuleInlineAsm(s.str()); 1916} 1917 1918/* *** */ 1919 1920ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 1921 : CGM(cgm) 1922{ 1923 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 1924 ASTContext &Ctx = CGM.getContext(); 1925 1926 ShortTy = Types.ConvertType(Ctx.ShortTy); 1927 IntTy = Types.ConvertType(Ctx.IntTy); 1928 LongTy = Types.ConvertType(Ctx.LongTy); 1929 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 1930 1931 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 1932 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 1933 1934 // FIXME: It would be nice to unify this with the opaque type, so 1935 // that the IR comes out a bit cleaner. 1936 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 1937 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 1938 1939 MethodDescriptionTy = 1940 llvm::StructType::get(SelectorPtrTy, 1941 Int8PtrTy, 1942 NULL); 1943 CGM.getModule().addTypeName("struct._objc_method_description", 1944 MethodDescriptionTy); 1945 1946 MethodDescriptionListTy = 1947 llvm::StructType::get(IntTy, 1948 llvm::ArrayType::get(MethodDescriptionTy, 0), 1949 NULL); 1950 CGM.getModule().addTypeName("struct._objc_method_description_list", 1951 MethodDescriptionListTy); 1952 MethodDescriptionListPtrTy = 1953 llvm::PointerType::getUnqual(MethodDescriptionListTy); 1954 1955 PropertyTy = llvm::StructType::get(Int8PtrTy, 1956 Int8PtrTy, 1957 NULL); 1958 CGM.getModule().addTypeName("struct._objc_property", 1959 PropertyTy); 1960 1961 PropertyListTy = llvm::StructType::get(IntTy, 1962 IntTy, 1963 llvm::ArrayType::get(PropertyTy, 0), 1964 NULL); 1965 CGM.getModule().addTypeName("struct._objc_property_list", 1966 PropertyListTy); 1967 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 1968 1969 // Protocol description structures 1970 1971 ProtocolExtensionTy = 1972 llvm::StructType::get(Types.ConvertType(Ctx.IntTy), 1973 llvm::PointerType::getUnqual(MethodDescriptionListTy), 1974 llvm::PointerType::getUnqual(MethodDescriptionListTy), 1975 PropertyListPtrTy, 1976 NULL); 1977 CGM.getModule().addTypeName("struct._objc_protocol_extension", 1978 ProtocolExtensionTy); 1979 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 1980 1981 // Handle recursive construction of Protocl and ProtocolList types 1982 1983 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(); 1984 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); 1985 1986 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder), 1987 LongTy, 1988 llvm::ArrayType::get(ProtocolTyHolder, 0), 1989 NULL); 1990 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T); 1991 1992 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy), 1993 Int8PtrTy, 1994 llvm::PointerType::getUnqual(ProtocolListTyHolder), 1995 MethodDescriptionListPtrTy, 1996 MethodDescriptionListPtrTy, 1997 NULL); 1998 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T); 1999 2000 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get()); 2001 CGM.getModule().addTypeName("struct._objc_protocol_list", 2002 ProtocolListTy); 2003 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 2004 2005 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get()); 2006 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy); 2007 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 2008 2009 // Class description structures 2010 2011 IvarTy = llvm::StructType::get(Int8PtrTy, 2012 Int8PtrTy, 2013 IntTy, 2014 NULL); 2015 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy); 2016 2017 IvarListTy = llvm::OpaqueType::get(); 2018 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy); 2019 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); 2020 2021 MethodTy = llvm::StructType::get(SelectorPtrTy, 2022 Int8PtrTy, 2023 Int8PtrTy, 2024 NULL); 2025 CGM.getModule().addTypeName("struct._objc_method", MethodTy); 2026 2027 MethodListTy = llvm::OpaqueType::get(); 2028 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy); 2029 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); 2030 2031 CacheTy = llvm::OpaqueType::get(); 2032 CGM.getModule().addTypeName("struct._objc_cache", CacheTy); 2033 CachePtrTy = llvm::PointerType::getUnqual(CacheTy); 2034 2035 ClassExtensionTy = 2036 llvm::StructType::get(IntTy, 2037 Int8PtrTy, 2038 PropertyListPtrTy, 2039 NULL); 2040 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy); 2041 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy); 2042 2043 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(); 2044 2045 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder), 2046 llvm::PointerType::getUnqual(ClassTyHolder), 2047 Int8PtrTy, 2048 LongTy, 2049 LongTy, 2050 LongTy, 2051 IvarListPtrTy, 2052 MethodListPtrTy, 2053 CachePtrTy, 2054 ProtocolListPtrTy, 2055 Int8PtrTy, 2056 ClassExtensionPtrTy, 2057 NULL); 2058 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T); 2059 2060 ClassTy = cast<llvm::StructType>(ClassTyHolder.get()); 2061 CGM.getModule().addTypeName("struct._objc_class", ClassTy); 2062 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy); 2063 2064 CategoryTy = llvm::StructType::get(Int8PtrTy, 2065 Int8PtrTy, 2066 MethodListPtrTy, 2067 MethodListPtrTy, 2068 ProtocolListPtrTy, 2069 IntTy, 2070 PropertyListPtrTy, 2071 NULL); 2072 CGM.getModule().addTypeName("struct._objc_category", CategoryTy); 2073 2074 // I'm not sure I like this. The implicit coordination is a bit 2075 // gross. We should solve this in a reasonable fashion because this 2076 // is a pretty common task (match some runtime data structure with 2077 // an LLVM data structure). 2078 2079 // FIXME: This is leaked. 2080 // FIXME: Merge with rewriter code? 2081 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0, 2082 SourceLocation(), 2083 &Ctx.Idents.get("_objc_super")); 2084 FieldDecl *FieldDecls[2]; 2085 FieldDecls[0] = FieldDecl::Create(Ctx, SourceLocation(), 0, 2086 Ctx.getObjCIdType()); 2087 FieldDecls[1] = FieldDecl::Create(Ctx, SourceLocation(), 0, 2088 Ctx.getObjCClassType()); 2089 RD->defineBody(Ctx, FieldDecls, 2); 2090 2091 SuperCTy = Ctx.getTagDeclType(RD); 2092 SuperPtrCTy = Ctx.getPointerType(SuperCTy); 2093 2094 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy)); 2095 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); 2096 2097 // Global metadata structures 2098 2099 SymtabTy = llvm::StructType::get(LongTy, 2100 SelectorPtrTy, 2101 ShortTy, 2102 ShortTy, 2103 llvm::ArrayType::get(Int8PtrTy, 0), 2104 NULL); 2105 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy); 2106 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy); 2107 2108 ModuleTy = 2109 llvm::StructType::get(LongTy, 2110 LongTy, 2111 Int8PtrTy, 2112 SymtabPtrTy, 2113 NULL); 2114 CGM.getModule().addTypeName("struct._objc_module", ModuleTy); 2115 2116 // Message send functions 2117 2118 std::vector<const llvm::Type*> Params; 2119 Params.push_back(ObjectPtrTy); 2120 Params.push_back(SelectorPtrTy); 2121 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy, 2122 Params, 2123 true), 2124 llvm::Function::ExternalLinkage, 2125 "objc_msgSend", 2126 &CGM.getModule()); 2127 2128 Params.clear(); 2129 Params.push_back(Int8PtrTy); 2130 Params.push_back(ObjectPtrTy); 2131 Params.push_back(SelectorPtrTy); 2132 MessageSendStretFn = 2133 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy, 2134 Params, 2135 true), 2136 llvm::Function::ExternalLinkage, 2137 "objc_msgSend_stret", 2138 &CGM.getModule()); 2139 2140 Params.clear(); 2141 Params.push_back(SuperPtrTy); 2142 Params.push_back(SelectorPtrTy); 2143 MessageSendSuperFn = 2144 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy, 2145 Params, 2146 true), 2147 llvm::Function::ExternalLinkage, 2148 "objc_msgSendSuper", 2149 &CGM.getModule()); 2150 2151 Params.clear(); 2152 Params.push_back(Int8PtrTy); 2153 Params.push_back(SuperPtrTy); 2154 Params.push_back(SelectorPtrTy); 2155 MessageSendSuperStretFn = 2156 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy, 2157 Params, 2158 true), 2159 llvm::Function::ExternalLinkage, 2160 "objc_msgSendSuper_stret", 2161 &CGM.getModule()); 2162 2163 // Enumeration mutation. 2164 2165 Params.clear(); 2166 Params.push_back(ObjectPtrTy); 2167 EnumerationMutationFn = 2168 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy, 2169 Params, 2170 false), 2171 llvm::Function::ExternalLinkage, 2172 "objc_enumerationMutation", 2173 &CGM.getModule()); 2174 2175 // FIXME: This is the size of the setjmp buffer and should be 2176 // target specific. 18 is what's used on 32-bit X86. 2177 uint64_t SetJmpBufferSize = 18; 2178 2179 // Exceptions 2180 const llvm::Type *StackPtrTy = 2181 llvm::PointerType::getUnqual(llvm::ArrayType::get(llvm::Type::Int8Ty, 4)); 2182 2183 ExceptionDataTy = 2184 llvm::StructType::get(llvm::ArrayType::get(llvm::Type::Int32Ty, 2185 SetJmpBufferSize), 2186 StackPtrTy, NULL); 2187 CGM.getModule().addTypeName("struct._objc_exception_data", 2188 ExceptionDataTy); 2189 2190 Params.clear(); 2191 Params.push_back(ObjectPtrTy); 2192 ExceptionThrowFn = 2193 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy, 2194 Params, 2195 false), 2196 llvm::Function::ExternalLinkage, 2197 "objc_exception_throw", 2198 &CGM.getModule()); 2199 2200 Params.clear(); 2201 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy)); 2202 ExceptionTryEnterFn = 2203 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy, 2204 Params, 2205 false), 2206 llvm::Function::ExternalLinkage, 2207 "objc_exception_try_enter", 2208 &CGM.getModule()); 2209 ExceptionTryExitFn = 2210 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy, 2211 Params, 2212 false), 2213 llvm::Function::ExternalLinkage, 2214 "objc_exception_try_exit", 2215 &CGM.getModule()); 2216 ExceptionExtractFn = 2217 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy, 2218 Params, 2219 false), 2220 llvm::Function::ExternalLinkage, 2221 "objc_exception_extract", 2222 &CGM.getModule()); 2223 2224 Params.clear(); 2225 Params.push_back(ClassPtrTy); 2226 Params.push_back(ObjectPtrTy); 2227 ExceptionMatchFn = 2228 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::Int32Ty, 2229 Params, 2230 false), 2231 llvm::Function::ExternalLinkage, 2232 "objc_exception_match", 2233 &CGM.getModule()); 2234 2235 Params.clear(); 2236 Params.push_back(llvm::PointerType::getUnqual(llvm::Type::Int32Ty)); 2237 SetJmpFn = 2238 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::Int32Ty, 2239 Params, 2240 false), 2241 llvm::Function::ExternalLinkage, 2242 "_setjmp", 2243 &CGM.getModule()); 2244 2245} 2246 2247ObjCTypesHelper::~ObjCTypesHelper() { 2248} 2249 2250llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper, 2251 bool IsStret, 2252 const llvm::Type *ReturnTy) { 2253 llvm::Function *F; 2254 llvm::FunctionType *CallFTy; 2255 2256 // FIXME: Should we be caching any of this? 2257 if (IsStret) { 2258 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn; 2259 std::vector<const llvm::Type*> Params(3); 2260 Params[0] = llvm::PointerType::getUnqual(ReturnTy); 2261 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy; 2262 Params[2] = SelectorPtrTy; 2263 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true); 2264 } else { // FIXME: floating point? 2265 F = IsSuper ? MessageSendSuperFn : MessageSendFn; 2266 std::vector<const llvm::Type*> Params(2); 2267 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy; 2268 Params[1] = SelectorPtrTy; 2269 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true); 2270 } 2271 2272 return llvm::ConstantExpr::getBitCast(F, 2273 llvm::PointerType::getUnqual(CallFTy)); 2274} 2275 2276/* *** */ 2277 2278CodeGen::CGObjCRuntime * 2279CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 2280 return new CGObjCMac(CGM); 2281} 2282