blob: 518c574d02dd75ed1e5636f7104b6cd125186a42 [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
Daniel Dunbar14c80b72008-08-23 09:25:55 +000041 llvm::Function *MessageSendFn, *MessageSendStretFn;
42 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000043
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000044public:
Daniel Dunbar27f9d772008-08-21 04:36:09 +000045 const llvm::Type *ShortTy, *IntTy, *LongTy;
46 const llvm::Type *Int8PtrTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000047
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000048 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
49 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000050 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000051 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000052 /// ProtocolPtrTy - LLVM type for external protocol handles
53 /// (typeof(Protocol))
54 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000055
Daniel Dunbare8b470d2008-08-23 04:28:29 +000056 /// SuperTy - LLVM type for struct objc_super.
57 const llvm::StructType *SuperTy;
Daniel Dunbar14c80b72008-08-23 09:25:55 +000058 /// SuperPtrTy - LLVM type for struct objc_super *.
59 const llvm::Type *SuperPtrTy;
Daniel Dunbare8b470d2008-08-23 04:28:29 +000060
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000061 /// SymtabTy - LLVM type for struct objc_symtab.
62 const llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000063 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
64 const llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000065 /// ModuleTy - LLVM type for struct objc_module.
66 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000067
Daniel Dunbar6efc0c52008-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 Dunbarc8ef5512008-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 Dunbar6efc0c52008-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 Dunbar86e253a2008-08-22 20:34:54 +000099 /// CategoryTy - LLVM type for struct objc_category.
100 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-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 Dunbar6efc0c52008-08-13 03:21:16 +0000125
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000126public:
127 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
128 ~ObjCTypesHelper();
129
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000130 llvm::Value *getMessageSendFn(bool IsSuper, const llvm::Type *ReturnTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000131};
132
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000133class CGObjCMac : public CodeGen::CGObjCRuntime {
134private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000135 CodeGen::CodeGenModule &CGM;
136 ObjCTypesHelper ObjCTypes;
137 /// ObjCABI - FIXME: Not sure yet.
138 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000139
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000140 /// LazySymbols - Symbols to generate a lazy reference for. See
141 /// DefinedSymbols and FinishModule().
142 std::set<IdentifierInfo*> LazySymbols;
143
144 /// DefinedSymbols - External symbols which are defined by this
145 /// module. The symbols in this list and LazySymbols are used to add
146 /// special linker symbols which ensure that Objective-C modules are
147 /// linked properly.
148 std::set<IdentifierInfo*> DefinedSymbols;
149
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000150 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000151 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000152
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000153 /// MethodVarNames - uniqued method variable names.
154 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
155
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000156 /// MethodVarTypes - uniqued method type signatures. We have to use
157 /// a StringMap here because have no other unique reference.
158 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
159
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000160 /// PropertyNames - uniqued method variable names.
161 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
162
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000163 /// ClassReferences - uniqued class references.
164 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
165
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000166 /// SelectorReferences - uniqued selector references.
167 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
168
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000169 /// Protocols - Protocols for which an objc_protocol structure has
170 /// been emitted. Forward declarations are handled by creating an
171 /// empty structure whose initializer is filled in when/if defined.
172 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
173
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000174 /// DefinedClasses - List of defined classes.
175 std::vector<llvm::GlobalValue*> DefinedClasses;
176
177 /// DefinedCategories - List of defined categories.
178 std::vector<llvm::GlobalValue*> DefinedCategories;
179
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000180 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000181 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000182 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000183
184 /// EmitImageInfo - Emit the image info marker used to encode some module
185 /// level information.
186 void EmitImageInfo();
187
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000188 /// EmitModuleInfo - Another marker encoding module level
189 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000190 void EmitModuleInfo();
191
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000192 /// EmitModuleSymols - Emit module symbols, the list of defined
193 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000194 llvm::Constant *EmitModuleSymbols();
195
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000196 /// FinishModule - Write out global data structures at the end of
197 /// processing a translation unit.
198 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000199
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000200 /// EmitClassExtension - Generate the class extension structure used
201 /// to store the weak ivar layout and properties. The return value
202 /// has type ClassExtensionPtrTy.
203 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
204
205 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
206 /// for the given class.
207 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
208 const ObjCInterfaceDecl *ID);
209
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000210 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
211 const ObjCMessageExpr *E,
212 llvm::Value *Arg0,
213 bool IsSuper);
214
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000215 /// EmitIvarList - Emit the ivar list for the given
216 /// implementation. If ForClass is true the list of class ivars
217 /// (i.e. metaclass ivars) is emitted, otherwise the list of
218 /// interface ivars will be emitted. The return value has type
219 /// IvarListPtrTy.
220 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
221 bool ForClass,
222 const llvm::Type *InterfaceTy);
223
224 /// EmitMetaClass - Emit a class structure for the metaclass of the
225 /// given implementation. return value has type ClassPtrTy.
226 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
227 llvm::Constant *Protocols,
228 const llvm::Type *InterfaceTy);
229
230 /// EmitMethodList - Emit the method list for the given
231 /// implementation. If ForClass is true the list of class methods
232 /// will be emitted, otherwise the list of instance methods will be
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000233 /// generated. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000234 llvm::Constant *EmitMethodList(const std::string &Name,
235 const char *Section,
236 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
237 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000238
239 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000240 /// method declarations.
241 /// - TypeName: The name for the type containing the methods.
242 /// - IsProtocol: True iff these methods are for a protocol.
243 /// - ClassMethds: True iff these are class methods.
244 /// - Required: When true, only "required" methods are
245 /// listed. Similarly, when false only "optional" methods are
246 /// listed. For classes this should always be true.
247 /// - begin, end: The method list to output.
248 ///
249 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000250 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
251 bool IsProtocol,
252 bool ClassMethods,
253 bool Required,
254 ObjCMethodDecl * const *begin,
255 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000256
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000257 /// EmitPropertyList - Emit the given property list. The return
258 /// value has type PropertyListPtrTy.
259 llvm::Constant *EmitPropertyList(const std::string &Name,
260 ObjCPropertyDecl * const *begin,
261 ObjCPropertyDecl * const *end);
262
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000263 /// EmitProtocolExtension - Generate the protocol extension
264 /// structure used to store optional instance and class methods, and
265 /// protocol properties. The return value has type
266 /// ProtocolExtensionPtrTy.
267 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
268
269 /// EmitProtocolList - Generate the list of referenced
270 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc933702008-08-21 21:57:41 +0000271 llvm::Constant *EmitProtocolList(const std::string &Name,
272 ObjCProtocolDecl::protocol_iterator begin,
273 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000274
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000275 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
276 /// for the given selector.
277 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
278
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000279 /// GetProtocolRef - Return a reference to the internal protocol
280 /// description, creating an empty one if it has not been
281 /// defined. The return value has type pointer-to ProtocolTy.
282 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
283
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000284 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000285 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000286 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000287
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000288 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000289 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000290 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000291 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000292 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000293
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000294 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000295 /// selector's name. The return value has type char *.
296
297 // FIXME: This is a horrible name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000298 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000299 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000300
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000301 /// GetPropertyName - Return a unique constant for the given
302 /// name. The return value has type char *.
303 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
304
305 // FIXME: This is a horrible name too.
306 llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
307
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000308 /// GetNameForMethod - Return a name for the given method.
309 /// \param[out] NameOut - The return value.
310 void GetNameForMethod(const ObjCMethodDecl *OMD,
311 std::string &NameOut);
312
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000313public:
314 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000315 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000316
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000317 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
318 const ObjCMessageExpr *E,
319 llvm::Value *Receiver);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000320
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000321 virtual CodeGen::RValue
322 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
323 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000324 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000325 llvm::Value *Receiver);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000326
327 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000328 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000329
330 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
331
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000332 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000333
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000334 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000335
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000336 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000337
338 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000339 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000340
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000341 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000342
343 virtual llvm::Function *ModuleInitFunction();
344};
345} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000346
347/* *** Helper Functions *** */
348
349/// getConstantGEP() - Help routine to construct simple GEPs.
350static llvm::Constant *getConstantGEP(llvm::Constant *C,
351 unsigned idx0,
352 unsigned idx1) {
353 llvm::Value *Idxs[] = {
354 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
355 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
356 };
357 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
358}
359
360/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000361
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000362CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
363 : CGM(cgm),
364 ObjCTypes(cgm),
365 ObjCABI(1)
366{
367 // FIXME: How does this get set in GCC? And what does it even mean?
368 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
369 ObjCABI = 2;
370
371 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000372}
373
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000374/// GetClass - Return a reference to the class for the given interface
375/// decl.
376llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000377 const ObjCInterfaceDecl *ID) {
378 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000379}
380
381/// GetSelector - Return the pointer to the unique'd string for this selector.
382llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000383 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000384}
385
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000386/// Generate a constant CFString object.
387/*
388 struct __builtin_CFString {
389 const int *isa; // point to __CFConstantStringClassReference
390 int flags;
391 const char *str;
392 long length;
393 };
394*/
395
396llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbar3e9df992008-08-23 18:37:06 +0000397 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000398}
399
400/// Generates a message send where the super is the receiver. This is
401/// a message send to self with special delivery semantics indicating
402/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000403CodeGen::RValue
404CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
405 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000406 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000407 llvm::Value *Receiver) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000408 // FIXME: This should be cached, not looked up every time. Meh. We
409 // should just make sure the optimizer hits it.
410 llvm::Value *ReceiverClass = EmitClassRef(CGF.Builder, SuperClass);
411
412 // Create and init a super structure; this is a (receiver, class)
413 // pair we will pass to objc_msgSendSuper.
414 llvm::Value *ObjCSuper =
415 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
416 llvm::Value *ReceiverAsObject =
417 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
418 CGF.Builder.CreateStore(ReceiverAsObject,
419 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
420 CGF.Builder.CreateStore(ReceiverClass,
421 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
422
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000423 return EmitMessageSend(CGF, E, ObjCSuper, true);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000424}
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000425
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000426/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000427CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
428 const ObjCMessageExpr *E,
429 llvm::Value *Receiver) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000430 llvm::Value *Arg0 =
431 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
432 return EmitMessageSend(CGF, E, Arg0, false);
433}
434
435CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
436 const ObjCMessageExpr *E,
437 llvm::Value *Arg0,
438 bool IsSuper) {
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000439 llvm::Value *Args[2];
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000440 Args[0] = Arg0;
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000441 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000442
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000443 // FIXME: This is a hack, we are implicitly coordinating with
444 // EmitCallExprExt, which will move the return type to the first
445 // parameter and set the structure return flag. See
446 // getMessageSendFn().
447
448
449 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
450 return CGF.EmitCallExprExt(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),
451 E->getType(),
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000452 E->arg_begin(),
453 E->arg_end(),
454 Args, 2);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000455}
456
457llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000458 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000459 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
460 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000461}
462
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000463/*
464 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
465 struct _objc_protocol {
466 struct _objc_protocol_extension *isa;
467 char *protocol_name;
468 struct _objc_protocol_list *protocol_list;
469 struct _objc__method_prototype_list *instance_methods;
470 struct _objc__method_prototype_list *class_methods
471 };
472
473 See EmitProtocolExtension().
474*/
475void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000476 // FIXME: I don't understand why gcc generates this, or where it is
477 // resolved. Investigate. Its also wasteful to look this up over and
478 // over.
479 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
480
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000481 const char *ProtocolName = PD->getName();
482
483 std::vector<llvm::Constant*> Values(5);
484 Values[0] = EmitProtocolExtension(PD);
485 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000486 Values[2] =
487 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
488 PD->protocol_begin(),
489 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000490 Values[3] = EmitMethodDescList(ProtocolName,
491 true, // IsProtocol
492 false, // ClassMethods
493 true, // Required
494 PD->instmeth_begin(),
495 PD->instmeth_end());
496 Values[4] = EmitMethodDescList(ProtocolName,
497 true, // IsProtocol
498 true, // ClassMethods
499 true, // Required
500 PD->classmeth_begin(),
501 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000502 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
503 Values);
504
505 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
506 if (Entry) {
507 // Already created, just update the initializer
508 Entry->setInitializer(Init);
509 } else {
510 Entry =
511 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
512 llvm::GlobalValue::InternalLinkage,
513 Init,
514 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
515 &CGM.getModule());
516 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
517 UsedGlobals.push_back(Entry);
518 // FIXME: Is this necessary? Why only for protocol?
519 Entry->setAlignment(4);
520 }
521}
522
523llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
524 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
525
526 if (!Entry) {
527 std::vector<llvm::Constant*> Values(5);
528 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
529 Values[1] = GetClassName(PD->getIdentifier());
530 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
531 Values[3] = Values[4] =
532 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
533 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
534 Values);
535
536 Entry =
537 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
538 llvm::GlobalValue::InternalLinkage,
539 Init,
540 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
541 &CGM.getModule());
542 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
543 UsedGlobals.push_back(Entry);
544 // FIXME: Is this necessary? Why only for protocol?
545 Entry->setAlignment(4);
546 }
547
548 return Entry;
549}
550
551/*
552 struct _objc_protocol_extension {
553 uint32_t size;
554 struct objc_method_description_list *optional_instance_methods;
555 struct objc_method_description_list *optional_class_methods;
556 struct objc_property_list *instance_properties;
557 };
558*/
559llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
560 uint64_t Size =
561 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
562 std::vector<llvm::Constant*> Values(4);
563 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000564 Values[1] = EmitMethodDescList(PD->getName(),
565 true, // IsProtocol
566 false, // ClassMethods
567 false, // Required
568 PD->instmeth_begin(),
569 PD->instmeth_end());
570 Values[2] = EmitMethodDescList(PD->getName(),
571 true, // IsProtocol
572 true, // ClassMethods
573 false, // Required
574 PD->classmeth_begin(),
575 PD->classmeth_end());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000576 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
577 PD->getName(),
578 PD->classprop_begin(),
579 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000580
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000581 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000582 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
583 Values[3]->isNullValue())
584 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
585
586 llvm::Constant *Init =
587 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
588 llvm::GlobalVariable *GV =
589 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
590 llvm::GlobalValue::InternalLinkage,
591 Init,
592 (std::string("\01L_OBJC_PROTOCOLEXT_") +
593 PD->getName()),
594 &CGM.getModule());
595 // No special section, but goes in llvm.used
596 UsedGlobals.push_back(GV);
597
598 return GV;
599}
600
601/*
602 struct objc_protocol_list {
603 struct objc_protocol_list *next;
604 long count;
605 Protocol *list[];
606 };
607*/
Daniel Dunbardbc933702008-08-21 21:57:41 +0000608llvm::Constant *
609CGObjCMac::EmitProtocolList(const std::string &Name,
610 ObjCProtocolDecl::protocol_iterator begin,
611 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000612 std::vector<llvm::Constant*> ProtocolRefs;
613
Daniel Dunbardbc933702008-08-21 21:57:41 +0000614 for (; begin != end; ++begin)
615 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000616
617 // Just return null for empty protocol lists
618 if (ProtocolRefs.empty())
619 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
620
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000621 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000622 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
623
624 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000625 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000626 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
627 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
628 Values[2] =
629 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
630 ProtocolRefs.size()),
631 ProtocolRefs);
632
633 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
634 llvm::GlobalVariable *GV =
635 new llvm::GlobalVariable(Init->getType(), false,
636 llvm::GlobalValue::InternalLinkage,
637 Init,
Daniel Dunbardbc933702008-08-21 21:57:41 +0000638 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000639 &CGM.getModule());
640 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
641 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
642}
643
644/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000645 struct _objc_property {
646 const char * const name;
647 const char * const attributes;
648 };
649
650 struct _objc_property_list {
651 uint32_t entsize; // sizeof (struct _objc_property)
652 uint32_t prop_count;
653 struct _objc_property[prop_count];
654 };
655*/
656llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
657 ObjCPropertyDecl * const *begin,
658 ObjCPropertyDecl * const *end) {
659 std::vector<llvm::Constant*> Properties, Prop(2);
660 for (; begin != end; ++begin) {
661 const ObjCPropertyDecl *PD = *begin;
662 Prop[0] = GetPropertyName(PD->getIdentifier());
663 Prop[1] = GetPropertyType(PD);
664 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
665 Prop));
666 }
667
668 // Return null for empty list.
669 if (Properties.empty())
670 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
671
672 unsigned PropertySize =
673 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
674 std::vector<llvm::Constant*> Values(3);
675 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
676 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
677 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
678 Properties.size());
679 Values[2] = llvm::ConstantArray::get(AT, Properties);
680 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
681
682 llvm::GlobalVariable *GV =
683 new llvm::GlobalVariable(Init->getType(), false,
684 llvm::GlobalValue::InternalLinkage,
685 Init,
686 Name,
687 &CGM.getModule());
688 // No special section on property lists?
689 UsedGlobals.push_back(GV);
690 return llvm::ConstantExpr::getBitCast(GV,
691 ObjCTypes.PropertyListPtrTy);
692
693}
694
695/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000696 struct objc_method_description_list {
697 int count;
698 struct objc_method_description list[];
699 };
700*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000701llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
702 bool IsProtocol,
703 bool ClassMethods,
704 bool Required,
705 ObjCMethodDecl * const *begin,
706 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000707 std::vector<llvm::Constant*> Methods, Desc(2);
708 for (; begin != end; ++begin) {
709 ObjCMethodDecl *D = *begin;
710 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
711
712 // Skip if this method is required and we are outputting optional
713 // methods, or vice versa.
714 if (Required != IsRequired)
715 continue;
716
717 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
718 ObjCTypes.SelectorPtrTy);
719 Desc[1] = GetMethodVarType(D);
720 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
721 Desc));
722 }
723
724 // Return null for empty list.
725 if (Methods.empty())
726 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
727
728 std::vector<llvm::Constant*> Values(2);
729 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
730 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
731 Methods.size());
732 Values[1] = llvm::ConstantArray::get(AT, Methods);
733 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
734
735 char Prefix[256];
736 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
737 IsProtocol ? "PROTOCOL_" : "",
738 ClassMethods ? "CLASS_" : "INSTANCE_",
739 !Required ? "OPT_" : "");
740 llvm::GlobalVariable *GV =
741 new llvm::GlobalVariable(Init->getType(), false,
742 llvm::GlobalValue::InternalLinkage,
743 Init,
744 std::string(Prefix) + TypeName,
745 &CGM.getModule());
746 if (ClassMethods) {
747 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
748 } else {
749 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
750 }
751 UsedGlobals.push_back(GV);
752 return llvm::ConstantExpr::getBitCast(GV,
753 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000754}
755
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000756/*
757 struct _objc_category {
758 char *category_name;
759 char *class_name;
760 struct _objc_method_list *instance_methods;
761 struct _objc_method_list *class_methods;
762 struct _objc_protocol_list *protocols;
763 uint32_t size; // <rdar://4585769>
764 struct _objc_property_list *instance_properties;
765 };
766 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000767void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000768 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
769
770 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
771 std::string ExtName(std::string(Interface->getName()) +
772 "_" +
773 OCD->getName());
774
775 std::vector<llvm::Constant*> Values(7);
776 Values[0] = GetClassName(OCD->getIdentifier());
777 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000778 Values[2] =
779 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
780 ExtName,
781 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
782 OCD->instmeth_begin(),
783 OCD->instmeth_end());
784 Values[3] =
785 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
786 "__OBJC,__cat_class_meth,regular,no_dead_strip",
787 OCD->classmeth_begin(),
788 OCD->classmeth_end());
789 Values[4] =
790 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
791 Interface->protocol_begin(),
792 Interface->protocol_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000793 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000794 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
795 Interface->classprop_begin(),
796 Interface->classprop_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000797
798 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
799 Values);
800
801 llvm::GlobalVariable *GV =
802 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
803 llvm::GlobalValue::InternalLinkage,
804 Init,
805 std::string("\01L_OBJC_CATEGORY_")+ExtName,
806 &CGM.getModule());
807 GV->setSection("__OBJC,__category,regular,no_dead_strip");
808 UsedGlobals.push_back(GV);
809 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000810}
811
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000812// FIXME: Get from somewhere?
813enum ClassFlags {
814 eClassFlags_Factory = 0x00001,
815 eClassFlags_Meta = 0x00002,
816 // <rdr://5142207>
817 eClassFlags_HasCXXStructors = 0x02000,
818 eClassFlags_Hidden = 0x20000,
819 eClassFlags_ABI2_Hidden = 0x00010,
820 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
821};
822
823// <rdr://5142207&4705298&4843145>
824static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
825 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
826 // FIXME: Support -fvisibility
827 switch (attr->getVisibility()) {
828 default:
829 assert(0 && "Unknown visibility");
830 return false;
831 case VisibilityAttr::DefaultVisibility:
832 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
833 return false;
834 case VisibilityAttr::HiddenVisibility:
835 return true;
836 }
837 } else {
838 return false; // FIXME: Support -fvisibility
839 }
840}
841
842/*
843 struct _objc_class {
844 Class isa;
845 Class super_class;
846 const char *name;
847 long version;
848 long info;
849 long instance_size;
850 struct _objc_ivar_list *ivars;
851 struct _objc_method_list *methods;
852 struct _objc_cache *cache;
853 struct _objc_protocol_list *protocols;
854 // Objective-C 1.0 extensions (<rdr://4585769>)
855 const char *ivar_layout;
856 struct _objc_class_ext *ext;
857 };
858
859 See EmitClassExtension();
860 */
861void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000862 DefinedSymbols.insert(ID->getIdentifier());
863
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000864 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000865 // FIXME: Gross
866 ObjCInterfaceDecl *Interface =
867 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000868 llvm::Constant *Protocols =
869 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
870 Interface->protocol_begin(),
871 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000872 const llvm::Type *InterfaceTy =
873 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
874 unsigned Flags = eClassFlags_Factory;
875 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
876
877 // FIXME: Set CXX-structors flag.
878 if (IsClassHidden(ID->getClassInterface()))
879 Flags |= eClassFlags_Hidden;
880
881 std::vector<llvm::Constant*> Values(12);
882 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
883 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000884 // Record a reference to the super class.
885 LazySymbols.insert(Super->getIdentifier());
886
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000887 Values[ 1] =
888 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
889 ObjCTypes.ClassPtrTy);
890 } else {
891 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
892 }
893 Values[ 2] = GetClassName(ID->getIdentifier());
894 // Version is always 0.
895 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
896 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
897 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
898 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000899 Values[ 7] =
900 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
901 "__OBJC,__inst_meth,regular,no_dead_strip",
902 ID->instmeth_begin(),
903 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000904 // cache is always NULL.
905 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
906 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000907 // FIXME: Set ivar_layout
908 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000909 Values[11] = EmitClassExtension(ID);
910 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
911 Values);
912
913 llvm::GlobalVariable *GV =
914 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
915 llvm::GlobalValue::InternalLinkage,
916 Init,
917 std::string("\01L_OBJC_CLASS_")+ClassName,
918 &CGM.getModule());
919 GV->setSection("__OBJC,__class,regular,no_dead_strip");
920 UsedGlobals.push_back(GV);
921 // FIXME: Why?
922 GV->setAlignment(32);
923 DefinedClasses.push_back(GV);
924}
925
926llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
927 llvm::Constant *Protocols,
928 const llvm::Type *InterfaceTy) {
929 const char *ClassName = ID->getName();
930 unsigned Flags = eClassFlags_Meta;
931 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
932
933 if (IsClassHidden(ID->getClassInterface()))
934 Flags |= eClassFlags_Hidden;
935
936 std::vector<llvm::Constant*> Values(12);
937 // The isa for the metaclass is the root of the hierarchy.
938 const ObjCInterfaceDecl *Root = ID->getClassInterface();
939 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
940 Root = Super;
941 Values[ 0] =
942 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
943 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000944 // The super class for the metaclass is emitted as the name of the
945 // super class. The runtime fixes this up to point to the
946 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000947 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
948 Values[ 1] =
949 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
950 ObjCTypes.ClassPtrTy);
951 } else {
952 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
953 }
954 Values[ 2] = GetClassName(ID->getIdentifier());
955 // Version is always 0.
956 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
957 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
958 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
959 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000960 Values[ 7] =
961 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
962 "__OBJC,__inst_meth,regular,no_dead_strip",
963 ID->classmeth_begin(),
964 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000965 // cache is always NULL.
966 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
967 Values[ 9] = Protocols;
968 // ivar_layout for metaclass is always NULL.
969 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
970 // The class extension is always unused for metaclasses.
971 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
972 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
973 Values);
974
975 llvm::GlobalVariable *GV =
976 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
977 llvm::GlobalValue::InternalLinkage,
978 Init,
979 std::string("\01L_OBJC_METACLASS_")+ClassName,
980 &CGM.getModule());
981 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
982 UsedGlobals.push_back(GV);
983 // FIXME: Why?
984 GV->setAlignment(32);
985
986 return GV;
987}
988
989/*
990 struct objc_class_ext {
991 uint32_t size;
992 const char *weak_ivar_layout;
993 struct _objc_property_list *properties;
994 };
995*/
996llvm::Constant *
997CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
998 uint64_t Size =
999 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1000
1001 std::vector<llvm::Constant*> Values(3);
1002 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001003 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001004 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001005 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1006 ID->getName(),
1007 ID->getClassInterface()->classprop_begin(),
1008 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001009
1010 // Return null if no extension bits are used.
1011 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1012 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1013
1014 llvm::Constant *Init =
1015 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1016 llvm::GlobalVariable *GV =
1017 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1018 llvm::GlobalValue::InternalLinkage,
1019 Init,
1020 (std::string("\01L_OBJC_CLASSEXT_") +
1021 ID->getName()),
1022 &CGM.getModule());
1023 // No special section, but goes in llvm.used
1024 UsedGlobals.push_back(GV);
1025
1026 return GV;
1027}
1028
1029/*
1030 struct objc_ivar {
1031 char *ivar_name;
1032 char *ivar_type;
1033 int ivar_offset;
1034 };
1035
1036 struct objc_ivar_list {
1037 int ivar_count;
1038 struct objc_ivar list[count];
1039 };
1040 */
1041llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1042 bool ForClass,
1043 const llvm::Type *InterfaceTy) {
1044 std::vector<llvm::Constant*> Ivars, Ivar(3);
1045
1046 // When emitting the root class GCC emits ivar entries for the
1047 // actual class structure. It is not clear if we need to follow this
1048 // behavior; for now lets try and get away with not doing it. If so,
1049 // the cleanest solution would be to make up an ObjCInterfaceDecl
1050 // for the class.
1051 if (ForClass)
1052 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1053
1054 const llvm::StructLayout *Layout =
1055 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1056 for (ObjCInterfaceDecl::ivar_iterator
1057 i = ID->getClassInterface()->ivar_begin(),
1058 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1059 ObjCIvarDecl *V = *i;
1060 unsigned Offset =
1061 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1062 std::string TypeStr;
1063 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1064 Ivar[0] = GetMethodVarName(V->getIdentifier());
1065 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1066 EncodingRecordTypes);
1067 Ivar[1] = GetMethodVarType(TypeStr);
1068 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1069 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1070 Ivar));
1071 }
1072
1073 // Return null for empty list.
1074 if (Ivars.empty())
1075 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1076
1077 std::vector<llvm::Constant*> Values(2);
1078 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1079 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1080 Ivars.size());
1081 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1082 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1083
1084 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1085 "\01L_OBJC_INSTANCE_VARIABLES_");
1086 llvm::GlobalVariable *GV =
1087 new llvm::GlobalVariable(Init->getType(), false,
1088 llvm::GlobalValue::InternalLinkage,
1089 Init,
1090 std::string(Prefix) + ID->getName(),
1091 &CGM.getModule());
1092 if (ForClass) {
1093 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1094 // FIXME: Why is this only here?
1095 GV->setAlignment(32);
1096 } else {
1097 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1098 }
1099 UsedGlobals.push_back(GV);
1100 return llvm::ConstantExpr::getBitCast(GV,
1101 ObjCTypes.IvarListPtrTy);
1102}
1103
1104/*
1105 struct objc_method {
1106 SEL method_name;
1107 char *method_types;
1108 void *method;
1109 };
1110
1111 struct objc_method_list {
1112 struct objc_method_list *obsolete;
1113 int count;
1114 struct objc_method methods_list[count];
1115 };
1116*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001117llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1118 const char *Section,
1119 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1120 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001121 std::vector<llvm::Constant*> Methods, Method(3);
1122
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001123 for (; begin != end; ++begin) {
1124 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001125
1126 Method[0] =
1127 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1128 ObjCTypes.SelectorPtrTy);
1129 Method[1] = GetMethodVarType(MD);
1130
1131 // FIXME: This is gross, we shouldn't be looking up by name.
1132 std::string Name;
1133 GetNameForMethod(MD, Name);
1134 Method[2] =
1135 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1136 ObjCTypes.Int8PtrTy);
1137 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1138 Method));
1139 }
1140
1141 // Return null for empty list.
1142 if (Methods.empty())
1143 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1144
1145 std::vector<llvm::Constant*> Values(3);
1146 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1147 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1148 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1149 Methods.size());
1150 Values[2] = llvm::ConstantArray::get(AT, Methods);
1151 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1152
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001153 llvm::GlobalVariable *GV =
1154 new llvm::GlobalVariable(Init->getType(), false,
1155 llvm::GlobalValue::InternalLinkage,
1156 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001157 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001158 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001159 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001160 UsedGlobals.push_back(GV);
1161 return llvm::ConstantExpr::getBitCast(GV,
1162 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001163}
1164
1165llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1166 const llvm::Type *ReturnTy =
1167 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1168 const llvm::Type *SelfTy =
1169 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1170
1171 std::vector<const llvm::Type*> ArgTys;
1172 ArgTys.reserve(1 + 2 + OMD->param_size());
1173
1174 // FIXME: This is not something we should have to be dealing with
1175 // here.
1176 bool useStructRet =
1177 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1178 if (useStructRet) {
1179 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1180 ReturnTy = llvm::Type::VoidTy;
1181 }
1182
1183 // Implicit arguments
1184 ArgTys.push_back(SelfTy);
1185 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1186
1187 for (ObjCMethodDecl::param_const_iterator
1188 i = OMD->param_begin(), e = OMD->param_end();
1189 i != e; ++i) {
1190 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001191 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001192 ArgTys.push_back(Ty);
1193 } else {
1194 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1195 }
1196 }
1197
1198 std::string Name;
1199 GetNameForMethod(OMD, Name);
1200
1201 llvm::Function *Method =
1202 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1203 ArgTys,
1204 OMD->isVariadic()),
1205 llvm::GlobalValue::InternalLinkage,
1206 Name,
1207 &CGM.getModule());
1208
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001209 unsigned Offset = 3; // Return plus self and selector implicit args.
1210 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001211 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001212 ++Offset;
1213 }
1214
1215 // FIXME: This is horrible, we need to be reusing the machinery in
1216 // CodeGenModule.cpp (SetFunctionAttributes).
1217 for (ObjCMethodDecl::param_const_iterator
1218 i = OMD->param_begin(), e = OMD->param_end();
1219 i != e; ++i, ++Offset) {
1220 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1221 if (!Ty->isSingleValueType())
1222 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1223 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001224
1225 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001226}
1227
1228llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001229 // Abuse this interface function as a place to finalize.
1230 FinishModule();
1231
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001232 return NULL;
1233}
1234
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001235/* *** Private Interface *** */
1236
1237/// EmitImageInfo - Emit the image info marker used to encode some module
1238/// level information.
1239///
1240/// See: <rdr://4810609&4810587&4810587>
1241/// struct IMAGE_INFO {
1242/// unsigned version;
1243/// unsigned flags;
1244/// };
1245enum ImageInfoFlags {
1246 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1247 eImageInfo_GarbageCollected = (1 << 1),
1248 eImageInfo_GCOnly = (1 << 2)
1249};
1250
1251void CGObjCMac::EmitImageInfo() {
1252 unsigned version = 0; // Version is unused?
1253 unsigned flags = 0;
1254
1255 // FIXME: Fix and continue?
1256 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1257 flags |= eImageInfo_GarbageCollected;
1258 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1259 flags |= eImageInfo_GCOnly;
1260
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001261 // Emitted as int[2];
1262 llvm::Constant *values[2] = {
1263 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1264 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1265 };
1266 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001267 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001268 new llvm::GlobalVariable(AT, true,
1269 llvm::GlobalValue::InternalLinkage,
1270 llvm::ConstantArray::get(AT, values, 2),
1271 "\01L_OBJC_IMAGE_INFO",
1272 &CGM.getModule());
1273
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001274 if (ObjCABI == 1) {
1275 GV->setSection("__OBJC, __image_info,regular");
1276 } else {
1277 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1278 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001279
1280 UsedGlobals.push_back(GV);
1281}
1282
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001283
1284// struct objc_module {
1285// unsigned long version;
1286// unsigned long size;
1287// const char *name;
1288// Symtab symtab;
1289// };
1290
1291// FIXME: Get from somewhere
1292static const int ModuleVersion = 7;
1293
1294void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001295 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1296
1297 std::vector<llvm::Constant*> Values(4);
1298 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1299 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001300 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001301 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001302 Values[3] = EmitModuleSymbols();
1303
1304 llvm::GlobalVariable *GV =
1305 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1306 llvm::GlobalValue::InternalLinkage,
1307 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1308 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001309 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001310 &CGM.getModule());
1311 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1312 UsedGlobals.push_back(GV);
1313}
1314
1315llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001316 unsigned NumClasses = DefinedClasses.size();
1317 unsigned NumCategories = DefinedCategories.size();
1318
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001319 // Return null if no symbols were defined.
1320 if (!NumClasses && !NumCategories)
1321 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
1322
1323 std::vector<llvm::Constant*> Values(5);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001324 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1325 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1326 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1327 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1328
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001329 // The runtime expects exactly the list of defined classes followed
1330 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001331 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001332 for (unsigned i=0; i<NumClasses; i++)
1333 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1334 ObjCTypes.Int8PtrTy);
1335 for (unsigned i=0; i<NumCategories; i++)
1336 Symbols[NumClasses + i] =
1337 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1338 ObjCTypes.Int8PtrTy);
1339
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001340 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001341 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001342 NumClasses + NumCategories),
1343 Symbols);
1344
1345 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1346
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001347 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001348 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001349 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001350 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001351 "\01L_OBJC_SYMBOLS",
1352 &CGM.getModule());
1353 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1354 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001355 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1356}
1357
1358llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1359 const ObjCInterfaceDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001360 LazySymbols.insert(ID->getIdentifier());
1361
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001362 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1363
1364 if (!Entry) {
1365 llvm::Constant *Casted =
1366 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1367 ObjCTypes.ClassPtrTy);
1368 Entry =
1369 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1370 llvm::GlobalValue::InternalLinkage,
1371 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1372 &CGM.getModule());
1373 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1374 UsedGlobals.push_back(Entry);
1375 }
1376
1377 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001378}
1379
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001380llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1381 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1382
1383 if (!Entry) {
1384 llvm::Constant *Casted =
1385 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1386 ObjCTypes.SelectorPtrTy);
1387 Entry =
1388 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1389 llvm::GlobalValue::InternalLinkage,
1390 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1391 &CGM.getModule());
1392 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1393 UsedGlobals.push_back(Entry);
1394 }
1395
1396 return Builder.CreateLoad(Entry, false, "tmp");
1397}
1398
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001399llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1400 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001401
1402 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001403 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001404 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001405 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001406 llvm::GlobalValue::InternalLinkage,
1407 C, "\01L_OBJC_CLASS_NAME_",
1408 &CGM.getModule());
1409 Entry->setSection("__TEXT,__cstring,cstring_literals");
1410 UsedGlobals.push_back(Entry);
1411 }
1412
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001413 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001414}
1415
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001416llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1417 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1418
1419 if (!Entry) {
1420 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1421 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001422 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001423 llvm::GlobalValue::InternalLinkage,
1424 C, "\01L_OBJC_METH_VAR_NAME_",
1425 &CGM.getModule());
1426 Entry->setSection("__TEXT,__cstring,cstring_literals");
1427 UsedGlobals.push_back(Entry);
1428 }
1429
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001430 return getConstantGEP(Entry, 0, 0);
1431}
1432
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001433// FIXME: Merge into a single cstring creation function.
1434llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1435 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1436}
1437
1438// FIXME: Merge into a single cstring creation function.
1439llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1440 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1441}
1442
1443llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1444 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001445
1446 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001447 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001448 Entry =
1449 new llvm::GlobalVariable(C->getType(), false,
1450 llvm::GlobalValue::InternalLinkage,
1451 C, "\01L_OBJC_METH_VAR_TYPE_",
1452 &CGM.getModule());
1453 Entry->setSection("__TEXT,__cstring,cstring_literals");
1454 UsedGlobals.push_back(Entry);
1455 }
1456
1457 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001458}
1459
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001460// FIXME: Merge into a single cstring creation function.
1461llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1462 std::string TypeStr;
1463 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1464 return GetMethodVarType(TypeStr);
1465}
1466
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001467// FIXME: Merge into a single cstring creation function.
1468llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1469 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1470
1471 if (!Entry) {
1472 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1473 Entry =
1474 new llvm::GlobalVariable(C->getType(), false,
1475 llvm::GlobalValue::InternalLinkage,
1476 C, "\01L_OBJC_PROP_NAME_ATTR_",
1477 &CGM.getModule());
1478 Entry->setSection("__TEXT,__cstring,cstring_literals");
1479 UsedGlobals.push_back(Entry);
1480 }
1481
1482 return getConstantGEP(Entry, 0, 0);
1483}
1484
1485// FIXME: Merge into a single cstring creation function.
1486llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1487 std::string TypeStr("MOOO!");
1488 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1489 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1490}
1491
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001492void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1493 std::string &NameOut) {
1494 // FIXME: Find the mangling GCC uses.
1495 std::stringstream s;
1496 s << (D->isInstance() ? "-" : "+");
1497 s << "[";
1498 s << D->getClassInterface()->getName();
1499 s << " ";
1500 s << D->getSelector().getName();
1501 s << "]";
1502 NameOut = s.str();
1503}
1504
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001505void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001506 EmitModuleInfo();
1507
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001508 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001509
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001510 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001511 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001512 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001513 }
1514
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001515 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001516 llvm::GlobalValue *GV =
1517 new llvm::GlobalVariable(AT, false,
1518 llvm::GlobalValue::AppendingLinkage,
1519 llvm::ConstantArray::get(AT, Used),
1520 "llvm.used",
1521 &CGM.getModule());
1522
1523 GV->setSection("llvm.metadata");
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001524
1525 // Add assembler directives to add lazy undefined symbol references
1526 // for classes which are referenced but not defined. This is
1527 // important for correct linker interaction.
1528
1529 // FIXME: Uh, this isn't particularly portable.
1530 std::stringstream s;
1531 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
1532 e = LazySymbols.end(); i != e; ++i) {
1533 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
1534 }
1535 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
1536 e = DefinedSymbols.end(); i != e; ++i) {
1537 s << "\t.objc_class_name_" << (*i)->getName() << " = 0\n"
1538 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
1539 }
1540 CGM.getModule().appendModuleInlineAsm(s.str());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001541}
1542
1543/* *** */
1544
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001545ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbar3e9df992008-08-23 18:37:06 +00001546 : CGM(cgm)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001547{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001548 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1549 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001550
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001551 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001552 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001553 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001554 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1555
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001556 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1557 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001558
1559 // FIXME: It would be nice to unify this with the opaque type, so
1560 // that the IR comes out a bit cleaner.
1561 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1562 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001563
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001564 MethodDescriptionTy =
1565 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001566 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001567 NULL);
1568 CGM.getModule().addTypeName("struct._objc_method_description",
1569 MethodDescriptionTy);
1570
1571 MethodDescriptionListTy =
1572 llvm::StructType::get(IntTy,
1573 llvm::ArrayType::get(MethodDescriptionTy, 0),
1574 NULL);
1575 CGM.getModule().addTypeName("struct._objc_method_description_list",
1576 MethodDescriptionListTy);
1577 MethodDescriptionListPtrTy =
1578 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1579
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001580 PropertyTy = llvm::StructType::get(Int8PtrTy,
1581 Int8PtrTy,
1582 NULL);
1583 CGM.getModule().addTypeName("struct._objc_property",
1584 PropertyTy);
1585
1586 PropertyListTy = llvm::StructType::get(IntTy,
1587 IntTy,
1588 llvm::ArrayType::get(PropertyTy, 0),
1589 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001590 CGM.getModule().addTypeName("struct._objc_property_list",
1591 PropertyListTy);
1592 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1593
1594 // Protocol description structures
1595
1596 ProtocolExtensionTy =
1597 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1598 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1599 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1600 PropertyListPtrTy,
1601 NULL);
1602 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1603 ProtocolExtensionTy);
1604 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1605
1606 // Handle recursive construction of Protocl and ProtocolList types
1607
1608 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1609 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1610
1611 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1612 LongTy,
1613 llvm::ArrayType::get(ProtocolTyHolder, 0),
1614 NULL);
1615 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1616
1617 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001618 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001619 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1620 MethodDescriptionListPtrTy,
1621 MethodDescriptionListPtrTy,
1622 NULL);
1623 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1624
1625 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1626 CGM.getModule().addTypeName("struct._objc_protocol_list",
1627 ProtocolListTy);
1628 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1629
1630 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1631 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1632 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001633
1634 // Class description structures
1635
1636 IvarTy = llvm::StructType::get(Int8PtrTy,
1637 Int8PtrTy,
1638 IntTy,
1639 NULL);
1640 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1641
1642 IvarListTy = llvm::OpaqueType::get();
1643 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1644 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1645
1646 MethodTy = llvm::StructType::get(SelectorPtrTy,
1647 Int8PtrTy,
1648 Int8PtrTy,
1649 NULL);
1650 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1651
1652 MethodListTy = llvm::OpaqueType::get();
1653 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1654 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1655
1656 CacheTy = llvm::OpaqueType::get();
1657 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1658 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1659
1660 ClassExtensionTy =
1661 llvm::StructType::get(IntTy,
1662 Int8PtrTy,
1663 PropertyListPtrTy,
1664 NULL);
1665 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1666 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1667
1668 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1669
1670 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1671 llvm::PointerType::getUnqual(ClassTyHolder),
1672 Int8PtrTy,
1673 LongTy,
1674 LongTy,
1675 LongTy,
1676 IvarListPtrTy,
1677 MethodListPtrTy,
1678 CachePtrTy,
1679 ProtocolListPtrTy,
1680 Int8PtrTy,
1681 ClassExtensionPtrTy,
1682 NULL);
1683 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1684
1685 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1686 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1687 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1688
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001689 CategoryTy = llvm::StructType::get(Int8PtrTy,
1690 Int8PtrTy,
1691 MethodListPtrTy,
1692 MethodListPtrTy,
1693 ProtocolListPtrTy,
1694 IntTy,
1695 PropertyListPtrTy,
1696 NULL);
1697 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1698
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001699 SuperTy =
1700 llvm::StructType::get(ObjectPtrTy,
1701 ClassPtrTy,
1702 NULL);
1703 CGM.getModule().addTypeName("struct._objc_super",
1704 SuperTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001705 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001706
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001707 // Global metadata structures
1708
1709 SymtabTy = llvm::StructType::get(LongTy,
1710 SelectorPtrTy,
1711 ShortTy,
1712 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001713 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001714 NULL);
1715 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1716 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1717
1718 ModuleTy =
1719 llvm::StructType::get(LongTy,
1720 LongTy,
1721 Int8PtrTy,
1722 SymtabPtrTy,
1723 NULL);
1724 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001725
1726 // Message send functions
1727
1728 std::vector<const llvm::Type*> Params;
1729 Params.push_back(ObjectPtrTy);
1730 Params.push_back(SelectorPtrTy);
1731 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1732 Params,
1733 true),
1734 llvm::Function::ExternalLinkage,
1735 "objc_msgSend",
1736 &CGM.getModule());
1737
1738 Params.clear();
1739 Params.push_back(Int8PtrTy);
1740 Params.push_back(ObjectPtrTy);
1741 Params.push_back(SelectorPtrTy);
1742 MessageSendStretFn =
1743 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1744 Params,
1745 true),
1746 llvm::Function::ExternalLinkage,
1747 "objc_msgSend_stret",
1748 &CGM.getModule());
1749
1750 Params.clear();
1751 Params.push_back(SuperPtrTy);
1752 Params.push_back(SelectorPtrTy);
1753 MessageSendSuperFn =
1754 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1755 Params,
1756 true),
1757 llvm::Function::ExternalLinkage,
1758 "objc_msgSendSuper",
1759 &CGM.getModule());
1760
1761 Params.clear();
1762 Params.push_back(Int8PtrTy);
1763 Params.push_back(SuperPtrTy);
1764 Params.push_back(SelectorPtrTy);
1765 MessageSendSuperStretFn =
1766 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1767 Params,
1768 true),
1769 llvm::Function::ExternalLinkage,
1770 "objc_msgSendSuper_stret",
1771 &CGM.getModule());
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001772}
1773
1774ObjCTypesHelper::~ObjCTypesHelper() {
1775}
1776
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001777llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
1778 const llvm::Type *ReturnTy) {
1779 llvm::Function *F;
1780 llvm::FunctionType *CallFTy;
1781
1782 // FIXME: Should we be caching any of this?
1783 if (!ReturnTy->isSingleValueType()) {
1784 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
1785 std::vector<const llvm::Type*> Params(3);
1786 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
1787 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1788 Params[2] = SelectorPtrTy;
1789 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
1790 } else { // XXX floating point?
1791 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
1792 std::vector<const llvm::Type*> Params(2);
1793 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1794 Params[1] = SelectorPtrTy;
1795 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001796 }
1797
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001798 return llvm::ConstantExpr::getBitCast(F,
1799 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001800}
1801
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001802/* *** */
1803
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001804CodeGen::CGObjCRuntime *
1805CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001806 return new CGObjCMac(CGM);
1807}