blob: bd510899032120170178a7f59c3b032526706bbe [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 Dunbar4e2d7d02008-08-12 06:48:42 +000023#include "llvm/Target/TargetData.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000024
25using namespace clang;
26
27namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000028
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;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000037 llvm::Function *MessageSendFn;
38
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000039public:
40 const llvm::Type *LongTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000041
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000042 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
43 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000044 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000045 const llvm::Type *SelectorPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000046 /// 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;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000053
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000054public:
55 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
56 ~ObjCTypesHelper();
57
58 llvm::Constant *getCFConstantStringClassReference();
59 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +000060 llvm::Function *getMessageSendFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000061};
62
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000063class CGObjCMac : public CodeGen::CGObjCRuntime {
64private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000065 CodeGen::CodeGenModule &CGM;
66 ObjCTypesHelper ObjCTypes;
67 /// ObjCABI - FIXME: Not sure yet.
68 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000069
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000070 /// ClassNames - uniqued class names.
71 llvm::DenseMap<Selector, llvm::GlobalVariable*> ClassNames;
72
Daniel Dunbar259d93d2008-08-12 03:39:23 +000073 /// 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
Daniel Dunbarf77ac862008-08-11 21:35:06 +000079 /// UsedGlobals - list of globals to pack into the llvm.used metadata
80 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000081 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +000082
83 /// EmitImageInfo - Emit the image info marker used to encode some module
84 /// level information.
85 void EmitImageInfo();
86
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000087 /// 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
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000100 /// FinishModule - Write out global data structures at the end of
101 /// processing a translation unit.
102 void FinishModule();
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000103
104 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
105 /// for the given selector.
106 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
107
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000108 /// GetClassName - Return a unique constant for the given selector's
109 /// name.
110 llvm::Constant *GetClassName(Selector Sel);
111
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000112 /// GetMethodVarName - Return a unique constant for the given
113 /// selector's name.
114 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000115
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000116public:
117 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000118 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000119
120 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
121 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000122 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,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000129 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 char *ProtocolName);
172
173 virtual void GenerateProtocol(const char *ProtocolName,
174 const llvm::SmallVectorImpl<std::string> &Protocols,
175 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
176 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
177 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
178 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes);
179
180 virtual llvm::Function *ModuleInitFunction();
181};
182} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000183
184/* *** Helper Functions *** */
185
186/// getConstantGEP() - Help routine to construct simple GEPs.
187static llvm::Constant *getConstantGEP(llvm::Constant *C,
188 unsigned idx0,
189 unsigned idx1) {
190 llvm::Value *Idxs[] = {
191 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
192 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
193 };
194 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
195}
196
197/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000198
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000199CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
200 : CGM(cgm),
201 ObjCTypes(cgm),
202 ObjCABI(1)
203{
204 // FIXME: How does this get set in GCC? And what does it even mean?
205 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
206 ObjCABI = 2;
207
208 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000209}
210
211// This has to perform the lookup every time, since posing and related
212// techniques can modify the name -> class mapping.
213llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
214 llvm::Value *ClassName) {
215 assert(0 && "Cannot lookup classes on Mac runtime.");
216 return 0;
217}
218
219/// GetSelector - Return the pointer to the unique'd string for this selector.
220llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000221 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000222}
223
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000224/// Generate a constant CFString object.
225/*
226 struct __builtin_CFString {
227 const int *isa; // point to __CFConstantStringClassReference
228 int flags;
229 const char *str;
230 long length;
231 };
232*/
233
234llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
235 // FIXME: I have no idea what this constant is (it is a magic
236 // constant in GCC as well). Most likely the encoding of the string
237 // and at least one part of it relates to UTF-16. Is this just the
238 // code for UTF-8? Where is this handled for us?
239 // See: <rdr://2996215>
240 unsigned flags = 0x07c8;
241
242 // FIXME: Use some machinery to unique this. We can't reuse the CGM
243 // one since we put them in a different section.
244 llvm::Constant *StringC = llvm::ConstantArray::get(String);
245 llvm::Constant *StringGV =
246 new llvm::GlobalVariable(StringC->getType(), true,
247 llvm::GlobalValue::InternalLinkage,
248 StringC, ".str", &CGM.getModule());
249 llvm::Constant *Values[4] = {
250 ObjCTypes.getCFConstantStringClassReference(),
251 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
252 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
253 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
254 };
255
256 llvm::Constant *CFStringC =
257 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
258 std::vector<llvm::Constant*>(Values, Values+4));
259
260 llvm::GlobalVariable *CFStringGV =
261 new llvm::GlobalVariable(CFStringC->getType(), true,
262 llvm::GlobalValue::InternalLinkage,
263 CFStringC, "",
264 &CGM.getModule());
265
266 CFStringGV->setSection("__DATA, __cfstring");
267
268 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000269}
270
271/// Generates a message send where the super is the receiver. This is
272/// a message send to self with special delivery semantics indicating
273/// which class's method should be called.
274llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
275 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000276 const char *SuperClassName,
277 llvm::Value *Receiver,
278 Selector Sel,
279 llvm::Value** ArgV,
280 unsigned ArgC) {
281 assert(0 && "Cannot generate message send to super for Mac runtime.");
282 return 0;
283}
284
285/// Generate code for a message send expression.
286llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
287 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000288 llvm::Value *Receiver,
289 Selector Sel,
290 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000291 unsigned ArgC) {
292 llvm::Function *F = ObjCTypes.getMessageSendFn();
293 llvm::Value **Args = new llvm::Value*[ArgC+2];
294 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
295 Args[1] = EmitSelector(Builder, Sel);
296 std::copy(ArgV, ArgV+ArgC, Args+2);
297 llvm::CallInst *CI = Builder.CreateCall(F, Args, Args+ArgC+2, "tmp");
298 delete[] Args;
299 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000300}
301
302llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
303 const char *ProtocolName) {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000304 // assert(0 && "Cannot get protocol reference on Mac runtime.");
305 return llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000306 return 0;
307}
308
309void CGObjCMac::GenerateProtocol(const char *ProtocolName,
310 const llvm::SmallVectorImpl<std::string> &Protocols,
311 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
312 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
313 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
314 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes) {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000315 // assert(0 && "Cannot generate protocol for Mac runtime.");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000316}
317
318void CGObjCMac::GenerateCategory(
319 const char *ClassName,
320 const char *CategoryName,
321 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
322 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
323 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
324 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
325 const llvm::SmallVectorImpl<std::string> &Protocols) {
326 assert(0 && "Cannot generate category for Mac runtime.");
327}
328
329void CGObjCMac::GenerateClass(
330 const char *ClassName,
331 const char *SuperClassName,
332 const int instanceSize,
333 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
334 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
335 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
336 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
337 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
338 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
339 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
340 const llvm::SmallVectorImpl<std::string> &Protocols) {
341 assert(0 && "Cannot generate class for Mac runtime.");
342}
343
344llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000345 // Abuse this interface function as a place to finalize.
346 FinishModule();
347
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000348 return NULL;
349}
350
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000351llvm::Function *CGObjCMac::MethodPreamble(const std::string &ClassName,
352 const std::string &CategoryName,
353 const std::string &MethodName,
354 const llvm::Type *ReturnTy,
355 const llvm::Type *SelfTy,
356 const llvm::Type **ArgTy,
357 unsigned ArgC,
358 bool isClassMethod,
359 bool isVarArg) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000360 assert(0 && "Cannot generate method preamble for Mac runtime.");
361 return 0;
362}
363
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000364/* *** Private Interface *** */
365
366/// EmitImageInfo - Emit the image info marker used to encode some module
367/// level information.
368///
369/// See: <rdr://4810609&4810587&4810587>
370/// struct IMAGE_INFO {
371/// unsigned version;
372/// unsigned flags;
373/// };
374enum ImageInfoFlags {
375 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
376 eImageInfo_GarbageCollected = (1 << 1),
377 eImageInfo_GCOnly = (1 << 2)
378};
379
380void CGObjCMac::EmitImageInfo() {
381 unsigned version = 0; // Version is unused?
382 unsigned flags = 0;
383
384 // FIXME: Fix and continue?
385 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
386 flags |= eImageInfo_GarbageCollected;
387 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
388 flags |= eImageInfo_GCOnly;
389
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000390 // Emitted as int[2];
391 llvm::Constant *values[2] = {
392 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
393 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
394 };
395 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000396 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000397 new llvm::GlobalVariable(AT, true,
398 llvm::GlobalValue::InternalLinkage,
399 llvm::ConstantArray::get(AT, values, 2),
400 "\01L_OBJC_IMAGE_INFO",
401 &CGM.getModule());
402
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000403 if (ObjCABI == 1) {
404 GV->setSection("__OBJC, __image_info,regular");
405 } else {
406 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
407 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000408
409 UsedGlobals.push_back(GV);
410}
411
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000412
413// struct objc_module {
414// unsigned long version;
415// unsigned long size;
416// const char *name;
417// Symtab symtab;
418// };
419
420// FIXME: Get from somewhere
421static const int ModuleVersion = 7;
422
423void CGObjCMac::EmitModuleInfo() {
424 IdentifierInfo *EmptyIdent = &CGM.getContext().Idents.get("");
425 Selector EmptySel = CGM.getContext().Selectors.getNullarySelector(EmptyIdent);
426 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
427
428 std::vector<llvm::Constant*> Values(4);
429 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
430 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
431 // FIXME: GCC just appears to make up an empty name for this? Why?
432 Values[2] = getConstantGEP(GetClassName(EmptySel), 0, 0);
433 Values[3] = EmitModuleSymbols();
434
435 llvm::GlobalVariable *GV =
436 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
437 llvm::GlobalValue::InternalLinkage,
438 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
439 Values),
440 "\01L_OBJC_MODULE_INFO",
441 &CGM.getModule());
442 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
443 UsedGlobals.push_back(GV);
444}
445
446llvm::Constant *CGObjCMac::EmitModuleSymbols() {
447 // FIXME: Is this ever used?
448 llvm::GlobalVariable *GV =
449 new llvm::GlobalVariable(ObjCTypes.SymtabTy, false,
450 llvm::GlobalValue::InternalLinkage,
451 llvm::Constant::getNullValue(ObjCTypes.SymtabTy),
452 "\01L_OBJC_SYMBOLS",
453 &CGM.getModule());
454 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
455 UsedGlobals.push_back(GV);
456 return GV;
457}
458
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000459llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
460 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
461
462 if (!Entry) {
463 llvm::Constant *Casted =
464 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
465 ObjCTypes.SelectorPtrTy);
466 Entry =
467 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
468 llvm::GlobalValue::InternalLinkage,
469 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
470 &CGM.getModule());
471 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
472 UsedGlobals.push_back(Entry);
473 }
474
475 return Builder.CreateLoad(Entry, false, "tmp");
476}
477
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000478llvm::Constant *CGObjCMac::GetClassName(Selector Sel) {
479 llvm::GlobalVariable *&Entry = ClassNames[Sel];
480
481 if (!Entry) {
482 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
483 Entry =
484 new llvm::GlobalVariable(C->getType(), true,
485 llvm::GlobalValue::InternalLinkage,
486 C, "\01L_OBJC_CLASS_NAME_",
487 &CGM.getModule());
488 Entry->setSection("__TEXT,__cstring,cstring_literals");
489 UsedGlobals.push_back(Entry);
490 }
491
492 return Entry;
493}
494
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000495llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
496 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
497
498 if (!Entry) {
499 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
500 Entry =
501 new llvm::GlobalVariable(C->getType(), true,
502 llvm::GlobalValue::InternalLinkage,
503 C, "\01L_OBJC_METH_VAR_NAME_",
504 &CGM.getModule());
505 Entry->setSection("__TEXT,__cstring,cstring_literals");
506 UsedGlobals.push_back(Entry);
507 }
508
509 return Entry;
510}
511
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000512void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000513 EmitModuleInfo();
514
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000515 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000516
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000517 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000518 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000519 e = UsedGlobals.end(); i != e; ++i) {
520 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
521 }
522
523 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
524 llvm::GlobalValue *GV =
525 new llvm::GlobalVariable(AT, false,
526 llvm::GlobalValue::AppendingLinkage,
527 llvm::ConstantArray::get(AT, Used),
528 "llvm.used",
529 &CGM.getModule());
530
531 GV->setSection("llvm.metadata");
532}
533
534/* *** */
535
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000536ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
537 : CGM(cgm),
538 CFStringType(0),
539 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000540 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000541{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000542 CodeGen::CodeGenTypes &Types = CGM.getTypes();
543 ASTContext &Ctx = CGM.getContext();
544
545 LongTy = Types.ConvertType(Ctx.LongTy);
546 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
547 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
548 ProtocolPtrTy = Types.ConvertType(Ctx.getObjCProtoType());
549
550 SymtabTy = llvm::StructType::get(LongTy,
551 SelectorPtrTy,
552 Types.ConvertType(Ctx.ShortTy),
553 Types.ConvertType(Ctx.ShortTy),
554 NULL);
555 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
556
557 ModuleTy =
558 llvm::StructType::get(LongTy,
559 LongTy,
560 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
561 llvm::PointerType::getUnqual(SymtabTy),
562 NULL);
563 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000564}
565
566ObjCTypesHelper::~ObjCTypesHelper() {
567}
568
569const llvm::StructType *ObjCTypesHelper::getCFStringType() {
570 if (!CFStringType) {
571 CFStringType =
572 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
573 llvm::Type::Int32Ty,
574 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
575 LongTy,
576 NULL);
577
578 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
579 }
580
581 return CFStringType;
582}
583
584llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
585 if (!CFConstantStringClassReference) {
586 llvm::GlobalValue *GV =
587 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
588 false,
589 llvm::GlobalValue::ExternalLinkage,
590 0, "__CFConstantStringClassReference",
591 &CGM.getModule());
592
593 // Decay to pointer.
594 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
595 }
596
597 return CFConstantStringClassReference;
598}
599
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000600llvm::Function *ObjCTypesHelper::getMessageSendFn() {
601 if (!MessageSendFn) {
602 std::vector<const llvm::Type*> Params;
603 Params.push_back(ObjectPtrTy);
604 Params.push_back(SelectorPtrTy);
605 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
606 Params,
607 true),
608 llvm::Function::ExternalLinkage,
609 "objc_msgSend",
610 &CGM.getModule());
611 }
612
613 return MessageSendFn;
614}
615
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000616/* *** */
617
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000618CodeGen::CGObjCRuntime *CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM){
619 return new CGObjCMac(CGM);
620}