CGObjCMac.cpp revision af2f62ce32e462f256855cd24b06dec4755d2827
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/Basic/LangOptions.h" 20 21#include "llvm/Module.h" 22#include "llvm/Support/IRBuilder.h" 23#include "llvm/Target/TargetData.h" 24 25using namespace clang; 26 27namespace { 28 29/// ObjCTypesHelper - Helper class that encapsulates lazy 30/// construction of varies types used during ObjC generation. 31class ObjCTypesHelper { 32private: 33 CodeGen::CodeGenModule &CGM; 34 35 const llvm::StructType *CFStringType; 36 llvm::Constant *CFConstantStringClassReference; 37 llvm::Function *MessageSendFn; 38 39public: 40 const llvm::Type *LongTy; 41 42 /// ObjectPtrTy - LLVM type for object handles (typeof(id)) 43 const llvm::Type *ObjectPtrTy; 44 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL)) 45 const llvm::Type *SelectorPtrTy; 46 /// ProtocolPtrTy - LLVM type for protocol handles (typeof(Protocol)) 47 const llvm::Type *ProtocolPtrTy; 48 49 /// SymtabTy - LLVM type for struct objc_symtab. 50 const llvm::StructType *SymtabTy; 51 /// ModuleTy - LLVM type for struct objc_module. 52 const llvm::StructType *ModuleTy; 53 54public: 55 ObjCTypesHelper(CodeGen::CodeGenModule &cgm); 56 ~ObjCTypesHelper(); 57 58 llvm::Constant *getCFConstantStringClassReference(); 59 const llvm::StructType *getCFStringType(); 60 llvm::Function *getMessageSendFn(); 61}; 62 63class CGObjCMac : public CodeGen::CGObjCRuntime { 64private: 65 CodeGen::CodeGenModule &CGM; 66 ObjCTypesHelper ObjCTypes; 67 /// ObjCABI - FIXME: Not sure yet. 68 unsigned ObjCABI; 69 70 /// ClassNames - uniqued class names. 71 llvm::DenseMap<Selector, llvm::GlobalVariable*> ClassNames; 72 73 /// MethodVarNames - uniqued method variable names. 74 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames; 75 76 /// SelectorReferences - uniqued selector references. 77 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences; 78 79 /// UsedGlobals - list of globals to pack into the llvm.used metadata 80 /// to prevent them from being clobbered. 81 std::vector<llvm::GlobalVariable*> UsedGlobals; 82 83 /// EmitImageInfo - Emit the image info marker used to encode some module 84 /// level information. 85 void EmitImageInfo(); 86 87 /// EmitModuleInfo - Another marker encoding module level 88 /// information. 89 90 // FIXME: Not sure yet of the difference between this and 91 // IMAGE_INFO. otool looks at this before printing out Obj-C info 92 // though... 93 void EmitModuleInfo(); 94 95 /// EmitModuleSymols - Emit module symbols, the result is a constant 96 /// of type pointer-to SymtabTy. // FIXME: Describe more completely 97 /// once known. 98 llvm::Constant *EmitModuleSymbols(); 99 100 /// FinishModule - Write out global data structures at the end of 101 /// processing a translation unit. 102 void FinishModule(); 103 104 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, 105 /// for the given selector. 106 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel); 107 108 /// GetClassName - Return a unique constant for the given selector's 109 /// name. 110 llvm::Constant *GetClassName(Selector Sel); 111 112 /// GetMethodVarName - Return a unique constant for the given 113 /// selector's name. 114 llvm::Constant *GetMethodVarName(Selector Sel); 115 116public: 117 CGObjCMac(CodeGen::CodeGenModule &cgm); 118 virtual llvm::Constant *GenerateConstantString(const std::string &String); 119 120 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder, 121 const llvm::Type *ReturnTy, 122 llvm::Value *Receiver, 123 Selector Sel, 124 llvm::Value** ArgV, 125 unsigned ArgC); 126 127 virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, 128 const llvm::Type *ReturnTy, 129 const char *SuperClassName, 130 llvm::Value *Receiver, 131 Selector Sel, 132 llvm::Value** ArgV, 133 unsigned ArgC); 134 135 virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder, 136 llvm::Value *ClassName); 137 138 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel); 139 140 virtual llvm::Function *MethodPreamble(const std::string &ClassName, 141 const std::string &CategoryName, 142 const std::string &MethodName, 143 const llvm::Type *ReturnTy, 144 const llvm::Type *SelfTy, 145 const llvm::Type **ArgTy, 146 unsigned ArgC, 147 bool isClassMethod, 148 bool isVarArg); 149 150 virtual void GenerateCategory(const char *ClassName, const char *CategoryName, 151 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 152 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 153 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 154 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 155 const llvm::SmallVectorImpl<std::string> &Protocols); 156 157 virtual void GenerateClass( 158 const char *ClassName, 159 const char *SuperClassName, 160 const int instanceSize, 161 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 162 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 163 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets, 164 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 165 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 166 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 167 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 168 const llvm::SmallVectorImpl<std::string> &Protocols); 169 170 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder, 171 const ObjCProtocolDecl *PD); 172 173 virtual void GenerateProtocol(const ObjCProtocolDecl *PD); 174 175 virtual llvm::Function *ModuleInitFunction(); 176}; 177} // end anonymous namespace 178 179/* *** Helper Functions *** */ 180 181/// getConstantGEP() - Help routine to construct simple GEPs. 182static llvm::Constant *getConstantGEP(llvm::Constant *C, 183 unsigned idx0, 184 unsigned idx1) { 185 llvm::Value *Idxs[] = { 186 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0), 187 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1) 188 }; 189 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2); 190} 191 192/* *** CGObjCMac Public Interface *** */ 193 194CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) 195 : CGM(cgm), 196 ObjCTypes(cgm), 197 ObjCABI(1) 198{ 199 // FIXME: How does this get set in GCC? And what does it even mean? 200 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy)) 201 ObjCABI = 2; 202 203 EmitImageInfo(); 204} 205 206// This has to perform the lookup every time, since posing and related 207// techniques can modify the name -> class mapping. 208llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder, 209 llvm::Value *ClassName) { 210 assert(0 && "Cannot lookup classes on Mac runtime."); 211 return 0; 212} 213 214/// GetSelector - Return the pointer to the unique'd string for this selector. 215llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) { 216 return EmitSelector(Builder, Sel); 217} 218 219/// Generate a constant CFString object. 220/* 221 struct __builtin_CFString { 222 const int *isa; // point to __CFConstantStringClassReference 223 int flags; 224 const char *str; 225 long length; 226 }; 227*/ 228 229llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) { 230 // FIXME: I have no idea what this constant is (it is a magic 231 // constant in GCC as well). Most likely the encoding of the string 232 // and at least one part of it relates to UTF-16. Is this just the 233 // code for UTF-8? Where is this handled for us? 234 // See: <rdr://2996215> 235 unsigned flags = 0x07c8; 236 237 // FIXME: Use some machinery to unique this. We can't reuse the CGM 238 // one since we put them in a different section. 239 llvm::Constant *StringC = llvm::ConstantArray::get(String); 240 llvm::Constant *StringGV = 241 new llvm::GlobalVariable(StringC->getType(), true, 242 llvm::GlobalValue::InternalLinkage, 243 StringC, ".str", &CGM.getModule()); 244 llvm::Constant *Values[4] = { 245 ObjCTypes.getCFConstantStringClassReference(), 246 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags), 247 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr 248 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size()) 249 }; 250 251 llvm::Constant *CFStringC = 252 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(), 253 std::vector<llvm::Constant*>(Values, Values+4)); 254 255 llvm::GlobalVariable *CFStringGV = 256 new llvm::GlobalVariable(CFStringC->getType(), true, 257 llvm::GlobalValue::InternalLinkage, 258 CFStringC, "", 259 &CGM.getModule()); 260 261 CFStringGV->setSection("__DATA, __cfstring"); 262 263 return CFStringGV; 264} 265 266/// Generates a message send where the super is the receiver. This is 267/// a message send to self with special delivery semantics indicating 268/// which class's method should be called. 269llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder, 270 const llvm::Type *ReturnTy, 271 const char *SuperClassName, 272 llvm::Value *Receiver, 273 Selector Sel, 274 llvm::Value** ArgV, 275 unsigned ArgC) { 276 assert(0 && "Cannot generate message send to super for Mac runtime."); 277 return 0; 278} 279 280/// Generate code for a message send expression. 281llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder, 282 const llvm::Type *ReturnTy, 283 llvm::Value *Receiver, 284 Selector Sel, 285 llvm::Value** ArgV, 286 unsigned ArgC) { 287 llvm::Function *F = ObjCTypes.getMessageSendFn(); 288 llvm::Value **Args = new llvm::Value*[ArgC+2]; 289 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp"); 290 Args[1] = EmitSelector(Builder, Sel); 291 std::copy(ArgV, ArgV+ArgC, Args+2); 292 llvm::CallInst *CI = Builder.CreateCall(F, Args, Args+ArgC+2, "tmp"); 293 delete[] Args; 294 return Builder.CreateBitCast(CI, ReturnTy, "tmp"); 295} 296 297llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder, 298 const ObjCProtocolDecl *PD) { 299 // assert(0 && "Cannot get protocol reference on Mac runtime."); 300 return llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy); 301 return 0; 302} 303 304void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) { 305 // assert(0 && "Cannot generate protocol for Mac runtime."); 306} 307 308void CGObjCMac::GenerateCategory( 309 const char *ClassName, 310 const char *CategoryName, 311 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 312 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 313 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 314 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 315 const llvm::SmallVectorImpl<std::string> &Protocols) { 316 assert(0 && "Cannot generate category for Mac runtime."); 317} 318 319void CGObjCMac::GenerateClass( 320 const char *ClassName, 321 const char *SuperClassName, 322 const int instanceSize, 323 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames, 324 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes, 325 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets, 326 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels, 327 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes, 328 const llvm::SmallVectorImpl<Selector> &ClassMethodSels, 329 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes, 330 const llvm::SmallVectorImpl<std::string> &Protocols) { 331 assert(0 && "Cannot generate class for Mac runtime."); 332} 333 334llvm::Function *CGObjCMac::ModuleInitFunction() { 335 // Abuse this interface function as a place to finalize. 336 FinishModule(); 337 338 return NULL; 339} 340 341llvm::Function *CGObjCMac::MethodPreamble(const std::string &ClassName, 342 const std::string &CategoryName, 343 const std::string &MethodName, 344 const llvm::Type *ReturnTy, 345 const llvm::Type *SelfTy, 346 const llvm::Type **ArgTy, 347 unsigned ArgC, 348 bool isClassMethod, 349 bool isVarArg) { 350 assert(0 && "Cannot generate method preamble for Mac runtime."); 351 return 0; 352} 353 354/* *** Private Interface *** */ 355 356/// EmitImageInfo - Emit the image info marker used to encode some module 357/// level information. 358/// 359/// See: <rdr://4810609&4810587&4810587> 360/// struct IMAGE_INFO { 361/// unsigned version; 362/// unsigned flags; 363/// }; 364enum ImageInfoFlags { 365 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies 366 eImageInfo_GarbageCollected = (1 << 1), 367 eImageInfo_GCOnly = (1 << 2) 368}; 369 370void CGObjCMac::EmitImageInfo() { 371 unsigned version = 0; // Version is unused? 372 unsigned flags = 0; 373 374 // FIXME: Fix and continue? 375 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC) 376 flags |= eImageInfo_GarbageCollected; 377 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) 378 flags |= eImageInfo_GCOnly; 379 380 // Emitted as int[2]; 381 llvm::Constant *values[2] = { 382 llvm::ConstantInt::get(llvm::Type::Int32Ty, version), 383 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags) 384 }; 385 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2); 386 llvm::GlobalVariable *GV = 387 new llvm::GlobalVariable(AT, true, 388 llvm::GlobalValue::InternalLinkage, 389 llvm::ConstantArray::get(AT, values, 2), 390 "\01L_OBJC_IMAGE_INFO", 391 &CGM.getModule()); 392 393 if (ObjCABI == 1) { 394 GV->setSection("__OBJC, __image_info,regular"); 395 } else { 396 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); 397 } 398 399 UsedGlobals.push_back(GV); 400} 401 402 403// struct objc_module { 404// unsigned long version; 405// unsigned long size; 406// const char *name; 407// Symtab symtab; 408// }; 409 410// FIXME: Get from somewhere 411static const int ModuleVersion = 7; 412 413void CGObjCMac::EmitModuleInfo() { 414 IdentifierInfo *EmptyIdent = &CGM.getContext().Idents.get(""); 415 Selector EmptySel = CGM.getContext().Selectors.getNullarySelector(EmptyIdent); 416 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy); 417 418 std::vector<llvm::Constant*> Values(4); 419 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion); 420 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); 421 // FIXME: GCC just appears to make up an empty name for this? Why? 422 Values[2] = getConstantGEP(GetClassName(EmptySel), 0, 0); 423 Values[3] = EmitModuleSymbols(); 424 425 llvm::GlobalVariable *GV = 426 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false, 427 llvm::GlobalValue::InternalLinkage, 428 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, 429 Values), 430 "\01L_OBJC_MODULE_INFO", 431 &CGM.getModule()); 432 GV->setSection("__OBJC,__module_info,regular,no_dead_strip"); 433 UsedGlobals.push_back(GV); 434} 435 436llvm::Constant *CGObjCMac::EmitModuleSymbols() { 437 // FIXME: Is this ever used? 438 llvm::GlobalVariable *GV = 439 new llvm::GlobalVariable(ObjCTypes.SymtabTy, false, 440 llvm::GlobalValue::InternalLinkage, 441 llvm::Constant::getNullValue(ObjCTypes.SymtabTy), 442 "\01L_OBJC_SYMBOLS", 443 &CGM.getModule()); 444 GV->setSection("__OBJC,__symbols,regular,no_dead_strip"); 445 UsedGlobals.push_back(GV); 446 return GV; 447} 448 449llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) { 450 llvm::GlobalVariable *&Entry = SelectorReferences[Sel]; 451 452 if (!Entry) { 453 llvm::Constant *Casted = 454 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel), 455 ObjCTypes.SelectorPtrTy); 456 Entry = 457 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false, 458 llvm::GlobalValue::InternalLinkage, 459 Casted, "\01L_OBJC_SELECTOR_REFERENCES_", 460 &CGM.getModule()); 461 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip"); 462 UsedGlobals.push_back(Entry); 463 } 464 465 return Builder.CreateLoad(Entry, false, "tmp"); 466} 467 468llvm::Constant *CGObjCMac::GetClassName(Selector Sel) { 469 llvm::GlobalVariable *&Entry = ClassNames[Sel]; 470 471 if (!Entry) { 472 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName()); 473 Entry = 474 new llvm::GlobalVariable(C->getType(), true, 475 llvm::GlobalValue::InternalLinkage, 476 C, "\01L_OBJC_CLASS_NAME_", 477 &CGM.getModule()); 478 Entry->setSection("__TEXT,__cstring,cstring_literals"); 479 UsedGlobals.push_back(Entry); 480 } 481 482 return Entry; 483} 484 485llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) { 486 llvm::GlobalVariable *&Entry = MethodVarNames[Sel]; 487 488 if (!Entry) { 489 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName()); 490 Entry = 491 new llvm::GlobalVariable(C->getType(), true, 492 llvm::GlobalValue::InternalLinkage, 493 C, "\01L_OBJC_METH_VAR_NAME_", 494 &CGM.getModule()); 495 Entry->setSection("__TEXT,__cstring,cstring_literals"); 496 UsedGlobals.push_back(Entry); 497 } 498 499 return Entry; 500} 501 502void CGObjCMac::FinishModule() { 503 EmitModuleInfo(); 504 505 std::vector<llvm::Constant*> Used; 506 507 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); 508 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), 509 e = UsedGlobals.end(); i != e; ++i) { 510 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr)); 511 } 512 513 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size()); 514 llvm::GlobalValue *GV = 515 new llvm::GlobalVariable(AT, false, 516 llvm::GlobalValue::AppendingLinkage, 517 llvm::ConstantArray::get(AT, Used), 518 "llvm.used", 519 &CGM.getModule()); 520 521 GV->setSection("llvm.metadata"); 522} 523 524/* *** */ 525 526ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) 527 : CGM(cgm), 528 CFStringType(0), 529 CFConstantStringClassReference(0), 530 MessageSendFn(0) 531{ 532 CodeGen::CodeGenTypes &Types = CGM.getTypes(); 533 ASTContext &Ctx = CGM.getContext(); 534 535 LongTy = Types.ConvertType(Ctx.LongTy); 536 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType()); 537 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType()); 538 ProtocolPtrTy = Types.ConvertType(Ctx.getObjCProtoType()); 539 540 SymtabTy = llvm::StructType::get(LongTy, 541 SelectorPtrTy, 542 Types.ConvertType(Ctx.ShortTy), 543 Types.ConvertType(Ctx.ShortTy), 544 NULL); 545 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy); 546 547 ModuleTy = 548 llvm::StructType::get(LongTy, 549 LongTy, 550 llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 551 llvm::PointerType::getUnqual(SymtabTy), 552 NULL); 553 CGM.getModule().addTypeName("struct._objc_module", ModuleTy); 554} 555 556ObjCTypesHelper::~ObjCTypesHelper() { 557} 558 559const llvm::StructType *ObjCTypesHelper::getCFStringType() { 560 if (!CFStringType) { 561 CFStringType = 562 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty), 563 llvm::Type::Int32Ty, 564 llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 565 LongTy, 566 NULL); 567 568 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType); 569 } 570 571 return CFStringType; 572} 573 574llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() { 575 if (!CFConstantStringClassReference) { 576 llvm::GlobalValue *GV = 577 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0), 578 false, 579 llvm::GlobalValue::ExternalLinkage, 580 0, "__CFConstantStringClassReference", 581 &CGM.getModule()); 582 583 // Decay to pointer. 584 CFConstantStringClassReference = getConstantGEP(GV, 0, 0); 585 } 586 587 return CFConstantStringClassReference; 588} 589 590llvm::Function *ObjCTypesHelper::getMessageSendFn() { 591 if (!MessageSendFn) { 592 std::vector<const llvm::Type*> Params; 593 Params.push_back(ObjectPtrTy); 594 Params.push_back(SelectorPtrTy); 595 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy, 596 Params, 597 true), 598 llvm::Function::ExternalLinkage, 599 "objc_msgSend", 600 &CGM.getModule()); 601 } 602 603 return MessageSendFn; 604} 605 606/* *** */ 607 608CodeGen::CGObjCRuntime *CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM){ 609 return new CGObjCMac(CGM); 610} 611