CGObjCMac.cpp revision 6efc0c559b5f9861d4bbd4aef5b4897c02b2ae74
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 "clang/AST/ASTContext.h" 18#include "clang/AST/Decl.h" 19#include "clang/AST/DeclObjC.h" 20#include "clang/Basic/LangOptions.h" 21 22#include "llvm/Module.h" 23#include "llvm/Support/IRBuilder.h" 24#include "llvm/Target/TargetData.h" 25 26using namespace clang; 27 28namespace { 29 30 // FIXME: We should find a nicer way to make the labels for 31 // metadata, string concatenation is lame. 32 33/// ObjCTypesHelper - Helper class that encapsulates lazy 34/// construction of varies types used during ObjC generation. 35class ObjCTypesHelper { 36private: 37 CodeGen::CodeGenModule &CGM; 38 39 const llvm::StructType *CFStringType; 40 llvm::Constant *CFConstantStringClassReference; 41 llvm::Function *MessageSendFn; 42 43public: 44 const llvm::Type *IntTy, *LongTy; 45 46 /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 47 const llvm::Type *ObjectPtrTy; 48 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 49 const llvm::Type *SelectorPtrTy; 50 /// ProtocolPtrTy - LLVM type for external protocol handles 51 /// (typeof(Protocol)) 52 const llvm::Type *ExternalProtocolPtrTy; 53 54 /// SymtabTy - LLVM type for struct objc_symtab. 55 const llvm::StructType *SymtabTy; 56 /// ModuleTy - LLVM type for struct objc_module. 57 const llvm::StructType *ModuleTy; 58 59 /// ProtocolTy - LLVM type for struct objc_protocol. 60 const llvm::StructType *ProtocolTy; 61 /// ProtocolPtrTy - LLVM type for struct objc_protocol *. 62 const llvm::Type *ProtocolPtrTy; 63 /// ProtocolExtensionTy - LLVM type for struct 64 /// objc_protocol_extension. 65 const llvm::StructType *ProtocolExtensionTy; 66 /// ProtocolExtensionTy - LLVM type for struct 67 /// objc_protocol_extension *. 68 const llvm::Type *ProtocolExtensionPtrTy; 69 /// MethodDescriptionTy - LLVM type for struct 70 /// objc_method_description. 71 const llvm::StructType *MethodDescriptionTy; 72 /// MethodDescriptionListTy - LLVM type for struct 73 /// objc_method_description_list. 74 const llvm::StructType *MethodDescriptionListTy; 75 /// MethodDescriptionListPtrTy - LLVM type for struct 76 /// objc_method_description_list *. 77 const llvm::Type *MethodDescriptionListPtrTy; 78 /// PropertyListTy - LLVM type for struct objc_property_list. 79 const llvm::Type *PropertyListTy; 80 /// PropertyListPtrTy - LLVM type for struct objc_property_list*. 81 const llvm::Type *PropertyListPtrTy; 82 /// ProtocolListTy - LLVM type for struct objc_property_list. 83 const llvm::Type *ProtocolListTy; 84 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. 85 const llvm::Type *ProtocolListPtrTy; 86 87public: 88 ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 89 ~ObjCTypesHelper(); 90 91 llvm::Constant *getCFConstantStringClassReference(); 92 const llvm::StructType *getCFStringType(); 93 llvm::Function *getMessageSendFn(); 94}; 95 96class CGObjCMac : public CodeGen::CGObjCRuntime { 97private: 98 CodeGen::CodeGenModule &CGM; 99 ObjCTypesHelper ObjCTypes; 100 /// ObjCABI - FIXME: Not sure yet. 101 unsigned ObjCABI; 102 103 /// ClassNames - uniqued class names. 104 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames; 105 106 /// MethodVarNames - uniqued method variable names. 107 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 108 109 /// MethodVarTypes - uniqued method type signatures. We have to use 110 /// a StringMap here because have no other unique reference. 111 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes; 112 113 /// SelectorReferences - uniqued selector references. 114 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 115 116 /// Protocols - Protocols for which an objc_protocol structure has 117 /// been emitted. Forward declarations are handled by creating an 118 /// empty structure whose initializer is filled in when/if defined. 119 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols; 120 121 /// UsedGlobals - List of globals to pack into the llvm.used metadata 122 /// to prevent them from being clobbered. 123 std::vector<llvm::GlobalVariable*> UsedGlobals; 124 125 /// EmitImageInfo - Emit the image info marker used to encode some module 126 /// level information. 127 void EmitImageInfo(); 128 129 /// EmitModuleInfo - Another marker encoding module level 130 /// information. 131 132 // FIXME: Not sure yet of the difference between this and 133 // IMAGE_INFO. otool looks at this before printing out Obj-C info 134 // though... 135 void EmitModuleInfo(); 136 137 /// EmitModuleSymols - Emit module symbols, the result is a constant 138 /// of type pointer-to SymtabTy. // FIXME: Describe more completely 139 /// once known. 140 llvm::Constant *EmitModuleSymbols(); 141 142 /// FinishModule - Write out global data structures at the end of 143 /// processing a translation unit. 144 void FinishModule(); 145 146 /// EmitMethodList - Emit a method description list for a list of 147 /// method declarations. 148 /// - TypeName: The name for the type containing the methods. 149 /// - IsProtocol: True iff these methods are for a protocol. 150 /// - ClassMethds: True iff these are class methods. 151 /// - Required: When true, only "required" methods are 152 /// listed. Similarly, when false only "optional" methods are 153 /// listed. For classes this should always be true. 154 /// - begin, end: The method list to output. 155 /// 156 /// The return value has type MethodDescriptionListPtrTy. 157 llvm::Constant *EmitMethodList(const std::string &TypeName, 158 bool IsProtocol, 159 bool ClassMethods, 160 bool Required, 161 ObjCMethodDecl * const *begin, 162 ObjCMethodDecl * const *end); 163 164 /// EmitProtocolExtension - Generate the protocol extension 165 /// structure used to store optional instance and class methods, and 166 /// protocol properties. The return value has type 167 /// ProtocolExtensionPtrTy. 168 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD); 169 170 /// EmitProtocolList - Generate the list of referenced 171 /// protocols. The return value has type ProtocolListPtrTy. 172 llvm::Constant *EmitProtocolList(const ObjCProtocolDecl *PD); 173 174 /// GetProtocolRef - Return a reference to the internal protocol 175 /// description, creating an empty one if it has not been 176 /// defined. The return value has type pointer-to ProtocolTy. 177 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD); 178 179 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 180 /// for the given selector. 181 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel); 182 183 /// GetClassName - Return a unique constant for the given selector's 184 /// name. 185 llvm::Constant *GetClassName(IdentifierInfo *Ident); 186 187 /// GetMethodVarName - Return a unique constant for the given 188 /// selector's name. This returns a constant i8* to the start of 189 /// the name. 190 llvm::Constant *GetMethodVarName(Selector Sel); 191 192 /// GetMethodVarType - Return a unique constant for the given 193 /// selector's name. This returns a constant i8* to the start of 194 /// the name. 195 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D); 196 197public: 198 CGObjCMac(CodeGen::CodeGenModule &cgm); 199 virtual llvm::Constant *GenerateConstantString(const std::string &String); 200 201 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder, 202 const llvm::Type *ReturnTy, 203 llvm::Value *Receiver, 204 Selector Sel, 205 llvm::Value** ArgV, 206 unsigned ArgC); 207 208 virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, 209 const llvm::Type *ReturnTy, 210 const char *SuperClassName, 211 llvm::Value *Receiver, 212 Selector Sel, 213 llvm::Value** ArgV, 214 unsigned ArgC); 215 216 virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder, 217 llvm::Value *ClassName); 218 219 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel); 220 221 virtual llvm::Function *MethodPreamble(const std::string &ClassName, 222 const std::string &CategoryName, 223 const std::string &MethodName, 224 const llvm::Type *ReturnTy, 225 const llvm::Type *SelfTy, 226 const llvm::Type **ArgTy, 227 unsigned ArgC, 228 bool isClassMethod, 229 bool isVarArg); 230 231 virtual void GenerateCategory(const char *ClassName, const char *CategoryName, 232 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 233 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 234 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 235 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 236 const llvm::SmallVectorImpl<std::string> &Protocols); 237 238 virtual void GenerateClass( 239 const char *ClassName, 240 const char *SuperClassName, 241 const int instanceSize, 242 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 243 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 244 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets, 245 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 246 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 247 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 248 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 249 const llvm::SmallVectorImpl<std::string> &Protocols); 250 251 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder, 252 const ObjCProtocolDecl *PD); 253 254 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 255 256 virtual llvm::Function *ModuleInitFunction(); 257}; 258} // end anonymous namespace 259 260/* *** Helper Functions *** */ 261 262/// getConstantGEP() - Help routine to construct simple GEPs. 263static llvm::Constant *getConstantGEP(llvm::Constant *C, 264 unsigned idx0, 265 unsigned idx1) { 266 llvm::Value *Idxs[] = { 267 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0), 268 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1) 269 }; 270 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2); 271} 272 273/* *** CGObjCMac Public Interface *** */ 274 275CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) 276 : CGM(cgm), 277 ObjCTypes(cgm), 278 ObjCABI(1) 279{ 280 // FIXME: How does this get set in GCC? And what does it even mean? 281 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy)) 282 ObjCABI = 2; 283 284 EmitImageInfo(); 285} 286 287// This has to perform the lookup every time, since posing and related 288// techniques can modify the name -> class mapping. 289llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder, 290 llvm::Value *ClassName) { 291 assert(0 && "Cannot lookup classes on Mac runtime."); 292 return 0; 293} 294 295/// GetSelector - Return the pointer to the unique'd string for this selector. 296llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) { 297 return EmitSelector(Builder, Sel); 298} 299 300/// Generate a constant CFString object. 301/* 302 struct __builtin_CFString { 303 const int *isa; // point to __CFConstantStringClassReference 304 int flags; 305 const char *str; 306 long length; 307 }; 308*/ 309 310llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) { 311 // FIXME: I have no idea what this constant is (it is a magic 312 // constant in GCC as well). Most likely the encoding of the string 313 // and at least one part of it relates to UTF-16. Is this just the 314 // code for UTF-8? Where is this handled for us? 315 // See: <rdr://2996215> 316 unsigned flags = 0x07c8; 317 318 // FIXME: Use some machinery to unique this. We can't reuse the CGM 319 // one since we put them in a different section. 320 llvm::Constant *StringC = llvm::ConstantArray::get(String); 321 llvm::Constant *StringGV = 322 new llvm::GlobalVariable(StringC->getType(), true, 323 llvm::GlobalValue::InternalLinkage, 324 StringC, ".str", &CGM.getModule()); 325 llvm::Constant *Values[4] = { 326 ObjCTypes.getCFConstantStringClassReference(), 327 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags), 328 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr 329 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size()) 330 }; 331 332 llvm::Constant *CFStringC = 333 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(), 334 std::vector<llvm::Constant*>(Values, Values+4)); 335 336 llvm::GlobalVariable *CFStringGV = 337 new llvm::GlobalVariable(CFStringC->getType(), true, 338 llvm::GlobalValue::InternalLinkage, 339 CFStringC, "", 340 &CGM.getModule()); 341 342 CFStringGV->setSection("__DATA, __cfstring"); 343 344 return CFStringGV; 345} 346 347/// Generates a message send where the super is the receiver. This is 348/// a message send to self with special delivery semantics indicating 349/// which class's method should be called. 350llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, 351 const llvm::Type *ReturnTy, 352 const char *SuperClassName, 353 llvm::Value *Receiver, 354 Selector Sel, 355 llvm::Value** ArgV, 356 unsigned ArgC) { 357 assert(0 && "Cannot generate message send to super for Mac runtime."); 358 return 0; 359} 360 361/// Generate code for a message send expression. 362llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder, 363 const llvm::Type *ReturnTy, 364 llvm::Value *Receiver, 365 Selector Sel, 366 llvm::Value** ArgV, 367 unsigned ArgC) { 368 llvm::Function *F = ObjCTypes.getMessageSendFn(); 369 llvm::Value **Args = new llvm::Value*[ArgC+2]; 370 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp"); 371 Args[1] = EmitSelector(Builder, Sel); 372 std::copy(ArgV, ArgV+ArgC, Args+2); 373 llvm::CallInst *CI = Builder.CreateCall(F, Args, Args+ArgC+2, "tmp"); 374 delete[] Args; 375 return Builder.CreateBitCast(CI, ReturnTy, "tmp"); 376} 377 378llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder, 379 const ObjCProtocolDecl *PD) { 380 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), 381 ObjCTypes.ExternalProtocolPtrTy); 382} 383 384/* 385 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions 386 struct _objc_protocol { 387 struct _objc_protocol_extension *isa; 388 char *protocol_name; 389 struct _objc_protocol_list *protocol_list; 390 struct _objc__method_prototype_list *instance_methods; 391 struct _objc__method_prototype_list *class_methods 392 }; 393 394 See EmitProtocolExtension(). 395*/ 396void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 397 const char *ProtocolName = PD->getName(); 398 399 std::vector<llvm::Constant*> Values(5); 400 Values[0] = EmitProtocolExtension(PD); 401 Values[1] = GetClassName(PD->getIdentifier()); 402 Values[2] = EmitProtocolList(PD); 403 Values[3] = EmitMethodList(ProtocolName, 404 true, // IsProtocol 405 false, // ClassMethods 406 true, // Required 407 PD->instmeth_begin(), 408 PD->instmeth_end()); 409 Values[4] = EmitMethodList(ProtocolName, 410 true, // IsProtocol 411 true, // ClassMethods 412 true, // Required 413 PD->classmeth_begin(), 414 PD->classmeth_end()); 415 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 416 Values); 417 418 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 419 if (Entry) { 420 // Already created, just update the initializer 421 Entry->setInitializer(Init); 422 } else { 423 Entry = 424 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 425 llvm::GlobalValue::InternalLinkage, 426 Init, 427 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName, 428 &CGM.getModule()); 429 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 430 UsedGlobals.push_back(Entry); 431 // FIXME: Is this necessary? Why only for protocol? 432 Entry->setAlignment(4); 433 } 434} 435 436llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) { 437 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()]; 438 439 if (!Entry) { 440 std::vector<llvm::Constant*> Values(5); 441 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 442 Values[1] = GetClassName(PD->getIdentifier()); 443 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 444 Values[3] = Values[4] = 445 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 446 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, 447 Values); 448 449 Entry = 450 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false, 451 llvm::GlobalValue::InternalLinkage, 452 Init, 453 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(), 454 &CGM.getModule()); 455 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip"); 456 UsedGlobals.push_back(Entry); 457 // FIXME: Is this necessary? Why only for protocol? 458 Entry->setAlignment(4); 459 } 460 461 return Entry; 462} 463 464/* 465 struct _objc_protocol_extension { 466 uint32_t size; 467 struct objc_method_description_list *optional_instance_methods; 468 struct objc_method_description_list *optional_class_methods; 469 struct objc_property_list *instance_properties; 470 }; 471*/ 472llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) { 473 uint64_t Size = 474 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy); 475 std::vector<llvm::Constant*> Values(4); 476 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); 477 Values[1] = EmitMethodList(PD->getName(), 478 true, // IsProtocol 479 false, // ClassMethods 480 false, // Required 481 PD->instmeth_begin(), 482 PD->instmeth_end()); 483 Values[2] = EmitMethodList(PD->getName(), 484 true, // IsProtocol 485 true, // ClassMethods 486 false, // Required 487 PD->classmeth_begin(), 488 PD->classmeth_end()); 489 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); 490 assert(!PD->getNumPropertyDecl() && 491 "Cannot emit Obj-C protocol properties for NeXT runtime."); 492 493 // Return null if no extension bits are used 494 if (Values[1]->isNullValue() && Values[2]->isNullValue() && 495 Values[3]->isNullValue()) 496 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy); 497 498 llvm::Constant *Init = 499 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values); 500 llvm::GlobalVariable *GV = 501 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false, 502 llvm::GlobalValue::InternalLinkage, 503 Init, 504 (std::string("\01L_OBJC_PROTOCOLEXT_") + 505 PD->getName()), 506 &CGM.getModule()); 507 // No special section, but goes in llvm.used 508 UsedGlobals.push_back(GV); 509 510 return GV; 511} 512 513/* 514 struct objc_protocol_list { 515 struct objc_protocol_list *next; 516 long count; 517 Protocol *list[]; 518 }; 519*/ 520llvm::Constant *CGObjCMac::EmitProtocolList(const ObjCProtocolDecl *PD) { 521 std::vector<llvm::Constant*> ProtocolRefs; 522 523 for (ObjCProtocolDecl::protocol_iterator i = PD->protocol_begin(), 524 e = PD->protocol_end(); i != e; ++i) 525 ProtocolRefs.push_back(GetProtocolRef(*i)); 526 527 // Just return null for empty protocol lists 528 if (ProtocolRefs.empty()) 529 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 530 531 // This list is null terminated? 532 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy)); 533 534 std::vector<llvm::Constant*> Values(3); 535 // XXX: What is this for? 536 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy); 537 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1); 538 Values[2] = 539 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy, 540 ProtocolRefs.size()), 541 ProtocolRefs); 542 543 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 544 llvm::GlobalVariable *GV = 545 new llvm::GlobalVariable(Init->getType(), false, 546 llvm::GlobalValue::InternalLinkage, 547 Init, 548 (std::string("\01L_OBJC_PROTOCOL_REFS_") + 549 PD->getName()), 550 &CGM.getModule()); 551 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip"); 552 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy); 553} 554 555/* 556 struct objc_method_description_list { 557 int count; 558 struct objc_method_description list[]; 559 }; 560*/ 561llvm::Constant *CGObjCMac::EmitMethodList(const std::string &TypeName, 562 bool IsProtocol, 563 bool ClassMethods, 564 bool Required, 565 ObjCMethodDecl * const *begin, 566 ObjCMethodDecl * const *end) { 567 std::vector<llvm::Constant*> Methods, Desc(2); 568 for (; begin != end; ++begin) { 569 ObjCMethodDecl *D = *begin; 570 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional; 571 572 // Skip if this method is required and we are outputting optional 573 // methods, or vice versa. 574 if (Required != IsRequired) 575 continue; 576 577 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()), 578 ObjCTypes.SelectorPtrTy); 579 Desc[1] = GetMethodVarType(D); 580 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy, 581 Desc)); 582 } 583 584 // Return null for empty list. 585 if (Methods.empty()) 586 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy); 587 588 std::vector<llvm::Constant*> Values(2); 589 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); 590 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy, 591 Methods.size()); 592 Values[1] = llvm::ConstantArray::get(AT, Methods); 593 llvm::Constant *Init = llvm::ConstantStruct::get(Values); 594 595 char Prefix[256]; 596 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s", 597 IsProtocol ? "PROTOCOL_" : "", 598 ClassMethods ? "CLASS_" : "INSTANCE_", 599 !Required ? "OPT_" : ""); 600 llvm::GlobalVariable *GV = 601 new llvm::GlobalVariable(Init->getType(), false, 602 llvm::GlobalValue::InternalLinkage, 603 Init, 604 std::string(Prefix) + TypeName, 605 &CGM.getModule()); 606 if (ClassMethods) { 607 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip"); 608 } else { 609 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip"); 610 } 611 UsedGlobals.push_back(GV); 612 return llvm::ConstantExpr::getBitCast(GV, 613 ObjCTypes.MethodDescriptionListPtrTy); 614} 615 616void CGObjCMac::GenerateCategory( 617 const char *ClassName, 618 const char *CategoryName, 619 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 620 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 621 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 622 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 623 const llvm::SmallVectorImpl<std::string> &Protocols) { 624 assert(0 && "Cannot generate category for Mac runtime."); 625} 626 627void CGObjCMac::GenerateClass( 628 const char *ClassName, 629 const char *SuperClassName, 630 const int instanceSize, 631 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 632 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 633 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets, 634 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 635 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 636 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 637 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 638 const llvm::SmallVectorImpl<std::string> &Protocols) { 639 assert(0 && "Cannot generate class for Mac runtime."); 640} 641 642llvm::Function *CGObjCMac::ModuleInitFunction() { 643 // Abuse this interface function as a place to finalize. 644 FinishModule(); 645 646 return NULL; 647} 648 649llvm::Function *CGObjCMac::MethodPreamble(const std::string &ClassName, 650 const std::string &CategoryName, 651 const std::string &MethodName, 652 const llvm::Type *ReturnTy, 653 const llvm::Type *SelfTy, 654 const llvm::Type **ArgTy, 655 unsigned ArgC, 656 bool isClassMethod, 657 bool isVarArg) { 658 assert(0 && "Cannot generate method preamble for Mac runtime."); 659 return 0; 660} 661 662/* *** Private Interface *** */ 663 664/// EmitImageInfo - Emit the image info marker used to encode some module 665/// level information. 666/// 667/// See: <rdr://4810609&4810587&4810587> 668/// struct IMAGE_INFO { 669/// unsigned version; 670/// unsigned flags; 671/// }; 672enum ImageInfoFlags { 673 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies 674 eImageInfo_GarbageCollected = (1 << 1), 675 eImageInfo_GCOnly = (1 << 2) 676}; 677 678void CGObjCMac::EmitImageInfo() { 679 unsigned version = 0; // Version is unused? 680 unsigned flags = 0; 681 682 // FIXME: Fix and continue? 683 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 684 flags |= eImageInfo_GarbageCollected; 685 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 686 flags |= eImageInfo_GCOnly; 687 688 // Emitted as int[2]; 689 llvm::Constant *values[2] = { 690 llvm::ConstantInt::get(llvm::Type::Int32Ty, version), 691 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags) 692 }; 693 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2); 694 llvm::GlobalVariable *GV = 695 new llvm::GlobalVariable(AT, true, 696 llvm::GlobalValue::InternalLinkage, 697 llvm::ConstantArray::get(AT, values, 2), 698 "\01L_OBJC_IMAGE_INFO", 699 &CGM.getModule()); 700 701 if (ObjCABI == 1) { 702 GV->setSection("__OBJC, __image_info,regular"); 703 } else { 704 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); 705 } 706 707 UsedGlobals.push_back(GV); 708} 709 710 711// struct objc_module { 712// unsigned long version; 713// unsigned long size; 714// const char *name; 715// Symtab symtab; 716// }; 717 718// FIXME: Get from somewhere 719static const int ModuleVersion = 7; 720 721void CGObjCMac::EmitModuleInfo() { 722 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy); 723 724 std::vector<llvm::Constant*> Values(4); 725 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion); 726 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 727 // FIXME: GCC just appears to make up an empty name for this? Why? 728 Values[2] = GetClassName(&CGM.getContext().Idents.get("")); 729 Values[3] = EmitModuleSymbols(); 730 731 llvm::GlobalVariable *GV = 732 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false, 733 llvm::GlobalValue::InternalLinkage, 734 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, 735 Values), 736 "\01L_OBJC_MODULES", 737 &CGM.getModule()); 738 GV->setSection("__OBJC,__module_info,regular,no_dead_strip"); 739 UsedGlobals.push_back(GV); 740} 741 742llvm::Constant *CGObjCMac::EmitModuleSymbols() { 743 // FIXME: Is this ever used? 744 llvm::GlobalVariable *GV = 745 new llvm::GlobalVariable(ObjCTypes.SymtabTy, false, 746 llvm::GlobalValue::InternalLinkage, 747 llvm::Constant::getNullValue(ObjCTypes.SymtabTy), 748 "\01L_OBJC_SYMBOLS", 749 &CGM.getModule()); 750 GV->setSection("__OBJC,__symbols,regular,no_dead_strip"); 751 UsedGlobals.push_back(GV); 752 return GV; 753} 754 755llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) { 756 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 757 758 if (!Entry) { 759 llvm::Constant *Casted = 760 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 761 ObjCTypes.SelectorPtrTy); 762 Entry = 763 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false, 764 llvm::GlobalValue::InternalLinkage, 765 Casted, "\01L_OBJC_SELECTOR_REFERENCES_", 766 &CGM.getModule()); 767 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip"); 768 UsedGlobals.push_back(Entry); 769 } 770 771 return Builder.CreateLoad(Entry, false, "tmp"); 772} 773 774llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) { 775 llvm::GlobalVariable *&Entry = ClassNames[Ident]; 776 777 if (!Entry) { 778 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName()); 779 Entry = 780 new llvm::GlobalVariable(C->getType(), false, 781 llvm::GlobalValue::InternalLinkage, 782 C, "\01L_OBJC_CLASS_NAME_", 783 &CGM.getModule()); 784 Entry->setSection("__TEXT,__cstring,cstring_literals"); 785 UsedGlobals.push_back(Entry); 786 } 787 788 return getConstantGEP(Entry, 0, 0); 789} 790 791llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) { 792 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 793 794 if (!Entry) { 795 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName()); 796 Entry = 797 new llvm::GlobalVariable(C->getType(), false, 798 llvm::GlobalValue::InternalLinkage, 799 C, "\01L_OBJC_METH_VAR_NAME_", 800 &CGM.getModule()); 801 Entry->setSection("__TEXT,__cstring,cstring_literals"); 802 UsedGlobals.push_back(Entry); 803 } 804 805 return getConstantGEP(Entry, 0, 0); 806} 807 808llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) { 809 std::string TypeStr; 810 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr); 811 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr]; 812 813 if (!Entry) { 814 llvm::Constant *C = llvm::ConstantArray::get(TypeStr); 815 Entry = 816 new llvm::GlobalVariable(C->getType(), false, 817 llvm::GlobalValue::InternalLinkage, 818 C, "\01L_OBJC_METH_VAR_TYPE_", 819 &CGM.getModule()); 820 Entry->setSection("__TEXT,__cstring,cstring_literals"); 821 UsedGlobals.push_back(Entry); 822 } 823 824 return getConstantGEP(Entry, 0, 0); 825} 826 827void CGObjCMac::FinishModule() { 828 EmitModuleInfo(); 829 830 std::vector<llvm::Constant*> Used; 831 832 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 833 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), 834 e = UsedGlobals.end(); i != e; ++i) { 835 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr)); 836 } 837 838 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size()); 839 llvm::GlobalValue *GV = 840 new llvm::GlobalVariable(AT, false, 841 llvm::GlobalValue::AppendingLinkage, 842 llvm::ConstantArray::get(AT, Used), 843 "llvm.used", 844 &CGM.getModule()); 845 846 GV->setSection("llvm.metadata"); 847} 848 849/* *** */ 850 851ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 852 : CGM(cgm), 853 CFStringType(0), 854 CFConstantStringClassReference(0), 855 MessageSendFn(0) 856{ 857 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 858 ASTContext &Ctx = CGM.getContext(); 859 860 IntTy = Types.ConvertType(Ctx.IntTy); 861 LongTy = Types.ConvertType(Ctx.LongTy); 862 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 863 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 864 865 // FIXME: It would be nice to unify this with the opaque type, so 866 // that the IR comes out a bit cleaner. 867 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType()); 868 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T); 869 870 SymtabTy = llvm::StructType::get(LongTy, 871 SelectorPtrTy, 872 Types.ConvertType(Ctx.ShortTy), 873 Types.ConvertType(Ctx.ShortTy), 874 NULL); 875 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy); 876 877 ModuleTy = 878 llvm::StructType::get(LongTy, 879 LongTy, 880 llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 881 llvm::PointerType::getUnqual(SymtabTy), 882 NULL); 883 CGM.getModule().addTypeName("struct._objc_module", ModuleTy); 884 885 MethodDescriptionTy = 886 llvm::StructType::get(SelectorPtrTy, 887 llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 888 NULL); 889 CGM.getModule().addTypeName("struct._objc_method_description", 890 MethodDescriptionTy); 891 892 MethodDescriptionListTy = 893 llvm::StructType::get(IntTy, 894 llvm::ArrayType::get(MethodDescriptionTy, 0), 895 NULL); 896 CGM.getModule().addTypeName("struct._objc_method_description_list", 897 MethodDescriptionListTy); 898 MethodDescriptionListPtrTy = 899 llvm::PointerType::getUnqual(MethodDescriptionListTy); 900 901 PropertyListTy = llvm::OpaqueType::get(); 902 CGM.getModule().addTypeName("struct._objc_property_list", 903 PropertyListTy); 904 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); 905 906 // Protocol description structures 907 908 ProtocolExtensionTy = 909 llvm::StructType::get(Types.ConvertType(Ctx.IntTy), 910 llvm::PointerType::getUnqual(MethodDescriptionListTy), 911 llvm::PointerType::getUnqual(MethodDescriptionListTy), 912 PropertyListPtrTy, 913 NULL); 914 CGM.getModule().addTypeName("struct._objc_protocol_extension", 915 ProtocolExtensionTy); 916 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy); 917 918 // Handle recursive construction of Protocl and ProtocolList types 919 920 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get(); 921 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); 922 923 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder), 924 LongTy, 925 llvm::ArrayType::get(ProtocolTyHolder, 0), 926 NULL); 927 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T); 928 929 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy), 930 llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 931 llvm::PointerType::getUnqual(ProtocolListTyHolder), 932 MethodDescriptionListPtrTy, 933 MethodDescriptionListPtrTy, 934 NULL); 935 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T); 936 937 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get()); 938 CGM.getModule().addTypeName("struct._objc_protocol_list", 939 ProtocolListTy); 940 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy); 941 942 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get()); 943 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy); 944 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy); 945} 946 947ObjCTypesHelper::~ObjCTypesHelper() { 948} 949 950const llvm::StructType *ObjCTypesHelper::getCFStringType() { 951 if (!CFStringType) { 952 CFStringType = 953 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty), 954 llvm::Type::Int32Ty, 955 llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 956 LongTy, 957 NULL); 958 959 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType); 960 } 961 962 return CFStringType; 963} 964 965llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() { 966 if (!CFConstantStringClassReference) { 967 llvm::GlobalValue *GV = 968 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0), 969 false, 970 llvm::GlobalValue::ExternalLinkage, 971 0, "__CFConstantStringClassReference", 972 &CGM.getModule()); 973 974 // Decay to pointer. 975 CFConstantStringClassReference = getConstantGEP(GV, 0, 0); 976 } 977 978 return CFConstantStringClassReference; 979} 980 981llvm::Function *ObjCTypesHelper::getMessageSendFn() { 982 if (!MessageSendFn) { 983 std::vector<const llvm::Type*> Params; 984 Params.push_back(ObjectPtrTy); 985 Params.push_back(SelectorPtrTy); 986 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy, 987 Params, 988 true), 989 llvm::Function::ExternalLinkage, 990 "objc_msgSend", 991 &CGM.getModule()); 992 } 993 994 return MessageSendFn; 995} 996 997/* *** */ 998 999CodeGen::CGObjCRuntime * 1000CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { 1001 return new CGObjCMac(CGM); 1002} 1003