blob: d5a21bb7697e7ade57847f05b0ebaefc3e55c0b8 [file] [log] [blame]
Daniel Dunbar8c85fac2008-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 Dunbar1be1df32008-08-11 21:35:06 +000015
16#include "CodeGenModule.h"
Daniel Dunbarace33292008-08-16 03:19:19 +000017#include "CodeGenFunction.h"
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000018#include "clang/AST/ASTContext.h"
Daniel Dunbarde300732008-08-11 04:54:23 +000019#include "clang/AST/Decl.h"
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000020#include "clang/AST/DeclObjC.h"
Daniel Dunbar1be1df32008-08-11 21:35:06 +000021#include "clang/Basic/LangOptions.h"
22
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000023#include "llvm/Module.h"
Daniel Dunbar35b777f2008-10-29 22:36:39 +000024#include "llvm/ADT/DenseSet.h"
Daniel Dunbar8c85fac2008-08-11 02:45:11 +000025#include "llvm/Support/IRBuilder.h"
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000026#include "llvm/Target/TargetData.h"
Daniel Dunbarace33292008-08-16 03:19:19 +000027#include <sstream>
Daniel Dunbar8c85fac2008-08-11 02:45:11 +000028
29using namespace clang;
Daniel Dunbar0a2da0f2008-09-09 01:06:48 +000030using namespace CodeGen;
Daniel Dunbar8c85fac2008-08-11 02:45:11 +000031
32namespace {
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000033
Daniel Dunbarfe131f02008-08-27 02:31:56 +000034 typedef std::vector<llvm::Constant*> ConstantVector;
35
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000036 // FIXME: We should find a nicer way to make the labels for
37 // metadata, string concatenation is lame.
38
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000039/// ObjCTypesHelper - Helper class that encapsulates lazy
40/// construction of varies types used during ObjC generation.
41class ObjCTypesHelper {
42private:
43 CodeGen::CodeGenModule &CGM;
44
Daniel Dunbaraecef4c2008-10-17 03:24:53 +000045 llvm::Function *MessageSendFn, *MessageSendStretFn, *MessageSendFpretFn;
46 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn,
47 *MessageSendSuperFpretFn;
Daniel Dunbar5eec6142008-08-12 03:39:23 +000048
Daniel Dunbardaf4ad42008-08-12 00:12:39 +000049public:
Daniel Dunbarb050fa62008-08-21 04:36:09 +000050 const llvm::Type *ShortTy, *IntTy, *LongTy;
51 const llvm::Type *Int8PtrTy;
Daniel Dunbar5eec6142008-08-12 03:39:23 +000052
Daniel Dunbar6fa3daf2008-08-12 05:28:47 +000053 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
54 const llvm::Type *ObjectPtrTy;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000055 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar6fa3daf2008-08-12 05:28:47 +000056 const llvm::Type *SelectorPtrTy;
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000057 /// ProtocolPtrTy - LLVM type for external protocol handles
58 /// (typeof(Protocol))
59 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000060
Daniel Dunbar0ed60b02008-08-30 03:02:31 +000061 // SuperCTy - clang type for struct objc_super.
62 QualType SuperCTy;
63 // SuperPtrCTy - clang type for struct objc_super *.
64 QualType SuperPtrCTy;
65
Daniel Dunbar15245e52008-08-23 04:28:29 +000066 /// SuperTy - LLVM type for struct objc_super.
67 const llvm::StructType *SuperTy;
Daniel Dunbar87062ff2008-08-23 09:25:55 +000068 /// SuperPtrTy - LLVM type for struct objc_super *.
69 const llvm::Type *SuperPtrTy;
Daniel Dunbar15245e52008-08-23 04:28:29 +000070
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000071 /// SymtabTy - LLVM type for struct objc_symtab.
72 const llvm::StructType *SymtabTy;
Daniel Dunbarb050fa62008-08-21 04:36:09 +000073 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
74 const llvm::Type *SymtabPtrTy;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +000075 /// ModuleTy - LLVM type for struct objc_module.
76 const llvm::StructType *ModuleTy;
Daniel Dunbar5eec6142008-08-12 03:39:23 +000077
Daniel Dunbarcffcdac2008-08-13 03:21:16 +000078 /// ProtocolTy - LLVM type for struct objc_protocol.
79 const llvm::StructType *ProtocolTy;
80 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
81 const llvm::Type *ProtocolPtrTy;
82 /// ProtocolExtensionTy - LLVM type for struct
83 /// objc_protocol_extension.
84 const llvm::StructType *ProtocolExtensionTy;
85 /// ProtocolExtensionTy - LLVM type for struct
86 /// objc_protocol_extension *.
87 const llvm::Type *ProtocolExtensionPtrTy;
88 /// MethodDescriptionTy - LLVM type for struct
89 /// objc_method_description.
90 const llvm::StructType *MethodDescriptionTy;
91 /// MethodDescriptionListTy - LLVM type for struct
92 /// objc_method_description_list.
93 const llvm::StructType *MethodDescriptionListTy;
94 /// MethodDescriptionListPtrTy - LLVM type for struct
95 /// objc_method_description_list *.
96 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbara6eb6b72008-08-23 00:19:03 +000097 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
98 /// in GCC parlance).
99 const llvm::StructType *PropertyTy;
100 /// PropertyListTy - LLVM type for struct objc_property_list
101 /// (_prop_list_t in GCC parlance).
102 const llvm::StructType *PropertyListTy;
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000103 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
104 const llvm::Type *PropertyListPtrTy;
105 /// ProtocolListTy - LLVM type for struct objc_property_list.
106 const llvm::Type *ProtocolListTy;
107 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
108 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000109 /// CategoryTy - LLVM type for struct objc_category.
110 const llvm::StructType *CategoryTy;
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000111 /// ClassTy - LLVM type for struct objc_class.
112 const llvm::StructType *ClassTy;
113 /// ClassPtrTy - LLVM type for struct objc_class *.
114 const llvm::Type *ClassPtrTy;
115 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
116 const llvm::StructType *ClassExtensionTy;
117 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
118 const llvm::Type *ClassExtensionPtrTy;
119 /// CacheTy - LLVM type for struct objc_cache.
120 const llvm::Type *CacheTy;
121 /// CachePtrTy - LLVM type for struct objc_cache *.
122 const llvm::Type *CachePtrTy;
123 // IvarTy - LLVM type for struct objc_ivar.
124 const llvm::StructType *IvarTy;
125 /// IvarListTy - LLVM type for struct objc_ivar_list.
126 const llvm::Type *IvarListTy;
127 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
128 const llvm::Type *IvarListPtrTy;
129 // MethodTy - LLVM type for struct objc_method.
130 const llvm::StructType *MethodTy;
131 /// MethodListTy - LLVM type for struct objc_method_list.
132 const llvm::Type *MethodListTy;
133 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
134 const llvm::Type *MethodListPtrTy;
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000135
Daniel Dunbarf7103722008-09-24 03:38:44 +0000136 llvm::Function *GetPropertyFn, *SetPropertyFn;
Anders Carlsson58d16242008-08-31 04:05:03 +0000137 llvm::Function *EnumerationMutationFn;
Anders Carlsson9acb0a42008-09-09 10:10:21 +0000138
139 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
140 const llvm::Type *ExceptionDataTy;
141
142 /// ExceptionThrowFn - LLVM objc_exception_throw function.
143 llvm::Function *ExceptionThrowFn;
144
145 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
146 llvm::Function *ExceptionTryEnterFn;
147
148 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
149 llvm::Function *ExceptionTryExitFn;
150
151 /// ExceptionExtractFn - LLVM objc_exception_extract function.
152 llvm::Function *ExceptionExtractFn;
153
154 /// ExceptionMatchFn - LLVM objc_exception_match function.
155 llvm::Function *ExceptionMatchFn;
156
157 /// SetJmpFn - LLVM _setjmp function.
158 llvm::Function *SetJmpFn;
159
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000160public:
161 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
162 ~ObjCTypesHelper();
Daniel Dunbaraecef4c2008-10-17 03:24:53 +0000163
164
165 llvm::Function *getSendFn(bool IsSuper) {
166 return IsSuper ? MessageSendSuperFn : MessageSendFn;
167 }
168
169 llvm::Function *getSendStretFn(bool IsSuper) {
170 return IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
171 }
172
173 llvm::Function *getSendFpretFn(bool IsSuper) {
174 return IsSuper ? MessageSendSuperFpretFn : MessageSendFpretFn;
175 }
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000176};
177
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000178class CGObjCMac : public CodeGen::CGObjCRuntime {
179private:
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000180 CodeGen::CodeGenModule &CGM;
181 ObjCTypesHelper ObjCTypes;
182 /// ObjCABI - FIXME: Not sure yet.
183 unsigned ObjCABI;
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000184
Daniel Dunbar8ede0052008-08-25 06:02:07 +0000185 /// LazySymbols - Symbols to generate a lazy reference for. See
186 /// DefinedSymbols and FinishModule().
187 std::set<IdentifierInfo*> LazySymbols;
188
189 /// DefinedSymbols - External symbols which are defined by this
190 /// module. The symbols in this list and LazySymbols are used to add
191 /// special linker symbols which ensure that Objective-C modules are
192 /// linked properly.
193 std::set<IdentifierInfo*> DefinedSymbols;
194
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000195 /// ClassNames - uniqued class names.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000196 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000197
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000198 /// MethodVarNames - uniqued method variable names.
199 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
200
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000201 /// MethodVarTypes - uniqued method type signatures. We have to use
202 /// a StringMap here because have no other unique reference.
203 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
204
Daniel Dunbar12996f52008-08-26 21:51:14 +0000205 /// MethodDefinitions - map of methods which have been defined in
206 /// this translation unit.
207 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
208
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000209 /// PropertyNames - uniqued method variable names.
210 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
211
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000212 /// ClassReferences - uniqued class references.
213 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
214
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000215 /// SelectorReferences - uniqued selector references.
216 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
217
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000218 /// Protocols - Protocols for which an objc_protocol structure has
219 /// been emitted. Forward declarations are handled by creating an
220 /// empty structure whose initializer is filled in when/if defined.
221 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
222
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000223 /// DefinedProtocols - Protocols which have actually been
224 /// defined. We should not need this, see FIXME in GenerateProtocol.
225 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
226
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000227 /// DefinedClasses - List of defined classes.
228 std::vector<llvm::GlobalValue*> DefinedClasses;
229
230 /// DefinedCategories - List of defined categories.
231 std::vector<llvm::GlobalValue*> DefinedCategories;
232
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000233 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000234 /// to prevent them from being clobbered.
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000235 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000236
237 /// EmitImageInfo - Emit the image info marker used to encode some module
238 /// level information.
239 void EmitImageInfo();
240
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000241 /// EmitModuleInfo - Another marker encoding module level
242 /// information.
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000243 void EmitModuleInfo();
244
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000245 /// EmitModuleSymols - Emit module symbols, the list of defined
246 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000247 llvm::Constant *EmitModuleSymbols();
248
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000249 /// FinishModule - Write out global data structures at the end of
250 /// processing a translation unit.
251 void FinishModule();
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000252
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000253 /// EmitClassExtension - Generate the class extension structure used
254 /// to store the weak ivar layout and properties. The return value
255 /// has type ClassExtensionPtrTy.
256 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
257
258 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
259 /// for the given class.
260 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
261 const ObjCInterfaceDecl *ID);
262
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000263 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbardd851282008-08-30 05:35:15 +0000264 QualType ResultType,
265 Selector Sel,
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000266 llvm::Value *Arg0,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000267 QualType Arg0Ty,
268 bool IsSuper,
269 const CallArgList &CallArgs);
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000270
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000271 /// EmitIvarList - Emit the ivar list for the given
272 /// implementation. If ForClass is true the list of class ivars
273 /// (i.e. metaclass ivars) is emitted, otherwise the list of
274 /// interface ivars will be emitted. The return value has type
275 /// IvarListPtrTy.
276 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
277 bool ForClass,
278 const llvm::Type *InterfaceTy);
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000279
280 /// EmitMetaClass - Emit a forward reference to the class structure
281 /// for the metaclass of the given interface. The return value has
282 /// type ClassPtrTy.
283 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
284
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000285 /// EmitMetaClass - Emit a class structure for the metaclass of the
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000286 /// given implementation. The return value has type ClassPtrTy.
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000287 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
288 llvm::Constant *Protocols,
Daniel Dunbar12996f52008-08-26 21:51:14 +0000289 const llvm::Type *InterfaceTy,
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000290 const ConstantVector &Methods);
291
292 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
293
294 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000295
296 /// EmitMethodList - Emit the method list for the given
Daniel Dunbar6b57d432008-08-26 08:29:31 +0000297 /// implementation. The return value has type MethodListPtrTy.
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000298 llvm::Constant *EmitMethodList(const std::string &Name,
299 const char *Section,
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000300 const ConstantVector &Methods);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000301
302 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000303 /// method declarations.
304 /// - TypeName: The name for the type containing the methods.
305 /// - IsProtocol: True iff these methods are for a protocol.
306 /// - ClassMethds: True iff these are class methods.
307 /// - Required: When true, only "required" methods are
308 /// listed. Similarly, when false only "optional" methods are
309 /// listed. For classes this should always be true.
310 /// - begin, end: The method list to output.
311 ///
312 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000313 llvm::Constant *EmitMethodDescList(const std::string &Name,
314 const char *Section,
315 const ConstantVector &Methods);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000316
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000317 /// EmitPropertyList - Emit the given property list. The return
318 /// value has type PropertyListPtrTy.
319 llvm::Constant *EmitPropertyList(const std::string &Name,
Daniel Dunbar698d6f32008-08-28 04:38:10 +0000320 const Decl *Container,
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000321 ObjCPropertyDecl * const *begin,
322 ObjCPropertyDecl * const *end);
323
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000324 /// GetOrEmitProtocol - Get the protocol object for the given
325 /// declaration, emitting it if necessary. The return value has type
326 /// ProtocolPtrTy.
327 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
328
329 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
330 /// object for the given declaration, emitting it if needed. These
331 /// forward references will be filled in with empty bodies if no
332 /// definition is seen. The return value has type ProtocolPtrTy.
333 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
334
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000335 /// EmitProtocolExtension - Generate the protocol extension
336 /// structure used to store optional instance and class methods, and
337 /// protocol properties. The return value has type
338 /// ProtocolExtensionPtrTy.
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000339 llvm::Constant *
340 EmitProtocolExtension(const ObjCProtocolDecl *PD,
341 const ConstantVector &OptInstanceMethods,
342 const ConstantVector &OptClassMethods);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000343
344 /// EmitProtocolList - Generate the list of referenced
345 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000346 llvm::Constant *EmitProtocolList(const std::string &Name,
347 ObjCProtocolDecl::protocol_iterator begin,
348 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000349
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000350 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
351 /// for the given selector.
352 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
353
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000354 /// GetProtocolRef - Return a reference to the internal protocol
355 /// description, creating an empty one if it has not been
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000356 /// defined. The return value has type ProtocolPtrTy.
357 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000358
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000359 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000360 /// name. The return value has type char *.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000361 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +0000362
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000363 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000364 /// selector's name. The return value has type char *.
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000365 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000366 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000367 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbar1be1df32008-08-11 21:35:06 +0000368
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000369 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000370 /// selector's name. The return value has type char *.
371
372 // FIXME: This is a horrible name.
Daniel Dunbar12996f52008-08-26 21:51:14 +0000373 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000374 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000375
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000376 /// GetPropertyName - Return a unique constant for the given
377 /// name. The return value has type char *.
378 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
379
Daniel Dunbar698d6f32008-08-28 04:38:10 +0000380 // FIXME: This can be dropped once string functions are unified.
381 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
382 const Decl *Container);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000383
Daniel Dunbarace33292008-08-16 03:19:19 +0000384 /// GetNameForMethod - Return a name for the given method.
385 /// \param[out] NameOut - The return value.
386 void GetNameForMethod(const ObjCMethodDecl *OMD,
387 std::string &NameOut);
388
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000389public:
390 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000391 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000392
Daniel Dunbara04840b2008-08-23 03:46:30 +0000393 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbardd851282008-08-30 05:35:15 +0000394 QualType ResultType,
395 Selector Sel,
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000396 llvm::Value *Receiver,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000397 bool IsClassMessage,
398 const CallArgList &CallArgs);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000399
Daniel Dunbara04840b2008-08-23 03:46:30 +0000400 virtual CodeGen::RValue
401 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbardd851282008-08-30 05:35:15 +0000402 QualType ResultType,
403 Selector Sel,
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000404 const ObjCInterfaceDecl *Class,
405 llvm::Value *Receiver,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000406 bool IsClassMessage,
407 const CallArgList &CallArgs);
Daniel Dunbar434627a2008-08-16 00:25:02 +0000408
409 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000410 const ObjCInterfaceDecl *ID);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000411
412 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
413
Daniel Dunbarac93e472008-08-15 22:20:32 +0000414 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000415
Daniel Dunbarac93e472008-08-15 22:20:32 +0000416 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000417
Daniel Dunbarac93e472008-08-15 22:20:32 +0000418 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000419
420 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbar84bb85f2008-08-13 00:59:25 +0000421 const ObjCProtocolDecl *PD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000422
Daniel Dunbar84bb85f2008-08-13 00:59:25 +0000423 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000424
425 virtual llvm::Function *ModuleInitFunction();
Daniel Dunbarf7103722008-09-24 03:38:44 +0000426 virtual llvm::Function *GetPropertyGetFunction();
427 virtual llvm::Function *GetPropertySetFunction();
Anders Carlsson58d16242008-08-31 04:05:03 +0000428 virtual llvm::Function *EnumerationMutationFunction();
Anders Carlssonb01a2112008-09-09 10:04:29 +0000429
430 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
431 const ObjCAtTryStmt &S);
432 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
433 const ObjCAtThrowStmt &S);
434
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000435};
436} // end anonymous namespace
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000437
438/* *** Helper Functions *** */
439
440/// getConstantGEP() - Help routine to construct simple GEPs.
441static llvm::Constant *getConstantGEP(llvm::Constant *C,
442 unsigned idx0,
443 unsigned idx1) {
444 llvm::Value *Idxs[] = {
445 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
446 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
447 };
448 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
449}
450
451/* *** CGObjCMac Public Interface *** */
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000452
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000453CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
454 : CGM(cgm),
455 ObjCTypes(cgm),
456 ObjCABI(1)
457{
458 // FIXME: How does this get set in GCC? And what does it even mean?
459 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
460 ObjCABI = 2;
461
462 EmitImageInfo();
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000463}
464
Daniel Dunbar434627a2008-08-16 00:25:02 +0000465/// GetClass - Return a reference to the class for the given interface
466/// decl.
467llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000468 const ObjCInterfaceDecl *ID) {
469 return EmitClassRef(Builder, ID);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000470}
471
472/// GetSelector - Return the pointer to the unique'd string for this selector.
473llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar5eec6142008-08-12 03:39:23 +0000474 return EmitSelector(Builder, Sel);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000475}
476
Daniel Dunbardaf4ad42008-08-12 00:12:39 +0000477/// Generate a constant CFString object.
478/*
479 struct __builtin_CFString {
480 const int *isa; // point to __CFConstantStringClassReference
481 int flags;
482 const char *str;
483 long length;
484 };
485*/
486
487llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbardbdb9512008-08-23 18:37:06 +0000488 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000489}
490
491/// Generates a message send where the super is the receiver. This is
492/// a message send to self with special delivery semantics indicating
493/// which class's method should be called.
Daniel Dunbara04840b2008-08-23 03:46:30 +0000494CodeGen::RValue
495CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbardd851282008-08-30 05:35:15 +0000496 QualType ResultType,
497 Selector Sel,
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000498 const ObjCInterfaceDecl *Class,
499 llvm::Value *Receiver,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000500 bool IsClassMessage,
Daniel Dunbar0a2da0f2008-09-09 01:06:48 +0000501 const CodeGen::CallArgList &CallArgs) {
Daniel Dunbar15245e52008-08-23 04:28:29 +0000502 // Create and init a super structure; this is a (receiver, class)
503 // pair we will pass to objc_msgSendSuper.
504 llvm::Value *ObjCSuper =
505 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
506 llvm::Value *ReceiverAsObject =
507 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
508 CGF.Builder.CreateStore(ReceiverAsObject,
509 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbar15245e52008-08-23 04:28:29 +0000510
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000511 // If this is a class message the metaclass is passed as the target.
512 llvm::Value *Target;
513 if (IsClassMessage) {
514 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
515 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
516 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
517 Target = Super;
518 } else {
519 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
520 }
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000521 // FIXME: We shouldn't need to do this cast, rectify the ASTContext
522 // and ObjCTypes types.
523 const llvm::Type *ClassTy =
524 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000525 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000526 CGF.Builder.CreateStore(Target,
527 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
528
Daniel Dunbardd851282008-08-30 05:35:15 +0000529 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000530 ObjCSuper, ObjCTypes.SuperPtrCTy,
531 true, CallArgs);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000532}
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000533
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000534/// Generate code for a message send expression.
Daniel Dunbara04840b2008-08-23 03:46:30 +0000535CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbardd851282008-08-30 05:35:15 +0000536 QualType ResultType,
537 Selector Sel,
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +0000538 llvm::Value *Receiver,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000539 bool IsClassMessage,
540 const CallArgList &CallArgs) {
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000541 llvm::Value *Arg0 =
542 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
Daniel Dunbardd851282008-08-30 05:35:15 +0000543 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000544 Arg0, CGF.getContext().getObjCIdType(),
545 false, CallArgs);
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000546}
547
548CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbardd851282008-08-30 05:35:15 +0000549 QualType ResultType,
550 Selector Sel,
Daniel Dunbar87062ff2008-08-23 09:25:55 +0000551 llvm::Value *Arg0,
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000552 QualType Arg0Ty,
553 bool IsSuper,
554 const CallArgList &CallArgs) {
555 CallArgList ActualArgs;
Daniel Dunbar0a2da0f2008-09-09 01:06:48 +0000556 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
557 ActualArgs.push_back(std::make_pair(RValue::get(EmitSelector(CGF.Builder,
558 Sel)),
Daniel Dunbar0ed60b02008-08-30 03:02:31 +0000559 CGF.getContext().getObjCSelType()));
560 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
Daniel Dunbarac93e472008-08-15 22:20:32 +0000561
Daniel Dunbara9976a22008-09-10 07:00:50 +0000562 const llvm::FunctionType *FTy =
563 CGM.getTypes().GetFunctionType(CGCallInfo(ResultType, ActualArgs),
564 false);
Daniel Dunbaraecef4c2008-10-17 03:24:53 +0000565
566 llvm::Constant *Fn;
567 if (CGM.ReturnTypeUsesSret(ResultType)) {
568 Fn = ObjCTypes.getSendStretFn(IsSuper);
569 } else if (ResultType->isFloatingType()) {
570 // FIXME: Sadly, this is wrong. This actually depends on the
571 // architecture. This happens to be right for x86-32 though.
572 Fn = ObjCTypes.getSendFpretFn(IsSuper);
573 } else {
574 Fn = ObjCTypes.getSendFn(IsSuper);
575 }
Daniel Dunbara9976a22008-09-10 07:00:50 +0000576 Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy));
Daniel Dunbar49f5a0d2008-09-09 23:48:28 +0000577 return CGF.EmitCall(Fn, ResultType, ActualArgs);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000578}
579
580llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbar84bb85f2008-08-13 00:59:25 +0000581 const ObjCProtocolDecl *PD) {
Daniel Dunbarb3518152008-09-04 04:33:15 +0000582 // FIXME: I don't understand why gcc generates this, or where it is
583 // resolved. Investigate. Its also wasteful to look this up over and
584 // over.
585 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
586
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000587 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
588 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000589}
590
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000591void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
592 // FIXME: We shouldn't need this, the protocol decl should contain
593 // enough information to tell us whether this was a declaration or a
594 // definition.
595 DefinedProtocols.insert(PD->getIdentifier());
596
597 // If we have generated a forward reference to this protocol, emit
598 // it now. Otherwise do nothing, the protocol objects are lazily
599 // emitted.
600 if (Protocols.count(PD->getIdentifier()))
601 GetOrEmitProtocol(PD);
602}
603
604llvm::Constant *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
605 if (DefinedProtocols.count(PD->getIdentifier()))
606 return GetOrEmitProtocol(PD);
607 return GetOrEmitProtocolRef(PD);
608}
609
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000610/*
611 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
612 struct _objc_protocol {
613 struct _objc_protocol_extension *isa;
614 char *protocol_name;
615 struct _objc_protocol_list *protocol_list;
616 struct _objc__method_prototype_list *instance_methods;
617 struct _objc__method_prototype_list *class_methods
618 };
619
620 See EmitProtocolExtension().
621*/
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000622llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
623 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
624
625 // Early exit if a defining object has already been generated.
626 if (Entry && Entry->hasInitializer())
627 return Entry;
628
Daniel Dunbar8ede0052008-08-25 06:02:07 +0000629 // FIXME: I don't understand why gcc generates this, or where it is
630 // resolved. Investigate. Its also wasteful to look this up over and
631 // over.
632 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
633
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000634 const char *ProtocolName = PD->getName();
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000635
636 // Construct method lists.
637 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
638 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
639 for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
640 e = PD->instmeth_end(); i != e; ++i) {
641 ObjCMethodDecl *MD = *i;
642 llvm::Constant *C = GetMethodDescriptionConstant(MD);
643 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
644 OptInstanceMethods.push_back(C);
645 } else {
646 InstanceMethods.push_back(C);
647 }
648 }
649
650 for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
651 e = PD->classmeth_end(); i != e; ++i) {
652 ObjCMethodDecl *MD = *i;
653 llvm::Constant *C = GetMethodDescriptionConstant(MD);
654 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
655 OptClassMethods.push_back(C);
656 } else {
657 ClassMethods.push_back(C);
658 }
659 }
660
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000661 std::vector<llvm::Constant*> Values(5);
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000662 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000663 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000664 Values[2] =
665 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
666 PD->protocol_begin(),
667 PD->protocol_end());
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000668 Values[3] =
669 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_")
670 + PD->getName(),
671 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
672 InstanceMethods);
673 Values[4] =
674 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_")
675 + PD->getName(),
676 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
677 ClassMethods);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000678 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
679 Values);
680
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000681 if (Entry) {
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000682 // Already created, fix the linkage and update the initializer.
683 Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000684 Entry->setInitializer(Init);
685 } else {
686 Entry =
687 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
688 llvm::GlobalValue::InternalLinkage,
689 Init,
690 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
691 &CGM.getModule());
692 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
693 UsedGlobals.push_back(Entry);
694 // FIXME: Is this necessary? Why only for protocol?
695 Entry->setAlignment(4);
696 }
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000697
698 return Entry;
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000699}
700
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000701llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000702 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
703
704 if (!Entry) {
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000705 // We use the initializer as a marker of whether this is a forward
706 // reference or not. At module finalization we add the empty
707 // contents for protocols which were referenced but never defined.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000708 Entry =
709 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
Daniel Dunbar35b777f2008-10-29 22:36:39 +0000710 llvm::GlobalValue::ExternalLinkage,
711 0,
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000712 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
713 &CGM.getModule());
714 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
715 UsedGlobals.push_back(Entry);
716 // FIXME: Is this necessary? Why only for protocol?
717 Entry->setAlignment(4);
718 }
719
720 return Entry;
721}
722
723/*
724 struct _objc_protocol_extension {
725 uint32_t size;
726 struct objc_method_description_list *optional_instance_methods;
727 struct objc_method_description_list *optional_class_methods;
728 struct objc_property_list *instance_properties;
729 };
730*/
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000731llvm::Constant *
732CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
733 const ConstantVector &OptInstanceMethods,
734 const ConstantVector &OptClassMethods) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000735 uint64_t Size =
736 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
737 std::vector<llvm::Constant*> Values(4);
738 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000739 Values[1] =
740 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_")
741 + PD->getName(),
742 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
743 OptInstanceMethods);
744 Values[2] =
745 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_")
746 + PD->getName(),
747 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
748 OptClassMethods);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000749 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
750 PD->getName(),
Daniel Dunbar698d6f32008-08-28 04:38:10 +0000751 0,
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000752 PD->classprop_begin(),
753 PD->classprop_end());
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000754
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000755 // Return null if no extension bits are used.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000756 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
757 Values[3]->isNullValue())
758 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
759
760 llvm::Constant *Init =
761 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
762 llvm::GlobalVariable *GV =
763 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
764 llvm::GlobalValue::InternalLinkage,
765 Init,
766 (std::string("\01L_OBJC_PROTOCOLEXT_") +
767 PD->getName()),
768 &CGM.getModule());
769 // No special section, but goes in llvm.used
770 UsedGlobals.push_back(GV);
771
772 return GV;
773}
774
775/*
776 struct objc_protocol_list {
777 struct objc_protocol_list *next;
778 long count;
779 Protocol *list[];
780 };
781*/
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000782llvm::Constant *
783CGObjCMac::EmitProtocolList(const std::string &Name,
784 ObjCProtocolDecl::protocol_iterator begin,
785 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000786 std::vector<llvm::Constant*> ProtocolRefs;
787
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000788 for (; begin != end; ++begin)
789 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000790
791 // Just return null for empty protocol lists
792 if (ProtocolRefs.empty())
793 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
794
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000795 // This list is null terminated.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000796 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
797
798 std::vector<llvm::Constant*> Values(3);
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000799 // This field is only used by the runtime.
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000800 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
801 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
802 Values[2] =
803 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
804 ProtocolRefs.size()),
805 ProtocolRefs);
806
807 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
808 llvm::GlobalVariable *GV =
809 new llvm::GlobalVariable(Init->getType(), false,
810 llvm::GlobalValue::InternalLinkage,
811 Init,
Daniel Dunbar67e778b2008-08-21 21:57:41 +0000812 Name,
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000813 &CGM.getModule());
814 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
815 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
816}
817
818/*
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000819 struct _objc_property {
820 const char * const name;
821 const char * const attributes;
822 };
823
824 struct _objc_property_list {
825 uint32_t entsize; // sizeof (struct _objc_property)
826 uint32_t prop_count;
827 struct _objc_property[prop_count];
828 };
829*/
830llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
Daniel Dunbar698d6f32008-08-28 04:38:10 +0000831 const Decl *Container,
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000832 ObjCPropertyDecl * const *begin,
833 ObjCPropertyDecl * const *end) {
834 std::vector<llvm::Constant*> Properties, Prop(2);
835 for (; begin != end; ++begin) {
836 const ObjCPropertyDecl *PD = *begin;
837 Prop[0] = GetPropertyName(PD->getIdentifier());
Daniel Dunbar698d6f32008-08-28 04:38:10 +0000838 Prop[1] = GetPropertyTypeString(PD, Container);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000839 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
840 Prop));
841 }
842
843 // Return null for empty list.
844 if (Properties.empty())
845 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
846
847 unsigned PropertySize =
848 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
849 std::vector<llvm::Constant*> Values(3);
850 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
851 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
852 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
853 Properties.size());
854 Values[2] = llvm::ConstantArray::get(AT, Properties);
855 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
856
857 llvm::GlobalVariable *GV =
858 new llvm::GlobalVariable(Init->getType(), false,
859 llvm::GlobalValue::InternalLinkage,
860 Init,
861 Name,
862 &CGM.getModule());
863 // No special section on property lists?
864 UsedGlobals.push_back(GV);
865 return llvm::ConstantExpr::getBitCast(GV,
866 ObjCTypes.PropertyListPtrTy);
867
868}
869
870/*
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000871 struct objc_method_description_list {
872 int count;
873 struct objc_method_description list[];
874 };
875*/
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000876llvm::Constant *
877CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
878 std::vector<llvm::Constant*> Desc(2);
879 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
880 ObjCTypes.SelectorPtrTy);
881 Desc[1] = GetMethodVarType(MD);
882 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
883 Desc);
884}
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000885
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000886llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name,
887 const char *Section,
888 const ConstantVector &Methods) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000889 // Return null for empty list.
890 if (Methods.empty())
891 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
892
893 std::vector<llvm::Constant*> Values(2);
894 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
895 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
896 Methods.size());
897 Values[1] = llvm::ConstantArray::get(AT, Methods);
898 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
899
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000900 llvm::GlobalVariable *GV =
901 new llvm::GlobalVariable(Init->getType(), false,
902 llvm::GlobalValue::InternalLinkage,
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000903 Init, Name, &CGM.getModule());
904 GV->setSection(Section);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +0000905 UsedGlobals.push_back(GV);
906 return llvm::ConstantExpr::getBitCast(GV,
907 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000908}
909
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000910/*
911 struct _objc_category {
912 char *category_name;
913 char *class_name;
914 struct _objc_method_list *instance_methods;
915 struct _objc_method_list *class_methods;
916 struct _objc_protocol_list *protocols;
917 uint32_t size; // <rdar://4585769>
918 struct _objc_property_list *instance_properties;
919 };
920 */
Daniel Dunbarac93e472008-08-15 22:20:32 +0000921void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000922 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
923
Daniel Dunbar0cd49032008-08-26 23:03:11 +0000924 // FIXME: This is poor design, the OCD should have a pointer to the
925 // category decl. Additionally, note that Category can be null for
926 // the @implementation w/o an @interface case. Sema should just
927 // create one for us as it does for @implementation so everyone else
928 // can live life under a clear blue sky.
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000929 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
Daniel Dunbar0cd49032008-08-26 23:03:11 +0000930 const ObjCCategoryDecl *Category =
931 Interface->FindCategoryDeclaration(OCD->getIdentifier());
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000932 std::string ExtName(std::string(Interface->getName()) +
933 "_" +
934 OCD->getName());
935
Daniel Dunbar12996f52008-08-26 21:51:14 +0000936 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
937 for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
938 e = OCD->instmeth_end(); i != e; ++i) {
939 // Instance methods should always be defined.
940 InstanceMethods.push_back(GetMethodConstant(*i));
941 }
942 for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
943 e = OCD->classmeth_end(); i != e; ++i) {
944 // Class methods should always be defined.
945 ClassMethods.push_back(GetMethodConstant(*i));
946 }
947
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000948 std::vector<llvm::Constant*> Values(7);
949 Values[0] = GetClassName(OCD->getIdentifier());
950 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000951 Values[2] =
952 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
953 ExtName,
954 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
Daniel Dunbar12996f52008-08-26 21:51:14 +0000955 InstanceMethods);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +0000956 Values[3] =
957 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
958 "__OBJC,__cat_class_meth,regular,no_dead_strip",
Daniel Dunbar12996f52008-08-26 21:51:14 +0000959 ClassMethods);
Daniel Dunbarfe131f02008-08-27 02:31:56 +0000960 if (Category) {
961 Values[4] =
962 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
963 Category->protocol_begin(),
964 Category->protocol_end());
965 } else {
966 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
967 }
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000968 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar0cd49032008-08-26 23:03:11 +0000969
970 // If there is no category @interface then there can be no properties.
971 if (Category) {
972 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
Daniel Dunbar698d6f32008-08-28 04:38:10 +0000973 OCD,
Daniel Dunbar0cd49032008-08-26 23:03:11 +0000974 Category->classprop_begin(),
975 Category->classprop_end());
976 } else {
977 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
978 }
Daniel Dunbar4246a8b2008-08-22 20:34:54 +0000979
980 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
981 Values);
982
983 llvm::GlobalVariable *GV =
984 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
985 llvm::GlobalValue::InternalLinkage,
986 Init,
987 std::string("\01L_OBJC_CATEGORY_")+ExtName,
988 &CGM.getModule());
989 GV->setSection("__OBJC,__category,regular,no_dead_strip");
990 UsedGlobals.push_back(GV);
991 DefinedCategories.push_back(GV);
Daniel Dunbar8c85fac2008-08-11 02:45:11 +0000992}
993
Daniel Dunbarb050fa62008-08-21 04:36:09 +0000994// FIXME: Get from somewhere?
995enum ClassFlags {
996 eClassFlags_Factory = 0x00001,
997 eClassFlags_Meta = 0x00002,
998 // <rdr://5142207>
999 eClassFlags_HasCXXStructors = 0x02000,
1000 eClassFlags_Hidden = 0x20000,
1001 eClassFlags_ABI2_Hidden = 0x00010,
1002 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
1003};
1004
1005// <rdr://5142207&4705298&4843145>
1006static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
1007 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
1008 // FIXME: Support -fvisibility
1009 switch (attr->getVisibility()) {
1010 default:
1011 assert(0 && "Unknown visibility");
1012 return false;
1013 case VisibilityAttr::DefaultVisibility:
1014 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
1015 return false;
1016 case VisibilityAttr::HiddenVisibility:
1017 return true;
1018 }
1019 } else {
1020 return false; // FIXME: Support -fvisibility
1021 }
1022}
1023
1024/*
1025 struct _objc_class {
1026 Class isa;
1027 Class super_class;
1028 const char *name;
1029 long version;
1030 long info;
1031 long instance_size;
1032 struct _objc_ivar_list *ivars;
1033 struct _objc_method_list *methods;
1034 struct _objc_cache *cache;
1035 struct _objc_protocol_list *protocols;
1036 // Objective-C 1.0 extensions (<rdr://4585769>)
1037 const char *ivar_layout;
1038 struct _objc_class_ext *ext;
1039 };
1040
1041 See EmitClassExtension();
1042 */
1043void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar8ede0052008-08-25 06:02:07 +00001044 DefinedSymbols.insert(ID->getIdentifier());
1045
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001046 const char *ClassName = ID->getName();
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001047 // FIXME: Gross
1048 ObjCInterfaceDecl *Interface =
1049 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbar67e778b2008-08-21 21:57:41 +00001050 llvm::Constant *Protocols =
1051 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
1052 Interface->protocol_begin(),
1053 Interface->protocol_end());
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001054 const llvm::Type *InterfaceTy =
1055 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
1056 unsigned Flags = eClassFlags_Factory;
1057 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
1058
1059 // FIXME: Set CXX-structors flag.
1060 if (IsClassHidden(ID->getClassInterface()))
1061 Flags |= eClassFlags_Hidden;
1062
Daniel Dunbar12996f52008-08-26 21:51:14 +00001063 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
1064 for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
1065 e = ID->instmeth_end(); i != e; ++i) {
1066 // Instance methods should always be defined.
1067 InstanceMethods.push_back(GetMethodConstant(*i));
1068 }
1069 for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
1070 e = ID->classmeth_end(); i != e; ++i) {
1071 // Class methods should always be defined.
1072 ClassMethods.push_back(GetMethodConstant(*i));
1073 }
1074
1075 for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
1076 e = ID->propimpl_end(); i != e; ++i) {
1077 ObjCPropertyImplDecl *PID = *i;
1078
1079 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
1080 ObjCPropertyDecl *PD = PID->getPropertyDecl();
1081
1082 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
1083 if (llvm::Constant *C = GetMethodConstant(MD))
1084 InstanceMethods.push_back(C);
1085 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
1086 if (llvm::Constant *C = GetMethodConstant(MD))
1087 InstanceMethods.push_back(C);
1088 }
1089 }
1090
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001091 std::vector<llvm::Constant*> Values(12);
Daniel Dunbar12996f52008-08-26 21:51:14 +00001092 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001093 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar8ede0052008-08-25 06:02:07 +00001094 // Record a reference to the super class.
1095 LazySymbols.insert(Super->getIdentifier());
1096
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001097 Values[ 1] =
1098 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1099 ObjCTypes.ClassPtrTy);
1100 } else {
1101 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1102 }
1103 Values[ 2] = GetClassName(ID->getIdentifier());
1104 // Version is always 0.
1105 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1106 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1107 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1108 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00001109 Values[ 7] =
1110 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
1111 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbar12996f52008-08-26 21:51:14 +00001112 InstanceMethods);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001113 // cache is always NULL.
1114 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1115 Values[ 9] = Protocols;
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001116 // FIXME: Set ivar_layout
1117 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001118 Values[11] = EmitClassExtension(ID);
1119 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1120 Values);
1121
1122 llvm::GlobalVariable *GV =
1123 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1124 llvm::GlobalValue::InternalLinkage,
1125 Init,
1126 std::string("\01L_OBJC_CLASS_")+ClassName,
1127 &CGM.getModule());
1128 GV->setSection("__OBJC,__class,regular,no_dead_strip");
1129 UsedGlobals.push_back(GV);
1130 // FIXME: Why?
1131 GV->setAlignment(32);
1132 DefinedClasses.push_back(GV);
1133}
1134
1135llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
1136 llvm::Constant *Protocols,
Daniel Dunbar12996f52008-08-26 21:51:14 +00001137 const llvm::Type *InterfaceTy,
Daniel Dunbarfe131f02008-08-27 02:31:56 +00001138 const ConstantVector &Methods) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001139 const char *ClassName = ID->getName();
1140 unsigned Flags = eClassFlags_Meta;
1141 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
1142
1143 if (IsClassHidden(ID->getClassInterface()))
1144 Flags |= eClassFlags_Hidden;
1145
1146 std::vector<llvm::Constant*> Values(12);
1147 // The isa for the metaclass is the root of the hierarchy.
1148 const ObjCInterfaceDecl *Root = ID->getClassInterface();
1149 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
1150 Root = Super;
1151 Values[ 0] =
1152 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
1153 ObjCTypes.ClassPtrTy);
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001154 // The super class for the metaclass is emitted as the name of the
1155 // super class. The runtime fixes this up to point to the
1156 // *metaclass* for the super class.
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001157 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
1158 Values[ 1] =
1159 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1160 ObjCTypes.ClassPtrTy);
1161 } else {
1162 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1163 }
1164 Values[ 2] = GetClassName(ID->getIdentifier());
1165 // Version is always 0.
1166 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1167 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1168 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1169 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00001170 Values[ 7] =
1171 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
1172 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbar12996f52008-08-26 21:51:14 +00001173 Methods);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001174 // cache is always NULL.
1175 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1176 Values[ 9] = Protocols;
1177 // ivar_layout for metaclass is always NULL.
1178 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1179 // The class extension is always unused for metaclasses.
1180 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1181 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1182 Values);
1183
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +00001184 std::string Name("\01L_OBJC_METACLASS_");
1185 Name += ClassName;
1186
1187 // Check for a forward reference.
1188 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
1189 if (GV) {
1190 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1191 "Forward metaclass reference has incorrect type.");
1192 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
1193 GV->setInitializer(Init);
1194 } else {
1195 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1196 llvm::GlobalValue::InternalLinkage,
1197 Init, Name,
1198 &CGM.getModule());
1199 }
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001200 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
1201 UsedGlobals.push_back(GV);
1202 // FIXME: Why?
1203 GV->setAlignment(32);
1204
1205 return GV;
1206}
1207
Daniel Dunbarb1ee5d62008-08-25 08:19:24 +00001208llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
1209 std::string Name("\01L_OBJC_METACLASS_");
1210 Name += ID->getName();
1211
1212 // FIXME: Should we look these up somewhere other than the
1213 // module. Its a bit silly since we only generate these while
1214 // processing an implementation, so exactly one pointer would work
1215 // if know when we entered/exitted an implementation block.
1216
1217 // Check for an existing forward reference.
1218 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) {
1219 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1220 "Forward metaclass reference has incorrect type.");
1221 return GV;
1222 } else {
1223 // Generate as an external reference to keep a consistent
1224 // module. This will be patched up when we emit the metaclass.
1225 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1226 llvm::GlobalValue::ExternalLinkage,
1227 0,
1228 Name,
1229 &CGM.getModule());
1230 }
1231}
1232
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001233/*
1234 struct objc_class_ext {
1235 uint32_t size;
1236 const char *weak_ivar_layout;
1237 struct _objc_property_list *properties;
1238 };
1239*/
1240llvm::Constant *
1241CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1242 uint64_t Size =
1243 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1244
1245 std::vector<llvm::Constant*> Values(3);
1246 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001247 // FIXME: Output weak_ivar_layout string.
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001248 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00001249 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1250 ID->getName(),
Daniel Dunbar698d6f32008-08-28 04:38:10 +00001251 ID,
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00001252 ID->getClassInterface()->classprop_begin(),
1253 ID->getClassInterface()->classprop_end());
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001254
1255 // Return null if no extension bits are used.
1256 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1257 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1258
1259 llvm::Constant *Init =
1260 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1261 llvm::GlobalVariable *GV =
1262 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1263 llvm::GlobalValue::InternalLinkage,
1264 Init,
1265 (std::string("\01L_OBJC_CLASSEXT_") +
1266 ID->getName()),
1267 &CGM.getModule());
1268 // No special section, but goes in llvm.used
1269 UsedGlobals.push_back(GV);
1270
1271 return GV;
1272}
1273
1274/*
1275 struct objc_ivar {
1276 char *ivar_name;
1277 char *ivar_type;
1278 int ivar_offset;
1279 };
1280
1281 struct objc_ivar_list {
1282 int ivar_count;
1283 struct objc_ivar list[count];
1284 };
1285 */
1286llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1287 bool ForClass,
1288 const llvm::Type *InterfaceTy) {
1289 std::vector<llvm::Constant*> Ivars, Ivar(3);
1290
1291 // When emitting the root class GCC emits ivar entries for the
1292 // actual class structure. It is not clear if we need to follow this
1293 // behavior; for now lets try and get away with not doing it. If so,
1294 // the cleanest solution would be to make up an ObjCInterfaceDecl
1295 // for the class.
1296 if (ForClass)
1297 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1298
1299 const llvm::StructLayout *Layout =
1300 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1301 for (ObjCInterfaceDecl::ivar_iterator
1302 i = ID->getClassInterface()->ivar_begin(),
1303 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1304 ObjCIvarDecl *V = *i;
1305 unsigned Offset =
1306 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1307 std::string TypeStr;
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001308 Ivar[0] = GetMethodVarName(V->getIdentifier());
Daniel Dunbarc9197cd2008-10-17 20:21:44 +00001309 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, true);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001310 Ivar[1] = GetMethodVarType(TypeStr);
1311 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
Daniel Dunbarc9197cd2008-10-17 20:21:44 +00001312 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001313 }
1314
1315 // Return null for empty list.
1316 if (Ivars.empty())
1317 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1318
1319 std::vector<llvm::Constant*> Values(2);
1320 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1321 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1322 Ivars.size());
1323 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1324 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1325
1326 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1327 "\01L_OBJC_INSTANCE_VARIABLES_");
1328 llvm::GlobalVariable *GV =
1329 new llvm::GlobalVariable(Init->getType(), false,
1330 llvm::GlobalValue::InternalLinkage,
1331 Init,
1332 std::string(Prefix) + ID->getName(),
1333 &CGM.getModule());
1334 if (ForClass) {
1335 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1336 // FIXME: Why is this only here?
1337 GV->setAlignment(32);
1338 } else {
1339 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1340 }
1341 UsedGlobals.push_back(GV);
1342 return llvm::ConstantExpr::getBitCast(GV,
1343 ObjCTypes.IvarListPtrTy);
1344}
1345
1346/*
1347 struct objc_method {
1348 SEL method_name;
1349 char *method_types;
1350 void *method;
1351 };
1352
1353 struct objc_method_list {
1354 struct objc_method_list *obsolete;
1355 int count;
1356 struct objc_method methods_list[count];
1357 };
1358*/
Daniel Dunbar12996f52008-08-26 21:51:14 +00001359
1360/// GetMethodConstant - Return a struct objc_method constant for the
1361/// given method if it has been defined. The result is null if the
1362/// method has not been defined. The return value has type MethodPtrTy.
Daniel Dunbarfe131f02008-08-27 02:31:56 +00001363llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
Daniel Dunbar12996f52008-08-26 21:51:14 +00001364 // FIXME: Use DenseMap::lookup
1365 llvm::Function *Fn = MethodDefinitions[MD];
1366 if (!Fn)
1367 return 0;
1368
1369 std::vector<llvm::Constant*> Method(3);
1370 Method[0] =
1371 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1372 ObjCTypes.SelectorPtrTy);
1373 Method[1] = GetMethodVarType(MD);
1374 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
1375 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
1376}
1377
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001378llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1379 const char *Section,
Daniel Dunbarfe131f02008-08-27 02:31:56 +00001380 const ConstantVector &Methods) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001381 // Return null for empty list.
1382 if (Methods.empty())
1383 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1384
1385 std::vector<llvm::Constant*> Values(3);
1386 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1387 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1388 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1389 Methods.size());
1390 Values[2] = llvm::ConstantArray::get(AT, Methods);
1391 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1392
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001393 llvm::GlobalVariable *GV =
1394 new llvm::GlobalVariable(Init->getType(), false,
1395 llvm::GlobalValue::InternalLinkage,
1396 Init,
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001397 Name,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001398 &CGM.getModule());
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001399 GV->setSection(Section);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001400 UsedGlobals.push_back(GV);
1401 return llvm::ConstantExpr::getBitCast(GV,
1402 ObjCTypes.MethodListPtrTy);
Daniel Dunbarace33292008-08-16 03:19:19 +00001403}
1404
1405llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
Daniel Dunbarace33292008-08-16 03:19:19 +00001406 std::string Name;
1407 GetNameForMethod(OMD, Name);
1408
Daniel Dunbar3ad1f072008-09-10 04:01:49 +00001409 const llvm::FunctionType *MethodTy =
1410 CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()));
Daniel Dunbarace33292008-08-16 03:19:19 +00001411 llvm::Function *Method =
Daniel Dunbar3ad1f072008-09-10 04:01:49 +00001412 llvm::Function::Create(MethodTy,
Daniel Dunbarace33292008-08-16 03:19:19 +00001413 llvm::GlobalValue::InternalLinkage,
1414 Name,
1415 &CGM.getModule());
Daniel Dunbar12996f52008-08-26 21:51:14 +00001416 MethodDefinitions.insert(std::make_pair(OMD, Method));
Daniel Dunbarace33292008-08-16 03:19:19 +00001417
Daniel Dunbarace33292008-08-16 03:19:19 +00001418 return Method;
Daniel Dunbar8c85fac2008-08-11 02:45:11 +00001419}
1420
1421llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001422 // Abuse this interface function as a place to finalize.
1423 FinishModule();
1424
Daniel Dunbar8c85fac2008-08-11 02:45:11 +00001425 return NULL;
1426}
1427
Daniel Dunbarf7103722008-09-24 03:38:44 +00001428llvm::Function *CGObjCMac::GetPropertyGetFunction() {
1429 return ObjCTypes.GetPropertyFn;
1430}
1431
1432llvm::Function *CGObjCMac::GetPropertySetFunction() {
1433 return ObjCTypes.SetPropertyFn;
1434}
1435
Anders Carlsson58d16242008-08-31 04:05:03 +00001436llvm::Function *CGObjCMac::EnumerationMutationFunction()
1437{
1438 return ObjCTypes.EnumerationMutationFn;
1439}
1440
Daniel Dunbar83544842008-09-28 01:03:14 +00001441/*
1442
1443Objective-C setjmp-longjmp (sjlj) Exception Handling
1444--
1445
1446The basic framework for a @try-catch-finally is as follows:
1447{
1448 objc_exception_data d;
1449 id _rethrow = null;
1450
1451 objc_exception_try_enter(&d);
1452 if (!setjmp(d.jmp_buf)) {
1453 ... try body ...
1454 } else {
1455 // exception path
1456 id _caught = objc_exception_extract(&d);
1457
1458 // enter new try scope for handlers
1459 if (!setjmp(d.jmp_buf)) {
1460 ... match exception and execute catch blocks ...
1461
1462 // fell off end, rethrow.
1463 _rethrow = _caught;
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001464 ... jump-through-finally to finally_rethrow ...
Daniel Dunbar83544842008-09-28 01:03:14 +00001465 } else {
1466 // exception in catch block
1467 _rethrow = objc_exception_extract(&d);
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001468 ... jump-through-finally_no_exit to finally_rethrow ...
Daniel Dunbar83544842008-09-28 01:03:14 +00001469 }
1470 }
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001471 ... jump-through-finally to finally_end ...
Daniel Dunbar83544842008-09-28 01:03:14 +00001472
1473finally:
1474 // match either the initial try_enter or the catch try_enter,
1475 // depending on the path followed.
1476 objc_exception_try_exit(&d);
1477finally_no_exit:
1478 ... finally block ....
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001479 ... dispatch to finally destination ...
1480
1481finally_rethrow:
1482 objc_exception_throw(_rethrow);
1483
1484finally_end:
Daniel Dunbar83544842008-09-28 01:03:14 +00001485}
1486
1487This framework differs slightly from the one gcc uses, in that gcc
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001488uses _rethrow to determine if objc_exception_try_exit should be called
1489and if the object should be rethrown. This breaks in the face of
1490throwing nil and introduces unnecessary branches.
Daniel Dunbar83544842008-09-28 01:03:14 +00001491
1492We specialize this framework for a few particular circumstances:
1493
1494 - If there are no catch blocks, then we avoid emitting the second
1495 exception handling context.
1496
1497 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
1498 e)) we avoid emitting the code to rethrow an uncaught exception.
1499
1500 - FIXME: If there is no @finally block we can do a few more
1501 simplifications.
1502
1503Rethrows and Jumps-Through-Finally
1504--
1505
1506Support for implicit rethrows and jumping through the finally block is
1507handled by storing the current exception-handling context in
1508ObjCEHStack.
1509
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001510In order to implement proper @finally semantics, we support one basic
1511mechanism for jumping through the finally block to an arbitrary
1512destination. Constructs which generate exits from a @try or @catch
1513block use this mechanism to implement the proper semantics by chaining
1514jumps, as necessary.
1515
1516This mechanism works like the one used for indirect goto: we
1517arbitrarily assign an ID to each destination and store the ID for the
1518destination in a variable prior to entering the finally block. At the
1519end of the finally block we simply create a switch to the proper
1520destination.
1521
Daniel Dunbar83544842008-09-28 01:03:14 +00001522*/
1523
Anders Carlssonb01a2112008-09-09 10:04:29 +00001524void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001525 const ObjCAtTryStmt &S) {
1526 // Create various blocks we refer to for handling @finally.
1527 llvm::BasicBlock *FinallyBlock = llvm::BasicBlock::Create("finally");
1528 llvm::BasicBlock *FinallyNoExit = llvm::BasicBlock::Create("finally.noexit");
1529 llvm::BasicBlock *FinallyRethrow = llvm::BasicBlock::Create("finally.throw");
1530 llvm::BasicBlock *FinallyEnd = llvm::BasicBlock::Create("finally.end");
1531 llvm::Value *DestCode =
1532 CGF.CreateTempAlloca(llvm::Type::Int32Ty, "finally.dst");
1533
1534 // Generate jump code. Done here so we can directly add things to
1535 // the switch instruction.
1536 llvm::BasicBlock *FinallyJump = llvm::BasicBlock::Create("finally.jump");
1537 llvm::SwitchInst *FinallySwitch =
1538 llvm::SwitchInst::Create(new llvm::LoadInst(DestCode, "", FinallyJump),
1539 FinallyEnd, 10, FinallyJump);
1540
1541 // Push an EH context entry, used for handling rethrows and jumps
1542 // through finally.
1543 CodeGenFunction::ObjCEHEntry EHEntry(FinallyBlock, FinallyNoExit,
1544 FinallySwitch, DestCode);
1545 CGF.ObjCEHStack.push_back(&EHEntry);
1546
1547 // Allocate memory for the exception data and rethrow pointer.
Anders Carlssonfca6c292008-09-09 17:59:25 +00001548 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
1549 "exceptiondata.ptr");
Daniel Dunbar35b777f2008-10-29 22:36:39 +00001550 llvm::Value *RethrowPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy,
1551 "_rethrow");
Anders Carlssonfca6c292008-09-09 17:59:25 +00001552
1553 // Enter a new try block and call setjmp.
1554 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
1555 llvm::Value *JmpBufPtr = CGF.Builder.CreateStructGEP(ExceptionData, 0,
1556 "jmpbufarray");
1557 JmpBufPtr = CGF.Builder.CreateStructGEP(JmpBufPtr, 0, "tmp");
1558 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
1559 JmpBufPtr, "result");
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001560
Anders Carlssonfca6c292008-09-09 17:59:25 +00001561 llvm::BasicBlock *TryBlock = llvm::BasicBlock::Create("try");
Daniel Dunbar0ac66f72008-09-27 23:30:04 +00001562 llvm::BasicBlock *TryHandler = llvm::BasicBlock::Create("try.handler");
Daniel Dunbarbe56f012008-10-02 17:05:36 +00001563 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(SetJmpResult, "threw"),
Daniel Dunbar0ac66f72008-09-27 23:30:04 +00001564 TryHandler, TryBlock);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001565
1566 // Emit the @try block.
1567 CGF.EmitBlock(TryBlock);
1568 CGF.EmitStmt(S.getTryBody());
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001569 CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001570
1571 // Emit the "exception in @try" block.
Daniel Dunbar0ac66f72008-09-27 23:30:04 +00001572 CGF.EmitBlock(TryHandler);
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001573
1574 // Retrieve the exception object. We may emit multiple blocks but
1575 // nothing can cross this so the value is already in SSA form.
1576 llvm::Value *Caught = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
1577 ExceptionData,
1578 "caught");
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001579 EHEntry.Exception = Caught;
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001580 if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) {
1581 // Enter a new exception try block (in case a @catch block throws
1582 // an exception).
Anders Carlssonfca6c292008-09-09 17:59:25 +00001583 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData);
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001584
Anders Carlssonfca6c292008-09-09 17:59:25 +00001585 llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn,
1586 JmpBufPtr, "result");
Daniel Dunbarbe56f012008-10-02 17:05:36 +00001587 llvm::Value *Threw = CGF.Builder.CreateIsNotNull(SetJmpResult, "threw");
Anders Carlssonfca6c292008-09-09 17:59:25 +00001588
1589 llvm::BasicBlock *CatchBlock = llvm::BasicBlock::Create("catch");
Daniel Dunbar0ac66f72008-09-27 23:30:04 +00001590 llvm::BasicBlock *CatchHandler = llvm::BasicBlock::Create("catch.handler");
1591 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001592
1593 CGF.EmitBlock(CatchBlock);
1594
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001595 // Handle catch list. As a special case we check if everything is
1596 // matched and avoid generating code for falling off the end if
1597 // so.
1598 bool AllMatched = false;
Anders Carlssonfca6c292008-09-09 17:59:25 +00001599 for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001600 llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("catch");
Anders Carlssonfca6c292008-09-09 17:59:25 +00001601
Anders Carlsson75d86732008-09-11 09:15:33 +00001602 const DeclStmt *CatchParam =
1603 cast_or_null<DeclStmt>(CatchStmt->getCatchParamStmt());
Daniel Dunbar7a68b452008-09-27 07:36:24 +00001604 const VarDecl *VD = 0;
1605 const PointerType *PT = 0;
1606
Anders Carlssonfca6c292008-09-09 17:59:25 +00001607 // catch(...) always matches.
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001608 if (!CatchParam) {
1609 AllMatched = true;
1610 } else {
Ted Kremenekf41e9f72008-10-06 20:58:56 +00001611 VD = cast<VarDecl>(CatchParam->getSolitaryDecl());
Daniel Dunbar7a68b452008-09-27 07:36:24 +00001612 PT = VD->getType()->getAsPointerType();
Anders Carlssonfca6c292008-09-09 17:59:25 +00001613
Daniel Dunbard04c9352008-09-27 22:21:14 +00001614 // catch(id e) always matches.
1615 // FIXME: For the time being we also match id<X>; this should
1616 // be rejected by Sema instead.
1617 if ((PT && CGF.getContext().isObjCIdType(PT->getPointeeType())) ||
1618 VD->getType()->isObjCQualifiedIdType())
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001619 AllMatched = true;
Anders Carlssonfca6c292008-09-09 17:59:25 +00001620 }
1621
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001622 if (AllMatched) {
Anders Carlsson75d86732008-09-11 09:15:33 +00001623 if (CatchParam) {
1624 CGF.EmitStmt(CatchParam);
Daniel Dunbar7a68b452008-09-27 07:36:24 +00001625 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(VD));
Anders Carlsson75d86732008-09-11 09:15:33 +00001626 }
Anders Carlsson1f4acc32008-09-11 08:21:54 +00001627
Anders Carlsson75d86732008-09-11 09:15:33 +00001628 CGF.EmitStmt(CatchStmt->getCatchBody());
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001629 CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001630 break;
1631 }
1632
Daniel Dunbar7a68b452008-09-27 07:36:24 +00001633 assert(PT && "Unexpected non-pointer type in @catch");
1634 QualType T = PT->getPointeeType();
Anders Carlssona4519172008-09-11 06:35:14 +00001635 const ObjCInterfaceType *ObjCType = T->getAsObjCInterfaceType();
Anders Carlssonfca6c292008-09-09 17:59:25 +00001636 assert(ObjCType && "Catch parameter must have Objective-C type!");
1637
1638 // Check if the @catch block matches the exception object.
1639 llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl());
1640
Anders Carlssonfca6c292008-09-09 17:59:25 +00001641 llvm::Value *Match = CGF.Builder.CreateCall2(ObjCTypes.ExceptionMatchFn,
1642 Class, Caught, "match");
Anders Carlssonfca6c292008-09-09 17:59:25 +00001643
1644 llvm::BasicBlock *MatchedBlock = llvm::BasicBlock::Create("matched");
1645
Daniel Dunbarbe56f012008-10-02 17:05:36 +00001646 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
Daniel Dunbar0ac66f72008-09-27 23:30:04 +00001647 MatchedBlock, NextCatchBlock);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001648
1649 // Emit the @catch block.
1650 CGF.EmitBlock(MatchedBlock);
Daniel Dunbar83544842008-09-28 01:03:14 +00001651 CGF.EmitStmt(CatchParam);
1652
1653 llvm::Value *Tmp =
1654 CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()),
1655 "tmp");
1656 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(VD));
Anders Carlsson75d86732008-09-11 09:15:33 +00001657
1658 CGF.EmitStmt(CatchStmt->getCatchBody());
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001659 CGF.EmitJumpThroughFinally(&EHEntry, FinallyEnd);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001660
1661 CGF.EmitBlock(NextCatchBlock);
1662 }
1663
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001664 if (!AllMatched) {
1665 // None of the handlers caught the exception, so store it to be
1666 // rethrown at the end of the @finally block.
1667 CGF.Builder.CreateStore(Caught, RethrowPtr);
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001668 CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow);
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001669 }
1670
1671 // Emit the exception handler for the @catch blocks.
Daniel Dunbar0ac66f72008-09-27 23:30:04 +00001672 CGF.EmitBlock(CatchHandler);
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001673 CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn,
1674 ExceptionData),
1675 RethrowPtr);
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001676 CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);
Daniel Dunbar4655e2e2008-09-27 07:03:52 +00001677 } else {
Anders Carlssonfca6c292008-09-09 17:59:25 +00001678 CGF.Builder.CreateStore(Caught, RethrowPtr);
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001679 CGF.EmitJumpThroughFinally(&EHEntry, FinallyRethrow, false);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001680 }
1681
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001682 // Pop the exception-handling stack entry. It is important to do
1683 // this now, because the code in the @finally block is not in this
1684 // context.
1685 CGF.ObjCEHStack.pop_back();
1686
Anders Carlssonfca6c292008-09-09 17:59:25 +00001687 // Emit the @finally block.
1688 CGF.EmitBlock(FinallyBlock);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001689 CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData);
Daniel Dunbar7a68b452008-09-27 07:36:24 +00001690
1691 CGF.EmitBlock(FinallyNoExit);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001692 if (const ObjCAtFinallyStmt* FinallyStmt = S.getFinallyStmt())
1693 CGF.EmitStmt(FinallyStmt->getFinallyBody());
1694
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001695 CGF.EmitBlock(FinallyJump);
1696
1697 CGF.EmitBlock(FinallyRethrow);
1698 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn,
1699 CGF.Builder.CreateLoad(RethrowPtr));
Daniel Dunbar0ac66f72008-09-27 23:30:04 +00001700 CGF.Builder.CreateUnreachable();
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001701
1702 CGF.EmitBlock(FinallyEnd);
Anders Carlssonb01a2112008-09-09 10:04:29 +00001703}
1704
1705void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001706 const ObjCAtThrowStmt &S) {
Anders Carlsson05d7be72008-09-09 16:16:55 +00001707 llvm::Value *ExceptionAsObject;
1708
1709 if (const Expr *ThrowExpr = S.getThrowExpr()) {
1710 llvm::Value *Exception = CGF.EmitScalarExpr(ThrowExpr);
1711 ExceptionAsObject =
1712 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy, "tmp");
1713 } else {
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001714 assert((!CGF.ObjCEHStack.empty() && CGF.ObjCEHStack.back()->Exception) &&
Daniel Dunbar83544842008-09-28 01:03:14 +00001715 "Unexpected rethrow outside @catch block.");
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001716 ExceptionAsObject = CGF.ObjCEHStack.back()->Exception;
Anders Carlsson05d7be72008-09-09 16:16:55 +00001717 }
1718
1719 CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, ExceptionAsObject);
Anders Carlssonfca6c292008-09-09 17:59:25 +00001720 CGF.Builder.CreateUnreachable();
1721 CGF.EmitBlock(llvm::BasicBlock::Create("bb"));
Anders Carlssonb01a2112008-09-09 10:04:29 +00001722}
1723
Daniel Dunbare9900eb2008-09-30 01:06:03 +00001724void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E,
1725 llvm::BasicBlock *Dst,
1726 bool ExecuteTryExit) {
1727 llvm::BasicBlock *Src = Builder.GetInsertBlock();
1728
1729 if (isDummyBlock(Src))
1730 return;
1731
1732 // Find the destination code for this block. We always use 0 for the
1733 // fallthrough block (default destination).
1734 llvm::SwitchInst *SI = E->FinallySwitch;
1735 llvm::ConstantInt *ID;
1736 if (Dst == SI->getDefaultDest()) {
1737 ID = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
1738 } else {
1739 ID = SI->findCaseDest(Dst);
1740 if (!ID) {
1741 // No code found, get a new unique one by just using the number
1742 // of switch successors.
1743 ID = llvm::ConstantInt::get(llvm::Type::Int32Ty, SI->getNumSuccessors());
1744 SI->addCase(ID, Dst);
1745 }
1746 }
1747
1748 // Set the destination code and branch.
1749 Builder.CreateStore(ID, E->DestCode);
1750 Builder.CreateBr(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit);
1751}
1752
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001753/* *** Private Interface *** */
1754
1755/// EmitImageInfo - Emit the image info marker used to encode some module
1756/// level information.
1757///
1758/// See: <rdr://4810609&4810587&4810587>
1759/// struct IMAGE_INFO {
1760/// unsigned version;
1761/// unsigned flags;
1762/// };
1763enum ImageInfoFlags {
1764 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1765 eImageInfo_GarbageCollected = (1 << 1),
1766 eImageInfo_GCOnly = (1 << 2)
1767};
1768
1769void CGObjCMac::EmitImageInfo() {
1770 unsigned version = 0; // Version is unused?
1771 unsigned flags = 0;
1772
1773 // FIXME: Fix and continue?
1774 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1775 flags |= eImageInfo_GarbageCollected;
1776 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1777 flags |= eImageInfo_GCOnly;
1778
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001779 // Emitted as int[2];
1780 llvm::Constant *values[2] = {
1781 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1782 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1783 };
1784 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001785 llvm::GlobalVariable *GV =
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001786 new llvm::GlobalVariable(AT, true,
1787 llvm::GlobalValue::InternalLinkage,
1788 llvm::ConstantArray::get(AT, values, 2),
1789 "\01L_OBJC_IMAGE_INFO",
1790 &CGM.getModule());
1791
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00001792 if (ObjCABI == 1) {
1793 GV->setSection("__OBJC, __image_info,regular");
1794 } else {
1795 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1796 }
Daniel Dunbar1be1df32008-08-11 21:35:06 +00001797
1798 UsedGlobals.push_back(GV);
1799}
1800
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001801
1802// struct objc_module {
1803// unsigned long version;
1804// unsigned long size;
1805// const char *name;
1806// Symtab symtab;
1807// };
1808
1809// FIXME: Get from somewhere
1810static const int ModuleVersion = 7;
1811
1812void CGObjCMac::EmitModuleInfo() {
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001813 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1814
1815 std::vector<llvm::Constant*> Values(4);
1816 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1817 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbarac93e472008-08-15 22:20:32 +00001818 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001819 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001820 Values[3] = EmitModuleSymbols();
1821
1822 llvm::GlobalVariable *GV =
1823 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1824 llvm::GlobalValue::InternalLinkage,
1825 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1826 Values),
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001827 "\01L_OBJC_MODULES",
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001828 &CGM.getModule());
1829 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1830 UsedGlobals.push_back(GV);
1831}
1832
1833llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001834 unsigned NumClasses = DefinedClasses.size();
1835 unsigned NumCategories = DefinedCategories.size();
1836
Daniel Dunbar8ede0052008-08-25 06:02:07 +00001837 // Return null if no symbols were defined.
1838 if (!NumClasses && !NumCategories)
1839 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
1840
1841 std::vector<llvm::Constant*> Values(5);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001842 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1843 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1844 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1845 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1846
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001847 // The runtime expects exactly the list of defined classes followed
1848 // by the list of defined categories, in a single array.
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001849 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001850 for (unsigned i=0; i<NumClasses; i++)
1851 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1852 ObjCTypes.Int8PtrTy);
1853 for (unsigned i=0; i<NumCategories; i++)
1854 Symbols[NumClasses + i] =
1855 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1856 ObjCTypes.Int8PtrTy);
1857
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001858 Values[4] =
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00001859 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001860 NumClasses + NumCategories),
1861 Symbols);
1862
1863 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1864
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001865 llvm::GlobalVariable *GV =
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001866 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001867 llvm::GlobalValue::InternalLinkage,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001868 Init,
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001869 "\01L_OBJC_SYMBOLS",
1870 &CGM.getModule());
1871 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1872 UsedGlobals.push_back(GV);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001873 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1874}
1875
1876llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1877 const ObjCInterfaceDecl *ID) {
Daniel Dunbar8ede0052008-08-25 06:02:07 +00001878 LazySymbols.insert(ID->getIdentifier());
1879
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001880 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1881
1882 if (!Entry) {
1883 llvm::Constant *Casted =
1884 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1885 ObjCTypes.ClassPtrTy);
1886 Entry =
1887 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1888 llvm::GlobalValue::InternalLinkage,
1889 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1890 &CGM.getModule());
1891 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1892 UsedGlobals.push_back(Entry);
1893 }
1894
1895 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001896}
1897
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001898llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1899 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1900
1901 if (!Entry) {
1902 llvm::Constant *Casted =
1903 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1904 ObjCTypes.SelectorPtrTy);
1905 Entry =
1906 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1907 llvm::GlobalValue::InternalLinkage,
1908 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1909 &CGM.getModule());
1910 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1911 UsedGlobals.push_back(Entry);
1912 }
1913
1914 return Builder.CreateLoad(Entry, false, "tmp");
1915}
1916
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001917llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1918 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001919
1920 if (!Entry) {
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001921 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001922 Entry =
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001923 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001924 llvm::GlobalValue::InternalLinkage,
1925 C, "\01L_OBJC_CLASS_NAME_",
1926 &CGM.getModule());
1927 Entry->setSection("__TEXT,__cstring,cstring_literals");
1928 UsedGlobals.push_back(Entry);
1929 }
1930
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001931 return getConstantGEP(Entry, 0, 0);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00001932}
1933
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001934llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1935 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1936
1937 if (!Entry) {
1938 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1939 Entry =
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001940 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001941 llvm::GlobalValue::InternalLinkage,
1942 C, "\01L_OBJC_METH_VAR_NAME_",
1943 &CGM.getModule());
1944 Entry->setSection("__TEXT,__cstring,cstring_literals");
1945 UsedGlobals.push_back(Entry);
1946 }
1947
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001948 return getConstantGEP(Entry, 0, 0);
1949}
1950
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001951// FIXME: Merge into a single cstring creation function.
1952llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1953 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1954}
1955
1956// FIXME: Merge into a single cstring creation function.
1957llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1958 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1959}
1960
1961llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1962 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001963
1964 if (!Entry) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001965 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00001966 Entry =
1967 new llvm::GlobalVariable(C->getType(), false,
1968 llvm::GlobalValue::InternalLinkage,
1969 C, "\01L_OBJC_METH_VAR_TYPE_",
1970 &CGM.getModule());
1971 Entry->setSection("__TEXT,__cstring,cstring_literals");
1972 UsedGlobals.push_back(Entry);
1973 }
1974
1975 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar5eec6142008-08-12 03:39:23 +00001976}
1977
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001978// FIXME: Merge into a single cstring creation function.
Daniel Dunbar12996f52008-08-26 21:51:14 +00001979llvm::Constant *CGObjCMac::GetMethodVarType(const ObjCMethodDecl *D) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001980 std::string TypeStr;
Daniel Dunbar12996f52008-08-26 21:51:14 +00001981 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
1982 TypeStr);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00001983 return GetMethodVarType(TypeStr);
1984}
1985
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00001986// FIXME: Merge into a single cstring creation function.
1987llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1988 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1989
1990 if (!Entry) {
1991 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1992 Entry =
1993 new llvm::GlobalVariable(C->getType(), false,
1994 llvm::GlobalValue::InternalLinkage,
1995 C, "\01L_OBJC_PROP_NAME_ATTR_",
1996 &CGM.getModule());
1997 Entry->setSection("__TEXT,__cstring,cstring_literals");
1998 UsedGlobals.push_back(Entry);
1999 }
2000
2001 return getConstantGEP(Entry, 0, 0);
2002}
2003
2004// FIXME: Merge into a single cstring creation function.
Daniel Dunbar698d6f32008-08-28 04:38:10 +00002005// FIXME: This Decl should be more precise.
2006llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
2007 const Decl *Container) {
2008 std::string TypeStr;
2009 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00002010 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
2011}
2012
Daniel Dunbarace33292008-08-16 03:19:19 +00002013void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
2014 std::string &NameOut) {
2015 // FIXME: Find the mangling GCC uses.
2016 std::stringstream s;
2017 s << (D->isInstance() ? "-" : "+");
2018 s << "[";
2019 s << D->getClassInterface()->getName();
2020 s << " ";
2021 s << D->getSelector().getName();
2022 s << "]";
2023 NameOut = s.str();
2024}
2025
Daniel Dunbar1be1df32008-08-11 21:35:06 +00002026void CGObjCMac::FinishModule() {
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00002027 EmitModuleInfo();
2028
Daniel Dunbar35b777f2008-10-29 22:36:39 +00002029 // Emit the dummy bodies for any protocols which were referenced but
2030 // never defined.
2031 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
2032 i = Protocols.begin(), e = Protocols.end(); i != e; ++i) {
2033 if (i->second->hasInitializer())
2034 continue;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00002035
Daniel Dunbar35b777f2008-10-29 22:36:39 +00002036 std::vector<llvm::Constant*> Values(5);
2037 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2038 Values[1] = GetClassName(i->first);
2039 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2040 Values[3] = Values[4] =
2041 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
2042 i->second->setLinkage(llvm::GlobalValue::InternalLinkage);
2043 i->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2044 Values));
2045 }
2046
2047 std::vector<llvm::Constant*> Used;
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00002048 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbar1be1df32008-08-11 21:35:06 +00002049 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002050 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbar1be1df32008-08-11 21:35:06 +00002051 }
2052
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002053 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbar1be1df32008-08-11 21:35:06 +00002054 llvm::GlobalValue *GV =
2055 new llvm::GlobalVariable(AT, false,
2056 llvm::GlobalValue::AppendingLinkage,
2057 llvm::ConstantArray::get(AT, Used),
2058 "llvm.used",
2059 &CGM.getModule());
2060
2061 GV->setSection("llvm.metadata");
Daniel Dunbar8ede0052008-08-25 06:02:07 +00002062
2063 // Add assembler directives to add lazy undefined symbol references
2064 // for classes which are referenced but not defined. This is
2065 // important for correct linker interaction.
2066
2067 // FIXME: Uh, this isn't particularly portable.
2068 std::stringstream s;
2069 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
2070 e = LazySymbols.end(); i != e; ++i) {
2071 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
2072 }
2073 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
2074 e = DefinedSymbols.end(); i != e; ++i) {
Daniel Dunbar698d6f32008-08-28 04:38:10 +00002075 s << "\t.objc_class_name_" << (*i)->getName() << "=0\n"
Daniel Dunbar8ede0052008-08-25 06:02:07 +00002076 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
2077 }
2078 CGM.getModule().appendModuleInlineAsm(s.str());
Daniel Dunbar1be1df32008-08-11 21:35:06 +00002079}
2080
2081/* *** */
2082
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00002083ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbardbdb9512008-08-23 18:37:06 +00002084 : CGM(cgm)
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00002085{
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00002086 CodeGen::CodeGenTypes &Types = CGM.getTypes();
2087 ASTContext &Ctx = CGM.getContext();
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002088
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002089 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002090 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00002091 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002092 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
2093
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00002094 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
2095 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002096
2097 // FIXME: It would be nice to unify this with the opaque type, so
2098 // that the IR comes out a bit cleaner.
2099 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
2100 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbarb8fe21b2008-08-12 06:48:42 +00002101
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002102 MethodDescriptionTy =
2103 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002104 Int8PtrTy,
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002105 NULL);
2106 CGM.getModule().addTypeName("struct._objc_method_description",
2107 MethodDescriptionTy);
2108
2109 MethodDescriptionListTy =
2110 llvm::StructType::get(IntTy,
2111 llvm::ArrayType::get(MethodDescriptionTy, 0),
2112 NULL);
2113 CGM.getModule().addTypeName("struct._objc_method_description_list",
2114 MethodDescriptionListTy);
2115 MethodDescriptionListPtrTy =
2116 llvm::PointerType::getUnqual(MethodDescriptionListTy);
2117
Daniel Dunbara6eb6b72008-08-23 00:19:03 +00002118 PropertyTy = llvm::StructType::get(Int8PtrTy,
2119 Int8PtrTy,
2120 NULL);
2121 CGM.getModule().addTypeName("struct._objc_property",
2122 PropertyTy);
2123
2124 PropertyListTy = llvm::StructType::get(IntTy,
2125 IntTy,
2126 llvm::ArrayType::get(PropertyTy, 0),
2127 NULL);
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002128 CGM.getModule().addTypeName("struct._objc_property_list",
2129 PropertyListTy);
2130 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
2131
2132 // Protocol description structures
2133
2134 ProtocolExtensionTy =
2135 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
2136 llvm::PointerType::getUnqual(MethodDescriptionListTy),
2137 llvm::PointerType::getUnqual(MethodDescriptionListTy),
2138 PropertyListPtrTy,
2139 NULL);
2140 CGM.getModule().addTypeName("struct._objc_protocol_extension",
2141 ProtocolExtensionTy);
2142 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
2143
Daniel Dunbar35b777f2008-10-29 22:36:39 +00002144 // Handle recursive construction of Protocol and ProtocolList types
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002145
2146 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
2147 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
2148
2149 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
2150 LongTy,
2151 llvm::ArrayType::get(ProtocolTyHolder, 0),
2152 NULL);
2153 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
2154
2155 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002156 Int8PtrTy,
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002157 llvm::PointerType::getUnqual(ProtocolListTyHolder),
2158 MethodDescriptionListPtrTy,
2159 MethodDescriptionListPtrTy,
2160 NULL);
2161 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
2162
2163 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
2164 CGM.getModule().addTypeName("struct._objc_protocol_list",
2165 ProtocolListTy);
2166 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
2167
2168 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
2169 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
2170 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002171
2172 // Class description structures
2173
2174 IvarTy = llvm::StructType::get(Int8PtrTy,
2175 Int8PtrTy,
2176 IntTy,
2177 NULL);
2178 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
2179
2180 IvarListTy = llvm::OpaqueType::get();
2181 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
2182 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
2183
2184 MethodTy = llvm::StructType::get(SelectorPtrTy,
2185 Int8PtrTy,
2186 Int8PtrTy,
2187 NULL);
2188 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
2189
2190 MethodListTy = llvm::OpaqueType::get();
2191 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
2192 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
2193
2194 CacheTy = llvm::OpaqueType::get();
2195 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
2196 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
2197
2198 ClassExtensionTy =
2199 llvm::StructType::get(IntTy,
2200 Int8PtrTy,
2201 PropertyListPtrTy,
2202 NULL);
2203 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
2204 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
2205
2206 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
2207
2208 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
2209 llvm::PointerType::getUnqual(ClassTyHolder),
2210 Int8PtrTy,
2211 LongTy,
2212 LongTy,
2213 LongTy,
2214 IvarListPtrTy,
2215 MethodListPtrTy,
2216 CachePtrTy,
2217 ProtocolListPtrTy,
2218 Int8PtrTy,
2219 ClassExtensionPtrTy,
2220 NULL);
2221 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
2222
2223 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
2224 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
2225 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
2226
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00002227 CategoryTy = llvm::StructType::get(Int8PtrTy,
2228 Int8PtrTy,
2229 MethodListPtrTy,
2230 MethodListPtrTy,
2231 ProtocolListPtrTy,
2232 IntTy,
2233 PropertyListPtrTy,
2234 NULL);
2235 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
2236
Daniel Dunbar0ed60b02008-08-30 03:02:31 +00002237 // I'm not sure I like this. The implicit coordination is a bit
2238 // gross. We should solve this in a reasonable fashion because this
2239 // is a pretty common task (match some runtime data structure with
2240 // an LLVM data structure).
2241
2242 // FIXME: This is leaked.
2243 // FIXME: Merge with rewriter code?
2244 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
2245 SourceLocation(),
Ted Kremenek2c984042008-09-05 01:34:33 +00002246 &Ctx.Idents.get("_objc_super"));
Daniel Dunbar0ed60b02008-08-30 03:02:31 +00002247 FieldDecl *FieldDecls[2];
2248 FieldDecls[0] = FieldDecl::Create(Ctx, SourceLocation(), 0,
2249 Ctx.getObjCIdType());
2250 FieldDecls[1] = FieldDecl::Create(Ctx, SourceLocation(), 0,
2251 Ctx.getObjCClassType());
Ted Kremenek46a837c2008-09-05 17:16:31 +00002252 RD->defineBody(Ctx, FieldDecls, 2);
Daniel Dunbar0ed60b02008-08-30 03:02:31 +00002253
2254 SuperCTy = Ctx.getTagDeclType(RD);
2255 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
2256
2257 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
Daniel Dunbar87062ff2008-08-23 09:25:55 +00002258 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbar15245e52008-08-23 04:28:29 +00002259
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002260 // Global metadata structures
2261
2262 SymtabTy = llvm::StructType::get(LongTy,
2263 SelectorPtrTy,
2264 ShortTy,
2265 ShortTy,
Daniel Dunbar4246a8b2008-08-22 20:34:54 +00002266 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbarb050fa62008-08-21 04:36:09 +00002267 NULL);
2268 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
2269 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
2270
2271 ModuleTy =
2272 llvm::StructType::get(LongTy,
2273 LongTy,
2274 Int8PtrTy,
2275 SymtabPtrTy,
2276 NULL);
2277 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar87062ff2008-08-23 09:25:55 +00002278
Daniel Dunbarf7103722008-09-24 03:38:44 +00002279 // Message send functions.
Daniel Dunbar87062ff2008-08-23 09:25:55 +00002280
2281 std::vector<const llvm::Type*> Params;
2282 Params.push_back(ObjectPtrTy);
2283 Params.push_back(SelectorPtrTy);
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002284 MessageSendFn =
2285 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
2286 Params,
2287 true),
2288 "objc_msgSend");
Daniel Dunbar87062ff2008-08-23 09:25:55 +00002289
2290 Params.clear();
2291 Params.push_back(Int8PtrTy);
2292 Params.push_back(ObjectPtrTy);
2293 Params.push_back(SelectorPtrTy);
2294 MessageSendStretFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002295 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
2296 Params,
2297 true),
2298 "objc_msgSend_stret");
Daniel Dunbaraecef4c2008-10-17 03:24:53 +00002299
2300 Params.clear();
2301 Params.push_back(ObjectPtrTy);
2302 Params.push_back(SelectorPtrTy);
2303 // FIXME: This should be long double on x86_64?
2304 MessageSendFpretFn =
2305 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::DoubleTy,
2306 Params,
2307 true),
2308 "objc_msgSend_fpret");
Daniel Dunbar87062ff2008-08-23 09:25:55 +00002309
2310 Params.clear();
2311 Params.push_back(SuperPtrTy);
2312 Params.push_back(SelectorPtrTy);
2313 MessageSendSuperFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002314 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
2315 Params,
2316 true),
2317 "objc_msgSendSuper");
Daniel Dunbar87062ff2008-08-23 09:25:55 +00002318
2319 Params.clear();
2320 Params.push_back(Int8PtrTy);
2321 Params.push_back(SuperPtrTy);
2322 Params.push_back(SelectorPtrTy);
2323 MessageSendSuperStretFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002324 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
2325 Params,
2326 true),
2327 "objc_msgSendSuper_stret");
Daniel Dunbaraecef4c2008-10-17 03:24:53 +00002328
2329 // There is no objc_msgSendSuper_fpret? How can that work?
2330 MessageSendSuperFpretFn = MessageSendSuperFn;
Anders Carlsson58d16242008-08-31 04:05:03 +00002331
Daniel Dunbarf7103722008-09-24 03:38:44 +00002332 // Property manipulation functions.
2333
2334 Params.clear();
2335 Params.push_back(ObjectPtrTy);
2336 Params.push_back(SelectorPtrTy);
2337 Params.push_back(LongTy);
2338 Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
2339 GetPropertyFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002340 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
2341 Params,
2342 false),
2343 "objc_getProperty");
2344
Daniel Dunbarf7103722008-09-24 03:38:44 +00002345 Params.clear();
2346 Params.push_back(ObjectPtrTy);
2347 Params.push_back(SelectorPtrTy);
2348 Params.push_back(LongTy);
Daniel Dunbarf7f6c7b2008-09-24 06:32:09 +00002349 Params.push_back(ObjectPtrTy);
Daniel Dunbarf7103722008-09-24 03:38:44 +00002350 Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
2351 Params.push_back(Types.ConvertTypeForMem(Ctx.BoolTy));
2352 SetPropertyFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002353 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
2354 Params,
2355 false),
2356 "objc_setProperty");
Daniel Dunbarf7103722008-09-24 03:38:44 +00002357
Anders Carlsson58d16242008-08-31 04:05:03 +00002358 // Enumeration mutation.
Daniel Dunbarf7103722008-09-24 03:38:44 +00002359
Anders Carlsson58d16242008-08-31 04:05:03 +00002360 Params.clear();
2361 Params.push_back(ObjectPtrTy);
2362 EnumerationMutationFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002363 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
2364 Params,
2365 false),
2366 "objc_enumerationMutation");
Anders Carlsson9acb0a42008-09-09 10:10:21 +00002367
2368 // FIXME: This is the size of the setjmp buffer and should be
2369 // target specific. 18 is what's used on 32-bit X86.
2370 uint64_t SetJmpBufferSize = 18;
2371
2372 // Exceptions
2373 const llvm::Type *StackPtrTy =
Daniel Dunbar1c5e4632008-09-27 06:32:25 +00002374 llvm::ArrayType::get(llvm::PointerType::getUnqual(llvm::Type::Int8Ty), 4);
Anders Carlsson9acb0a42008-09-09 10:10:21 +00002375
2376 ExceptionDataTy =
2377 llvm::StructType::get(llvm::ArrayType::get(llvm::Type::Int32Ty,
2378 SetJmpBufferSize),
2379 StackPtrTy, NULL);
2380 CGM.getModule().addTypeName("struct._objc_exception_data",
2381 ExceptionDataTy);
2382
2383 Params.clear();
2384 Params.push_back(ObjectPtrTy);
2385 ExceptionThrowFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002386 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
2387 Params,
2388 false),
2389 "objc_exception_throw");
Anders Carlsson9acb0a42008-09-09 10:10:21 +00002390
2391 Params.clear();
2392 Params.push_back(llvm::PointerType::getUnqual(ExceptionDataTy));
2393 ExceptionTryEnterFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002394 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
2395 Params,
2396 false),
2397 "objc_exception_try_enter");
Anders Carlsson9acb0a42008-09-09 10:10:21 +00002398 ExceptionTryExitFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002399 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
2400 Params,
2401 false),
2402 "objc_exception_try_exit");
Anders Carlsson9acb0a42008-09-09 10:10:21 +00002403 ExceptionExtractFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002404 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
2405 Params,
2406 false),
2407 "objc_exception_extract");
Anders Carlsson9acb0a42008-09-09 10:10:21 +00002408
2409 Params.clear();
2410 Params.push_back(ClassPtrTy);
2411 Params.push_back(ObjectPtrTy);
2412 ExceptionMatchFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002413 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
2414 Params,
2415 false),
2416 "objc_exception_match");
Anders Carlsson9acb0a42008-09-09 10:10:21 +00002417
2418 Params.clear();
2419 Params.push_back(llvm::PointerType::getUnqual(llvm::Type::Int32Ty));
2420 SetJmpFn =
Daniel Dunbar4e19f4e2008-10-01 01:06:06 +00002421 CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
2422 Params,
2423 false),
2424 "_setjmp");
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00002425}
2426
2427ObjCTypesHelper::~ObjCTypesHelper() {
2428}
2429
Daniel Dunbardaf4ad42008-08-12 00:12:39 +00002430/* *** */
2431
Daniel Dunbarcffcdac2008-08-13 03:21:16 +00002432CodeGen::CGObjCRuntime *
2433CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbar8c85fac2008-08-11 02:45:11 +00002434 return new CGObjCMac(CGM);
2435}