blob: d3eb85b84871f5b9da94784b3024f49e8bad4a77 [file] [log] [blame]
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This provides Objective-C code generation targetting the Apple runtime.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CGObjCRuntime.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000015
16#include "CodeGenModule.h"
Daniel Dunbarb7ec2462008-08-16 03:19:19 +000017#include "CodeGenFunction.h"
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000018#include "clang/AST/ASTContext.h"
Daniel Dunbare91593e2008-08-11 04:54:23 +000019#include "clang/AST/Decl.h"
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000020#include "clang/AST/DeclObjC.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000021#include "clang/Basic/LangOptions.h"
22
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000023#include "llvm/Module.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000024#include "llvm/Support/IRBuilder.h"
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000025#include "llvm/Target/TargetData.h"
Daniel Dunbarb7ec2462008-08-16 03:19:19 +000026#include <sstream>
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000027
28using namespace clang;
29
30namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000031
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000032 // FIXME: We should find a nicer way to make the labels for
33 // metadata, string concatenation is lame.
34
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000035/// ObjCTypesHelper - Helper class that encapsulates lazy
36/// construction of varies types used during ObjC generation.
37class ObjCTypesHelper {
38private:
39 CodeGen::CodeGenModule &CGM;
40
41 const llvm::StructType *CFStringType;
42 llvm::Constant *CFConstantStringClassReference;
Daniel Dunbare8b470d2008-08-23 04:28:29 +000043 llvm::Function *MessageSendFn, *MessageSendSuperFn;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000044
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000045public:
Daniel Dunbar27f9d772008-08-21 04:36:09 +000046 const llvm::Type *ShortTy, *IntTy, *LongTy;
47 const llvm::Type *Int8PtrTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000048
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000049 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
50 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000051 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000052 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000053 /// ProtocolPtrTy - LLVM type for external protocol handles
54 /// (typeof(Protocol))
55 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000056
Daniel Dunbare8b470d2008-08-23 04:28:29 +000057 /// SuperTy - LLVM type for struct objc_super.
58 const llvm::StructType *SuperTy;
59
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000060 /// SymtabTy - LLVM type for struct objc_symtab.
61 const llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000062 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
63 const llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000064 /// ModuleTy - LLVM type for struct objc_module.
65 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000066
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000067 /// ProtocolTy - LLVM type for struct objc_protocol.
68 const llvm::StructType *ProtocolTy;
69 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
70 const llvm::Type *ProtocolPtrTy;
71 /// ProtocolExtensionTy - LLVM type for struct
72 /// objc_protocol_extension.
73 const llvm::StructType *ProtocolExtensionTy;
74 /// ProtocolExtensionTy - LLVM type for struct
75 /// objc_protocol_extension *.
76 const llvm::Type *ProtocolExtensionPtrTy;
77 /// MethodDescriptionTy - LLVM type for struct
78 /// objc_method_description.
79 const llvm::StructType *MethodDescriptionTy;
80 /// MethodDescriptionListTy - LLVM type for struct
81 /// objc_method_description_list.
82 const llvm::StructType *MethodDescriptionListTy;
83 /// MethodDescriptionListPtrTy - LLVM type for struct
84 /// objc_method_description_list *.
85 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbarc8ef5512008-08-23 00:19:03 +000086 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
87 /// in GCC parlance).
88 const llvm::StructType *PropertyTy;
89 /// PropertyListTy - LLVM type for struct objc_property_list
90 /// (_prop_list_t in GCC parlance).
91 const llvm::StructType *PropertyListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000092 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
93 const llvm::Type *PropertyListPtrTy;
94 /// ProtocolListTy - LLVM type for struct objc_property_list.
95 const llvm::Type *ProtocolListTy;
96 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
97 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +000098 /// CategoryTy - LLVM type for struct objc_category.
99 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000100 /// ClassTy - LLVM type for struct objc_class.
101 const llvm::StructType *ClassTy;
102 /// ClassPtrTy - LLVM type for struct objc_class *.
103 const llvm::Type *ClassPtrTy;
104 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
105 const llvm::StructType *ClassExtensionTy;
106 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
107 const llvm::Type *ClassExtensionPtrTy;
108 /// CacheTy - LLVM type for struct objc_cache.
109 const llvm::Type *CacheTy;
110 /// CachePtrTy - LLVM type for struct objc_cache *.
111 const llvm::Type *CachePtrTy;
112 // IvarTy - LLVM type for struct objc_ivar.
113 const llvm::StructType *IvarTy;
114 /// IvarListTy - LLVM type for struct objc_ivar_list.
115 const llvm::Type *IvarListTy;
116 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
117 const llvm::Type *IvarListPtrTy;
118 // MethodTy - LLVM type for struct objc_method.
119 const llvm::StructType *MethodTy;
120 /// MethodListTy - LLVM type for struct objc_method_list.
121 const llvm::Type *MethodListTy;
122 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
123 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000124
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000125public:
126 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
127 ~ObjCTypesHelper();
128
129 llvm::Constant *getCFConstantStringClassReference();
130 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000131 llvm::Function *getMessageSendFn();
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000132 llvm::Function *getMessageSendSuperFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000133};
134
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000135class CGObjCMac : public CodeGen::CGObjCRuntime {
136private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000137 CodeGen::CodeGenModule &CGM;
138 ObjCTypesHelper ObjCTypes;
139 /// ObjCABI - FIXME: Not sure yet.
140 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000141
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000142 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000143 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000144
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000145 /// MethodVarNames - uniqued method variable names.
146 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
147
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000148 /// MethodVarTypes - uniqued method type signatures. We have to use
149 /// a StringMap here because have no other unique reference.
150 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
151
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000152 /// PropertyNames - uniqued method variable names.
153 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
154
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000155 /// ClassReferences - uniqued class references.
156 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
157
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000158 /// SelectorReferences - uniqued selector references.
159 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
160
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000161 /// Protocols - Protocols for which an objc_protocol structure has
162 /// been emitted. Forward declarations are handled by creating an
163 /// empty structure whose initializer is filled in when/if defined.
164 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
165
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000166 /// DefinedClasses - List of defined classes.
167 std::vector<llvm::GlobalValue*> DefinedClasses;
168
169 /// DefinedCategories - List of defined categories.
170 std::vector<llvm::GlobalValue*> DefinedCategories;
171
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000172 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000173 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000174 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000175
176 /// EmitImageInfo - Emit the image info marker used to encode some module
177 /// level information.
178 void EmitImageInfo();
179
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000180 /// EmitModuleInfo - Another marker encoding module level
181 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000182 void EmitModuleInfo();
183
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000184 /// EmitModuleSymols - Emit module symbols, the list of defined
185 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000186 llvm::Constant *EmitModuleSymbols();
187
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000188 /// FinishModule - Write out global data structures at the end of
189 /// processing a translation unit.
190 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000191
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000192 /// EmitClassExtension - Generate the class extension structure used
193 /// to store the weak ivar layout and properties. The return value
194 /// has type ClassExtensionPtrTy.
195 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
196
197 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
198 /// for the given class.
199 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
200 const ObjCInterfaceDecl *ID);
201
202 /// EmitIvarList - Emit the ivar list for the given
203 /// implementation. If ForClass is true the list of class ivars
204 /// (i.e. metaclass ivars) is emitted, otherwise the list of
205 /// interface ivars will be emitted. The return value has type
206 /// IvarListPtrTy.
207 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
208 bool ForClass,
209 const llvm::Type *InterfaceTy);
210
211 /// EmitMetaClass - Emit a class structure for the metaclass of the
212 /// given implementation. return value has type ClassPtrTy.
213 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
214 llvm::Constant *Protocols,
215 const llvm::Type *InterfaceTy);
216
217 /// EmitMethodList - Emit the method list for the given
218 /// implementation. If ForClass is true the list of class methods
219 /// will be emitted, otherwise the list of instance methods will be
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000220 /// generated. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000221 llvm::Constant *EmitMethodList(const std::string &Name,
222 const char *Section,
223 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
224 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000225
226 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000227 /// method declarations.
228 /// - TypeName: The name for the type containing the methods.
229 /// - IsProtocol: True iff these methods are for a protocol.
230 /// - ClassMethds: True iff these are class methods.
231 /// - Required: When true, only "required" methods are
232 /// listed. Similarly, when false only "optional" methods are
233 /// listed. For classes this should always be true.
234 /// - begin, end: The method list to output.
235 ///
236 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000237 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
238 bool IsProtocol,
239 bool ClassMethods,
240 bool Required,
241 ObjCMethodDecl * const *begin,
242 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000243
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000244 /// EmitPropertyList - Emit the given property list. The return
245 /// value has type PropertyListPtrTy.
246 llvm::Constant *EmitPropertyList(const std::string &Name,
247 ObjCPropertyDecl * const *begin,
248 ObjCPropertyDecl * const *end);
249
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000250 /// EmitProtocolExtension - Generate the protocol extension
251 /// structure used to store optional instance and class methods, and
252 /// protocol properties. The return value has type
253 /// ProtocolExtensionPtrTy.
254 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
255
256 /// EmitProtocolList - Generate the list of referenced
257 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc93372008-08-21 21:57:41 +0000258 llvm::Constant *EmitProtocolList(const std::string &Name,
259 ObjCProtocolDecl::protocol_iterator begin,
260 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000261
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000262 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
263 /// for the given selector.
264 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
265
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000266 /// GetProtocolRef - Return a reference to the internal protocol
267 /// description, creating an empty one if it has not been
268 /// defined. The return value has type pointer-to ProtocolTy.
269 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
270
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000271 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000272 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000273 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000274
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000275 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000276 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000277 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000278 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000279 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000280
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000281 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000282 /// selector's name. The return value has type char *.
283
284 // FIXME: This is a horrible name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000285 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000286 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000287
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000288 /// GetPropertyName - Return a unique constant for the given
289 /// name. The return value has type char *.
290 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
291
292 // FIXME: This is a horrible name too.
293 llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
294
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000295 /// GetNameForMethod - Return a name for the given method.
296 /// \param[out] NameOut - The return value.
297 void GetNameForMethod(const ObjCMethodDecl *OMD,
298 std::string &NameOut);
299
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000300public:
301 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000302 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000303
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000304 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
305 const ObjCMessageExpr *E,
306 llvm::Value *Receiver);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000307
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000308 virtual CodeGen::RValue
309 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
310 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000311 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000312 llvm::Value *Receiver);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000313
314 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000315 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000316
317 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
318
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000319 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000320
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000321 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000322
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000323 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000324
325 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000326 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000327
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000328 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000329
330 virtual llvm::Function *ModuleInitFunction();
331};
332} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000333
334/* *** Helper Functions *** */
335
336/// getConstantGEP() - Help routine to construct simple GEPs.
337static llvm::Constant *getConstantGEP(llvm::Constant *C,
338 unsigned idx0,
339 unsigned idx1) {
340 llvm::Value *Idxs[] = {
341 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
342 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
343 };
344 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
345}
346
347/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000348
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000349CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
350 : CGM(cgm),
351 ObjCTypes(cgm),
352 ObjCABI(1)
353{
354 // FIXME: How does this get set in GCC? And what does it even mean?
355 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
356 ObjCABI = 2;
357
358 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000359}
360
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000361/// GetClass - Return a reference to the class for the given interface
362/// decl.
363llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000364 const ObjCInterfaceDecl *ID) {
365 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000366}
367
368/// GetSelector - Return the pointer to the unique'd string for this selector.
369llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000370 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000371}
372
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000373/// Generate a constant CFString object.
374/*
375 struct __builtin_CFString {
376 const int *isa; // point to __CFConstantStringClassReference
377 int flags;
378 const char *str;
379 long length;
380 };
381*/
382
383llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
384 // FIXME: I have no idea what this constant is (it is a magic
385 // constant in GCC as well). Most likely the encoding of the string
386 // and at least one part of it relates to UTF-16. Is this just the
387 // code for UTF-8? Where is this handled for us?
388 // See: <rdr://2996215>
389 unsigned flags = 0x07c8;
390
391 // FIXME: Use some machinery to unique this. We can't reuse the CGM
392 // one since we put them in a different section.
393 llvm::Constant *StringC = llvm::ConstantArray::get(String);
394 llvm::Constant *StringGV =
395 new llvm::GlobalVariable(StringC->getType(), true,
396 llvm::GlobalValue::InternalLinkage,
397 StringC, ".str", &CGM.getModule());
398 llvm::Constant *Values[4] = {
399 ObjCTypes.getCFConstantStringClassReference(),
400 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
401 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
402 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
403 };
404
405 llvm::Constant *CFStringC =
406 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
407 std::vector<llvm::Constant*>(Values, Values+4));
408
409 llvm::GlobalVariable *CFStringGV =
410 new llvm::GlobalVariable(CFStringC->getType(), true,
411 llvm::GlobalValue::InternalLinkage,
412 CFStringC, "",
413 &CGM.getModule());
414
415 CFStringGV->setSection("__DATA, __cfstring");
416
417 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000418}
419
420/// Generates a message send where the super is the receiver. This is
421/// a message send to self with special delivery semantics indicating
422/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000423CodeGen::RValue
424CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
425 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000426 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000427 llvm::Value *Receiver) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000428 // FIXME: This should be cached, not looked up every time. Meh. We
429 // should just make sure the optimizer hits it.
430 llvm::Value *ReceiverClass = EmitClassRef(CGF.Builder, SuperClass);
431
432 // Create and init a super structure; this is a (receiver, class)
433 // pair we will pass to objc_msgSendSuper.
434 llvm::Value *ObjCSuper =
435 CGF.Builder.CreateAlloca(ObjCTypes.SuperTy, 0, "objc_super");
436 llvm::Value *ReceiverAsObject =
437 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
438 CGF.Builder.CreateStore(ReceiverAsObject,
439 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
440 CGF.Builder.CreateStore(ReceiverClass,
441 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
442
443 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
444 llvm::Function *F = ObjCTypes.getMessageSendSuperFn();
445 llvm::Value *Args[2];
446 Args[0] = ObjCSuper;
447 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
448
449 std::vector<const llvm::Type*> Params(2);
450 Params[0] = llvm::PointerType::getUnqual(ObjCTypes.SuperTy);
451 Params[1] = ObjCTypes.SelectorPtrTy;
452 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
453 Params,
454 true);
455 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
456 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
457 return CGF.EmitCallExprExt(C, E->getType(),
458 E->arg_begin(),
459 E->arg_end(),
460 Args, 2);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000461}
462
463/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000464CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
465 const ObjCMessageExpr *E,
466 llvm::Value *Receiver) {
467 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000468 llvm::Function *F = ObjCTypes.getMessageSendFn();
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000469 llvm::Value *Args[2];
470 Args[0] = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
471 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000472
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000473 std::vector<const llvm::Type*> Params(2);
474 Params[0] = ObjCTypes.ObjectPtrTy;
475 Params[1] = ObjCTypes.SelectorPtrTy;
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000476 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
477 Params,
478 true);
479 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
480 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000481 return CGF.EmitCallExprExt(C, E->getType(),
482 E->arg_begin(),
483 E->arg_end(),
484 Args, 2);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000485}
486
487llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000488 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000489 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
490 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000491}
492
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000493/*
494 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
495 struct _objc_protocol {
496 struct _objc_protocol_extension *isa;
497 char *protocol_name;
498 struct _objc_protocol_list *protocol_list;
499 struct _objc__method_prototype_list *instance_methods;
500 struct _objc__method_prototype_list *class_methods
501 };
502
503 See EmitProtocolExtension().
504*/
505void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
506 const char *ProtocolName = PD->getName();
507
508 std::vector<llvm::Constant*> Values(5);
509 Values[0] = EmitProtocolExtension(PD);
510 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000511 Values[2] =
512 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
513 PD->protocol_begin(),
514 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000515 Values[3] = EmitMethodDescList(ProtocolName,
516 true, // IsProtocol
517 false, // ClassMethods
518 true, // Required
519 PD->instmeth_begin(),
520 PD->instmeth_end());
521 Values[4] = EmitMethodDescList(ProtocolName,
522 true, // IsProtocol
523 true, // ClassMethods
524 true, // Required
525 PD->classmeth_begin(),
526 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000527 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
528 Values);
529
530 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
531 if (Entry) {
532 // Already created, just update the initializer
533 Entry->setInitializer(Init);
534 } else {
535 Entry =
536 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
537 llvm::GlobalValue::InternalLinkage,
538 Init,
539 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
540 &CGM.getModule());
541 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
542 UsedGlobals.push_back(Entry);
543 // FIXME: Is this necessary? Why only for protocol?
544 Entry->setAlignment(4);
545 }
546}
547
548llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
549 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
550
551 if (!Entry) {
552 std::vector<llvm::Constant*> Values(5);
553 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
554 Values[1] = GetClassName(PD->getIdentifier());
555 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
556 Values[3] = Values[4] =
557 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
558 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
559 Values);
560
561 Entry =
562 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
563 llvm::GlobalValue::InternalLinkage,
564 Init,
565 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
566 &CGM.getModule());
567 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
568 UsedGlobals.push_back(Entry);
569 // FIXME: Is this necessary? Why only for protocol?
570 Entry->setAlignment(4);
571 }
572
573 return Entry;
574}
575
576/*
577 struct _objc_protocol_extension {
578 uint32_t size;
579 struct objc_method_description_list *optional_instance_methods;
580 struct objc_method_description_list *optional_class_methods;
581 struct objc_property_list *instance_properties;
582 };
583*/
584llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
585 uint64_t Size =
586 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
587 std::vector<llvm::Constant*> Values(4);
588 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000589 Values[1] = EmitMethodDescList(PD->getName(),
590 true, // IsProtocol
591 false, // ClassMethods
592 false, // Required
593 PD->instmeth_begin(),
594 PD->instmeth_end());
595 Values[2] = EmitMethodDescList(PD->getName(),
596 true, // IsProtocol
597 true, // ClassMethods
598 false, // Required
599 PD->classmeth_begin(),
600 PD->classmeth_end());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000601 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
602 PD->getName(),
603 PD->classprop_begin(),
604 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000605
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000606 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000607 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
608 Values[3]->isNullValue())
609 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
610
611 llvm::Constant *Init =
612 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
613 llvm::GlobalVariable *GV =
614 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
615 llvm::GlobalValue::InternalLinkage,
616 Init,
617 (std::string("\01L_OBJC_PROTOCOLEXT_") +
618 PD->getName()),
619 &CGM.getModule());
620 // No special section, but goes in llvm.used
621 UsedGlobals.push_back(GV);
622
623 return GV;
624}
625
626/*
627 struct objc_protocol_list {
628 struct objc_protocol_list *next;
629 long count;
630 Protocol *list[];
631 };
632*/
Daniel Dunbardbc93372008-08-21 21:57:41 +0000633llvm::Constant *
634CGObjCMac::EmitProtocolList(const std::string &Name,
635 ObjCProtocolDecl::protocol_iterator begin,
636 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000637 std::vector<llvm::Constant*> ProtocolRefs;
638
Daniel Dunbardbc93372008-08-21 21:57:41 +0000639 for (; begin != end; ++begin)
640 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000641
642 // Just return null for empty protocol lists
643 if (ProtocolRefs.empty())
644 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
645
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000646 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000647 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
648
649 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000650 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000651 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
652 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
653 Values[2] =
654 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
655 ProtocolRefs.size()),
656 ProtocolRefs);
657
658 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
659 llvm::GlobalVariable *GV =
660 new llvm::GlobalVariable(Init->getType(), false,
661 llvm::GlobalValue::InternalLinkage,
662 Init,
Daniel Dunbardbc93372008-08-21 21:57:41 +0000663 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000664 &CGM.getModule());
665 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
666 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
667}
668
669/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000670 struct _objc_property {
671 const char * const name;
672 const char * const attributes;
673 };
674
675 struct _objc_property_list {
676 uint32_t entsize; // sizeof (struct _objc_property)
677 uint32_t prop_count;
678 struct _objc_property[prop_count];
679 };
680*/
681llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
682 ObjCPropertyDecl * const *begin,
683 ObjCPropertyDecl * const *end) {
684 std::vector<llvm::Constant*> Properties, Prop(2);
685 for (; begin != end; ++begin) {
686 const ObjCPropertyDecl *PD = *begin;
687 Prop[0] = GetPropertyName(PD->getIdentifier());
688 Prop[1] = GetPropertyType(PD);
689 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
690 Prop));
691 }
692
693 // Return null for empty list.
694 if (Properties.empty())
695 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
696
697 unsigned PropertySize =
698 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
699 std::vector<llvm::Constant*> Values(3);
700 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
701 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
702 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
703 Properties.size());
704 Values[2] = llvm::ConstantArray::get(AT, Properties);
705 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
706
707 llvm::GlobalVariable *GV =
708 new llvm::GlobalVariable(Init->getType(), false,
709 llvm::GlobalValue::InternalLinkage,
710 Init,
711 Name,
712 &CGM.getModule());
713 // No special section on property lists?
714 UsedGlobals.push_back(GV);
715 return llvm::ConstantExpr::getBitCast(GV,
716 ObjCTypes.PropertyListPtrTy);
717
718}
719
720/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000721 struct objc_method_description_list {
722 int count;
723 struct objc_method_description list[];
724 };
725*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000726llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
727 bool IsProtocol,
728 bool ClassMethods,
729 bool Required,
730 ObjCMethodDecl * const *begin,
731 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000732 std::vector<llvm::Constant*> Methods, Desc(2);
733 for (; begin != end; ++begin) {
734 ObjCMethodDecl *D = *begin;
735 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
736
737 // Skip if this method is required and we are outputting optional
738 // methods, or vice versa.
739 if (Required != IsRequired)
740 continue;
741
742 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
743 ObjCTypes.SelectorPtrTy);
744 Desc[1] = GetMethodVarType(D);
745 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
746 Desc));
747 }
748
749 // Return null for empty list.
750 if (Methods.empty())
751 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
752
753 std::vector<llvm::Constant*> Values(2);
754 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
755 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
756 Methods.size());
757 Values[1] = llvm::ConstantArray::get(AT, Methods);
758 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
759
760 char Prefix[256];
761 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
762 IsProtocol ? "PROTOCOL_" : "",
763 ClassMethods ? "CLASS_" : "INSTANCE_",
764 !Required ? "OPT_" : "");
765 llvm::GlobalVariable *GV =
766 new llvm::GlobalVariable(Init->getType(), false,
767 llvm::GlobalValue::InternalLinkage,
768 Init,
769 std::string(Prefix) + TypeName,
770 &CGM.getModule());
771 if (ClassMethods) {
772 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
773 } else {
774 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
775 }
776 UsedGlobals.push_back(GV);
777 return llvm::ConstantExpr::getBitCast(GV,
778 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000779}
780
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000781/*
782 struct _objc_category {
783 char *category_name;
784 char *class_name;
785 struct _objc_method_list *instance_methods;
786 struct _objc_method_list *class_methods;
787 struct _objc_protocol_list *protocols;
788 uint32_t size; // <rdar://4585769>
789 struct _objc_property_list *instance_properties;
790 };
791 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000792void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000793 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
794
795 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
796 std::string ExtName(std::string(Interface->getName()) +
797 "_" +
798 OCD->getName());
799
800 std::vector<llvm::Constant*> Values(7);
801 Values[0] = GetClassName(OCD->getIdentifier());
802 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000803 Values[2] =
804 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
805 ExtName,
806 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
807 OCD->instmeth_begin(),
808 OCD->instmeth_end());
809 Values[3] =
810 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
811 "__OBJC,__cat_class_meth,regular,no_dead_strip",
812 OCD->classmeth_begin(),
813 OCD->classmeth_end());
814 Values[4] =
815 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
816 Interface->protocol_begin(),
817 Interface->protocol_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000818 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000819 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
820 Interface->classprop_begin(),
821 Interface->classprop_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000822
823 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
824 Values);
825
826 llvm::GlobalVariable *GV =
827 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
828 llvm::GlobalValue::InternalLinkage,
829 Init,
830 std::string("\01L_OBJC_CATEGORY_")+ExtName,
831 &CGM.getModule());
832 GV->setSection("__OBJC,__category,regular,no_dead_strip");
833 UsedGlobals.push_back(GV);
834 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000835}
836
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000837// FIXME: Get from somewhere?
838enum ClassFlags {
839 eClassFlags_Factory = 0x00001,
840 eClassFlags_Meta = 0x00002,
841 // <rdr://5142207>
842 eClassFlags_HasCXXStructors = 0x02000,
843 eClassFlags_Hidden = 0x20000,
844 eClassFlags_ABI2_Hidden = 0x00010,
845 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
846};
847
848// <rdr://5142207&4705298&4843145>
849static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
850 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
851 // FIXME: Support -fvisibility
852 switch (attr->getVisibility()) {
853 default:
854 assert(0 && "Unknown visibility");
855 return false;
856 case VisibilityAttr::DefaultVisibility:
857 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
858 return false;
859 case VisibilityAttr::HiddenVisibility:
860 return true;
861 }
862 } else {
863 return false; // FIXME: Support -fvisibility
864 }
865}
866
867/*
868 struct _objc_class {
869 Class isa;
870 Class super_class;
871 const char *name;
872 long version;
873 long info;
874 long instance_size;
875 struct _objc_ivar_list *ivars;
876 struct _objc_method_list *methods;
877 struct _objc_cache *cache;
878 struct _objc_protocol_list *protocols;
879 // Objective-C 1.0 extensions (<rdr://4585769>)
880 const char *ivar_layout;
881 struct _objc_class_ext *ext;
882 };
883
884 See EmitClassExtension();
885 */
886void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
887 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000888 // FIXME: Gross
889 ObjCInterfaceDecl *Interface =
890 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000891 llvm::Constant *Protocols =
892 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
893 Interface->protocol_begin(),
894 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000895 const llvm::Type *InterfaceTy =
896 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
897 unsigned Flags = eClassFlags_Factory;
898 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
899
900 // FIXME: Set CXX-structors flag.
901 if (IsClassHidden(ID->getClassInterface()))
902 Flags |= eClassFlags_Hidden;
903
904 std::vector<llvm::Constant*> Values(12);
905 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
906 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
907 Values[ 1] =
908 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
909 ObjCTypes.ClassPtrTy);
910 } else {
911 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
912 }
913 Values[ 2] = GetClassName(ID->getIdentifier());
914 // Version is always 0.
915 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
916 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
917 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
918 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000919 Values[ 7] =
920 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
921 "__OBJC,__inst_meth,regular,no_dead_strip",
922 ID->instmeth_begin(),
923 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000924 // cache is always NULL.
925 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
926 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000927 // FIXME: Set ivar_layout
928 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000929 Values[11] = EmitClassExtension(ID);
930 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
931 Values);
932
933 llvm::GlobalVariable *GV =
934 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
935 llvm::GlobalValue::InternalLinkage,
936 Init,
937 std::string("\01L_OBJC_CLASS_")+ClassName,
938 &CGM.getModule());
939 GV->setSection("__OBJC,__class,regular,no_dead_strip");
940 UsedGlobals.push_back(GV);
941 // FIXME: Why?
942 GV->setAlignment(32);
943 DefinedClasses.push_back(GV);
944}
945
946llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
947 llvm::Constant *Protocols,
948 const llvm::Type *InterfaceTy) {
949 const char *ClassName = ID->getName();
950 unsigned Flags = eClassFlags_Meta;
951 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
952
953 if (IsClassHidden(ID->getClassInterface()))
954 Flags |= eClassFlags_Hidden;
955
956 std::vector<llvm::Constant*> Values(12);
957 // The isa for the metaclass is the root of the hierarchy.
958 const ObjCInterfaceDecl *Root = ID->getClassInterface();
959 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
960 Root = Super;
961 Values[ 0] =
962 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
963 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000964 // The super class for the metaclass is emitted as the name of the
965 // super class. The runtime fixes this up to point to the
966 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000967 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
968 Values[ 1] =
969 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
970 ObjCTypes.ClassPtrTy);
971 } else {
972 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
973 }
974 Values[ 2] = GetClassName(ID->getIdentifier());
975 // Version is always 0.
976 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
977 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
978 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
979 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000980 Values[ 7] =
981 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
982 "__OBJC,__inst_meth,regular,no_dead_strip",
983 ID->classmeth_begin(),
984 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000985 // cache is always NULL.
986 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
987 Values[ 9] = Protocols;
988 // ivar_layout for metaclass is always NULL.
989 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
990 // The class extension is always unused for metaclasses.
991 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
992 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
993 Values);
994
995 llvm::GlobalVariable *GV =
996 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
997 llvm::GlobalValue::InternalLinkage,
998 Init,
999 std::string("\01L_OBJC_METACLASS_")+ClassName,
1000 &CGM.getModule());
1001 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
1002 UsedGlobals.push_back(GV);
1003 // FIXME: Why?
1004 GV->setAlignment(32);
1005
1006 return GV;
1007}
1008
1009/*
1010 struct objc_class_ext {
1011 uint32_t size;
1012 const char *weak_ivar_layout;
1013 struct _objc_property_list *properties;
1014 };
1015*/
1016llvm::Constant *
1017CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
1018 uint64_t Size =
1019 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
1020
1021 std::vector<llvm::Constant*> Values(3);
1022 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001023 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001024 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001025 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1026 ID->getName(),
1027 ID->getClassInterface()->classprop_begin(),
1028 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001029
1030 // Return null if no extension bits are used.
1031 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1032 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1033
1034 llvm::Constant *Init =
1035 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1036 llvm::GlobalVariable *GV =
1037 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1038 llvm::GlobalValue::InternalLinkage,
1039 Init,
1040 (std::string("\01L_OBJC_CLASSEXT_") +
1041 ID->getName()),
1042 &CGM.getModule());
1043 // No special section, but goes in llvm.used
1044 UsedGlobals.push_back(GV);
1045
1046 return GV;
1047}
1048
1049/*
1050 struct objc_ivar {
1051 char *ivar_name;
1052 char *ivar_type;
1053 int ivar_offset;
1054 };
1055
1056 struct objc_ivar_list {
1057 int ivar_count;
1058 struct objc_ivar list[count];
1059 };
1060 */
1061llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1062 bool ForClass,
1063 const llvm::Type *InterfaceTy) {
1064 std::vector<llvm::Constant*> Ivars, Ivar(3);
1065
1066 // When emitting the root class GCC emits ivar entries for the
1067 // actual class structure. It is not clear if we need to follow this
1068 // behavior; for now lets try and get away with not doing it. If so,
1069 // the cleanest solution would be to make up an ObjCInterfaceDecl
1070 // for the class.
1071 if (ForClass)
1072 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1073
1074 const llvm::StructLayout *Layout =
1075 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1076 for (ObjCInterfaceDecl::ivar_iterator
1077 i = ID->getClassInterface()->ivar_begin(),
1078 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1079 ObjCIvarDecl *V = *i;
1080 unsigned Offset =
1081 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1082 std::string TypeStr;
1083 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1084 Ivar[0] = GetMethodVarName(V->getIdentifier());
1085 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1086 EncodingRecordTypes);
1087 Ivar[1] = GetMethodVarType(TypeStr);
1088 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1089 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1090 Ivar));
1091 }
1092
1093 // Return null for empty list.
1094 if (Ivars.empty())
1095 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1096
1097 std::vector<llvm::Constant*> Values(2);
1098 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1099 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1100 Ivars.size());
1101 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1102 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1103
1104 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1105 "\01L_OBJC_INSTANCE_VARIABLES_");
1106 llvm::GlobalVariable *GV =
1107 new llvm::GlobalVariable(Init->getType(), false,
1108 llvm::GlobalValue::InternalLinkage,
1109 Init,
1110 std::string(Prefix) + ID->getName(),
1111 &CGM.getModule());
1112 if (ForClass) {
1113 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1114 // FIXME: Why is this only here?
1115 GV->setAlignment(32);
1116 } else {
1117 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1118 }
1119 UsedGlobals.push_back(GV);
1120 return llvm::ConstantExpr::getBitCast(GV,
1121 ObjCTypes.IvarListPtrTy);
1122}
1123
1124/*
1125 struct objc_method {
1126 SEL method_name;
1127 char *method_types;
1128 void *method;
1129 };
1130
1131 struct objc_method_list {
1132 struct objc_method_list *obsolete;
1133 int count;
1134 struct objc_method methods_list[count];
1135 };
1136*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001137llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1138 const char *Section,
1139 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1140 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001141 std::vector<llvm::Constant*> Methods, Method(3);
1142
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001143 for (; begin != end; ++begin) {
1144 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001145
1146 Method[0] =
1147 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1148 ObjCTypes.SelectorPtrTy);
1149 Method[1] = GetMethodVarType(MD);
1150
1151 // FIXME: This is gross, we shouldn't be looking up by name.
1152 std::string Name;
1153 GetNameForMethod(MD, Name);
1154 Method[2] =
1155 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1156 ObjCTypes.Int8PtrTy);
1157 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1158 Method));
1159 }
1160
1161 // Return null for empty list.
1162 if (Methods.empty())
1163 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1164
1165 std::vector<llvm::Constant*> Values(3);
1166 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1167 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1168 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1169 Methods.size());
1170 Values[2] = llvm::ConstantArray::get(AT, Methods);
1171 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1172
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001173 llvm::GlobalVariable *GV =
1174 new llvm::GlobalVariable(Init->getType(), false,
1175 llvm::GlobalValue::InternalLinkage,
1176 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001177 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001178 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001179 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001180 UsedGlobals.push_back(GV);
1181 return llvm::ConstantExpr::getBitCast(GV,
1182 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001183}
1184
1185llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1186 const llvm::Type *ReturnTy =
1187 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1188 const llvm::Type *SelfTy =
1189 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1190
1191 std::vector<const llvm::Type*> ArgTys;
1192 ArgTys.reserve(1 + 2 + OMD->param_size());
1193
1194 // FIXME: This is not something we should have to be dealing with
1195 // here.
1196 bool useStructRet =
1197 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1198 if (useStructRet) {
1199 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1200 ReturnTy = llvm::Type::VoidTy;
1201 }
1202
1203 // Implicit arguments
1204 ArgTys.push_back(SelfTy);
1205 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1206
1207 for (ObjCMethodDecl::param_const_iterator
1208 i = OMD->param_begin(), e = OMD->param_end();
1209 i != e; ++i) {
1210 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001211 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001212 ArgTys.push_back(Ty);
1213 } else {
1214 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1215 }
1216 }
1217
1218 std::string Name;
1219 GetNameForMethod(OMD, Name);
1220
1221 llvm::Function *Method =
1222 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1223 ArgTys,
1224 OMD->isVariadic()),
1225 llvm::GlobalValue::InternalLinkage,
1226 Name,
1227 &CGM.getModule());
1228
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001229 unsigned Offset = 3; // Return plus self and selector implicit args.
1230 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001231 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001232 ++Offset;
1233 }
1234
1235 // FIXME: This is horrible, we need to be reusing the machinery in
1236 // CodeGenModule.cpp (SetFunctionAttributes).
1237 for (ObjCMethodDecl::param_const_iterator
1238 i = OMD->param_begin(), e = OMD->param_end();
1239 i != e; ++i, ++Offset) {
1240 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1241 if (!Ty->isSingleValueType())
1242 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1243 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001244
1245 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001246}
1247
1248llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001249 // Abuse this interface function as a place to finalize.
1250 FinishModule();
1251
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001252 return NULL;
1253}
1254
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001255/* *** Private Interface *** */
1256
1257/// EmitImageInfo - Emit the image info marker used to encode some module
1258/// level information.
1259///
1260/// See: <rdr://4810609&4810587&4810587>
1261/// struct IMAGE_INFO {
1262/// unsigned version;
1263/// unsigned flags;
1264/// };
1265enum ImageInfoFlags {
1266 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1267 eImageInfo_GarbageCollected = (1 << 1),
1268 eImageInfo_GCOnly = (1 << 2)
1269};
1270
1271void CGObjCMac::EmitImageInfo() {
1272 unsigned version = 0; // Version is unused?
1273 unsigned flags = 0;
1274
1275 // FIXME: Fix and continue?
1276 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1277 flags |= eImageInfo_GarbageCollected;
1278 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1279 flags |= eImageInfo_GCOnly;
1280
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001281 // Emitted as int[2];
1282 llvm::Constant *values[2] = {
1283 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1284 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1285 };
1286 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001287 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001288 new llvm::GlobalVariable(AT, true,
1289 llvm::GlobalValue::InternalLinkage,
1290 llvm::ConstantArray::get(AT, values, 2),
1291 "\01L_OBJC_IMAGE_INFO",
1292 &CGM.getModule());
1293
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001294 if (ObjCABI == 1) {
1295 GV->setSection("__OBJC, __image_info,regular");
1296 } else {
1297 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1298 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001299
1300 UsedGlobals.push_back(GV);
1301}
1302
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001303
1304// struct objc_module {
1305// unsigned long version;
1306// unsigned long size;
1307// const char *name;
1308// Symtab symtab;
1309// };
1310
1311// FIXME: Get from somewhere
1312static const int ModuleVersion = 7;
1313
1314void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001315 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1316
1317 std::vector<llvm::Constant*> Values(4);
1318 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1319 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001320 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001321 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001322 Values[3] = EmitModuleSymbols();
1323
1324 llvm::GlobalVariable *GV =
1325 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1326 llvm::GlobalValue::InternalLinkage,
1327 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1328 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001329 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001330 &CGM.getModule());
1331 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1332 UsedGlobals.push_back(GV);
1333}
1334
1335llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001336 std::vector<llvm::Constant*> Values(5);
1337 unsigned NumClasses = DefinedClasses.size();
1338 unsigned NumCategories = DefinedCategories.size();
1339
1340 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1341 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1342 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1343 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1344
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001345 // The runtime expects exactly the list of defined classes followed
1346 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001347 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001348 for (unsigned i=0; i<NumClasses; i++)
1349 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1350 ObjCTypes.Int8PtrTy);
1351 for (unsigned i=0; i<NumCategories; i++)
1352 Symbols[NumClasses + i] =
1353 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1354 ObjCTypes.Int8PtrTy);
1355
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001356 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001357 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001358 NumClasses + NumCategories),
1359 Symbols);
1360
1361 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1362
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001363 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001364 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001365 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001366 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001367 "\01L_OBJC_SYMBOLS",
1368 &CGM.getModule());
1369 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1370 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001371 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1372}
1373
1374llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1375 const ObjCInterfaceDecl *ID) {
1376 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1377
1378 if (!Entry) {
1379 llvm::Constant *Casted =
1380 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1381 ObjCTypes.ClassPtrTy);
1382 Entry =
1383 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1384 llvm::GlobalValue::InternalLinkage,
1385 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1386 &CGM.getModule());
1387 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1388 UsedGlobals.push_back(Entry);
1389 }
1390
1391 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001392}
1393
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001394llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1395 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1396
1397 if (!Entry) {
1398 llvm::Constant *Casted =
1399 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1400 ObjCTypes.SelectorPtrTy);
1401 Entry =
1402 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1403 llvm::GlobalValue::InternalLinkage,
1404 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1405 &CGM.getModule());
1406 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1407 UsedGlobals.push_back(Entry);
1408 }
1409
1410 return Builder.CreateLoad(Entry, false, "tmp");
1411}
1412
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001413llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1414 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001415
1416 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001417 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001418 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001419 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001420 llvm::GlobalValue::InternalLinkage,
1421 C, "\01L_OBJC_CLASS_NAME_",
1422 &CGM.getModule());
1423 Entry->setSection("__TEXT,__cstring,cstring_literals");
1424 UsedGlobals.push_back(Entry);
1425 }
1426
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001427 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001428}
1429
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001430llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1431 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1432
1433 if (!Entry) {
1434 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1435 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001436 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001437 llvm::GlobalValue::InternalLinkage,
1438 C, "\01L_OBJC_METH_VAR_NAME_",
1439 &CGM.getModule());
1440 Entry->setSection("__TEXT,__cstring,cstring_literals");
1441 UsedGlobals.push_back(Entry);
1442 }
1443
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001444 return getConstantGEP(Entry, 0, 0);
1445}
1446
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001447// FIXME: Merge into a single cstring creation function.
1448llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1449 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1450}
1451
1452// FIXME: Merge into a single cstring creation function.
1453llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1454 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1455}
1456
1457llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1458 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001459
1460 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001461 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001462 Entry =
1463 new llvm::GlobalVariable(C->getType(), false,
1464 llvm::GlobalValue::InternalLinkage,
1465 C, "\01L_OBJC_METH_VAR_TYPE_",
1466 &CGM.getModule());
1467 Entry->setSection("__TEXT,__cstring,cstring_literals");
1468 UsedGlobals.push_back(Entry);
1469 }
1470
1471 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001472}
1473
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001474// FIXME: Merge into a single cstring creation function.
1475llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1476 std::string TypeStr;
1477 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1478 return GetMethodVarType(TypeStr);
1479}
1480
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001481// FIXME: Merge into a single cstring creation function.
1482llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1483 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1484
1485 if (!Entry) {
1486 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1487 Entry =
1488 new llvm::GlobalVariable(C->getType(), false,
1489 llvm::GlobalValue::InternalLinkage,
1490 C, "\01L_OBJC_PROP_NAME_ATTR_",
1491 &CGM.getModule());
1492 Entry->setSection("__TEXT,__cstring,cstring_literals");
1493 UsedGlobals.push_back(Entry);
1494 }
1495
1496 return getConstantGEP(Entry, 0, 0);
1497}
1498
1499// FIXME: Merge into a single cstring creation function.
1500llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1501 std::string TypeStr("MOOO!");
1502 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1503 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1504}
1505
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001506void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1507 std::string &NameOut) {
1508 // FIXME: Find the mangling GCC uses.
1509 std::stringstream s;
1510 s << (D->isInstance() ? "-" : "+");
1511 s << "[";
1512 s << D->getClassInterface()->getName();
1513 s << " ";
1514 s << D->getSelector().getName();
1515 s << "]";
1516 NameOut = s.str();
1517}
1518
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001519void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001520 EmitModuleInfo();
1521
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001522 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001523
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001524 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001525 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001526 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001527 }
1528
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001529 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001530 llvm::GlobalValue *GV =
1531 new llvm::GlobalVariable(AT, false,
1532 llvm::GlobalValue::AppendingLinkage,
1533 llvm::ConstantArray::get(AT, Used),
1534 "llvm.used",
1535 &CGM.getModule());
1536
1537 GV->setSection("llvm.metadata");
1538}
1539
1540/* *** */
1541
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001542ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
1543 : CGM(cgm),
1544 CFStringType(0),
1545 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001546 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001547{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001548 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1549 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001550
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001551 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001552 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001553 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001554 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1555
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001556 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1557 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001558
1559 // FIXME: It would be nice to unify this with the opaque type, so
1560 // that the IR comes out a bit cleaner.
1561 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1562 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001563
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001564 MethodDescriptionTy =
1565 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001566 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001567 NULL);
1568 CGM.getModule().addTypeName("struct._objc_method_description",
1569 MethodDescriptionTy);
1570
1571 MethodDescriptionListTy =
1572 llvm::StructType::get(IntTy,
1573 llvm::ArrayType::get(MethodDescriptionTy, 0),
1574 NULL);
1575 CGM.getModule().addTypeName("struct._objc_method_description_list",
1576 MethodDescriptionListTy);
1577 MethodDescriptionListPtrTy =
1578 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1579
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001580 PropertyTy = llvm::StructType::get(Int8PtrTy,
1581 Int8PtrTy,
1582 NULL);
1583 CGM.getModule().addTypeName("struct._objc_property",
1584 PropertyTy);
1585
1586 PropertyListTy = llvm::StructType::get(IntTy,
1587 IntTy,
1588 llvm::ArrayType::get(PropertyTy, 0),
1589 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001590 CGM.getModule().addTypeName("struct._objc_property_list",
1591 PropertyListTy);
1592 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1593
1594 // Protocol description structures
1595
1596 ProtocolExtensionTy =
1597 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1598 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1599 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1600 PropertyListPtrTy,
1601 NULL);
1602 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1603 ProtocolExtensionTy);
1604 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1605
1606 // Handle recursive construction of Protocl and ProtocolList types
1607
1608 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1609 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1610
1611 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1612 LongTy,
1613 llvm::ArrayType::get(ProtocolTyHolder, 0),
1614 NULL);
1615 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1616
1617 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001618 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001619 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1620 MethodDescriptionListPtrTy,
1621 MethodDescriptionListPtrTy,
1622 NULL);
1623 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1624
1625 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1626 CGM.getModule().addTypeName("struct._objc_protocol_list",
1627 ProtocolListTy);
1628 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1629
1630 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1631 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1632 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001633
1634 // Class description structures
1635
1636 IvarTy = llvm::StructType::get(Int8PtrTy,
1637 Int8PtrTy,
1638 IntTy,
1639 NULL);
1640 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1641
1642 IvarListTy = llvm::OpaqueType::get();
1643 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1644 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1645
1646 MethodTy = llvm::StructType::get(SelectorPtrTy,
1647 Int8PtrTy,
1648 Int8PtrTy,
1649 NULL);
1650 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1651
1652 MethodListTy = llvm::OpaqueType::get();
1653 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1654 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1655
1656 CacheTy = llvm::OpaqueType::get();
1657 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1658 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1659
1660 ClassExtensionTy =
1661 llvm::StructType::get(IntTy,
1662 Int8PtrTy,
1663 PropertyListPtrTy,
1664 NULL);
1665 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1666 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1667
1668 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1669
1670 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1671 llvm::PointerType::getUnqual(ClassTyHolder),
1672 Int8PtrTy,
1673 LongTy,
1674 LongTy,
1675 LongTy,
1676 IvarListPtrTy,
1677 MethodListPtrTy,
1678 CachePtrTy,
1679 ProtocolListPtrTy,
1680 Int8PtrTy,
1681 ClassExtensionPtrTy,
1682 NULL);
1683 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1684
1685 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1686 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1687 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1688
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001689 CategoryTy = llvm::StructType::get(Int8PtrTy,
1690 Int8PtrTy,
1691 MethodListPtrTy,
1692 MethodListPtrTy,
1693 ProtocolListPtrTy,
1694 IntTy,
1695 PropertyListPtrTy,
1696 NULL);
1697 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1698
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001699 SuperTy =
1700 llvm::StructType::get(ObjectPtrTy,
1701 ClassPtrTy,
1702 NULL);
1703 CGM.getModule().addTypeName("struct._objc_super",
1704 SuperTy);
1705
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001706 // Global metadata structures
1707
1708 SymtabTy = llvm::StructType::get(LongTy,
1709 SelectorPtrTy,
1710 ShortTy,
1711 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001712 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001713 NULL);
1714 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1715 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1716
1717 ModuleTy =
1718 llvm::StructType::get(LongTy,
1719 LongTy,
1720 Int8PtrTy,
1721 SymtabPtrTy,
1722 NULL);
1723 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001724}
1725
1726ObjCTypesHelper::~ObjCTypesHelper() {
1727}
1728
1729const llvm::StructType *ObjCTypesHelper::getCFStringType() {
1730 if (!CFStringType) {
1731 CFStringType =
1732 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
1733 llvm::Type::Int32Ty,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001734 Int8PtrTy,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001735 LongTy,
1736 NULL);
1737
1738 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
1739 }
1740
1741 return CFStringType;
1742}
1743
1744llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
1745 if (!CFConstantStringClassReference) {
1746 llvm::GlobalValue *GV =
1747 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
1748 false,
1749 llvm::GlobalValue::ExternalLinkage,
1750 0, "__CFConstantStringClassReference",
1751 &CGM.getModule());
1752
1753 // Decay to pointer.
1754 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1755 }
1756
1757 return CFConstantStringClassReference;
1758}
1759
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001760llvm::Function *ObjCTypesHelper::getMessageSendFn() {
1761 if (!MessageSendFn) {
1762 std::vector<const llvm::Type*> Params;
1763 Params.push_back(ObjectPtrTy);
1764 Params.push_back(SelectorPtrTy);
1765 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1766 Params,
1767 true),
1768 llvm::Function::ExternalLinkage,
1769 "objc_msgSend",
1770 &CGM.getModule());
1771 }
1772
1773 return MessageSendFn;
1774}
1775
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001776llvm::Function *ObjCTypesHelper::getMessageSendSuperFn() {
1777 if (!MessageSendSuperFn) {
1778 std::vector<const llvm::Type*> Params;
1779 Params.push_back(llvm::PointerType::getUnqual(SuperTy));
1780 Params.push_back(SelectorPtrTy);
1781 MessageSendSuperFn =
1782 llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1783 Params,
1784 true),
1785 llvm::Function::ExternalLinkage,
1786 "objc_msgSendSuper",
1787 &CGM.getModule());
1788 }
1789
1790 return MessageSendSuperFn;
1791}
1792
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001793/* *** */
1794
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001795CodeGen::CGObjCRuntime *
1796CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001797 return new CGObjCMac(CGM);
1798}