blob: 50d3abee0ba4bdfc28adf3bc5182ce5c0257ed0c [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);
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000223
224 /// EmitMetaClass - Emit a forward reference to the class structure
225 /// for the metaclass of the given interface. The return value has
226 /// type ClassPtrTy.
227 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
228
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000229 /// EmitMetaClass - Emit a class structure for the metaclass of the
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000230 /// given implementation. The return value has type ClassPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000231 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
232 llvm::Constant *Protocols,
233 const llvm::Type *InterfaceTy);
234
235 /// EmitMethodList - Emit the method list for the given
Daniel Dunbaraf05bb92008-08-26 08:29:31 +0000236 /// implementation. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000237 llvm::Constant *EmitMethodList(const std::string &Name,
238 const char *Section,
239 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
240 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000241
242 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000243 /// method declarations.
244 /// - TypeName: The name for the type containing the methods.
245 /// - IsProtocol: True iff these methods are for a protocol.
246 /// - ClassMethds: True iff these are class methods.
247 /// - Required: When true, only "required" methods are
248 /// listed. Similarly, when false only "optional" methods are
249 /// listed. For classes this should always be true.
250 /// - begin, end: The method list to output.
251 ///
252 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000253 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
254 bool IsProtocol,
255 bool ClassMethods,
256 bool Required,
257 ObjCMethodDecl * const *begin,
258 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000259
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000260 /// EmitPropertyList - Emit the given property list. The return
261 /// value has type PropertyListPtrTy.
262 llvm::Constant *EmitPropertyList(const std::string &Name,
263 ObjCPropertyDecl * const *begin,
264 ObjCPropertyDecl * const *end);
265
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000266 /// EmitProtocolExtension - Generate the protocol extension
267 /// structure used to store optional instance and class methods, and
268 /// protocol properties. The return value has type
269 /// ProtocolExtensionPtrTy.
270 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
271
272 /// EmitProtocolList - Generate the list of referenced
273 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc933702008-08-21 21:57:41 +0000274 llvm::Constant *EmitProtocolList(const std::string &Name,
275 ObjCProtocolDecl::protocol_iterator begin,
276 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000277
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000278 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
279 /// for the given selector.
280 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
281
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000282 /// GetProtocolRef - Return a reference to the internal protocol
283 /// description, creating an empty one if it has not been
284 /// defined. The return value has type pointer-to ProtocolTy.
285 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
286
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000287 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000288 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000289 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000290
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000291 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000292 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000293 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000294 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000295 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000296
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000297 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000298 /// selector's name. The return value has type char *.
299
300 // FIXME: This is a horrible name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000301 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000302 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000303
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000304 /// GetPropertyName - Return a unique constant for the given
305 /// name. The return value has type char *.
306 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
307
308 // FIXME: This is a horrible name too.
309 llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
310
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000311 /// GetNameForMethod - Return a name for the given method.
312 /// \param[out] NameOut - The return value.
313 void GetNameForMethod(const ObjCMethodDecl *OMD,
314 std::string &NameOut);
315
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000316public:
317 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000318 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000319
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000320 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
321 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000322 llvm::Value *Receiver,
323 bool IsClassMessage);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000324
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000325 virtual CodeGen::RValue
326 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
327 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000328 const ObjCInterfaceDecl *Class,
329 llvm::Value *Receiver,
330 bool IsClassMessage);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000331
332 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000333 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000334
335 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
336
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000337 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000338
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000339 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000340
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000341 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000342
343 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000344 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000345
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000346 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000347
348 virtual llvm::Function *ModuleInitFunction();
349};
350} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000351
352/* *** Helper Functions *** */
353
354/// getConstantGEP() - Help routine to construct simple GEPs.
355static llvm::Constant *getConstantGEP(llvm::Constant *C,
356 unsigned idx0,
357 unsigned idx1) {
358 llvm::Value *Idxs[] = {
359 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
360 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
361 };
362 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
363}
364
365/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000366
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000367CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
368 : CGM(cgm),
369 ObjCTypes(cgm),
370 ObjCABI(1)
371{
372 // FIXME: How does this get set in GCC? And what does it even mean?
373 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
374 ObjCABI = 2;
375
376 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000377}
378
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000379/// GetClass - Return a reference to the class for the given interface
380/// decl.
381llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000382 const ObjCInterfaceDecl *ID) {
383 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000384}
385
386/// GetSelector - Return the pointer to the unique'd string for this selector.
387llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000388 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000389}
390
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000391/// Generate a constant CFString object.
392/*
393 struct __builtin_CFString {
394 const int *isa; // point to __CFConstantStringClassReference
395 int flags;
396 const char *str;
397 long length;
398 };
399*/
400
401llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbar3e9df992008-08-23 18:37:06 +0000402 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000403}
404
405/// Generates a message send where the super is the receiver. This is
406/// a message send to self with special delivery semantics indicating
407/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000408CodeGen::RValue
409CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
410 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000411 const ObjCInterfaceDecl *Class,
412 llvm::Value *Receiver,
413 bool IsClassMessage) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000414 // Create and init a super structure; this is a (receiver, class)
415 // pair we will pass to objc_msgSendSuper.
416 llvm::Value *ObjCSuper =
417 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
418 llvm::Value *ReceiverAsObject =
419 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
420 CGF.Builder.CreateStore(ReceiverAsObject,
421 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000422
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000423 // If this is a class message the metaclass is passed as the target.
424 llvm::Value *Target;
425 if (IsClassMessage) {
426 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
427 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
428 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
429 Target = Super;
430 } else {
431 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
432 }
433 CGF.Builder.CreateStore(Target,
434 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
435
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000436 return EmitMessageSend(CGF, E, ObjCSuper, true);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000437}
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000438
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000439/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000440CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
441 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000442 llvm::Value *Receiver,
443 bool IsClassMessage) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000444 llvm::Value *Arg0 =
445 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
446 return EmitMessageSend(CGF, E, Arg0, false);
447}
448
449CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
450 const ObjCMessageExpr *E,
451 llvm::Value *Arg0,
452 bool IsSuper) {
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000453 llvm::Value *Args[2];
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000454 Args[0] = Arg0;
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000455 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000456
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000457 // FIXME: This is a hack, we are implicitly coordinating with
458 // EmitCallExprExt, which will move the return type to the first
459 // parameter and set the structure return flag. See
460 // getMessageSendFn().
461
462
463 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
464 return CGF.EmitCallExprExt(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),
465 E->getType(),
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000466 E->arg_begin(),
467 E->arg_end(),
468 Args, 2);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000469}
470
471llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000472 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000473 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
474 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000475}
476
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000477/*
478 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
479 struct _objc_protocol {
480 struct _objc_protocol_extension *isa;
481 char *protocol_name;
482 struct _objc_protocol_list *protocol_list;
483 struct _objc__method_prototype_list *instance_methods;
484 struct _objc__method_prototype_list *class_methods
485 };
486
487 See EmitProtocolExtension().
488*/
489void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000490 // FIXME: I don't understand why gcc generates this, or where it is
491 // resolved. Investigate. Its also wasteful to look this up over and
492 // over.
493 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
494
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000495 const char *ProtocolName = PD->getName();
496
497 std::vector<llvm::Constant*> Values(5);
498 Values[0] = EmitProtocolExtension(PD);
499 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000500 Values[2] =
501 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
502 PD->protocol_begin(),
503 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000504 Values[3] = EmitMethodDescList(ProtocolName,
505 true, // IsProtocol
506 false, // ClassMethods
507 true, // Required
508 PD->instmeth_begin(),
509 PD->instmeth_end());
510 Values[4] = EmitMethodDescList(ProtocolName,
511 true, // IsProtocol
512 true, // ClassMethods
513 true, // Required
514 PD->classmeth_begin(),
515 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000516 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
517 Values);
518
519 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
520 if (Entry) {
521 // Already created, just update the initializer
522 Entry->setInitializer(Init);
523 } else {
524 Entry =
525 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
526 llvm::GlobalValue::InternalLinkage,
527 Init,
528 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
529 &CGM.getModule());
530 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
531 UsedGlobals.push_back(Entry);
532 // FIXME: Is this necessary? Why only for protocol?
533 Entry->setAlignment(4);
534 }
535}
536
537llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
538 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
539
540 if (!Entry) {
541 std::vector<llvm::Constant*> Values(5);
542 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
543 Values[1] = GetClassName(PD->getIdentifier());
544 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
545 Values[3] = Values[4] =
546 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
547 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
548 Values);
549
550 Entry =
551 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
552 llvm::GlobalValue::InternalLinkage,
553 Init,
554 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
555 &CGM.getModule());
556 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
557 UsedGlobals.push_back(Entry);
558 // FIXME: Is this necessary? Why only for protocol?
559 Entry->setAlignment(4);
560 }
561
562 return Entry;
563}
564
565/*
566 struct _objc_protocol_extension {
567 uint32_t size;
568 struct objc_method_description_list *optional_instance_methods;
569 struct objc_method_description_list *optional_class_methods;
570 struct objc_property_list *instance_properties;
571 };
572*/
573llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
574 uint64_t Size =
575 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
576 std::vector<llvm::Constant*> Values(4);
577 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000578 Values[1] = EmitMethodDescList(PD->getName(),
579 true, // IsProtocol
580 false, // ClassMethods
581 false, // Required
582 PD->instmeth_begin(),
583 PD->instmeth_end());
584 Values[2] = EmitMethodDescList(PD->getName(),
585 true, // IsProtocol
586 true, // ClassMethods
587 false, // Required
588 PD->classmeth_begin(),
589 PD->classmeth_end());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000590 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
591 PD->getName(),
592 PD->classprop_begin(),
593 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000594
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000595 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000596 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
597 Values[3]->isNullValue())
598 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
599
600 llvm::Constant *Init =
601 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
602 llvm::GlobalVariable *GV =
603 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
604 llvm::GlobalValue::InternalLinkage,
605 Init,
606 (std::string("\01L_OBJC_PROTOCOLEXT_") +
607 PD->getName()),
608 &CGM.getModule());
609 // No special section, but goes in llvm.used
610 UsedGlobals.push_back(GV);
611
612 return GV;
613}
614
615/*
616 struct objc_protocol_list {
617 struct objc_protocol_list *next;
618 long count;
619 Protocol *list[];
620 };
621*/
Daniel Dunbardbc933702008-08-21 21:57:41 +0000622llvm::Constant *
623CGObjCMac::EmitProtocolList(const std::string &Name,
624 ObjCProtocolDecl::protocol_iterator begin,
625 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000626 std::vector<llvm::Constant*> ProtocolRefs;
627
Daniel Dunbardbc933702008-08-21 21:57:41 +0000628 for (; begin != end; ++begin)
629 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000630
631 // Just return null for empty protocol lists
632 if (ProtocolRefs.empty())
633 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
634
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000635 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000636 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
637
638 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000639 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000640 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
641 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
642 Values[2] =
643 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
644 ProtocolRefs.size()),
645 ProtocolRefs);
646
647 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
648 llvm::GlobalVariable *GV =
649 new llvm::GlobalVariable(Init->getType(), false,
650 llvm::GlobalValue::InternalLinkage,
651 Init,
Daniel Dunbardbc933702008-08-21 21:57:41 +0000652 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000653 &CGM.getModule());
654 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
655 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
656}
657
658/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000659 struct _objc_property {
660 const char * const name;
661 const char * const attributes;
662 };
663
664 struct _objc_property_list {
665 uint32_t entsize; // sizeof (struct _objc_property)
666 uint32_t prop_count;
667 struct _objc_property[prop_count];
668 };
669*/
670llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
671 ObjCPropertyDecl * const *begin,
672 ObjCPropertyDecl * const *end) {
673 std::vector<llvm::Constant*> Properties, Prop(2);
674 for (; begin != end; ++begin) {
675 const ObjCPropertyDecl *PD = *begin;
676 Prop[0] = GetPropertyName(PD->getIdentifier());
677 Prop[1] = GetPropertyType(PD);
678 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
679 Prop));
680 }
681
682 // Return null for empty list.
683 if (Properties.empty())
684 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
685
686 unsigned PropertySize =
687 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
688 std::vector<llvm::Constant*> Values(3);
689 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
690 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
691 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
692 Properties.size());
693 Values[2] = llvm::ConstantArray::get(AT, Properties);
694 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
695
696 llvm::GlobalVariable *GV =
697 new llvm::GlobalVariable(Init->getType(), false,
698 llvm::GlobalValue::InternalLinkage,
699 Init,
700 Name,
701 &CGM.getModule());
702 // No special section on property lists?
703 UsedGlobals.push_back(GV);
704 return llvm::ConstantExpr::getBitCast(GV,
705 ObjCTypes.PropertyListPtrTy);
706
707}
708
709/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000710 struct objc_method_description_list {
711 int count;
712 struct objc_method_description list[];
713 };
714*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000715llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
716 bool IsProtocol,
717 bool ClassMethods,
718 bool Required,
719 ObjCMethodDecl * const *begin,
720 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000721 std::vector<llvm::Constant*> Methods, Desc(2);
722 for (; begin != end; ++begin) {
723 ObjCMethodDecl *D = *begin;
724 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
725
726 // Skip if this method is required and we are outputting optional
727 // methods, or vice versa.
728 if (Required != IsRequired)
729 continue;
730
731 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
732 ObjCTypes.SelectorPtrTy);
733 Desc[1] = GetMethodVarType(D);
734 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
735 Desc));
736 }
737
738 // Return null for empty list.
739 if (Methods.empty())
740 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
741
742 std::vector<llvm::Constant*> Values(2);
743 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
744 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
745 Methods.size());
746 Values[1] = llvm::ConstantArray::get(AT, Methods);
747 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
748
749 char Prefix[256];
750 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
751 IsProtocol ? "PROTOCOL_" : "",
752 ClassMethods ? "CLASS_" : "INSTANCE_",
753 !Required ? "OPT_" : "");
754 llvm::GlobalVariable *GV =
755 new llvm::GlobalVariable(Init->getType(), false,
756 llvm::GlobalValue::InternalLinkage,
757 Init,
758 std::string(Prefix) + TypeName,
759 &CGM.getModule());
760 if (ClassMethods) {
761 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
762 } else {
763 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
764 }
765 UsedGlobals.push_back(GV);
766 return llvm::ConstantExpr::getBitCast(GV,
767 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000768}
769
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000770/*
771 struct _objc_category {
772 char *category_name;
773 char *class_name;
774 struct _objc_method_list *instance_methods;
775 struct _objc_method_list *class_methods;
776 struct _objc_protocol_list *protocols;
777 uint32_t size; // <rdar://4585769>
778 struct _objc_property_list *instance_properties;
779 };
780 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000781void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000782 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
783
784 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
785 std::string ExtName(std::string(Interface->getName()) +
786 "_" +
787 OCD->getName());
788
789 std::vector<llvm::Constant*> Values(7);
790 Values[0] = GetClassName(OCD->getIdentifier());
791 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000792 Values[2] =
793 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
794 ExtName,
795 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
796 OCD->instmeth_begin(),
797 OCD->instmeth_end());
798 Values[3] =
799 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
800 "__OBJC,__cat_class_meth,regular,no_dead_strip",
801 OCD->classmeth_begin(),
802 OCD->classmeth_end());
803 Values[4] =
804 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
805 Interface->protocol_begin(),
806 Interface->protocol_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000807 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000808 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
809 Interface->classprop_begin(),
810 Interface->classprop_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000811
812 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
813 Values);
814
815 llvm::GlobalVariable *GV =
816 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
817 llvm::GlobalValue::InternalLinkage,
818 Init,
819 std::string("\01L_OBJC_CATEGORY_")+ExtName,
820 &CGM.getModule());
821 GV->setSection("__OBJC,__category,regular,no_dead_strip");
822 UsedGlobals.push_back(GV);
823 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000824}
825
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000826// FIXME: Get from somewhere?
827enum ClassFlags {
828 eClassFlags_Factory = 0x00001,
829 eClassFlags_Meta = 0x00002,
830 // <rdr://5142207>
831 eClassFlags_HasCXXStructors = 0x02000,
832 eClassFlags_Hidden = 0x20000,
833 eClassFlags_ABI2_Hidden = 0x00010,
834 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
835};
836
837// <rdr://5142207&4705298&4843145>
838static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
839 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
840 // FIXME: Support -fvisibility
841 switch (attr->getVisibility()) {
842 default:
843 assert(0 && "Unknown visibility");
844 return false;
845 case VisibilityAttr::DefaultVisibility:
846 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
847 return false;
848 case VisibilityAttr::HiddenVisibility:
849 return true;
850 }
851 } else {
852 return false; // FIXME: Support -fvisibility
853 }
854}
855
856/*
857 struct _objc_class {
858 Class isa;
859 Class super_class;
860 const char *name;
861 long version;
862 long info;
863 long instance_size;
864 struct _objc_ivar_list *ivars;
865 struct _objc_method_list *methods;
866 struct _objc_cache *cache;
867 struct _objc_protocol_list *protocols;
868 // Objective-C 1.0 extensions (<rdr://4585769>)
869 const char *ivar_layout;
870 struct _objc_class_ext *ext;
871 };
872
873 See EmitClassExtension();
874 */
875void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000876 DefinedSymbols.insert(ID->getIdentifier());
877
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000878 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000879 // FIXME: Gross
880 ObjCInterfaceDecl *Interface =
881 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000882 llvm::Constant *Protocols =
883 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
884 Interface->protocol_begin(),
885 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000886 const llvm::Type *InterfaceTy =
887 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
888 unsigned Flags = eClassFlags_Factory;
889 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
890
891 // FIXME: Set CXX-structors flag.
892 if (IsClassHidden(ID->getClassInterface()))
893 Flags |= eClassFlags_Hidden;
894
895 std::vector<llvm::Constant*> Values(12);
896 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
897 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000898 // Record a reference to the super class.
899 LazySymbols.insert(Super->getIdentifier());
900
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000901 Values[ 1] =
902 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
903 ObjCTypes.ClassPtrTy);
904 } else {
905 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
906 }
907 Values[ 2] = GetClassName(ID->getIdentifier());
908 // Version is always 0.
909 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
910 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
911 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
912 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000913 Values[ 7] =
914 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
915 "__OBJC,__inst_meth,regular,no_dead_strip",
916 ID->instmeth_begin(),
917 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000918 // cache is always NULL.
919 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
920 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000921 // FIXME: Set ivar_layout
922 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000923 Values[11] = EmitClassExtension(ID);
924 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
925 Values);
926
927 llvm::GlobalVariable *GV =
928 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
929 llvm::GlobalValue::InternalLinkage,
930 Init,
931 std::string("\01L_OBJC_CLASS_")+ClassName,
932 &CGM.getModule());
933 GV->setSection("__OBJC,__class,regular,no_dead_strip");
934 UsedGlobals.push_back(GV);
935 // FIXME: Why?
936 GV->setAlignment(32);
937 DefinedClasses.push_back(GV);
938}
939
940llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
941 llvm::Constant *Protocols,
942 const llvm::Type *InterfaceTy) {
943 const char *ClassName = ID->getName();
944 unsigned Flags = eClassFlags_Meta;
945 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
946
947 if (IsClassHidden(ID->getClassInterface()))
948 Flags |= eClassFlags_Hidden;
949
950 std::vector<llvm::Constant*> Values(12);
951 // The isa for the metaclass is the root of the hierarchy.
952 const ObjCInterfaceDecl *Root = ID->getClassInterface();
953 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
954 Root = Super;
955 Values[ 0] =
956 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
957 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000958 // The super class for the metaclass is emitted as the name of the
959 // super class. The runtime fixes this up to point to the
960 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000961 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
962 Values[ 1] =
963 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
964 ObjCTypes.ClassPtrTy);
965 } else {
966 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
967 }
968 Values[ 2] = GetClassName(ID->getIdentifier());
969 // Version is always 0.
970 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
971 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
972 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
973 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000974 Values[ 7] =
975 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
976 "__OBJC,__inst_meth,regular,no_dead_strip",
977 ID->classmeth_begin(),
978 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000979 // cache is always NULL.
980 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
981 Values[ 9] = Protocols;
982 // ivar_layout for metaclass is always NULL.
983 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
984 // The class extension is always unused for metaclasses.
985 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
986 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
987 Values);
988
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000989 std::string Name("\01L_OBJC_METACLASS_");
990 Name += ClassName;
991
992 // Check for a forward reference.
993 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
994 if (GV) {
995 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
996 "Forward metaclass reference has incorrect type.");
997 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
998 GV->setInitializer(Init);
999 } else {
1000 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1001 llvm::GlobalValue::InternalLinkage,
1002 Init, Name,
1003 &CGM.getModule());
1004 }
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001005 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
1006 UsedGlobals.push_back(GV);
1007 // FIXME: Why?
1008 GV->setAlignment(32);
1009
1010 return GV;
1011}
1012
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001013llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
1014 std::string Name("\01L_OBJC_METACLASS_");
1015 Name += ID->getName();
1016
1017 // FIXME: Should we look these up somewhere other than the
1018 // module. Its a bit silly since we only generate these while
1019 // processing an implementation, so exactly one pointer would work
1020 // if know when we entered/exitted an implementation block.
1021
1022 // Check for an existing forward reference.
1023 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) {
1024 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1025 "Forward metaclass reference has incorrect type.");
1026 return GV;
1027 } else {
1028 // Generate as an external reference to keep a consistent
1029 // module. This will be patched up when we emit the metaclass.
1030 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1031 llvm::GlobalValue::ExternalLinkage,
1032 0,
1033 Name,
1034 &CGM.getModule());
1035 }
1036}
1037
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001038/*
1039 struct objc_class_ext {
1040 uint32_t size;
1041 const char *weak_ivar_layout;
1042 struct _objc_property_list *properties;
1043 };
1044*/
1045llvm::Constant *
1046CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1047 uint64_t Size =
1048 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1049
1050 std::vector<llvm::Constant*> Values(3);
1051 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001052 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001053 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001054 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1055 ID->getName(),
1056 ID->getClassInterface()->classprop_begin(),
1057 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001058
1059 // Return null if no extension bits are used.
1060 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1061 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1062
1063 llvm::Constant *Init =
1064 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1065 llvm::GlobalVariable *GV =
1066 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1067 llvm::GlobalValue::InternalLinkage,
1068 Init,
1069 (std::string("\01L_OBJC_CLASSEXT_") +
1070 ID->getName()),
1071 &CGM.getModule());
1072 // No special section, but goes in llvm.used
1073 UsedGlobals.push_back(GV);
1074
1075 return GV;
1076}
1077
1078/*
1079 struct objc_ivar {
1080 char *ivar_name;
1081 char *ivar_type;
1082 int ivar_offset;
1083 };
1084
1085 struct objc_ivar_list {
1086 int ivar_count;
1087 struct objc_ivar list[count];
1088 };
1089 */
1090llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1091 bool ForClass,
1092 const llvm::Type *InterfaceTy) {
1093 std::vector<llvm::Constant*> Ivars, Ivar(3);
1094
1095 // When emitting the root class GCC emits ivar entries for the
1096 // actual class structure. It is not clear if we need to follow this
1097 // behavior; for now lets try and get away with not doing it. If so,
1098 // the cleanest solution would be to make up an ObjCInterfaceDecl
1099 // for the class.
1100 if (ForClass)
1101 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1102
1103 const llvm::StructLayout *Layout =
1104 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1105 for (ObjCInterfaceDecl::ivar_iterator
1106 i = ID->getClassInterface()->ivar_begin(),
1107 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1108 ObjCIvarDecl *V = *i;
1109 unsigned Offset =
1110 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1111 std::string TypeStr;
1112 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1113 Ivar[0] = GetMethodVarName(V->getIdentifier());
1114 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1115 EncodingRecordTypes);
1116 Ivar[1] = GetMethodVarType(TypeStr);
1117 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1118 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1119 Ivar));
1120 }
1121
1122 // Return null for empty list.
1123 if (Ivars.empty())
1124 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1125
1126 std::vector<llvm::Constant*> Values(2);
1127 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1128 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1129 Ivars.size());
1130 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1131 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1132
1133 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1134 "\01L_OBJC_INSTANCE_VARIABLES_");
1135 llvm::GlobalVariable *GV =
1136 new llvm::GlobalVariable(Init->getType(), false,
1137 llvm::GlobalValue::InternalLinkage,
1138 Init,
1139 std::string(Prefix) + ID->getName(),
1140 &CGM.getModule());
1141 if (ForClass) {
1142 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1143 // FIXME: Why is this only here?
1144 GV->setAlignment(32);
1145 } else {
1146 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1147 }
1148 UsedGlobals.push_back(GV);
1149 return llvm::ConstantExpr::getBitCast(GV,
1150 ObjCTypes.IvarListPtrTy);
1151}
1152
1153/*
1154 struct objc_method {
1155 SEL method_name;
1156 char *method_types;
1157 void *method;
1158 };
1159
1160 struct objc_method_list {
1161 struct objc_method_list *obsolete;
1162 int count;
1163 struct objc_method methods_list[count];
1164 };
1165*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001166llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1167 const char *Section,
1168 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1169 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001170 std::vector<llvm::Constant*> Methods, Method(3);
1171
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001172 for (; begin != end; ++begin) {
1173 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001174
1175 Method[0] =
1176 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1177 ObjCTypes.SelectorPtrTy);
1178 Method[1] = GetMethodVarType(MD);
1179
1180 // FIXME: This is gross, we shouldn't be looking up by name.
1181 std::string Name;
1182 GetNameForMethod(MD, Name);
1183 Method[2] =
1184 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1185 ObjCTypes.Int8PtrTy);
1186 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1187 Method));
1188 }
1189
1190 // Return null for empty list.
1191 if (Methods.empty())
1192 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1193
1194 std::vector<llvm::Constant*> Values(3);
1195 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1196 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1197 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1198 Methods.size());
1199 Values[2] = llvm::ConstantArray::get(AT, Methods);
1200 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1201
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001202 llvm::GlobalVariable *GV =
1203 new llvm::GlobalVariable(Init->getType(), false,
1204 llvm::GlobalValue::InternalLinkage,
1205 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001206 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001207 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001208 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001209 UsedGlobals.push_back(GV);
1210 return llvm::ConstantExpr::getBitCast(GV,
1211 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001212}
1213
1214llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1215 const llvm::Type *ReturnTy =
1216 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1217 const llvm::Type *SelfTy =
1218 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1219
1220 std::vector<const llvm::Type*> ArgTys;
1221 ArgTys.reserve(1 + 2 + OMD->param_size());
1222
1223 // FIXME: This is not something we should have to be dealing with
1224 // here.
1225 bool useStructRet =
1226 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1227 if (useStructRet) {
1228 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1229 ReturnTy = llvm::Type::VoidTy;
1230 }
1231
1232 // Implicit arguments
1233 ArgTys.push_back(SelfTy);
1234 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1235
1236 for (ObjCMethodDecl::param_const_iterator
1237 i = OMD->param_begin(), e = OMD->param_end();
1238 i != e; ++i) {
1239 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001240 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001241 ArgTys.push_back(Ty);
1242 } else {
1243 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1244 }
1245 }
1246
1247 std::string Name;
1248 GetNameForMethod(OMD, Name);
1249
1250 llvm::Function *Method =
1251 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1252 ArgTys,
1253 OMD->isVariadic()),
1254 llvm::GlobalValue::InternalLinkage,
1255 Name,
1256 &CGM.getModule());
1257
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001258 unsigned Offset = 3; // Return plus self and selector implicit args.
1259 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001260 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001261 ++Offset;
1262 }
1263
1264 // FIXME: This is horrible, we need to be reusing the machinery in
1265 // CodeGenModule.cpp (SetFunctionAttributes).
1266 for (ObjCMethodDecl::param_const_iterator
1267 i = OMD->param_begin(), e = OMD->param_end();
1268 i != e; ++i, ++Offset) {
1269 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1270 if (!Ty->isSingleValueType())
1271 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1272 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001273
1274 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001275}
1276
1277llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001278 // Abuse this interface function as a place to finalize.
1279 FinishModule();
1280
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001281 return NULL;
1282}
1283
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001284/* *** Private Interface *** */
1285
1286/// EmitImageInfo - Emit the image info marker used to encode some module
1287/// level information.
1288///
1289/// See: <rdr://4810609&4810587&4810587>
1290/// struct IMAGE_INFO {
1291/// unsigned version;
1292/// unsigned flags;
1293/// };
1294enum ImageInfoFlags {
1295 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1296 eImageInfo_GarbageCollected = (1 << 1),
1297 eImageInfo_GCOnly = (1 << 2)
1298};
1299
1300void CGObjCMac::EmitImageInfo() {
1301 unsigned version = 0; // Version is unused?
1302 unsigned flags = 0;
1303
1304 // FIXME: Fix and continue?
1305 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1306 flags |= eImageInfo_GarbageCollected;
1307 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1308 flags |= eImageInfo_GCOnly;
1309
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001310 // Emitted as int[2];
1311 llvm::Constant *values[2] = {
1312 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1313 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1314 };
1315 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001316 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001317 new llvm::GlobalVariable(AT, true,
1318 llvm::GlobalValue::InternalLinkage,
1319 llvm::ConstantArray::get(AT, values, 2),
1320 "\01L_OBJC_IMAGE_INFO",
1321 &CGM.getModule());
1322
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001323 if (ObjCABI == 1) {
1324 GV->setSection("__OBJC, __image_info,regular");
1325 } else {
1326 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1327 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001328
1329 UsedGlobals.push_back(GV);
1330}
1331
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001332
1333// struct objc_module {
1334// unsigned long version;
1335// unsigned long size;
1336// const char *name;
1337// Symtab symtab;
1338// };
1339
1340// FIXME: Get from somewhere
1341static const int ModuleVersion = 7;
1342
1343void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001344 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1345
1346 std::vector<llvm::Constant*> Values(4);
1347 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1348 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001349 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001350 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001351 Values[3] = EmitModuleSymbols();
1352
1353 llvm::GlobalVariable *GV =
1354 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1355 llvm::GlobalValue::InternalLinkage,
1356 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1357 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001358 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001359 &CGM.getModule());
1360 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1361 UsedGlobals.push_back(GV);
1362}
1363
1364llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001365 unsigned NumClasses = DefinedClasses.size();
1366 unsigned NumCategories = DefinedCategories.size();
1367
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001368 // Return null if no symbols were defined.
1369 if (!NumClasses && !NumCategories)
1370 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
1371
1372 std::vector<llvm::Constant*> Values(5);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001373 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1374 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1375 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1376 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1377
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001378 // The runtime expects exactly the list of defined classes followed
1379 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001380 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001381 for (unsigned i=0; i<NumClasses; i++)
1382 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1383 ObjCTypes.Int8PtrTy);
1384 for (unsigned i=0; i<NumCategories; i++)
1385 Symbols[NumClasses + i] =
1386 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1387 ObjCTypes.Int8PtrTy);
1388
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001389 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001390 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001391 NumClasses + NumCategories),
1392 Symbols);
1393
1394 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1395
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001396 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001397 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001398 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001399 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001400 "\01L_OBJC_SYMBOLS",
1401 &CGM.getModule());
1402 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1403 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001404 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1405}
1406
1407llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1408 const ObjCInterfaceDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001409 LazySymbols.insert(ID->getIdentifier());
1410
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001411 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1412
1413 if (!Entry) {
1414 llvm::Constant *Casted =
1415 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1416 ObjCTypes.ClassPtrTy);
1417 Entry =
1418 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1419 llvm::GlobalValue::InternalLinkage,
1420 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1421 &CGM.getModule());
1422 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1423 UsedGlobals.push_back(Entry);
1424 }
1425
1426 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001427}
1428
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001429llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1430 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1431
1432 if (!Entry) {
1433 llvm::Constant *Casted =
1434 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1435 ObjCTypes.SelectorPtrTy);
1436 Entry =
1437 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1438 llvm::GlobalValue::InternalLinkage,
1439 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1440 &CGM.getModule());
1441 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1442 UsedGlobals.push_back(Entry);
1443 }
1444
1445 return Builder.CreateLoad(Entry, false, "tmp");
1446}
1447
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001448llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1449 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001450
1451 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001452 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001453 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001454 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001455 llvm::GlobalValue::InternalLinkage,
1456 C, "\01L_OBJC_CLASS_NAME_",
1457 &CGM.getModule());
1458 Entry->setSection("__TEXT,__cstring,cstring_literals");
1459 UsedGlobals.push_back(Entry);
1460 }
1461
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001462 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001463}
1464
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001465llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1466 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1467
1468 if (!Entry) {
1469 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1470 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001471 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001472 llvm::GlobalValue::InternalLinkage,
1473 C, "\01L_OBJC_METH_VAR_NAME_",
1474 &CGM.getModule());
1475 Entry->setSection("__TEXT,__cstring,cstring_literals");
1476 UsedGlobals.push_back(Entry);
1477 }
1478
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001479 return getConstantGEP(Entry, 0, 0);
1480}
1481
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001482// FIXME: Merge into a single cstring creation function.
1483llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1484 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1485}
1486
1487// FIXME: Merge into a single cstring creation function.
1488llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1489 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1490}
1491
1492llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1493 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001494
1495 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001496 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001497 Entry =
1498 new llvm::GlobalVariable(C->getType(), false,
1499 llvm::GlobalValue::InternalLinkage,
1500 C, "\01L_OBJC_METH_VAR_TYPE_",
1501 &CGM.getModule());
1502 Entry->setSection("__TEXT,__cstring,cstring_literals");
1503 UsedGlobals.push_back(Entry);
1504 }
1505
1506 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001507}
1508
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001509// FIXME: Merge into a single cstring creation function.
1510llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1511 std::string TypeStr;
1512 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1513 return GetMethodVarType(TypeStr);
1514}
1515
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001516// FIXME: Merge into a single cstring creation function.
1517llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1518 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1519
1520 if (!Entry) {
1521 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1522 Entry =
1523 new llvm::GlobalVariable(C->getType(), false,
1524 llvm::GlobalValue::InternalLinkage,
1525 C, "\01L_OBJC_PROP_NAME_ATTR_",
1526 &CGM.getModule());
1527 Entry->setSection("__TEXT,__cstring,cstring_literals");
1528 UsedGlobals.push_back(Entry);
1529 }
1530
1531 return getConstantGEP(Entry, 0, 0);
1532}
1533
1534// FIXME: Merge into a single cstring creation function.
1535llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1536 std::string TypeStr("MOOO!");
1537 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1538 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1539}
1540
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001541void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1542 std::string &NameOut) {
1543 // FIXME: Find the mangling GCC uses.
1544 std::stringstream s;
1545 s << (D->isInstance() ? "-" : "+");
1546 s << "[";
1547 s << D->getClassInterface()->getName();
1548 s << " ";
1549 s << D->getSelector().getName();
1550 s << "]";
1551 NameOut = s.str();
1552}
1553
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001554void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001555 EmitModuleInfo();
1556
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001557 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001558
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001559 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001560 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001561 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001562 }
1563
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001564 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001565 llvm::GlobalValue *GV =
1566 new llvm::GlobalVariable(AT, false,
1567 llvm::GlobalValue::AppendingLinkage,
1568 llvm::ConstantArray::get(AT, Used),
1569 "llvm.used",
1570 &CGM.getModule());
1571
1572 GV->setSection("llvm.metadata");
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001573
1574 // Add assembler directives to add lazy undefined symbol references
1575 // for classes which are referenced but not defined. This is
1576 // important for correct linker interaction.
1577
1578 // FIXME: Uh, this isn't particularly portable.
1579 std::stringstream s;
1580 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
1581 e = LazySymbols.end(); i != e; ++i) {
1582 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
1583 }
1584 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
1585 e = DefinedSymbols.end(); i != e; ++i) {
1586 s << "\t.objc_class_name_" << (*i)->getName() << " = 0\n"
1587 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
1588 }
1589 CGM.getModule().appendModuleInlineAsm(s.str());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001590}
1591
1592/* *** */
1593
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001594ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbar3e9df992008-08-23 18:37:06 +00001595 : CGM(cgm)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001596{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001597 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1598 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001599
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001600 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001601 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001602 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001603 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1604
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001605 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1606 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001607
1608 // FIXME: It would be nice to unify this with the opaque type, so
1609 // that the IR comes out a bit cleaner.
1610 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1611 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001612
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001613 MethodDescriptionTy =
1614 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001615 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001616 NULL);
1617 CGM.getModule().addTypeName("struct._objc_method_description",
1618 MethodDescriptionTy);
1619
1620 MethodDescriptionListTy =
1621 llvm::StructType::get(IntTy,
1622 llvm::ArrayType::get(MethodDescriptionTy, 0),
1623 NULL);
1624 CGM.getModule().addTypeName("struct._objc_method_description_list",
1625 MethodDescriptionListTy);
1626 MethodDescriptionListPtrTy =
1627 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1628
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001629 PropertyTy = llvm::StructType::get(Int8PtrTy,
1630 Int8PtrTy,
1631 NULL);
1632 CGM.getModule().addTypeName("struct._objc_property",
1633 PropertyTy);
1634
1635 PropertyListTy = llvm::StructType::get(IntTy,
1636 IntTy,
1637 llvm::ArrayType::get(PropertyTy, 0),
1638 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001639 CGM.getModule().addTypeName("struct._objc_property_list",
1640 PropertyListTy);
1641 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1642
1643 // Protocol description structures
1644
1645 ProtocolExtensionTy =
1646 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1647 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1648 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1649 PropertyListPtrTy,
1650 NULL);
1651 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1652 ProtocolExtensionTy);
1653 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1654
1655 // Handle recursive construction of Protocl and ProtocolList types
1656
1657 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1658 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1659
1660 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1661 LongTy,
1662 llvm::ArrayType::get(ProtocolTyHolder, 0),
1663 NULL);
1664 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1665
1666 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001667 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001668 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1669 MethodDescriptionListPtrTy,
1670 MethodDescriptionListPtrTy,
1671 NULL);
1672 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1673
1674 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1675 CGM.getModule().addTypeName("struct._objc_protocol_list",
1676 ProtocolListTy);
1677 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1678
1679 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1680 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1681 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001682
1683 // Class description structures
1684
1685 IvarTy = llvm::StructType::get(Int8PtrTy,
1686 Int8PtrTy,
1687 IntTy,
1688 NULL);
1689 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1690
1691 IvarListTy = llvm::OpaqueType::get();
1692 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1693 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1694
1695 MethodTy = llvm::StructType::get(SelectorPtrTy,
1696 Int8PtrTy,
1697 Int8PtrTy,
1698 NULL);
1699 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1700
1701 MethodListTy = llvm::OpaqueType::get();
1702 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1703 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1704
1705 CacheTy = llvm::OpaqueType::get();
1706 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1707 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1708
1709 ClassExtensionTy =
1710 llvm::StructType::get(IntTy,
1711 Int8PtrTy,
1712 PropertyListPtrTy,
1713 NULL);
1714 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1715 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1716
1717 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1718
1719 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1720 llvm::PointerType::getUnqual(ClassTyHolder),
1721 Int8PtrTy,
1722 LongTy,
1723 LongTy,
1724 LongTy,
1725 IvarListPtrTy,
1726 MethodListPtrTy,
1727 CachePtrTy,
1728 ProtocolListPtrTy,
1729 Int8PtrTy,
1730 ClassExtensionPtrTy,
1731 NULL);
1732 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1733
1734 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1735 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1736 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1737
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001738 CategoryTy = llvm::StructType::get(Int8PtrTy,
1739 Int8PtrTy,
1740 MethodListPtrTy,
1741 MethodListPtrTy,
1742 ProtocolListPtrTy,
1743 IntTy,
1744 PropertyListPtrTy,
1745 NULL);
1746 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1747
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001748 SuperTy =
1749 llvm::StructType::get(ObjectPtrTy,
1750 ClassPtrTy,
1751 NULL);
1752 CGM.getModule().addTypeName("struct._objc_super",
1753 SuperTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001754 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001755
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001756 // Global metadata structures
1757
1758 SymtabTy = llvm::StructType::get(LongTy,
1759 SelectorPtrTy,
1760 ShortTy,
1761 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001762 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001763 NULL);
1764 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1765 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1766
1767 ModuleTy =
1768 llvm::StructType::get(LongTy,
1769 LongTy,
1770 Int8PtrTy,
1771 SymtabPtrTy,
1772 NULL);
1773 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001774
1775 // Message send functions
1776
1777 std::vector<const llvm::Type*> Params;
1778 Params.push_back(ObjectPtrTy);
1779 Params.push_back(SelectorPtrTy);
1780 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1781 Params,
1782 true),
1783 llvm::Function::ExternalLinkage,
1784 "objc_msgSend",
1785 &CGM.getModule());
1786
1787 Params.clear();
1788 Params.push_back(Int8PtrTy);
1789 Params.push_back(ObjectPtrTy);
1790 Params.push_back(SelectorPtrTy);
1791 MessageSendStretFn =
1792 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1793 Params,
1794 true),
1795 llvm::Function::ExternalLinkage,
1796 "objc_msgSend_stret",
1797 &CGM.getModule());
1798
1799 Params.clear();
1800 Params.push_back(SuperPtrTy);
1801 Params.push_back(SelectorPtrTy);
1802 MessageSendSuperFn =
1803 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1804 Params,
1805 true),
1806 llvm::Function::ExternalLinkage,
1807 "objc_msgSendSuper",
1808 &CGM.getModule());
1809
1810 Params.clear();
1811 Params.push_back(Int8PtrTy);
1812 Params.push_back(SuperPtrTy);
1813 Params.push_back(SelectorPtrTy);
1814 MessageSendSuperStretFn =
1815 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1816 Params,
1817 true),
1818 llvm::Function::ExternalLinkage,
1819 "objc_msgSendSuper_stret",
1820 &CGM.getModule());
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001821}
1822
1823ObjCTypesHelper::~ObjCTypesHelper() {
1824}
1825
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001826llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
1827 const llvm::Type *ReturnTy) {
1828 llvm::Function *F;
1829 llvm::FunctionType *CallFTy;
1830
1831 // FIXME: Should we be caching any of this?
1832 if (!ReturnTy->isSingleValueType()) {
1833 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
1834 std::vector<const llvm::Type*> Params(3);
1835 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
1836 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1837 Params[2] = SelectorPtrTy;
1838 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
1839 } else { // XXX floating point?
1840 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
1841 std::vector<const llvm::Type*> Params(2);
1842 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1843 Params[1] = SelectorPtrTy;
1844 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001845 }
1846
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001847 return llvm::ConstantExpr::getBitCast(F,
1848 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001849}
1850
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001851/* *** */
1852
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001853CodeGen::CGObjCRuntime *
1854CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001855 return new CGObjCMac(CGM);
1856}