blob: 9638bc1430819eeecdfb11004ecc10fd39ad6774 [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 Dunbarae226fa2008-08-27 02:31:56 +000032 typedef std::vector<llvm::Constant*> ConstantVector;
33
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000034 // FIXME: We should find a nicer way to make the labels for
35 // metadata, string concatenation is lame.
36
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000037/// ObjCTypesHelper - Helper class that encapsulates lazy
38/// construction of varies types used during ObjC generation.
39class ObjCTypesHelper {
40private:
41 CodeGen::CodeGenModule &CGM;
42
Daniel Dunbar14c80b72008-08-23 09:25:55 +000043 llvm::Function *MessageSendFn, *MessageSendStretFn;
44 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000045
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000046public:
Daniel Dunbar27f9d772008-08-21 04:36:09 +000047 const llvm::Type *ShortTy, *IntTy, *LongTy;
48 const llvm::Type *Int8PtrTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000049
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000050 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
51 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000052 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000053 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000054 /// ProtocolPtrTy - LLVM type for external protocol handles
55 /// (typeof(Protocol))
56 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000057
Daniel Dunbar19cd87e2008-08-30 03:02:31 +000058 // SuperCTy - clang type for struct objc_super.
59 QualType SuperCTy;
60 // SuperPtrCTy - clang type for struct objc_super *.
61 QualType SuperPtrCTy;
62
Daniel Dunbare8b470d2008-08-23 04:28:29 +000063 /// SuperTy - LLVM type for struct objc_super.
64 const llvm::StructType *SuperTy;
Daniel Dunbar14c80b72008-08-23 09:25:55 +000065 /// SuperPtrTy - LLVM type for struct objc_super *.
66 const llvm::Type *SuperPtrTy;
Daniel Dunbare8b470d2008-08-23 04:28:29 +000067
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000068 /// SymtabTy - LLVM type for struct objc_symtab.
69 const llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000070 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
71 const llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000072 /// ModuleTy - LLVM type for struct objc_module.
73 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000074
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000075 /// ProtocolTy - LLVM type for struct objc_protocol.
76 const llvm::StructType *ProtocolTy;
77 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
78 const llvm::Type *ProtocolPtrTy;
79 /// ProtocolExtensionTy - LLVM type for struct
80 /// objc_protocol_extension.
81 const llvm::StructType *ProtocolExtensionTy;
82 /// ProtocolExtensionTy - LLVM type for struct
83 /// objc_protocol_extension *.
84 const llvm::Type *ProtocolExtensionPtrTy;
85 /// MethodDescriptionTy - LLVM type for struct
86 /// objc_method_description.
87 const llvm::StructType *MethodDescriptionTy;
88 /// MethodDescriptionListTy - LLVM type for struct
89 /// objc_method_description_list.
90 const llvm::StructType *MethodDescriptionListTy;
91 /// MethodDescriptionListPtrTy - LLVM type for struct
92 /// objc_method_description_list *.
93 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbarc8ef5512008-08-23 00:19:03 +000094 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
95 /// in GCC parlance).
96 const llvm::StructType *PropertyTy;
97 /// PropertyListTy - LLVM type for struct objc_property_list
98 /// (_prop_list_t in GCC parlance).
99 const llvm::StructType *PropertyListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000100 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
101 const llvm::Type *PropertyListPtrTy;
102 /// ProtocolListTy - LLVM type for struct objc_property_list.
103 const llvm::Type *ProtocolListTy;
104 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
105 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000106 /// CategoryTy - LLVM type for struct objc_category.
107 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000108 /// ClassTy - LLVM type for struct objc_class.
109 const llvm::StructType *ClassTy;
110 /// ClassPtrTy - LLVM type for struct objc_class *.
111 const llvm::Type *ClassPtrTy;
112 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
113 const llvm::StructType *ClassExtensionTy;
114 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
115 const llvm::Type *ClassExtensionPtrTy;
116 /// CacheTy - LLVM type for struct objc_cache.
117 const llvm::Type *CacheTy;
118 /// CachePtrTy - LLVM type for struct objc_cache *.
119 const llvm::Type *CachePtrTy;
120 // IvarTy - LLVM type for struct objc_ivar.
121 const llvm::StructType *IvarTy;
122 /// IvarListTy - LLVM type for struct objc_ivar_list.
123 const llvm::Type *IvarListTy;
124 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
125 const llvm::Type *IvarListPtrTy;
126 // MethodTy - LLVM type for struct objc_method.
127 const llvm::StructType *MethodTy;
128 /// MethodListTy - LLVM type for struct objc_method_list.
129 const llvm::Type *MethodListTy;
130 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
131 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000132
Anders Carlsson2abd89c2008-08-31 04:05:03 +0000133 llvm::Function *EnumerationMutationFn;
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000134public:
135 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
136 ~ObjCTypesHelper();
137
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000138 llvm::Value *getMessageSendFn(bool IsSuper, const llvm::Type *ReturnTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000139};
140
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000141class CGObjCMac : public CodeGen::CGObjCRuntime {
142private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000143 CodeGen::CodeGenModule &CGM;
144 ObjCTypesHelper ObjCTypes;
145 /// ObjCABI - FIXME: Not sure yet.
146 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000147
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000148 /// LazySymbols - Symbols to generate a lazy reference for. See
149 /// DefinedSymbols and FinishModule().
150 std::set<IdentifierInfo*> LazySymbols;
151
152 /// DefinedSymbols - External symbols which are defined by this
153 /// module. The symbols in this list and LazySymbols are used to add
154 /// special linker symbols which ensure that Objective-C modules are
155 /// linked properly.
156 std::set<IdentifierInfo*> DefinedSymbols;
157
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000158 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000159 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000160
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000161 /// MethodVarNames - uniqued method variable names.
162 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
163
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000164 /// MethodVarTypes - uniqued method type signatures. We have to use
165 /// a StringMap here because have no other unique reference.
166 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
167
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000168 /// MethodDefinitions - map of methods which have been defined in
169 /// this translation unit.
170 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
171
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000172 /// PropertyNames - uniqued method variable names.
173 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
174
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000175 /// ClassReferences - uniqued class references.
176 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
177
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000178 /// SelectorReferences - uniqued selector references.
179 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
180
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000181 /// Protocols - Protocols for which an objc_protocol structure has
182 /// been emitted. Forward declarations are handled by creating an
183 /// empty structure whose initializer is filled in when/if defined.
184 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
185
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000186 /// DefinedClasses - List of defined classes.
187 std::vector<llvm::GlobalValue*> DefinedClasses;
188
189 /// DefinedCategories - List of defined categories.
190 std::vector<llvm::GlobalValue*> DefinedCategories;
191
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000192 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000193 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000194 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000195
196 /// EmitImageInfo - Emit the image info marker used to encode some module
197 /// level information.
198 void EmitImageInfo();
199
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000200 /// EmitModuleInfo - Another marker encoding module level
201 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000202 void EmitModuleInfo();
203
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000204 /// EmitModuleSymols - Emit module symbols, the list of defined
205 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000206 llvm::Constant *EmitModuleSymbols();
207
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000208 /// FinishModule - Write out global data structures at the end of
209 /// processing a translation unit.
210 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000211
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000212 /// EmitClassExtension - Generate the class extension structure used
213 /// to store the weak ivar layout and properties. The return value
214 /// has type ClassExtensionPtrTy.
215 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
216
217 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
218 /// for the given class.
219 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
220 const ObjCInterfaceDecl *ID);
221
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000222 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000223 QualType ResultType,
224 Selector Sel,
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000225 llvm::Value *Arg0,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000226 QualType Arg0Ty,
227 bool IsSuper,
228 const CallArgList &CallArgs);
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000229
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000230 /// EmitIvarList - Emit the ivar list for the given
231 /// implementation. If ForClass is true the list of class ivars
232 /// (i.e. metaclass ivars) is emitted, otherwise the list of
233 /// interface ivars will be emitted. The return value has type
234 /// IvarListPtrTy.
235 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
236 bool ForClass,
237 const llvm::Type *InterfaceTy);
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000238
239 /// EmitMetaClass - Emit a forward reference to the class structure
240 /// for the metaclass of the given interface. The return value has
241 /// type ClassPtrTy.
242 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
243
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000244 /// EmitMetaClass - Emit a class structure for the metaclass of the
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000245 /// given implementation. The return value has type ClassPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000246 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
247 llvm::Constant *Protocols,
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000248 const llvm::Type *InterfaceTy,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000249 const ConstantVector &Methods);
250
251 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
252
253 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000254
255 /// EmitMethodList - Emit the method list for the given
Daniel Dunbaraf05bb92008-08-26 08:29:31 +0000256 /// implementation. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000257 llvm::Constant *EmitMethodList(const std::string &Name,
258 const char *Section,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000259 const ConstantVector &Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000260
261 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000262 /// method declarations.
263 /// - TypeName: The name for the type containing the methods.
264 /// - IsProtocol: True iff these methods are for a protocol.
265 /// - ClassMethds: True iff these are class methods.
266 /// - Required: When true, only "required" methods are
267 /// listed. Similarly, when false only "optional" methods are
268 /// listed. For classes this should always be true.
269 /// - begin, end: The method list to output.
270 ///
271 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000272 llvm::Constant *EmitMethodDescList(const std::string &Name,
273 const char *Section,
274 const ConstantVector &Methods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000275
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000276 /// EmitPropertyList - Emit the given property list. The return
277 /// value has type PropertyListPtrTy.
278 llvm::Constant *EmitPropertyList(const std::string &Name,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000279 const Decl *Container,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000280 ObjCPropertyDecl * const *begin,
281 ObjCPropertyDecl * const *end);
282
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000283 /// EmitProtocolExtension - Generate the protocol extension
284 /// structure used to store optional instance and class methods, and
285 /// protocol properties. The return value has type
286 /// ProtocolExtensionPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000287 llvm::Constant *
288 EmitProtocolExtension(const ObjCProtocolDecl *PD,
289 const ConstantVector &OptInstanceMethods,
290 const ConstantVector &OptClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000291
292 /// EmitProtocolList - Generate the list of referenced
293 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc933702008-08-21 21:57:41 +0000294 llvm::Constant *EmitProtocolList(const std::string &Name,
295 ObjCProtocolDecl::protocol_iterator begin,
296 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000297
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000298 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
299 /// for the given selector.
300 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
301
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000302 /// GetProtocolRef - Return a reference to the internal protocol
303 /// description, creating an empty one if it has not been
304 /// defined. The return value has type pointer-to ProtocolTy.
305 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
306
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000307 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000308 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000309 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000310
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000311 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000312 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000313 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000314 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000315 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000316
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000317 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000318 /// selector's name. The return value has type char *.
319
320 // FIXME: This is a horrible name.
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000321 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000322 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000323
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000324 /// GetPropertyName - Return a unique constant for the given
325 /// name. The return value has type char *.
326 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
327
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000328 // FIXME: This can be dropped once string functions are unified.
329 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
330 const Decl *Container);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000331
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000332 /// GetNameForMethod - Return a name for the given method.
333 /// \param[out] NameOut - The return value.
334 void GetNameForMethod(const ObjCMethodDecl *OMD,
335 std::string &NameOut);
336
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000337public:
338 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000339 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000340
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000341 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000342 QualType ResultType,
343 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000344 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000345 bool IsClassMessage,
346 const CallArgList &CallArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000347
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000348 virtual CodeGen::RValue
349 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000350 QualType ResultType,
351 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000352 const ObjCInterfaceDecl *Class,
353 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000354 bool IsClassMessage,
355 const CallArgList &CallArgs);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000356
357 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000358 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000359
360 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
361
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000362 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000363
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000364 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000365
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000366 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000367
368 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000369 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000370
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000371 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000372
373 virtual llvm::Function *ModuleInitFunction();
Anders Carlsson2abd89c2008-08-31 04:05:03 +0000374 virtual llvm::Function *EnumerationMutationFunction();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000375};
376} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000377
378/* *** Helper Functions *** */
379
380/// getConstantGEP() - Help routine to construct simple GEPs.
381static llvm::Constant *getConstantGEP(llvm::Constant *C,
382 unsigned idx0,
383 unsigned idx1) {
384 llvm::Value *Idxs[] = {
385 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
386 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
387 };
388 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
389}
390
391/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000392
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000393CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
394 : CGM(cgm),
395 ObjCTypes(cgm),
396 ObjCABI(1)
397{
398 // FIXME: How does this get set in GCC? And what does it even mean?
399 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
400 ObjCABI = 2;
401
402 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000403}
404
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000405/// GetClass - Return a reference to the class for the given interface
406/// decl.
407llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000408 const ObjCInterfaceDecl *ID) {
409 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000410}
411
412/// GetSelector - Return the pointer to the unique'd string for this selector.
413llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000414 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000415}
416
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000417/// Generate a constant CFString object.
418/*
419 struct __builtin_CFString {
420 const int *isa; // point to __CFConstantStringClassReference
421 int flags;
422 const char *str;
423 long length;
424 };
425*/
426
427llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbar3e9df992008-08-23 18:37:06 +0000428 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000429}
430
431/// Generates a message send where the super is the receiver. This is
432/// a message send to self with special delivery semantics indicating
433/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000434CodeGen::RValue
435CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000436 QualType ResultType,
437 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000438 const ObjCInterfaceDecl *Class,
439 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000440 bool IsClassMessage,
441 const CallArgList &CallArgs) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000442 // Create and init a super structure; this is a (receiver, class)
443 // pair we will pass to objc_msgSendSuper.
444 llvm::Value *ObjCSuper =
445 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
446 llvm::Value *ReceiverAsObject =
447 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
448 CGF.Builder.CreateStore(ReceiverAsObject,
449 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000450
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000451 // If this is a class message the metaclass is passed as the target.
452 llvm::Value *Target;
453 if (IsClassMessage) {
454 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
455 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
456 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
457 Target = Super;
458 } else {
459 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
460 }
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000461 // FIXME: We shouldn't need to do this cast, rectify the ASTContext
462 // and ObjCTypes types.
463 const llvm::Type *ClassTy =
464 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
465 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000466 CGF.Builder.CreateStore(Target,
467 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
468
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000469 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000470 ObjCSuper, ObjCTypes.SuperPtrCTy,
471 true, CallArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000472}
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000473
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000474/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000475CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000476 QualType ResultType,
477 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000478 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000479 bool IsClassMessage,
480 const CallArgList &CallArgs) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000481 llvm::Value *Arg0 =
482 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000483 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000484 Arg0, CGF.getContext().getObjCIdType(),
485 false, CallArgs);
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000486}
487
488CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000489 QualType ResultType,
490 Selector Sel,
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000491 llvm::Value *Arg0,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000492 QualType Arg0Ty,
493 bool IsSuper,
494 const CallArgList &CallArgs) {
495 CallArgList ActualArgs;
496 ActualArgs.push_back(std::make_pair(Arg0, Arg0Ty));
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000497 ActualArgs.push_back(std::make_pair(EmitSelector(CGF.Builder, Sel),
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000498 CGF.getContext().getObjCSelType()));
499 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000500
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000501 // FIXME: This is a hack, we are implicitly coordinating with
Daniel Dunbare66f4e32008-09-03 00:27:26 +0000502 // EmitCall, which will move the return type to the first parameter
503 // and set the structure return flag. See getMessageSendFn().
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000504
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000505 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType);
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000506 return CGF.EmitCall(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000507 ResultType, ActualArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000508}
509
510llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000511 const ObjCProtocolDecl *PD) {
Daniel Dunbarc67876d2008-09-04 04:33:15 +0000512 // FIXME: I don't understand why gcc generates this, or where it is
513 // resolved. Investigate. Its also wasteful to look this up over and
514 // over.
515 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
516
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000517 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
518 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000519}
520
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000521/*
522 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
523 struct _objc_protocol {
524 struct _objc_protocol_extension *isa;
525 char *protocol_name;
526 struct _objc_protocol_list *protocol_list;
527 struct _objc__method_prototype_list *instance_methods;
528 struct _objc__method_prototype_list *class_methods
529 };
530
531 See EmitProtocolExtension().
532*/
533void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000534 // FIXME: I don't understand why gcc generates this, or where it is
535 // resolved. Investigate. Its also wasteful to look this up over and
536 // over.
537 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
538
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000539 const char *ProtocolName = PD->getName();
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000540
541 // Construct method lists.
542 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
543 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
544 for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
545 e = PD->instmeth_end(); i != e; ++i) {
546 ObjCMethodDecl *MD = *i;
547 llvm::Constant *C = GetMethodDescriptionConstant(MD);
548 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
549 OptInstanceMethods.push_back(C);
550 } else {
551 InstanceMethods.push_back(C);
552 }
553 }
554
555 for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
556 e = PD->classmeth_end(); i != e; ++i) {
557 ObjCMethodDecl *MD = *i;
558 llvm::Constant *C = GetMethodDescriptionConstant(MD);
559 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
560 OptClassMethods.push_back(C);
561 } else {
562 ClassMethods.push_back(C);
563 }
564 }
565
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000566 std::vector<llvm::Constant*> Values(5);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000567 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000568 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000569 Values[2] =
570 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
571 PD->protocol_begin(),
572 PD->protocol_end());
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000573 Values[3] =
574 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_")
575 + PD->getName(),
576 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
577 InstanceMethods);
578 Values[4] =
579 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_")
580 + PD->getName(),
581 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
582 ClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000583 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
584 Values);
585
586 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
587 if (Entry) {
588 // Already created, just update the initializer
589 Entry->setInitializer(Init);
590 } else {
591 Entry =
592 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
593 llvm::GlobalValue::InternalLinkage,
594 Init,
595 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
596 &CGM.getModule());
597 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
598 UsedGlobals.push_back(Entry);
599 // FIXME: Is this necessary? Why only for protocol?
600 Entry->setAlignment(4);
601 }
602}
603
604llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
605 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
606
607 if (!Entry) {
608 std::vector<llvm::Constant*> Values(5);
609 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
610 Values[1] = GetClassName(PD->getIdentifier());
611 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
612 Values[3] = Values[4] =
613 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
614 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
615 Values);
616
617 Entry =
618 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
619 llvm::GlobalValue::InternalLinkage,
620 Init,
621 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
622 &CGM.getModule());
623 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
624 UsedGlobals.push_back(Entry);
625 // FIXME: Is this necessary? Why only for protocol?
626 Entry->setAlignment(4);
627 }
628
629 return Entry;
630}
631
632/*
633 struct _objc_protocol_extension {
634 uint32_t size;
635 struct objc_method_description_list *optional_instance_methods;
636 struct objc_method_description_list *optional_class_methods;
637 struct objc_property_list *instance_properties;
638 };
639*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000640llvm::Constant *
641CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
642 const ConstantVector &OptInstanceMethods,
643 const ConstantVector &OptClassMethods) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000644 uint64_t Size =
645 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
646 std::vector<llvm::Constant*> Values(4);
647 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000648 Values[1] =
649 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_")
650 + PD->getName(),
651 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
652 OptInstanceMethods);
653 Values[2] =
654 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_")
655 + PD->getName(),
656 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
657 OptClassMethods);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000658 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
659 PD->getName(),
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000660 0,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000661 PD->classprop_begin(),
662 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000663
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000664 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000665 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
666 Values[3]->isNullValue())
667 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
668
669 llvm::Constant *Init =
670 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
671 llvm::GlobalVariable *GV =
672 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
673 llvm::GlobalValue::InternalLinkage,
674 Init,
675 (std::string("\01L_OBJC_PROTOCOLEXT_") +
676 PD->getName()),
677 &CGM.getModule());
678 // No special section, but goes in llvm.used
679 UsedGlobals.push_back(GV);
680
681 return GV;
682}
683
684/*
685 struct objc_protocol_list {
686 struct objc_protocol_list *next;
687 long count;
688 Protocol *list[];
689 };
690*/
Daniel Dunbardbc933702008-08-21 21:57:41 +0000691llvm::Constant *
692CGObjCMac::EmitProtocolList(const std::string &Name,
693 ObjCProtocolDecl::protocol_iterator begin,
694 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000695 std::vector<llvm::Constant*> ProtocolRefs;
696
Daniel Dunbardbc933702008-08-21 21:57:41 +0000697 for (; begin != end; ++begin)
698 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000699
700 // Just return null for empty protocol lists
701 if (ProtocolRefs.empty())
702 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
703
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000704 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000705 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
706
707 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000708 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000709 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
710 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
711 Values[2] =
712 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
713 ProtocolRefs.size()),
714 ProtocolRefs);
715
716 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
717 llvm::GlobalVariable *GV =
718 new llvm::GlobalVariable(Init->getType(), false,
719 llvm::GlobalValue::InternalLinkage,
720 Init,
Daniel Dunbardbc933702008-08-21 21:57:41 +0000721 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000722 &CGM.getModule());
723 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
724 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
725}
726
727/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000728 struct _objc_property {
729 const char * const name;
730 const char * const attributes;
731 };
732
733 struct _objc_property_list {
734 uint32_t entsize; // sizeof (struct _objc_property)
735 uint32_t prop_count;
736 struct _objc_property[prop_count];
737 };
738*/
739llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000740 const Decl *Container,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000741 ObjCPropertyDecl * const *begin,
742 ObjCPropertyDecl * const *end) {
743 std::vector<llvm::Constant*> Properties, Prop(2);
744 for (; begin != end; ++begin) {
745 const ObjCPropertyDecl *PD = *begin;
746 Prop[0] = GetPropertyName(PD->getIdentifier());
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000747 Prop[1] = GetPropertyTypeString(PD, Container);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000748 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
749 Prop));
750 }
751
752 // Return null for empty list.
753 if (Properties.empty())
754 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
755
756 unsigned PropertySize =
757 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
758 std::vector<llvm::Constant*> Values(3);
759 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
760 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
761 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
762 Properties.size());
763 Values[2] = llvm::ConstantArray::get(AT, Properties);
764 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
765
766 llvm::GlobalVariable *GV =
767 new llvm::GlobalVariable(Init->getType(), false,
768 llvm::GlobalValue::InternalLinkage,
769 Init,
770 Name,
771 &CGM.getModule());
772 // No special section on property lists?
773 UsedGlobals.push_back(GV);
774 return llvm::ConstantExpr::getBitCast(GV,
775 ObjCTypes.PropertyListPtrTy);
776
777}
778
779/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000780 struct objc_method_description_list {
781 int count;
782 struct objc_method_description list[];
783 };
784*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000785llvm::Constant *
786CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
787 std::vector<llvm::Constant*> Desc(2);
788 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
789 ObjCTypes.SelectorPtrTy);
790 Desc[1] = GetMethodVarType(MD);
791 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
792 Desc);
793}
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000794
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000795llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name,
796 const char *Section,
797 const ConstantVector &Methods) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000798 // Return null for empty list.
799 if (Methods.empty())
800 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
801
802 std::vector<llvm::Constant*> Values(2);
803 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
804 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
805 Methods.size());
806 Values[1] = llvm::ConstantArray::get(AT, Methods);
807 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
808
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000809 llvm::GlobalVariable *GV =
810 new llvm::GlobalVariable(Init->getType(), false,
811 llvm::GlobalValue::InternalLinkage,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000812 Init, Name, &CGM.getModule());
813 GV->setSection(Section);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000814 UsedGlobals.push_back(GV);
815 return llvm::ConstantExpr::getBitCast(GV,
816 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000817}
818
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000819/*
820 struct _objc_category {
821 char *category_name;
822 char *class_name;
823 struct _objc_method_list *instance_methods;
824 struct _objc_method_list *class_methods;
825 struct _objc_protocol_list *protocols;
826 uint32_t size; // <rdar://4585769>
827 struct _objc_property_list *instance_properties;
828 };
829 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000830void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000831 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
832
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000833 // FIXME: This is poor design, the OCD should have a pointer to the
834 // category decl. Additionally, note that Category can be null for
835 // the @implementation w/o an @interface case. Sema should just
836 // create one for us as it does for @implementation so everyone else
837 // can live life under a clear blue sky.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000838 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000839 const ObjCCategoryDecl *Category =
840 Interface->FindCategoryDeclaration(OCD->getIdentifier());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000841 std::string ExtName(std::string(Interface->getName()) +
842 "_" +
843 OCD->getName());
844
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000845 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
846 for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
847 e = OCD->instmeth_end(); i != e; ++i) {
848 // Instance methods should always be defined.
849 InstanceMethods.push_back(GetMethodConstant(*i));
850 }
851 for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
852 e = OCD->classmeth_end(); i != e; ++i) {
853 // Class methods should always be defined.
854 ClassMethods.push_back(GetMethodConstant(*i));
855 }
856
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000857 std::vector<llvm::Constant*> Values(7);
858 Values[0] = GetClassName(OCD->getIdentifier());
859 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000860 Values[2] =
861 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
862 ExtName,
863 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000864 InstanceMethods);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000865 Values[3] =
866 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
867 "__OBJC,__cat_class_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000868 ClassMethods);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000869 if (Category) {
870 Values[4] =
871 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
872 Category->protocol_begin(),
873 Category->protocol_end());
874 } else {
875 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
876 }
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000877 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000878
879 // If there is no category @interface then there can be no properties.
880 if (Category) {
881 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000882 OCD,
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000883 Category->classprop_begin(),
884 Category->classprop_end());
885 } else {
886 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
887 }
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000888
889 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
890 Values);
891
892 llvm::GlobalVariable *GV =
893 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
894 llvm::GlobalValue::InternalLinkage,
895 Init,
896 std::string("\01L_OBJC_CATEGORY_")+ExtName,
897 &CGM.getModule());
898 GV->setSection("__OBJC,__category,regular,no_dead_strip");
899 UsedGlobals.push_back(GV);
900 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000901}
902
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000903// FIXME: Get from somewhere?
904enum ClassFlags {
905 eClassFlags_Factory = 0x00001,
906 eClassFlags_Meta = 0x00002,
907 // <rdr://5142207>
908 eClassFlags_HasCXXStructors = 0x02000,
909 eClassFlags_Hidden = 0x20000,
910 eClassFlags_ABI2_Hidden = 0x00010,
911 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
912};
913
914// <rdr://5142207&4705298&4843145>
915static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
916 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
917 // FIXME: Support -fvisibility
918 switch (attr->getVisibility()) {
919 default:
920 assert(0 && "Unknown visibility");
921 return false;
922 case VisibilityAttr::DefaultVisibility:
923 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
924 return false;
925 case VisibilityAttr::HiddenVisibility:
926 return true;
927 }
928 } else {
929 return false; // FIXME: Support -fvisibility
930 }
931}
932
933/*
934 struct _objc_class {
935 Class isa;
936 Class super_class;
937 const char *name;
938 long version;
939 long info;
940 long instance_size;
941 struct _objc_ivar_list *ivars;
942 struct _objc_method_list *methods;
943 struct _objc_cache *cache;
944 struct _objc_protocol_list *protocols;
945 // Objective-C 1.0 extensions (<rdr://4585769>)
946 const char *ivar_layout;
947 struct _objc_class_ext *ext;
948 };
949
950 See EmitClassExtension();
951 */
952void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000953 DefinedSymbols.insert(ID->getIdentifier());
954
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000955 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000956 // FIXME: Gross
957 ObjCInterfaceDecl *Interface =
958 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000959 llvm::Constant *Protocols =
960 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
961 Interface->protocol_begin(),
962 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000963 const llvm::Type *InterfaceTy =
964 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
965 unsigned Flags = eClassFlags_Factory;
966 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
967
968 // FIXME: Set CXX-structors flag.
969 if (IsClassHidden(ID->getClassInterface()))
970 Flags |= eClassFlags_Hidden;
971
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000972 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
973 for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
974 e = ID->instmeth_end(); i != e; ++i) {
975 // Instance methods should always be defined.
976 InstanceMethods.push_back(GetMethodConstant(*i));
977 }
978 for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
979 e = ID->classmeth_end(); i != e; ++i) {
980 // Class methods should always be defined.
981 ClassMethods.push_back(GetMethodConstant(*i));
982 }
983
984 for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
985 e = ID->propimpl_end(); i != e; ++i) {
986 ObjCPropertyImplDecl *PID = *i;
987
988 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
989 ObjCPropertyDecl *PD = PID->getPropertyDecl();
990
991 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
992 if (llvm::Constant *C = GetMethodConstant(MD))
993 InstanceMethods.push_back(C);
994 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
995 if (llvm::Constant *C = GetMethodConstant(MD))
996 InstanceMethods.push_back(C);
997 }
998 }
999
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001000 std::vector<llvm::Constant*> Values(12);
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001001 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001002 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001003 // Record a reference to the super class.
1004 LazySymbols.insert(Super->getIdentifier());
1005
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001006 Values[ 1] =
1007 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1008 ObjCTypes.ClassPtrTy);
1009 } else {
1010 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1011 }
1012 Values[ 2] = GetClassName(ID->getIdentifier());
1013 // Version is always 0.
1014 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1015 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1016 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1017 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001018 Values[ 7] =
1019 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
1020 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001021 InstanceMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001022 // cache is always NULL.
1023 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1024 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001025 // FIXME: Set ivar_layout
1026 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001027 Values[11] = EmitClassExtension(ID);
1028 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1029 Values);
1030
1031 llvm::GlobalVariable *GV =
1032 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1033 llvm::GlobalValue::InternalLinkage,
1034 Init,
1035 std::string("\01L_OBJC_CLASS_")+ClassName,
1036 &CGM.getModule());
1037 GV->setSection("__OBJC,__class,regular,no_dead_strip");
1038 UsedGlobals.push_back(GV);
1039 // FIXME: Why?
1040 GV->setAlignment(32);
1041 DefinedClasses.push_back(GV);
1042}
1043
1044llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
1045 llvm::Constant *Protocols,
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001046 const llvm::Type *InterfaceTy,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001047 const ConstantVector &Methods) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001048 const char *ClassName = ID->getName();
1049 unsigned Flags = eClassFlags_Meta;
1050 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
1051
1052 if (IsClassHidden(ID->getClassInterface()))
1053 Flags |= eClassFlags_Hidden;
1054
1055 std::vector<llvm::Constant*> Values(12);
1056 // The isa for the metaclass is the root of the hierarchy.
1057 const ObjCInterfaceDecl *Root = ID->getClassInterface();
1058 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
1059 Root = Super;
1060 Values[ 0] =
1061 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
1062 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001063 // The super class for the metaclass is emitted as the name of the
1064 // super class. The runtime fixes this up to point to the
1065 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001066 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
1067 Values[ 1] =
1068 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1069 ObjCTypes.ClassPtrTy);
1070 } else {
1071 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1072 }
1073 Values[ 2] = GetClassName(ID->getIdentifier());
1074 // Version is always 0.
1075 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1076 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1077 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1078 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001079 Values[ 7] =
1080 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
1081 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001082 Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001083 // cache is always NULL.
1084 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1085 Values[ 9] = Protocols;
1086 // ivar_layout for metaclass is always NULL.
1087 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1088 // The class extension is always unused for metaclasses.
1089 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1090 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1091 Values);
1092
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001093 std::string Name("\01L_OBJC_METACLASS_");
1094 Name += ClassName;
1095
1096 // Check for a forward reference.
1097 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
1098 if (GV) {
1099 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1100 "Forward metaclass reference has incorrect type.");
1101 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
1102 GV->setInitializer(Init);
1103 } else {
1104 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1105 llvm::GlobalValue::InternalLinkage,
1106 Init, Name,
1107 &CGM.getModule());
1108 }
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001109 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
1110 UsedGlobals.push_back(GV);
1111 // FIXME: Why?
1112 GV->setAlignment(32);
1113
1114 return GV;
1115}
1116
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001117llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
1118 std::string Name("\01L_OBJC_METACLASS_");
1119 Name += ID->getName();
1120
1121 // FIXME: Should we look these up somewhere other than the
1122 // module. Its a bit silly since we only generate these while
1123 // processing an implementation, so exactly one pointer would work
1124 // if know when we entered/exitted an implementation block.
1125
1126 // Check for an existing forward reference.
1127 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) {
1128 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1129 "Forward metaclass reference has incorrect type.");
1130 return GV;
1131 } else {
1132 // Generate as an external reference to keep a consistent
1133 // module. This will be patched up when we emit the metaclass.
1134 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1135 llvm::GlobalValue::ExternalLinkage,
1136 0,
1137 Name,
1138 &CGM.getModule());
1139 }
1140}
1141
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001142/*
1143 struct objc_class_ext {
1144 uint32_t size;
1145 const char *weak_ivar_layout;
1146 struct _objc_property_list *properties;
1147 };
1148*/
1149llvm::Constant *
1150CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1151 uint64_t Size =
1152 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1153
1154 std::vector<llvm::Constant*> Values(3);
1155 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001156 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001157 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001158 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1159 ID->getName(),
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001160 ID,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001161 ID->getClassInterface()->classprop_begin(),
1162 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001163
1164 // Return null if no extension bits are used.
1165 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1166 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1167
1168 llvm::Constant *Init =
1169 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1170 llvm::GlobalVariable *GV =
1171 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1172 llvm::GlobalValue::InternalLinkage,
1173 Init,
1174 (std::string("\01L_OBJC_CLASSEXT_") +
1175 ID->getName()),
1176 &CGM.getModule());
1177 // No special section, but goes in llvm.used
1178 UsedGlobals.push_back(GV);
1179
1180 return GV;
1181}
1182
1183/*
1184 struct objc_ivar {
1185 char *ivar_name;
1186 char *ivar_type;
1187 int ivar_offset;
1188 };
1189
1190 struct objc_ivar_list {
1191 int ivar_count;
1192 struct objc_ivar list[count];
1193 };
1194 */
1195llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1196 bool ForClass,
1197 const llvm::Type *InterfaceTy) {
1198 std::vector<llvm::Constant*> Ivars, Ivar(3);
1199
1200 // When emitting the root class GCC emits ivar entries for the
1201 // actual class structure. It is not clear if we need to follow this
1202 // behavior; for now lets try and get away with not doing it. If so,
1203 // the cleanest solution would be to make up an ObjCInterfaceDecl
1204 // for the class.
1205 if (ForClass)
1206 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1207
1208 const llvm::StructLayout *Layout =
1209 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1210 for (ObjCInterfaceDecl::ivar_iterator
1211 i = ID->getClassInterface()->ivar_begin(),
1212 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1213 ObjCIvarDecl *V = *i;
1214 unsigned Offset =
1215 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1216 std::string TypeStr;
1217 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1218 Ivar[0] = GetMethodVarName(V->getIdentifier());
1219 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1220 EncodingRecordTypes);
1221 Ivar[1] = GetMethodVarType(TypeStr);
1222 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1223 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1224 Ivar));
1225 }
1226
1227 // Return null for empty list.
1228 if (Ivars.empty())
1229 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1230
1231 std::vector<llvm::Constant*> Values(2);
1232 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1233 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1234 Ivars.size());
1235 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1236 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1237
1238 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1239 "\01L_OBJC_INSTANCE_VARIABLES_");
1240 llvm::GlobalVariable *GV =
1241 new llvm::GlobalVariable(Init->getType(), false,
1242 llvm::GlobalValue::InternalLinkage,
1243 Init,
1244 std::string(Prefix) + ID->getName(),
1245 &CGM.getModule());
1246 if (ForClass) {
1247 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1248 // FIXME: Why is this only here?
1249 GV->setAlignment(32);
1250 } else {
1251 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1252 }
1253 UsedGlobals.push_back(GV);
1254 return llvm::ConstantExpr::getBitCast(GV,
1255 ObjCTypes.IvarListPtrTy);
1256}
1257
1258/*
1259 struct objc_method {
1260 SEL method_name;
1261 char *method_types;
1262 void *method;
1263 };
1264
1265 struct objc_method_list {
1266 struct objc_method_list *obsolete;
1267 int count;
1268 struct objc_method methods_list[count];
1269 };
1270*/
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001271
1272/// GetMethodConstant - Return a struct objc_method constant for the
1273/// given method if it has been defined. The result is null if the
1274/// method has not been defined. The return value has type MethodPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001275llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001276 // FIXME: Use DenseMap::lookup
1277 llvm::Function *Fn = MethodDefinitions[MD];
1278 if (!Fn)
1279 return 0;
1280
1281 std::vector<llvm::Constant*> Method(3);
1282 Method[0] =
1283 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1284 ObjCTypes.SelectorPtrTy);
1285 Method[1] = GetMethodVarType(MD);
1286 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
1287 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
1288}
1289
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001290llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1291 const char *Section,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001292 const ConstantVector &Methods) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001293 // Return null for empty list.
1294 if (Methods.empty())
1295 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1296
1297 std::vector<llvm::Constant*> Values(3);
1298 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1299 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1300 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1301 Methods.size());
1302 Values[2] = llvm::ConstantArray::get(AT, Methods);
1303 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1304
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001305 llvm::GlobalVariable *GV =
1306 new llvm::GlobalVariable(Init->getType(), false,
1307 llvm::GlobalValue::InternalLinkage,
1308 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001309 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001310 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001311 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001312 UsedGlobals.push_back(GV);
1313 return llvm::ConstantExpr::getBitCast(GV,
1314 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001315}
1316
1317llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1318 const llvm::Type *ReturnTy =
1319 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1320 const llvm::Type *SelfTy =
1321 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1322
1323 std::vector<const llvm::Type*> ArgTys;
1324 ArgTys.reserve(1 + 2 + OMD->param_size());
1325
1326 // FIXME: This is not something we should have to be dealing with
1327 // here.
1328 bool useStructRet =
1329 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1330 if (useStructRet) {
1331 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1332 ReturnTy = llvm::Type::VoidTy;
1333 }
1334
1335 // Implicit arguments
1336 ArgTys.push_back(SelfTy);
1337 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1338
1339 for (ObjCMethodDecl::param_const_iterator
1340 i = OMD->param_begin(), e = OMD->param_end();
1341 i != e; ++i) {
1342 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001343 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001344 ArgTys.push_back(Ty);
1345 } else {
1346 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1347 }
1348 }
1349
1350 std::string Name;
1351 GetNameForMethod(OMD, Name);
1352
1353 llvm::Function *Method =
1354 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1355 ArgTys,
1356 OMD->isVariadic()),
1357 llvm::GlobalValue::InternalLinkage,
1358 Name,
1359 &CGM.getModule());
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001360 MethodDefinitions.insert(std::make_pair(OMD, Method));
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001361
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001362 unsigned Offset = 3; // Return plus self and selector implicit args.
1363 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001364 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001365 ++Offset;
1366 }
1367
1368 // FIXME: This is horrible, we need to be reusing the machinery in
1369 // CodeGenModule.cpp (SetFunctionAttributes).
1370 for (ObjCMethodDecl::param_const_iterator
1371 i = OMD->param_begin(), e = OMD->param_end();
1372 i != e; ++i, ++Offset) {
1373 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1374 if (!Ty->isSingleValueType())
1375 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1376 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001377
1378 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001379}
1380
1381llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001382 // Abuse this interface function as a place to finalize.
1383 FinishModule();
1384
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001385 return NULL;
1386}
1387
Anders Carlsson2abd89c2008-08-31 04:05:03 +00001388llvm::Function *CGObjCMac::EnumerationMutationFunction()
1389{
1390 return ObjCTypes.EnumerationMutationFn;
1391}
1392
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001393/* *** Private Interface *** */
1394
1395/// EmitImageInfo - Emit the image info marker used to encode some module
1396/// level information.
1397///
1398/// See: <rdr://4810609&4810587&4810587>
1399/// struct IMAGE_INFO {
1400/// unsigned version;
1401/// unsigned flags;
1402/// };
1403enum ImageInfoFlags {
1404 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1405 eImageInfo_GarbageCollected = (1 << 1),
1406 eImageInfo_GCOnly = (1 << 2)
1407};
1408
1409void CGObjCMac::EmitImageInfo() {
1410 unsigned version = 0; // Version is unused?
1411 unsigned flags = 0;
1412
1413 // FIXME: Fix and continue?
1414 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1415 flags |= eImageInfo_GarbageCollected;
1416 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1417 flags |= eImageInfo_GCOnly;
1418
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001419 // Emitted as int[2];
1420 llvm::Constant *values[2] = {
1421 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1422 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1423 };
1424 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001425 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001426 new llvm::GlobalVariable(AT, true,
1427 llvm::GlobalValue::InternalLinkage,
1428 llvm::ConstantArray::get(AT, values, 2),
1429 "\01L_OBJC_IMAGE_INFO",
1430 &CGM.getModule());
1431
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001432 if (ObjCABI == 1) {
1433 GV->setSection("__OBJC, __image_info,regular");
1434 } else {
1435 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1436 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001437
1438 UsedGlobals.push_back(GV);
1439}
1440
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001441
1442// struct objc_module {
1443// unsigned long version;
1444// unsigned long size;
1445// const char *name;
1446// Symtab symtab;
1447// };
1448
1449// FIXME: Get from somewhere
1450static const int ModuleVersion = 7;
1451
1452void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001453 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1454
1455 std::vector<llvm::Constant*> Values(4);
1456 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1457 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001458 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001459 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001460 Values[3] = EmitModuleSymbols();
1461
1462 llvm::GlobalVariable *GV =
1463 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1464 llvm::GlobalValue::InternalLinkage,
1465 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1466 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001467 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001468 &CGM.getModule());
1469 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1470 UsedGlobals.push_back(GV);
1471}
1472
1473llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001474 unsigned NumClasses = DefinedClasses.size();
1475 unsigned NumCategories = DefinedCategories.size();
1476
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001477 // Return null if no symbols were defined.
1478 if (!NumClasses && !NumCategories)
1479 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
1480
1481 std::vector<llvm::Constant*> Values(5);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001482 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1483 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1484 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1485 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1486
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001487 // The runtime expects exactly the list of defined classes followed
1488 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001489 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001490 for (unsigned i=0; i<NumClasses; i++)
1491 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1492 ObjCTypes.Int8PtrTy);
1493 for (unsigned i=0; i<NumCategories; i++)
1494 Symbols[NumClasses + i] =
1495 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1496 ObjCTypes.Int8PtrTy);
1497
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001498 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001499 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001500 NumClasses + NumCategories),
1501 Symbols);
1502
1503 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1504
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001505 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001506 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001507 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001508 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001509 "\01L_OBJC_SYMBOLS",
1510 &CGM.getModule());
1511 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1512 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001513 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1514}
1515
1516llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1517 const ObjCInterfaceDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001518 LazySymbols.insert(ID->getIdentifier());
1519
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001520 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1521
1522 if (!Entry) {
1523 llvm::Constant *Casted =
1524 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1525 ObjCTypes.ClassPtrTy);
1526 Entry =
1527 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1528 llvm::GlobalValue::InternalLinkage,
1529 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1530 &CGM.getModule());
1531 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1532 UsedGlobals.push_back(Entry);
1533 }
1534
1535 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001536}
1537
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001538llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1539 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1540
1541 if (!Entry) {
1542 llvm::Constant *Casted =
1543 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1544 ObjCTypes.SelectorPtrTy);
1545 Entry =
1546 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1547 llvm::GlobalValue::InternalLinkage,
1548 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1549 &CGM.getModule());
1550 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1551 UsedGlobals.push_back(Entry);
1552 }
1553
1554 return Builder.CreateLoad(Entry, false, "tmp");
1555}
1556
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001557llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1558 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001559
1560 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001561 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001562 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001563 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001564 llvm::GlobalValue::InternalLinkage,
1565 C, "\01L_OBJC_CLASS_NAME_",
1566 &CGM.getModule());
1567 Entry->setSection("__TEXT,__cstring,cstring_literals");
1568 UsedGlobals.push_back(Entry);
1569 }
1570
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001571 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001572}
1573
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001574llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1575 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1576
1577 if (!Entry) {
1578 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1579 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001580 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001581 llvm::GlobalValue::InternalLinkage,
1582 C, "\01L_OBJC_METH_VAR_NAME_",
1583 &CGM.getModule());
1584 Entry->setSection("__TEXT,__cstring,cstring_literals");
1585 UsedGlobals.push_back(Entry);
1586 }
1587
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001588 return getConstantGEP(Entry, 0, 0);
1589}
1590
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001591// FIXME: Merge into a single cstring creation function.
1592llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1593 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1594}
1595
1596// FIXME: Merge into a single cstring creation function.
1597llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1598 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1599}
1600
1601llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1602 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001603
1604 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001605 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001606 Entry =
1607 new llvm::GlobalVariable(C->getType(), false,
1608 llvm::GlobalValue::InternalLinkage,
1609 C, "\01L_OBJC_METH_VAR_TYPE_",
1610 &CGM.getModule());
1611 Entry->setSection("__TEXT,__cstring,cstring_literals");
1612 UsedGlobals.push_back(Entry);
1613 }
1614
1615 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001616}
1617
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001618// FIXME: Merge into a single cstring creation function.
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001619llvm::Constant *CGObjCMac::GetMethodVarType(const ObjCMethodDecl *D) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001620 std::string TypeStr;
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001621 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
1622 TypeStr);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001623 return GetMethodVarType(TypeStr);
1624}
1625
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001626// FIXME: Merge into a single cstring creation function.
1627llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1628 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1629
1630 if (!Entry) {
1631 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1632 Entry =
1633 new llvm::GlobalVariable(C->getType(), false,
1634 llvm::GlobalValue::InternalLinkage,
1635 C, "\01L_OBJC_PROP_NAME_ATTR_",
1636 &CGM.getModule());
1637 Entry->setSection("__TEXT,__cstring,cstring_literals");
1638 UsedGlobals.push_back(Entry);
1639 }
1640
1641 return getConstantGEP(Entry, 0, 0);
1642}
1643
1644// FIXME: Merge into a single cstring creation function.
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001645// FIXME: This Decl should be more precise.
1646llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
1647 const Decl *Container) {
1648 std::string TypeStr;
1649 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001650 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1651}
1652
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001653void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1654 std::string &NameOut) {
1655 // FIXME: Find the mangling GCC uses.
1656 std::stringstream s;
1657 s << (D->isInstance() ? "-" : "+");
1658 s << "[";
1659 s << D->getClassInterface()->getName();
1660 s << " ";
1661 s << D->getSelector().getName();
1662 s << "]";
1663 NameOut = s.str();
1664}
1665
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001666void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001667 EmitModuleInfo();
1668
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001669 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001670
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001671 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001672 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001673 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001674 }
1675
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001676 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001677 llvm::GlobalValue *GV =
1678 new llvm::GlobalVariable(AT, false,
1679 llvm::GlobalValue::AppendingLinkage,
1680 llvm::ConstantArray::get(AT, Used),
1681 "llvm.used",
1682 &CGM.getModule());
1683
1684 GV->setSection("llvm.metadata");
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001685
1686 // Add assembler directives to add lazy undefined symbol references
1687 // for classes which are referenced but not defined. This is
1688 // important for correct linker interaction.
1689
1690 // FIXME: Uh, this isn't particularly portable.
1691 std::stringstream s;
1692 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
1693 e = LazySymbols.end(); i != e; ++i) {
1694 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
1695 }
1696 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
1697 e = DefinedSymbols.end(); i != e; ++i) {
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001698 s << "\t.objc_class_name_" << (*i)->getName() << "=0\n"
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001699 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
1700 }
1701 CGM.getModule().appendModuleInlineAsm(s.str());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001702}
1703
1704/* *** */
1705
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001706ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbar3e9df992008-08-23 18:37:06 +00001707 : CGM(cgm)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001708{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001709 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1710 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001711
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001712 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001713 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001714 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001715 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1716
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001717 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1718 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001719
1720 // FIXME: It would be nice to unify this with the opaque type, so
1721 // that the IR comes out a bit cleaner.
1722 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1723 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001724
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001725 MethodDescriptionTy =
1726 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001727 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001728 NULL);
1729 CGM.getModule().addTypeName("struct._objc_method_description",
1730 MethodDescriptionTy);
1731
1732 MethodDescriptionListTy =
1733 llvm::StructType::get(IntTy,
1734 llvm::ArrayType::get(MethodDescriptionTy, 0),
1735 NULL);
1736 CGM.getModule().addTypeName("struct._objc_method_description_list",
1737 MethodDescriptionListTy);
1738 MethodDescriptionListPtrTy =
1739 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1740
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001741 PropertyTy = llvm::StructType::get(Int8PtrTy,
1742 Int8PtrTy,
1743 NULL);
1744 CGM.getModule().addTypeName("struct._objc_property",
1745 PropertyTy);
1746
1747 PropertyListTy = llvm::StructType::get(IntTy,
1748 IntTy,
1749 llvm::ArrayType::get(PropertyTy, 0),
1750 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001751 CGM.getModule().addTypeName("struct._objc_property_list",
1752 PropertyListTy);
1753 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1754
1755 // Protocol description structures
1756
1757 ProtocolExtensionTy =
1758 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1759 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1760 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1761 PropertyListPtrTy,
1762 NULL);
1763 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1764 ProtocolExtensionTy);
1765 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1766
1767 // Handle recursive construction of Protocl and ProtocolList types
1768
1769 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1770 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1771
1772 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1773 LongTy,
1774 llvm::ArrayType::get(ProtocolTyHolder, 0),
1775 NULL);
1776 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1777
1778 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001779 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001780 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1781 MethodDescriptionListPtrTy,
1782 MethodDescriptionListPtrTy,
1783 NULL);
1784 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1785
1786 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1787 CGM.getModule().addTypeName("struct._objc_protocol_list",
1788 ProtocolListTy);
1789 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1790
1791 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1792 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1793 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001794
1795 // Class description structures
1796
1797 IvarTy = llvm::StructType::get(Int8PtrTy,
1798 Int8PtrTy,
1799 IntTy,
1800 NULL);
1801 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1802
1803 IvarListTy = llvm::OpaqueType::get();
1804 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1805 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1806
1807 MethodTy = llvm::StructType::get(SelectorPtrTy,
1808 Int8PtrTy,
1809 Int8PtrTy,
1810 NULL);
1811 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1812
1813 MethodListTy = llvm::OpaqueType::get();
1814 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1815 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1816
1817 CacheTy = llvm::OpaqueType::get();
1818 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1819 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1820
1821 ClassExtensionTy =
1822 llvm::StructType::get(IntTy,
1823 Int8PtrTy,
1824 PropertyListPtrTy,
1825 NULL);
1826 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1827 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1828
1829 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1830
1831 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1832 llvm::PointerType::getUnqual(ClassTyHolder),
1833 Int8PtrTy,
1834 LongTy,
1835 LongTy,
1836 LongTy,
1837 IvarListPtrTy,
1838 MethodListPtrTy,
1839 CachePtrTy,
1840 ProtocolListPtrTy,
1841 Int8PtrTy,
1842 ClassExtensionPtrTy,
1843 NULL);
1844 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1845
1846 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1847 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1848 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1849
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001850 CategoryTy = llvm::StructType::get(Int8PtrTy,
1851 Int8PtrTy,
1852 MethodListPtrTy,
1853 MethodListPtrTy,
1854 ProtocolListPtrTy,
1855 IntTy,
1856 PropertyListPtrTy,
1857 NULL);
1858 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1859
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00001860 // I'm not sure I like this. The implicit coordination is a bit
1861 // gross. We should solve this in a reasonable fashion because this
1862 // is a pretty common task (match some runtime data structure with
1863 // an LLVM data structure).
1864
1865 // FIXME: This is leaked.
1866 // FIXME: Merge with rewriter code?
1867 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
1868 SourceLocation(),
1869 &Ctx.Idents.get("_objc_super"), 0);
1870 FieldDecl *FieldDecls[2];
1871 FieldDecls[0] = FieldDecl::Create(Ctx, SourceLocation(), 0,
1872 Ctx.getObjCIdType());
1873 FieldDecls[1] = FieldDecl::Create(Ctx, SourceLocation(), 0,
1874 Ctx.getObjCClassType());
1875 RD->defineBody(FieldDecls, 2);
1876
1877 SuperCTy = Ctx.getTagDeclType(RD);
1878 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
1879
1880 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001881 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001882
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001883 // Global metadata structures
1884
1885 SymtabTy = llvm::StructType::get(LongTy,
1886 SelectorPtrTy,
1887 ShortTy,
1888 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001889 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001890 NULL);
1891 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1892 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1893
1894 ModuleTy =
1895 llvm::StructType::get(LongTy,
1896 LongTy,
1897 Int8PtrTy,
1898 SymtabPtrTy,
1899 NULL);
1900 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001901
1902 // Message send functions
1903
1904 std::vector<const llvm::Type*> Params;
1905 Params.push_back(ObjectPtrTy);
1906 Params.push_back(SelectorPtrTy);
1907 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1908 Params,
1909 true),
1910 llvm::Function::ExternalLinkage,
1911 "objc_msgSend",
1912 &CGM.getModule());
1913
1914 Params.clear();
1915 Params.push_back(Int8PtrTy);
1916 Params.push_back(ObjectPtrTy);
1917 Params.push_back(SelectorPtrTy);
1918 MessageSendStretFn =
1919 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1920 Params,
1921 true),
1922 llvm::Function::ExternalLinkage,
1923 "objc_msgSend_stret",
1924 &CGM.getModule());
1925
1926 Params.clear();
1927 Params.push_back(SuperPtrTy);
1928 Params.push_back(SelectorPtrTy);
1929 MessageSendSuperFn =
1930 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1931 Params,
1932 true),
1933 llvm::Function::ExternalLinkage,
1934 "objc_msgSendSuper",
1935 &CGM.getModule());
1936
1937 Params.clear();
1938 Params.push_back(Int8PtrTy);
1939 Params.push_back(SuperPtrTy);
1940 Params.push_back(SelectorPtrTy);
1941 MessageSendSuperStretFn =
1942 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1943 Params,
1944 true),
1945 llvm::Function::ExternalLinkage,
1946 "objc_msgSendSuper_stret",
1947 &CGM.getModule());
Anders Carlsson2abd89c2008-08-31 04:05:03 +00001948
1949 // Enumeration mutation.
1950
1951 Params.clear();
1952 Params.push_back(ObjectPtrTy);
1953 EnumerationMutationFn =
1954 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1955 Params,
1956 false),
1957 llvm::Function::ExternalLinkage,
1958 "objc_enumerationMutation",
1959 &CGM.getModule());
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001960}
1961
1962ObjCTypesHelper::~ObjCTypesHelper() {
1963}
1964
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001965llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
1966 const llvm::Type *ReturnTy) {
1967 llvm::Function *F;
1968 llvm::FunctionType *CallFTy;
1969
1970 // FIXME: Should we be caching any of this?
1971 if (!ReturnTy->isSingleValueType()) {
1972 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
1973 std::vector<const llvm::Type*> Params(3);
1974 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
1975 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1976 Params[2] = SelectorPtrTy;
1977 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
Daniel Dunbar662174c82008-08-29 17:28:43 +00001978 } else { // FIXME: floating point?
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001979 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
1980 std::vector<const llvm::Type*> Params(2);
1981 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1982 Params[1] = SelectorPtrTy;
1983 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001984 }
1985
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001986 return llvm::ConstantExpr::getBitCast(F,
1987 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001988}
1989
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001990/* *** */
1991
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001992CodeGen::CGObjCRuntime *
1993CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001994 return new CGObjCMac(CGM);
1995}