blob: 95f23c9c27d4d8746afd586f5176034249478f52 [file] [log] [blame]
Daniel Dunbar8c85fac2008-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 Dunbar1be1df32008-08-11 21:35:06 +000015
16#include "CodeGenModule.h"
Daniel Dunbarace33292008-08-16 03:19:19 +000017#include "CodeGenFunction.h"
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000018#include "clang/AST/ASTContext.h"
Daniel Dunbarde300732008-08-11 04:54:23 +000019#include "clang/AST/Decl.h"
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000020#include "clang/AST/DeclObjC.h"
Daniel Dunbar1be1df32008-08-11 21:35:06 +000021#include "clang/Basic/LangOptions.h"
22
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000023#include "llvm/Module.h"
Daniel Dunbar8c85fac2008-08-11 02:45:11 +000024#include "llvm/Support/IRBuilder.h"
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000025#include "llvm/Target/TargetData.h"
Daniel Dunbarace33292008-08-16 03:19:19 +000026#include <sstream>
Daniel Dunbar8c85fac2008-08-11 02:45:11 +000027
28using namespace clang;
29
30namespace {
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000031
Daniel Dunbarcffcdac2008-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 Dunbardaf4ad42008-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
Daniel Dunbar87062ff2008-08-23 09:25:55 +000041 llvm::Function *MessageSendFn, *MessageSendStretFn;
42 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
Daniel Dunbar5eec6142008-08-12 03:39:23 +000043
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000044public:
Daniel Dunbarb050fa62008-08-21 04:36:09 +000045 const llvm::Type *ShortTy, *IntTy, *LongTy;
46 const llvm::Type *Int8PtrTy;
Daniel Dunbar5eec6142008-08-12 03:39:23 +000047
Daniel Dunbar6fa3daf2008-08-12 05:28:47 +000048 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
49 const llvm::Type *ObjectPtrTy;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000050 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar6fa3daf2008-08-12 05:28:47 +000051 const llvm::Type *SelectorPtrTy;
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000052 /// ProtocolPtrTy - LLVM type for external protocol handles
53 /// (typeof(Protocol))
54 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000055
Daniel Dunbar15245e52008-08-23 04:28:29 +000056 /// SuperTy - LLVM type for struct objc_super.
57 const llvm::StructType *SuperTy;
Daniel Dunbar87062ff2008-08-23 09:25:55 +000058 /// SuperPtrTy - LLVM type for struct objc_super *.
59 const llvm::Type *SuperPtrTy;
Daniel Dunbar15245e52008-08-23 04:28:29 +000060
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000061 /// SymtabTy - LLVM type for struct objc_symtab.
62 const llvm::StructType *SymtabTy;
Daniel Dunbarb050fa62008-08-21 04:36:09 +000063 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
64 const llvm::Type *SymtabPtrTy;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000065 /// ModuleTy - LLVM type for struct objc_module.
66 const llvm::StructType *ModuleTy;
Daniel Dunbar5eec6142008-08-12 03:39:23 +000067
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000068 /// ProtocolTy - LLVM type for struct objc_protocol.
69 const llvm::StructType *ProtocolTy;
70 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
71 const llvm::Type *ProtocolPtrTy;
72 /// ProtocolExtensionTy - LLVM type for struct
73 /// objc_protocol_extension.
74 const llvm::StructType *ProtocolExtensionTy;
75 /// ProtocolExtensionTy - LLVM type for struct
76 /// objc_protocol_extension *.
77 const llvm::Type *ProtocolExtensionPtrTy;
78 /// MethodDescriptionTy - LLVM type for struct
79 /// objc_method_description.
80 const llvm::StructType *MethodDescriptionTy;
81 /// MethodDescriptionListTy - LLVM type for struct
82 /// objc_method_description_list.
83 const llvm::StructType *MethodDescriptionListTy;
84 /// MethodDescriptionListPtrTy - LLVM type for struct
85 /// objc_method_description_list *.
86 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbara6eb6b72008-08-23 00:19:03 +000087 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
88 /// in GCC parlance).
89 const llvm::StructType *PropertyTy;
90 /// PropertyListTy - LLVM type for struct objc_property_list
91 /// (_prop_list_t in GCC parlance).
92 const llvm::StructType *PropertyListTy;
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000093 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
94 const llvm::Type *PropertyListPtrTy;
95 /// ProtocolListTy - LLVM type for struct objc_property_list.
96 const llvm::Type *ProtocolListTy;
97 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
98 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar4246a8b2008-08-22 20:34:54 +000099 /// CategoryTy - LLVM type for struct objc_category.
100 const llvm::StructType *CategoryTy;
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000101 /// ClassTy - LLVM type for struct objc_class.
102 const llvm::StructType *ClassTy;
103 /// ClassPtrTy - LLVM type for struct objc_class *.
104 const llvm::Type *ClassPtrTy;
105 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
106 const llvm::StructType *ClassExtensionTy;
107 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
108 const llvm::Type *ClassExtensionPtrTy;
109 /// CacheTy - LLVM type for struct objc_cache.
110 const llvm::Type *CacheTy;
111 /// CachePtrTy - LLVM type for struct objc_cache *.
112 const llvm::Type *CachePtrTy;
113 // IvarTy - LLVM type for struct objc_ivar.
114 const llvm::StructType *IvarTy;
115 /// IvarListTy - LLVM type for struct objc_ivar_list.
116 const llvm::Type *IvarListTy;
117 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
118 const llvm::Type *IvarListPtrTy;
119 // MethodTy - LLVM type for struct objc_method.
120 const llvm::StructType *MethodTy;
121 /// MethodListTy - LLVM type for struct objc_method_list.
122 const llvm::Type *MethodListTy;
123 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
124 const llvm::Type *MethodListPtrTy;
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000125
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000126public:
127 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
128 ~ObjCTypesHelper();
129
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000130 llvm::Value *getMessageSendFn(bool IsSuper, const llvm::Type *ReturnTy);
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000131};
132
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000133class CGObjCMac : public CodeGen::CGObjCRuntime {
134private:
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000135 CodeGen::CodeGenModule &CGM;
136 ObjCTypesHelper ObjCTypes;
137 /// ObjCABI - FIXME: Not sure yet.
138 unsigned ObjCABI;
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000139
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000140 /// ClassNames - uniqued class names.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000141 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000142
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000143 /// MethodVarNames - uniqued method variable names.
144 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
145
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000146 /// MethodVarTypes - uniqued method type signatures. We have to use
147 /// a StringMap here because have no other unique reference.
148 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
149
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000150 /// PropertyNames - uniqued method variable names.
151 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
152
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000153 /// ClassReferences - uniqued class references.
154 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
155
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000156 /// SelectorReferences - uniqued selector references.
157 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
158
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000159 /// Protocols - Protocols for which an objc_protocol structure has
160 /// been emitted. Forward declarations are handled by creating an
161 /// empty structure whose initializer is filled in when/if defined.
162 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
163
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000164 /// DefinedClasses - List of defined classes.
165 std::vector<llvm::GlobalValue*> DefinedClasses;
166
167 /// DefinedCategories - List of defined categories.
168 std::vector<llvm::GlobalValue*> DefinedCategories;
169
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000170 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000171 /// to prevent them from being clobbered.
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000172 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000173
174 /// EmitImageInfo - Emit the image info marker used to encode some module
175 /// level information.
176 void EmitImageInfo();
177
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000178 /// EmitModuleInfo - Another marker encoding module level
179 /// information.
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000180 void EmitModuleInfo();
181
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000182 /// EmitModuleSymols - Emit module symbols, the list of defined
183 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000184 llvm::Constant *EmitModuleSymbols();
185
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000186 /// FinishModule - Write out global data structures at the end of
187 /// processing a translation unit.
188 void FinishModule();
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000189
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000190 /// EmitClassExtension - Generate the class extension structure used
191 /// to store the weak ivar layout and properties. The return value
192 /// has type ClassExtensionPtrTy.
193 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
194
195 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
196 /// for the given class.
197 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
198 const ObjCInterfaceDecl *ID);
199
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000200 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
201 const ObjCMessageExpr *E,
202 llvm::Value *Arg0,
203 bool IsSuper);
204
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000205 /// EmitIvarList - Emit the ivar list for the given
206 /// implementation. If ForClass is true the list of class ivars
207 /// (i.e. metaclass ivars) is emitted, otherwise the list of
208 /// interface ivars will be emitted. The return value has type
209 /// IvarListPtrTy.
210 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
211 bool ForClass,
212 const llvm::Type *InterfaceTy);
213
214 /// EmitMetaClass - Emit a class structure for the metaclass of the
215 /// given implementation. return value has type ClassPtrTy.
216 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
217 llvm::Constant *Protocols,
218 const llvm::Type *InterfaceTy);
219
220 /// EmitMethodList - Emit the method list for the given
221 /// implementation. If ForClass is true the list of class methods
222 /// will be emitted, otherwise the list of instance methods will be
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000223 /// generated. The return value has type MethodListPtrTy.
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000224 llvm::Constant *EmitMethodList(const std::string &Name,
225 const char *Section,
226 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
227 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000228
229 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000230 /// method declarations.
231 /// - TypeName: The name for the type containing the methods.
232 /// - IsProtocol: True iff these methods are for a protocol.
233 /// - ClassMethds: True iff these are class methods.
234 /// - Required: When true, only "required" methods are
235 /// listed. Similarly, when false only "optional" methods are
236 /// listed. For classes this should always be true.
237 /// - begin, end: The method list to output.
238 ///
239 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000240 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
241 bool IsProtocol,
242 bool ClassMethods,
243 bool Required,
244 ObjCMethodDecl * const *begin,
245 ObjCMethodDecl * const *end);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000246
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000247 /// EmitPropertyList - Emit the given property list. The return
248 /// value has type PropertyListPtrTy.
249 llvm::Constant *EmitPropertyList(const std::string &Name,
250 ObjCPropertyDecl * const *begin,
251 ObjCPropertyDecl * const *end);
252
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000253 /// EmitProtocolExtension - Generate the protocol extension
254 /// structure used to store optional instance and class methods, and
255 /// protocol properties. The return value has type
256 /// ProtocolExtensionPtrTy.
257 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
258
259 /// EmitProtocolList - Generate the list of referenced
260 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000261 llvm::Constant *EmitProtocolList(const std::string &Name,
262 ObjCProtocolDecl::protocol_iterator begin,
263 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000264
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000265 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
266 /// for the given selector.
267 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
268
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000269 /// GetProtocolRef - Return a reference to the internal protocol
270 /// description, creating an empty one if it has not been
271 /// defined. The return value has type pointer-to ProtocolTy.
272 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
273
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000274 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000275 /// name. The return value has type char *.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000276 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000277
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000278 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000279 /// selector's name. The return value has type char *.
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000280 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000281 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000282 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000283
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000284 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000285 /// selector's name. The return value has type char *.
286
287 // FIXME: This is a horrible name.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000288 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000289 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000290
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000291 /// GetPropertyName - Return a unique constant for the given
292 /// name. The return value has type char *.
293 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
294
295 // FIXME: This is a horrible name too.
296 llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
297
Daniel Dunbarace33292008-08-16 03:19:19 +0000298 /// GetNameForMethod - Return a name for the given method.
299 /// \param[out] NameOut - The return value.
300 void GetNameForMethod(const ObjCMethodDecl *OMD,
301 std::string &NameOut);
302
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000303public:
304 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000305 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000306
Daniel Dunbara04840b2008-08-23 03:46:30 +0000307 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
308 const ObjCMessageExpr *E,
309 llvm::Value *Receiver);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000310
Daniel Dunbara04840b2008-08-23 03:46:30 +0000311 virtual CodeGen::RValue
312 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
313 const ObjCMessageExpr *E,
Daniel Dunbar434627a2008-08-16 00:25:02 +0000314 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbara04840b2008-08-23 03:46:30 +0000315 llvm::Value *Receiver);
Daniel Dunbar434627a2008-08-16 00:25:02 +0000316
317 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000318 const ObjCInterfaceDecl *ID);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000319
320 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
321
Daniel Dunbarac93e472008-08-15 22:20:32 +0000322 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000323
Daniel Dunbarac93e472008-08-15 22:20:32 +0000324 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000325
Daniel Dunbarac93e472008-08-15 22:20:32 +0000326 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000327
328 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbar84bb85f2008-08-13 00:59:25 +0000329 const ObjCProtocolDecl *PD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000330
Daniel Dunbar84bb85f2008-08-13 00:59:25 +0000331 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000332
333 virtual llvm::Function *ModuleInitFunction();
334};
335} // end anonymous namespace
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000336
337/* *** Helper Functions *** */
338
339/// getConstantGEP() - Help routine to construct simple GEPs.
340static llvm::Constant *getConstantGEP(llvm::Constant *C,
341 unsigned idx0,
342 unsigned idx1) {
343 llvm::Value *Idxs[] = {
344 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
345 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
346 };
347 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
348}
349
350/* *** CGObjCMac Public Interface *** */
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000351
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000352CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
353 : CGM(cgm),
354 ObjCTypes(cgm),
355 ObjCABI(1)
356{
357 // FIXME: How does this get set in GCC? And what does it even mean?
358 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
359 ObjCABI = 2;
360
361 EmitImageInfo();
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000362}
363
Daniel Dunbar434627a2008-08-16 00:25:02 +0000364/// GetClass - Return a reference to the class for the given interface
365/// decl.
366llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000367 const ObjCInterfaceDecl *ID) {
368 return EmitClassRef(Builder, ID);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000369}
370
371/// GetSelector - Return the pointer to the unique'd string for this selector.
372llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000373 return EmitSelector(Builder, Sel);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000374}
375
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000376/// Generate a constant CFString object.
377/*
378 struct __builtin_CFString {
379 const int *isa; // point to __CFConstantStringClassReference
380 int flags;
381 const char *str;
382 long length;
383 };
384*/
385
386llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbardbdb9512008-08-23 18:37:06 +0000387 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000388}
389
390/// Generates a message send where the super is the receiver. This is
391/// a message send to self with special delivery semantics indicating
392/// which class's method should be called.
Daniel Dunbara04840b2008-08-23 03:46:30 +0000393CodeGen::RValue
394CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
395 const ObjCMessageExpr *E,
Daniel Dunbar434627a2008-08-16 00:25:02 +0000396 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbara04840b2008-08-23 03:46:30 +0000397 llvm::Value *Receiver) {
Daniel Dunbar15245e52008-08-23 04:28:29 +0000398 // FIXME: This should be cached, not looked up every time. Meh. We
399 // should just make sure the optimizer hits it.
400 llvm::Value *ReceiverClass = EmitClassRef(CGF.Builder, SuperClass);
401
402 // Create and init a super structure; this is a (receiver, class)
403 // pair we will pass to objc_msgSendSuper.
404 llvm::Value *ObjCSuper =
405 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
406 llvm::Value *ReceiverAsObject =
407 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
408 CGF.Builder.CreateStore(ReceiverAsObject,
409 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
410 CGF.Builder.CreateStore(ReceiverClass,
411 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
412
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000413 return EmitMessageSend(CGF, E, ObjCSuper, true);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000414}
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000415
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000416/// Generate code for a message send expression.
Daniel Dunbara04840b2008-08-23 03:46:30 +0000417CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
418 const ObjCMessageExpr *E,
419 llvm::Value *Receiver) {
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000420 llvm::Value *Arg0 =
421 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
422 return EmitMessageSend(CGF, E, Arg0, false);
423}
424
425CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
426 const ObjCMessageExpr *E,
427 llvm::Value *Arg0,
428 bool IsSuper) {
Daniel Dunbara04840b2008-08-23 03:46:30 +0000429 llvm::Value *Args[2];
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000430 Args[0] = Arg0;
Daniel Dunbara04840b2008-08-23 03:46:30 +0000431 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
Daniel Dunbarac93e472008-08-15 22:20:32 +0000432
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000433 // FIXME: This is a hack, we are implicitly coordinating with
434 // EmitCallExprExt, which will move the return type to the first
435 // parameter and set the structure return flag. See
436 // getMessageSendFn().
437
438
439 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
440 return CGF.EmitCallExprExt(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),
441 E->getType(),
Daniel Dunbara04840b2008-08-23 03:46:30 +0000442 E->arg_begin(),
443 E->arg_end(),
444 Args, 2);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000445}
446
447llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbar84bb85f2008-08-13 00:59:25 +0000448 const ObjCProtocolDecl *PD) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000449 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
450 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000451}
452
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000453/*
454 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
455 struct _objc_protocol {
456 struct _objc_protocol_extension *isa;
457 char *protocol_name;
458 struct _objc_protocol_list *protocol_list;
459 struct _objc__method_prototype_list *instance_methods;
460 struct _objc__method_prototype_list *class_methods
461 };
462
463 See EmitProtocolExtension().
464*/
465void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
466 const char *ProtocolName = PD->getName();
467
468 std::vector<llvm::Constant*> Values(5);
469 Values[0] = EmitProtocolExtension(PD);
470 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000471 Values[2] =
472 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
473 PD->protocol_begin(),
474 PD->protocol_end());
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000475 Values[3] = EmitMethodDescList(ProtocolName,
476 true, // IsProtocol
477 false, // ClassMethods
478 true, // Required
479 PD->instmeth_begin(),
480 PD->instmeth_end());
481 Values[4] = EmitMethodDescList(ProtocolName,
482 true, // IsProtocol
483 true, // ClassMethods
484 true, // Required
485 PD->classmeth_begin(),
486 PD->classmeth_end());
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000487 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
488 Values);
489
490 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
491 if (Entry) {
492 // Already created, just update the initializer
493 Entry->setInitializer(Init);
494 } else {
495 Entry =
496 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
497 llvm::GlobalValue::InternalLinkage,
498 Init,
499 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
500 &CGM.getModule());
501 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
502 UsedGlobals.push_back(Entry);
503 // FIXME: Is this necessary? Why only for protocol?
504 Entry->setAlignment(4);
505 }
506}
507
508llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
509 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
510
511 if (!Entry) {
512 std::vector<llvm::Constant*> Values(5);
513 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
514 Values[1] = GetClassName(PD->getIdentifier());
515 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
516 Values[3] = Values[4] =
517 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
518 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
519 Values);
520
521 Entry =
522 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
523 llvm::GlobalValue::InternalLinkage,
524 Init,
525 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
526 &CGM.getModule());
527 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
528 UsedGlobals.push_back(Entry);
529 // FIXME: Is this necessary? Why only for protocol?
530 Entry->setAlignment(4);
531 }
532
533 return Entry;
534}
535
536/*
537 struct _objc_protocol_extension {
538 uint32_t size;
539 struct objc_method_description_list *optional_instance_methods;
540 struct objc_method_description_list *optional_class_methods;
541 struct objc_property_list *instance_properties;
542 };
543*/
544llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
545 uint64_t Size =
546 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
547 std::vector<llvm::Constant*> Values(4);
548 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000549 Values[1] = EmitMethodDescList(PD->getName(),
550 true, // IsProtocol
551 false, // ClassMethods
552 false, // Required
553 PD->instmeth_begin(),
554 PD->instmeth_end());
555 Values[2] = EmitMethodDescList(PD->getName(),
556 true, // IsProtocol
557 true, // ClassMethods
558 false, // Required
559 PD->classmeth_begin(),
560 PD->classmeth_end());
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000561 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
562 PD->getName(),
563 PD->classprop_begin(),
564 PD->classprop_end());
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000565
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000566 // Return null if no extension bits are used.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000567 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
568 Values[3]->isNullValue())
569 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
570
571 llvm::Constant *Init =
572 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
573 llvm::GlobalVariable *GV =
574 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
575 llvm::GlobalValue::InternalLinkage,
576 Init,
577 (std::string("\01L_OBJC_PROTOCOLEXT_") +
578 PD->getName()),
579 &CGM.getModule());
580 // No special section, but goes in llvm.used
581 UsedGlobals.push_back(GV);
582
583 return GV;
584}
585
586/*
587 struct objc_protocol_list {
588 struct objc_protocol_list *next;
589 long count;
590 Protocol *list[];
591 };
592*/
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000593llvm::Constant *
594CGObjCMac::EmitProtocolList(const std::string &Name,
595 ObjCProtocolDecl::protocol_iterator begin,
596 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000597 std::vector<llvm::Constant*> ProtocolRefs;
598
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000599 for (; begin != end; ++begin)
600 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000601
602 // Just return null for empty protocol lists
603 if (ProtocolRefs.empty())
604 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
605
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000606 // This list is null terminated.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000607 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
608
609 std::vector<llvm::Constant*> Values(3);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000610 // This field is only used by the runtime.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000611 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
612 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
613 Values[2] =
614 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
615 ProtocolRefs.size()),
616 ProtocolRefs);
617
618 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
619 llvm::GlobalVariable *GV =
620 new llvm::GlobalVariable(Init->getType(), false,
621 llvm::GlobalValue::InternalLinkage,
622 Init,
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000623 Name,
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000624 &CGM.getModule());
625 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
626 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
627}
628
629/*
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000630 struct _objc_property {
631 const char * const name;
632 const char * const attributes;
633 };
634
635 struct _objc_property_list {
636 uint32_t entsize; // sizeof (struct _objc_property)
637 uint32_t prop_count;
638 struct _objc_property[prop_count];
639 };
640*/
641llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
642 ObjCPropertyDecl * const *begin,
643 ObjCPropertyDecl * const *end) {
644 std::vector<llvm::Constant*> Properties, Prop(2);
645 for (; begin != end; ++begin) {
646 const ObjCPropertyDecl *PD = *begin;
647 Prop[0] = GetPropertyName(PD->getIdentifier());
648 Prop[1] = GetPropertyType(PD);
649 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
650 Prop));
651 }
652
653 // Return null for empty list.
654 if (Properties.empty())
655 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
656
657 unsigned PropertySize =
658 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
659 std::vector<llvm::Constant*> Values(3);
660 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
661 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
662 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
663 Properties.size());
664 Values[2] = llvm::ConstantArray::get(AT, Properties);
665 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
666
667 llvm::GlobalVariable *GV =
668 new llvm::GlobalVariable(Init->getType(), false,
669 llvm::GlobalValue::InternalLinkage,
670 Init,
671 Name,
672 &CGM.getModule());
673 // No special section on property lists?
674 UsedGlobals.push_back(GV);
675 return llvm::ConstantExpr::getBitCast(GV,
676 ObjCTypes.PropertyListPtrTy);
677
678}
679
680/*
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000681 struct objc_method_description_list {
682 int count;
683 struct objc_method_description list[];
684 };
685*/
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000686llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
687 bool IsProtocol,
688 bool ClassMethods,
689 bool Required,
690 ObjCMethodDecl * const *begin,
691 ObjCMethodDecl * const *end) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000692 std::vector<llvm::Constant*> Methods, Desc(2);
693 for (; begin != end; ++begin) {
694 ObjCMethodDecl *D = *begin;
695 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
696
697 // Skip if this method is required and we are outputting optional
698 // methods, or vice versa.
699 if (Required != IsRequired)
700 continue;
701
702 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
703 ObjCTypes.SelectorPtrTy);
704 Desc[1] = GetMethodVarType(D);
705 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
706 Desc));
707 }
708
709 // Return null for empty list.
710 if (Methods.empty())
711 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
712
713 std::vector<llvm::Constant*> Values(2);
714 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
715 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
716 Methods.size());
717 Values[1] = llvm::ConstantArray::get(AT, Methods);
718 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
719
720 char Prefix[256];
721 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
722 IsProtocol ? "PROTOCOL_" : "",
723 ClassMethods ? "CLASS_" : "INSTANCE_",
724 !Required ? "OPT_" : "");
725 llvm::GlobalVariable *GV =
726 new llvm::GlobalVariable(Init->getType(), false,
727 llvm::GlobalValue::InternalLinkage,
728 Init,
729 std::string(Prefix) + TypeName,
730 &CGM.getModule());
731 if (ClassMethods) {
732 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
733 } else {
734 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
735 }
736 UsedGlobals.push_back(GV);
737 return llvm::ConstantExpr::getBitCast(GV,
738 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000739}
740
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000741/*
742 struct _objc_category {
743 char *category_name;
744 char *class_name;
745 struct _objc_method_list *instance_methods;
746 struct _objc_method_list *class_methods;
747 struct _objc_protocol_list *protocols;
748 uint32_t size; // <rdar://4585769>
749 struct _objc_property_list *instance_properties;
750 };
751 */
Daniel Dunbarac93e472008-08-15 22:20:32 +0000752void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000753 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
754
755 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
756 std::string ExtName(std::string(Interface->getName()) +
757 "_" +
758 OCD->getName());
759
760 std::vector<llvm::Constant*> Values(7);
761 Values[0] = GetClassName(OCD->getIdentifier());
762 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000763 Values[2] =
764 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
765 ExtName,
766 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
767 OCD->instmeth_begin(),
768 OCD->instmeth_end());
769 Values[3] =
770 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
771 "__OBJC,__cat_class_meth,regular,no_dead_strip",
772 OCD->classmeth_begin(),
773 OCD->classmeth_end());
774 Values[4] =
775 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
776 Interface->protocol_begin(),
777 Interface->protocol_end());
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000778 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000779 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
780 Interface->classprop_begin(),
781 Interface->classprop_end());
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000782
783 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
784 Values);
785
786 llvm::GlobalVariable *GV =
787 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
788 llvm::GlobalValue::InternalLinkage,
789 Init,
790 std::string("\01L_OBJC_CATEGORY_")+ExtName,
791 &CGM.getModule());
792 GV->setSection("__OBJC,__category,regular,no_dead_strip");
793 UsedGlobals.push_back(GV);
794 DefinedCategories.push_back(GV);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000795}
796
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000797// FIXME: Get from somewhere?
798enum ClassFlags {
799 eClassFlags_Factory = 0x00001,
800 eClassFlags_Meta = 0x00002,
801 // <rdr://5142207>
802 eClassFlags_HasCXXStructors = 0x02000,
803 eClassFlags_Hidden = 0x20000,
804 eClassFlags_ABI2_Hidden = 0x00010,
805 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
806};
807
808// <rdr://5142207&4705298&4843145>
809static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
810 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
811 // FIXME: Support -fvisibility
812 switch (attr->getVisibility()) {
813 default:
814 assert(0 && "Unknown visibility");
815 return false;
816 case VisibilityAttr::DefaultVisibility:
817 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
818 return false;
819 case VisibilityAttr::HiddenVisibility:
820 return true;
821 }
822 } else {
823 return false; // FIXME: Support -fvisibility
824 }
825}
826
827/*
828 struct _objc_class {
829 Class isa;
830 Class super_class;
831 const char *name;
832 long version;
833 long info;
834 long instance_size;
835 struct _objc_ivar_list *ivars;
836 struct _objc_method_list *methods;
837 struct _objc_cache *cache;
838 struct _objc_protocol_list *protocols;
839 // Objective-C 1.0 extensions (<rdr://4585769>)
840 const char *ivar_layout;
841 struct _objc_class_ext *ext;
842 };
843
844 See EmitClassExtension();
845 */
846void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
847 const char *ClassName = ID->getName();
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000848 // FIXME: Gross
849 ObjCInterfaceDecl *Interface =
850 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000851 llvm::Constant *Protocols =
852 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
853 Interface->protocol_begin(),
854 Interface->protocol_end());
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000855 const llvm::Type *InterfaceTy =
856 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
857 unsigned Flags = eClassFlags_Factory;
858 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
859
860 // FIXME: Set CXX-structors flag.
861 if (IsClassHidden(ID->getClassInterface()))
862 Flags |= eClassFlags_Hidden;
863
864 std::vector<llvm::Constant*> Values(12);
865 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
866 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
867 Values[ 1] =
868 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
869 ObjCTypes.ClassPtrTy);
870 } else {
871 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
872 }
873 Values[ 2] = GetClassName(ID->getIdentifier());
874 // Version is always 0.
875 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
876 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
877 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
878 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000879 Values[ 7] =
880 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
881 "__OBJC,__inst_meth,regular,no_dead_strip",
882 ID->instmeth_begin(),
883 ID->instmeth_end());
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000884 // cache is always NULL.
885 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
886 Values[ 9] = Protocols;
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000887 // FIXME: Set ivar_layout
888 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000889 Values[11] = EmitClassExtension(ID);
890 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
891 Values);
892
893 llvm::GlobalVariable *GV =
894 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
895 llvm::GlobalValue::InternalLinkage,
896 Init,
897 std::string("\01L_OBJC_CLASS_")+ClassName,
898 &CGM.getModule());
899 GV->setSection("__OBJC,__class,regular,no_dead_strip");
900 UsedGlobals.push_back(GV);
901 // FIXME: Why?
902 GV->setAlignment(32);
903 DefinedClasses.push_back(GV);
904}
905
906llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
907 llvm::Constant *Protocols,
908 const llvm::Type *InterfaceTy) {
909 const char *ClassName = ID->getName();
910 unsigned Flags = eClassFlags_Meta;
911 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
912
913 if (IsClassHidden(ID->getClassInterface()))
914 Flags |= eClassFlags_Hidden;
915
916 std::vector<llvm::Constant*> Values(12);
917 // The isa for the metaclass is the root of the hierarchy.
918 const ObjCInterfaceDecl *Root = ID->getClassInterface();
919 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
920 Root = Super;
921 Values[ 0] =
922 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
923 ObjCTypes.ClassPtrTy);
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000924 // The super class for the metaclass is emitted as the name of the
925 // super class. The runtime fixes this up to point to the
926 // *metaclass* for the super class.
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000927 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
928 Values[ 1] =
929 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
930 ObjCTypes.ClassPtrTy);
931 } else {
932 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
933 }
934 Values[ 2] = GetClassName(ID->getIdentifier());
935 // Version is always 0.
936 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
937 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
938 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
939 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000940 Values[ 7] =
941 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
942 "__OBJC,__inst_meth,regular,no_dead_strip",
943 ID->classmeth_begin(),
944 ID->classmeth_end());
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000945 // cache is always NULL.
946 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
947 Values[ 9] = Protocols;
948 // ivar_layout for metaclass is always NULL.
949 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
950 // The class extension is always unused for metaclasses.
951 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
952 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
953 Values);
954
955 llvm::GlobalVariable *GV =
956 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
957 llvm::GlobalValue::InternalLinkage,
958 Init,
959 std::string("\01L_OBJC_METACLASS_")+ClassName,
960 &CGM.getModule());
961 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
962 UsedGlobals.push_back(GV);
963 // FIXME: Why?
964 GV->setAlignment(32);
965
966 return GV;
967}
968
969/*
970 struct objc_class_ext {
971 uint32_t size;
972 const char *weak_ivar_layout;
973 struct _objc_property_list *properties;
974 };
975*/
976llvm::Constant *
977CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
978 uint64_t Size =
979 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
980
981 std::vector<llvm::Constant*> Values(3);
982 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000983 // FIXME: Output weak_ivar_layout string.
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000984 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000985 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
986 ID->getName(),
987 ID->getClassInterface()->classprop_begin(),
988 ID->getClassInterface()->classprop_end());
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000989
990 // Return null if no extension bits are used.
991 if (Values[1]->isNullValue() && Values[2]->isNullValue())
992 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
993
994 llvm::Constant *Init =
995 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
996 llvm::GlobalVariable *GV =
997 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
998 llvm::GlobalValue::InternalLinkage,
999 Init,
1000 (std::string("\01L_OBJC_CLASSEXT_") +
1001 ID->getName()),
1002 &CGM.getModule());
1003 // No special section, but goes in llvm.used
1004 UsedGlobals.push_back(GV);
1005
1006 return GV;
1007}
1008
1009/*
1010 struct objc_ivar {
1011 char *ivar_name;
1012 char *ivar_type;
1013 int ivar_offset;
1014 };
1015
1016 struct objc_ivar_list {
1017 int ivar_count;
1018 struct objc_ivar list[count];
1019 };
1020 */
1021llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1022 bool ForClass,
1023 const llvm::Type *InterfaceTy) {
1024 std::vector<llvm::Constant*> Ivars, Ivar(3);
1025
1026 // When emitting the root class GCC emits ivar entries for the
1027 // actual class structure. It is not clear if we need to follow this
1028 // behavior; for now lets try and get away with not doing it. If so,
1029 // the cleanest solution would be to make up an ObjCInterfaceDecl
1030 // for the class.
1031 if (ForClass)
1032 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1033
1034 const llvm::StructLayout *Layout =
1035 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1036 for (ObjCInterfaceDecl::ivar_iterator
1037 i = ID->getClassInterface()->ivar_begin(),
1038 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1039 ObjCIvarDecl *V = *i;
1040 unsigned Offset =
1041 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1042 std::string TypeStr;
1043 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1044 Ivar[0] = GetMethodVarName(V->getIdentifier());
1045 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1046 EncodingRecordTypes);
1047 Ivar[1] = GetMethodVarType(TypeStr);
1048 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1049 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1050 Ivar));
1051 }
1052
1053 // Return null for empty list.
1054 if (Ivars.empty())
1055 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1056
1057 std::vector<llvm::Constant*> Values(2);
1058 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1059 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1060 Ivars.size());
1061 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1062 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1063
1064 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1065 "\01L_OBJC_INSTANCE_VARIABLES_");
1066 llvm::GlobalVariable *GV =
1067 new llvm::GlobalVariable(Init->getType(), false,
1068 llvm::GlobalValue::InternalLinkage,
1069 Init,
1070 std::string(Prefix) + ID->getName(),
1071 &CGM.getModule());
1072 if (ForClass) {
1073 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1074 // FIXME: Why is this only here?
1075 GV->setAlignment(32);
1076 } else {
1077 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1078 }
1079 UsedGlobals.push_back(GV);
1080 return llvm::ConstantExpr::getBitCast(GV,
1081 ObjCTypes.IvarListPtrTy);
1082}
1083
1084/*
1085 struct objc_method {
1086 SEL method_name;
1087 char *method_types;
1088 void *method;
1089 };
1090
1091 struct objc_method_list {
1092 struct objc_method_list *obsolete;
1093 int count;
1094 struct objc_method methods_list[count];
1095 };
1096*/
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001097llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1098 const char *Section,
1099 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1100 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001101 std::vector<llvm::Constant*> Methods, Method(3);
1102
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001103 for (; begin != end; ++begin) {
1104 ObjCMethodDecl *MD = *begin;
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001105
1106 Method[0] =
1107 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1108 ObjCTypes.SelectorPtrTy);
1109 Method[1] = GetMethodVarType(MD);
1110
1111 // FIXME: This is gross, we shouldn't be looking up by name.
1112 std::string Name;
1113 GetNameForMethod(MD, Name);
1114 Method[2] =
1115 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1116 ObjCTypes.Int8PtrTy);
1117 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1118 Method));
1119 }
1120
1121 // Return null for empty list.
1122 if (Methods.empty())
1123 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1124
1125 std::vector<llvm::Constant*> Values(3);
1126 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1127 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1128 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1129 Methods.size());
1130 Values[2] = llvm::ConstantArray::get(AT, Methods);
1131 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1132
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001133 llvm::GlobalVariable *GV =
1134 new llvm::GlobalVariable(Init->getType(), false,
1135 llvm::GlobalValue::InternalLinkage,
1136 Init,
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001137 Name,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001138 &CGM.getModule());
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001139 GV->setSection(Section);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001140 UsedGlobals.push_back(GV);
1141 return llvm::ConstantExpr::getBitCast(GV,
1142 ObjCTypes.MethodListPtrTy);
Daniel Dunbarace33292008-08-16 03:19:19 +00001143}
1144
1145llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1146 const llvm::Type *ReturnTy =
1147 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1148 const llvm::Type *SelfTy =
1149 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1150
1151 std::vector<const llvm::Type*> ArgTys;
1152 ArgTys.reserve(1 + 2 + OMD->param_size());
1153
1154 // FIXME: This is not something we should have to be dealing with
1155 // here.
1156 bool useStructRet =
1157 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1158 if (useStructRet) {
1159 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1160 ReturnTy = llvm::Type::VoidTy;
1161 }
1162
1163 // Implicit arguments
1164 ArgTys.push_back(SelfTy);
1165 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1166
1167 for (ObjCMethodDecl::param_const_iterator
1168 i = OMD->param_begin(), e = OMD->param_end();
1169 i != e; ++i) {
1170 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbara04840b2008-08-23 03:46:30 +00001171 if (Ty->isSingleValueType()) {
Daniel Dunbarace33292008-08-16 03:19:19 +00001172 ArgTys.push_back(Ty);
1173 } else {
1174 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1175 }
1176 }
1177
1178 std::string Name;
1179 GetNameForMethod(OMD, Name);
1180
1181 llvm::Function *Method =
1182 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1183 ArgTys,
1184 OMD->isVariadic()),
1185 llvm::GlobalValue::InternalLinkage,
1186 Name,
1187 &CGM.getModule());
1188
Daniel Dunbara04840b2008-08-23 03:46:30 +00001189 unsigned Offset = 3; // Return plus self and selector implicit args.
1190 if (useStructRet) {
Daniel Dunbarace33292008-08-16 03:19:19 +00001191 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbara04840b2008-08-23 03:46:30 +00001192 ++Offset;
1193 }
1194
1195 // FIXME: This is horrible, we need to be reusing the machinery in
1196 // CodeGenModule.cpp (SetFunctionAttributes).
1197 for (ObjCMethodDecl::param_const_iterator
1198 i = OMD->param_begin(), e = OMD->param_end();
1199 i != e; ++i, ++Offset) {
1200 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1201 if (!Ty->isSingleValueType())
1202 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1203 }
Daniel Dunbarace33292008-08-16 03:19:19 +00001204
1205 return Method;
Daniel Dunbar8c85fac2008-08-11 02:45:11 +00001206}
1207
1208llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001209 // Abuse this interface function as a place to finalize.
1210 FinishModule();
1211
Daniel Dunbar8c85fac2008-08-11 02:45:11 +00001212 return NULL;
1213}
1214
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001215/* *** Private Interface *** */
1216
1217/// EmitImageInfo - Emit the image info marker used to encode some module
1218/// level information.
1219///
1220/// See: <rdr://4810609&4810587&4810587>
1221/// struct IMAGE_INFO {
1222/// unsigned version;
1223/// unsigned flags;
1224/// };
1225enum ImageInfoFlags {
1226 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1227 eImageInfo_GarbageCollected = (1 << 1),
1228 eImageInfo_GCOnly = (1 << 2)
1229};
1230
1231void CGObjCMac::EmitImageInfo() {
1232 unsigned version = 0; // Version is unused?
1233 unsigned flags = 0;
1234
1235 // FIXME: Fix and continue?
1236 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1237 flags |= eImageInfo_GarbageCollected;
1238 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1239 flags |= eImageInfo_GCOnly;
1240
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001241 // Emitted as int[2];
1242 llvm::Constant *values[2] = {
1243 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1244 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1245 };
1246 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001247 llvm::GlobalVariable *GV =
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001248 new llvm::GlobalVariable(AT, true,
1249 llvm::GlobalValue::InternalLinkage,
1250 llvm::ConstantArray::get(AT, values, 2),
1251 "\01L_OBJC_IMAGE_INFO",
1252 &CGM.getModule());
1253
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00001254 if (ObjCABI == 1) {
1255 GV->setSection("__OBJC, __image_info,regular");
1256 } else {
1257 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1258 }
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001259
1260 UsedGlobals.push_back(GV);
1261}
1262
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001263
1264// struct objc_module {
1265// unsigned long version;
1266// unsigned long size;
1267// const char *name;
1268// Symtab symtab;
1269// };
1270
1271// FIXME: Get from somewhere
1272static const int ModuleVersion = 7;
1273
1274void CGObjCMac::EmitModuleInfo() {
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001275 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1276
1277 std::vector<llvm::Constant*> Values(4);
1278 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1279 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbarac93e472008-08-15 22:20:32 +00001280 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001281 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001282 Values[3] = EmitModuleSymbols();
1283
1284 llvm::GlobalVariable *GV =
1285 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1286 llvm::GlobalValue::InternalLinkage,
1287 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1288 Values),
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001289 "\01L_OBJC_MODULES",
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001290 &CGM.getModule());
1291 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1292 UsedGlobals.push_back(GV);
1293}
1294
1295llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001296 std::vector<llvm::Constant*> Values(5);
1297 unsigned NumClasses = DefinedClasses.size();
1298 unsigned NumCategories = DefinedCategories.size();
1299
1300 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1301 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1302 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1303 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1304
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001305 // The runtime expects exactly the list of defined classes followed
1306 // by the list of defined categories, in a single array.
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001307 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001308 for (unsigned i=0; i<NumClasses; i++)
1309 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1310 ObjCTypes.Int8PtrTy);
1311 for (unsigned i=0; i<NumCategories; i++)
1312 Symbols[NumClasses + i] =
1313 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1314 ObjCTypes.Int8PtrTy);
1315
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001316 Values[4] =
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001317 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001318 NumClasses + NumCategories),
1319 Symbols);
1320
1321 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1322
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001323 llvm::GlobalVariable *GV =
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001324 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001325 llvm::GlobalValue::InternalLinkage,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001326 Init,
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001327 "\01L_OBJC_SYMBOLS",
1328 &CGM.getModule());
1329 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1330 UsedGlobals.push_back(GV);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001331 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1332}
1333
1334llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1335 const ObjCInterfaceDecl *ID) {
1336 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1337
1338 if (!Entry) {
1339 llvm::Constant *Casted =
1340 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1341 ObjCTypes.ClassPtrTy);
1342 Entry =
1343 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1344 llvm::GlobalValue::InternalLinkage,
1345 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1346 &CGM.getModule());
1347 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1348 UsedGlobals.push_back(Entry);
1349 }
1350
1351 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001352}
1353
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001354llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1355 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1356
1357 if (!Entry) {
1358 llvm::Constant *Casted =
1359 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1360 ObjCTypes.SelectorPtrTy);
1361 Entry =
1362 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1363 llvm::GlobalValue::InternalLinkage,
1364 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1365 &CGM.getModule());
1366 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1367 UsedGlobals.push_back(Entry);
1368 }
1369
1370 return Builder.CreateLoad(Entry, false, "tmp");
1371}
1372
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001373llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1374 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001375
1376 if (!Entry) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001377 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001378 Entry =
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001379 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001380 llvm::GlobalValue::InternalLinkage,
1381 C, "\01L_OBJC_CLASS_NAME_",
1382 &CGM.getModule());
1383 Entry->setSection("__TEXT,__cstring,cstring_literals");
1384 UsedGlobals.push_back(Entry);
1385 }
1386
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001387 return getConstantGEP(Entry, 0, 0);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001388}
1389
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001390llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1391 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1392
1393 if (!Entry) {
1394 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1395 Entry =
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001396 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001397 llvm::GlobalValue::InternalLinkage,
1398 C, "\01L_OBJC_METH_VAR_NAME_",
1399 &CGM.getModule());
1400 Entry->setSection("__TEXT,__cstring,cstring_literals");
1401 UsedGlobals.push_back(Entry);
1402 }
1403
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001404 return getConstantGEP(Entry, 0, 0);
1405}
1406
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001407// FIXME: Merge into a single cstring creation function.
1408llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1409 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1410}
1411
1412// FIXME: Merge into a single cstring creation function.
1413llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1414 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1415}
1416
1417llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1418 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001419
1420 if (!Entry) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001421 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001422 Entry =
1423 new llvm::GlobalVariable(C->getType(), false,
1424 llvm::GlobalValue::InternalLinkage,
1425 C, "\01L_OBJC_METH_VAR_TYPE_",
1426 &CGM.getModule());
1427 Entry->setSection("__TEXT,__cstring,cstring_literals");
1428 UsedGlobals.push_back(Entry);
1429 }
1430
1431 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001432}
1433
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001434// FIXME: Merge into a single cstring creation function.
1435llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1436 std::string TypeStr;
1437 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1438 return GetMethodVarType(TypeStr);
1439}
1440
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00001441// FIXME: Merge into a single cstring creation function.
1442llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1443 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1444
1445 if (!Entry) {
1446 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1447 Entry =
1448 new llvm::GlobalVariable(C->getType(), false,
1449 llvm::GlobalValue::InternalLinkage,
1450 C, "\01L_OBJC_PROP_NAME_ATTR_",
1451 &CGM.getModule());
1452 Entry->setSection("__TEXT,__cstring,cstring_literals");
1453 UsedGlobals.push_back(Entry);
1454 }
1455
1456 return getConstantGEP(Entry, 0, 0);
1457}
1458
1459// FIXME: Merge into a single cstring creation function.
1460llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1461 std::string TypeStr("MOOO!");
1462 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1463 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1464}
1465
Daniel Dunbarace33292008-08-16 03:19:19 +00001466void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1467 std::string &NameOut) {
1468 // FIXME: Find the mangling GCC uses.
1469 std::stringstream s;
1470 s << (D->isInstance() ? "-" : "+");
1471 s << "[";
1472 s << D->getClassInterface()->getName();
1473 s << " ";
1474 s << D->getSelector().getName();
1475 s << "]";
1476 NameOut = s.str();
1477}
1478
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001479void CGObjCMac::FinishModule() {
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001480 EmitModuleInfo();
1481
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001482 std::vector<llvm::Constant*> Used;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001483
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001484 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001485 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001486 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001487 }
1488
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001489 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001490 llvm::GlobalValue *GV =
1491 new llvm::GlobalVariable(AT, false,
1492 llvm::GlobalValue::AppendingLinkage,
1493 llvm::ConstantArray::get(AT, Used),
1494 "llvm.used",
1495 &CGM.getModule());
1496
1497 GV->setSection("llvm.metadata");
1498}
1499
1500/* *** */
1501
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00001502ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbardbdb9512008-08-23 18:37:06 +00001503 : CGM(cgm)
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00001504{
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001505 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1506 ASTContext &Ctx = CGM.getContext();
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001507
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001508 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001509 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001510 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001511 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1512
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001513 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1514 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001515
1516 // FIXME: It would be nice to unify this with the opaque type, so
1517 // that the IR comes out a bit cleaner.
1518 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1519 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001520
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001521 MethodDescriptionTy =
1522 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001523 Int8PtrTy,
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001524 NULL);
1525 CGM.getModule().addTypeName("struct._objc_method_description",
1526 MethodDescriptionTy);
1527
1528 MethodDescriptionListTy =
1529 llvm::StructType::get(IntTy,
1530 llvm::ArrayType::get(MethodDescriptionTy, 0),
1531 NULL);
1532 CGM.getModule().addTypeName("struct._objc_method_description_list",
1533 MethodDescriptionListTy);
1534 MethodDescriptionListPtrTy =
1535 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1536
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00001537 PropertyTy = llvm::StructType::get(Int8PtrTy,
1538 Int8PtrTy,
1539 NULL);
1540 CGM.getModule().addTypeName("struct._objc_property",
1541 PropertyTy);
1542
1543 PropertyListTy = llvm::StructType::get(IntTy,
1544 IntTy,
1545 llvm::ArrayType::get(PropertyTy, 0),
1546 NULL);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001547 CGM.getModule().addTypeName("struct._objc_property_list",
1548 PropertyListTy);
1549 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1550
1551 // Protocol description structures
1552
1553 ProtocolExtensionTy =
1554 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1555 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1556 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1557 PropertyListPtrTy,
1558 NULL);
1559 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1560 ProtocolExtensionTy);
1561 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1562
1563 // Handle recursive construction of Protocl and ProtocolList types
1564
1565 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1566 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1567
1568 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1569 LongTy,
1570 llvm::ArrayType::get(ProtocolTyHolder, 0),
1571 NULL);
1572 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1573
1574 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001575 Int8PtrTy,
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001576 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1577 MethodDescriptionListPtrTy,
1578 MethodDescriptionListPtrTy,
1579 NULL);
1580 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1581
1582 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1583 CGM.getModule().addTypeName("struct._objc_protocol_list",
1584 ProtocolListTy);
1585 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1586
1587 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1588 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1589 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001590
1591 // Class description structures
1592
1593 IvarTy = llvm::StructType::get(Int8PtrTy,
1594 Int8PtrTy,
1595 IntTy,
1596 NULL);
1597 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1598
1599 IvarListTy = llvm::OpaqueType::get();
1600 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1601 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1602
1603 MethodTy = llvm::StructType::get(SelectorPtrTy,
1604 Int8PtrTy,
1605 Int8PtrTy,
1606 NULL);
1607 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1608
1609 MethodListTy = llvm::OpaqueType::get();
1610 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1611 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1612
1613 CacheTy = llvm::OpaqueType::get();
1614 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1615 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1616
1617 ClassExtensionTy =
1618 llvm::StructType::get(IntTy,
1619 Int8PtrTy,
1620 PropertyListPtrTy,
1621 NULL);
1622 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1623 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1624
1625 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1626
1627 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1628 llvm::PointerType::getUnqual(ClassTyHolder),
1629 Int8PtrTy,
1630 LongTy,
1631 LongTy,
1632 LongTy,
1633 IvarListPtrTy,
1634 MethodListPtrTy,
1635 CachePtrTy,
1636 ProtocolListPtrTy,
1637 Int8PtrTy,
1638 ClassExtensionPtrTy,
1639 NULL);
1640 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1641
1642 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1643 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1644 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1645
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001646 CategoryTy = llvm::StructType::get(Int8PtrTy,
1647 Int8PtrTy,
1648 MethodListPtrTy,
1649 MethodListPtrTy,
1650 ProtocolListPtrTy,
1651 IntTy,
1652 PropertyListPtrTy,
1653 NULL);
1654 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1655
Daniel Dunbar15245e52008-08-23 04:28:29 +00001656 SuperTy =
1657 llvm::StructType::get(ObjectPtrTy,
1658 ClassPtrTy,
1659 NULL);
1660 CGM.getModule().addTypeName("struct._objc_super",
1661 SuperTy);
Daniel Dunbar87062ff2008-08-23 09:25:55 +00001662 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbar15245e52008-08-23 04:28:29 +00001663
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001664 // Global metadata structures
1665
1666 SymtabTy = llvm::StructType::get(LongTy,
1667 SelectorPtrTy,
1668 ShortTy,
1669 ShortTy,
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001670 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001671 NULL);
1672 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1673 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1674
1675 ModuleTy =
1676 llvm::StructType::get(LongTy,
1677 LongTy,
1678 Int8PtrTy,
1679 SymtabPtrTy,
1680 NULL);
1681 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar87062ff2008-08-23 09:25:55 +00001682
1683 // Message send functions
1684
1685 std::vector<const llvm::Type*> Params;
1686 Params.push_back(ObjectPtrTy);
1687 Params.push_back(SelectorPtrTy);
1688 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1689 Params,
1690 true),
1691 llvm::Function::ExternalLinkage,
1692 "objc_msgSend",
1693 &CGM.getModule());
1694
1695 Params.clear();
1696 Params.push_back(Int8PtrTy);
1697 Params.push_back(ObjectPtrTy);
1698 Params.push_back(SelectorPtrTy);
1699 MessageSendStretFn =
1700 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1701 Params,
1702 true),
1703 llvm::Function::ExternalLinkage,
1704 "objc_msgSend_stret",
1705 &CGM.getModule());
1706
1707 Params.clear();
1708 Params.push_back(SuperPtrTy);
1709 Params.push_back(SelectorPtrTy);
1710 MessageSendSuperFn =
1711 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1712 Params,
1713 true),
1714 llvm::Function::ExternalLinkage,
1715 "objc_msgSendSuper",
1716 &CGM.getModule());
1717
1718 Params.clear();
1719 Params.push_back(Int8PtrTy);
1720 Params.push_back(SuperPtrTy);
1721 Params.push_back(SelectorPtrTy);
1722 MessageSendSuperStretFn =
1723 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1724 Params,
1725 true),
1726 llvm::Function::ExternalLinkage,
1727 "objc_msgSendSuper_stret",
1728 &CGM.getModule());
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00001729}
1730
1731ObjCTypesHelper::~ObjCTypesHelper() {
1732}
1733
Daniel Dunbar87062ff2008-08-23 09:25:55 +00001734llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
1735 const llvm::Type *ReturnTy) {
1736 llvm::Function *F;
1737 llvm::FunctionType *CallFTy;
1738
1739 // FIXME: Should we be caching any of this?
1740 if (!ReturnTy->isSingleValueType()) {
1741 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
1742 std::vector<const llvm::Type*> Params(3);
1743 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
1744 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1745 Params[2] = SelectorPtrTy;
1746 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
1747 } else { // XXX floating point?
1748 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
1749 std::vector<const llvm::Type*> Params(2);
1750 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1751 Params[1] = SelectorPtrTy;
1752 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001753 }
1754
Daniel Dunbar87062ff2008-08-23 09:25:55 +00001755 return llvm::ConstantExpr::getBitCast(F,
1756 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbar15245e52008-08-23 04:28:29 +00001757}
1758
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00001759/* *** */
1760
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001761CodeGen::CGObjCRuntime *
1762CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbar8c85fac2008-08-11 02:45:11 +00001763 return new CGObjCMac(CGM);
1764}