blob: 85f9860413db939d5230c4a097f2e1c41636f258 [file] [log] [blame]
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001//===------- 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"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000015
16#include "CodeGenModule.h"
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000017#include "clang/AST/ASTContext.h"
Daniel Dunbare91593e2008-08-11 04:54:23 +000018#include "clang/AST/Decl.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000019#include "clang/Basic/LangOptions.h"
20
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000021#include "llvm/Module.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000022#include "llvm/Support/IRBuilder.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000023
24using namespace clang;
25
26namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000027
28/// ObjCTypesHelper - Helper class that encapsulates lazy
29/// construction of varies types used during ObjC generation.
30class ObjCTypesHelper {
31private:
32 CodeGen::CodeGenModule &CGM;
33
34 const llvm::StructType *CFStringType;
35 llvm::Constant *CFConstantStringClassReference;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000036 llvm::Function *MessageSendFn;
37
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000038public:
39 const llvm::Type *LongTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000040
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000041 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
42 const llvm::Type *ObjectPtrTy;
43 /// SelectorTy - LLVM type for selector handles (typeof(SEL))
44 const llvm::Type *SelectorPtrTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000045
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000046public:
47 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
48 ~ObjCTypesHelper();
49
50 llvm::Constant *getCFConstantStringClassReference();
51 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +000052 llvm::Function *getMessageSendFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000053};
54
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000055class CGObjCMac : public CodeGen::CGObjCRuntime {
56private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000057 CodeGen::CodeGenModule &CGM;
58 ObjCTypesHelper ObjCTypes;
59 /// ObjCABI - FIXME: Not sure yet.
60 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000061
Daniel Dunbar259d93d2008-08-12 03:39:23 +000062 /// MethodVarNames - uniqued method variable names.
63 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
64
65 /// SelectorReferences - uniqued selector references.
66 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
67
Daniel Dunbarf77ac862008-08-11 21:35:06 +000068 /// UsedGlobals - list of globals to pack into the llvm.used metadata
69 /// to prevent them from being clobbered.
70 std::vector<llvm::GlobalValue*> UsedGlobals;
71
72 /// EmitImageInfo - Emit the image info marker used to encode some module
73 /// level information.
74 void EmitImageInfo();
75
76 /// FinishModule - Write out global data structures at the end of
77 /// processing a translation unit.
78 void FinishModule();
Daniel Dunbar259d93d2008-08-12 03:39:23 +000079
80 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
81 /// for the given selector.
82 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
83
84 /// GetMethodVarName - Return a unique constant for the given
85 /// selector's name.
86 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarf77ac862008-08-11 21:35:06 +000087
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000088public:
89 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000090 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000091
92 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
93 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000094 llvm::Value *Receiver,
95 Selector Sel,
96 llvm::Value** ArgV,
97 unsigned ArgC);
98
99 virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
100 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000101 const char *SuperClassName,
102 llvm::Value *Receiver,
103 Selector Sel,
104 llvm::Value** ArgV,
105 unsigned ArgC);
106
107 virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder,
108 llvm::Value *ClassName);
109
110 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
111
112 virtual llvm::Function *MethodPreamble(const std::string &ClassName,
113 const std::string &CategoryName,
114 const std::string &MethodName,
115 const llvm::Type *ReturnTy,
116 const llvm::Type *SelfTy,
117 const llvm::Type **ArgTy,
118 unsigned ArgC,
119 bool isClassMethod,
120 bool isVarArg);
121
122 virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
123 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
124 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
125 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
126 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
127 const llvm::SmallVectorImpl<std::string> &Protocols);
128
129 virtual void GenerateClass(
130 const char *ClassName,
131 const char *SuperClassName,
132 const int instanceSize,
133 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
134 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
135 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
136 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
137 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
138 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
139 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
140 const llvm::SmallVectorImpl<std::string> &Protocols);
141
142 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
143 const char *ProtocolName);
144
145 virtual void GenerateProtocol(const char *ProtocolName,
146 const llvm::SmallVectorImpl<std::string> &Protocols,
147 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
148 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
149 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
150 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes);
151
152 virtual llvm::Function *ModuleInitFunction();
153};
154} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000155
156/* *** Helper Functions *** */
157
158/// getConstantGEP() - Help routine to construct simple GEPs.
159static llvm::Constant *getConstantGEP(llvm::Constant *C,
160 unsigned idx0,
161 unsigned idx1) {
162 llvm::Value *Idxs[] = {
163 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
164 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
165 };
166 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
167}
168
169/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000170
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000171CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
172 : CGM(cgm),
173 ObjCTypes(cgm),
174 ObjCABI(1)
175{
176 // FIXME: How does this get set in GCC? And what does it even mean?
177 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
178 ObjCABI = 2;
179
180 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000181}
182
183// This has to perform the lookup every time, since posing and related
184// techniques can modify the name -> class mapping.
185llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
186 llvm::Value *ClassName) {
187 assert(0 && "Cannot lookup classes on Mac runtime.");
188 return 0;
189}
190
191/// GetSelector - Return the pointer to the unique'd string for this selector.
192llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000193 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000194}
195
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000196/// Generate a constant CFString object.
197/*
198 struct __builtin_CFString {
199 const int *isa; // point to __CFConstantStringClassReference
200 int flags;
201 const char *str;
202 long length;
203 };
204*/
205
206llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
207 // FIXME: I have no idea what this constant is (it is a magic
208 // constant in GCC as well). Most likely the encoding of the string
209 // and at least one part of it relates to UTF-16. Is this just the
210 // code for UTF-8? Where is this handled for us?
211 // See: <rdr://2996215>
212 unsigned flags = 0x07c8;
213
214 // FIXME: Use some machinery to unique this. We can't reuse the CGM
215 // one since we put them in a different section.
216 llvm::Constant *StringC = llvm::ConstantArray::get(String);
217 llvm::Constant *StringGV =
218 new llvm::GlobalVariable(StringC->getType(), true,
219 llvm::GlobalValue::InternalLinkage,
220 StringC, ".str", &CGM.getModule());
221 llvm::Constant *Values[4] = {
222 ObjCTypes.getCFConstantStringClassReference(),
223 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
224 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
225 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
226 };
227
228 llvm::Constant *CFStringC =
229 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
230 std::vector<llvm::Constant*>(Values, Values+4));
231
232 llvm::GlobalVariable *CFStringGV =
233 new llvm::GlobalVariable(CFStringC->getType(), true,
234 llvm::GlobalValue::InternalLinkage,
235 CFStringC, "",
236 &CGM.getModule());
237
238 CFStringGV->setSection("__DATA, __cfstring");
239
240 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000241}
242
243/// Generates a message send where the super is the receiver. This is
244/// a message send to self with special delivery semantics indicating
245/// which class's method should be called.
246llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
247 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000248 const char *SuperClassName,
249 llvm::Value *Receiver,
250 Selector Sel,
251 llvm::Value** ArgV,
252 unsigned ArgC) {
253 assert(0 && "Cannot generate message send to super for Mac runtime.");
254 return 0;
255}
256
257/// Generate code for a message send expression.
258llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
259 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000260 llvm::Value *Receiver,
261 Selector Sel,
262 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000263 unsigned ArgC) {
264 llvm::Function *F = ObjCTypes.getMessageSendFn();
265 llvm::Value **Args = new llvm::Value*[ArgC+2];
266 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
267 Args[1] = EmitSelector(Builder, Sel);
268 std::copy(ArgV, ArgV+ArgC, Args+2);
269 llvm::CallInst *CI = Builder.CreateCall(F, Args, Args+ArgC+2, "tmp");
270 delete[] Args;
271 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000272}
273
274llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
275 const char *ProtocolName) {
276 assert(0 && "Cannot get protocol reference on Mac runtime.");
277 return 0;
278}
279
280void CGObjCMac::GenerateProtocol(const char *ProtocolName,
281 const llvm::SmallVectorImpl<std::string> &Protocols,
282 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
283 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
284 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
285 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes) {
286 assert(0 && "Cannot generate protocol for Mac runtime.");
287}
288
289void CGObjCMac::GenerateCategory(
290 const char *ClassName,
291 const char *CategoryName,
292 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
293 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
294 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
295 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
296 const llvm::SmallVectorImpl<std::string> &Protocols) {
297 assert(0 && "Cannot generate category for Mac runtime.");
298}
299
300void CGObjCMac::GenerateClass(
301 const char *ClassName,
302 const char *SuperClassName,
303 const int instanceSize,
304 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
305 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
306 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
307 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
308 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
309 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
310 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
311 const llvm::SmallVectorImpl<std::string> &Protocols) {
312 assert(0 && "Cannot generate class for Mac runtime.");
313}
314
315llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000316 // Abuse this interface function as a place to finalize.
317 FinishModule();
318
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000319 return NULL;
320}
321
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000322llvm::Function *CGObjCMac::MethodPreamble(const std::string &ClassName,
323 const std::string &CategoryName,
324 const std::string &MethodName,
325 const llvm::Type *ReturnTy,
326 const llvm::Type *SelfTy,
327 const llvm::Type **ArgTy,
328 unsigned ArgC,
329 bool isClassMethod,
330 bool isVarArg) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000331 assert(0 && "Cannot generate method preamble for Mac runtime.");
332 return 0;
333}
334
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000335/* *** Private Interface *** */
336
337/// EmitImageInfo - Emit the image info marker used to encode some module
338/// level information.
339///
340/// See: <rdr://4810609&4810587&4810587>
341/// struct IMAGE_INFO {
342/// unsigned version;
343/// unsigned flags;
344/// };
345enum ImageInfoFlags {
346 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
347 eImageInfo_GarbageCollected = (1 << 1),
348 eImageInfo_GCOnly = (1 << 2)
349};
350
351void CGObjCMac::EmitImageInfo() {
352 unsigned version = 0; // Version is unused?
353 unsigned flags = 0;
354
355 // FIXME: Fix and continue?
356 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
357 flags |= eImageInfo_GarbageCollected;
358 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
359 flags |= eImageInfo_GCOnly;
360
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000361 // Emitted as int[2];
362 llvm::Constant *values[2] = {
363 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
364 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
365 };
366 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
367 llvm::GlobalValue *GV =
368 new llvm::GlobalVariable(AT, true,
369 llvm::GlobalValue::InternalLinkage,
370 llvm::ConstantArray::get(AT, values, 2),
371 "\01L_OBJC_IMAGE_INFO",
372 &CGM.getModule());
373
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000374 if (ObjCABI == 1) {
375 GV->setSection("__OBJC, __image_info,regular");
376 } else {
377 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
378 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000379
380 UsedGlobals.push_back(GV);
381}
382
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000383llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
384 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
385
386 if (!Entry) {
387 llvm::Constant *Casted =
388 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
389 ObjCTypes.SelectorPtrTy);
390 Entry =
391 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
392 llvm::GlobalValue::InternalLinkage,
393 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
394 &CGM.getModule());
395 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
396 UsedGlobals.push_back(Entry);
397 }
398
399 return Builder.CreateLoad(Entry, false, "tmp");
400}
401
402llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
403 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
404
405 if (!Entry) {
406 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
407 Entry =
408 new llvm::GlobalVariable(C->getType(), true,
409 llvm::GlobalValue::InternalLinkage,
410 C, "\01L_OBJC_METH_VAR_NAME_",
411 &CGM.getModule());
412 Entry->setSection("__TEXT,__cstring,cstring_literals");
413 UsedGlobals.push_back(Entry);
414 }
415
416 return Entry;
417}
418
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000419void CGObjCMac::FinishModule() {
420 std::vector<llvm::Constant*> Used;
421
422 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
423 for (std::vector<llvm::GlobalValue*>::iterator i = UsedGlobals.begin(),
424 e = UsedGlobals.end(); i != e; ++i) {
425 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
426 }
427
428 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
429 llvm::GlobalValue *GV =
430 new llvm::GlobalVariable(AT, false,
431 llvm::GlobalValue::AppendingLinkage,
432 llvm::ConstantArray::get(AT, Used),
433 "llvm.used",
434 &CGM.getModule());
435
436 GV->setSection("llvm.metadata");
437}
438
439/* *** */
440
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000441ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
442 : CGM(cgm),
443 CFStringType(0),
444 CFConstantStringClassReference(0),
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000445 MessageSendFn(0),
446 LongTy(CGM.getTypes().ConvertType(CGM.getContext().LongTy)),
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000447 ObjectPtrTy(CGM.getTypes().ConvertType(CGM.getContext().getObjCIdType())),
448 SelectorPtrTy(CGM.getTypes().ConvertType(CGM.getContext().getObjCSelType()))
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000449{
450}
451
452ObjCTypesHelper::~ObjCTypesHelper() {
453}
454
455const llvm::StructType *ObjCTypesHelper::getCFStringType() {
456 if (!CFStringType) {
457 CFStringType =
458 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
459 llvm::Type::Int32Ty,
460 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
461 LongTy,
462 NULL);
463
464 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
465 }
466
467 return CFStringType;
468}
469
470llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
471 if (!CFConstantStringClassReference) {
472 llvm::GlobalValue *GV =
473 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
474 false,
475 llvm::GlobalValue::ExternalLinkage,
476 0, "__CFConstantStringClassReference",
477 &CGM.getModule());
478
479 // Decay to pointer.
480 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
481 }
482
483 return CFConstantStringClassReference;
484}
485
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000486llvm::Function *ObjCTypesHelper::getMessageSendFn() {
487 if (!MessageSendFn) {
488 std::vector<const llvm::Type*> Params;
489 Params.push_back(ObjectPtrTy);
490 Params.push_back(SelectorPtrTy);
491 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
492 Params,
493 true),
494 llvm::Function::ExternalLinkage,
495 "objc_msgSend",
496 &CGM.getModule());
497 }
498
499 return MessageSendFn;
500}
501
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000502/* *** */
503
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000504CodeGen::CGObjCRuntime *CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM){
505 return new CGObjCMac(CGM);
506}