blob: 4223709786370e32565f335039218b49c41e7475 [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
236 /// implementation. If ForClass is true the list of class methods
237 /// will be emitted, otherwise the list of instance methods will be
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000238 /// generated. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000239 llvm::Constant *EmitMethodList(const std::string &Name,
240 const char *Section,
241 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
242 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000243
244 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000245 /// method declarations.
246 /// - TypeName: The name for the type containing the methods.
247 /// - IsProtocol: True iff these methods are for a protocol.
248 /// - ClassMethds: True iff these are class methods.
249 /// - Required: When true, only "required" methods are
250 /// listed. Similarly, when false only "optional" methods are
251 /// listed. For classes this should always be true.
252 /// - begin, end: The method list to output.
253 ///
254 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000255 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
256 bool IsProtocol,
257 bool ClassMethods,
258 bool Required,
259 ObjCMethodDecl * const *begin,
260 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000261
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000262 /// EmitPropertyList - Emit the given property list. The return
263 /// value has type PropertyListPtrTy.
264 llvm::Constant *EmitPropertyList(const std::string &Name,
265 ObjCPropertyDecl * const *begin,
266 ObjCPropertyDecl * const *end);
267
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000268 /// EmitProtocolExtension - Generate the protocol extension
269 /// structure used to store optional instance and class methods, and
270 /// protocol properties. The return value has type
271 /// ProtocolExtensionPtrTy.
272 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
273
274 /// EmitProtocolList - Generate the list of referenced
275 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc93372008-08-21 21:57:41 +0000276 llvm::Constant *EmitProtocolList(const std::string &Name,
277 ObjCProtocolDecl::protocol_iterator begin,
278 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000279
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000280 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
281 /// for the given selector.
282 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
283
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000284 /// GetProtocolRef - Return a reference to the internal protocol
285 /// description, creating an empty one if it has not been
286 /// defined. The return value has type pointer-to ProtocolTy.
287 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
288
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000289 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000290 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000291 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000292
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000293 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000294 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000295 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000296 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000297 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000298
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000299 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000300 /// selector's name. The return value has type char *.
301
302 // FIXME: This is a horrible name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000303 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000304 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000305
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000306 /// GetPropertyName - Return a unique constant for the given
307 /// name. The return value has type char *.
308 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
309
310 // FIXME: This is a horrible name too.
311 llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
312
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000313 /// GetNameForMethod - Return a name for the given method.
314 /// \param[out] NameOut - The return value.
315 void GetNameForMethod(const ObjCMethodDecl *OMD,
316 std::string &NameOut);
317
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000318public:
319 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000320 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000321
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000322 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
323 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000324 llvm::Value *Receiver,
325 bool IsClassMessage);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000326
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000327 virtual CodeGen::RValue
328 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
329 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000330 const ObjCInterfaceDecl *Class,
331 llvm::Value *Receiver,
332 bool IsClassMessage);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000333
334 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000335 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000336
337 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
338
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000339 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000340
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000341 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000342
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000343 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000344
345 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000346 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000347
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000348 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000349
350 virtual llvm::Function *ModuleInitFunction();
351};
352} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000353
354/* *** Helper Functions *** */
355
356/// getConstantGEP() - Help routine to construct simple GEPs.
357static llvm::Constant *getConstantGEP(llvm::Constant *C,
358 unsigned idx0,
359 unsigned idx1) {
360 llvm::Value *Idxs[] = {
361 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
362 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
363 };
364 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
365}
366
367/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000368
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000369CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
370 : CGM(cgm),
371 ObjCTypes(cgm),
372 ObjCABI(1)
373{
374 // FIXME: How does this get set in GCC? And what does it even mean?
375 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
376 ObjCABI = 2;
377
378 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000379}
380
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000381/// GetClass - Return a reference to the class for the given interface
382/// decl.
383llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000384 const ObjCInterfaceDecl *ID) {
385 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000386}
387
388/// GetSelector - Return the pointer to the unique'd string for this selector.
389llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000390 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000391}
392
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000393/// Generate a constant CFString object.
394/*
395 struct __builtin_CFString {
396 const int *isa; // point to __CFConstantStringClassReference
397 int flags;
398 const char *str;
399 long length;
400 };
401*/
402
403llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbar3e9df992008-08-23 18:37:06 +0000404 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000405}
406
407/// Generates a message send where the super is the receiver. This is
408/// a message send to self with special delivery semantics indicating
409/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000410CodeGen::RValue
411CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
412 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000413 const ObjCInterfaceDecl *Class,
414 llvm::Value *Receiver,
415 bool IsClassMessage) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000416 // Create and init a super structure; this is a (receiver, class)
417 // pair we will pass to objc_msgSendSuper.
418 llvm::Value *ObjCSuper =
419 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
420 llvm::Value *ReceiverAsObject =
421 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
422 CGF.Builder.CreateStore(ReceiverAsObject,
423 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000424
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000425 // If this is a class message the metaclass is passed as the target.
426 llvm::Value *Target;
427 if (IsClassMessage) {
428 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
429 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
430 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
431 Target = Super;
432 } else {
433 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
434 }
435 CGF.Builder.CreateStore(Target,
436 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
437
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000438 return EmitMessageSend(CGF, E, ObjCSuper, true);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000439}
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000440
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000441/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000442CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
443 const ObjCMessageExpr *E,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000444 llvm::Value *Receiver,
445 bool IsClassMessage) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000446 llvm::Value *Arg0 =
447 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
448 return EmitMessageSend(CGF, E, Arg0, false);
449}
450
451CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
452 const ObjCMessageExpr *E,
453 llvm::Value *Arg0,
454 bool IsSuper) {
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000455 llvm::Value *Args[2];
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000456 Args[0] = Arg0;
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000457 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000458
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000459 // FIXME: This is a hack, we are implicitly coordinating with
460 // EmitCallExprExt, which will move the return type to the first
461 // parameter and set the structure return flag. See
462 // getMessageSendFn().
463
464
465 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
466 return CGF.EmitCallExprExt(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),
467 E->getType(),
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000468 E->arg_begin(),
469 E->arg_end(),
470 Args, 2);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000471}
472
473llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000474 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000475 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
476 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000477}
478
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000479/*
480 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
481 struct _objc_protocol {
482 struct _objc_protocol_extension *isa;
483 char *protocol_name;
484 struct _objc_protocol_list *protocol_list;
485 struct _objc__method_prototype_list *instance_methods;
486 struct _objc__method_prototype_list *class_methods
487 };
488
489 See EmitProtocolExtension().
490*/
491void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000492 // FIXME: I don't understand why gcc generates this, or where it is
493 // resolved. Investigate. Its also wasteful to look this up over and
494 // over.
495 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
496
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000497 const char *ProtocolName = PD->getName();
498
499 std::vector<llvm::Constant*> Values(5);
500 Values[0] = EmitProtocolExtension(PD);
501 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000502 Values[2] =
503 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
504 PD->protocol_begin(),
505 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000506 Values[3] = EmitMethodDescList(ProtocolName,
507 true, // IsProtocol
508 false, // ClassMethods
509 true, // Required
510 PD->instmeth_begin(),
511 PD->instmeth_end());
512 Values[4] = EmitMethodDescList(ProtocolName,
513 true, // IsProtocol
514 true, // ClassMethods
515 true, // Required
516 PD->classmeth_begin(),
517 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000518 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
519 Values);
520
521 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
522 if (Entry) {
523 // Already created, just update the initializer
524 Entry->setInitializer(Init);
525 } else {
526 Entry =
527 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
528 llvm::GlobalValue::InternalLinkage,
529 Init,
530 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
531 &CGM.getModule());
532 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
533 UsedGlobals.push_back(Entry);
534 // FIXME: Is this necessary? Why only for protocol?
535 Entry->setAlignment(4);
536 }
537}
538
539llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
540 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
541
542 if (!Entry) {
543 std::vector<llvm::Constant*> Values(5);
544 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
545 Values[1] = GetClassName(PD->getIdentifier());
546 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
547 Values[3] = Values[4] =
548 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
549 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
550 Values);
551
552 Entry =
553 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
554 llvm::GlobalValue::InternalLinkage,
555 Init,
556 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
557 &CGM.getModule());
558 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
559 UsedGlobals.push_back(Entry);
560 // FIXME: Is this necessary? Why only for protocol?
561 Entry->setAlignment(4);
562 }
563
564 return Entry;
565}
566
567/*
568 struct _objc_protocol_extension {
569 uint32_t size;
570 struct objc_method_description_list *optional_instance_methods;
571 struct objc_method_description_list *optional_class_methods;
572 struct objc_property_list *instance_properties;
573 };
574*/
575llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
576 uint64_t Size =
577 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
578 std::vector<llvm::Constant*> Values(4);
579 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000580 Values[1] = EmitMethodDescList(PD->getName(),
581 true, // IsProtocol
582 false, // ClassMethods
583 false, // Required
584 PD->instmeth_begin(),
585 PD->instmeth_end());
586 Values[2] = EmitMethodDescList(PD->getName(),
587 true, // IsProtocol
588 true, // ClassMethods
589 false, // Required
590 PD->classmeth_begin(),
591 PD->classmeth_end());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000592 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
593 PD->getName(),
594 PD->classprop_begin(),
595 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000596
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000597 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000598 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
599 Values[3]->isNullValue())
600 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
601
602 llvm::Constant *Init =
603 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
604 llvm::GlobalVariable *GV =
605 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
606 llvm::GlobalValue::InternalLinkage,
607 Init,
608 (std::string("\01L_OBJC_PROTOCOLEXT_") +
609 PD->getName()),
610 &CGM.getModule());
611 // No special section, but goes in llvm.used
612 UsedGlobals.push_back(GV);
613
614 return GV;
615}
616
617/*
618 struct objc_protocol_list {
619 struct objc_protocol_list *next;
620 long count;
621 Protocol *list[];
622 };
623*/
Daniel Dunbardbc93372008-08-21 21:57:41 +0000624llvm::Constant *
625CGObjCMac::EmitProtocolList(const std::string &Name,
626 ObjCProtocolDecl::protocol_iterator begin,
627 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000628 std::vector<llvm::Constant*> ProtocolRefs;
629
Daniel Dunbardbc93372008-08-21 21:57:41 +0000630 for (; begin != end; ++begin)
631 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000632
633 // Just return null for empty protocol lists
634 if (ProtocolRefs.empty())
635 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
636
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000637 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000638 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
639
640 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000641 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000642 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
643 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
644 Values[2] =
645 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
646 ProtocolRefs.size()),
647 ProtocolRefs);
648
649 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
650 llvm::GlobalVariable *GV =
651 new llvm::GlobalVariable(Init->getType(), false,
652 llvm::GlobalValue::InternalLinkage,
653 Init,
Daniel Dunbardbc93372008-08-21 21:57:41 +0000654 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000655 &CGM.getModule());
656 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
657 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
658}
659
660/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000661 struct _objc_property {
662 const char * const name;
663 const char * const attributes;
664 };
665
666 struct _objc_property_list {
667 uint32_t entsize; // sizeof (struct _objc_property)
668 uint32_t prop_count;
669 struct _objc_property[prop_count];
670 };
671*/
672llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
673 ObjCPropertyDecl * const *begin,
674 ObjCPropertyDecl * const *end) {
675 std::vector<llvm::Constant*> Properties, Prop(2);
676 for (; begin != end; ++begin) {
677 const ObjCPropertyDecl *PD = *begin;
678 Prop[0] = GetPropertyName(PD->getIdentifier());
679 Prop[1] = GetPropertyType(PD);
680 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
681 Prop));
682 }
683
684 // Return null for empty list.
685 if (Properties.empty())
686 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
687
688 unsigned PropertySize =
689 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
690 std::vector<llvm::Constant*> Values(3);
691 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
692 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
693 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
694 Properties.size());
695 Values[2] = llvm::ConstantArray::get(AT, Properties);
696 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
697
698 llvm::GlobalVariable *GV =
699 new llvm::GlobalVariable(Init->getType(), false,
700 llvm::GlobalValue::InternalLinkage,
701 Init,
702 Name,
703 &CGM.getModule());
704 // No special section on property lists?
705 UsedGlobals.push_back(GV);
706 return llvm::ConstantExpr::getBitCast(GV,
707 ObjCTypes.PropertyListPtrTy);
708
709}
710
711/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000712 struct objc_method_description_list {
713 int count;
714 struct objc_method_description list[];
715 };
716*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000717llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
718 bool IsProtocol,
719 bool ClassMethods,
720 bool Required,
721 ObjCMethodDecl * const *begin,
722 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000723 std::vector<llvm::Constant*> Methods, Desc(2);
724 for (; begin != end; ++begin) {
725 ObjCMethodDecl *D = *begin;
726 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
727
728 // Skip if this method is required and we are outputting optional
729 // methods, or vice versa.
730 if (Required != IsRequired)
731 continue;
732
733 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
734 ObjCTypes.SelectorPtrTy);
735 Desc[1] = GetMethodVarType(D);
736 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
737 Desc));
738 }
739
740 // Return null for empty list.
741 if (Methods.empty())
742 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
743
744 std::vector<llvm::Constant*> Values(2);
745 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
746 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
747 Methods.size());
748 Values[1] = llvm::ConstantArray::get(AT, Methods);
749 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
750
751 char Prefix[256];
752 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
753 IsProtocol ? "PROTOCOL_" : "",
754 ClassMethods ? "CLASS_" : "INSTANCE_",
755 !Required ? "OPT_" : "");
756 llvm::GlobalVariable *GV =
757 new llvm::GlobalVariable(Init->getType(), false,
758 llvm::GlobalValue::InternalLinkage,
759 Init,
760 std::string(Prefix) + TypeName,
761 &CGM.getModule());
762 if (ClassMethods) {
763 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
764 } else {
765 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
766 }
767 UsedGlobals.push_back(GV);
768 return llvm::ConstantExpr::getBitCast(GV,
769 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000770}
771
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000772/*
773 struct _objc_category {
774 char *category_name;
775 char *class_name;
776 struct _objc_method_list *instance_methods;
777 struct _objc_method_list *class_methods;
778 struct _objc_protocol_list *protocols;
779 uint32_t size; // <rdar://4585769>
780 struct _objc_property_list *instance_properties;
781 };
782 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000783void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000784 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
785
786 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
787 std::string ExtName(std::string(Interface->getName()) +
788 "_" +
789 OCD->getName());
790
791 std::vector<llvm::Constant*> Values(7);
792 Values[0] = GetClassName(OCD->getIdentifier());
793 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000794 Values[2] =
795 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
796 ExtName,
797 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
798 OCD->instmeth_begin(),
799 OCD->instmeth_end());
800 Values[3] =
801 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
802 "__OBJC,__cat_class_meth,regular,no_dead_strip",
803 OCD->classmeth_begin(),
804 OCD->classmeth_end());
805 Values[4] =
806 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
807 Interface->protocol_begin(),
808 Interface->protocol_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000809 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000810 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
811 Interface->classprop_begin(),
812 Interface->classprop_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000813
814 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
815 Values);
816
817 llvm::GlobalVariable *GV =
818 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
819 llvm::GlobalValue::InternalLinkage,
820 Init,
821 std::string("\01L_OBJC_CATEGORY_")+ExtName,
822 &CGM.getModule());
823 GV->setSection("__OBJC,__category,regular,no_dead_strip");
824 UsedGlobals.push_back(GV);
825 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000826}
827
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000828// FIXME: Get from somewhere?
829enum ClassFlags {
830 eClassFlags_Factory = 0x00001,
831 eClassFlags_Meta = 0x00002,
832 // <rdr://5142207>
833 eClassFlags_HasCXXStructors = 0x02000,
834 eClassFlags_Hidden = 0x20000,
835 eClassFlags_ABI2_Hidden = 0x00010,
836 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
837};
838
839// <rdr://5142207&4705298&4843145>
840static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
841 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
842 // FIXME: Support -fvisibility
843 switch (attr->getVisibility()) {
844 default:
845 assert(0 && "Unknown visibility");
846 return false;
847 case VisibilityAttr::DefaultVisibility:
848 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
849 return false;
850 case VisibilityAttr::HiddenVisibility:
851 return true;
852 }
853 } else {
854 return false; // FIXME: Support -fvisibility
855 }
856}
857
858/*
859 struct _objc_class {
860 Class isa;
861 Class super_class;
862 const char *name;
863 long version;
864 long info;
865 long instance_size;
866 struct _objc_ivar_list *ivars;
867 struct _objc_method_list *methods;
868 struct _objc_cache *cache;
869 struct _objc_protocol_list *protocols;
870 // Objective-C 1.0 extensions (<rdr://4585769>)
871 const char *ivar_layout;
872 struct _objc_class_ext *ext;
873 };
874
875 See EmitClassExtension();
876 */
877void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000878 DefinedSymbols.insert(ID->getIdentifier());
879
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000880 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000881 // FIXME: Gross
882 ObjCInterfaceDecl *Interface =
883 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000884 llvm::Constant *Protocols =
885 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
886 Interface->protocol_begin(),
887 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000888 const llvm::Type *InterfaceTy =
889 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
890 unsigned Flags = eClassFlags_Factory;
891 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
892
893 // FIXME: Set CXX-structors flag.
894 if (IsClassHidden(ID->getClassInterface()))
895 Flags |= eClassFlags_Hidden;
896
897 std::vector<llvm::Constant*> Values(12);
898 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
899 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000900 // Record a reference to the super class.
901 LazySymbols.insert(Super->getIdentifier());
902
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000903 Values[ 1] =
904 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
905 ObjCTypes.ClassPtrTy);
906 } else {
907 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
908 }
909 Values[ 2] = GetClassName(ID->getIdentifier());
910 // Version is always 0.
911 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
912 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
913 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
914 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000915 Values[ 7] =
916 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
917 "__OBJC,__inst_meth,regular,no_dead_strip",
918 ID->instmeth_begin(),
919 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000920 // cache is always NULL.
921 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
922 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000923 // FIXME: Set ivar_layout
924 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000925 Values[11] = EmitClassExtension(ID);
926 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
927 Values);
928
929 llvm::GlobalVariable *GV =
930 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
931 llvm::GlobalValue::InternalLinkage,
932 Init,
933 std::string("\01L_OBJC_CLASS_")+ClassName,
934 &CGM.getModule());
935 GV->setSection("__OBJC,__class,regular,no_dead_strip");
936 UsedGlobals.push_back(GV);
937 // FIXME: Why?
938 GV->setAlignment(32);
939 DefinedClasses.push_back(GV);
940}
941
942llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
943 llvm::Constant *Protocols,
944 const llvm::Type *InterfaceTy) {
945 const char *ClassName = ID->getName();
946 unsigned Flags = eClassFlags_Meta;
947 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
948
949 if (IsClassHidden(ID->getClassInterface()))
950 Flags |= eClassFlags_Hidden;
951
952 std::vector<llvm::Constant*> Values(12);
953 // The isa for the metaclass is the root of the hierarchy.
954 const ObjCInterfaceDecl *Root = ID->getClassInterface();
955 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
956 Root = Super;
957 Values[ 0] =
958 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
959 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000960 // The super class for the metaclass is emitted as the name of the
961 // super class. The runtime fixes this up to point to the
962 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000963 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
964 Values[ 1] =
965 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
966 ObjCTypes.ClassPtrTy);
967 } else {
968 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
969 }
970 Values[ 2] = GetClassName(ID->getIdentifier());
971 // Version is always 0.
972 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
973 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
974 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
975 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000976 Values[ 7] =
977 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
978 "__OBJC,__inst_meth,regular,no_dead_strip",
979 ID->classmeth_begin(),
980 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000981 // cache is always NULL.
982 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
983 Values[ 9] = Protocols;
984 // ivar_layout for metaclass is always NULL.
985 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
986 // The class extension is always unused for metaclasses.
987 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
988 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
989 Values);
990
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000991 std::string Name("\01L_OBJC_METACLASS_");
992 Name += ClassName;
993
994 // Check for a forward reference.
995 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
996 if (GV) {
997 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
998 "Forward metaclass reference has incorrect type.");
999 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
1000 GV->setInitializer(Init);
1001 } else {
1002 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1003 llvm::GlobalValue::InternalLinkage,
1004 Init, Name,
1005 &CGM.getModule());
1006 }
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001007 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
1008 UsedGlobals.push_back(GV);
1009 // FIXME: Why?
1010 GV->setAlignment(32);
1011
1012 return GV;
1013}
1014
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001015llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
1016 std::string Name("\01L_OBJC_METACLASS_");
1017 Name += ID->getName();
1018
1019 // FIXME: Should we look these up somewhere other than the
1020 // module. Its a bit silly since we only generate these while
1021 // processing an implementation, so exactly one pointer would work
1022 // if know when we entered/exitted an implementation block.
1023
1024 // Check for an existing forward reference.
1025 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) {
1026 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1027 "Forward metaclass reference has incorrect type.");
1028 return GV;
1029 } else {
1030 // Generate as an external reference to keep a consistent
1031 // module. This will be patched up when we emit the metaclass.
1032 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1033 llvm::GlobalValue::ExternalLinkage,
1034 0,
1035 Name,
1036 &CGM.getModule());
1037 }
1038}
1039
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001040/*
1041 struct objc_class_ext {
1042 uint32_t size;
1043 const char *weak_ivar_layout;
1044 struct _objc_property_list *properties;
1045 };
1046*/
1047llvm::Constant *
1048CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1049 uint64_t Size =
1050 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1051
1052 std::vector<llvm::Constant*> Values(3);
1053 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001054 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001055 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001056 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1057 ID->getName(),
1058 ID->getClassInterface()->classprop_begin(),
1059 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001060
1061 // Return null if no extension bits are used.
1062 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1063 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1064
1065 llvm::Constant *Init =
1066 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1067 llvm::GlobalVariable *GV =
1068 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1069 llvm::GlobalValue::InternalLinkage,
1070 Init,
1071 (std::string("\01L_OBJC_CLASSEXT_") +
1072 ID->getName()),
1073 &CGM.getModule());
1074 // No special section, but goes in llvm.used
1075 UsedGlobals.push_back(GV);
1076
1077 return GV;
1078}
1079
1080/*
1081 struct objc_ivar {
1082 char *ivar_name;
1083 char *ivar_type;
1084 int ivar_offset;
1085 };
1086
1087 struct objc_ivar_list {
1088 int ivar_count;
1089 struct objc_ivar list[count];
1090 };
1091 */
1092llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1093 bool ForClass,
1094 const llvm::Type *InterfaceTy) {
1095 std::vector<llvm::Constant*> Ivars, Ivar(3);
1096
1097 // When emitting the root class GCC emits ivar entries for the
1098 // actual class structure. It is not clear if we need to follow this
1099 // behavior; for now lets try and get away with not doing it. If so,
1100 // the cleanest solution would be to make up an ObjCInterfaceDecl
1101 // for the class.
1102 if (ForClass)
1103 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1104
1105 const llvm::StructLayout *Layout =
1106 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1107 for (ObjCInterfaceDecl::ivar_iterator
1108 i = ID->getClassInterface()->ivar_begin(),
1109 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1110 ObjCIvarDecl *V = *i;
1111 unsigned Offset =
1112 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1113 std::string TypeStr;
1114 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1115 Ivar[0] = GetMethodVarName(V->getIdentifier());
1116 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1117 EncodingRecordTypes);
1118 Ivar[1] = GetMethodVarType(TypeStr);
1119 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1120 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1121 Ivar));
1122 }
1123
1124 // Return null for empty list.
1125 if (Ivars.empty())
1126 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1127
1128 std::vector<llvm::Constant*> Values(2);
1129 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1130 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1131 Ivars.size());
1132 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1133 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1134
1135 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1136 "\01L_OBJC_INSTANCE_VARIABLES_");
1137 llvm::GlobalVariable *GV =
1138 new llvm::GlobalVariable(Init->getType(), false,
1139 llvm::GlobalValue::InternalLinkage,
1140 Init,
1141 std::string(Prefix) + ID->getName(),
1142 &CGM.getModule());
1143 if (ForClass) {
1144 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1145 // FIXME: Why is this only here?
1146 GV->setAlignment(32);
1147 } else {
1148 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1149 }
1150 UsedGlobals.push_back(GV);
1151 return llvm::ConstantExpr::getBitCast(GV,
1152 ObjCTypes.IvarListPtrTy);
1153}
1154
1155/*
1156 struct objc_method {
1157 SEL method_name;
1158 char *method_types;
1159 void *method;
1160 };
1161
1162 struct objc_method_list {
1163 struct objc_method_list *obsolete;
1164 int count;
1165 struct objc_method methods_list[count];
1166 };
1167*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001168llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1169 const char *Section,
1170 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1171 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001172 std::vector<llvm::Constant*> Methods, Method(3);
1173
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001174 for (; begin != end; ++begin) {
1175 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001176
1177 Method[0] =
1178 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1179 ObjCTypes.SelectorPtrTy);
1180 Method[1] = GetMethodVarType(MD);
1181
1182 // FIXME: This is gross, we shouldn't be looking up by name.
1183 std::string Name;
1184 GetNameForMethod(MD, Name);
1185 Method[2] =
1186 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1187 ObjCTypes.Int8PtrTy);
1188 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1189 Method));
1190 }
1191
1192 // Return null for empty list.
1193 if (Methods.empty())
1194 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1195
1196 std::vector<llvm::Constant*> Values(3);
1197 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1198 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1199 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1200 Methods.size());
1201 Values[2] = llvm::ConstantArray::get(AT, Methods);
1202 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1203
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001204 llvm::GlobalVariable *GV =
1205 new llvm::GlobalVariable(Init->getType(), false,
1206 llvm::GlobalValue::InternalLinkage,
1207 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001208 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001209 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001210 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001211 UsedGlobals.push_back(GV);
1212 return llvm::ConstantExpr::getBitCast(GV,
1213 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001214}
1215
1216llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1217 const llvm::Type *ReturnTy =
1218 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1219 const llvm::Type *SelfTy =
1220 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1221
1222 std::vector<const llvm::Type*> ArgTys;
1223 ArgTys.reserve(1 + 2 + OMD->param_size());
1224
1225 // FIXME: This is not something we should have to be dealing with
1226 // here.
1227 bool useStructRet =
1228 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1229 if (useStructRet) {
1230 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1231 ReturnTy = llvm::Type::VoidTy;
1232 }
1233
1234 // Implicit arguments
1235 ArgTys.push_back(SelfTy);
1236 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1237
1238 for (ObjCMethodDecl::param_const_iterator
1239 i = OMD->param_begin(), e = OMD->param_end();
1240 i != e; ++i) {
1241 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001242 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001243 ArgTys.push_back(Ty);
1244 } else {
1245 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1246 }
1247 }
1248
1249 std::string Name;
1250 GetNameForMethod(OMD, Name);
1251
1252 llvm::Function *Method =
1253 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1254 ArgTys,
1255 OMD->isVariadic()),
1256 llvm::GlobalValue::InternalLinkage,
1257 Name,
1258 &CGM.getModule());
1259
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001260 unsigned Offset = 3; // Return plus self and selector implicit args.
1261 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001262 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001263 ++Offset;
1264 }
1265
1266 // FIXME: This is horrible, we need to be reusing the machinery in
1267 // CodeGenModule.cpp (SetFunctionAttributes).
1268 for (ObjCMethodDecl::param_const_iterator
1269 i = OMD->param_begin(), e = OMD->param_end();
1270 i != e; ++i, ++Offset) {
1271 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1272 if (!Ty->isSingleValueType())
1273 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1274 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001275
1276 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001277}
1278
1279llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001280 // Abuse this interface function as a place to finalize.
1281 FinishModule();
1282
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001283 return NULL;
1284}
1285
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001286/* *** Private Interface *** */
1287
1288/// EmitImageInfo - Emit the image info marker used to encode some module
1289/// level information.
1290///
1291/// See: <rdr://4810609&4810587&4810587>
1292/// struct IMAGE_INFO {
1293/// unsigned version;
1294/// unsigned flags;
1295/// };
1296enum ImageInfoFlags {
1297 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1298 eImageInfo_GarbageCollected = (1 << 1),
1299 eImageInfo_GCOnly = (1 << 2)
1300};
1301
1302void CGObjCMac::EmitImageInfo() {
1303 unsigned version = 0; // Version is unused?
1304 unsigned flags = 0;
1305
1306 // FIXME: Fix and continue?
1307 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1308 flags |= eImageInfo_GarbageCollected;
1309 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1310 flags |= eImageInfo_GCOnly;
1311
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001312 // Emitted as int[2];
1313 llvm::Constant *values[2] = {
1314 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1315 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1316 };
1317 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001318 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001319 new llvm::GlobalVariable(AT, true,
1320 llvm::GlobalValue::InternalLinkage,
1321 llvm::ConstantArray::get(AT, values, 2),
1322 "\01L_OBJC_IMAGE_INFO",
1323 &CGM.getModule());
1324
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001325 if (ObjCABI == 1) {
1326 GV->setSection("__OBJC, __image_info,regular");
1327 } else {
1328 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1329 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001330
1331 UsedGlobals.push_back(GV);
1332}
1333
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001334
1335// struct objc_module {
1336// unsigned long version;
1337// unsigned long size;
1338// const char *name;
1339// Symtab symtab;
1340// };
1341
1342// FIXME: Get from somewhere
1343static const int ModuleVersion = 7;
1344
1345void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001346 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1347
1348 std::vector<llvm::Constant*> Values(4);
1349 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1350 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001351 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001352 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001353 Values[3] = EmitModuleSymbols();
1354
1355 llvm::GlobalVariable *GV =
1356 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1357 llvm::GlobalValue::InternalLinkage,
1358 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1359 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001360 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001361 &CGM.getModule());
1362 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1363 UsedGlobals.push_back(GV);
1364}
1365
1366llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001367 unsigned NumClasses = DefinedClasses.size();
1368 unsigned NumCategories = DefinedCategories.size();
1369
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001370 // Return null if no symbols were defined.
1371 if (!NumClasses && !NumCategories)
1372 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
1373
1374 std::vector<llvm::Constant*> Values(5);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001375 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1376 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1377 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1378 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1379
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001380 // The runtime expects exactly the list of defined classes followed
1381 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001382 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001383 for (unsigned i=0; i<NumClasses; i++)
1384 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1385 ObjCTypes.Int8PtrTy);
1386 for (unsigned i=0; i<NumCategories; i++)
1387 Symbols[NumClasses + i] =
1388 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1389 ObjCTypes.Int8PtrTy);
1390
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001391 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001392 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001393 NumClasses + NumCategories),
1394 Symbols);
1395
1396 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1397
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001398 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001399 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001400 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001401 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001402 "\01L_OBJC_SYMBOLS",
1403 &CGM.getModule());
1404 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1405 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001406 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1407}
1408
1409llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1410 const ObjCInterfaceDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001411 LazySymbols.insert(ID->getIdentifier());
1412
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001413 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1414
1415 if (!Entry) {
1416 llvm::Constant *Casted =
1417 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1418 ObjCTypes.ClassPtrTy);
1419 Entry =
1420 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1421 llvm::GlobalValue::InternalLinkage,
1422 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1423 &CGM.getModule());
1424 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1425 UsedGlobals.push_back(Entry);
1426 }
1427
1428 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001429}
1430
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001431llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1432 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1433
1434 if (!Entry) {
1435 llvm::Constant *Casted =
1436 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1437 ObjCTypes.SelectorPtrTy);
1438 Entry =
1439 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1440 llvm::GlobalValue::InternalLinkage,
1441 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1442 &CGM.getModule());
1443 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1444 UsedGlobals.push_back(Entry);
1445 }
1446
1447 return Builder.CreateLoad(Entry, false, "tmp");
1448}
1449
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001450llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1451 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001452
1453 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001454 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001455 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001456 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001457 llvm::GlobalValue::InternalLinkage,
1458 C, "\01L_OBJC_CLASS_NAME_",
1459 &CGM.getModule());
1460 Entry->setSection("__TEXT,__cstring,cstring_literals");
1461 UsedGlobals.push_back(Entry);
1462 }
1463
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001464 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001465}
1466
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001467llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1468 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1469
1470 if (!Entry) {
1471 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1472 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001473 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001474 llvm::GlobalValue::InternalLinkage,
1475 C, "\01L_OBJC_METH_VAR_NAME_",
1476 &CGM.getModule());
1477 Entry->setSection("__TEXT,__cstring,cstring_literals");
1478 UsedGlobals.push_back(Entry);
1479 }
1480
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001481 return getConstantGEP(Entry, 0, 0);
1482}
1483
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001484// FIXME: Merge into a single cstring creation function.
1485llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1486 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1487}
1488
1489// FIXME: Merge into a single cstring creation function.
1490llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1491 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1492}
1493
1494llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1495 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001496
1497 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001498 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001499 Entry =
1500 new llvm::GlobalVariable(C->getType(), false,
1501 llvm::GlobalValue::InternalLinkage,
1502 C, "\01L_OBJC_METH_VAR_TYPE_",
1503 &CGM.getModule());
1504 Entry->setSection("__TEXT,__cstring,cstring_literals");
1505 UsedGlobals.push_back(Entry);
1506 }
1507
1508 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001509}
1510
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001511// FIXME: Merge into a single cstring creation function.
1512llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1513 std::string TypeStr;
1514 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1515 return GetMethodVarType(TypeStr);
1516}
1517
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001518// FIXME: Merge into a single cstring creation function.
1519llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1520 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1521
1522 if (!Entry) {
1523 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1524 Entry =
1525 new llvm::GlobalVariable(C->getType(), false,
1526 llvm::GlobalValue::InternalLinkage,
1527 C, "\01L_OBJC_PROP_NAME_ATTR_",
1528 &CGM.getModule());
1529 Entry->setSection("__TEXT,__cstring,cstring_literals");
1530 UsedGlobals.push_back(Entry);
1531 }
1532
1533 return getConstantGEP(Entry, 0, 0);
1534}
1535
1536// FIXME: Merge into a single cstring creation function.
1537llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1538 std::string TypeStr("MOOO!");
1539 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1540 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1541}
1542
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001543void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1544 std::string &NameOut) {
1545 // FIXME: Find the mangling GCC uses.
1546 std::stringstream s;
1547 s << (D->isInstance() ? "-" : "+");
1548 s << "[";
1549 s << D->getClassInterface()->getName();
1550 s << " ";
1551 s << D->getSelector().getName();
1552 s << "]";
1553 NameOut = s.str();
1554}
1555
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001556void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001557 EmitModuleInfo();
1558
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001559 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001560
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001561 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001562 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001563 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001564 }
1565
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001566 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001567 llvm::GlobalValue *GV =
1568 new llvm::GlobalVariable(AT, false,
1569 llvm::GlobalValue::AppendingLinkage,
1570 llvm::ConstantArray::get(AT, Used),
1571 "llvm.used",
1572 &CGM.getModule());
1573
1574 GV->setSection("llvm.metadata");
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001575
1576 // Add assembler directives to add lazy undefined symbol references
1577 // for classes which are referenced but not defined. This is
1578 // important for correct linker interaction.
1579
1580 // FIXME: Uh, this isn't particularly portable.
1581 std::stringstream s;
1582 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
1583 e = LazySymbols.end(); i != e; ++i) {
1584 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
1585 }
1586 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
1587 e = DefinedSymbols.end(); i != e; ++i) {
1588 s << "\t.objc_class_name_" << (*i)->getName() << " = 0\n"
1589 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
1590 }
1591 CGM.getModule().appendModuleInlineAsm(s.str());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001592}
1593
1594/* *** */
1595
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001596ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbar3e9df992008-08-23 18:37:06 +00001597 : CGM(cgm)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001598{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001599 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1600 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001601
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001602 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001603 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001604 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001605 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1606
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001607 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1608 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001609
1610 // FIXME: It would be nice to unify this with the opaque type, so
1611 // that the IR comes out a bit cleaner.
1612 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1613 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001614
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001615 MethodDescriptionTy =
1616 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001617 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001618 NULL);
1619 CGM.getModule().addTypeName("struct._objc_method_description",
1620 MethodDescriptionTy);
1621
1622 MethodDescriptionListTy =
1623 llvm::StructType::get(IntTy,
1624 llvm::ArrayType::get(MethodDescriptionTy, 0),
1625 NULL);
1626 CGM.getModule().addTypeName("struct._objc_method_description_list",
1627 MethodDescriptionListTy);
1628 MethodDescriptionListPtrTy =
1629 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1630
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001631 PropertyTy = llvm::StructType::get(Int8PtrTy,
1632 Int8PtrTy,
1633 NULL);
1634 CGM.getModule().addTypeName("struct._objc_property",
1635 PropertyTy);
1636
1637 PropertyListTy = llvm::StructType::get(IntTy,
1638 IntTy,
1639 llvm::ArrayType::get(PropertyTy, 0),
1640 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001641 CGM.getModule().addTypeName("struct._objc_property_list",
1642 PropertyListTy);
1643 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1644
1645 // Protocol description structures
1646
1647 ProtocolExtensionTy =
1648 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1649 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1650 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1651 PropertyListPtrTy,
1652 NULL);
1653 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1654 ProtocolExtensionTy);
1655 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1656
1657 // Handle recursive construction of Protocl and ProtocolList types
1658
1659 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1660 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1661
1662 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1663 LongTy,
1664 llvm::ArrayType::get(ProtocolTyHolder, 0),
1665 NULL);
1666 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1667
1668 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001669 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001670 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1671 MethodDescriptionListPtrTy,
1672 MethodDescriptionListPtrTy,
1673 NULL);
1674 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1675
1676 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1677 CGM.getModule().addTypeName("struct._objc_protocol_list",
1678 ProtocolListTy);
1679 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1680
1681 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1682 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1683 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001684
1685 // Class description structures
1686
1687 IvarTy = llvm::StructType::get(Int8PtrTy,
1688 Int8PtrTy,
1689 IntTy,
1690 NULL);
1691 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1692
1693 IvarListTy = llvm::OpaqueType::get();
1694 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1695 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1696
1697 MethodTy = llvm::StructType::get(SelectorPtrTy,
1698 Int8PtrTy,
1699 Int8PtrTy,
1700 NULL);
1701 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1702
1703 MethodListTy = llvm::OpaqueType::get();
1704 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1705 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1706
1707 CacheTy = llvm::OpaqueType::get();
1708 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1709 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1710
1711 ClassExtensionTy =
1712 llvm::StructType::get(IntTy,
1713 Int8PtrTy,
1714 PropertyListPtrTy,
1715 NULL);
1716 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1717 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1718
1719 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1720
1721 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1722 llvm::PointerType::getUnqual(ClassTyHolder),
1723 Int8PtrTy,
1724 LongTy,
1725 LongTy,
1726 LongTy,
1727 IvarListPtrTy,
1728 MethodListPtrTy,
1729 CachePtrTy,
1730 ProtocolListPtrTy,
1731 Int8PtrTy,
1732 ClassExtensionPtrTy,
1733 NULL);
1734 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1735
1736 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1737 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1738 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1739
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001740 CategoryTy = llvm::StructType::get(Int8PtrTy,
1741 Int8PtrTy,
1742 MethodListPtrTy,
1743 MethodListPtrTy,
1744 ProtocolListPtrTy,
1745 IntTy,
1746 PropertyListPtrTy,
1747 NULL);
1748 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1749
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001750 SuperTy =
1751 llvm::StructType::get(ObjectPtrTy,
1752 ClassPtrTy,
1753 NULL);
1754 CGM.getModule().addTypeName("struct._objc_super",
1755 SuperTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001756 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001757
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001758 // Global metadata structures
1759
1760 SymtabTy = llvm::StructType::get(LongTy,
1761 SelectorPtrTy,
1762 ShortTy,
1763 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001764 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001765 NULL);
1766 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1767 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1768
1769 ModuleTy =
1770 llvm::StructType::get(LongTy,
1771 LongTy,
1772 Int8PtrTy,
1773 SymtabPtrTy,
1774 NULL);
1775 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001776
1777 // Message send functions
1778
1779 std::vector<const llvm::Type*> Params;
1780 Params.push_back(ObjectPtrTy);
1781 Params.push_back(SelectorPtrTy);
1782 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1783 Params,
1784 true),
1785 llvm::Function::ExternalLinkage,
1786 "objc_msgSend",
1787 &CGM.getModule());
1788
1789 Params.clear();
1790 Params.push_back(Int8PtrTy);
1791 Params.push_back(ObjectPtrTy);
1792 Params.push_back(SelectorPtrTy);
1793 MessageSendStretFn =
1794 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1795 Params,
1796 true),
1797 llvm::Function::ExternalLinkage,
1798 "objc_msgSend_stret",
1799 &CGM.getModule());
1800
1801 Params.clear();
1802 Params.push_back(SuperPtrTy);
1803 Params.push_back(SelectorPtrTy);
1804 MessageSendSuperFn =
1805 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1806 Params,
1807 true),
1808 llvm::Function::ExternalLinkage,
1809 "objc_msgSendSuper",
1810 &CGM.getModule());
1811
1812 Params.clear();
1813 Params.push_back(Int8PtrTy);
1814 Params.push_back(SuperPtrTy);
1815 Params.push_back(SelectorPtrTy);
1816 MessageSendSuperStretFn =
1817 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1818 Params,
1819 true),
1820 llvm::Function::ExternalLinkage,
1821 "objc_msgSendSuper_stret",
1822 &CGM.getModule());
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001823}
1824
1825ObjCTypesHelper::~ObjCTypesHelper() {
1826}
1827
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001828llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
1829 const llvm::Type *ReturnTy) {
1830 llvm::Function *F;
1831 llvm::FunctionType *CallFTy;
1832
1833 // FIXME: Should we be caching any of this?
1834 if (!ReturnTy->isSingleValueType()) {
1835 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
1836 std::vector<const llvm::Type*> Params(3);
1837 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
1838 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1839 Params[2] = SelectorPtrTy;
1840 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
1841 } else { // XXX floating point?
1842 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
1843 std::vector<const llvm::Type*> Params(2);
1844 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1845 Params[1] = SelectorPtrTy;
1846 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001847 }
1848
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001849 return llvm::ConstantExpr::getBitCast(F,
1850 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001851}
1852
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001853/* *** */
1854
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001855CodeGen::CGObjCRuntime *
1856CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001857 return new CGObjCMac(CGM);
1858}