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