blob: f0e70978f7bbc3c956eae4ee776f56022d1c5f5a [file] [log] [blame]
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This provides Objective-C code generation targetting the Apple runtime.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CGObjCRuntime.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000015
16#include "CodeGenModule.h"
Daniel Dunbarb7ec2462008-08-16 03:19:19 +000017#include "CodeGenFunction.h"
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000018#include "clang/AST/ASTContext.h"
Daniel Dunbare91593e2008-08-11 04:54:23 +000019#include "clang/AST/Decl.h"
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000020#include "clang/AST/DeclObjC.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000021#include "clang/Basic/LangOptions.h"
22
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000023#include "llvm/Module.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000024#include "llvm/Support/IRBuilder.h"
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000025#include "llvm/Target/TargetData.h"
Daniel Dunbarb7ec2462008-08-16 03:19:19 +000026#include <sstream>
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000027
28using namespace clang;
Daniel Dunbar46f45b92008-09-09 01:06:48 +000029using namespace CodeGen;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000030
31namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000032
Daniel Dunbarae226fa2008-08-27 02:31:56 +000033 typedef std::vector<llvm::Constant*> ConstantVector;
34
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000035 // FIXME: We should find a nicer way to make the labels for
36 // metadata, string concatenation is lame.
37
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000038/// ObjCTypesHelper - Helper class that encapsulates lazy
39/// construction of varies types used during ObjC generation.
40class ObjCTypesHelper {
41private:
42 CodeGen::CodeGenModule &CGM;
43
Daniel Dunbar14c80b72008-08-23 09:25:55 +000044 llvm::Function *MessageSendFn, *MessageSendStretFn;
45 llvm::Function *MessageSendSuperFn, *MessageSendSuperStretFn;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000046
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000047public:
Daniel Dunbar27f9d772008-08-21 04:36:09 +000048 const llvm::Type *ShortTy, *IntTy, *LongTy;
49 const llvm::Type *Int8PtrTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000050
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000051 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
52 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000053 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000054 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000055 /// ProtocolPtrTy - LLVM type for external protocol handles
56 /// (typeof(Protocol))
57 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000058
Daniel Dunbar19cd87e2008-08-30 03:02:31 +000059 // SuperCTy - clang type for struct objc_super.
60 QualType SuperCTy;
61 // SuperPtrCTy - clang type for struct objc_super *.
62 QualType SuperPtrCTy;
63
Daniel Dunbare8b470d2008-08-23 04:28:29 +000064 /// SuperTy - LLVM type for struct objc_super.
65 const llvm::StructType *SuperTy;
Daniel Dunbar14c80b72008-08-23 09:25:55 +000066 /// SuperPtrTy - LLVM type for struct objc_super *.
67 const llvm::Type *SuperPtrTy;
Daniel Dunbare8b470d2008-08-23 04:28:29 +000068
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000069 /// SymtabTy - LLVM type for struct objc_symtab.
70 const llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000071 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
72 const llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000073 /// ModuleTy - LLVM type for struct objc_module.
74 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000075
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000076 /// ProtocolTy - LLVM type for struct objc_protocol.
77 const llvm::StructType *ProtocolTy;
78 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
79 const llvm::Type *ProtocolPtrTy;
80 /// ProtocolExtensionTy - LLVM type for struct
81 /// objc_protocol_extension.
82 const llvm::StructType *ProtocolExtensionTy;
83 /// ProtocolExtensionTy - LLVM type for struct
84 /// objc_protocol_extension *.
85 const llvm::Type *ProtocolExtensionPtrTy;
86 /// MethodDescriptionTy - LLVM type for struct
87 /// objc_method_description.
88 const llvm::StructType *MethodDescriptionTy;
89 /// MethodDescriptionListTy - LLVM type for struct
90 /// objc_method_description_list.
91 const llvm::StructType *MethodDescriptionListTy;
92 /// MethodDescriptionListPtrTy - LLVM type for struct
93 /// objc_method_description_list *.
94 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbarc8ef5512008-08-23 00:19:03 +000095 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
96 /// in GCC parlance).
97 const llvm::StructType *PropertyTy;
98 /// PropertyListTy - LLVM type for struct objc_property_list
99 /// (_prop_list_t in GCC parlance).
100 const llvm::StructType *PropertyListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000101 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
102 const llvm::Type *PropertyListPtrTy;
103 /// ProtocolListTy - LLVM type for struct objc_property_list.
104 const llvm::Type *ProtocolListTy;
105 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
106 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000107 /// CategoryTy - LLVM type for struct objc_category.
108 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000109 /// ClassTy - LLVM type for struct objc_class.
110 const llvm::StructType *ClassTy;
111 /// ClassPtrTy - LLVM type for struct objc_class *.
112 const llvm::Type *ClassPtrTy;
113 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
114 const llvm::StructType *ClassExtensionTy;
115 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
116 const llvm::Type *ClassExtensionPtrTy;
117 /// CacheTy - LLVM type for struct objc_cache.
118 const llvm::Type *CacheTy;
119 /// CachePtrTy - LLVM type for struct objc_cache *.
120 const llvm::Type *CachePtrTy;
121 // IvarTy - LLVM type for struct objc_ivar.
122 const llvm::StructType *IvarTy;
123 /// IvarListTy - LLVM type for struct objc_ivar_list.
124 const llvm::Type *IvarListTy;
125 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
126 const llvm::Type *IvarListPtrTy;
127 // MethodTy - LLVM type for struct objc_method.
128 const llvm::StructType *MethodTy;
129 /// MethodListTy - LLVM type for struct objc_method_list.
130 const llvm::Type *MethodListTy;
131 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
132 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000133
Anders Carlsson2abd89c2008-08-31 04:05:03 +0000134 llvm::Function *EnumerationMutationFn;
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000135public:
136 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
137 ~ObjCTypesHelper();
138
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000139 llvm::Value *getMessageSendFn(bool IsSuper, const llvm::Type *ReturnTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000140};
141
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000142class CGObjCMac : public CodeGen::CGObjCRuntime {
143private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000144 CodeGen::CodeGenModule &CGM;
145 ObjCTypesHelper ObjCTypes;
146 /// ObjCABI - FIXME: Not sure yet.
147 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000148
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000149 /// LazySymbols - Symbols to generate a lazy reference for. See
150 /// DefinedSymbols and FinishModule().
151 std::set<IdentifierInfo*> LazySymbols;
152
153 /// DefinedSymbols - External symbols which are defined by this
154 /// module. The symbols in this list and LazySymbols are used to add
155 /// special linker symbols which ensure that Objective-C modules are
156 /// linked properly.
157 std::set<IdentifierInfo*> DefinedSymbols;
158
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000159 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000160 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000161
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000162 /// MethodVarNames - uniqued method variable names.
163 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
164
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000165 /// MethodVarTypes - uniqued method type signatures. We have to use
166 /// a StringMap here because have no other unique reference.
167 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
168
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000169 /// MethodDefinitions - map of methods which have been defined in
170 /// this translation unit.
171 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
172
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000173 /// PropertyNames - uniqued method variable names.
174 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
175
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000176 /// ClassReferences - uniqued class references.
177 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
178
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000179 /// SelectorReferences - uniqued selector references.
180 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
181
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000182 /// Protocols - Protocols for which an objc_protocol structure has
183 /// been emitted. Forward declarations are handled by creating an
184 /// empty structure whose initializer is filled in when/if defined.
185 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
186
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000187 /// DefinedClasses - List of defined classes.
188 std::vector<llvm::GlobalValue*> DefinedClasses;
189
190 /// DefinedCategories - List of defined categories.
191 std::vector<llvm::GlobalValue*> DefinedCategories;
192
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000193 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000194 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000195 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000196
197 /// EmitImageInfo - Emit the image info marker used to encode some module
198 /// level information.
199 void EmitImageInfo();
200
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000201 /// EmitModuleInfo - Another marker encoding module level
202 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000203 void EmitModuleInfo();
204
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000205 /// EmitModuleSymols - Emit module symbols, the list of defined
206 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000207 llvm::Constant *EmitModuleSymbols();
208
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000209 /// FinishModule - Write out global data structures at the end of
210 /// processing a translation unit.
211 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000212
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000213 /// EmitClassExtension - Generate the class extension structure used
214 /// to store the weak ivar layout and properties. The return value
215 /// has type ClassExtensionPtrTy.
216 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
217
218 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
219 /// for the given class.
220 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
221 const ObjCInterfaceDecl *ID);
222
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000223 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000224 QualType ResultType,
225 Selector Sel,
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000226 llvm::Value *Arg0,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000227 QualType Arg0Ty,
228 bool IsSuper,
229 const CallArgList &CallArgs);
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000230
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000231 /// EmitIvarList - Emit the ivar list for the given
232 /// implementation. If ForClass is true the list of class ivars
233 /// (i.e. metaclass ivars) is emitted, otherwise the list of
234 /// interface ivars will be emitted. The return value has type
235 /// IvarListPtrTy.
236 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
237 bool ForClass,
238 const llvm::Type *InterfaceTy);
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000239
240 /// EmitMetaClass - Emit a forward reference to the class structure
241 /// for the metaclass of the given interface. The return value has
242 /// type ClassPtrTy.
243 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
244
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000245 /// EmitMetaClass - Emit a class structure for the metaclass of the
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000246 /// given implementation. The return value has type ClassPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000247 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
248 llvm::Constant *Protocols,
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000249 const llvm::Type *InterfaceTy,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000250 const ConstantVector &Methods);
251
252 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
253
254 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000255
256 /// EmitMethodList - Emit the method list for the given
Daniel Dunbaraf05bb92008-08-26 08:29:31 +0000257 /// implementation. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000258 llvm::Constant *EmitMethodList(const std::string &Name,
259 const char *Section,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000260 const ConstantVector &Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000261
262 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000263 /// method declarations.
264 /// - TypeName: The name for the type containing the methods.
265 /// - IsProtocol: True iff these methods are for a protocol.
266 /// - ClassMethds: True iff these are class methods.
267 /// - Required: When true, only "required" methods are
268 /// listed. Similarly, when false only "optional" methods are
269 /// listed. For classes this should always be true.
270 /// - begin, end: The method list to output.
271 ///
272 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000273 llvm::Constant *EmitMethodDescList(const std::string &Name,
274 const char *Section,
275 const ConstantVector &Methods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000276
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000277 /// EmitPropertyList - Emit the given property list. The return
278 /// value has type PropertyListPtrTy.
279 llvm::Constant *EmitPropertyList(const std::string &Name,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000280 const Decl *Container,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000281 ObjCPropertyDecl * const *begin,
282 ObjCPropertyDecl * const *end);
283
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000284 /// EmitProtocolExtension - Generate the protocol extension
285 /// structure used to store optional instance and class methods, and
286 /// protocol properties. The return value has type
287 /// ProtocolExtensionPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000288 llvm::Constant *
289 EmitProtocolExtension(const ObjCProtocolDecl *PD,
290 const ConstantVector &OptInstanceMethods,
291 const ConstantVector &OptClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000292
293 /// EmitProtocolList - Generate the list of referenced
294 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc933702008-08-21 21:57:41 +0000295 llvm::Constant *EmitProtocolList(const std::string &Name,
296 ObjCProtocolDecl::protocol_iterator begin,
297 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000298
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000299 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
300 /// for the given selector.
301 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
302
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000303 /// GetProtocolRef - Return a reference to the internal protocol
304 /// description, creating an empty one if it has not been
305 /// defined. The return value has type pointer-to ProtocolTy.
306 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
307
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000308 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000309 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000310 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000311
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000312 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000313 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000314 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000315 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000316 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000317
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000318 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000319 /// selector's name. The return value has type char *.
320
321 // FIXME: This is a horrible name.
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000322 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000323 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000324
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000325 /// GetPropertyName - Return a unique constant for the given
326 /// name. The return value has type char *.
327 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
328
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000329 // FIXME: This can be dropped once string functions are unified.
330 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
331 const Decl *Container);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000332
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000333 /// GetNameForMethod - Return a name for the given method.
334 /// \param[out] NameOut - The return value.
335 void GetNameForMethod(const ObjCMethodDecl *OMD,
336 std::string &NameOut);
337
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000338public:
339 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000340 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000341
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000342 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000343 QualType ResultType,
344 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000345 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000346 bool IsClassMessage,
347 const CallArgList &CallArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000348
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000349 virtual CodeGen::RValue
350 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000351 QualType ResultType,
352 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000353 const ObjCInterfaceDecl *Class,
354 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000355 bool IsClassMessage,
356 const CallArgList &CallArgs);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000357
358 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000359 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000360
361 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
362
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000363 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000364
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000365 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000366
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000367 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000368
369 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000370 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000371
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000372 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000373
374 virtual llvm::Function *ModuleInitFunction();
Anders Carlsson2abd89c2008-08-31 04:05:03 +0000375 virtual llvm::Function *EnumerationMutationFunction();
Anders Carlsson64d5d6c2008-09-09 10:04:29 +0000376
377 virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
378 const ObjCAtTryStmt &S);
379 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
380 const ObjCAtThrowStmt &S);
381
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000382};
383} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000384
385/* *** Helper Functions *** */
386
387/// getConstantGEP() - Help routine to construct simple GEPs.
388static llvm::Constant *getConstantGEP(llvm::Constant *C,
389 unsigned idx0,
390 unsigned idx1) {
391 llvm::Value *Idxs[] = {
392 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
393 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
394 };
395 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
396}
397
398/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000399
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000400CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
401 : CGM(cgm),
402 ObjCTypes(cgm),
403 ObjCABI(1)
404{
405 // FIXME: How does this get set in GCC? And what does it even mean?
406 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
407 ObjCABI = 2;
408
409 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000410}
411
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000412/// GetClass - Return a reference to the class for the given interface
413/// decl.
414llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000415 const ObjCInterfaceDecl *ID) {
416 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000417}
418
419/// GetSelector - Return the pointer to the unique'd string for this selector.
420llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000421 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000422}
423
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000424/// Generate a constant CFString object.
425/*
426 struct __builtin_CFString {
427 const int *isa; // point to __CFConstantStringClassReference
428 int flags;
429 const char *str;
430 long length;
431 };
432*/
433
434llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
Daniel Dunbar3e9df992008-08-23 18:37:06 +0000435 return CGM.GetAddrOfConstantCFString(String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000436}
437
438/// Generates a message send where the super is the receiver. This is
439/// a message send to self with special delivery semantics indicating
440/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000441CodeGen::RValue
442CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000443 QualType ResultType,
444 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000445 const ObjCInterfaceDecl *Class,
446 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000447 bool IsClassMessage,
Daniel Dunbar46f45b92008-09-09 01:06:48 +0000448 const CodeGen::CallArgList &CallArgs) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000449 // Create and init a super structure; this is a (receiver, class)
450 // pair we will pass to objc_msgSendSuper.
451 llvm::Value *ObjCSuper =
452 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
453 llvm::Value *ReceiverAsObject =
454 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
455 CGF.Builder.CreateStore(ReceiverAsObject,
456 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000457
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000458 // If this is a class message the metaclass is passed as the target.
459 llvm::Value *Target;
460 if (IsClassMessage) {
461 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
462 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
463 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
464 Target = Super;
465 } else {
466 Target = EmitClassRef(CGF.Builder, Class->getSuperClass());
467 }
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000468 // FIXME: We shouldn't need to do this cast, rectify the ASTContext
469 // and ObjCTypes types.
470 const llvm::Type *ClassTy =
471 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
472 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000473 CGF.Builder.CreateStore(Target,
474 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
475
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000476 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000477 ObjCSuper, ObjCTypes.SuperPtrCTy,
478 true, CallArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000479}
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000480
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000481/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000482CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000483 QualType ResultType,
484 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000485 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000486 bool IsClassMessage,
487 const CallArgList &CallArgs) {
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000488 llvm::Value *Arg0 =
489 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000490 return EmitMessageSend(CGF, ResultType, Sel,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000491 Arg0, CGF.getContext().getObjCIdType(),
492 false, CallArgs);
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000493}
494
495CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000496 QualType ResultType,
497 Selector Sel,
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000498 llvm::Value *Arg0,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000499 QualType Arg0Ty,
500 bool IsSuper,
501 const CallArgList &CallArgs) {
502 CallArgList ActualArgs;
Daniel Dunbar46f45b92008-09-09 01:06:48 +0000503 ActualArgs.push_back(std::make_pair(RValue::get(Arg0), Arg0Ty));
504 ActualArgs.push_back(std::make_pair(RValue::get(EmitSelector(CGF.Builder,
505 Sel)),
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000506 CGF.getContext().getObjCSelType()));
507 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000508
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000509 // FIXME: This is a hack, we are implicitly coordinating with
Daniel Dunbare66f4e32008-09-03 00:27:26 +0000510 // EmitCall, which will move the return type to the first parameter
511 // and set the structure return flag. See getMessageSendFn().
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000512
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000513 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(ResultType);
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000514 return CGF.EmitCall(ObjCTypes.getMessageSendFn(IsSuper, ReturnTy),
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000515 ResultType, ActualArgs);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000516}
517
518llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000519 const ObjCProtocolDecl *PD) {
Daniel Dunbarc67876d2008-09-04 04:33:15 +0000520 // FIXME: I don't understand why gcc generates this, or where it is
521 // resolved. Investigate. Its also wasteful to look this up over and
522 // over.
523 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
524
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000525 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
526 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000527}
528
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000529/*
530 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
531 struct _objc_protocol {
532 struct _objc_protocol_extension *isa;
533 char *protocol_name;
534 struct _objc_protocol_list *protocol_list;
535 struct _objc__method_prototype_list *instance_methods;
536 struct _objc__method_prototype_list *class_methods
537 };
538
539 See EmitProtocolExtension().
540*/
541void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000542 // FIXME: I don't understand why gcc generates this, or where it is
543 // resolved. Investigate. Its also wasteful to look this up over and
544 // over.
545 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
546
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000547 const char *ProtocolName = PD->getName();
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000548
549 // Construct method lists.
550 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
551 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
552 for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
553 e = PD->instmeth_end(); i != e; ++i) {
554 ObjCMethodDecl *MD = *i;
555 llvm::Constant *C = GetMethodDescriptionConstant(MD);
556 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
557 OptInstanceMethods.push_back(C);
558 } else {
559 InstanceMethods.push_back(C);
560 }
561 }
562
563 for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
564 e = PD->classmeth_end(); i != e; ++i) {
565 ObjCMethodDecl *MD = *i;
566 llvm::Constant *C = GetMethodDescriptionConstant(MD);
567 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
568 OptClassMethods.push_back(C);
569 } else {
570 ClassMethods.push_back(C);
571 }
572 }
573
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000574 std::vector<llvm::Constant*> Values(5);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000575 Values[0] = EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000576 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000577 Values[2] =
578 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
579 PD->protocol_begin(),
580 PD->protocol_end());
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000581 Values[3] =
582 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_")
583 + PD->getName(),
584 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
585 InstanceMethods);
586 Values[4] =
587 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_")
588 + PD->getName(),
589 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
590 ClassMethods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000591 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
592 Values);
593
594 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
595 if (Entry) {
596 // Already created, just update the initializer
597 Entry->setInitializer(Init);
598 } else {
599 Entry =
600 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
601 llvm::GlobalValue::InternalLinkage,
602 Init,
603 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
604 &CGM.getModule());
605 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
606 UsedGlobals.push_back(Entry);
607 // FIXME: Is this necessary? Why only for protocol?
608 Entry->setAlignment(4);
609 }
610}
611
612llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
613 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
614
615 if (!Entry) {
616 std::vector<llvm::Constant*> Values(5);
617 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
618 Values[1] = GetClassName(PD->getIdentifier());
619 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
620 Values[3] = Values[4] =
621 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
622 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
623 Values);
624
625 Entry =
626 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
627 llvm::GlobalValue::InternalLinkage,
628 Init,
629 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
630 &CGM.getModule());
631 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
632 UsedGlobals.push_back(Entry);
633 // FIXME: Is this necessary? Why only for protocol?
634 Entry->setAlignment(4);
635 }
636
637 return Entry;
638}
639
640/*
641 struct _objc_protocol_extension {
642 uint32_t size;
643 struct objc_method_description_list *optional_instance_methods;
644 struct objc_method_description_list *optional_class_methods;
645 struct objc_property_list *instance_properties;
646 };
647*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000648llvm::Constant *
649CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
650 const ConstantVector &OptInstanceMethods,
651 const ConstantVector &OptClassMethods) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000652 uint64_t Size =
653 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
654 std::vector<llvm::Constant*> Values(4);
655 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000656 Values[1] =
657 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_")
658 + PD->getName(),
659 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
660 OptInstanceMethods);
661 Values[2] =
662 EmitMethodDescList(std::string("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_")
663 + PD->getName(),
664 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
665 OptClassMethods);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000666 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
667 PD->getName(),
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000668 0,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000669 PD->classprop_begin(),
670 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000671
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000672 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000673 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
674 Values[3]->isNullValue())
675 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
676
677 llvm::Constant *Init =
678 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
679 llvm::GlobalVariable *GV =
680 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
681 llvm::GlobalValue::InternalLinkage,
682 Init,
683 (std::string("\01L_OBJC_PROTOCOLEXT_") +
684 PD->getName()),
685 &CGM.getModule());
686 // No special section, but goes in llvm.used
687 UsedGlobals.push_back(GV);
688
689 return GV;
690}
691
692/*
693 struct objc_protocol_list {
694 struct objc_protocol_list *next;
695 long count;
696 Protocol *list[];
697 };
698*/
Daniel Dunbardbc933702008-08-21 21:57:41 +0000699llvm::Constant *
700CGObjCMac::EmitProtocolList(const std::string &Name,
701 ObjCProtocolDecl::protocol_iterator begin,
702 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000703 std::vector<llvm::Constant*> ProtocolRefs;
704
Daniel Dunbardbc933702008-08-21 21:57:41 +0000705 for (; begin != end; ++begin)
706 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000707
708 // Just return null for empty protocol lists
709 if (ProtocolRefs.empty())
710 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
711
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000712 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000713 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
714
715 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000716 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000717 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
718 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
719 Values[2] =
720 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
721 ProtocolRefs.size()),
722 ProtocolRefs);
723
724 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
725 llvm::GlobalVariable *GV =
726 new llvm::GlobalVariable(Init->getType(), false,
727 llvm::GlobalValue::InternalLinkage,
728 Init,
Daniel Dunbardbc933702008-08-21 21:57:41 +0000729 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000730 &CGM.getModule());
731 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
732 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
733}
734
735/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000736 struct _objc_property {
737 const char * const name;
738 const char * const attributes;
739 };
740
741 struct _objc_property_list {
742 uint32_t entsize; // sizeof (struct _objc_property)
743 uint32_t prop_count;
744 struct _objc_property[prop_count];
745 };
746*/
747llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000748 const Decl *Container,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000749 ObjCPropertyDecl * const *begin,
750 ObjCPropertyDecl * const *end) {
751 std::vector<llvm::Constant*> Properties, Prop(2);
752 for (; begin != end; ++begin) {
753 const ObjCPropertyDecl *PD = *begin;
754 Prop[0] = GetPropertyName(PD->getIdentifier());
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000755 Prop[1] = GetPropertyTypeString(PD, Container);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000756 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
757 Prop));
758 }
759
760 // Return null for empty list.
761 if (Properties.empty())
762 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
763
764 unsigned PropertySize =
765 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
766 std::vector<llvm::Constant*> Values(3);
767 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
768 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
769 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
770 Properties.size());
771 Values[2] = llvm::ConstantArray::get(AT, Properties);
772 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
773
774 llvm::GlobalVariable *GV =
775 new llvm::GlobalVariable(Init->getType(), false,
776 llvm::GlobalValue::InternalLinkage,
777 Init,
778 Name,
779 &CGM.getModule());
780 // No special section on property lists?
781 UsedGlobals.push_back(GV);
782 return llvm::ConstantExpr::getBitCast(GV,
783 ObjCTypes.PropertyListPtrTy);
784
785}
786
787/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000788 struct objc_method_description_list {
789 int count;
790 struct objc_method_description list[];
791 };
792*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000793llvm::Constant *
794CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
795 std::vector<llvm::Constant*> Desc(2);
796 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
797 ObjCTypes.SelectorPtrTy);
798 Desc[1] = GetMethodVarType(MD);
799 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
800 Desc);
801}
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000802
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000803llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &Name,
804 const char *Section,
805 const ConstantVector &Methods) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000806 // Return null for empty list.
807 if (Methods.empty())
808 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
809
810 std::vector<llvm::Constant*> Values(2);
811 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
812 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
813 Methods.size());
814 Values[1] = llvm::ConstantArray::get(AT, Methods);
815 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
816
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000817 llvm::GlobalVariable *GV =
818 new llvm::GlobalVariable(Init->getType(), false,
819 llvm::GlobalValue::InternalLinkage,
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000820 Init, Name, &CGM.getModule());
821 GV->setSection(Section);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000822 UsedGlobals.push_back(GV);
823 return llvm::ConstantExpr::getBitCast(GV,
824 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000825}
826
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000827/*
828 struct _objc_category {
829 char *category_name;
830 char *class_name;
831 struct _objc_method_list *instance_methods;
832 struct _objc_method_list *class_methods;
833 struct _objc_protocol_list *protocols;
834 uint32_t size; // <rdar://4585769>
835 struct _objc_property_list *instance_properties;
836 };
837 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000838void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000839 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
840
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000841 // FIXME: This is poor design, the OCD should have a pointer to the
842 // category decl. Additionally, note that Category can be null for
843 // the @implementation w/o an @interface case. Sema should just
844 // create one for us as it does for @implementation so everyone else
845 // can live life under a clear blue sky.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000846 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000847 const ObjCCategoryDecl *Category =
848 Interface->FindCategoryDeclaration(OCD->getIdentifier());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000849 std::string ExtName(std::string(Interface->getName()) +
850 "_" +
851 OCD->getName());
852
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000853 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
854 for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(),
855 e = OCD->instmeth_end(); i != e; ++i) {
856 // Instance methods should always be defined.
857 InstanceMethods.push_back(GetMethodConstant(*i));
858 }
859 for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(),
860 e = OCD->classmeth_end(); i != e; ++i) {
861 // Class methods should always be defined.
862 ClassMethods.push_back(GetMethodConstant(*i));
863 }
864
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000865 std::vector<llvm::Constant*> Values(7);
866 Values[0] = GetClassName(OCD->getIdentifier());
867 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000868 Values[2] =
869 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
870 ExtName,
871 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000872 InstanceMethods);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000873 Values[3] =
874 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
875 "__OBJC,__cat_class_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000876 ClassMethods);
Daniel Dunbarae226fa2008-08-27 02:31:56 +0000877 if (Category) {
878 Values[4] =
879 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
880 Category->protocol_begin(),
881 Category->protocol_end());
882 } else {
883 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
884 }
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000885 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000886
887 // If there is no category @interface then there can be no properties.
888 if (Category) {
889 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
Daniel Dunbarc56f34a2008-08-28 04:38:10 +0000890 OCD,
Daniel Dunbar86e2f402008-08-26 23:03:11 +0000891 Category->classprop_begin(),
892 Category->classprop_end());
893 } else {
894 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
895 }
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000896
897 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
898 Values);
899
900 llvm::GlobalVariable *GV =
901 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
902 llvm::GlobalValue::InternalLinkage,
903 Init,
904 std::string("\01L_OBJC_CATEGORY_")+ExtName,
905 &CGM.getModule());
906 GV->setSection("__OBJC,__category,regular,no_dead_strip");
907 UsedGlobals.push_back(GV);
908 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000909}
910
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000911// FIXME: Get from somewhere?
912enum ClassFlags {
913 eClassFlags_Factory = 0x00001,
914 eClassFlags_Meta = 0x00002,
915 // <rdr://5142207>
916 eClassFlags_HasCXXStructors = 0x02000,
917 eClassFlags_Hidden = 0x20000,
918 eClassFlags_ABI2_Hidden = 0x00010,
919 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
920};
921
922// <rdr://5142207&4705298&4843145>
923static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
924 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
925 // FIXME: Support -fvisibility
926 switch (attr->getVisibility()) {
927 default:
928 assert(0 && "Unknown visibility");
929 return false;
930 case VisibilityAttr::DefaultVisibility:
931 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
932 return false;
933 case VisibilityAttr::HiddenVisibility:
934 return true;
935 }
936 } else {
937 return false; // FIXME: Support -fvisibility
938 }
939}
940
941/*
942 struct _objc_class {
943 Class isa;
944 Class super_class;
945 const char *name;
946 long version;
947 long info;
948 long instance_size;
949 struct _objc_ivar_list *ivars;
950 struct _objc_method_list *methods;
951 struct _objc_cache *cache;
952 struct _objc_protocol_list *protocols;
953 // Objective-C 1.0 extensions (<rdr://4585769>)
954 const char *ivar_layout;
955 struct _objc_class_ext *ext;
956 };
957
958 See EmitClassExtension();
959 */
960void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000961 DefinedSymbols.insert(ID->getIdentifier());
962
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000963 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000964 // FIXME: Gross
965 ObjCInterfaceDecl *Interface =
966 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc933702008-08-21 21:57:41 +0000967 llvm::Constant *Protocols =
968 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
969 Interface->protocol_begin(),
970 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000971 const llvm::Type *InterfaceTy =
972 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
973 unsigned Flags = eClassFlags_Factory;
974 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
975
976 // FIXME: Set CXX-structors flag.
977 if (IsClassHidden(ID->getClassInterface()))
978 Flags |= eClassFlags_Hidden;
979
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000980 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
981 for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(),
982 e = ID->instmeth_end(); i != e; ++i) {
983 // Instance methods should always be defined.
984 InstanceMethods.push_back(GetMethodConstant(*i));
985 }
986 for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(),
987 e = ID->classmeth_end(); i != e; ++i) {
988 // Class methods should always be defined.
989 ClassMethods.push_back(GetMethodConstant(*i));
990 }
991
992 for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
993 e = ID->propimpl_end(); i != e; ++i) {
994 ObjCPropertyImplDecl *PID = *i;
995
996 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
997 ObjCPropertyDecl *PD = PID->getPropertyDecl();
998
999 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
1000 if (llvm::Constant *C = GetMethodConstant(MD))
1001 InstanceMethods.push_back(C);
1002 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
1003 if (llvm::Constant *C = GetMethodConstant(MD))
1004 InstanceMethods.push_back(C);
1005 }
1006 }
1007
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001008 std::vector<llvm::Constant*> Values(12);
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001009 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy, ClassMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001010 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001011 // Record a reference to the super class.
1012 LazySymbols.insert(Super->getIdentifier());
1013
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001014 Values[ 1] =
1015 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1016 ObjCTypes.ClassPtrTy);
1017 } else {
1018 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1019 }
1020 Values[ 2] = GetClassName(ID->getIdentifier());
1021 // Version is always 0.
1022 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1023 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1024 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1025 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001026 Values[ 7] =
1027 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
1028 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001029 InstanceMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001030 // cache is always NULL.
1031 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1032 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001033 // FIXME: Set ivar_layout
1034 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001035 Values[11] = EmitClassExtension(ID);
1036 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1037 Values);
1038
1039 llvm::GlobalVariable *GV =
1040 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1041 llvm::GlobalValue::InternalLinkage,
1042 Init,
1043 std::string("\01L_OBJC_CLASS_")+ClassName,
1044 &CGM.getModule());
1045 GV->setSection("__OBJC,__class,regular,no_dead_strip");
1046 UsedGlobals.push_back(GV);
1047 // FIXME: Why?
1048 GV->setAlignment(32);
1049 DefinedClasses.push_back(GV);
1050}
1051
1052llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
1053 llvm::Constant *Protocols,
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001054 const llvm::Type *InterfaceTy,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001055 const ConstantVector &Methods) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001056 const char *ClassName = ID->getName();
1057 unsigned Flags = eClassFlags_Meta;
1058 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
1059
1060 if (IsClassHidden(ID->getClassInterface()))
1061 Flags |= eClassFlags_Hidden;
1062
1063 std::vector<llvm::Constant*> Values(12);
1064 // The isa for the metaclass is the root of the hierarchy.
1065 const ObjCInterfaceDecl *Root = ID->getClassInterface();
1066 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
1067 Root = Super;
1068 Values[ 0] =
1069 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
1070 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001071 // The super class for the metaclass is emitted as the name of the
1072 // super class. The runtime fixes this up to point to the
1073 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001074 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
1075 Values[ 1] =
1076 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
1077 ObjCTypes.ClassPtrTy);
1078 } else {
1079 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
1080 }
1081 Values[ 2] = GetClassName(ID->getIdentifier());
1082 // Version is always 0.
1083 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1084 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
1085 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
1086 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001087 Values[ 7] =
1088 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
1089 "__OBJC,__inst_meth,regular,no_dead_strip",
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001090 Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001091 // cache is always NULL.
1092 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
1093 Values[ 9] = Protocols;
1094 // ivar_layout for metaclass is always NULL.
1095 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1096 // The class extension is always unused for metaclasses.
1097 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1098 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
1099 Values);
1100
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001101 std::string Name("\01L_OBJC_METACLASS_");
1102 Name += ClassName;
1103
1104 // Check for a forward reference.
1105 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
1106 if (GV) {
1107 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1108 "Forward metaclass reference has incorrect type.");
1109 GV->setLinkage(llvm::GlobalValue::InternalLinkage);
1110 GV->setInitializer(Init);
1111 } else {
1112 GV = new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1113 llvm::GlobalValue::InternalLinkage,
1114 Init, Name,
1115 &CGM.getModule());
1116 }
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001117 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
1118 UsedGlobals.push_back(GV);
1119 // FIXME: Why?
1120 GV->setAlignment(32);
1121
1122 return GV;
1123}
1124
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001125llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
1126 std::string Name("\01L_OBJC_METACLASS_");
1127 Name += ID->getName();
1128
1129 // FIXME: Should we look these up somewhere other than the
1130 // module. Its a bit silly since we only generate these while
1131 // processing an implementation, so exactly one pointer would work
1132 // if know when we entered/exitted an implementation block.
1133
1134 // Check for an existing forward reference.
1135 if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name)) {
1136 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
1137 "Forward metaclass reference has incorrect type.");
1138 return GV;
1139 } else {
1140 // Generate as an external reference to keep a consistent
1141 // module. This will be patched up when we emit the metaclass.
1142 return new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
1143 llvm::GlobalValue::ExternalLinkage,
1144 0,
1145 Name,
1146 &CGM.getModule());
1147 }
1148}
1149
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001150/*
1151 struct objc_class_ext {
1152 uint32_t size;
1153 const char *weak_ivar_layout;
1154 struct _objc_property_list *properties;
1155 };
1156*/
1157llvm::Constant *
1158CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1159 uint64_t Size =
1160 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1161
1162 std::vector<llvm::Constant*> Values(3);
1163 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001164 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001165 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001166 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1167 ID->getName(),
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001168 ID,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001169 ID->getClassInterface()->classprop_begin(),
1170 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001171
1172 // Return null if no extension bits are used.
1173 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1174 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1175
1176 llvm::Constant *Init =
1177 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1178 llvm::GlobalVariable *GV =
1179 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1180 llvm::GlobalValue::InternalLinkage,
1181 Init,
1182 (std::string("\01L_OBJC_CLASSEXT_") +
1183 ID->getName()),
1184 &CGM.getModule());
1185 // No special section, but goes in llvm.used
1186 UsedGlobals.push_back(GV);
1187
1188 return GV;
1189}
1190
1191/*
1192 struct objc_ivar {
1193 char *ivar_name;
1194 char *ivar_type;
1195 int ivar_offset;
1196 };
1197
1198 struct objc_ivar_list {
1199 int ivar_count;
1200 struct objc_ivar list[count];
1201 };
1202 */
1203llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1204 bool ForClass,
1205 const llvm::Type *InterfaceTy) {
1206 std::vector<llvm::Constant*> Ivars, Ivar(3);
1207
1208 // When emitting the root class GCC emits ivar entries for the
1209 // actual class structure. It is not clear if we need to follow this
1210 // behavior; for now lets try and get away with not doing it. If so,
1211 // the cleanest solution would be to make up an ObjCInterfaceDecl
1212 // for the class.
1213 if (ForClass)
1214 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1215
1216 const llvm::StructLayout *Layout =
1217 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1218 for (ObjCInterfaceDecl::ivar_iterator
1219 i = ID->getClassInterface()->ivar_begin(),
1220 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1221 ObjCIvarDecl *V = *i;
1222 unsigned Offset =
1223 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1224 std::string TypeStr;
1225 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1226 Ivar[0] = GetMethodVarName(V->getIdentifier());
1227 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1228 EncodingRecordTypes);
1229 Ivar[1] = GetMethodVarType(TypeStr);
1230 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1231 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1232 Ivar));
1233 }
1234
1235 // Return null for empty list.
1236 if (Ivars.empty())
1237 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1238
1239 std::vector<llvm::Constant*> Values(2);
1240 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1241 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1242 Ivars.size());
1243 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1244 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1245
1246 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1247 "\01L_OBJC_INSTANCE_VARIABLES_");
1248 llvm::GlobalVariable *GV =
1249 new llvm::GlobalVariable(Init->getType(), false,
1250 llvm::GlobalValue::InternalLinkage,
1251 Init,
1252 std::string(Prefix) + ID->getName(),
1253 &CGM.getModule());
1254 if (ForClass) {
1255 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1256 // FIXME: Why is this only here?
1257 GV->setAlignment(32);
1258 } else {
1259 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1260 }
1261 UsedGlobals.push_back(GV);
1262 return llvm::ConstantExpr::getBitCast(GV,
1263 ObjCTypes.IvarListPtrTy);
1264}
1265
1266/*
1267 struct objc_method {
1268 SEL method_name;
1269 char *method_types;
1270 void *method;
1271 };
1272
1273 struct objc_method_list {
1274 struct objc_method_list *obsolete;
1275 int count;
1276 struct objc_method methods_list[count];
1277 };
1278*/
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001279
1280/// GetMethodConstant - Return a struct objc_method constant for the
1281/// given method if it has been defined. The result is null if the
1282/// method has not been defined. The return value has type MethodPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001283llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001284 // FIXME: Use DenseMap::lookup
1285 llvm::Function *Fn = MethodDefinitions[MD];
1286 if (!Fn)
1287 return 0;
1288
1289 std::vector<llvm::Constant*> Method(3);
1290 Method[0] =
1291 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1292 ObjCTypes.SelectorPtrTy);
1293 Method[1] = GetMethodVarType(MD);
1294 Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy);
1295 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
1296}
1297
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001298llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1299 const char *Section,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001300 const ConstantVector &Methods) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001301 // Return null for empty list.
1302 if (Methods.empty())
1303 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1304
1305 std::vector<llvm::Constant*> Values(3);
1306 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1307 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1308 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1309 Methods.size());
1310 Values[2] = llvm::ConstantArray::get(AT, Methods);
1311 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1312
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001313 llvm::GlobalVariable *GV =
1314 new llvm::GlobalVariable(Init->getType(), false,
1315 llvm::GlobalValue::InternalLinkage,
1316 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001317 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001318 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001319 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001320 UsedGlobals.push_back(GV);
1321 return llvm::ConstantExpr::getBitCast(GV,
1322 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001323}
1324
1325llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1326 const llvm::Type *ReturnTy =
1327 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1328 const llvm::Type *SelfTy =
1329 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1330
1331 std::vector<const llvm::Type*> ArgTys;
1332 ArgTys.reserve(1 + 2 + OMD->param_size());
1333
1334 // FIXME: This is not something we should have to be dealing with
1335 // here.
1336 bool useStructRet =
1337 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1338 if (useStructRet) {
1339 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1340 ReturnTy = llvm::Type::VoidTy;
1341 }
1342
1343 // Implicit arguments
1344 ArgTys.push_back(SelfTy);
1345 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1346
1347 for (ObjCMethodDecl::param_const_iterator
1348 i = OMD->param_begin(), e = OMD->param_end();
1349 i != e; ++i) {
1350 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001351 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001352 ArgTys.push_back(Ty);
1353 } else {
1354 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1355 }
1356 }
1357
1358 std::string Name;
1359 GetNameForMethod(OMD, Name);
1360
1361 llvm::Function *Method =
1362 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1363 ArgTys,
1364 OMD->isVariadic()),
1365 llvm::GlobalValue::InternalLinkage,
1366 Name,
1367 &CGM.getModule());
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001368 MethodDefinitions.insert(std::make_pair(OMD, Method));
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001369
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001370 unsigned Offset = 3; // Return plus self and selector implicit args.
1371 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001372 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001373 ++Offset;
1374 }
1375
1376 // FIXME: This is horrible, we need to be reusing the machinery in
1377 // CodeGenModule.cpp (SetFunctionAttributes).
1378 for (ObjCMethodDecl::param_const_iterator
1379 i = OMD->param_begin(), e = OMD->param_end();
1380 i != e; ++i, ++Offset) {
1381 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1382 if (!Ty->isSingleValueType())
1383 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1384 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001385
1386 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001387}
1388
1389llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001390 // Abuse this interface function as a place to finalize.
1391 FinishModule();
1392
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001393 return NULL;
1394}
1395
Anders Carlsson2abd89c2008-08-31 04:05:03 +00001396llvm::Function *CGObjCMac::EnumerationMutationFunction()
1397{
1398 return ObjCTypes.EnumerationMutationFn;
1399}
1400
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00001401void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1402 const ObjCAtTryStmt &S)
1403{
1404 CGF.ErrorUnsupported(&S, "@try statement");
1405}
1406
1407void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1408 const ObjCAtThrowStmt &S)
1409{
1410 CGF.ErrorUnsupported(&S, "@throw statement");
1411}
1412
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001413/* *** Private Interface *** */
1414
1415/// EmitImageInfo - Emit the image info marker used to encode some module
1416/// level information.
1417///
1418/// See: <rdr://4810609&4810587&4810587>
1419/// struct IMAGE_INFO {
1420/// unsigned version;
1421/// unsigned flags;
1422/// };
1423enum ImageInfoFlags {
1424 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1425 eImageInfo_GarbageCollected = (1 << 1),
1426 eImageInfo_GCOnly = (1 << 2)
1427};
1428
1429void CGObjCMac::EmitImageInfo() {
1430 unsigned version = 0; // Version is unused?
1431 unsigned flags = 0;
1432
1433 // FIXME: Fix and continue?
1434 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1435 flags |= eImageInfo_GarbageCollected;
1436 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1437 flags |= eImageInfo_GCOnly;
1438
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001439 // Emitted as int[2];
1440 llvm::Constant *values[2] = {
1441 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1442 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1443 };
1444 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001445 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001446 new llvm::GlobalVariable(AT, true,
1447 llvm::GlobalValue::InternalLinkage,
1448 llvm::ConstantArray::get(AT, values, 2),
1449 "\01L_OBJC_IMAGE_INFO",
1450 &CGM.getModule());
1451
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001452 if (ObjCABI == 1) {
1453 GV->setSection("__OBJC, __image_info,regular");
1454 } else {
1455 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1456 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001457
1458 UsedGlobals.push_back(GV);
1459}
1460
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001461
1462// struct objc_module {
1463// unsigned long version;
1464// unsigned long size;
1465// const char *name;
1466// Symtab symtab;
1467// };
1468
1469// FIXME: Get from somewhere
1470static const int ModuleVersion = 7;
1471
1472void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001473 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1474
1475 std::vector<llvm::Constant*> Values(4);
1476 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1477 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001478 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001479 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001480 Values[3] = EmitModuleSymbols();
1481
1482 llvm::GlobalVariable *GV =
1483 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1484 llvm::GlobalValue::InternalLinkage,
1485 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1486 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001487 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001488 &CGM.getModule());
1489 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1490 UsedGlobals.push_back(GV);
1491}
1492
1493llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001494 unsigned NumClasses = DefinedClasses.size();
1495 unsigned NumCategories = DefinedCategories.size();
1496
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001497 // Return null if no symbols were defined.
1498 if (!NumClasses && !NumCategories)
1499 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
1500
1501 std::vector<llvm::Constant*> Values(5);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001502 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1503 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1504 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1505 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1506
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001507 // The runtime expects exactly the list of defined classes followed
1508 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001509 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001510 for (unsigned i=0; i<NumClasses; i++)
1511 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1512 ObjCTypes.Int8PtrTy);
1513 for (unsigned i=0; i<NumCategories; i++)
1514 Symbols[NumClasses + i] =
1515 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1516 ObjCTypes.Int8PtrTy);
1517
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001518 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001519 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001520 NumClasses + NumCategories),
1521 Symbols);
1522
1523 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1524
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001525 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001526 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001527 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001528 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001529 "\01L_OBJC_SYMBOLS",
1530 &CGM.getModule());
1531 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1532 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001533 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1534}
1535
1536llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1537 const ObjCInterfaceDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001538 LazySymbols.insert(ID->getIdentifier());
1539
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001540 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1541
1542 if (!Entry) {
1543 llvm::Constant *Casted =
1544 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1545 ObjCTypes.ClassPtrTy);
1546 Entry =
1547 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1548 llvm::GlobalValue::InternalLinkage,
1549 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1550 &CGM.getModule());
1551 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1552 UsedGlobals.push_back(Entry);
1553 }
1554
1555 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001556}
1557
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001558llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1559 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1560
1561 if (!Entry) {
1562 llvm::Constant *Casted =
1563 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1564 ObjCTypes.SelectorPtrTy);
1565 Entry =
1566 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1567 llvm::GlobalValue::InternalLinkage,
1568 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1569 &CGM.getModule());
1570 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1571 UsedGlobals.push_back(Entry);
1572 }
1573
1574 return Builder.CreateLoad(Entry, false, "tmp");
1575}
1576
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001577llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1578 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001579
1580 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001581 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001582 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001583 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001584 llvm::GlobalValue::InternalLinkage,
1585 C, "\01L_OBJC_CLASS_NAME_",
1586 &CGM.getModule());
1587 Entry->setSection("__TEXT,__cstring,cstring_literals");
1588 UsedGlobals.push_back(Entry);
1589 }
1590
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001591 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001592}
1593
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001594llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1595 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1596
1597 if (!Entry) {
1598 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1599 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001600 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001601 llvm::GlobalValue::InternalLinkage,
1602 C, "\01L_OBJC_METH_VAR_NAME_",
1603 &CGM.getModule());
1604 Entry->setSection("__TEXT,__cstring,cstring_literals");
1605 UsedGlobals.push_back(Entry);
1606 }
1607
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001608 return getConstantGEP(Entry, 0, 0);
1609}
1610
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001611// FIXME: Merge into a single cstring creation function.
1612llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1613 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1614}
1615
1616// FIXME: Merge into a single cstring creation function.
1617llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1618 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1619}
1620
1621llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1622 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001623
1624 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001625 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001626 Entry =
1627 new llvm::GlobalVariable(C->getType(), false,
1628 llvm::GlobalValue::InternalLinkage,
1629 C, "\01L_OBJC_METH_VAR_TYPE_",
1630 &CGM.getModule());
1631 Entry->setSection("__TEXT,__cstring,cstring_literals");
1632 UsedGlobals.push_back(Entry);
1633 }
1634
1635 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001636}
1637
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001638// FIXME: Merge into a single cstring creation function.
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001639llvm::Constant *CGObjCMac::GetMethodVarType(const ObjCMethodDecl *D) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001640 std::string TypeStr;
Daniel Dunbarc45ef602008-08-26 21:51:14 +00001641 CGM.getContext().getObjCEncodingForMethodDecl(const_cast<ObjCMethodDecl*>(D),
1642 TypeStr);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001643 return GetMethodVarType(TypeStr);
1644}
1645
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001646// FIXME: Merge into a single cstring creation function.
1647llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1648 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1649
1650 if (!Entry) {
1651 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1652 Entry =
1653 new llvm::GlobalVariable(C->getType(), false,
1654 llvm::GlobalValue::InternalLinkage,
1655 C, "\01L_OBJC_PROP_NAME_ATTR_",
1656 &CGM.getModule());
1657 Entry->setSection("__TEXT,__cstring,cstring_literals");
1658 UsedGlobals.push_back(Entry);
1659 }
1660
1661 return getConstantGEP(Entry, 0, 0);
1662}
1663
1664// FIXME: Merge into a single cstring creation function.
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001665// FIXME: This Decl should be more precise.
1666llvm::Constant *CGObjCMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
1667 const Decl *Container) {
1668 std::string TypeStr;
1669 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001670 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1671}
1672
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001673void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1674 std::string &NameOut) {
1675 // FIXME: Find the mangling GCC uses.
1676 std::stringstream s;
1677 s << (D->isInstance() ? "-" : "+");
1678 s << "[";
1679 s << D->getClassInterface()->getName();
1680 s << " ";
1681 s << D->getSelector().getName();
1682 s << "]";
1683 NameOut = s.str();
1684}
1685
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001686void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001687 EmitModuleInfo();
1688
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001689 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001690
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001691 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001692 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001693 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001694 }
1695
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001696 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001697 llvm::GlobalValue *GV =
1698 new llvm::GlobalVariable(AT, false,
1699 llvm::GlobalValue::AppendingLinkage,
1700 llvm::ConstantArray::get(AT, Used),
1701 "llvm.used",
1702 &CGM.getModule());
1703
1704 GV->setSection("llvm.metadata");
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001705
1706 // Add assembler directives to add lazy undefined symbol references
1707 // for classes which are referenced but not defined. This is
1708 // important for correct linker interaction.
1709
1710 // FIXME: Uh, this isn't particularly portable.
1711 std::stringstream s;
1712 for (std::set<IdentifierInfo*>::iterator i = LazySymbols.begin(),
1713 e = LazySymbols.end(); i != e; ++i) {
1714 s << "\t.lazy_reference .objc_class_name_" << (*i)->getName() << "\n";
1715 }
1716 for (std::set<IdentifierInfo*>::iterator i = DefinedSymbols.begin(),
1717 e = DefinedSymbols.end(); i != e; ++i) {
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00001718 s << "\t.objc_class_name_" << (*i)->getName() << "=0\n"
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00001719 << "\t.globl .objc_class_name_" << (*i)->getName() << "\n";
1720 }
1721 CGM.getModule().appendModuleInlineAsm(s.str());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001722}
1723
1724/* *** */
1725
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001726ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Daniel Dunbar3e9df992008-08-23 18:37:06 +00001727 : CGM(cgm)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001728{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001729 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1730 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001731
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001732 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001733 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001734 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001735 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1736
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001737 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1738 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001739
1740 // FIXME: It would be nice to unify this with the opaque type, so
1741 // that the IR comes out a bit cleaner.
1742 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1743 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001744
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001745 MethodDescriptionTy =
1746 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001747 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001748 NULL);
1749 CGM.getModule().addTypeName("struct._objc_method_description",
1750 MethodDescriptionTy);
1751
1752 MethodDescriptionListTy =
1753 llvm::StructType::get(IntTy,
1754 llvm::ArrayType::get(MethodDescriptionTy, 0),
1755 NULL);
1756 CGM.getModule().addTypeName("struct._objc_method_description_list",
1757 MethodDescriptionListTy);
1758 MethodDescriptionListPtrTy =
1759 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1760
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001761 PropertyTy = llvm::StructType::get(Int8PtrTy,
1762 Int8PtrTy,
1763 NULL);
1764 CGM.getModule().addTypeName("struct._objc_property",
1765 PropertyTy);
1766
1767 PropertyListTy = llvm::StructType::get(IntTy,
1768 IntTy,
1769 llvm::ArrayType::get(PropertyTy, 0),
1770 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001771 CGM.getModule().addTypeName("struct._objc_property_list",
1772 PropertyListTy);
1773 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1774
1775 // Protocol description structures
1776
1777 ProtocolExtensionTy =
1778 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1779 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1780 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1781 PropertyListPtrTy,
1782 NULL);
1783 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1784 ProtocolExtensionTy);
1785 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1786
1787 // Handle recursive construction of Protocl and ProtocolList types
1788
1789 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1790 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1791
1792 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1793 LongTy,
1794 llvm::ArrayType::get(ProtocolTyHolder, 0),
1795 NULL);
1796 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1797
1798 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001799 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001800 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1801 MethodDescriptionListPtrTy,
1802 MethodDescriptionListPtrTy,
1803 NULL);
1804 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1805
1806 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1807 CGM.getModule().addTypeName("struct._objc_protocol_list",
1808 ProtocolListTy);
1809 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1810
1811 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1812 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1813 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001814
1815 // Class description structures
1816
1817 IvarTy = llvm::StructType::get(Int8PtrTy,
1818 Int8PtrTy,
1819 IntTy,
1820 NULL);
1821 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1822
1823 IvarListTy = llvm::OpaqueType::get();
1824 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1825 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1826
1827 MethodTy = llvm::StructType::get(SelectorPtrTy,
1828 Int8PtrTy,
1829 Int8PtrTy,
1830 NULL);
1831 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1832
1833 MethodListTy = llvm::OpaqueType::get();
1834 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1835 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1836
1837 CacheTy = llvm::OpaqueType::get();
1838 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1839 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1840
1841 ClassExtensionTy =
1842 llvm::StructType::get(IntTy,
1843 Int8PtrTy,
1844 PropertyListPtrTy,
1845 NULL);
1846 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1847 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1848
1849 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1850
1851 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1852 llvm::PointerType::getUnqual(ClassTyHolder),
1853 Int8PtrTy,
1854 LongTy,
1855 LongTy,
1856 LongTy,
1857 IvarListPtrTy,
1858 MethodListPtrTy,
1859 CachePtrTy,
1860 ProtocolListPtrTy,
1861 Int8PtrTy,
1862 ClassExtensionPtrTy,
1863 NULL);
1864 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1865
1866 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1867 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1868 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1869
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001870 CategoryTy = llvm::StructType::get(Int8PtrTy,
1871 Int8PtrTy,
1872 MethodListPtrTy,
1873 MethodListPtrTy,
1874 ProtocolListPtrTy,
1875 IntTy,
1876 PropertyListPtrTy,
1877 NULL);
1878 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1879
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00001880 // I'm not sure I like this. The implicit coordination is a bit
1881 // gross. We should solve this in a reasonable fashion because this
1882 // is a pretty common task (match some runtime data structure with
1883 // an LLVM data structure).
1884
1885 // FIXME: This is leaked.
1886 // FIXME: Merge with rewriter code?
1887 RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
1888 SourceLocation(),
Ted Kremenekdf042e62008-09-05 01:34:33 +00001889 &Ctx.Idents.get("_objc_super"));
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00001890 FieldDecl *FieldDecls[2];
1891 FieldDecls[0] = FieldDecl::Create(Ctx, SourceLocation(), 0,
1892 Ctx.getObjCIdType());
1893 FieldDecls[1] = FieldDecl::Create(Ctx, SourceLocation(), 0,
1894 Ctx.getObjCClassType());
Ted Kremenek4b7c9832008-09-05 17:16:31 +00001895 RD->defineBody(Ctx, FieldDecls, 2);
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00001896
1897 SuperCTy = Ctx.getTagDeclType(RD);
1898 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
1899
1900 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001901 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001902
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001903 // Global metadata structures
1904
1905 SymtabTy = llvm::StructType::get(LongTy,
1906 SelectorPtrTy,
1907 ShortTy,
1908 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001909 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001910 NULL);
1911 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1912 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1913
1914 ModuleTy =
1915 llvm::StructType::get(LongTy,
1916 LongTy,
1917 Int8PtrTy,
1918 SymtabPtrTy,
1919 NULL);
1920 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001921
1922 // Message send functions
1923
1924 std::vector<const llvm::Type*> Params;
1925 Params.push_back(ObjectPtrTy);
1926 Params.push_back(SelectorPtrTy);
1927 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1928 Params,
1929 true),
1930 llvm::Function::ExternalLinkage,
1931 "objc_msgSend",
1932 &CGM.getModule());
1933
1934 Params.clear();
1935 Params.push_back(Int8PtrTy);
1936 Params.push_back(ObjectPtrTy);
1937 Params.push_back(SelectorPtrTy);
1938 MessageSendStretFn =
1939 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1940 Params,
1941 true),
1942 llvm::Function::ExternalLinkage,
1943 "objc_msgSend_stret",
1944 &CGM.getModule());
1945
1946 Params.clear();
1947 Params.push_back(SuperPtrTy);
1948 Params.push_back(SelectorPtrTy);
1949 MessageSendSuperFn =
1950 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1951 Params,
1952 true),
1953 llvm::Function::ExternalLinkage,
1954 "objc_msgSendSuper",
1955 &CGM.getModule());
1956
1957 Params.clear();
1958 Params.push_back(Int8PtrTy);
1959 Params.push_back(SuperPtrTy);
1960 Params.push_back(SelectorPtrTy);
1961 MessageSendSuperStretFn =
1962 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1963 Params,
1964 true),
1965 llvm::Function::ExternalLinkage,
1966 "objc_msgSendSuper_stret",
1967 &CGM.getModule());
Anders Carlsson2abd89c2008-08-31 04:05:03 +00001968
1969 // Enumeration mutation.
1970
1971 Params.clear();
1972 Params.push_back(ObjectPtrTy);
1973 EnumerationMutationFn =
1974 llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
1975 Params,
1976 false),
1977 llvm::Function::ExternalLinkage,
1978 "objc_enumerationMutation",
1979 &CGM.getModule());
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001980}
1981
1982ObjCTypesHelper::~ObjCTypesHelper() {
1983}
1984
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001985llvm::Value *ObjCTypesHelper::getMessageSendFn(bool IsSuper,
1986 const llvm::Type *ReturnTy) {
1987 llvm::Function *F;
1988 llvm::FunctionType *CallFTy;
1989
1990 // FIXME: Should we be caching any of this?
1991 if (!ReturnTy->isSingleValueType()) {
1992 F = IsSuper ? MessageSendSuperStretFn : MessageSendStretFn;
1993 std::vector<const llvm::Type*> Params(3);
1994 Params[0] = llvm::PointerType::getUnqual(ReturnTy);
1995 Params[1] = IsSuper ? SuperPtrTy : ObjectPtrTy;
1996 Params[2] = SelectorPtrTy;
1997 CallFTy = llvm::FunctionType::get(llvm::Type::VoidTy, Params, true);
Daniel Dunbar662174c82008-08-29 17:28:43 +00001998 } else { // FIXME: floating point?
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001999 F = IsSuper ? MessageSendSuperFn : MessageSendFn;
2000 std::vector<const llvm::Type*> Params(2);
2001 Params[0] = IsSuper ? SuperPtrTy : ObjectPtrTy;
2002 Params[1] = SelectorPtrTy;
2003 CallFTy = llvm::FunctionType::get(ReturnTy, Params, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00002004 }
2005
Daniel Dunbar14c80b72008-08-23 09:25:55 +00002006 return llvm::ConstantExpr::getBitCast(F,
2007 llvm::PointerType::getUnqual(CallFTy));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00002008}
2009
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00002010/* *** */
2011
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002012CodeGen::CGObjCRuntime *
2013CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00002014 return new CGObjCMac(CGM);
2015}