blob: 61b9534759a8eb75a782bb32db0cff58f370d0da [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 Dunbar6efc0c52008-08-13 03:21:16 +000019#include "clang/AST/DeclObjC.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000020#include "clang/Basic/LangOptions.h"
21
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000022#include "llvm/Module.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000023#include "llvm/Support/IRBuilder.h"
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000024#include "llvm/Target/TargetData.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000025
26using namespace clang;
27
28namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000029
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000030 // FIXME: We should find a nicer way to make the labels for
31 // metadata, string concatenation is lame.
32
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000033/// 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;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000041 llvm::Function *MessageSendFn;
42
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000043public:
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000044 const llvm::Type *IntTy, *LongTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000045
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000046 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
47 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000048 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000049 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000050 /// ProtocolPtrTy - LLVM type for external protocol handles
51 /// (typeof(Protocol))
52 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000053
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;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000058
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000059 /// 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
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000087public:
88 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
89 ~ObjCTypesHelper();
90
91 llvm::Constant *getCFConstantStringClassReference();
92 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +000093 llvm::Function *getMessageSendFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000094};
95
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000096class CGObjCMac : public CodeGen::CGObjCRuntime {
97private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000098 CodeGen::CodeGenModule &CGM;
99 ObjCTypesHelper ObjCTypes;
100 /// ObjCABI - FIXME: Not sure yet.
101 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000102
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000103 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000104 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000105
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000106 /// MethodVarNames - uniqued method variable names.
107 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
108
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000109 /// 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
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000113 /// SelectorReferences - uniqued selector references.
114 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
115
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000116 /// 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
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000122 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000123 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000124
125 /// EmitImageInfo - Emit the image info marker used to encode some module
126 /// level information.
127 void EmitImageInfo();
128
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000129 /// 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
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000142 /// FinishModule - Write out global data structures at the end of
143 /// processing a translation unit.
144 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000145
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
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000179 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
180 /// for the given selector.
181 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
182
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000183 /// GetClassName - Return a unique constant for the given selector's
184 /// name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000185 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000186
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000187 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000188 /// selector's name. This returns a constant i8* to the start of
189 /// the name.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000190 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000191
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000192 /// 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
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000197public:
198 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000199 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000200
201 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
202 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000203 llvm::Value *Receiver,
204 Selector Sel,
205 llvm::Value** ArgV,
206 unsigned ArgC);
207
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000208 virtual llvm::Value *
209 GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
210 const llvm::Type *ReturnTy,
211 const ObjCInterfaceDecl *SuperClass,
212 llvm::Value *Receiver,
213 Selector Sel,
214 llvm::Value** ArgV,
215 unsigned ArgC);
216
217 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
218 const ObjCInterfaceDecl *SuperClass);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000219
220 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
221
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000222 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000223
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000224 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000225
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000226 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000227
228 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000229 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000230
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000231 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000232
233 virtual llvm::Function *ModuleInitFunction();
234};
235} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000236
237/* *** Helper Functions *** */
238
239/// getConstantGEP() - Help routine to construct simple GEPs.
240static llvm::Constant *getConstantGEP(llvm::Constant *C,
241 unsigned idx0,
242 unsigned idx1) {
243 llvm::Value *Idxs[] = {
244 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
245 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
246 };
247 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
248}
249
250/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000251
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000252CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
253 : CGM(cgm),
254 ObjCTypes(cgm),
255 ObjCABI(1)
256{
257 // FIXME: How does this get set in GCC? And what does it even mean?
258 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
259 ObjCABI = 2;
260
261 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000262}
263
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000264/// GetClass - Return a reference to the class for the given interface
265/// decl.
266llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
267 const ObjCInterfaceDecl *OID) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000268 assert(0 && "Cannot lookup classes on Mac runtime.");
269 return 0;
270}
271
272/// GetSelector - Return the pointer to the unique'd string for this selector.
273llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000274 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000275}
276
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000277/// Generate a constant CFString object.
278/*
279 struct __builtin_CFString {
280 const int *isa; // point to __CFConstantStringClassReference
281 int flags;
282 const char *str;
283 long length;
284 };
285*/
286
287llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
288 // FIXME: I have no idea what this constant is (it is a magic
289 // constant in GCC as well). Most likely the encoding of the string
290 // and at least one part of it relates to UTF-16. Is this just the
291 // code for UTF-8? Where is this handled for us?
292 // See: <rdr://2996215>
293 unsigned flags = 0x07c8;
294
295 // FIXME: Use some machinery to unique this. We can't reuse the CGM
296 // one since we put them in a different section.
297 llvm::Constant *StringC = llvm::ConstantArray::get(String);
298 llvm::Constant *StringGV =
299 new llvm::GlobalVariable(StringC->getType(), true,
300 llvm::GlobalValue::InternalLinkage,
301 StringC, ".str", &CGM.getModule());
302 llvm::Constant *Values[4] = {
303 ObjCTypes.getCFConstantStringClassReference(),
304 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
305 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
306 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
307 };
308
309 llvm::Constant *CFStringC =
310 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
311 std::vector<llvm::Constant*>(Values, Values+4));
312
313 llvm::GlobalVariable *CFStringGV =
314 new llvm::GlobalVariable(CFStringC->getType(), true,
315 llvm::GlobalValue::InternalLinkage,
316 CFStringC, "",
317 &CGM.getModule());
318
319 CFStringGV->setSection("__DATA, __cfstring");
320
321 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000322}
323
324/// Generates a message send where the super is the receiver. This is
325/// a message send to self with special delivery semantics indicating
326/// which class's method should be called.
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000327llvm::Value *
328CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
329 const llvm::Type *ReturnTy,
330 const ObjCInterfaceDecl *SuperClass,
331 llvm::Value *Receiver,
332 Selector Sel,
333 llvm::Value** ArgV,
334 unsigned ArgC) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000335 assert(0 && "Cannot generate message send to super for Mac runtime.");
336 return 0;
337}
338
339/// Generate code for a message send expression.
340llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
341 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000342 llvm::Value *Receiver,
343 Selector Sel,
344 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000345 unsigned ArgC) {
346 llvm::Function *F = ObjCTypes.getMessageSendFn();
347 llvm::Value **Args = new llvm::Value*[ArgC+2];
348 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
349 Args[1] = EmitSelector(Builder, Sel);
350 std::copy(ArgV, ArgV+ArgC, Args+2);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000351
352 std::vector<const llvm::Type*> Params;
353 Params.push_back(ObjCTypes.ObjectPtrTy);
354 Params.push_back(ObjCTypes.SelectorPtrTy);
355 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
356 Params,
357 true);
358 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
359 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
360 llvm::CallInst *CI = Builder.CreateCall(C,
361 Args, Args+ArgC+2, "tmp");
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000362 delete[] Args;
363 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000364}
365
366llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000367 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000368 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
369 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000370}
371
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000372/*
373 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
374 struct _objc_protocol {
375 struct _objc_protocol_extension *isa;
376 char *protocol_name;
377 struct _objc_protocol_list *protocol_list;
378 struct _objc__method_prototype_list *instance_methods;
379 struct _objc__method_prototype_list *class_methods
380 };
381
382 See EmitProtocolExtension().
383*/
384void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
385 const char *ProtocolName = PD->getName();
386
387 std::vector<llvm::Constant*> Values(5);
388 Values[0] = EmitProtocolExtension(PD);
389 Values[1] = GetClassName(PD->getIdentifier());
390 Values[2] = EmitProtocolList(PD);
391 Values[3] = EmitMethodList(ProtocolName,
392 true, // IsProtocol
393 false, // ClassMethods
394 true, // Required
395 PD->instmeth_begin(),
396 PD->instmeth_end());
397 Values[4] = EmitMethodList(ProtocolName,
398 true, // IsProtocol
399 true, // ClassMethods
400 true, // Required
401 PD->classmeth_begin(),
402 PD->classmeth_end());
403 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
404 Values);
405
406 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
407 if (Entry) {
408 // Already created, just update the initializer
409 Entry->setInitializer(Init);
410 } else {
411 Entry =
412 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
413 llvm::GlobalValue::InternalLinkage,
414 Init,
415 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
416 &CGM.getModule());
417 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
418 UsedGlobals.push_back(Entry);
419 // FIXME: Is this necessary? Why only for protocol?
420 Entry->setAlignment(4);
421 }
422}
423
424llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
425 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
426
427 if (!Entry) {
428 std::vector<llvm::Constant*> Values(5);
429 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
430 Values[1] = GetClassName(PD->getIdentifier());
431 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
432 Values[3] = Values[4] =
433 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
434 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
435 Values);
436
437 Entry =
438 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
439 llvm::GlobalValue::InternalLinkage,
440 Init,
441 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
442 &CGM.getModule());
443 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
444 UsedGlobals.push_back(Entry);
445 // FIXME: Is this necessary? Why only for protocol?
446 Entry->setAlignment(4);
447 }
448
449 return Entry;
450}
451
452/*
453 struct _objc_protocol_extension {
454 uint32_t size;
455 struct objc_method_description_list *optional_instance_methods;
456 struct objc_method_description_list *optional_class_methods;
457 struct objc_property_list *instance_properties;
458 };
459*/
460llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
461 uint64_t Size =
462 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
463 std::vector<llvm::Constant*> Values(4);
464 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
465 Values[1] = EmitMethodList(PD->getName(),
466 true, // IsProtocol
467 false, // ClassMethods
468 false, // Required
469 PD->instmeth_begin(),
470 PD->instmeth_end());
471 Values[2] = EmitMethodList(PD->getName(),
472 true, // IsProtocol
473 true, // ClassMethods
474 false, // Required
475 PD->classmeth_begin(),
476 PD->classmeth_end());
477 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
478 assert(!PD->getNumPropertyDecl() &&
479 "Cannot emit Obj-C protocol properties for NeXT runtime.");
480
481 // Return null if no extension bits are used
482 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
483 Values[3]->isNullValue())
484 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
485
486 llvm::Constant *Init =
487 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
488 llvm::GlobalVariable *GV =
489 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
490 llvm::GlobalValue::InternalLinkage,
491 Init,
492 (std::string("\01L_OBJC_PROTOCOLEXT_") +
493 PD->getName()),
494 &CGM.getModule());
495 // No special section, but goes in llvm.used
496 UsedGlobals.push_back(GV);
497
498 return GV;
499}
500
501/*
502 struct objc_protocol_list {
503 struct objc_protocol_list *next;
504 long count;
505 Protocol *list[];
506 };
507*/
508llvm::Constant *CGObjCMac::EmitProtocolList(const ObjCProtocolDecl *PD) {
509 std::vector<llvm::Constant*> ProtocolRefs;
510
511 for (ObjCProtocolDecl::protocol_iterator i = PD->protocol_begin(),
512 e = PD->protocol_end(); i != e; ++i)
513 ProtocolRefs.push_back(GetProtocolRef(*i));
514
515 // Just return null for empty protocol lists
516 if (ProtocolRefs.empty())
517 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
518
519 // This list is null terminated?
520 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
521
522 std::vector<llvm::Constant*> Values(3);
523 // XXX: What is this for?
524 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
525 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
526 Values[2] =
527 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
528 ProtocolRefs.size()),
529 ProtocolRefs);
530
531 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
532 llvm::GlobalVariable *GV =
533 new llvm::GlobalVariable(Init->getType(), false,
534 llvm::GlobalValue::InternalLinkage,
535 Init,
536 (std::string("\01L_OBJC_PROTOCOL_REFS_") +
537 PD->getName()),
538 &CGM.getModule());
539 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
540 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
541}
542
543/*
544 struct objc_method_description_list {
545 int count;
546 struct objc_method_description list[];
547 };
548*/
549llvm::Constant *CGObjCMac::EmitMethodList(const std::string &TypeName,
550 bool IsProtocol,
551 bool ClassMethods,
552 bool Required,
553 ObjCMethodDecl * const *begin,
554 ObjCMethodDecl * const *end) {
555 std::vector<llvm::Constant*> Methods, Desc(2);
556 for (; begin != end; ++begin) {
557 ObjCMethodDecl *D = *begin;
558 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
559
560 // Skip if this method is required and we are outputting optional
561 // methods, or vice versa.
562 if (Required != IsRequired)
563 continue;
564
565 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
566 ObjCTypes.SelectorPtrTy);
567 Desc[1] = GetMethodVarType(D);
568 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
569 Desc));
570 }
571
572 // Return null for empty list.
573 if (Methods.empty())
574 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
575
576 std::vector<llvm::Constant*> Values(2);
577 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
578 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
579 Methods.size());
580 Values[1] = llvm::ConstantArray::get(AT, Methods);
581 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
582
583 char Prefix[256];
584 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
585 IsProtocol ? "PROTOCOL_" : "",
586 ClassMethods ? "CLASS_" : "INSTANCE_",
587 !Required ? "OPT_" : "");
588 llvm::GlobalVariable *GV =
589 new llvm::GlobalVariable(Init->getType(), false,
590 llvm::GlobalValue::InternalLinkage,
591 Init,
592 std::string(Prefix) + TypeName,
593 &CGM.getModule());
594 if (ClassMethods) {
595 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
596 } else {
597 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
598 }
599 UsedGlobals.push_back(GV);
600 return llvm::ConstantExpr::getBitCast(GV,
601 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000602}
603
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000604void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000605 assert(0 && "Cannot generate category for Mac runtime.");
606}
607
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000608void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ClassDecl) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000609 assert(0 && "Cannot generate class for Mac runtime.");
610}
611
612llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000613 // Abuse this interface function as a place to finalize.
614 FinishModule();
615
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000616 return NULL;
617}
618
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000619llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000620 assert(0 && "Cannot generate method preamble for Mac runtime.");
621 return 0;
622}
623
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000624/* *** Private Interface *** */
625
626/// EmitImageInfo - Emit the image info marker used to encode some module
627/// level information.
628///
629/// See: <rdr://4810609&4810587&4810587>
630/// struct IMAGE_INFO {
631/// unsigned version;
632/// unsigned flags;
633/// };
634enum ImageInfoFlags {
635 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
636 eImageInfo_GarbageCollected = (1 << 1),
637 eImageInfo_GCOnly = (1 << 2)
638};
639
640void CGObjCMac::EmitImageInfo() {
641 unsigned version = 0; // Version is unused?
642 unsigned flags = 0;
643
644 // FIXME: Fix and continue?
645 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
646 flags |= eImageInfo_GarbageCollected;
647 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
648 flags |= eImageInfo_GCOnly;
649
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000650 // Emitted as int[2];
651 llvm::Constant *values[2] = {
652 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
653 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
654 };
655 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000656 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000657 new llvm::GlobalVariable(AT, true,
658 llvm::GlobalValue::InternalLinkage,
659 llvm::ConstantArray::get(AT, values, 2),
660 "\01L_OBJC_IMAGE_INFO",
661 &CGM.getModule());
662
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000663 if (ObjCABI == 1) {
664 GV->setSection("__OBJC, __image_info,regular");
665 } else {
666 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
667 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000668
669 UsedGlobals.push_back(GV);
670}
671
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000672
673// struct objc_module {
674// unsigned long version;
675// unsigned long size;
676// const char *name;
677// Symtab symtab;
678// };
679
680// FIXME: Get from somewhere
681static const int ModuleVersion = 7;
682
683void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000684 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
685
686 std::vector<llvm::Constant*> Values(4);
687 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
688 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000689 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000690 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000691 Values[3] = EmitModuleSymbols();
692
693 llvm::GlobalVariable *GV =
694 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
695 llvm::GlobalValue::InternalLinkage,
696 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
697 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000698 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000699 &CGM.getModule());
700 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
701 UsedGlobals.push_back(GV);
702}
703
704llvm::Constant *CGObjCMac::EmitModuleSymbols() {
705 // FIXME: Is this ever used?
706 llvm::GlobalVariable *GV =
707 new llvm::GlobalVariable(ObjCTypes.SymtabTy, false,
708 llvm::GlobalValue::InternalLinkage,
709 llvm::Constant::getNullValue(ObjCTypes.SymtabTy),
710 "\01L_OBJC_SYMBOLS",
711 &CGM.getModule());
712 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
713 UsedGlobals.push_back(GV);
714 return GV;
715}
716
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000717llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
718 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
719
720 if (!Entry) {
721 llvm::Constant *Casted =
722 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
723 ObjCTypes.SelectorPtrTy);
724 Entry =
725 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
726 llvm::GlobalValue::InternalLinkage,
727 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
728 &CGM.getModule());
729 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
730 UsedGlobals.push_back(Entry);
731 }
732
733 return Builder.CreateLoad(Entry, false, "tmp");
734}
735
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000736llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
737 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000738
739 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000740 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000741 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000742 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000743 llvm::GlobalValue::InternalLinkage,
744 C, "\01L_OBJC_CLASS_NAME_",
745 &CGM.getModule());
746 Entry->setSection("__TEXT,__cstring,cstring_literals");
747 UsedGlobals.push_back(Entry);
748 }
749
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000750 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000751}
752
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000753llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
754 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
755
756 if (!Entry) {
757 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
758 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000759 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000760 llvm::GlobalValue::InternalLinkage,
761 C, "\01L_OBJC_METH_VAR_NAME_",
762 &CGM.getModule());
763 Entry->setSection("__TEXT,__cstring,cstring_literals");
764 UsedGlobals.push_back(Entry);
765 }
766
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000767 return getConstantGEP(Entry, 0, 0);
768}
769
770llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
771 std::string TypeStr;
772 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
773 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
774
775 if (!Entry) {
776 llvm::Constant *C = llvm::ConstantArray::get(TypeStr);
777 Entry =
778 new llvm::GlobalVariable(C->getType(), false,
779 llvm::GlobalValue::InternalLinkage,
780 C, "\01L_OBJC_METH_VAR_TYPE_",
781 &CGM.getModule());
782 Entry->setSection("__TEXT,__cstring,cstring_literals");
783 UsedGlobals.push_back(Entry);
784 }
785
786 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000787}
788
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000789void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000790 EmitModuleInfo();
791
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000792 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000793
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000794 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000795 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000796 e = UsedGlobals.end(); i != e; ++i) {
797 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
798 }
799
800 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
801 llvm::GlobalValue *GV =
802 new llvm::GlobalVariable(AT, false,
803 llvm::GlobalValue::AppendingLinkage,
804 llvm::ConstantArray::get(AT, Used),
805 "llvm.used",
806 &CGM.getModule());
807
808 GV->setSection("llvm.metadata");
809}
810
811/* *** */
812
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000813ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
814 : CGM(cgm),
815 CFStringType(0),
816 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000817 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000818{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000819 CodeGen::CodeGenTypes &Types = CGM.getTypes();
820 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000821
822 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000823 LongTy = Types.ConvertType(Ctx.LongTy);
824 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
825 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000826
827 // FIXME: It would be nice to unify this with the opaque type, so
828 // that the IR comes out a bit cleaner.
829 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
830 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000831
832 SymtabTy = llvm::StructType::get(LongTy,
833 SelectorPtrTy,
834 Types.ConvertType(Ctx.ShortTy),
835 Types.ConvertType(Ctx.ShortTy),
836 NULL);
837 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
838
839 ModuleTy =
840 llvm::StructType::get(LongTy,
841 LongTy,
842 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
843 llvm::PointerType::getUnqual(SymtabTy),
844 NULL);
845 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000846
847 MethodDescriptionTy =
848 llvm::StructType::get(SelectorPtrTy,
849 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
850 NULL);
851 CGM.getModule().addTypeName("struct._objc_method_description",
852 MethodDescriptionTy);
853
854 MethodDescriptionListTy =
855 llvm::StructType::get(IntTy,
856 llvm::ArrayType::get(MethodDescriptionTy, 0),
857 NULL);
858 CGM.getModule().addTypeName("struct._objc_method_description_list",
859 MethodDescriptionListTy);
860 MethodDescriptionListPtrTy =
861 llvm::PointerType::getUnqual(MethodDescriptionListTy);
862
863 PropertyListTy = llvm::OpaqueType::get();
864 CGM.getModule().addTypeName("struct._objc_property_list",
865 PropertyListTy);
866 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
867
868 // Protocol description structures
869
870 ProtocolExtensionTy =
871 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
872 llvm::PointerType::getUnqual(MethodDescriptionListTy),
873 llvm::PointerType::getUnqual(MethodDescriptionListTy),
874 PropertyListPtrTy,
875 NULL);
876 CGM.getModule().addTypeName("struct._objc_protocol_extension",
877 ProtocolExtensionTy);
878 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
879
880 // Handle recursive construction of Protocl and ProtocolList types
881
882 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
883 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
884
885 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
886 LongTy,
887 llvm::ArrayType::get(ProtocolTyHolder, 0),
888 NULL);
889 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
890
891 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
892 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
893 llvm::PointerType::getUnqual(ProtocolListTyHolder),
894 MethodDescriptionListPtrTy,
895 MethodDescriptionListPtrTy,
896 NULL);
897 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
898
899 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
900 CGM.getModule().addTypeName("struct._objc_protocol_list",
901 ProtocolListTy);
902 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
903
904 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
905 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
906 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000907}
908
909ObjCTypesHelper::~ObjCTypesHelper() {
910}
911
912const llvm::StructType *ObjCTypesHelper::getCFStringType() {
913 if (!CFStringType) {
914 CFStringType =
915 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
916 llvm::Type::Int32Ty,
917 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
918 LongTy,
919 NULL);
920
921 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
922 }
923
924 return CFStringType;
925}
926
927llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
928 if (!CFConstantStringClassReference) {
929 llvm::GlobalValue *GV =
930 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
931 false,
932 llvm::GlobalValue::ExternalLinkage,
933 0, "__CFConstantStringClassReference",
934 &CGM.getModule());
935
936 // Decay to pointer.
937 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
938 }
939
940 return CFConstantStringClassReference;
941}
942
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000943llvm::Function *ObjCTypesHelper::getMessageSendFn() {
944 if (!MessageSendFn) {
945 std::vector<const llvm::Type*> Params;
946 Params.push_back(ObjectPtrTy);
947 Params.push_back(SelectorPtrTy);
948 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
949 Params,
950 true),
951 llvm::Function::ExternalLinkage,
952 "objc_msgSend",
953 &CGM.getModule());
954 }
955
956 return MessageSendFn;
957}
958
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000959/* *** */
960
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000961CodeGen::CGObjCRuntime *
962CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000963 return new CGObjCMac(CGM);
964}