blob: b307148955dc898af96730b3a1398b9744de18b5 [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
208 virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
209 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000210 const char *SuperClassName,
211 llvm::Value *Receiver,
212 Selector Sel,
213 llvm::Value** ArgV,
214 unsigned ArgC);
215
216 virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder,
217 llvm::Value *ClassName);
218
219 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
220
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000221 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000222
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000223 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000224
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000225 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000226
227 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000228 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000229
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000230 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000231
232 virtual llvm::Function *ModuleInitFunction();
233};
234} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000235
236/* *** Helper Functions *** */
237
238/// getConstantGEP() - Help routine to construct simple GEPs.
239static llvm::Constant *getConstantGEP(llvm::Constant *C,
240 unsigned idx0,
241 unsigned idx1) {
242 llvm::Value *Idxs[] = {
243 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
244 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
245 };
246 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
247}
248
249/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000250
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000251CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
252 : CGM(cgm),
253 ObjCTypes(cgm),
254 ObjCABI(1)
255{
256 // FIXME: How does this get set in GCC? And what does it even mean?
257 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
258 ObjCABI = 2;
259
260 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000261}
262
263// This has to perform the lookup every time, since posing and related
264// techniques can modify the name -> class mapping.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000265llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000266 llvm::Value *ClassName) {
267 assert(0 && "Cannot lookup classes on Mac runtime.");
268 return 0;
269}
270
271/// GetSelector - Return the pointer to the unique'd string for this selector.
272llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000273 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000274}
275
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000276/// Generate a constant CFString object.
277/*
278 struct __builtin_CFString {
279 const int *isa; // point to __CFConstantStringClassReference
280 int flags;
281 const char *str;
282 long length;
283 };
284*/
285
286llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
287 // FIXME: I have no idea what this constant is (it is a magic
288 // constant in GCC as well). Most likely the encoding of the string
289 // and at least one part of it relates to UTF-16. Is this just the
290 // code for UTF-8? Where is this handled for us?
291 // See: <rdr://2996215>
292 unsigned flags = 0x07c8;
293
294 // FIXME: Use some machinery to unique this. We can't reuse the CGM
295 // one since we put them in a different section.
296 llvm::Constant *StringC = llvm::ConstantArray::get(String);
297 llvm::Constant *StringGV =
298 new llvm::GlobalVariable(StringC->getType(), true,
299 llvm::GlobalValue::InternalLinkage,
300 StringC, ".str", &CGM.getModule());
301 llvm::Constant *Values[4] = {
302 ObjCTypes.getCFConstantStringClassReference(),
303 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
304 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
305 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
306 };
307
308 llvm::Constant *CFStringC =
309 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
310 std::vector<llvm::Constant*>(Values, Values+4));
311
312 llvm::GlobalVariable *CFStringGV =
313 new llvm::GlobalVariable(CFStringC->getType(), true,
314 llvm::GlobalValue::InternalLinkage,
315 CFStringC, "",
316 &CGM.getModule());
317
318 CFStringGV->setSection("__DATA, __cfstring");
319
320 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000321}
322
323/// Generates a message send where the super is the receiver. This is
324/// a message send to self with special delivery semantics indicating
325/// which class's method should be called.
326llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
327 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000328 const char *SuperClassName,
329 llvm::Value *Receiver,
330 Selector Sel,
331 llvm::Value** ArgV,
332 unsigned ArgC) {
333 assert(0 && "Cannot generate message send to super for Mac runtime.");
334 return 0;
335}
336
337/// Generate code for a message send expression.
338llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
339 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000340 llvm::Value *Receiver,
341 Selector Sel,
342 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000343 unsigned ArgC) {
344 llvm::Function *F = ObjCTypes.getMessageSendFn();
345 llvm::Value **Args = new llvm::Value*[ArgC+2];
346 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
347 Args[1] = EmitSelector(Builder, Sel);
348 std::copy(ArgV, ArgV+ArgC, Args+2);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000349
350 std::vector<const llvm::Type*> Params;
351 Params.push_back(ObjCTypes.ObjectPtrTy);
352 Params.push_back(ObjCTypes.SelectorPtrTy);
353 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
354 Params,
355 true);
356 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
357 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
358 llvm::CallInst *CI = Builder.CreateCall(C,
359 Args, Args+ArgC+2, "tmp");
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000360 delete[] Args;
361 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000362}
363
364llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000365 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000366 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
367 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000368}
369
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000370/*
371 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
372 struct _objc_protocol {
373 struct _objc_protocol_extension *isa;
374 char *protocol_name;
375 struct _objc_protocol_list *protocol_list;
376 struct _objc__method_prototype_list *instance_methods;
377 struct _objc__method_prototype_list *class_methods
378 };
379
380 See EmitProtocolExtension().
381*/
382void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
383 const char *ProtocolName = PD->getName();
384
385 std::vector<llvm::Constant*> Values(5);
386 Values[0] = EmitProtocolExtension(PD);
387 Values[1] = GetClassName(PD->getIdentifier());
388 Values[2] = EmitProtocolList(PD);
389 Values[3] = EmitMethodList(ProtocolName,
390 true, // IsProtocol
391 false, // ClassMethods
392 true, // Required
393 PD->instmeth_begin(),
394 PD->instmeth_end());
395 Values[4] = EmitMethodList(ProtocolName,
396 true, // IsProtocol
397 true, // ClassMethods
398 true, // Required
399 PD->classmeth_begin(),
400 PD->classmeth_end());
401 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
402 Values);
403
404 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
405 if (Entry) {
406 // Already created, just update the initializer
407 Entry->setInitializer(Init);
408 } else {
409 Entry =
410 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
411 llvm::GlobalValue::InternalLinkage,
412 Init,
413 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
414 &CGM.getModule());
415 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
416 UsedGlobals.push_back(Entry);
417 // FIXME: Is this necessary? Why only for protocol?
418 Entry->setAlignment(4);
419 }
420}
421
422llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
423 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
424
425 if (!Entry) {
426 std::vector<llvm::Constant*> Values(5);
427 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
428 Values[1] = GetClassName(PD->getIdentifier());
429 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
430 Values[3] = Values[4] =
431 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
432 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
433 Values);
434
435 Entry =
436 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
437 llvm::GlobalValue::InternalLinkage,
438 Init,
439 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
440 &CGM.getModule());
441 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
442 UsedGlobals.push_back(Entry);
443 // FIXME: Is this necessary? Why only for protocol?
444 Entry->setAlignment(4);
445 }
446
447 return Entry;
448}
449
450/*
451 struct _objc_protocol_extension {
452 uint32_t size;
453 struct objc_method_description_list *optional_instance_methods;
454 struct objc_method_description_list *optional_class_methods;
455 struct objc_property_list *instance_properties;
456 };
457*/
458llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
459 uint64_t Size =
460 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
461 std::vector<llvm::Constant*> Values(4);
462 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
463 Values[1] = EmitMethodList(PD->getName(),
464 true, // IsProtocol
465 false, // ClassMethods
466 false, // Required
467 PD->instmeth_begin(),
468 PD->instmeth_end());
469 Values[2] = EmitMethodList(PD->getName(),
470 true, // IsProtocol
471 true, // ClassMethods
472 false, // Required
473 PD->classmeth_begin(),
474 PD->classmeth_end());
475 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
476 assert(!PD->getNumPropertyDecl() &&
477 "Cannot emit Obj-C protocol properties for NeXT runtime.");
478
479 // Return null if no extension bits are used
480 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
481 Values[3]->isNullValue())
482 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
483
484 llvm::Constant *Init =
485 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
486 llvm::GlobalVariable *GV =
487 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
488 llvm::GlobalValue::InternalLinkage,
489 Init,
490 (std::string("\01L_OBJC_PROTOCOLEXT_") +
491 PD->getName()),
492 &CGM.getModule());
493 // No special section, but goes in llvm.used
494 UsedGlobals.push_back(GV);
495
496 return GV;
497}
498
499/*
500 struct objc_protocol_list {
501 struct objc_protocol_list *next;
502 long count;
503 Protocol *list[];
504 };
505*/
506llvm::Constant *CGObjCMac::EmitProtocolList(const ObjCProtocolDecl *PD) {
507 std::vector<llvm::Constant*> ProtocolRefs;
508
509 for (ObjCProtocolDecl::protocol_iterator i = PD->protocol_begin(),
510 e = PD->protocol_end(); i != e; ++i)
511 ProtocolRefs.push_back(GetProtocolRef(*i));
512
513 // Just return null for empty protocol lists
514 if (ProtocolRefs.empty())
515 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
516
517 // This list is null terminated?
518 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
519
520 std::vector<llvm::Constant*> Values(3);
521 // XXX: What is this for?
522 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
523 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
524 Values[2] =
525 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
526 ProtocolRefs.size()),
527 ProtocolRefs);
528
529 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
530 llvm::GlobalVariable *GV =
531 new llvm::GlobalVariable(Init->getType(), false,
532 llvm::GlobalValue::InternalLinkage,
533 Init,
534 (std::string("\01L_OBJC_PROTOCOL_REFS_") +
535 PD->getName()),
536 &CGM.getModule());
537 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
538 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
539}
540
541/*
542 struct objc_method_description_list {
543 int count;
544 struct objc_method_description list[];
545 };
546*/
547llvm::Constant *CGObjCMac::EmitMethodList(const std::string &TypeName,
548 bool IsProtocol,
549 bool ClassMethods,
550 bool Required,
551 ObjCMethodDecl * const *begin,
552 ObjCMethodDecl * const *end) {
553 std::vector<llvm::Constant*> Methods, Desc(2);
554 for (; begin != end; ++begin) {
555 ObjCMethodDecl *D = *begin;
556 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
557
558 // Skip if this method is required and we are outputting optional
559 // methods, or vice versa.
560 if (Required != IsRequired)
561 continue;
562
563 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
564 ObjCTypes.SelectorPtrTy);
565 Desc[1] = GetMethodVarType(D);
566 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
567 Desc));
568 }
569
570 // Return null for empty list.
571 if (Methods.empty())
572 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
573
574 std::vector<llvm::Constant*> Values(2);
575 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
576 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
577 Methods.size());
578 Values[1] = llvm::ConstantArray::get(AT, Methods);
579 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
580
581 char Prefix[256];
582 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
583 IsProtocol ? "PROTOCOL_" : "",
584 ClassMethods ? "CLASS_" : "INSTANCE_",
585 !Required ? "OPT_" : "");
586 llvm::GlobalVariable *GV =
587 new llvm::GlobalVariable(Init->getType(), false,
588 llvm::GlobalValue::InternalLinkage,
589 Init,
590 std::string(Prefix) + TypeName,
591 &CGM.getModule());
592 if (ClassMethods) {
593 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
594 } else {
595 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
596 }
597 UsedGlobals.push_back(GV);
598 return llvm::ConstantExpr::getBitCast(GV,
599 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000600}
601
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000602void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000603 assert(0 && "Cannot generate category for Mac runtime.");
604}
605
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000606void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ClassDecl) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000607 assert(0 && "Cannot generate class for Mac runtime.");
608}
609
610llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000611 // Abuse this interface function as a place to finalize.
612 FinishModule();
613
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000614 return NULL;
615}
616
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000617llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000618 assert(0 && "Cannot generate method preamble for Mac runtime.");
619 return 0;
620}
621
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000622/* *** Private Interface *** */
623
624/// EmitImageInfo - Emit the image info marker used to encode some module
625/// level information.
626///
627/// See: <rdr://4810609&4810587&4810587>
628/// struct IMAGE_INFO {
629/// unsigned version;
630/// unsigned flags;
631/// };
632enum ImageInfoFlags {
633 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
634 eImageInfo_GarbageCollected = (1 << 1),
635 eImageInfo_GCOnly = (1 << 2)
636};
637
638void CGObjCMac::EmitImageInfo() {
639 unsigned version = 0; // Version is unused?
640 unsigned flags = 0;
641
642 // FIXME: Fix and continue?
643 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
644 flags |= eImageInfo_GarbageCollected;
645 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
646 flags |= eImageInfo_GCOnly;
647
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000648 // Emitted as int[2];
649 llvm::Constant *values[2] = {
650 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
651 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
652 };
653 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000654 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000655 new llvm::GlobalVariable(AT, true,
656 llvm::GlobalValue::InternalLinkage,
657 llvm::ConstantArray::get(AT, values, 2),
658 "\01L_OBJC_IMAGE_INFO",
659 &CGM.getModule());
660
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000661 if (ObjCABI == 1) {
662 GV->setSection("__OBJC, __image_info,regular");
663 } else {
664 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
665 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000666
667 UsedGlobals.push_back(GV);
668}
669
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000670
671// struct objc_module {
672// unsigned long version;
673// unsigned long size;
674// const char *name;
675// Symtab symtab;
676// };
677
678// FIXME: Get from somewhere
679static const int ModuleVersion = 7;
680
681void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000682 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
683
684 std::vector<llvm::Constant*> Values(4);
685 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
686 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000687 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000688 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000689 Values[3] = EmitModuleSymbols();
690
691 llvm::GlobalVariable *GV =
692 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
693 llvm::GlobalValue::InternalLinkage,
694 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
695 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000696 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000697 &CGM.getModule());
698 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
699 UsedGlobals.push_back(GV);
700}
701
702llvm::Constant *CGObjCMac::EmitModuleSymbols() {
703 // FIXME: Is this ever used?
704 llvm::GlobalVariable *GV =
705 new llvm::GlobalVariable(ObjCTypes.SymtabTy, false,
706 llvm::GlobalValue::InternalLinkage,
707 llvm::Constant::getNullValue(ObjCTypes.SymtabTy),
708 "\01L_OBJC_SYMBOLS",
709 &CGM.getModule());
710 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
711 UsedGlobals.push_back(GV);
712 return GV;
713}
714
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000715llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
716 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
717
718 if (!Entry) {
719 llvm::Constant *Casted =
720 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
721 ObjCTypes.SelectorPtrTy);
722 Entry =
723 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
724 llvm::GlobalValue::InternalLinkage,
725 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
726 &CGM.getModule());
727 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
728 UsedGlobals.push_back(Entry);
729 }
730
731 return Builder.CreateLoad(Entry, false, "tmp");
732}
733
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000734llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
735 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000736
737 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000738 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000739 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000740 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000741 llvm::GlobalValue::InternalLinkage,
742 C, "\01L_OBJC_CLASS_NAME_",
743 &CGM.getModule());
744 Entry->setSection("__TEXT,__cstring,cstring_literals");
745 UsedGlobals.push_back(Entry);
746 }
747
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000748 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000749}
750
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000751llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
752 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
753
754 if (!Entry) {
755 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
756 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000757 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000758 llvm::GlobalValue::InternalLinkage,
759 C, "\01L_OBJC_METH_VAR_NAME_",
760 &CGM.getModule());
761 Entry->setSection("__TEXT,__cstring,cstring_literals");
762 UsedGlobals.push_back(Entry);
763 }
764
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000765 return getConstantGEP(Entry, 0, 0);
766}
767
768llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
769 std::string TypeStr;
770 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
771 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
772
773 if (!Entry) {
774 llvm::Constant *C = llvm::ConstantArray::get(TypeStr);
775 Entry =
776 new llvm::GlobalVariable(C->getType(), false,
777 llvm::GlobalValue::InternalLinkage,
778 C, "\01L_OBJC_METH_VAR_TYPE_",
779 &CGM.getModule());
780 Entry->setSection("__TEXT,__cstring,cstring_literals");
781 UsedGlobals.push_back(Entry);
782 }
783
784 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000785}
786
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000787void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000788 EmitModuleInfo();
789
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000790 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000791
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000792 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000793 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000794 e = UsedGlobals.end(); i != e; ++i) {
795 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
796 }
797
798 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
799 llvm::GlobalValue *GV =
800 new llvm::GlobalVariable(AT, false,
801 llvm::GlobalValue::AppendingLinkage,
802 llvm::ConstantArray::get(AT, Used),
803 "llvm.used",
804 &CGM.getModule());
805
806 GV->setSection("llvm.metadata");
807}
808
809/* *** */
810
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000811ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
812 : CGM(cgm),
813 CFStringType(0),
814 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000815 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000816{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000817 CodeGen::CodeGenTypes &Types = CGM.getTypes();
818 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000819
820 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000821 LongTy = Types.ConvertType(Ctx.LongTy);
822 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
823 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000824
825 // FIXME: It would be nice to unify this with the opaque type, so
826 // that the IR comes out a bit cleaner.
827 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
828 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000829
830 SymtabTy = llvm::StructType::get(LongTy,
831 SelectorPtrTy,
832 Types.ConvertType(Ctx.ShortTy),
833 Types.ConvertType(Ctx.ShortTy),
834 NULL);
835 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
836
837 ModuleTy =
838 llvm::StructType::get(LongTy,
839 LongTy,
840 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
841 llvm::PointerType::getUnqual(SymtabTy),
842 NULL);
843 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000844
845 MethodDescriptionTy =
846 llvm::StructType::get(SelectorPtrTy,
847 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
848 NULL);
849 CGM.getModule().addTypeName("struct._objc_method_description",
850 MethodDescriptionTy);
851
852 MethodDescriptionListTy =
853 llvm::StructType::get(IntTy,
854 llvm::ArrayType::get(MethodDescriptionTy, 0),
855 NULL);
856 CGM.getModule().addTypeName("struct._objc_method_description_list",
857 MethodDescriptionListTy);
858 MethodDescriptionListPtrTy =
859 llvm::PointerType::getUnqual(MethodDescriptionListTy);
860
861 PropertyListTy = llvm::OpaqueType::get();
862 CGM.getModule().addTypeName("struct._objc_property_list",
863 PropertyListTy);
864 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
865
866 // Protocol description structures
867
868 ProtocolExtensionTy =
869 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
870 llvm::PointerType::getUnqual(MethodDescriptionListTy),
871 llvm::PointerType::getUnqual(MethodDescriptionListTy),
872 PropertyListPtrTy,
873 NULL);
874 CGM.getModule().addTypeName("struct._objc_protocol_extension",
875 ProtocolExtensionTy);
876 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
877
878 // Handle recursive construction of Protocl and ProtocolList types
879
880 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
881 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
882
883 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
884 LongTy,
885 llvm::ArrayType::get(ProtocolTyHolder, 0),
886 NULL);
887 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
888
889 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
890 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
891 llvm::PointerType::getUnqual(ProtocolListTyHolder),
892 MethodDescriptionListPtrTy,
893 MethodDescriptionListPtrTy,
894 NULL);
895 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
896
897 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
898 CGM.getModule().addTypeName("struct._objc_protocol_list",
899 ProtocolListTy);
900 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
901
902 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
903 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
904 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000905}
906
907ObjCTypesHelper::~ObjCTypesHelper() {
908}
909
910const llvm::StructType *ObjCTypesHelper::getCFStringType() {
911 if (!CFStringType) {
912 CFStringType =
913 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
914 llvm::Type::Int32Ty,
915 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
916 LongTy,
917 NULL);
918
919 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
920 }
921
922 return CFStringType;
923}
924
925llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
926 if (!CFConstantStringClassReference) {
927 llvm::GlobalValue *GV =
928 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
929 false,
930 llvm::GlobalValue::ExternalLinkage,
931 0, "__CFConstantStringClassReference",
932 &CGM.getModule());
933
934 // Decay to pointer.
935 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
936 }
937
938 return CFConstantStringClassReference;
939}
940
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000941llvm::Function *ObjCTypesHelper::getMessageSendFn() {
942 if (!MessageSendFn) {
943 std::vector<const llvm::Type*> Params;
944 Params.push_back(ObjectPtrTy);
945 Params.push_back(SelectorPtrTy);
946 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
947 Params,
948 true),
949 llvm::Function::ExternalLinkage,
950 "objc_msgSend",
951 &CGM.getModule());
952 }
953
954 return MessageSendFn;
955}
956
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000957/* *** */
958
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000959CodeGen::CGObjCRuntime *
960CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000961 return new CGObjCMac(CGM);
962}