blob: f7fe2570c09ed6d9e21343e652f4b97ab760db9e [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
41 /// ObjectTy - Opaque type for Objective-C objects
42 const llvm::Type *ObjectTy, *ObjectPtrTy;
43 /// SelectorTy - Opaque type for Objective-C selectors
44 const llvm::Type *SelectorTy, *SelectorPtrTy;
45
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,
94 llvm::Value *Sender,
95 llvm::Value *Receiver,
96 Selector Sel,
97 llvm::Value** ArgV,
98 unsigned ArgC);
99
100 virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
101 const llvm::Type *ReturnTy,
102 llvm::Value *Sender,
103 const char *SuperClassName,
104 llvm::Value *Receiver,
105 Selector Sel,
106 llvm::Value** ArgV,
107 unsigned ArgC);
108
109 virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder,
110 llvm::Value *ClassName);
111
112 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
113
114 virtual llvm::Function *MethodPreamble(const std::string &ClassName,
115 const std::string &CategoryName,
116 const std::string &MethodName,
117 const llvm::Type *ReturnTy,
118 const llvm::Type *SelfTy,
119 const llvm::Type **ArgTy,
120 unsigned ArgC,
121 bool isClassMethod,
122 bool isVarArg);
123
124 virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
125 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
126 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
127 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
128 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
129 const llvm::SmallVectorImpl<std::string> &Protocols);
130
131 virtual void GenerateClass(
132 const char *ClassName,
133 const char *SuperClassName,
134 const int instanceSize,
135 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
136 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
137 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
138 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
139 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
140 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
141 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
142 const llvm::SmallVectorImpl<std::string> &Protocols);
143
144 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
145 const char *ProtocolName);
146
147 virtual void GenerateProtocol(const char *ProtocolName,
148 const llvm::SmallVectorImpl<std::string> &Protocols,
149 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
150 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
151 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
152 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes);
153
154 virtual llvm::Function *ModuleInitFunction();
155};
156} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000157
158/* *** Helper Functions *** */
159
160/// getConstantGEP() - Help routine to construct simple GEPs.
161static llvm::Constant *getConstantGEP(llvm::Constant *C,
162 unsigned idx0,
163 unsigned idx1) {
164 llvm::Value *Idxs[] = {
165 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
166 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
167 };
168 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
169}
170
171/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000172
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000173CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
174 : CGM(cgm),
175 ObjCTypes(cgm),
176 ObjCABI(1)
177{
178 // FIXME: How does this get set in GCC? And what does it even mean?
179 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
180 ObjCABI = 2;
181
182 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000183}
184
185// This has to perform the lookup every time, since posing and related
186// techniques can modify the name -> class mapping.
187llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
188 llvm::Value *ClassName) {
189 assert(0 && "Cannot lookup classes on Mac runtime.");
190 return 0;
191}
192
193/// GetSelector - Return the pointer to the unique'd string for this selector.
194llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000195 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000196}
197
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000198/// Generate a constant CFString object.
199/*
200 struct __builtin_CFString {
201 const int *isa; // point to __CFConstantStringClassReference
202 int flags;
203 const char *str;
204 long length;
205 };
206*/
207
208llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
209 // FIXME: I have no idea what this constant is (it is a magic
210 // constant in GCC as well). Most likely the encoding of the string
211 // and at least one part of it relates to UTF-16. Is this just the
212 // code for UTF-8? Where is this handled for us?
213 // See: <rdr://2996215>
214 unsigned flags = 0x07c8;
215
216 // FIXME: Use some machinery to unique this. We can't reuse the CGM
217 // one since we put them in a different section.
218 llvm::Constant *StringC = llvm::ConstantArray::get(String);
219 llvm::Constant *StringGV =
220 new llvm::GlobalVariable(StringC->getType(), true,
221 llvm::GlobalValue::InternalLinkage,
222 StringC, ".str", &CGM.getModule());
223 llvm::Constant *Values[4] = {
224 ObjCTypes.getCFConstantStringClassReference(),
225 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
226 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
227 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
228 };
229
230 llvm::Constant *CFStringC =
231 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
232 std::vector<llvm::Constant*>(Values, Values+4));
233
234 llvm::GlobalVariable *CFStringGV =
235 new llvm::GlobalVariable(CFStringC->getType(), true,
236 llvm::GlobalValue::InternalLinkage,
237 CFStringC, "",
238 &CGM.getModule());
239
240 CFStringGV->setSection("__DATA, __cfstring");
241
242 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000243}
244
245/// Generates a message send where the super is the receiver. This is
246/// a message send to self with special delivery semantics indicating
247/// which class's method should be called.
248llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
249 const llvm::Type *ReturnTy,
250 llvm::Value *Sender,
251 const char *SuperClassName,
252 llvm::Value *Receiver,
253 Selector Sel,
254 llvm::Value** ArgV,
255 unsigned ArgC) {
256 assert(0 && "Cannot generate message send to super for Mac runtime.");
257 return 0;
258}
259
260/// Generate code for a message send expression.
261llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
262 const llvm::Type *ReturnTy,
263 llvm::Value *Sender,
264 llvm::Value *Receiver,
265 Selector Sel,
266 llvm::Value** ArgV,
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000267 unsigned ArgC) {
268 if (!Sender) {
269 llvm::Function *F = ObjCTypes.getMessageSendFn();
270 llvm::Value **Args = new llvm::Value*[ArgC+2];
271 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
272 Args[1] = EmitSelector(Builder, Sel);
273 std::copy(ArgV, ArgV+ArgC, Args+2);
274 llvm::CallInst *CI = Builder.CreateCall(F, Args, Args+ArgC+2, "tmp");
275 delete[] Args;
276 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
277 } else {
278 assert(0 && "cannot generate message sends with sender");
279 return 0;
280 }
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000281}
282
283llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
284 const char *ProtocolName) {
285 assert(0 && "Cannot get protocol reference on Mac runtime.");
286 return 0;
287}
288
289void CGObjCMac::GenerateProtocol(const char *ProtocolName,
290 const llvm::SmallVectorImpl<std::string> &Protocols,
291 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
292 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
293 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
294 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes) {
295 assert(0 && "Cannot generate protocol for Mac runtime.");
296}
297
298void CGObjCMac::GenerateCategory(
299 const char *ClassName,
300 const char *CategoryName,
301 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
302 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
303 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
304 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
305 const llvm::SmallVectorImpl<std::string> &Protocols) {
306 assert(0 && "Cannot generate category for Mac runtime.");
307}
308
309void CGObjCMac::GenerateClass(
310 const char *ClassName,
311 const char *SuperClassName,
312 const int instanceSize,
313 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
314 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
315 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
316 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
317 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
318 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
319 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
320 const llvm::SmallVectorImpl<std::string> &Protocols) {
321 assert(0 && "Cannot generate class for Mac runtime.");
322}
323
324llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000325 // Abuse this interface function as a place to finalize.
326 FinishModule();
327
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000328 return NULL;
329}
330
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000331llvm::Function *CGObjCMac::MethodPreamble(const std::string &ClassName,
332 const std::string &CategoryName,
333 const std::string &MethodName,
334 const llvm::Type *ReturnTy,
335 const llvm::Type *SelfTy,
336 const llvm::Type **ArgTy,
337 unsigned ArgC,
338 bool isClassMethod,
339 bool isVarArg) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000340 assert(0 && "Cannot generate method preamble for Mac runtime.");
341 return 0;
342}
343
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000344/* *** Private Interface *** */
345
346/// EmitImageInfo - Emit the image info marker used to encode some module
347/// level information.
348///
349/// See: <rdr://4810609&4810587&4810587>
350/// struct IMAGE_INFO {
351/// unsigned version;
352/// unsigned flags;
353/// };
354enum ImageInfoFlags {
355 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
356 eImageInfo_GarbageCollected = (1 << 1),
357 eImageInfo_GCOnly = (1 << 2)
358};
359
360void CGObjCMac::EmitImageInfo() {
361 unsigned version = 0; // Version is unused?
362 unsigned flags = 0;
363
364 // FIXME: Fix and continue?
365 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
366 flags |= eImageInfo_GarbageCollected;
367 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
368 flags |= eImageInfo_GCOnly;
369
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000370 // Emitted as int[2];
371 llvm::Constant *values[2] = {
372 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
373 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
374 };
375 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
376 llvm::GlobalValue *GV =
377 new llvm::GlobalVariable(AT, true,
378 llvm::GlobalValue::InternalLinkage,
379 llvm::ConstantArray::get(AT, values, 2),
380 "\01L_OBJC_IMAGE_INFO",
381 &CGM.getModule());
382
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000383 if (ObjCABI == 1) {
384 GV->setSection("__OBJC, __image_info,regular");
385 } else {
386 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
387 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000388
389 UsedGlobals.push_back(GV);
390}
391
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000392llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
393 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
394
395 if (!Entry) {
396 llvm::Constant *Casted =
397 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
398 ObjCTypes.SelectorPtrTy);
399 Entry =
400 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
401 llvm::GlobalValue::InternalLinkage,
402 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
403 &CGM.getModule());
404 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
405 UsedGlobals.push_back(Entry);
406 }
407
408 return Builder.CreateLoad(Entry, false, "tmp");
409}
410
411llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
412 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
413
414 if (!Entry) {
415 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
416 Entry =
417 new llvm::GlobalVariable(C->getType(), true,
418 llvm::GlobalValue::InternalLinkage,
419 C, "\01L_OBJC_METH_VAR_NAME_",
420 &CGM.getModule());
421 Entry->setSection("__TEXT,__cstring,cstring_literals");
422 UsedGlobals.push_back(Entry);
423 }
424
425 return Entry;
426}
427
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000428void CGObjCMac::FinishModule() {
429 std::vector<llvm::Constant*> Used;
430
431 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
432 for (std::vector<llvm::GlobalValue*>::iterator i = UsedGlobals.begin(),
433 e = UsedGlobals.end(); i != e; ++i) {
434 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
435 }
436
437 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
438 llvm::GlobalValue *GV =
439 new llvm::GlobalVariable(AT, false,
440 llvm::GlobalValue::AppendingLinkage,
441 llvm::ConstantArray::get(AT, Used),
442 "llvm.used",
443 &CGM.getModule());
444
445 GV->setSection("llvm.metadata");
446}
447
448/* *** */
449
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000450ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
451 : CGM(cgm),
452 CFStringType(0),
453 CFConstantStringClassReference(0),
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000454 MessageSendFn(0),
455 LongTy(CGM.getTypes().ConvertType(CGM.getContext().LongTy)),
456 // FIXME: We want the types from the front-end.
457 ObjectTy(llvm::OpaqueType::get()),
458 ObjectPtrTy(llvm::PointerType::getUnqual(ObjectTy)),
459 SelectorTy(llvm::OpaqueType::get()),
460 SelectorPtrTy(llvm::PointerType::getUnqual(SelectorTy))
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000461{
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000462 CGM.getModule().addTypeName("struct.__objc_object", ObjectTy);
463 CGM.getModule().addTypeName("struct.__objc_selector", SelectorTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000464}
465
466ObjCTypesHelper::~ObjCTypesHelper() {
467}
468
469const llvm::StructType *ObjCTypesHelper::getCFStringType() {
470 if (!CFStringType) {
471 CFStringType =
472 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
473 llvm::Type::Int32Ty,
474 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
475 LongTy,
476 NULL);
477
478 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
479 }
480
481 return CFStringType;
482}
483
484llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
485 if (!CFConstantStringClassReference) {
486 llvm::GlobalValue *GV =
487 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
488 false,
489 llvm::GlobalValue::ExternalLinkage,
490 0, "__CFConstantStringClassReference",
491 &CGM.getModule());
492
493 // Decay to pointer.
494 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
495 }
496
497 return CFConstantStringClassReference;
498}
499
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000500llvm::Function *ObjCTypesHelper::getMessageSendFn() {
501 if (!MessageSendFn) {
502 std::vector<const llvm::Type*> Params;
503 Params.push_back(ObjectPtrTy);
504 Params.push_back(SelectorPtrTy);
505 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
506 Params,
507 true),
508 llvm::Function::ExternalLinkage,
509 "objc_msgSend",
510 &CGM.getModule());
511 }
512
513 return MessageSendFn;
514}
515
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000516/* *** */
517
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000518CodeGen::CGObjCRuntime *CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM){
519 return new CGObjCMac(CGM);
520}