blob: 1db7e01c930febb54ac11f6e7c18809a374a7149 [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
221 virtual llvm::Function *MethodPreamble(const std::string &ClassName,
222 const std::string &CategoryName,
223 const std::string &MethodName,
224 const llvm::Type *ReturnTy,
225 const llvm::Type *SelfTy,
226 const llvm::Type **ArgTy,
227 unsigned ArgC,
228 bool isClassMethod,
229 bool isVarArg);
230
231 virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
232 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
233 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
234 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
235 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
236 const llvm::SmallVectorImpl<std::string> &Protocols);
237
238 virtual void GenerateClass(
239 const char *ClassName,
240 const char *SuperClassName,
241 const int instanceSize,
242 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
243 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
244 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
245 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
246 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
247 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
248 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
249 const llvm::SmallVectorImpl<std::string> &Protocols);
250
251 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000252 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000253
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000254 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000255
256 virtual llvm::Function *ModuleInitFunction();
257};
258} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000259
260/* *** Helper Functions *** */
261
262/// getConstantGEP() - Help routine to construct simple GEPs.
263static llvm::Constant *getConstantGEP(llvm::Constant *C,
264 unsigned idx0,
265 unsigned idx1) {
266 llvm::Value *Idxs[] = {
267 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
268 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
269 };
270 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
271}
272
273/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000274
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000275CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
276 : CGM(cgm),
277 ObjCTypes(cgm),
278 ObjCABI(1)
279{
280 // FIXME: How does this get set in GCC? And what does it even mean?
281 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
282 ObjCABI = 2;
283
284 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000285}
286
287// This has to perform the lookup every time, since posing and related
288// techniques can modify the name -> class mapping.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000289llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000290 llvm::Value *ClassName) {
291 assert(0 && "Cannot lookup classes on Mac runtime.");
292 return 0;
293}
294
295/// GetSelector - Return the pointer to the unique'd string for this selector.
296llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000297 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000298}
299
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000300/// Generate a constant CFString object.
301/*
302 struct __builtin_CFString {
303 const int *isa; // point to __CFConstantStringClassReference
304 int flags;
305 const char *str;
306 long length;
307 };
308*/
309
310llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
311 // FIXME: I have no idea what this constant is (it is a magic
312 // constant in GCC as well). Most likely the encoding of the string
313 // and at least one part of it relates to UTF-16. Is this just the
314 // code for UTF-8? Where is this handled for us?
315 // See: <rdr://2996215>
316 unsigned flags = 0x07c8;
317
318 // FIXME: Use some machinery to unique this. We can't reuse the CGM
319 // one since we put them in a different section.
320 llvm::Constant *StringC = llvm::ConstantArray::get(String);
321 llvm::Constant *StringGV =
322 new llvm::GlobalVariable(StringC->getType(), true,
323 llvm::GlobalValue::InternalLinkage,
324 StringC, ".str", &CGM.getModule());
325 llvm::Constant *Values[4] = {
326 ObjCTypes.getCFConstantStringClassReference(),
327 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
328 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
329 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
330 };
331
332 llvm::Constant *CFStringC =
333 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
334 std::vector<llvm::Constant*>(Values, Values+4));
335
336 llvm::GlobalVariable *CFStringGV =
337 new llvm::GlobalVariable(CFStringC->getType(), true,
338 llvm::GlobalValue::InternalLinkage,
339 CFStringC, "",
340 &CGM.getModule());
341
342 CFStringGV->setSection("__DATA, __cfstring");
343
344 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000345}
346
347/// Generates a message send where the super is the receiver. This is
348/// a message send to self with special delivery semantics indicating
349/// which class's method should be called.
350llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
351 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000352 const char *SuperClassName,
353 llvm::Value *Receiver,
354 Selector Sel,
355 llvm::Value** ArgV,
356 unsigned ArgC) {
357 assert(0 && "Cannot generate message send to super for Mac runtime.");
358 return 0;
359}
360
361/// Generate code for a message send expression.
362llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
363 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000364 llvm::Value *Receiver,
365 Selector Sel,
366 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000367 unsigned ArgC) {
368 llvm::Function *F = ObjCTypes.getMessageSendFn();
369 llvm::Value **Args = new llvm::Value*[ArgC+2];
370 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
371 Args[1] = EmitSelector(Builder, Sel);
372 std::copy(ArgV, ArgV+ArgC, Args+2);
373 llvm::CallInst *CI = Builder.CreateCall(F, Args, Args+ArgC+2, "tmp");
374 delete[] Args;
375 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000376}
377
378llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000379 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000380 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
381 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000382}
383
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000384/*
385 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
386 struct _objc_protocol {
387 struct _objc_protocol_extension *isa;
388 char *protocol_name;
389 struct _objc_protocol_list *protocol_list;
390 struct _objc__method_prototype_list *instance_methods;
391 struct _objc__method_prototype_list *class_methods
392 };
393
394 See EmitProtocolExtension().
395*/
396void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
397 const char *ProtocolName = PD->getName();
398
399 std::vector<llvm::Constant*> Values(5);
400 Values[0] = EmitProtocolExtension(PD);
401 Values[1] = GetClassName(PD->getIdentifier());
402 Values[2] = EmitProtocolList(PD);
403 Values[3] = EmitMethodList(ProtocolName,
404 true, // IsProtocol
405 false, // ClassMethods
406 true, // Required
407 PD->instmeth_begin(),
408 PD->instmeth_end());
409 Values[4] = EmitMethodList(ProtocolName,
410 true, // IsProtocol
411 true, // ClassMethods
412 true, // Required
413 PD->classmeth_begin(),
414 PD->classmeth_end());
415 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
416 Values);
417
418 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
419 if (Entry) {
420 // Already created, just update the initializer
421 Entry->setInitializer(Init);
422 } else {
423 Entry =
424 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
425 llvm::GlobalValue::InternalLinkage,
426 Init,
427 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
428 &CGM.getModule());
429 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
430 UsedGlobals.push_back(Entry);
431 // FIXME: Is this necessary? Why only for protocol?
432 Entry->setAlignment(4);
433 }
434}
435
436llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
437 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
438
439 if (!Entry) {
440 std::vector<llvm::Constant*> Values(5);
441 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
442 Values[1] = GetClassName(PD->getIdentifier());
443 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
444 Values[3] = Values[4] =
445 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
446 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
447 Values);
448
449 Entry =
450 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
451 llvm::GlobalValue::InternalLinkage,
452 Init,
453 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
454 &CGM.getModule());
455 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
456 UsedGlobals.push_back(Entry);
457 // FIXME: Is this necessary? Why only for protocol?
458 Entry->setAlignment(4);
459 }
460
461 return Entry;
462}
463
464/*
465 struct _objc_protocol_extension {
466 uint32_t size;
467 struct objc_method_description_list *optional_instance_methods;
468 struct objc_method_description_list *optional_class_methods;
469 struct objc_property_list *instance_properties;
470 };
471*/
472llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
473 uint64_t Size =
474 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
475 std::vector<llvm::Constant*> Values(4);
476 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
477 Values[1] = EmitMethodList(PD->getName(),
478 true, // IsProtocol
479 false, // ClassMethods
480 false, // Required
481 PD->instmeth_begin(),
482 PD->instmeth_end());
483 Values[2] = EmitMethodList(PD->getName(),
484 true, // IsProtocol
485 true, // ClassMethods
486 false, // Required
487 PD->classmeth_begin(),
488 PD->classmeth_end());
489 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
490 assert(!PD->getNumPropertyDecl() &&
491 "Cannot emit Obj-C protocol properties for NeXT runtime.");
492
493 // Return null if no extension bits are used
494 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
495 Values[3]->isNullValue())
496 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
497
498 llvm::Constant *Init =
499 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
500 llvm::GlobalVariable *GV =
501 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
502 llvm::GlobalValue::InternalLinkage,
503 Init,
504 (std::string("\01L_OBJC_PROTOCOLEXT_") +
505 PD->getName()),
506 &CGM.getModule());
507 // No special section, but goes in llvm.used
508 UsedGlobals.push_back(GV);
509
510 return GV;
511}
512
513/*
514 struct objc_protocol_list {
515 struct objc_protocol_list *next;
516 long count;
517 Protocol *list[];
518 };
519*/
520llvm::Constant *CGObjCMac::EmitProtocolList(const ObjCProtocolDecl *PD) {
521 std::vector<llvm::Constant*> ProtocolRefs;
522
523 for (ObjCProtocolDecl::protocol_iterator i = PD->protocol_begin(),
524 e = PD->protocol_end(); i != e; ++i)
525 ProtocolRefs.push_back(GetProtocolRef(*i));
526
527 // Just return null for empty protocol lists
528 if (ProtocolRefs.empty())
529 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
530
531 // This list is null terminated?
532 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
533
534 std::vector<llvm::Constant*> Values(3);
535 // XXX: What is this for?
536 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
537 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
538 Values[2] =
539 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
540 ProtocolRefs.size()),
541 ProtocolRefs);
542
543 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
544 llvm::GlobalVariable *GV =
545 new llvm::GlobalVariable(Init->getType(), false,
546 llvm::GlobalValue::InternalLinkage,
547 Init,
548 (std::string("\01L_OBJC_PROTOCOL_REFS_") +
549 PD->getName()),
550 &CGM.getModule());
551 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
552 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
553}
554
555/*
556 struct objc_method_description_list {
557 int count;
558 struct objc_method_description list[];
559 };
560*/
561llvm::Constant *CGObjCMac::EmitMethodList(const std::string &TypeName,
562 bool IsProtocol,
563 bool ClassMethods,
564 bool Required,
565 ObjCMethodDecl * const *begin,
566 ObjCMethodDecl * const *end) {
567 std::vector<llvm::Constant*> Methods, Desc(2);
568 for (; begin != end; ++begin) {
569 ObjCMethodDecl *D = *begin;
570 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
571
572 // Skip if this method is required and we are outputting optional
573 // methods, or vice versa.
574 if (Required != IsRequired)
575 continue;
576
577 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
578 ObjCTypes.SelectorPtrTy);
579 Desc[1] = GetMethodVarType(D);
580 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
581 Desc));
582 }
583
584 // Return null for empty list.
585 if (Methods.empty())
586 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
587
588 std::vector<llvm::Constant*> Values(2);
589 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
590 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
591 Methods.size());
592 Values[1] = llvm::ConstantArray::get(AT, Methods);
593 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
594
595 char Prefix[256];
596 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
597 IsProtocol ? "PROTOCOL_" : "",
598 ClassMethods ? "CLASS_" : "INSTANCE_",
599 !Required ? "OPT_" : "");
600 llvm::GlobalVariable *GV =
601 new llvm::GlobalVariable(Init->getType(), false,
602 llvm::GlobalValue::InternalLinkage,
603 Init,
604 std::string(Prefix) + TypeName,
605 &CGM.getModule());
606 if (ClassMethods) {
607 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
608 } else {
609 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
610 }
611 UsedGlobals.push_back(GV);
612 return llvm::ConstantExpr::getBitCast(GV,
613 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000614}
615
616void CGObjCMac::GenerateCategory(
617 const char *ClassName,
618 const char *CategoryName,
619 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
620 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
621 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
622 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
623 const llvm::SmallVectorImpl<std::string> &Protocols) {
624 assert(0 && "Cannot generate category for Mac runtime.");
625}
626
627void CGObjCMac::GenerateClass(
628 const char *ClassName,
629 const char *SuperClassName,
630 const int instanceSize,
631 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
632 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
633 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
634 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
635 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
636 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
637 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
638 const llvm::SmallVectorImpl<std::string> &Protocols) {
639 assert(0 && "Cannot generate class for Mac runtime.");
640}
641
642llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000643 // Abuse this interface function as a place to finalize.
644 FinishModule();
645
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000646 return NULL;
647}
648
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000649llvm::Function *CGObjCMac::MethodPreamble(const std::string &ClassName,
650 const std::string &CategoryName,
651 const std::string &MethodName,
652 const llvm::Type *ReturnTy,
653 const llvm::Type *SelfTy,
654 const llvm::Type **ArgTy,
655 unsigned ArgC,
656 bool isClassMethod,
657 bool isVarArg) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000658 assert(0 && "Cannot generate method preamble for Mac runtime.");
659 return 0;
660}
661
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000662/* *** Private Interface *** */
663
664/// EmitImageInfo - Emit the image info marker used to encode some module
665/// level information.
666///
667/// See: <rdr://4810609&4810587&4810587>
668/// struct IMAGE_INFO {
669/// unsigned version;
670/// unsigned flags;
671/// };
672enum ImageInfoFlags {
673 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
674 eImageInfo_GarbageCollected = (1 << 1),
675 eImageInfo_GCOnly = (1 << 2)
676};
677
678void CGObjCMac::EmitImageInfo() {
679 unsigned version = 0; // Version is unused?
680 unsigned flags = 0;
681
682 // FIXME: Fix and continue?
683 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
684 flags |= eImageInfo_GarbageCollected;
685 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
686 flags |= eImageInfo_GCOnly;
687
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000688 // Emitted as int[2];
689 llvm::Constant *values[2] = {
690 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
691 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
692 };
693 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000694 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000695 new llvm::GlobalVariable(AT, true,
696 llvm::GlobalValue::InternalLinkage,
697 llvm::ConstantArray::get(AT, values, 2),
698 "\01L_OBJC_IMAGE_INFO",
699 &CGM.getModule());
700
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000701 if (ObjCABI == 1) {
702 GV->setSection("__OBJC, __image_info,regular");
703 } else {
704 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
705 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000706
707 UsedGlobals.push_back(GV);
708}
709
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000710
711// struct objc_module {
712// unsigned long version;
713// unsigned long size;
714// const char *name;
715// Symtab symtab;
716// };
717
718// FIXME: Get from somewhere
719static const int ModuleVersion = 7;
720
721void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000722 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
723
724 std::vector<llvm::Constant*> Values(4);
725 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
726 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
727 // FIXME: GCC just appears to make up an empty name for this? Why?
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000728 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000729 Values[3] = EmitModuleSymbols();
730
731 llvm::GlobalVariable *GV =
732 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
733 llvm::GlobalValue::InternalLinkage,
734 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
735 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000736 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000737 &CGM.getModule());
738 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
739 UsedGlobals.push_back(GV);
740}
741
742llvm::Constant *CGObjCMac::EmitModuleSymbols() {
743 // FIXME: Is this ever used?
744 llvm::GlobalVariable *GV =
745 new llvm::GlobalVariable(ObjCTypes.SymtabTy, false,
746 llvm::GlobalValue::InternalLinkage,
747 llvm::Constant::getNullValue(ObjCTypes.SymtabTy),
748 "\01L_OBJC_SYMBOLS",
749 &CGM.getModule());
750 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
751 UsedGlobals.push_back(GV);
752 return GV;
753}
754
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000755llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
756 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
757
758 if (!Entry) {
759 llvm::Constant *Casted =
760 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
761 ObjCTypes.SelectorPtrTy);
762 Entry =
763 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
764 llvm::GlobalValue::InternalLinkage,
765 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
766 &CGM.getModule());
767 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
768 UsedGlobals.push_back(Entry);
769 }
770
771 return Builder.CreateLoad(Entry, false, "tmp");
772}
773
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000774llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
775 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000776
777 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000778 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000779 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000780 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000781 llvm::GlobalValue::InternalLinkage,
782 C, "\01L_OBJC_CLASS_NAME_",
783 &CGM.getModule());
784 Entry->setSection("__TEXT,__cstring,cstring_literals");
785 UsedGlobals.push_back(Entry);
786 }
787
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000788 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000789}
790
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000791llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
792 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
793
794 if (!Entry) {
795 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
796 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000797 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000798 llvm::GlobalValue::InternalLinkage,
799 C, "\01L_OBJC_METH_VAR_NAME_",
800 &CGM.getModule());
801 Entry->setSection("__TEXT,__cstring,cstring_literals");
802 UsedGlobals.push_back(Entry);
803 }
804
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000805 return getConstantGEP(Entry, 0, 0);
806}
807
808llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
809 std::string TypeStr;
810 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
811 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
812
813 if (!Entry) {
814 llvm::Constant *C = llvm::ConstantArray::get(TypeStr);
815 Entry =
816 new llvm::GlobalVariable(C->getType(), false,
817 llvm::GlobalValue::InternalLinkage,
818 C, "\01L_OBJC_METH_VAR_TYPE_",
819 &CGM.getModule());
820 Entry->setSection("__TEXT,__cstring,cstring_literals");
821 UsedGlobals.push_back(Entry);
822 }
823
824 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000825}
826
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000827void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000828 EmitModuleInfo();
829
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000830 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000831
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000832 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000833 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000834 e = UsedGlobals.end(); i != e; ++i) {
835 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
836 }
837
838 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
839 llvm::GlobalValue *GV =
840 new llvm::GlobalVariable(AT, false,
841 llvm::GlobalValue::AppendingLinkage,
842 llvm::ConstantArray::get(AT, Used),
843 "llvm.used",
844 &CGM.getModule());
845
846 GV->setSection("llvm.metadata");
847}
848
849/* *** */
850
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000851ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
852 : CGM(cgm),
853 CFStringType(0),
854 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000855 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000856{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000857 CodeGen::CodeGenTypes &Types = CGM.getTypes();
858 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000859
860 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000861 LongTy = Types.ConvertType(Ctx.LongTy);
862 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
863 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000864
865 // FIXME: It would be nice to unify this with the opaque type, so
866 // that the IR comes out a bit cleaner.
867 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
868 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000869
870 SymtabTy = llvm::StructType::get(LongTy,
871 SelectorPtrTy,
872 Types.ConvertType(Ctx.ShortTy),
873 Types.ConvertType(Ctx.ShortTy),
874 NULL);
875 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
876
877 ModuleTy =
878 llvm::StructType::get(LongTy,
879 LongTy,
880 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
881 llvm::PointerType::getUnqual(SymtabTy),
882 NULL);
883 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000884
885 MethodDescriptionTy =
886 llvm::StructType::get(SelectorPtrTy,
887 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
888 NULL);
889 CGM.getModule().addTypeName("struct._objc_method_description",
890 MethodDescriptionTy);
891
892 MethodDescriptionListTy =
893 llvm::StructType::get(IntTy,
894 llvm::ArrayType::get(MethodDescriptionTy, 0),
895 NULL);
896 CGM.getModule().addTypeName("struct._objc_method_description_list",
897 MethodDescriptionListTy);
898 MethodDescriptionListPtrTy =
899 llvm::PointerType::getUnqual(MethodDescriptionListTy);
900
901 PropertyListTy = llvm::OpaqueType::get();
902 CGM.getModule().addTypeName("struct._objc_property_list",
903 PropertyListTy);
904 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
905
906 // Protocol description structures
907
908 ProtocolExtensionTy =
909 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
910 llvm::PointerType::getUnqual(MethodDescriptionListTy),
911 llvm::PointerType::getUnqual(MethodDescriptionListTy),
912 PropertyListPtrTy,
913 NULL);
914 CGM.getModule().addTypeName("struct._objc_protocol_extension",
915 ProtocolExtensionTy);
916 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
917
918 // Handle recursive construction of Protocl and ProtocolList types
919
920 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
921 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
922
923 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
924 LongTy,
925 llvm::ArrayType::get(ProtocolTyHolder, 0),
926 NULL);
927 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
928
929 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
930 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
931 llvm::PointerType::getUnqual(ProtocolListTyHolder),
932 MethodDescriptionListPtrTy,
933 MethodDescriptionListPtrTy,
934 NULL);
935 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
936
937 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
938 CGM.getModule().addTypeName("struct._objc_protocol_list",
939 ProtocolListTy);
940 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
941
942 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
943 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
944 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000945}
946
947ObjCTypesHelper::~ObjCTypesHelper() {
948}
949
950const llvm::StructType *ObjCTypesHelper::getCFStringType() {
951 if (!CFStringType) {
952 CFStringType =
953 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
954 llvm::Type::Int32Ty,
955 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
956 LongTy,
957 NULL);
958
959 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
960 }
961
962 return CFStringType;
963}
964
965llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
966 if (!CFConstantStringClassReference) {
967 llvm::GlobalValue *GV =
968 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
969 false,
970 llvm::GlobalValue::ExternalLinkage,
971 0, "__CFConstantStringClassReference",
972 &CGM.getModule());
973
974 // Decay to pointer.
975 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
976 }
977
978 return CFConstantStringClassReference;
979}
980
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000981llvm::Function *ObjCTypesHelper::getMessageSendFn() {
982 if (!MessageSendFn) {
983 std::vector<const llvm::Type*> Params;
984 Params.push_back(ObjectPtrTy);
985 Params.push_back(SelectorPtrTy);
986 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
987 Params,
988 true),
989 llvm::Function::ExternalLinkage,
990 "objc_msgSend",
991 &CGM.getModule());
992 }
993
994 return MessageSendFn;
995}
996
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000997/* *** */
998
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000999CodeGen::CGObjCRuntime *
1000CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001001 return new CGObjCMac(CGM);
1002}