blob: 7b5db812318e0a7b669776cc306eb90a4c57b4d0 [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 Dunbarb7ec2462008-08-16 03:19:19 +000017#include "CodeGenFunction.h"
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000018#include "clang/AST/ASTContext.h"
Daniel Dunbare91593e2008-08-11 04:54:23 +000019#include "clang/AST/Decl.h"
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000020#include "clang/AST/DeclObjC.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000021#include "clang/Basic/LangOptions.h"
22
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000023#include "llvm/Module.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000024#include "llvm/Support/IRBuilder.h"
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000025#include "llvm/Target/TargetData.h"
Daniel Dunbarb7ec2462008-08-16 03:19:19 +000026#include <sstream>
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000027
28using namespace clang;
29
30namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000031
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000032 // FIXME: We should find a nicer way to make the labels for
33 // metadata, string concatenation is lame.
34
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000035/// ObjCTypesHelper - Helper class that encapsulates lazy
36/// construction of varies types used during ObjC generation.
37class ObjCTypesHelper {
38private:
39 CodeGen::CodeGenModule &CGM;
40
41 const llvm::StructType *CFStringType;
42 llvm::Constant *CFConstantStringClassReference;
Daniel Dunbar14c80b72008-08-23 09:25:55 +000043 llvm::Function *MessageSendFn, *MessageSendStretFn;
44 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000045
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000046public:
Daniel Dunbar27f9d772008-08-21 04:36:09 +000047 const llvm::Type *ShortTy, *IntTy, *LongTy;
48 const llvm::Type *Int8PtrTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000049
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000050 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
51 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000052 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000053 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000054 /// ProtocolPtrTy - LLVM type for external protocol handles
55 /// (typeof(Protocol))
56 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000057
Daniel Dunbare8b470d2008-08-23 04:28:29 +000058 /// SuperTy - LLVM type for struct objc_super.
59 const llvm::StructType *SuperTy;
Daniel Dunbar14c80b72008-08-23 09:25:55 +000060 /// SuperPtrTy - LLVM type for struct objc_super *.
61 const llvm::Type *SuperPtrTy;
Daniel Dunbare8b470d2008-08-23 04:28:29 +000062
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000063 /// SymtabTy - LLVM type for struct objc_symtab.
64 const llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000065 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
66 const llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000067 /// ModuleTy - LLVM type for struct objc_module.
68 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000069
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000070 /// ProtocolTy - LLVM type for struct objc_protocol.
71 const llvm::StructType *ProtocolTy;
72 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
73 const llvm::Type *ProtocolPtrTy;
74 /// ProtocolExtensionTy - LLVM type for struct
75 /// objc_protocol_extension.
76 const llvm::StructType *ProtocolExtensionTy;
77 /// ProtocolExtensionTy - LLVM type for struct
78 /// objc_protocol_extension *.
79 const llvm::Type *ProtocolExtensionPtrTy;
80 /// MethodDescriptionTy - LLVM type for struct
81 /// objc_method_description.
82 const llvm::StructType *MethodDescriptionTy;
83 /// MethodDescriptionListTy - LLVM type for struct
84 /// objc_method_description_list.
85 const llvm::StructType *MethodDescriptionListTy;
86 /// MethodDescriptionListPtrTy - LLVM type for struct
87 /// objc_method_description_list *.
88 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbarc8ef5512008-08-23 00:19:03 +000089 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
90 /// in GCC parlance).
91 const llvm::StructType *PropertyTy;
92 /// PropertyListTy - LLVM type for struct objc_property_list
93 /// (_prop_list_t in GCC parlance).
94 const llvm::StructType *PropertyListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000095 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
96 const llvm::Type *PropertyListPtrTy;
97 /// ProtocolListTy - LLVM type for struct objc_property_list.
98 const llvm::Type *ProtocolListTy;
99 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
100 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000101 /// CategoryTy - LLVM type for struct objc_category.
102 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000103 /// ClassTy - LLVM type for struct objc_class.
104 const llvm::StructType *ClassTy;
105 /// ClassPtrTy - LLVM type for struct objc_class *.
106 const llvm::Type *ClassPtrTy;
107 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
108 const llvm::StructType *ClassExtensionTy;
109 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
110 const llvm::Type *ClassExtensionPtrTy;
111 /// CacheTy - LLVM type for struct objc_cache.
112 const llvm::Type *CacheTy;
113 /// CachePtrTy - LLVM type for struct objc_cache *.
114 const llvm::Type *CachePtrTy;
115 // IvarTy - LLVM type for struct objc_ivar.
116 const llvm::StructType *IvarTy;
117 /// IvarListTy - LLVM type for struct objc_ivar_list.
118 const llvm::Type *IvarListTy;
119 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
120 const llvm::Type *IvarListPtrTy;
121 // MethodTy - LLVM type for struct objc_method.
122 const llvm::StructType *MethodTy;
123 /// MethodListTy - LLVM type for struct objc_method_list.
124 const llvm::Type *MethodListTy;
125 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
126 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000127
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000128public:
129 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
130 ~ObjCTypesHelper();
131
132 llvm::Constant *getCFConstantStringClassReference();
133 const llvm::StructType *getCFStringType();
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000134 llvm::Value *getMessageSendFn(bool IsSuper, const llvm::Type *ReturnTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000135};
136
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000137class CGObjCMac : public CodeGen::CGObjCRuntime {
138private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000139 CodeGen::CodeGenModule &CGM;
140 ObjCTypesHelper ObjCTypes;
141 /// ObjCABI - FIXME: Not sure yet.
142 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000143
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000144 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000145 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000146
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000147 /// MethodVarNames - uniqued method variable names.
148 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
149
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000150 /// MethodVarTypes - uniqued method type signatures. We have to use
151 /// a StringMap here because have no other unique reference.
152 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
153
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000154 /// PropertyNames - uniqued method variable names.
155 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
156
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000157 /// ClassReferences - uniqued class references.
158 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
159
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000160 /// SelectorReferences - uniqued selector references.
161 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
162
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000163 /// Protocols - Protocols for which an objc_protocol structure has
164 /// been emitted. Forward declarations are handled by creating an
165 /// empty structure whose initializer is filled in when/if defined.
166 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
167
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000168 /// DefinedClasses - List of defined classes.
169 std::vector<llvm::GlobalValue*> DefinedClasses;
170
171 /// DefinedCategories - List of defined categories.
172 std::vector<llvm::GlobalValue*> DefinedCategories;
173
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000174 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000175 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000176 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000177
178 /// EmitImageInfo - Emit the image info marker used to encode some module
179 /// level information.
180 void EmitImageInfo();
181
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000182 /// EmitModuleInfo - Another marker encoding module level
183 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000184 void EmitModuleInfo();
185
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000186 /// EmitModuleSymols - Emit module symbols, the list of defined
187 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000188 llvm::Constant *EmitModuleSymbols();
189
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000190 /// FinishModule - Write out global data structures at the end of
191 /// processing a translation unit.
192 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000193
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000194 /// EmitClassExtension - Generate the class extension structure used
195 /// to store the weak ivar layout and properties. The return value
196 /// has type ClassExtensionPtrTy.
197 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
198
199 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
200 /// for the given class.
201 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
202 const ObjCInterfaceDecl *ID);
203
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000204 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
205 const ObjCMessageExpr *E,
206 llvm::Value *Arg0,
207 bool IsSuper);
208
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000209 /// EmitIvarList - Emit the ivar list for the given
210 /// implementation. If ForClass is true the list of class ivars
211 /// (i.e. metaclass ivars) is emitted, otherwise the list of
212 /// interface ivars will be emitted. The return value has type
213 /// IvarListPtrTy.
214 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
215 bool ForClass,
216 const llvm::Type *InterfaceTy);
217
218 /// EmitMetaClass - Emit a class structure for the metaclass of the
219 /// given implementation. return value has type ClassPtrTy.
220 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
221 llvm::Constant *Protocols,
222 const llvm::Type *InterfaceTy);
223
224 /// EmitMethodList - Emit the method list for the given
225 /// implementation. If ForClass is true the list of class methods
226 /// will be emitted, otherwise the list of instance methods will be
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000227 /// generated. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000228 llvm::Constant *EmitMethodList(const std::string &Name,
229 const char *Section,
230 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
231 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000232
233 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000234 /// method declarations.
235 /// - TypeName: The name for the type containing the methods.
236 /// - IsProtocol: True iff these methods are for a protocol.
237 /// - ClassMethds: True iff these are class methods.
238 /// - Required: When true, only "required" methods are
239 /// listed. Similarly, when false only "optional" methods are
240 /// listed. For classes this should always be true.
241 /// - begin, end: The method list to output.
242 ///
243 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000244 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
245 bool IsProtocol,
246 bool ClassMethods,
247 bool Required,
248 ObjCMethodDecl * const *begin,
249 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000250
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000251 /// EmitPropertyList - Emit the given property list. The return
252 /// value has type PropertyListPtrTy.
253 llvm::Constant *EmitPropertyList(const std::string &Name,
254 ObjCPropertyDecl * const *begin,
255 ObjCPropertyDecl * const *end);
256
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000257 /// EmitProtocolExtension - Generate the protocol extension
258 /// structure used to store optional instance and class methods, and
259 /// protocol properties. The return value has type
260 /// ProtocolExtensionPtrTy.
261 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
262
263 /// EmitProtocolList - Generate the list of referenced
264 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc933702008-08-21 21:57:41 +0000265 llvm::Constant *EmitProtocolList(const std::string &Name,
266 ObjCProtocolDecl::protocol_iterator begin,
267 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000268
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000269 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
270 /// for the given selector.
271 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
272
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000273 /// GetProtocolRef - Return a reference to the internal protocol
274 /// description, creating an empty one if it has not been
275 /// defined. The return value has type pointer-to ProtocolTy.
276 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
277
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000278 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000279 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000280 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000281
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000282 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000283 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000284 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000285 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000286 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000287
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000288 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000289 /// selector's name. The return value has type char *.
290
291 // FIXME: This is a horrible name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000292 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000293 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000294
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000295 /// GetPropertyName - Return a unique constant for the given
296 /// name. The return value has type char *.
297 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
298
299 // FIXME: This is a horrible name too.
300 llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
301
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000302 /// GetNameForMethod - Return a name for the given method.
303 /// \param[out] NameOut - The return value.
304 void GetNameForMethod(const ObjCMethodDecl *OMD,
305 std::string &NameOut);
306
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000307public:
308 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000309 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000310
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000311 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
312 const ObjCMessageExpr *E,
313 llvm::Value *Receiver);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000314
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000315 virtual CodeGen::RValue
316 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
317 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000318 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000319 llvm::Value *Receiver);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000320
321 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000322 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000323
324 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
325
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000326 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000327
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000328 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000329
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000330 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000331
332 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000333 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000334
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000335 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000336
337 virtual llvm::Function *ModuleInitFunction();
338};
339} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000340
341/* *** Helper Functions *** */
342
343/// getConstantGEP() - Help routine to construct simple GEPs.
344static llvm::Constant *getConstantGEP(llvm::Constant *C,
345 unsigned idx0,
346 unsigned idx1) {
347 llvm::Value *Idxs[] = {
348 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
349 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
350 };
351 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
352}
353
354/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000355
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000356CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
357 : CGM(cgm),
358 ObjCTypes(cgm),
359 ObjCABI(1)
360{
361 // FIXME: How does this get set in GCC? And what does it even mean?
362 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
363 ObjCABI = 2;
364
365 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000366}
367
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000368/// GetClass - Return a reference to the class for the given interface
369/// decl.
370llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000371 const ObjCInterfaceDecl *ID) {
372 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000373}
374
375/// GetSelector - Return the pointer to the unique'd string for this selector.
376llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000377 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000378}
379
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000380/// Generate a constant CFString object.
381/*
382 struct __builtin_CFString {
383 const int *isa; // point to __CFConstantStringClassReference
384 int flags;
385 const char *str;
386 long length;
387 };
388*/
389
390llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
391 // FIXME: I have no idea what this constant is (it is a magic
392 // constant in GCC as well). Most likely the encoding of the string
393 // and at least one part of it relates to UTF-16. Is this just the
394 // code for UTF-8? Where is this handled for us?
395 // See: <rdr://2996215>
396 unsigned flags = 0x07c8;
397
398 // FIXME: Use some machinery to unique this. We can't reuse the CGM
399 // one since we put them in a different section.
400 llvm::Constant *StringC = llvm::ConstantArray::get(String);
401 llvm::Constant *StringGV =
402 new llvm::GlobalVariable(StringC->getType(), true,
403 llvm::GlobalValue::InternalLinkage,
404 StringC, ".str", &CGM.getModule());
405 llvm::Constant *Values[4] = {
406 ObjCTypes.getCFConstantStringClassReference(),
407 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
408 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
409 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
410 };
411
412 llvm::Constant *CFStringC =
413 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
414 std::vector<llvm::Constant*>(Values, Values+4));
415
416 llvm::GlobalVariable *CFStringGV =
417 new llvm::GlobalVariable(CFStringC->getType(), true,
418 llvm::GlobalValue::InternalLinkage,
419 CFStringC, "",
420 &CGM.getModule());
421
422 CFStringGV->setSection("__DATA, __cfstring");
423
424 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000425}
426
427/// Generates a message send where the super is the receiver. This is
428/// a message send to self with special delivery semantics indicating
429/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000430CodeGen::RValue
431CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
432 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000433 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000434 llvm::Value *Receiver) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000435 // FIXME: This should be cached, not looked up every time. Meh. We
436 // should just make sure the optimizer hits it.
437 llvm::Value *ReceiverClass = EmitClassRef(CGF.Builder, SuperClass);
438
439 // Create and init a super structure; this is a (receiver, class)
440 // pair we will pass to objc_msgSendSuper.
441 llvm::Value *ObjCSuper =
442 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
443 llvm::Value *ReceiverAsObject =
444 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
445 CGF.Builder.CreateStore(ReceiverAsObject,
446 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
447 CGF.Builder.CreateStore(ReceiverClass,
448 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
449
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000450 return EmitMessageSend(CGF, E, ObjCSuper, true);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000451}
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000452
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000453/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000454CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
455 const ObjCMessageExpr *E,
456 llvm::Value *Receiver) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000457 llvm::Value *Arg0 =
458 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
459 return EmitMessageSend(CGF, E, Arg0, false);
460}
461
462CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
463 const ObjCMessageExpr *E,
464 llvm::Value *Arg0,
465 bool IsSuper) {
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000466 llvm::Value *Args[2];
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000467 Args[0] = Arg0;
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000468 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000469
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000470 // FIXME: This is a hack, we are implicitly coordinating with
471 // EmitCallExprExt, which will move the return type to the first
472 // parameter and set the structure return flag. See
473 // getMessageSendFn().
474
475
476 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
477 return CGF.EmitCallExprExt(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),
478 E->getType(),
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000479 E->arg_begin(),
480 E->arg_end(),
481 Args, 2);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000482}
483
484llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000485 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000486 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
487 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000488}
489
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000490/*
491 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
492 struct _objc_protocol {
493 struct _objc_protocol_extension *isa;
494 char *protocol_name;
495 struct _objc_protocol_list *protocol_list;
496 struct _objc__method_prototype_list *instance_methods;
497 struct _objc__method_prototype_list *class_methods
498 };
499
500 See EmitProtocolExtension().
501*/
502void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
503 const char *ProtocolName = PD->getName();
504
505 std::vector<llvm::Constant*> Values(5);
506 Values[0] = EmitProtocolExtension(PD);
507 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000508 Values[2] =
509 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
510 PD->protocol_begin(),
511 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000512 Values[3] = EmitMethodDescList(ProtocolName,
513 true, // IsProtocol
514 false, // ClassMethods
515 true, // Required
516 PD->instmeth_begin(),
517 PD->instmeth_end());
518 Values[4] = EmitMethodDescList(ProtocolName,
519 true, // IsProtocol
520 true, // ClassMethods
521 true, // Required
522 PD->classmeth_begin(),
523 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000524 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
525 Values);
526
527 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
528 if (Entry) {
529 // Already created, just update the initializer
530 Entry->setInitializer(Init);
531 } else {
532 Entry =
533 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
534 llvm::GlobalValue::InternalLinkage,
535 Init,
536 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
537 &CGM.getModule());
538 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
539 UsedGlobals.push_back(Entry);
540 // FIXME: Is this necessary? Why only for protocol?
541 Entry->setAlignment(4);
542 }
543}
544
545llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
546 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
547
548 if (!Entry) {
549 std::vector<llvm::Constant*> Values(5);
550 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
551 Values[1] = GetClassName(PD->getIdentifier());
552 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
553 Values[3] = Values[4] =
554 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
555 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
556 Values);
557
558 Entry =
559 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
560 llvm::GlobalValue::InternalLinkage,
561 Init,
562 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
563 &CGM.getModule());
564 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
565 UsedGlobals.push_back(Entry);
566 // FIXME: Is this necessary? Why only for protocol?
567 Entry->setAlignment(4);
568 }
569
570 return Entry;
571}
572
573/*
574 struct _objc_protocol_extension {
575 uint32_t size;
576 struct objc_method_description_list *optional_instance_methods;
577 struct objc_method_description_list *optional_class_methods;
578 struct objc_property_list *instance_properties;
579 };
580*/
581llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
582 uint64_t Size =
583 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
584 std::vector<llvm::Constant*> Values(4);
585 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000586 Values[1] = EmitMethodDescList(PD->getName(),
587 true, // IsProtocol
588 false, // ClassMethods
589 false, // Required
590 PD->instmeth_begin(),
591 PD->instmeth_end());
592 Values[2] = EmitMethodDescList(PD->getName(),
593 true, // IsProtocol
594 true, // ClassMethods
595 false, // Required
596 PD->classmeth_begin(),
597 PD->classmeth_end());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000598 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
599 PD->getName(),
600 PD->classprop_begin(),
601 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000602
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000603 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000604 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
605 Values[3]->isNullValue())
606 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
607
608 llvm::Constant *Init =
609 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
610 llvm::GlobalVariable *GV =
611 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
612 llvm::GlobalValue::InternalLinkage,
613 Init,
614 (std::string("\01L_OBJC_PROTOCOLEXT_") +
615 PD->getName()),
616 &CGM.getModule());
617 // No special section, but goes in llvm.used
618 UsedGlobals.push_back(GV);
619
620 return GV;
621}
622
623/*
624 struct objc_protocol_list {
625 struct objc_protocol_list *next;
626 long count;
627 Protocol *list[];
628 };
629*/
Daniel Dunbardbc933702008-08-21 21:57:41 +0000630llvm::Constant *
631CGObjCMac::EmitProtocolList(const std::string &Name,
632 ObjCProtocolDecl::protocol_iterator begin,
633 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000634 std::vector<llvm::Constant*> ProtocolRefs;
635
Daniel Dunbardbc933702008-08-21 21:57:41 +0000636 for (; begin != end; ++begin)
637 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000638
639 // Just return null for empty protocol lists
640 if (ProtocolRefs.empty())
641 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
642
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000643 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000644 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
645
646 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000647 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000648 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
649 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
650 Values[2] =
651 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
652 ProtocolRefs.size()),
653 ProtocolRefs);
654
655 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
656 llvm::GlobalVariable *GV =
657 new llvm::GlobalVariable(Init->getType(), false,
658 llvm::GlobalValue::InternalLinkage,
659 Init,
Daniel Dunbardbc933702008-08-21 21:57:41 +0000660 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000661 &CGM.getModule());
662 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
663 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
664}
665
666/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000667 struct _objc_property {
668 const char * const name;
669 const char * const attributes;
670 };
671
672 struct _objc_property_list {
673 uint32_t entsize; // sizeof (struct _objc_property)
674 uint32_t prop_count;
675 struct _objc_property[prop_count];
676 };
677*/
678llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
679 ObjCPropertyDecl * const *begin,
680 ObjCPropertyDecl * const *end) {
681 std::vector<llvm::Constant*> Properties, Prop(2);
682 for (; begin != end; ++begin) {
683 const ObjCPropertyDecl *PD = *begin;
684 Prop[0] = GetPropertyName(PD->getIdentifier());
685 Prop[1] = GetPropertyType(PD);
686 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
687 Prop));
688 }
689
690 // Return null for empty list.
691 if (Properties.empty())
692 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
693
694 unsigned PropertySize =
695 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
696 std::vector<llvm::Constant*> Values(3);
697 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
698 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
699 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
700 Properties.size());
701 Values[2] = llvm::ConstantArray::get(AT, Properties);
702 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
703
704 llvm::GlobalVariable *GV =
705 new llvm::GlobalVariable(Init->getType(), false,
706 llvm::GlobalValue::InternalLinkage,
707 Init,
708 Name,
709 &CGM.getModule());
710 // No special section on property lists?
711 UsedGlobals.push_back(GV);
712 return llvm::ConstantExpr::getBitCast(GV,
713 ObjCTypes.PropertyListPtrTy);
714
715}
716
717/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000718 struct objc_method_description_list {
719 int count;
720 struct objc_method_description list[];
721 };
722*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000723llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
724 bool IsProtocol,
725 bool ClassMethods,
726 bool Required,
727 ObjCMethodDecl * const *begin,
728 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000729 std::vector<llvm::Constant*> Methods, Desc(2);
730 for (; begin != end; ++begin) {
731 ObjCMethodDecl *D = *begin;
732 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
733
734 // Skip if this method is required and we are outputting optional
735 // methods, or vice versa.
736 if (Required != IsRequired)
737 continue;
738
739 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
740 ObjCTypes.SelectorPtrTy);
741 Desc[1] = GetMethodVarType(D);
742 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
743 Desc));
744 }
745
746 // Return null for empty list.
747 if (Methods.empty())
748 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
749
750 std::vector<llvm::Constant*> Values(2);
751 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
752 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
753 Methods.size());
754 Values[1] = llvm::ConstantArray::get(AT, Methods);
755 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
756
757 char Prefix[256];
758 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
759 IsProtocol ? "PROTOCOL_" : "",
760 ClassMethods ? "CLASS_" : "INSTANCE_",
761 !Required ? "OPT_" : "");
762 llvm::GlobalVariable *GV =
763 new llvm::GlobalVariable(Init->getType(), false,
764 llvm::GlobalValue::InternalLinkage,
765 Init,
766 std::string(Prefix) + TypeName,
767 &CGM.getModule());
768 if (ClassMethods) {
769 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
770 } else {
771 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
772 }
773 UsedGlobals.push_back(GV);
774 return llvm::ConstantExpr::getBitCast(GV,
775 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000776}
777
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000778/*
779 struct _objc_category {
780 char *category_name;
781 char *class_name;
782 struct _objc_method_list *instance_methods;
783 struct _objc_method_list *class_methods;
784 struct _objc_protocol_list *protocols;
785 uint32_t size; // <rdar://4585769>
786 struct _objc_property_list *instance_properties;
787 };
788 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000789void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000790 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
791
792 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
793 std::string ExtName(std::string(Interface->getName()) +
794 "_" +
795 OCD->getName());
796
797 std::vector<llvm::Constant*> Values(7);
798 Values[0] = GetClassName(OCD->getIdentifier());
799 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000800 Values[2] =
801 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
802 ExtName,
803 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
804 OCD->instmeth_begin(),
805 OCD->instmeth_end());
806 Values[3] =
807 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
808 "__OBJC,__cat_class_meth,regular,no_dead_strip",
809 OCD->classmeth_begin(),
810 OCD->classmeth_end());
811 Values[4] =
812 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
813 Interface->protocol_begin(),
814 Interface->protocol_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000815 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000816 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
817 Interface->classprop_begin(),
818 Interface->classprop_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000819
820 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
821 Values);
822
823 llvm::GlobalVariable *GV =
824 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
825 llvm::GlobalValue::InternalLinkage,
826 Init,
827 std::string("\01L_OBJC_CATEGORY_")+ExtName,
828 &CGM.getModule());
829 GV->setSection("__OBJC,__category,regular,no_dead_strip");
830 UsedGlobals.push_back(GV);
831 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000832}
833
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000834// FIXME: Get from somewhere?
835enum ClassFlags {
836 eClassFlags_Factory = 0x00001,
837 eClassFlags_Meta = 0x00002,
838 // <rdr://5142207>
839 eClassFlags_HasCXXStructors = 0x02000,
840 eClassFlags_Hidden = 0x20000,
841 eClassFlags_ABI2_Hidden = 0x00010,
842 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
843};
844
845// <rdr://5142207&4705298&4843145>
846static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
847 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
848 // FIXME: Support -fvisibility
849 switch (attr->getVisibility()) {
850 default:
851 assert(0 && "Unknown visibility");
852 return false;
853 case VisibilityAttr::DefaultVisibility:
854 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
855 return false;
856 case VisibilityAttr::HiddenVisibility:
857 return true;
858 }
859 } else {
860 return false; // FIXME: Support -fvisibility
861 }
862}
863
864/*
865 struct _objc_class {
866 Class isa;
867 Class super_class;
868 const char *name;
869 long version;
870 long info;
871 long instance_size;
872 struct _objc_ivar_list *ivars;
873 struct _objc_method_list *methods;
874 struct _objc_cache *cache;
875 struct _objc_protocol_list *protocols;
876 // Objective-C 1.0 extensions (<rdr://4585769>)
877 const char *ivar_layout;
878 struct _objc_class_ext *ext;
879 };
880
881 See EmitClassExtension();
882 */
883void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
884 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000885 // FIXME: Gross
886 ObjCInterfaceDecl *Interface =
887 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000888 llvm::Constant *Protocols =
889 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
890 Interface->protocol_begin(),
891 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000892 const llvm::Type *InterfaceTy =
893 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
894 unsigned Flags = eClassFlags_Factory;
895 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
896
897 // FIXME: Set CXX-structors flag.
898 if (IsClassHidden(ID->getClassInterface()))
899 Flags |= eClassFlags_Hidden;
900
901 std::vector<llvm::Constant*> Values(12);
902 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
903 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
904 Values[ 1] =
905 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
906 ObjCTypes.ClassPtrTy);
907 } else {
908 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
909 }
910 Values[ 2] = GetClassName(ID->getIdentifier());
911 // Version is always 0.
912 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
913 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
914 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
915 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000916 Values[ 7] =
917 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
918 "__OBJC,__inst_meth,regular,no_dead_strip",
919 ID->instmeth_begin(),
920 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000921 // cache is always NULL.
922 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
923 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000924 // FIXME: Set ivar_layout
925 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000926 Values[11] = EmitClassExtension(ID);
927 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
928 Values);
929
930 llvm::GlobalVariable *GV =
931 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
932 llvm::GlobalValue::InternalLinkage,
933 Init,
934 std::string("\01L_OBJC_CLASS_")+ClassName,
935 &CGM.getModule());
936 GV->setSection("__OBJC,__class,regular,no_dead_strip");
937 UsedGlobals.push_back(GV);
938 // FIXME: Why?
939 GV->setAlignment(32);
940 DefinedClasses.push_back(GV);
941}
942
943llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
944 llvm::Constant *Protocols,
945 const llvm::Type *InterfaceTy) {
946 const char *ClassName = ID->getName();
947 unsigned Flags = eClassFlags_Meta;
948 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
949
950 if (IsClassHidden(ID->getClassInterface()))
951 Flags |= eClassFlags_Hidden;
952
953 std::vector<llvm::Constant*> Values(12);
954 // The isa for the metaclass is the root of the hierarchy.
955 const ObjCInterfaceDecl *Root = ID->getClassInterface();
956 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
957 Root = Super;
958 Values[ 0] =
959 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
960 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000961 // The super class for the metaclass is emitted as the name of the
962 // super class. The runtime fixes this up to point to the
963 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000964 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
965 Values[ 1] =
966 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
967 ObjCTypes.ClassPtrTy);
968 } else {
969 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
970 }
971 Values[ 2] = GetClassName(ID->getIdentifier());
972 // Version is always 0.
973 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
974 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
975 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
976 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000977 Values[ 7] =
978 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
979 "__OBJC,__inst_meth,regular,no_dead_strip",
980 ID->classmeth_begin(),
981 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000982 // cache is always NULL.
983 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
984 Values[ 9] = Protocols;
985 // ivar_layout for metaclass is always NULL.
986 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
987 // The class extension is always unused for metaclasses.
988 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
989 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
990 Values);
991
992 llvm::GlobalVariable *GV =
993 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
994 llvm::GlobalValue::InternalLinkage,
995 Init,
996 std::string("\01L_OBJC_METACLASS_")+ClassName,
997 &CGM.getModule());
998 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
999 UsedGlobals.push_back(GV);
1000 // FIXME: Why?
1001 GV->setAlignment(32);
1002
1003 return GV;
1004}
1005
1006/*
1007 struct objc_class_ext {
1008 uint32_t size;
1009 const char *weak_ivar_layout;
1010 struct _objc_property_list *properties;
1011 };
1012*/
1013llvm::Constant *
1014CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1015 uint64_t Size =
1016 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1017
1018 std::vector<llvm::Constant*> Values(3);
1019 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001020 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001021 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001022 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1023 ID->getName(),
1024 ID->getClassInterface()->classprop_begin(),
1025 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001026
1027 // Return null if no extension bits are used.
1028 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1029 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1030
1031 llvm::Constant *Init =
1032 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1033 llvm::GlobalVariable *GV =
1034 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1035 llvm::GlobalValue::InternalLinkage,
1036 Init,
1037 (std::string("\01L_OBJC_CLASSEXT_") +
1038 ID->getName()),
1039 &CGM.getModule());
1040 // No special section, but goes in llvm.used
1041 UsedGlobals.push_back(GV);
1042
1043 return GV;
1044}
1045
1046/*
1047 struct objc_ivar {
1048 char *ivar_name;
1049 char *ivar_type;
1050 int ivar_offset;
1051 };
1052
1053 struct objc_ivar_list {
1054 int ivar_count;
1055 struct objc_ivar list[count];
1056 };
1057 */
1058llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1059 bool ForClass,
1060 const llvm::Type *InterfaceTy) {
1061 std::vector<llvm::Constant*> Ivars, Ivar(3);
1062
1063 // When emitting the root class GCC emits ivar entries for the
1064 // actual class structure. It is not clear if we need to follow this
1065 // behavior; for now lets try and get away with not doing it. If so,
1066 // the cleanest solution would be to make up an ObjCInterfaceDecl
1067 // for the class.
1068 if (ForClass)
1069 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1070
1071 const llvm::StructLayout *Layout =
1072 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1073 for (ObjCInterfaceDecl::ivar_iterator
1074 i = ID->getClassInterface()->ivar_begin(),
1075 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1076 ObjCIvarDecl *V = *i;
1077 unsigned Offset =
1078 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1079 std::string TypeStr;
1080 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1081 Ivar[0] = GetMethodVarName(V->getIdentifier());
1082 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1083 EncodingRecordTypes);
1084 Ivar[1] = GetMethodVarType(TypeStr);
1085 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1086 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1087 Ivar));
1088 }
1089
1090 // Return null for empty list.
1091 if (Ivars.empty())
1092 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1093
1094 std::vector<llvm::Constant*> Values(2);
1095 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1096 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1097 Ivars.size());
1098 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1099 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1100
1101 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1102 "\01L_OBJC_INSTANCE_VARIABLES_");
1103 llvm::GlobalVariable *GV =
1104 new llvm::GlobalVariable(Init->getType(), false,
1105 llvm::GlobalValue::InternalLinkage,
1106 Init,
1107 std::string(Prefix) + ID->getName(),
1108 &CGM.getModule());
1109 if (ForClass) {
1110 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1111 // FIXME: Why is this only here?
1112 GV->setAlignment(32);
1113 } else {
1114 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1115 }
1116 UsedGlobals.push_back(GV);
1117 return llvm::ConstantExpr::getBitCast(GV,
1118 ObjCTypes.IvarListPtrTy);
1119}
1120
1121/*
1122 struct objc_method {
1123 SEL method_name;
1124 char *method_types;
1125 void *method;
1126 };
1127
1128 struct objc_method_list {
1129 struct objc_method_list *obsolete;
1130 int count;
1131 struct objc_method methods_list[count];
1132 };
1133*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001134llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1135 const char *Section,
1136 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1137 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001138 std::vector<llvm::Constant*> Methods, Method(3);
1139
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001140 for (; begin != end; ++begin) {
1141 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001142
1143 Method[0] =
1144 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1145 ObjCTypes.SelectorPtrTy);
1146 Method[1] = GetMethodVarType(MD);
1147
1148 // FIXME: This is gross, we shouldn't be looking up by name.
1149 std::string Name;
1150 GetNameForMethod(MD, Name);
1151 Method[2] =
1152 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1153 ObjCTypes.Int8PtrTy);
1154 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1155 Method));
1156 }
1157
1158 // Return null for empty list.
1159 if (Methods.empty())
1160 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1161
1162 std::vector<llvm::Constant*> Values(3);
1163 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1164 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1165 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1166 Methods.size());
1167 Values[2] = llvm::ConstantArray::get(AT, Methods);
1168 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1169
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001170 llvm::GlobalVariable *GV =
1171 new llvm::GlobalVariable(Init->getType(), false,
1172 llvm::GlobalValue::InternalLinkage,
1173 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001174 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001175 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001176 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001177 UsedGlobals.push_back(GV);
1178 return llvm::ConstantExpr::getBitCast(GV,
1179 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001180}
1181
1182llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1183 const llvm::Type *ReturnTy =
1184 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1185 const llvm::Type *SelfTy =
1186 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1187
1188 std::vector<const llvm::Type*> ArgTys;
1189 ArgTys.reserve(1 + 2 + OMD->param_size());
1190
1191 // FIXME: This is not something we should have to be dealing with
1192 // here.
1193 bool useStructRet =
1194 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1195 if (useStructRet) {
1196 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1197 ReturnTy = llvm::Type::VoidTy;
1198 }
1199
1200 // Implicit arguments
1201 ArgTys.push_back(SelfTy);
1202 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1203
1204 for (ObjCMethodDecl::param_const_iterator
1205 i = OMD->param_begin(), e = OMD->param_end();
1206 i != e; ++i) {
1207 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001208 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001209 ArgTys.push_back(Ty);
1210 } else {
1211 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1212 }
1213 }
1214
1215 std::string Name;
1216 GetNameForMethod(OMD, Name);
1217
1218 llvm::Function *Method =
1219 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1220 ArgTys,
1221 OMD->isVariadic()),
1222 llvm::GlobalValue::InternalLinkage,
1223 Name,
1224 &CGM.getModule());
1225
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001226 unsigned Offset = 3; // Return plus self and selector implicit args.
1227 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001228 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001229 ++Offset;
1230 }
1231
1232 // FIXME: This is horrible, we need to be reusing the machinery in
1233 // CodeGenModule.cpp (SetFunctionAttributes).
1234 for (ObjCMethodDecl::param_const_iterator
1235 i = OMD->param_begin(), e = OMD->param_end();
1236 i != e; ++i, ++Offset) {
1237 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1238 if (!Ty->isSingleValueType())
1239 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1240 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001241
1242 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001243}
1244
1245llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001246 // Abuse this interface function as a place to finalize.
1247 FinishModule();
1248
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001249 return NULL;
1250}
1251
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001252/* *** Private Interface *** */
1253
1254/// EmitImageInfo - Emit the image info marker used to encode some module
1255/// level information.
1256///
1257/// See: <rdr://4810609&4810587&4810587>
1258/// struct IMAGE_INFO {
1259/// unsigned version;
1260/// unsigned flags;
1261/// };
1262enum ImageInfoFlags {
1263 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1264 eImageInfo_GarbageCollected = (1 << 1),
1265 eImageInfo_GCOnly = (1 << 2)
1266};
1267
1268void CGObjCMac::EmitImageInfo() {
1269 unsigned version = 0; // Version is unused?
1270 unsigned flags = 0;
1271
1272 // FIXME: Fix and continue?
1273 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1274 flags |= eImageInfo_GarbageCollected;
1275 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1276 flags |= eImageInfo_GCOnly;
1277
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001278 // Emitted as int[2];
1279 llvm::Constant *values[2] = {
1280 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1281 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1282 };
1283 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001284 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001285 new llvm::GlobalVariable(AT, true,
1286 llvm::GlobalValue::InternalLinkage,
1287 llvm::ConstantArray::get(AT, values, 2),
1288 "\01L_OBJC_IMAGE_INFO",
1289 &CGM.getModule());
1290
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001291 if (ObjCABI == 1) {
1292 GV->setSection("__OBJC, __image_info,regular");
1293 } else {
1294 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1295 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001296
1297 UsedGlobals.push_back(GV);
1298}
1299
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001300
1301// struct objc_module {
1302// unsigned long version;
1303// unsigned long size;
1304// const char *name;
1305// Symtab symtab;
1306// };
1307
1308// FIXME: Get from somewhere
1309static const int ModuleVersion = 7;
1310
1311void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001312 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1313
1314 std::vector<llvm::Constant*> Values(4);
1315 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1316 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001317 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001318 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001319 Values[3] = EmitModuleSymbols();
1320
1321 llvm::GlobalVariable *GV =
1322 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1323 llvm::GlobalValue::InternalLinkage,
1324 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1325 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001326 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001327 &CGM.getModule());
1328 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1329 UsedGlobals.push_back(GV);
1330}
1331
1332llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001333 std::vector<llvm::Constant*> Values(5);
1334 unsigned NumClasses = DefinedClasses.size();
1335 unsigned NumCategories = DefinedCategories.size();
1336
1337 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1338 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1339 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1340 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1341
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001342 // The runtime expects exactly the list of defined classes followed
1343 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001344 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001345 for (unsigned i=0; i<NumClasses; i++)
1346 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1347 ObjCTypes.Int8PtrTy);
1348 for (unsigned i=0; i<NumCategories; i++)
1349 Symbols[NumClasses + i] =
1350 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1351 ObjCTypes.Int8PtrTy);
1352
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001353 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001354 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001355 NumClasses + NumCategories),
1356 Symbols);
1357
1358 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1359
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001360 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001361 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001362 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001363 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001364 "\01L_OBJC_SYMBOLS",
1365 &CGM.getModule());
1366 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1367 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001368 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1369}
1370
1371llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1372 const ObjCInterfaceDecl *ID) {
1373 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1374
1375 if (!Entry) {
1376 llvm::Constant *Casted =
1377 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1378 ObjCTypes.ClassPtrTy);
1379 Entry =
1380 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1381 llvm::GlobalValue::InternalLinkage,
1382 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1383 &CGM.getModule());
1384 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1385 UsedGlobals.push_back(Entry);
1386 }
1387
1388 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001389}
1390
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001391llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1392 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1393
1394 if (!Entry) {
1395 llvm::Constant *Casted =
1396 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1397 ObjCTypes.SelectorPtrTy);
1398 Entry =
1399 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1400 llvm::GlobalValue::InternalLinkage,
1401 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1402 &CGM.getModule());
1403 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1404 UsedGlobals.push_back(Entry);
1405 }
1406
1407 return Builder.CreateLoad(Entry, false, "tmp");
1408}
1409
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001410llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1411 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001412
1413 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001414 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001415 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001416 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001417 llvm::GlobalValue::InternalLinkage,
1418 C, "\01L_OBJC_CLASS_NAME_",
1419 &CGM.getModule());
1420 Entry->setSection("__TEXT,__cstring,cstring_literals");
1421 UsedGlobals.push_back(Entry);
1422 }
1423
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001424 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001425}
1426
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001427llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1428 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1429
1430 if (!Entry) {
1431 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1432 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001433 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001434 llvm::GlobalValue::InternalLinkage,
1435 C, "\01L_OBJC_METH_VAR_NAME_",
1436 &CGM.getModule());
1437 Entry->setSection("__TEXT,__cstring,cstring_literals");
1438 UsedGlobals.push_back(Entry);
1439 }
1440
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001441 return getConstantGEP(Entry, 0, 0);
1442}
1443
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001444// FIXME: Merge into a single cstring creation function.
1445llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1446 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1447}
1448
1449// FIXME: Merge into a single cstring creation function.
1450llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1451 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1452}
1453
1454llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1455 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001456
1457 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001458 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001459 Entry =
1460 new llvm::GlobalVariable(C->getType(), false,
1461 llvm::GlobalValue::InternalLinkage,
1462 C, "\01L_OBJC_METH_VAR_TYPE_",
1463 &CGM.getModule());
1464 Entry->setSection("__TEXT,__cstring,cstring_literals");
1465 UsedGlobals.push_back(Entry);
1466 }
1467
1468 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001469}
1470
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001471// FIXME: Merge into a single cstring creation function.
1472llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1473 std::string TypeStr;
1474 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1475 return GetMethodVarType(TypeStr);
1476}
1477
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001478// FIXME: Merge into a single cstring creation function.
1479llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1480 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1481
1482 if (!Entry) {
1483 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1484 Entry =
1485 new llvm::GlobalVariable(C->getType(), false,
1486 llvm::GlobalValue::InternalLinkage,
1487 C, "\01L_OBJC_PROP_NAME_ATTR_",
1488 &CGM.getModule());
1489 Entry->setSection("__TEXT,__cstring,cstring_literals");
1490 UsedGlobals.push_back(Entry);
1491 }
1492
1493 return getConstantGEP(Entry, 0, 0);
1494}
1495
1496// FIXME: Merge into a single cstring creation function.
1497llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1498 std::string TypeStr("MOOO!");
1499 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1500 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1501}
1502
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001503void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1504 std::string &NameOut) {
1505 // FIXME: Find the mangling GCC uses.
1506 std::stringstream s;
1507 s << (D->isInstance() ? "-" : "+");
1508 s << "[";
1509 s << D->getClassInterface()->getName();
1510 s << " ";
1511 s << D->getSelector().getName();
1512 s << "]";
1513 NameOut = s.str();
1514}
1515
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001516void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001517 EmitModuleInfo();
1518
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001519 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001520
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001521 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001522 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001523 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001524 }
1525
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001526 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001527 llvm::GlobalValue *GV =
1528 new llvm::GlobalVariable(AT, false,
1529 llvm::GlobalValue::AppendingLinkage,
1530 llvm::ConstantArray::get(AT, Used),
1531 "llvm.used",
1532 &CGM.getModule());
1533
1534 GV->setSection("llvm.metadata");
1535}
1536
1537/* *** */
1538
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001539ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
1540 : CGM(cgm),
1541 CFStringType(0),
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001542 CFConstantStringClassReference(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001543{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001544 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1545 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001546
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001547 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001548 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001549 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001550 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1551
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001552 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1553 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001554
1555 // FIXME: It would be nice to unify this with the opaque type, so
1556 // that the IR comes out a bit cleaner.
1557 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1558 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001559
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001560 MethodDescriptionTy =
1561 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001562 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001563 NULL);
1564 CGM.getModule().addTypeName("struct._objc_method_description",
1565 MethodDescriptionTy);
1566
1567 MethodDescriptionListTy =
1568 llvm::StructType::get(IntTy,
1569 llvm::ArrayType::get(MethodDescriptionTy, 0),
1570 NULL);
1571 CGM.getModule().addTypeName("struct._objc_method_description_list",
1572 MethodDescriptionListTy);
1573 MethodDescriptionListPtrTy =
1574 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1575
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001576 PropertyTy = llvm::StructType::get(Int8PtrTy,
1577 Int8PtrTy,
1578 NULL);
1579 CGM.getModule().addTypeName("struct._objc_property",
1580 PropertyTy);
1581
1582 PropertyListTy = llvm::StructType::get(IntTy,
1583 IntTy,
1584 llvm::ArrayType::get(PropertyTy, 0),
1585 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001586 CGM.getModule().addTypeName("struct._objc_property_list",
1587 PropertyListTy);
1588 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1589
1590 // Protocol description structures
1591
1592 ProtocolExtensionTy =
1593 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1594 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1595 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1596 PropertyListPtrTy,
1597 NULL);
1598 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1599 ProtocolExtensionTy);
1600 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1601
1602 // Handle recursive construction of Protocl and ProtocolList types
1603
1604 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1605 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1606
1607 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1608 LongTy,
1609 llvm::ArrayType::get(ProtocolTyHolder, 0),
1610 NULL);
1611 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1612
1613 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001614 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001615 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1616 MethodDescriptionListPtrTy,
1617 MethodDescriptionListPtrTy,
1618 NULL);
1619 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1620
1621 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1622 CGM.getModule().addTypeName("struct._objc_protocol_list",
1623 ProtocolListTy);
1624 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1625
1626 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1627 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1628 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001629
1630 // Class description structures
1631
1632 IvarTy = llvm::StructType::get(Int8PtrTy,
1633 Int8PtrTy,
1634 IntTy,
1635 NULL);
1636 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1637
1638 IvarListTy = llvm::OpaqueType::get();
1639 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1640 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1641
1642 MethodTy = llvm::StructType::get(SelectorPtrTy,
1643 Int8PtrTy,
1644 Int8PtrTy,
1645 NULL);
1646 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1647
1648 MethodListTy = llvm::OpaqueType::get();
1649 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1650 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1651
1652 CacheTy = llvm::OpaqueType::get();
1653 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1654 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1655
1656 ClassExtensionTy =
1657 llvm::StructType::get(IntTy,
1658 Int8PtrTy,
1659 PropertyListPtrTy,
1660 NULL);
1661 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1662 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1663
1664 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1665
1666 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1667 llvm::PointerType::getUnqual(ClassTyHolder),
1668 Int8PtrTy,
1669 LongTy,
1670 LongTy,
1671 LongTy,
1672 IvarListPtrTy,
1673 MethodListPtrTy,
1674 CachePtrTy,
1675 ProtocolListPtrTy,
1676 Int8PtrTy,
1677 ClassExtensionPtrTy,
1678 NULL);
1679 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1680
1681 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1682 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1683 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1684
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001685 CategoryTy = llvm::StructType::get(Int8PtrTy,
1686 Int8PtrTy,
1687 MethodListPtrTy,
1688 MethodListPtrTy,
1689 ProtocolListPtrTy,
1690 IntTy,
1691 PropertyListPtrTy,
1692 NULL);
1693 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1694
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001695 SuperTy =
1696 llvm::StructType::get(ObjectPtrTy,
1697 ClassPtrTy,
1698 NULL);
1699 CGM.getModule().addTypeName("struct._objc_super",
1700 SuperTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001701 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001702
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001703 // Global metadata structures
1704
1705 SymtabTy = llvm::StructType::get(LongTy,
1706 SelectorPtrTy,
1707 ShortTy,
1708 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001709 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001710 NULL);
1711 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1712 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1713
1714 ModuleTy =
1715 llvm::StructType::get(LongTy,
1716 LongTy,
1717 Int8PtrTy,
1718 SymtabPtrTy,
1719 NULL);
1720 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001721
1722 // Message send functions
1723
1724 std::vector<const llvm::Type*> Params;
1725 Params.push_back(ObjectPtrTy);
1726 Params.push_back(SelectorPtrTy);
1727 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1728 Params,
1729 true),
1730 llvm::Function::ExternalLinkage,
1731 "objc_msgSend",
1732 &CGM.getModule());
1733
1734 Params.clear();
1735 Params.push_back(Int8PtrTy);
1736 Params.push_back(ObjectPtrTy);
1737 Params.push_back(SelectorPtrTy);
1738 MessageSendStretFn =
1739 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1740 Params,
1741 true),
1742 llvm::Function::ExternalLinkage,
1743 "objc_msgSend_stret",
1744 &CGM.getModule());
1745
1746 Params.clear();
1747 Params.push_back(SuperPtrTy);
1748 Params.push_back(SelectorPtrTy);
1749 MessageSendSuperFn =
1750 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1751 Params,
1752 true),
1753 llvm::Function::ExternalLinkage,
1754 "objc_msgSendSuper",
1755 &CGM.getModule());
1756
1757 Params.clear();
1758 Params.push_back(Int8PtrTy);
1759 Params.push_back(SuperPtrTy);
1760 Params.push_back(SelectorPtrTy);
1761 MessageSendSuperStretFn =
1762 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1763 Params,
1764 true),
1765 llvm::Function::ExternalLinkage,
1766 "objc_msgSendSuper_stret",
1767 &CGM.getModule());
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001768}
1769
1770ObjCTypesHelper::~ObjCTypesHelper() {
1771}
1772
1773const llvm::StructType *ObjCTypesHelper::getCFStringType() {
1774 if (!CFStringType) {
1775 CFStringType =
1776 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
1777 llvm::Type::Int32Ty,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001778 Int8PtrTy,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001779 LongTy,
1780 NULL);
1781
1782 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
1783 }
1784
1785 return CFStringType;
1786}
1787
1788llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
1789 if (!CFConstantStringClassReference) {
1790 llvm::GlobalValue *GV =
1791 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
1792 false,
1793 llvm::GlobalValue::ExternalLinkage,
1794 0, "__CFConstantStringClassReference",
1795 &CGM.getModule());
1796
1797 // Decay to pointer.
1798 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1799 }
1800
1801 return CFConstantStringClassReference;
1802}
1803
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001804llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
1805 const llvm::Type *ReturnTy) {
1806 llvm::Function *F;
1807 llvm::FunctionType *CallFTy;
1808
1809 // FIXME: Should we be caching any of this?
1810 if (!ReturnTy->isSingleValueType()) {
1811 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
1812 std::vector<const llvm::Type*> Params(3);
1813 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
1814 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1815 Params[2] = SelectorPtrTy;
1816 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
1817 } else { // XXX floating point?
1818 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
1819 std::vector<const llvm::Type*> Params(2);
1820 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1821 Params[1] = SelectorPtrTy;
1822 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001823 }
1824
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001825 return llvm::ConstantExpr::getBitCast(F,
1826 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001827}
1828
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001829/* *** */
1830
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001831CodeGen::CGObjCRuntime *
1832CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001833 return new CGObjCMac(CGM);
1834}