blob: d63004f2121843dc8cfb9b6ac223b8e41b8d470e [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;
Daniel Dunbar46f45b92008-09-09 01:06:48 +000029using namespace CodeGen;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000030
31namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000032
Daniel Dunbarae226fa2008-08-27 02:31:56 +000033 typedef std::vector<llvm::Constant*> ConstantVector;
34
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000035 // FIXME: We should find a nicer way to make the labels for
36 // metadata, string concatenation is lame.
37
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000038/// ObjCTypesHelper - Helper class that encapsulates lazy
39/// construction of varies types used during ObjC generation.
40class ObjCTypesHelper {
41private:
42 CodeGen::CodeGenModule &CGM;
43
Daniel Dunbar14c80b72008-08-23 09:25:55 +000044 llvm::Function *MessageSendFn, *MessageSendStretFn;
45 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000046
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000047public:
Daniel Dunbar27f9d772008-08-21 04:36:09 +000048 const llvm::Type *ShortTy, *IntTy, *LongTy;
49 const llvm::Type *Int8PtrTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000050
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000051 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
52 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000053 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000054 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000055 /// ProtocolPtrTy - LLVM type for external protocol handles
56 /// (typeof(Protocol))
57 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000058
Daniel Dunbar19cd87e2008-08-30 03:02:31 +000059 // SuperCTy - clang type for struct objc_super.
60 QualType SuperCTy;
61 // SuperPtrCTy - clang type for struct objc_super *.
62 QualType SuperPtrCTy;
63
Daniel Dunbare8b470d2008-08-23 04:28:29 +000064 /// SuperTy - LLVM type for struct objc_super.
65 const llvm::StructType *SuperTy;
Daniel Dunbar14c80b72008-08-23 09:25:55 +000066 /// SuperPtrTy - LLVM type for struct objc_super *.
67 const llvm::Type *SuperPtrTy;
Daniel Dunbare8b470d2008-08-23 04:28:29 +000068
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000069 /// SymtabTy - LLVM type for struct objc_symtab.
70 const llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000071 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
72 const llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000073 /// ModuleTy - LLVM type for struct objc_module.
74 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000075
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000076 /// ProtocolTy - LLVM type for struct objc_protocol.
77 const llvm::StructType *ProtocolTy;
78 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
79 const llvm::Type *ProtocolPtrTy;
80 /// ProtocolExtensionTy - LLVM type for struct
81 /// objc_protocol_extension.
82 const llvm::StructType *ProtocolExtensionTy;
83 /// ProtocolExtensionTy - LLVM type for struct
84 /// objc_protocol_extension *.
85 const llvm::Type *ProtocolExtensionPtrTy;
86 /// MethodDescriptionTy - LLVM type for struct
87 /// objc_method_description.
88 const llvm::StructType *MethodDescriptionTy;
89 /// MethodDescriptionListTy - LLVM type for struct
90 /// objc_method_description_list.
91 const llvm::StructType *MethodDescriptionListTy;
92 /// MethodDescriptionListPtrTy - LLVM type for struct
93 /// objc_method_description_list *.
94 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbarc8ef5512008-08-23 00:19:03 +000095 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
96 /// in GCC parlance).
97 const llvm::StructType *PropertyTy;
98 /// PropertyListTy - LLVM type for struct objc_property_list
99 /// (_prop_list_t in GCC parlance).
100 const llvm::StructType *PropertyListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000101 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
102 const llvm::Type *PropertyListPtrTy;
103 /// ProtocolListTy - LLVM type for struct objc_property_list.
104 const llvm::Type *ProtocolListTy;
105 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
106 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000107 /// CategoryTy - LLVM type for struct objc_category.
108 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000109 /// ClassTy - LLVM type for struct objc_class.
110 const llvm::StructType *ClassTy;
111 /// ClassPtrTy - LLVM type for struct objc_class *.
112 const llvm::Type *ClassPtrTy;
113 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
114 const llvm::StructType *ClassExtensionTy;
115 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
116 const llvm::Type *ClassExtensionPtrTy;
117 /// CacheTy - LLVM type for struct objc_cache.
118 const llvm::Type *CacheTy;
119 /// CachePtrTy - LLVM type for struct objc_cache *.
120 const llvm::Type *CachePtrTy;
121 // IvarTy - LLVM type for struct objc_ivar.
122 const llvm::StructType *IvarTy;
123 /// IvarListTy - LLVM type for struct objc_ivar_list.
124 const llvm::Type *IvarListTy;
125 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
126 const llvm::Type *IvarListPtrTy;
127 // MethodTy - LLVM type for struct objc_method.
128 const llvm::StructType *MethodTy;
129 /// MethodListTy - LLVM type for struct objc_method_list.
130 const llvm::Type *MethodListTy;
131 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
132 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000133
Anders Carlsson2abd89c2008-08-31 04:05:03 +0000134 llvm::Function *EnumerationMutationFn;
Anders Carlsson124526b2008-09-09 10:10:21 +0000135
136 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
137 const llvm::Type *ExceptionDataTy;
138
139 /// ExceptionThrowFn - LLVM objc_exception_throw function.
140 llvm::Function *ExceptionThrowFn;
141
142 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
143 llvm::Function *ExceptionTryEnterFn;
144
145 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
146 llvm::Function *ExceptionTryExitFn;
147
148 /// ExceptionExtractFn - LLVM objc_exception_extract function.
149 llvm::Function *ExceptionExtractFn;
150
151 /// ExceptionMatchFn - LLVM objc_exception_match function.
152 llvm::Function *ExceptionMatchFn;
153
154 /// SetJmpFn - LLVM _setjmp function.
155 llvm::Function *SetJmpFn;
156
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000157public:
158 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
159 ~ObjCTypesHelper();
160
Daniel Dunbar3913f182008-09-09 23:48:28 +0000161 llvm::Value *getMessageSendFn(bool IsSuper, bool isStret,
162 const llvm::Type *ReturnTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000163};
164
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000165class CGObjCMac : public CodeGen::CGObjCRuntime {
166private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000167 CodeGen::CodeGenModule &CGM;
168 ObjCTypesHelper ObjCTypes;
169 /// ObjCABI - FIXME: Not sure yet.
170 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000171
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000172 /// LazySymbols - Symbols to generate a lazy reference for. See
173 /// DefinedSymbols and FinishModule().
174 std::set<IdentifierInfo*> LazySymbols;
175
176 /// DefinedSymbols - External symbols which are defined by this
177 /// module. The symbols in this list and LazySymbols are used to add
178 /// special linker symbols which ensure that Objective-C modules are
179 /// linked properly.
180 std::set<IdentifierInfo*> DefinedSymbols;
181
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000182 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000183 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000184
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000185 /// MethodVarNames - uniqued method variable names.
186 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
187
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000188 /// MethodVarTypes - uniqued method type signatures. We have to use
189 /// a StringMap here because have no other unique reference.
190 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
191
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000192 /// MethodDefinitions - map of methods which have been defined in
193 /// this translation unit.
194 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
195
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000196 /// PropertyNames - uniqued method variable names.
197 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
198
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000199 /// ClassReferences - uniqued class references.
200 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
201
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000202 /// SelectorReferences - uniqued selector references.
203 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
204
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000205 /// Protocols - Protocols for which an objc_protocol structure has
206 /// been emitted. Forward declarations are handled by creating an
207 /// empty structure whose initializer is filled in when/if defined.
208 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
209
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000210 /// DefinedClasses - List of defined classes.
211 std::vector<llvm::GlobalValue*> DefinedClasses;
212
213 /// DefinedCategories - List of defined categories.
214 std::vector<llvm::GlobalValue*> DefinedCategories;
215
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000216 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000217 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000218 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000219
220 /// EmitImageInfo - Emit the image info marker used to encode some module
221 /// level information.
222 void EmitImageInfo();
223
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000224 /// EmitModuleInfo - Another marker encoding module level
225 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000226 void EmitModuleInfo();
227
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000228 /// EmitModuleSymols - Emit module symbols, the list of defined
229 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000230 llvm::Constant *EmitModuleSymbols();
231
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000232 /// FinishModule - Write out global data structures at the end of
233 /// processing a translation unit.
234 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000235
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000236 /// EmitClassExtension - Generate the class extension structure used
237 /// to store the weak ivar layout and properties. The return value
238 /// has type ClassExtensionPtrTy.
239 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
240
241 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
242 /// for the given class.
243 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
244 const ObjCInterfaceDecl *ID);
245
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000246 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000247 QualType ResultType,
248 Selector Sel,
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000249 llvm::Value *Arg0,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000250 QualType Arg0Ty,
251 bool IsSuper,
252 const CallArgList &CallArgs);
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000253
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000254 /// EmitIvarList - Emit the ivar list for the given
255 /// implementation. If ForClass is true the list of class ivars
256 /// (i.e. metaclass ivars) is emitted, otherwise the list of
257 /// interface ivars will be emitted. The return value has type
258 /// IvarListPtrTy.
259 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
260 bool ForClass,
261 const llvm::Type *InterfaceTy);
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000262
263 /// EmitMetaClass - Emit a forward reference to the class structure
264 /// for the metaclass of the given interface. The return value has
265 /// type ClassPtrTy.
266 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
267
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000268 /// EmitMetaClass - Emit a class structure for the metaclass of the
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000269 /// given implementation. The return value has type ClassPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000270 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
271 llvm::Constant *Protocols,
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000272 const llvm::Type *InterfaceTy,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000273 const ConstantVector &Methods);
274
275 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
276
277 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000278
279 /// EmitMethodList - Emit the method list for the given
Daniel Dunbaraf05bb92008-08-26 08:29:31 +0000280 /// implementation. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000281 llvm::Constant *EmitMethodList(const std::string &Name,
282 const char *Section,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000283 const ConstantVector &Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000284
285 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000286 /// method declarations.
287 /// - TypeName: The name for the type containing the methods.
288 /// - IsProtocol: True iff these methods are for a protocol.
289 /// - ClassMethds: True iff these are class methods.
290 /// - Required: When true, only "required" methods are
291 /// listed. Similarly, when false only "optional" methods are
292 /// listed. For classes this should always be true.
293 /// - begin, end: The method list to output.
294 ///
295 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000296 llvm::Constant *EmitMethodDescList(const std::string &Name,
297 const char *Section,
298 const ConstantVector &Methods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000299
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000300 /// EmitPropertyList - Emit the given property list. The return
301 /// value has type PropertyListPtrTy.
302 llvm::Constant *EmitPropertyList(const std::string &Name,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000303 const Decl *Container,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000304 ObjCPropertyDecl * const *begin,
305 ObjCPropertyDecl * const *end);
306
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000307 /// EmitProtocolExtension - Generate the protocol extension
308 /// structure used to store optional instance and class methods, and
309 /// protocol properties. The return value has type
310 /// ProtocolExtensionPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000311 llvm::Constant *
312 EmitProtocolExtension(const ObjCProtocolDecl *PD,
313 const ConstantVector &OptInstanceMethods,
314 const ConstantVector &OptClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000315
316 /// EmitProtocolList - Generate the list of referenced
317 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc933702008-08-21 21:57:41 +0000318 llvm::Constant *EmitProtocolList(const std::string &Name,
319 ObjCProtocolDecl::protocol_iterator begin,
320 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000321
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000322 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
323 /// for the given selector.
324 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
325
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000326 /// GetProtocolRef - Return a reference to the internal protocol
327 /// description, creating an empty one if it has not been
328 /// defined. The return value has type pointer-to ProtocolTy.
329 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
330
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000331 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000332 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000333 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000334
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000335 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000336 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000337 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000338 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000339 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000340
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000341 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000342 /// selector's name. The return value has type char *.
343
344 // FIXME: This is a horrible name.
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000345 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000346 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000347
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000348 /// GetPropertyName - Return a unique constant for the given
349 /// name. The return value has type char *.
350 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
351
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000352 // FIXME: This can be dropped once string functions are unified.
353 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
354 const Decl *Container);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000355
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000356 /// GetNameForMethod - Return a name for the given method.
357 /// \param[out] NameOut - The return value.
358 void GetNameForMethod(const ObjCMethodDecl *OMD,
359 std::string &NameOut);
360
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000361public:
362 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000363 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000364
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000365 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000366 QualType ResultType,
367 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000368 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000369 bool IsClassMessage,
370 const CallArgList &CallArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000371
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000372 virtual CodeGen::RValue
373 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000374 QualType ResultType,
375 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000376 const ObjCInterfaceDecl *Class,
377 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000378 bool IsClassMessage,
379 const CallArgList &CallArgs);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000380
381 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000382 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000383
384 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
385
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000386 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000387
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000388 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000389
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000390 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000391
392 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000393 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000394
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000395 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000396
397 virtual llvm::Function *ModuleInitFunction();
Anders Carlsson2abd89c2008-08-31 04:05:03 +0000398 virtual llvm::Function *EnumerationMutationFunction();
Anders Carlsson64d5d6c2008-09-09 10:04:29 +0000399
400 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
401 const ObjCAtTryStmt &S);
402 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
403 const ObjCAtThrowStmt &S);
404
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000405};
406} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000407
408/* *** Helper Functions *** */
409
410/// getConstantGEP() - Help routine to construct simple GEPs.
411static llvm::Constant *getConstantGEP(llvm::Constant *C,
412 unsigned idx0,
413 unsigned idx1) {
414 llvm::Value *Idxs[] = {
415 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
416 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
417 };
418 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
419}
420
421/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000422
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000423CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
424 : CGM(cgm),
425 ObjCTypes(cgm),
426 ObjCABI(1)
427{
428 // FIXME: How does this get set in GCC? And what does it even mean?
429 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
430 ObjCABI = 2;
431
432 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000433}
434
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000435/// GetClass - Return a reference to the class for the given interface
436/// decl.
437llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000438 const ObjCInterfaceDecl *ID) {
439 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000440}
441
442/// GetSelector - Return the pointer to the unique'd string for this selector.
443llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000444 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000445}
446
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000447/// Generate a constant CFString object.
448/*
449 struct __builtin_CFString {
450 const int *isa; // point to __CFConstantStringClassReference
451 int flags;
452 const char *str;
453 long length;
454 };
455*/
456
457llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbar3e9df992008-08-23 18:37:06 +0000458 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000459}
460
461/// Generates a message send where the super is the receiver. This is
462/// a message send to self with special delivery semantics indicating
463/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000464CodeGen::RValue
465CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000466 QualType ResultType,
467 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000468 const ObjCInterfaceDecl *Class,
469 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000470 bool IsClassMessage,
Daniel Dunbar46f45b92008-09-09 01:06:48 +0000471 const CodeGen::CallArgList &CallArgs) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000472 // Create and init a super structure; this is a (receiver, class)
473 // pair we will pass to objc_msgSendSuper.
474 llvm::Value *ObjCSuper =
475 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
476 llvm::Value *ReceiverAsObject =
477 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
478 CGF.Builder.CreateStore(ReceiverAsObject,
479 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000480
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000481 // If this is a class message the metaclass is passed as the target.
482 llvm::Value *Target;
483 if (IsClassMessage) {
484 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
485 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
486 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
487 Target = Super;
488 } else {
489 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
490 }
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000491 // FIXME: We shouldn't need to do this cast, rectify the ASTContext
492 // and ObjCTypes types.
493 const llvm::Type *ClassTy =
494 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
495 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000496 CGF.Builder.CreateStore(Target,
497 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
498
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000499 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000500 ObjCSuper, ObjCTypes.SuperPtrCTy,
501 true, CallArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000502}
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000503
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000504/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000505CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000506 QualType ResultType,
507 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000508 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000509 bool IsClassMessage,
510 const CallArgList &CallArgs) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000511 llvm::Value *Arg0 =
512 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000513 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000514 Arg0, CGF.getContext().getObjCIdType(),
515 false, CallArgs);
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000516}
517
518CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000519 QualType ResultType,
520 Selector Sel,
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000521 llvm::Value *Arg0,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000522 QualType Arg0Ty,
523 bool IsSuper,
524 const CallArgList &CallArgs) {
525 CallArgList ActualArgs;
Daniel Dunbar46f45b92008-09-09 01:06:48 +0000526 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
527 ActualArgs.push_back(std::make_pair(RValue::get(EmitSelector(CGF.Builder,
528 Sel)),
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000529 CGF.getContext().getObjCSelType()));
530 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000531
Daniel Dunbar3913f182008-09-09 23:48:28 +0000532 llvm::Value *Fn =
533 ObjCTypes.getMessageSendFn(IsSuper,
Daniel Dunbarb7688072008-09-10 00:41:16 +0000534 CGM.ReturnTypeUsesSret(ResultType),
Daniel Dunbar3913f182008-09-09 23:48:28 +0000535 CGM.getTypes().ConvertType(ResultType));
536 return CGF.EmitCall(Fn, ResultType, ActualArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000537}
538
539llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000540 const ObjCProtocolDecl *PD) {
Daniel Dunbarc67876d2008-09-04 04:33:15 +0000541 // FIXME: I don't understand why gcc generates this, or where it is
542 // resolved. Investigate. Its also wasteful to look this up over and
543 // over.
544 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
545
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000546 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
547 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000548}
549
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000550/*
551 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
552 struct _objc_protocol {
553 struct _objc_protocol_extension *isa;
554 char *protocol_name;
555 struct _objc_protocol_list *protocol_list;
556 struct _objc__method_prototype_list *instance_methods;
557 struct _objc__method_prototype_list *class_methods
558 };
559
560 See EmitProtocolExtension().
561*/
562void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000563 // FIXME: I don't understand why gcc generates this, or where it is
564 // resolved. Investigate. Its also wasteful to look this up over and
565 // over.
566 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
567
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000568 const char *ProtocolName = PD->getName();
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000569
570 // Construct method lists.
571 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
572 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
573 for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
574 e = PD->instmeth_end(); i != e; ++i) {
575 ObjCMethodDecl *MD = *i;
576 llvm::Constant *C = GetMethodDescriptionConstant(MD);
577 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
578 OptInstanceMethods.push_back(C);
579 } else {
580 InstanceMethods.push_back(C);
581 }
582 }
583
584 for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
585 e = PD->classmeth_end(); i != e; ++i) {
586 ObjCMethodDecl *MD = *i;
587 llvm::Constant *C = GetMethodDescriptionConstant(MD);
588 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
589 OptClassMethods.push_back(C);
590 } else {
591 ClassMethods.push_back(C);
592 }
593 }
594
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000595 std::vector<llvm::Constant*> Values(5);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000596 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000597 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000598 Values[2] =
599 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
600 PD->protocol_begin(),
601 PD->protocol_end());
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000602 Values[3] =
603 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_")
604 + PD->getName(),
605 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
606 InstanceMethods);
607 Values[4] =
608 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_")
609 + PD->getName(),
610 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
611 ClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000612 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
613 Values);
614
615 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
616 if (Entry) {
617 // Already created, just update the initializer
618 Entry->setInitializer(Init);
619 } else {
620 Entry =
621 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
622 llvm::GlobalValue::InternalLinkage,
623 Init,
624 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
625 &CGM.getModule());
626 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
627 UsedGlobals.push_back(Entry);
628 // FIXME: Is this necessary? Why only for protocol?
629 Entry->setAlignment(4);
630 }
631}
632
633llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
634 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
635
636 if (!Entry) {
637 std::vector<llvm::Constant*> Values(5);
638 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
639 Values[1] = GetClassName(PD->getIdentifier());
640 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
641 Values[3] = Values[4] =
642 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
643 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
644 Values);
645
646 Entry =
647 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
648 llvm::GlobalValue::InternalLinkage,
649 Init,
650 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
651 &CGM.getModule());
652 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
653 UsedGlobals.push_back(Entry);
654 // FIXME: Is this necessary? Why only for protocol?
655 Entry->setAlignment(4);
656 }
657
658 return Entry;
659}
660
661/*
662 struct _objc_protocol_extension {
663 uint32_t size;
664 struct objc_method_description_list *optional_instance_methods;
665 struct objc_method_description_list *optional_class_methods;
666 struct objc_property_list *instance_properties;
667 };
668*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000669llvm::Constant *
670CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
671 const ConstantVector &OptInstanceMethods,
672 const ConstantVector &OptClassMethods) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000673 uint64_t Size =
674 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
675 std::vector<llvm::Constant*> Values(4);
676 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000677 Values[1] =
678 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_")
679 + PD->getName(),
680 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
681 OptInstanceMethods);
682 Values[2] =
683 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_")
684 + PD->getName(),
685 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
686 OptClassMethods);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000687 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
688 PD->getName(),
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000689 0,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000690 PD->classprop_begin(),
691 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000692
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000693 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000694 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
695 Values[3]->isNullValue())
696 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
697
698 llvm::Constant *Init =
699 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
700 llvm::GlobalVariable *GV =
701 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
702 llvm::GlobalValue::InternalLinkage,
703 Init,
704 (std::string("\01L_OBJC_PROTOCOLEXT_") +
705 PD->getName()),
706 &CGM.getModule());
707 // No special section, but goes in llvm.used
708 UsedGlobals.push_back(GV);
709
710 return GV;
711}
712
713/*
714 struct objc_protocol_list {
715 struct objc_protocol_list *next;
716 long count;
717 Protocol *list[];
718 };
719*/
Daniel Dunbardbc933702008-08-21 21:57:41 +0000720llvm::Constant *
721CGObjCMac::EmitProtocolList(const std::string &Name,
722 ObjCProtocolDecl::protocol_iterator begin,
723 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000724 std::vector<llvm::Constant*> ProtocolRefs;
725
Daniel Dunbardbc933702008-08-21 21:57:41 +0000726 for (; begin != end; ++begin)
727 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000728
729 // Just return null for empty protocol lists
730 if (ProtocolRefs.empty())
731 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
732
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000733 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000734 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
735
736 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000737 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000738 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
739 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
740 Values[2] =
741 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
742 ProtocolRefs.size()),
743 ProtocolRefs);
744
745 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
746 llvm::GlobalVariable *GV =
747 new llvm::GlobalVariable(Init->getType(), false,
748 llvm::GlobalValue::InternalLinkage,
749 Init,
Daniel Dunbardbc933702008-08-21 21:57:41 +0000750 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000751 &CGM.getModule());
752 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
753 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
754}
755
756/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000757 struct _objc_property {
758 const char * const name;
759 const char * const attributes;
760 };
761
762 struct _objc_property_list {
763 uint32_t entsize; // sizeof (struct _objc_property)
764 uint32_t prop_count;
765 struct _objc_property[prop_count];
766 };
767*/
768llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000769 const Decl *Container,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000770 ObjCPropertyDecl * const *begin,
771 ObjCPropertyDecl * const *end) {
772 std::vector<llvm::Constant*> Properties, Prop(2);
773 for (; begin != end; ++begin) {
774 const ObjCPropertyDecl *PD = *begin;
775 Prop[0] = GetPropertyName(PD->getIdentifier());
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000776 Prop[1] = GetPropertyTypeString(PD, Container);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000777 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
778 Prop));
779 }
780
781 // Return null for empty list.
782 if (Properties.empty())
783 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
784
785 unsigned PropertySize =
786 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
787 std::vector<llvm::Constant*> Values(3);
788 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
789 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
790 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
791 Properties.size());
792 Values[2] = llvm::ConstantArray::get(AT, Properties);
793 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
794
795 llvm::GlobalVariable *GV =
796 new llvm::GlobalVariable(Init->getType(), false,
797 llvm::GlobalValue::InternalLinkage,
798 Init,
799 Name,
800 &CGM.getModule());
801 // No special section on property lists?
802 UsedGlobals.push_back(GV);
803 return llvm::ConstantExpr::getBitCast(GV,
804 ObjCTypes.PropertyListPtrTy);
805
806}
807
808/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000809 struct objc_method_description_list {
810 int count;
811 struct objc_method_description list[];
812 };
813*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000814llvm::Constant *
815CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
816 std::vector<llvm::Constant*> Desc(2);
817 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
818 ObjCTypes.SelectorPtrTy);
819 Desc[1] = GetMethodVarType(MD);
820 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
821 Desc);
822}
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000823
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000824llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name,
825 const char *Section,
826 const ConstantVector &Methods) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000827 // Return null for empty list.
828 if (Methods.empty())
829 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
830
831 std::vector<llvm::Constant*> Values(2);
832 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
833 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
834 Methods.size());
835 Values[1] = llvm::ConstantArray::get(AT, Methods);
836 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
837
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000838 llvm::GlobalVariable *GV =
839 new llvm::GlobalVariable(Init->getType(), false,
840 llvm::GlobalValue::InternalLinkage,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000841 Init, Name, &CGM.getModule());
842 GV->setSection(Section);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000843 UsedGlobals.push_back(GV);
844 return llvm::ConstantExpr::getBitCast(GV,
845 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000846}
847
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000848/*
849 struct _objc_category {
850 char *category_name;
851 char *class_name;
852 struct _objc_method_list *instance_methods;
853 struct _objc_method_list *class_methods;
854 struct _objc_protocol_list *protocols;
855 uint32_t size; // <rdar://4585769>
856 struct _objc_property_list *instance_properties;
857 };
858 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000859void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000860 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
861
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000862 // FIXME: This is poor design, the OCD should have a pointer to the
863 // category decl. Additionally, note that Category can be null for
864 // the @implementation w/o an @interface case. Sema should just
865 // create one for us as it does for @implementation so everyone else
866 // can live life under a clear blue sky.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000867 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000868 const ObjCCategoryDecl *Category =
869 Interface->FindCategoryDeclaration(OCD->getIdentifier());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000870 std::string ExtName(std::string(Interface->getName()) +
871 "_" +
872 OCD->getName());
873
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000874 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
875 for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
876 e = OCD->instmeth_end(); i != e; ++i) {
877 // Instance methods should always be defined.
878 InstanceMethods.push_back(GetMethodConstant(*i));
879 }
880 for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
881 e = OCD->classmeth_end(); i != e; ++i) {
882 // Class methods should always be defined.
883 ClassMethods.push_back(GetMethodConstant(*i));
884 }
885
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000886 std::vector<llvm::Constant*> Values(7);
887 Values[0] = GetClassName(OCD->getIdentifier());
888 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000889 Values[2] =
890 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
891 ExtName,
892 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000893 InstanceMethods);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000894 Values[3] =
895 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
896 "__OBJC,__cat_class_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000897 ClassMethods);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000898 if (Category) {
899 Values[4] =
900 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
901 Category->protocol_begin(),
902 Category->protocol_end());
903 } else {
904 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
905 }
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000906 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000907
908 // If there is no category @interface then there can be no properties.
909 if (Category) {
910 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000911 OCD,
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000912 Category->classprop_begin(),
913 Category->classprop_end());
914 } else {
915 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
916 }
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000917
918 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
919 Values);
920
921 llvm::GlobalVariable *GV =
922 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
923 llvm::GlobalValue::InternalLinkage,
924 Init,
925 std::string("\01L_OBJC_CATEGORY_")+ExtName,
926 &CGM.getModule());
927 GV->setSection("__OBJC,__category,regular,no_dead_strip");
928 UsedGlobals.push_back(GV);
929 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000930}
931
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000932// FIXME: Get from somewhere?
933enum ClassFlags {
934 eClassFlags_Factory = 0x00001,
935 eClassFlags_Meta = 0x00002,
936 // <rdr://5142207>
937 eClassFlags_HasCXXStructors = 0x02000,
938 eClassFlags_Hidden = 0x20000,
939 eClassFlags_ABI2_Hidden = 0x00010,
940 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
941};
942
943// <rdr://5142207&4705298&4843145>
944static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
945 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
946 // FIXME: Support -fvisibility
947 switch (attr->getVisibility()) {
948 default:
949 assert(0 && "Unknown visibility");
950 return false;
951 case VisibilityAttr::DefaultVisibility:
952 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
953 return false;
954 case VisibilityAttr::HiddenVisibility:
955 return true;
956 }
957 } else {
958 return false; // FIXME: Support -fvisibility
959 }
960}
961
962/*
963 struct _objc_class {
964 Class isa;
965 Class super_class;
966 const char *name;
967 long version;
968 long info;
969 long instance_size;
970 struct _objc_ivar_list *ivars;
971 struct _objc_method_list *methods;
972 struct _objc_cache *cache;
973 struct _objc_protocol_list *protocols;
974 // Objective-C 1.0 extensions (<rdr://4585769>)
975 const char *ivar_layout;
976 struct _objc_class_ext *ext;
977 };
978
979 See EmitClassExtension();
980 */
981void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000982 DefinedSymbols.insert(ID->getIdentifier());
983
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000984 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000985 // FIXME: Gross
986 ObjCInterfaceDecl *Interface =
987 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000988 llvm::Constant *Protocols =
989 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
990 Interface->protocol_begin(),
991 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000992 const llvm::Type *InterfaceTy =
993 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
994 unsigned Flags = eClassFlags_Factory;
995 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
996
997 // FIXME: Set CXX-structors flag.
998 if (IsClassHidden(ID->getClassInterface()))
999 Flags |= eClassFlags_Hidden;
1000
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001001 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1002 for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
1003 e = ID->instmeth_end(); i != e; ++i) {
1004 // Instance methods should always be defined.
1005 InstanceMethods.push_back(GetMethodConstant(*i));
1006 }
1007 for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
1008 e = ID->classmeth_end(); i != e; ++i) {
1009 // Class methods should always be defined.
1010 ClassMethods.push_back(GetMethodConstant(*i));
1011 }
1012
1013 for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
1014 e = ID->propimpl_end(); i != e; ++i) {
1015 ObjCPropertyImplDecl *PID = *i;
1016
1017 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
1018 ObjCPropertyDecl *PD = PID->getPropertyDecl();
1019
1020 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
1021 if (llvm::Constant *C = GetMethodConstant(MD))
1022 InstanceMethods.push_back(C);
1023 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
1024 if (llvm::Constant *C = GetMethodConstant(MD))
1025 InstanceMethods.push_back(C);
1026 }
1027 }
1028
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001029 std::vector<llvm::Constant*> Values(12);
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001030 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001031 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001032 // Record a reference to the super class.
1033 LazySymbols.insert(Super->getIdentifier());
1034
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001035 Values[ 1] =
1036 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1037 ObjCTypes.ClassPtrTy);
1038 } else {
1039 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1040 }
1041 Values[ 2] = GetClassName(ID->getIdentifier());
1042 // Version is always 0.
1043 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1044 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1045 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1046 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001047 Values[ 7] =
1048 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
1049 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001050 InstanceMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001051 // cache is always NULL.
1052 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1053 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001054 // FIXME: Set ivar_layout
1055 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001056 Values[11] = EmitClassExtension(ID);
1057 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1058 Values);
1059
1060 llvm::GlobalVariable *GV =
1061 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1062 llvm::GlobalValue::InternalLinkage,
1063 Init,
1064 std::string("\01L_OBJC_CLASS_")+ClassName,
1065 &CGM.getModule());
1066 GV->setSection("__OBJC,__class,regular,no_dead_strip");
1067 UsedGlobals.push_back(GV);
1068 // FIXME: Why?
1069 GV->setAlignment(32);
1070 DefinedClasses.push_back(GV);
1071}
1072
1073llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
1074 llvm::Constant *Protocols,
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001075 const llvm::Type *InterfaceTy,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001076 const ConstantVector &Methods) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001077 const char *ClassName = ID->getName();
1078 unsigned Flags = eClassFlags_Meta;
1079 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
1080
1081 if (IsClassHidden(ID->getClassInterface()))
1082 Flags |= eClassFlags_Hidden;
1083
1084 std::vector<llvm::Constant*> Values(12);
1085 // The isa for the metaclass is the root of the hierarchy.
1086 const ObjCInterfaceDecl *Root = ID->getClassInterface();
1087 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
1088 Root = Super;
1089 Values[ 0] =
1090 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
1091 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001092 // The super class for the metaclass is emitted as the name of the
1093 // super class. The runtime fixes this up to point to the
1094 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001095 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
1096 Values[ 1] =
1097 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1098 ObjCTypes.ClassPtrTy);
1099 } else {
1100 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1101 }
1102 Values[ 2] = GetClassName(ID->getIdentifier());
1103 // Version is always 0.
1104 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1105 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1106 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1107 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001108 Values[ 7] =
1109 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
1110 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001111 Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001112 // cache is always NULL.
1113 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1114 Values[ 9] = Protocols;
1115 // ivar_layout for metaclass is always NULL.
1116 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1117 // The class extension is always unused for metaclasses.
1118 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1119 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1120 Values);
1121
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001122 std::string Name("\01L_OBJC_METACLASS_");
1123 Name += ClassName;
1124
1125 // Check for a forward reference.
1126 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
1127 if (GV) {
1128 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1129 "Forward metaclass reference has incorrect type.");
1130 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
1131 GV->setInitializer(Init);
1132 } else {
1133 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1134 llvm::GlobalValue::InternalLinkage,
1135 Init, Name,
1136 &CGM.getModule());
1137 }
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001138 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
1139 UsedGlobals.push_back(GV);
1140 // FIXME: Why?
1141 GV->setAlignment(32);
1142
1143 return GV;
1144}
1145
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001146llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
1147 std::string Name("\01L_OBJC_METACLASS_");
1148 Name += ID->getName();
1149
1150 // FIXME: Should we look these up somewhere other than the
1151 // module. Its a bit silly since we only generate these while
1152 // processing an implementation, so exactly one pointer would work
1153 // if know when we entered/exitted an implementation block.
1154
1155 // Check for an existing forward reference.
1156 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) {
1157 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1158 "Forward metaclass reference has incorrect type.");
1159 return GV;
1160 } else {
1161 // Generate as an external reference to keep a consistent
1162 // module. This will be patched up when we emit the metaclass.
1163 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1164 llvm::GlobalValue::ExternalLinkage,
1165 0,
1166 Name,
1167 &CGM.getModule());
1168 }
1169}
1170
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001171/*
1172 struct objc_class_ext {
1173 uint32_t size;
1174 const char *weak_ivar_layout;
1175 struct _objc_property_list *properties;
1176 };
1177*/
1178llvm::Constant *
1179CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1180 uint64_t Size =
1181 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1182
1183 std::vector<llvm::Constant*> Values(3);
1184 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001185 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001186 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001187 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1188 ID->getName(),
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001189 ID,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001190 ID->getClassInterface()->classprop_begin(),
1191 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001192
1193 // Return null if no extension bits are used.
1194 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1195 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1196
1197 llvm::Constant *Init =
1198 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1199 llvm::GlobalVariable *GV =
1200 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1201 llvm::GlobalValue::InternalLinkage,
1202 Init,
1203 (std::string("\01L_OBJC_CLASSEXT_") +
1204 ID->getName()),
1205 &CGM.getModule());
1206 // No special section, but goes in llvm.used
1207 UsedGlobals.push_back(GV);
1208
1209 return GV;
1210}
1211
1212/*
1213 struct objc_ivar {
1214 char *ivar_name;
1215 char *ivar_type;
1216 int ivar_offset;
1217 };
1218
1219 struct objc_ivar_list {
1220 int ivar_count;
1221 struct objc_ivar list[count];
1222 };
1223 */
1224llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1225 bool ForClass,
1226 const llvm::Type *InterfaceTy) {
1227 std::vector<llvm::Constant*> Ivars, Ivar(3);
1228
1229 // When emitting the root class GCC emits ivar entries for the
1230 // actual class structure. It is not clear if we need to follow this
1231 // behavior; for now lets try and get away with not doing it. If so,
1232 // the cleanest solution would be to make up an ObjCInterfaceDecl
1233 // for the class.
1234 if (ForClass)
1235 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1236
1237 const llvm::StructLayout *Layout =
1238 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1239 for (ObjCInterfaceDecl::ivar_iterator
1240 i = ID->getClassInterface()->ivar_begin(),
1241 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1242 ObjCIvarDecl *V = *i;
1243 unsigned Offset =
1244 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1245 std::string TypeStr;
1246 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1247 Ivar[0] = GetMethodVarName(V->getIdentifier());
1248 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1249 EncodingRecordTypes);
1250 Ivar[1] = GetMethodVarType(TypeStr);
1251 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1252 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1253 Ivar));
1254 }
1255
1256 // Return null for empty list.
1257 if (Ivars.empty())
1258 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1259
1260 std::vector<llvm::Constant*> Values(2);
1261 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1262 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1263 Ivars.size());
1264 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1265 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1266
1267 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1268 "\01L_OBJC_INSTANCE_VARIABLES_");
1269 llvm::GlobalVariable *GV =
1270 new llvm::GlobalVariable(Init->getType(), false,
1271 llvm::GlobalValue::InternalLinkage,
1272 Init,
1273 std::string(Prefix) + ID->getName(),
1274 &CGM.getModule());
1275 if (ForClass) {
1276 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1277 // FIXME: Why is this only here?
1278 GV->setAlignment(32);
1279 } else {
1280 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1281 }
1282 UsedGlobals.push_back(GV);
1283 return llvm::ConstantExpr::getBitCast(GV,
1284 ObjCTypes.IvarListPtrTy);
1285}
1286
1287/*
1288 struct objc_method {
1289 SEL method_name;
1290 char *method_types;
1291 void *method;
1292 };
1293
1294 struct objc_method_list {
1295 struct objc_method_list *obsolete;
1296 int count;
1297 struct objc_method methods_list[count];
1298 };
1299*/
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001300
1301/// GetMethodConstant - Return a struct objc_method constant for the
1302/// given method if it has been defined. The result is null if the
1303/// method has not been defined. The return value has type MethodPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001304llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001305 // FIXME: Use DenseMap::lookup
1306 llvm::Function *Fn = MethodDefinitions[MD];
1307 if (!Fn)
1308 return 0;
1309
1310 std::vector<llvm::Constant*> Method(3);
1311 Method[0] =
1312 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1313 ObjCTypes.SelectorPtrTy);
1314 Method[1] = GetMethodVarType(MD);
1315 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
1316 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
1317}
1318
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001319llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1320 const char *Section,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001321 const ConstantVector &Methods) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001322 // Return null for empty list.
1323 if (Methods.empty())
1324 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1325
1326 std::vector<llvm::Constant*> Values(3);
1327 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1328 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1329 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1330 Methods.size());
1331 Values[2] = llvm::ConstantArray::get(AT, Methods);
1332 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1333
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001334 llvm::GlobalVariable *GV =
1335 new llvm::GlobalVariable(Init->getType(), false,
1336 llvm::GlobalValue::InternalLinkage,
1337 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001338 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001339 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001340 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001341 UsedGlobals.push_back(GV);
1342 return llvm::ConstantExpr::getBitCast(GV,
1343 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001344}
1345
1346llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001347 std::string Name;
1348 GetNameForMethod(OMD, Name);
1349
Daniel Dunbar45c25ba2008-09-10 04:01:49 +00001350 const llvm::FunctionType *MethodTy =
1351 CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001352 llvm::Function *Method =
Daniel Dunbar45c25ba2008-09-10 04:01:49 +00001353 llvm::Function::Create(MethodTy,
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001354 llvm::GlobalValue::InternalLinkage,
1355 Name,
1356 &CGM.getModule());
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001357 MethodDefinitions.insert(std::make_pair(OMD, Method));
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001358
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001359 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001360}
1361
1362llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001363 // Abuse this interface function as a place to finalize.
1364 FinishModule();
1365
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001366 return NULL;
1367}
1368
Anders Carlsson2abd89c2008-08-31 04:05:03 +00001369llvm::Function *CGObjCMac::EnumerationMutationFunction()
1370{
1371 return ObjCTypes.EnumerationMutationFn;
1372}
1373
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00001374void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1375 const ObjCAtTryStmt &S)
1376{
Anders Carlsson80f25672008-09-09 17:59:25 +00001377 // Allocate exception data.
1378 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
1379 "exceptiondata.ptr");
1380
1381 // Allocate memory for the rethrow pointer.
1382 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy);
1383 CGF.Builder.CreateStore(llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy),
1384 RethrowPtr);
1385
1386 // Enter a new try block and call setjmp.
1387 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
1388 llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0,
1389 "jmpbufarray");
1390 JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp");
1391 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
1392 JmpBufPtr, "result");
1393
1394
1395 llvm::BasicBlock *FinallyBlock = llvm::BasicBlock::Create("finally");
1396
1397 llvm::BasicBlock *TryBlock = llvm::BasicBlock::Create("try");
1398 llvm::BasicBlock *ExceptionInTryBlock =
1399 llvm::BasicBlock::Create("exceptionintry");
1400
1401 // If setjmp returns 1, there was an exception in the @try block.
1402 llvm::Value *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
1403 llvm::Value *IsZero = CGF.Builder.CreateICmpEQ(SetJmpResult, Zero, "iszero");
1404 CGF.Builder.CreateCondBr(IsZero, TryBlock, ExceptionInTryBlock);
1405
1406 // Emit the @try block.
1407 CGF.EmitBlock(TryBlock);
1408 CGF.EmitStmt(S.getTryBody());
1409 CGF.Builder.CreateBr(FinallyBlock);
1410
1411 // Emit the "exception in @try" block.
1412 CGF.EmitBlock(ExceptionInTryBlock);
1413
1414 if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) {
1415 // Allocate memory for the caught exception and extract it from the
1416 // exception data.
1417 llvm::Value *CaughtPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy);
1418 llvm::Value *Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
1419 ExceptionData);
1420 CGF.Builder.CreateStore(Extract, CaughtPtr);
1421
1422 // Enter a new exception try block
1423 // (in case a @catch block throws an exception).
1424 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
1425
1426 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
1427 JmpBufPtr, "result");
1428
1429
1430 llvm::Value *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
1431 llvm::Value *IsZero = CGF.Builder.CreateICmpEQ(SetJmpResult, Zero,
1432 "iszero");
1433
1434 llvm::BasicBlock *CatchBlock = llvm::BasicBlock::Create("catch");
1435 llvm::BasicBlock *ExceptionInCatchBlock =
1436 llvm::BasicBlock::Create("exceptionincatch");
1437 CGF.Builder.CreateCondBr(IsZero, CatchBlock, ExceptionInCatchBlock);
1438
1439 CGF.EmitBlock(CatchBlock);
1440
1441 // Handle catch list
1442 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
1443 llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("nextcatch");
1444
1445 QualType T;
1446 bool MatchesAll = false;
1447
1448 // catch(...) always matches.
1449 if (CatchStmt->hasEllipsis())
1450 MatchesAll = true;
1451 else {
1452 const DeclStmt *DS = cast<DeclStmt>(CatchStmt->getCatchParamStmt());
1453 QualType PT = cast<ValueDecl>(DS->getDecl())->getType();
1454 T = PT->getAsPointerType()->getPointeeType();
1455
1456 // catch(id e) always matches.
1457 if (CGF.getContext().isObjCIdType(T))
1458 MatchesAll = true;
1459 }
1460
1461 if (MatchesAll) {
1462 CGF.EmitStmt(CatchStmt->getCatchBody());
1463 CGF.Builder.CreateBr(FinallyBlock);
1464
1465 CGF.EmitBlock(NextCatchBlock);
1466 break;
1467 }
1468
1469 const ObjCInterfaceType *ObjCType = T->getAsPointerToObjCInterfaceType();
1470 assert(ObjCType && "Catch parameter must have Objective-C type!");
1471
1472 // Check if the @catch block matches the exception object.
1473 llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl());
1474
1475 llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught");
1476 llvm::Value *Match = CGF.Builder.CreateCall2(ObjCTypes.ExceptionMatchFn,
1477 Class, Caught, "match");
1478
1479 llvm::Value *DidMatch = CGF.Builder.CreateICmpNE(Match, Zero, "iszero");
1480
1481 llvm::BasicBlock *MatchedBlock = llvm::BasicBlock::Create("matched");
1482
1483 CGF.Builder.CreateCondBr(DidMatch, MatchedBlock, NextCatchBlock);
1484
1485 // Emit the @catch block.
1486 CGF.EmitBlock(MatchedBlock);
1487 CGF.EmitStmt(CatchStmt->getCatchBody());
1488 CGF.Builder.CreateBr(FinallyBlock);
1489
1490 CGF.EmitBlock(NextCatchBlock);
1491 }
1492
1493 // None of the handlers caught the exception, so store it and rethrow
1494 // it later.
1495 llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught");
1496 CGF.Builder.CreateStore(Caught, RethrowPtr);
1497 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn,
1498 ExceptionData);
1499
1500 CGF.Builder.CreateBr(FinallyBlock);
1501
1502 CGF.EmitBlock(ExceptionInCatchBlock);
1503
1504 Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
1505 ExceptionData);
1506 CGF.Builder.CreateStore(Extract, RethrowPtr);
1507 }
1508
1509 // Emit the @finally block.
1510 CGF.EmitBlock(FinallyBlock);
1511
1512 llvm::Value *Rethrow = CGF.Builder.CreateLoad(RethrowPtr);
1513 llvm::Value *ZeroPtr = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
1514
1515 llvm::Value *RethrowIsZero = CGF.Builder.CreateICmpEQ(Rethrow, ZeroPtr);
1516
1517 llvm::BasicBlock *TryExitBlock = llvm::BasicBlock::Create("tryexit");
1518 llvm::BasicBlock *AfterTryExitBlock =
1519 llvm::BasicBlock::Create("aftertryexit");
1520
1521 CGF.Builder.CreateCondBr(RethrowIsZero, TryExitBlock, AfterTryExitBlock);
1522 CGF.EmitBlock(TryExitBlock);
1523 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData);
1524 CGF.EmitBlock(AfterTryExitBlock);
1525
1526 if (const ObjCAtFinallyStmt* FinallyStmt = S.getFinallyStmt())
1527 CGF.EmitStmt(FinallyStmt->getFinallyBody());
1528
1529 llvm::Value *RethrowIsNotZero = CGF.Builder.CreateICmpNE(Rethrow, ZeroPtr);
1530
1531 llvm::BasicBlock *RethrowBlock = llvm::BasicBlock::Create("rethrow");
1532 llvm::BasicBlock *FinallyEndBlock = llvm::BasicBlock::Create("finallyend");
1533
1534 // If necessary, rethrow the exception.
1535 CGF.Builder.CreateCondBr(RethrowIsNotZero, RethrowBlock, FinallyEndBlock);
1536 CGF.EmitBlock(RethrowBlock);
1537 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, Rethrow);
1538 CGF.EmitBlock(FinallyEndBlock);
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00001539}
1540
1541void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1542 const ObjCAtThrowStmt &S)
1543{
Anders Carlsson2b1e3112008-09-09 16:16:55 +00001544 llvm::Value *ExceptionAsObject;
1545
1546 if (const Expr *ThrowExpr = S.getThrowExpr()) {
1547 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
1548 ExceptionAsObject =
1549 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
1550 } else {
1551 assert(0 && "FIXME: rethrows not supported!");
1552 }
1553
1554 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, ExceptionAsObject);
Anders Carlsson80f25672008-09-09 17:59:25 +00001555 CGF.Builder.CreateUnreachable();
1556 CGF.EmitBlock(llvm::BasicBlock::Create("bb"));
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00001557}
1558
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001559/* *** Private Interface *** */
1560
1561/// EmitImageInfo - Emit the image info marker used to encode some module
1562/// level information.
1563///
1564/// See: <rdr://4810609&4810587&4810587>
1565/// struct IMAGE_INFO {
1566/// unsigned version;
1567/// unsigned flags;
1568/// };
1569enum ImageInfoFlags {
1570 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1571 eImageInfo_GarbageCollected = (1 << 1),
1572 eImageInfo_GCOnly = (1 << 2)
1573};
1574
1575void CGObjCMac::EmitImageInfo() {
1576 unsigned version = 0; // Version is unused?
1577 unsigned flags = 0;
1578
1579 // FIXME: Fix and continue?
1580 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1581 flags |= eImageInfo_GarbageCollected;
1582 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1583 flags |= eImageInfo_GCOnly;
1584
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001585 // Emitted as int[2];
1586 llvm::Constant *values[2] = {
1587 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1588 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1589 };
1590 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001591 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001592 new llvm::GlobalVariable(AT, true,
1593 llvm::GlobalValue::InternalLinkage,
1594 llvm::ConstantArray::get(AT, values, 2),
1595 "\01L_OBJC_IMAGE_INFO",
1596 &CGM.getModule());
1597
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001598 if (ObjCABI == 1) {
1599 GV->setSection("__OBJC, __image_info,regular");
1600 } else {
1601 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1602 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001603
1604 UsedGlobals.push_back(GV);
1605}
1606
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001607
1608// struct objc_module {
1609// unsigned long version;
1610// unsigned long size;
1611// const char *name;
1612// Symtab symtab;
1613// };
1614
1615// FIXME: Get from somewhere
1616static const int ModuleVersion = 7;
1617
1618void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001619 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1620
1621 std::vector<llvm::Constant*> Values(4);
1622 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1623 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001624 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001625 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001626 Values[3] = EmitModuleSymbols();
1627
1628 llvm::GlobalVariable *GV =
1629 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1630 llvm::GlobalValue::InternalLinkage,
1631 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1632 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001633 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001634 &CGM.getModule());
1635 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1636 UsedGlobals.push_back(GV);
1637}
1638
1639llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001640 unsigned NumClasses = DefinedClasses.size();
1641 unsigned NumCategories = DefinedCategories.size();
1642
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001643 // Return null if no symbols were defined.
1644 if (!NumClasses && !NumCategories)
1645 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
1646
1647 std::vector<llvm::Constant*> Values(5);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001648 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1649 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1650 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1651 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1652
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001653 // The runtime expects exactly the list of defined classes followed
1654 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001655 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001656 for (unsigned i=0; i<NumClasses; i++)
1657 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1658 ObjCTypes.Int8PtrTy);
1659 for (unsigned i=0; i<NumCategories; i++)
1660 Symbols[NumClasses + i] =
1661 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1662 ObjCTypes.Int8PtrTy);
1663
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001664 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001665 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001666 NumClasses + NumCategories),
1667 Symbols);
1668
1669 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1670
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001671 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001672 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001673 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001674 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001675 "\01L_OBJC_SYMBOLS",
1676 &CGM.getModule());
1677 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1678 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001679 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1680}
1681
1682llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1683 const ObjCInterfaceDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001684 LazySymbols.insert(ID->getIdentifier());
1685
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001686 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1687
1688 if (!Entry) {
1689 llvm::Constant *Casted =
1690 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1691 ObjCTypes.ClassPtrTy);
1692 Entry =
1693 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1694 llvm::GlobalValue::InternalLinkage,
1695 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1696 &CGM.getModule());
1697 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1698 UsedGlobals.push_back(Entry);
1699 }
1700
1701 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001702}
1703
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001704llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1705 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1706
1707 if (!Entry) {
1708 llvm::Constant *Casted =
1709 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1710 ObjCTypes.SelectorPtrTy);
1711 Entry =
1712 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1713 llvm::GlobalValue::InternalLinkage,
1714 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1715 &CGM.getModule());
1716 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1717 UsedGlobals.push_back(Entry);
1718 }
1719
1720 return Builder.CreateLoad(Entry, false, "tmp");
1721}
1722
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001723llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1724 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001725
1726 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001727 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001728 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001729 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001730 llvm::GlobalValue::InternalLinkage,
1731 C, "\01L_OBJC_CLASS_NAME_",
1732 &CGM.getModule());
1733 Entry->setSection("__TEXT,__cstring,cstring_literals");
1734 UsedGlobals.push_back(Entry);
1735 }
1736
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001737 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001738}
1739
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001740llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1741 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1742
1743 if (!Entry) {
1744 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1745 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001746 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001747 llvm::GlobalValue::InternalLinkage,
1748 C, "\01L_OBJC_METH_VAR_NAME_",
1749 &CGM.getModule());
1750 Entry->setSection("__TEXT,__cstring,cstring_literals");
1751 UsedGlobals.push_back(Entry);
1752 }
1753
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001754 return getConstantGEP(Entry, 0, 0);
1755}
1756
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001757// FIXME: Merge into a single cstring creation function.
1758llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1759 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1760}
1761
1762// FIXME: Merge into a single cstring creation function.
1763llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1764 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1765}
1766
1767llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1768 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001769
1770 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001771 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001772 Entry =
1773 new llvm::GlobalVariable(C->getType(), false,
1774 llvm::GlobalValue::InternalLinkage,
1775 C, "\01L_OBJC_METH_VAR_TYPE_",
1776 &CGM.getModule());
1777 Entry->setSection("__TEXT,__cstring,cstring_literals");
1778 UsedGlobals.push_back(Entry);
1779 }
1780
1781 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001782}
1783
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001784// FIXME: Merge into a single cstring creation function.
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001785llvm::Constant *CGObjCMac::GetMethodVarType(const ObjCMethodDecl *D) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001786 std::string TypeStr;
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001787 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
1788 TypeStr);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001789 return GetMethodVarType(TypeStr);
1790}
1791
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001792// FIXME: Merge into a single cstring creation function.
1793llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1794 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1795
1796 if (!Entry) {
1797 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1798 Entry =
1799 new llvm::GlobalVariable(C->getType(), false,
1800 llvm::GlobalValue::InternalLinkage,
1801 C, "\01L_OBJC_PROP_NAME_ATTR_",
1802 &CGM.getModule());
1803 Entry->setSection("__TEXT,__cstring,cstring_literals");
1804 UsedGlobals.push_back(Entry);
1805 }
1806
1807 return getConstantGEP(Entry, 0, 0);
1808}
1809
1810// FIXME: Merge into a single cstring creation function.
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001811// FIXME: This Decl should be more precise.
1812llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
1813 const Decl *Container) {
1814 std::string TypeStr;
1815 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001816 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1817}
1818
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001819void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1820 std::string &NameOut) {
1821 // FIXME: Find the mangling GCC uses.
1822 std::stringstream s;
1823 s << (D->isInstance() ? "-" : "+");
1824 s << "[";
1825 s << D->getClassInterface()->getName();
1826 s << " ";
1827 s << D->getSelector().getName();
1828 s << "]";
1829 NameOut = s.str();
1830}
1831
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001832void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001833 EmitModuleInfo();
1834
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001835 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001836
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001837 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001838 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001839 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001840 }
1841
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001842 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001843 llvm::GlobalValue *GV =
1844 new llvm::GlobalVariable(AT, false,
1845 llvm::GlobalValue::AppendingLinkage,
1846 llvm::ConstantArray::get(AT, Used),
1847 "llvm.used",
1848 &CGM.getModule());
1849
1850 GV->setSection("llvm.metadata");
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001851
1852 // Add assembler directives to add lazy undefined symbol references
1853 // for classes which are referenced but not defined. This is
1854 // important for correct linker interaction.
1855
1856 // FIXME: Uh, this isn't particularly portable.
1857 std::stringstream s;
1858 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
1859 e = LazySymbols.end(); i != e; ++i) {
1860 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
1861 }
1862 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
1863 e = DefinedSymbols.end(); i != e; ++i) {
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001864 s << "\t.objc_class_name_" << (*i)->getName() << "=0\n"
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001865 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
1866 }
1867 CGM.getModule().appendModuleInlineAsm(s.str());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001868}
1869
1870/* *** */
1871
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001872ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbar3e9df992008-08-23 18:37:06 +00001873 : CGM(cgm)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001874{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001875 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1876 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001877
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001878 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001879 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001880 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001881 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1882
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001883 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1884 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001885
1886 // FIXME: It would be nice to unify this with the opaque type, so
1887 // that the IR comes out a bit cleaner.
1888 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1889 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001890
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001891 MethodDescriptionTy =
1892 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001893 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001894 NULL);
1895 CGM.getModule().addTypeName("struct._objc_method_description",
1896 MethodDescriptionTy);
1897
1898 MethodDescriptionListTy =
1899 llvm::StructType::get(IntTy,
1900 llvm::ArrayType::get(MethodDescriptionTy, 0),
1901 NULL);
1902 CGM.getModule().addTypeName("struct._objc_method_description_list",
1903 MethodDescriptionListTy);
1904 MethodDescriptionListPtrTy =
1905 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1906
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001907 PropertyTy = llvm::StructType::get(Int8PtrTy,
1908 Int8PtrTy,
1909 NULL);
1910 CGM.getModule().addTypeName("struct._objc_property",
1911 PropertyTy);
1912
1913 PropertyListTy = llvm::StructType::get(IntTy,
1914 IntTy,
1915 llvm::ArrayType::get(PropertyTy, 0),
1916 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001917 CGM.getModule().addTypeName("struct._objc_property_list",
1918 PropertyListTy);
1919 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1920
1921 // Protocol description structures
1922
1923 ProtocolExtensionTy =
1924 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1925 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1926 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1927 PropertyListPtrTy,
1928 NULL);
1929 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1930 ProtocolExtensionTy);
1931 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1932
1933 // Handle recursive construction of Protocl and ProtocolList types
1934
1935 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1936 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1937
1938 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1939 LongTy,
1940 llvm::ArrayType::get(ProtocolTyHolder, 0),
1941 NULL);
1942 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1943
1944 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001945 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001946 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1947 MethodDescriptionListPtrTy,
1948 MethodDescriptionListPtrTy,
1949 NULL);
1950 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1951
1952 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1953 CGM.getModule().addTypeName("struct._objc_protocol_list",
1954 ProtocolListTy);
1955 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1956
1957 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1958 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1959 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001960
1961 // Class description structures
1962
1963 IvarTy = llvm::StructType::get(Int8PtrTy,
1964 Int8PtrTy,
1965 IntTy,
1966 NULL);
1967 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1968
1969 IvarListTy = llvm::OpaqueType::get();
1970 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1971 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1972
1973 MethodTy = llvm::StructType::get(SelectorPtrTy,
1974 Int8PtrTy,
1975 Int8PtrTy,
1976 NULL);
1977 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1978
1979 MethodListTy = llvm::OpaqueType::get();
1980 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1981 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1982
1983 CacheTy = llvm::OpaqueType::get();
1984 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1985 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1986
1987 ClassExtensionTy =
1988 llvm::StructType::get(IntTy,
1989 Int8PtrTy,
1990 PropertyListPtrTy,
1991 NULL);
1992 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1993 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1994
1995 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1996
1997 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1998 llvm::PointerType::getUnqual(ClassTyHolder),
1999 Int8PtrTy,
2000 LongTy,
2001 LongTy,
2002 LongTy,
2003 IvarListPtrTy,
2004 MethodListPtrTy,
2005 CachePtrTy,
2006 ProtocolListPtrTy,
2007 Int8PtrTy,
2008 ClassExtensionPtrTy,
2009 NULL);
2010 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
2011
2012 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
2013 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
2014 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
2015
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002016 CategoryTy = llvm::StructType::get(Int8PtrTy,
2017 Int8PtrTy,
2018 MethodListPtrTy,
2019 MethodListPtrTy,
2020 ProtocolListPtrTy,
2021 IntTy,
2022 PropertyListPtrTy,
2023 NULL);
2024 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
2025
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00002026 // I'm not sure I like this. The implicit coordination is a bit
2027 // gross. We should solve this in a reasonable fashion because this
2028 // is a pretty common task (match some runtime data structure with
2029 // an LLVM data structure).
2030
2031 // FIXME: This is leaked.
2032 // FIXME: Merge with rewriter code?
2033 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
2034 SourceLocation(),
Ted Kremenekdf042e62008-09-05 01:34:33 +00002035 &Ctx.Idents.get("_objc_super"));
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00002036 FieldDecl *FieldDecls[2];
2037 FieldDecls[0] = FieldDecl::Create(Ctx, SourceLocation(), 0,
2038 Ctx.getObjCIdType());
2039 FieldDecls[1] = FieldDecl::Create(Ctx, SourceLocation(), 0,
2040 Ctx.getObjCClassType());
Ted Kremenek4b7c9832008-09-05 17:16:31 +00002041 RD->defineBody(Ctx, FieldDecls, 2);
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00002042
2043 SuperCTy = Ctx.getTagDeclType(RD);
2044 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
2045
2046 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002047 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbare8b470d2008-08-23 04:28:29 +00002048
Daniel Dunbar27f9d772008-08-21 04:36:09 +00002049 // Global metadata structures
2050
2051 SymtabTy = llvm::StructType::get(LongTy,
2052 SelectorPtrTy,
2053 ShortTy,
2054 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002055 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00002056 NULL);
2057 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
2058 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
2059
2060 ModuleTy =
2061 llvm::StructType::get(LongTy,
2062 LongTy,
2063 Int8PtrTy,
2064 SymtabPtrTy,
2065 NULL);
2066 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002067
2068 // Message send functions
2069
2070 std::vector<const llvm::Type*> Params;
2071 Params.push_back(ObjectPtrTy);
2072 Params.push_back(SelectorPtrTy);
2073 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
2074 Params,
2075 true),
2076 llvm::Function::ExternalLinkage,
2077 "objc_msgSend",
2078 &CGM.getModule());
2079
2080 Params.clear();
2081 Params.push_back(Int8PtrTy);
2082 Params.push_back(ObjectPtrTy);
2083 Params.push_back(SelectorPtrTy);
2084 MessageSendStretFn =
2085 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
2086 Params,
2087 true),
2088 llvm::Function::ExternalLinkage,
2089 "objc_msgSend_stret",
2090 &CGM.getModule());
2091
2092 Params.clear();
2093 Params.push_back(SuperPtrTy);
2094 Params.push_back(SelectorPtrTy);
2095 MessageSendSuperFn =
2096 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
2097 Params,
2098 true),
2099 llvm::Function::ExternalLinkage,
2100 "objc_msgSendSuper",
2101 &CGM.getModule());
2102
2103 Params.clear();
2104 Params.push_back(Int8PtrTy);
2105 Params.push_back(SuperPtrTy);
2106 Params.push_back(SelectorPtrTy);
2107 MessageSendSuperStretFn =
2108 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
2109 Params,
2110 true),
2111 llvm::Function::ExternalLinkage,
2112 "objc_msgSendSuper_stret",
2113 &CGM.getModule());
Anders Carlsson2abd89c2008-08-31 04:05:03 +00002114
2115 // Enumeration mutation.
2116
2117 Params.clear();
2118 Params.push_back(ObjectPtrTy);
2119 EnumerationMutationFn =
2120 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
2121 Params,
2122 false),
2123 llvm::Function::ExternalLinkage,
2124 "objc_enumerationMutation",
2125 &CGM.getModule());
Anders Carlsson124526b2008-09-09 10:10:21 +00002126
2127 // FIXME: This is the size of the setjmp buffer and should be
2128 // target specific. 18 is what's used on 32-bit X86.
2129 uint64_t SetJmpBufferSize = 18;
2130
2131 // Exceptions
2132 const llvm::Type *StackPtrTy =
2133 llvm::PointerType::getUnqual(llvm::ArrayType::get(llvm::Type::Int8Ty, 4));
2134
2135 ExceptionDataTy =
2136 llvm::StructType::get(llvm::ArrayType::get(llvm::Type::Int32Ty,
2137 SetJmpBufferSize),
2138 StackPtrTy, NULL);
2139 CGM.getModule().addTypeName("struct._objc_exception_data",
2140 ExceptionDataTy);
2141
2142 Params.clear();
2143 Params.push_back(ObjectPtrTy);
2144 ExceptionThrowFn =
2145 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
2146 Params,
2147 false),
2148 llvm::Function::ExternalLinkage,
2149 "objc_exception_throw",
2150 &CGM.getModule());
2151
2152 Params.clear();
2153 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
2154 ExceptionTryEnterFn =
2155 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
2156 Params,
2157 false),
2158 llvm::Function::ExternalLinkage,
2159 "objc_exception_try_enter",
2160 &CGM.getModule());
2161 ExceptionTryExitFn =
2162 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
2163 Params,
2164 false),
2165 llvm::Function::ExternalLinkage,
2166 "objc_exception_try_exit",
2167 &CGM.getModule());
2168 ExceptionExtractFn =
2169 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
2170 Params,
2171 false),
2172 llvm::Function::ExternalLinkage,
2173 "objc_exception_extract",
2174 &CGM.getModule());
2175
2176 Params.clear();
2177 Params.push_back(ClassPtrTy);
2178 Params.push_back(ObjectPtrTy);
2179 ExceptionMatchFn =
2180 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::Int32Ty,
2181 Params,
2182 false),
2183 llvm::Function::ExternalLinkage,
2184 "objc_exception_match",
2185 &CGM.getModule());
2186
2187 Params.clear();
2188 Params.push_back(llvm::PointerType::getUnqual(llvm::Type::Int32Ty));
2189 SetJmpFn =
2190 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::Int32Ty,
2191 Params,
2192 false),
2193 llvm::Function::ExternalLinkage,
2194 "_setjmp",
2195 &CGM.getModule());
2196
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00002197}
2198
2199ObjCTypesHelper::~ObjCTypesHelper() {
2200}
2201
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002202llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
Daniel Dunbar3913f182008-09-09 23:48:28 +00002203 bool IsStret,
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002204 const llvm::Type *ReturnTy) {
2205 llvm::Function *F;
2206 llvm::FunctionType *CallFTy;
2207
2208 // FIXME: Should we be caching any of this?
Daniel Dunbar3913f182008-09-09 23:48:28 +00002209 if (IsStret) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002210 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
2211 std::vector<const llvm::Type*> Params(3);
2212 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
2213 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
2214 Params[2] = SelectorPtrTy;
2215 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
Daniel Dunbar662174c82008-08-29 17:28:43 +00002216 } else { // FIXME: floating point?
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002217 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
2218 std::vector<const llvm::Type*> Params(2);
2219 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
2220 Params[1] = SelectorPtrTy;
2221 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00002222 }
2223
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002224 return llvm::ConstantExpr::getBitCast(F,
2225 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00002226}
2227
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00002228/* *** */
2229
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002230CodeGen::CGObjCRuntime *
2231CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00002232 return new CGObjCMac(CGM);
2233}