blob: ee33385bb00becaf773f2f1a42e670bde8bf0519 [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 Dunbar259d93d2008-08-12 03:39:23 +000043 llvm::Function *MessageSendFn;
44
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
57 /// SymtabTy - LLVM type for struct objc_symtab.
58 const llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000059 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
60 const llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000061 /// ModuleTy - LLVM type for struct objc_module.
62 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000063
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000064 /// ProtocolTy - LLVM type for struct objc_protocol.
65 const llvm::StructType *ProtocolTy;
66 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
67 const llvm::Type *ProtocolPtrTy;
68 /// ProtocolExtensionTy - LLVM type for struct
69 /// objc_protocol_extension.
70 const llvm::StructType *ProtocolExtensionTy;
71 /// ProtocolExtensionTy - LLVM type for struct
72 /// objc_protocol_extension *.
73 const llvm::Type *ProtocolExtensionPtrTy;
74 /// MethodDescriptionTy - LLVM type for struct
75 /// objc_method_description.
76 const llvm::StructType *MethodDescriptionTy;
77 /// MethodDescriptionListTy - LLVM type for struct
78 /// objc_method_description_list.
79 const llvm::StructType *MethodDescriptionListTy;
80 /// MethodDescriptionListPtrTy - LLVM type for struct
81 /// objc_method_description_list *.
82 const llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbarc8ef5512008-08-23 00:19:03 +000083 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
84 /// in GCC parlance).
85 const llvm::StructType *PropertyTy;
86 /// PropertyListTy - LLVM type for struct objc_property_list
87 /// (_prop_list_t in GCC parlance).
88 const llvm::StructType *PropertyListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000089 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
90 const llvm::Type *PropertyListPtrTy;
91 /// ProtocolListTy - LLVM type for struct objc_property_list.
92 const llvm::Type *ProtocolListTy;
93 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
94 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +000095 /// CategoryTy - LLVM type for struct objc_category.
96 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000097 /// ClassTy - LLVM type for struct objc_class.
98 const llvm::StructType *ClassTy;
99 /// ClassPtrTy - LLVM type for struct objc_class *.
100 const llvm::Type *ClassPtrTy;
101 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
102 const llvm::StructType *ClassExtensionTy;
103 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
104 const llvm::Type *ClassExtensionPtrTy;
105 /// CacheTy - LLVM type for struct objc_cache.
106 const llvm::Type *CacheTy;
107 /// CachePtrTy - LLVM type for struct objc_cache *.
108 const llvm::Type *CachePtrTy;
109 // IvarTy - LLVM type for struct objc_ivar.
110 const llvm::StructType *IvarTy;
111 /// IvarListTy - LLVM type for struct objc_ivar_list.
112 const llvm::Type *IvarListTy;
113 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
114 const llvm::Type *IvarListPtrTy;
115 // MethodTy - LLVM type for struct objc_method.
116 const llvm::StructType *MethodTy;
117 /// MethodListTy - LLVM type for struct objc_method_list.
118 const llvm::Type *MethodListTy;
119 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
120 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000121
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000122public:
123 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
124 ~ObjCTypesHelper();
125
126 llvm::Constant *getCFConstantStringClassReference();
127 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000128 llvm::Function *getMessageSendFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000129};
130
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000131class CGObjCMac : public CodeGen::CGObjCRuntime {
132private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000133 CodeGen::CodeGenModule &CGM;
134 ObjCTypesHelper ObjCTypes;
135 /// ObjCABI - FIXME: Not sure yet.
136 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000137
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000138 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000139 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000140
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000141 /// MethodVarNames - uniqued method variable names.
142 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
143
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000144 /// MethodVarTypes - uniqued method type signatures. We have to use
145 /// a StringMap here because have no other unique reference.
146 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
147
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000148 /// PropertyNames - uniqued method variable names.
149 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
150
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000151 /// ClassReferences - uniqued class references.
152 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
153
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000154 /// SelectorReferences - uniqued selector references.
155 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
156
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000157 /// Protocols - Protocols for which an objc_protocol structure has
158 /// been emitted. Forward declarations are handled by creating an
159 /// empty structure whose initializer is filled in when/if defined.
160 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
161
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000162 /// DefinedClasses - List of defined classes.
163 std::vector<llvm::GlobalValue*> DefinedClasses;
164
165 /// DefinedCategories - List of defined categories.
166 std::vector<llvm::GlobalValue*> DefinedCategories;
167
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000168 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000169 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000170 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000171
172 /// EmitImageInfo - Emit the image info marker used to encode some module
173 /// level information.
174 void EmitImageInfo();
175
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000176 /// EmitModuleInfo - Another marker encoding module level
177 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000178 void EmitModuleInfo();
179
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000180 /// EmitModuleSymols - Emit module symbols, the list of defined
181 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000182 llvm::Constant *EmitModuleSymbols();
183
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000184 /// FinishModule - Write out global data structures at the end of
185 /// processing a translation unit.
186 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000187
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000188 /// EmitClassExtension - Generate the class extension structure used
189 /// to store the weak ivar layout and properties. The return value
190 /// has type ClassExtensionPtrTy.
191 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
192
193 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
194 /// for the given class.
195 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
196 const ObjCInterfaceDecl *ID);
197
198 /// EmitIvarList - Emit the ivar list for the given
199 /// implementation. If ForClass is true the list of class ivars
200 /// (i.e. metaclass ivars) is emitted, otherwise the list of
201 /// interface ivars will be emitted. The return value has type
202 /// IvarListPtrTy.
203 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
204 bool ForClass,
205 const llvm::Type *InterfaceTy);
206
207 /// EmitMetaClass - Emit a class structure for the metaclass of the
208 /// given implementation. return value has type ClassPtrTy.
209 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
210 llvm::Constant *Protocols,
211 const llvm::Type *InterfaceTy);
212
213 /// EmitMethodList - Emit the method list for the given
214 /// implementation. If ForClass is true the list of class methods
215 /// will be emitted, otherwise the list of instance methods will be
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000216 /// generated. The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000217 llvm::Constant *EmitMethodList(const std::string &Name,
218 const char *Section,
219 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
220 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000221
222 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000223 /// method declarations.
224 /// - TypeName: The name for the type containing the methods.
225 /// - IsProtocol: True iff these methods are for a protocol.
226 /// - ClassMethds: True iff these are class methods.
227 /// - Required: When true, only "required" methods are
228 /// listed. Similarly, when false only "optional" methods are
229 /// listed. For classes this should always be true.
230 /// - begin, end: The method list to output.
231 ///
232 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000233 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
234 bool IsProtocol,
235 bool ClassMethods,
236 bool Required,
237 ObjCMethodDecl * const *begin,
238 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000239
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000240 /// EmitPropertyList - Emit the given property list. The return
241 /// value has type PropertyListPtrTy.
242 llvm::Constant *EmitPropertyList(const std::string &Name,
243 ObjCPropertyDecl * const *begin,
244 ObjCPropertyDecl * const *end);
245
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000246 /// EmitProtocolExtension - Generate the protocol extension
247 /// structure used to store optional instance and class methods, and
248 /// protocol properties. The return value has type
249 /// ProtocolExtensionPtrTy.
250 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
251
252 /// EmitProtocolList - Generate the list of referenced
253 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc93372008-08-21 21:57:41 +0000254 llvm::Constant *EmitProtocolList(const std::string &Name,
255 ObjCProtocolDecl::protocol_iterator begin,
256 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000257
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000258 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
259 /// for the given selector.
260 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
261
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000262 /// GetProtocolRef - Return a reference to the internal protocol
263 /// description, creating an empty one if it has not been
264 /// defined. The return value has type pointer-to ProtocolTy.
265 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
266
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000267 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000268 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000269 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000270
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000271 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000272 /// selector's name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000273 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000274 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000275 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000276
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000277 /// GetMethodVarType - Return a unique constant for the given
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000278 /// selector's name. The return value has type char *.
279
280 // FIXME: This is a horrible name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000281 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000282 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000283
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000284 /// GetPropertyName - Return a unique constant for the given
285 /// name. The return value has type char *.
286 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
287
288 // FIXME: This is a horrible name too.
289 llvm::Constant *GetPropertyType(const ObjCPropertyDecl *PD);
290
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000291 /// GetNameForMethod - Return a name for the given method.
292 /// \param[out] NameOut - The return value.
293 void GetNameForMethod(const ObjCMethodDecl *OMD,
294 std::string &NameOut);
295
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000296public:
297 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000298 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000299
300 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
301 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000302 llvm::Value *Receiver,
303 Selector Sel,
304 llvm::Value** ArgV,
305 unsigned ArgC);
306
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000307 virtual llvm::Value *
308 GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
309 const llvm::Type *ReturnTy,
310 const ObjCInterfaceDecl *SuperClass,
311 llvm::Value *Receiver,
312 Selector Sel,
313 llvm::Value** ArgV,
314 unsigned ArgC);
315
316 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000317 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000318
319 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
320
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000321 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000322
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000323 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000324
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000325 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000326
327 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000328 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000329
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000330 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000331
332 virtual llvm::Function *ModuleInitFunction();
333};
334} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000335
336/* *** Helper Functions *** */
337
338/// getConstantGEP() - Help routine to construct simple GEPs.
339static llvm::Constant *getConstantGEP(llvm::Constant *C,
340 unsigned idx0,
341 unsigned idx1) {
342 llvm::Value *Idxs[] = {
343 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
344 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
345 };
346 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
347}
348
349/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000350
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000351CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
352 : CGM(cgm),
353 ObjCTypes(cgm),
354 ObjCABI(1)
355{
356 // FIXME: How does this get set in GCC? And what does it even mean?
357 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
358 ObjCABI = 2;
359
360 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000361}
362
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000363/// GetClass - Return a reference to the class for the given interface
364/// decl.
365llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000366 const ObjCInterfaceDecl *ID) {
367 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000368}
369
370/// GetSelector - Return the pointer to the unique'd string for this selector.
371llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000372 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000373}
374
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000375/// Generate a constant CFString object.
376/*
377 struct __builtin_CFString {
378 const int *isa; // point to __CFConstantStringClassReference
379 int flags;
380 const char *str;
381 long length;
382 };
383*/
384
385llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
386 // FIXME: I have no idea what this constant is (it is a magic
387 // constant in GCC as well). Most likely the encoding of the string
388 // and at least one part of it relates to UTF-16. Is this just the
389 // code for UTF-8? Where is this handled for us?
390 // See: <rdr://2996215>
391 unsigned flags = 0x07c8;
392
393 // FIXME: Use some machinery to unique this. We can't reuse the CGM
394 // one since we put them in a different section.
395 llvm::Constant *StringC = llvm::ConstantArray::get(String);
396 llvm::Constant *StringGV =
397 new llvm::GlobalVariable(StringC->getType(), true,
398 llvm::GlobalValue::InternalLinkage,
399 StringC, ".str", &CGM.getModule());
400 llvm::Constant *Values[4] = {
401 ObjCTypes.getCFConstantStringClassReference(),
402 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
403 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
404 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
405 };
406
407 llvm::Constant *CFStringC =
408 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
409 std::vector<llvm::Constant*>(Values, Values+4));
410
411 llvm::GlobalVariable *CFStringGV =
412 new llvm::GlobalVariable(CFStringC->getType(), true,
413 llvm::GlobalValue::InternalLinkage,
414 CFStringC, "",
415 &CGM.getModule());
416
417 CFStringGV->setSection("__DATA, __cfstring");
418
419 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000420}
421
422/// Generates a message send where the super is the receiver. This is
423/// a message send to self with special delivery semantics indicating
424/// which class's method should be called.
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000425llvm::Value *
426CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
427 const llvm::Type *ReturnTy,
428 const ObjCInterfaceDecl *SuperClass,
429 llvm::Value *Receiver,
430 Selector Sel,
431 llvm::Value** ArgV,
432 unsigned ArgC) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000433 assert(0 && "Cannot generate message send to super for Mac runtime.");
434 return 0;
435}
436
437/// Generate code for a message send expression.
438llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
439 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000440 llvm::Value *Receiver,
441 Selector Sel,
442 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000443 unsigned ArgC) {
444 llvm::Function *F = ObjCTypes.getMessageSendFn();
445 llvm::Value **Args = new llvm::Value*[ArgC+2];
446 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
447 Args[1] = EmitSelector(Builder, Sel);
448 std::copy(ArgV, ArgV+ArgC, Args+2);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000449
450 std::vector<const llvm::Type*> Params;
451 Params.push_back(ObjCTypes.ObjectPtrTy);
452 Params.push_back(ObjCTypes.SelectorPtrTy);
453 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
454 Params,
455 true);
456 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
457 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
458 llvm::CallInst *CI = Builder.CreateCall(C,
459 Args, Args+ArgC+2, "tmp");
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000460 delete[] Args;
461 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000462}
463
464llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000465 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000466 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
467 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000468}
469
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000470/*
471 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
472 struct _objc_protocol {
473 struct _objc_protocol_extension *isa;
474 char *protocol_name;
475 struct _objc_protocol_list *protocol_list;
476 struct _objc__method_prototype_list *instance_methods;
477 struct _objc__method_prototype_list *class_methods
478 };
479
480 See EmitProtocolExtension().
481*/
482void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
483 const char *ProtocolName = PD->getName();
484
485 std::vector<llvm::Constant*> Values(5);
486 Values[0] = EmitProtocolExtension(PD);
487 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000488 Values[2] =
489 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
490 PD->protocol_begin(),
491 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000492 Values[3] = EmitMethodDescList(ProtocolName,
493 true, // IsProtocol
494 false, // ClassMethods
495 true, // Required
496 PD->instmeth_begin(),
497 PD->instmeth_end());
498 Values[4] = EmitMethodDescList(ProtocolName,
499 true, // IsProtocol
500 true, // ClassMethods
501 true, // Required
502 PD->classmeth_begin(),
503 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000504 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
505 Values);
506
507 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
508 if (Entry) {
509 // Already created, just update the initializer
510 Entry->setInitializer(Init);
511 } else {
512 Entry =
513 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
514 llvm::GlobalValue::InternalLinkage,
515 Init,
516 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
517 &CGM.getModule());
518 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
519 UsedGlobals.push_back(Entry);
520 // FIXME: Is this necessary? Why only for protocol?
521 Entry->setAlignment(4);
522 }
523}
524
525llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
526 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
527
528 if (!Entry) {
529 std::vector<llvm::Constant*> Values(5);
530 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
531 Values[1] = GetClassName(PD->getIdentifier());
532 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
533 Values[3] = Values[4] =
534 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
535 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
536 Values);
537
538 Entry =
539 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
540 llvm::GlobalValue::InternalLinkage,
541 Init,
542 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
543 &CGM.getModule());
544 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
545 UsedGlobals.push_back(Entry);
546 // FIXME: Is this necessary? Why only for protocol?
547 Entry->setAlignment(4);
548 }
549
550 return Entry;
551}
552
553/*
554 struct _objc_protocol_extension {
555 uint32_t size;
556 struct objc_method_description_list *optional_instance_methods;
557 struct objc_method_description_list *optional_class_methods;
558 struct objc_property_list *instance_properties;
559 };
560*/
561llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
562 uint64_t Size =
563 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
564 std::vector<llvm::Constant*> Values(4);
565 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000566 Values[1] = EmitMethodDescList(PD->getName(),
567 true, // IsProtocol
568 false, // ClassMethods
569 false, // Required
570 PD->instmeth_begin(),
571 PD->instmeth_end());
572 Values[2] = EmitMethodDescList(PD->getName(),
573 true, // IsProtocol
574 true, // ClassMethods
575 false, // Required
576 PD->classmeth_begin(),
577 PD->classmeth_end());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000578 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
579 PD->getName(),
580 PD->classprop_begin(),
581 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000582
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000583 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000584 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
585 Values[3]->isNullValue())
586 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
587
588 llvm::Constant *Init =
589 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
590 llvm::GlobalVariable *GV =
591 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
592 llvm::GlobalValue::InternalLinkage,
593 Init,
594 (std::string("\01L_OBJC_PROTOCOLEXT_") +
595 PD->getName()),
596 &CGM.getModule());
597 // No special section, but goes in llvm.used
598 UsedGlobals.push_back(GV);
599
600 return GV;
601}
602
603/*
604 struct objc_protocol_list {
605 struct objc_protocol_list *next;
606 long count;
607 Protocol *list[];
608 };
609*/
Daniel Dunbardbc93372008-08-21 21:57:41 +0000610llvm::Constant *
611CGObjCMac::EmitProtocolList(const std::string &Name,
612 ObjCProtocolDecl::protocol_iterator begin,
613 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000614 std::vector<llvm::Constant*> ProtocolRefs;
615
Daniel Dunbardbc93372008-08-21 21:57:41 +0000616 for (; begin != end; ++begin)
617 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000618
619 // Just return null for empty protocol lists
620 if (ProtocolRefs.empty())
621 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
622
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000623 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000624 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
625
626 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000627 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000628 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
629 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
630 Values[2] =
631 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
632 ProtocolRefs.size()),
633 ProtocolRefs);
634
635 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
636 llvm::GlobalVariable *GV =
637 new llvm::GlobalVariable(Init->getType(), false,
638 llvm::GlobalValue::InternalLinkage,
639 Init,
Daniel Dunbardbc93372008-08-21 21:57:41 +0000640 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000641 &CGM.getModule());
642 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
643 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
644}
645
646/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000647 struct _objc_property {
648 const char * const name;
649 const char * const attributes;
650 };
651
652 struct _objc_property_list {
653 uint32_t entsize; // sizeof (struct _objc_property)
654 uint32_t prop_count;
655 struct _objc_property[prop_count];
656 };
657*/
658llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
659 ObjCPropertyDecl * const *begin,
660 ObjCPropertyDecl * const *end) {
661 std::vector<llvm::Constant*> Properties, Prop(2);
662 for (; begin != end; ++begin) {
663 const ObjCPropertyDecl *PD = *begin;
664 Prop[0] = GetPropertyName(PD->getIdentifier());
665 Prop[1] = GetPropertyType(PD);
666 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
667 Prop));
668 }
669
670 // Return null for empty list.
671 if (Properties.empty())
672 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
673
674 unsigned PropertySize =
675 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
676 std::vector<llvm::Constant*> Values(3);
677 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
678 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
679 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
680 Properties.size());
681 Values[2] = llvm::ConstantArray::get(AT, Properties);
682 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
683
684 llvm::GlobalVariable *GV =
685 new llvm::GlobalVariable(Init->getType(), false,
686 llvm::GlobalValue::InternalLinkage,
687 Init,
688 Name,
689 &CGM.getModule());
690 // No special section on property lists?
691 UsedGlobals.push_back(GV);
692 return llvm::ConstantExpr::getBitCast(GV,
693 ObjCTypes.PropertyListPtrTy);
694
695}
696
697/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000698 struct objc_method_description_list {
699 int count;
700 struct objc_method_description list[];
701 };
702*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000703llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
704 bool IsProtocol,
705 bool ClassMethods,
706 bool Required,
707 ObjCMethodDecl * const *begin,
708 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000709 std::vector<llvm::Constant*> Methods, Desc(2);
710 for (; begin != end; ++begin) {
711 ObjCMethodDecl *D = *begin;
712 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
713
714 // Skip if this method is required and we are outputting optional
715 // methods, or vice versa.
716 if (Required != IsRequired)
717 continue;
718
719 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
720 ObjCTypes.SelectorPtrTy);
721 Desc[1] = GetMethodVarType(D);
722 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
723 Desc));
724 }
725
726 // Return null for empty list.
727 if (Methods.empty())
728 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
729
730 std::vector<llvm::Constant*> Values(2);
731 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
732 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
733 Methods.size());
734 Values[1] = llvm::ConstantArray::get(AT, Methods);
735 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
736
737 char Prefix[256];
738 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
739 IsProtocol ? "PROTOCOL_" : "",
740 ClassMethods ? "CLASS_" : "INSTANCE_",
741 !Required ? "OPT_" : "");
742 llvm::GlobalVariable *GV =
743 new llvm::GlobalVariable(Init->getType(), false,
744 llvm::GlobalValue::InternalLinkage,
745 Init,
746 std::string(Prefix) + TypeName,
747 &CGM.getModule());
748 if (ClassMethods) {
749 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
750 } else {
751 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
752 }
753 UsedGlobals.push_back(GV);
754 return llvm::ConstantExpr::getBitCast(GV,
755 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000756}
757
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000758/*
759 struct _objc_category {
760 char *category_name;
761 char *class_name;
762 struct _objc_method_list *instance_methods;
763 struct _objc_method_list *class_methods;
764 struct _objc_protocol_list *protocols;
765 uint32_t size; // <rdar://4585769>
766 struct _objc_property_list *instance_properties;
767 };
768 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000769void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000770 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
771
772 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
773 std::string ExtName(std::string(Interface->getName()) +
774 "_" +
775 OCD->getName());
776
777 std::vector<llvm::Constant*> Values(7);
778 Values[0] = GetClassName(OCD->getIdentifier());
779 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000780 Values[2] =
781 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
782 ExtName,
783 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
784 OCD->instmeth_begin(),
785 OCD->instmeth_end());
786 Values[3] =
787 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
788 "__OBJC,__cat_class_meth,regular,no_dead_strip",
789 OCD->classmeth_begin(),
790 OCD->classmeth_end());
791 Values[4] =
792 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
793 Interface->protocol_begin(),
794 Interface->protocol_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000795 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000796 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
797 Interface->classprop_begin(),
798 Interface->classprop_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000799
800 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
801 Values);
802
803 llvm::GlobalVariable *GV =
804 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
805 llvm::GlobalValue::InternalLinkage,
806 Init,
807 std::string("\01L_OBJC_CATEGORY_")+ExtName,
808 &CGM.getModule());
809 GV->setSection("__OBJC,__category,regular,no_dead_strip");
810 UsedGlobals.push_back(GV);
811 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000812}
813
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000814// FIXME: Get from somewhere?
815enum ClassFlags {
816 eClassFlags_Factory = 0x00001,
817 eClassFlags_Meta = 0x00002,
818 // <rdr://5142207>
819 eClassFlags_HasCXXStructors = 0x02000,
820 eClassFlags_Hidden = 0x20000,
821 eClassFlags_ABI2_Hidden = 0x00010,
822 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
823};
824
825// <rdr://5142207&4705298&4843145>
826static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
827 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
828 // FIXME: Support -fvisibility
829 switch (attr->getVisibility()) {
830 default:
831 assert(0 && "Unknown visibility");
832 return false;
833 case VisibilityAttr::DefaultVisibility:
834 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
835 return false;
836 case VisibilityAttr::HiddenVisibility:
837 return true;
838 }
839 } else {
840 return false; // FIXME: Support -fvisibility
841 }
842}
843
844/*
845 struct _objc_class {
846 Class isa;
847 Class super_class;
848 const char *name;
849 long version;
850 long info;
851 long instance_size;
852 struct _objc_ivar_list *ivars;
853 struct _objc_method_list *methods;
854 struct _objc_cache *cache;
855 struct _objc_protocol_list *protocols;
856 // Objective-C 1.0 extensions (<rdr://4585769>)
857 const char *ivar_layout;
858 struct _objc_class_ext *ext;
859 };
860
861 See EmitClassExtension();
862 */
863void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
864 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000865 // FIXME: Gross
866 ObjCInterfaceDecl *Interface =
867 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000868 llvm::Constant *Protocols =
869 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
870 Interface->protocol_begin(),
871 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000872 const llvm::Type *InterfaceTy =
873 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
874 unsigned Flags = eClassFlags_Factory;
875 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
876
877 // FIXME: Set CXX-structors flag.
878 if (IsClassHidden(ID->getClassInterface()))
879 Flags |= eClassFlags_Hidden;
880
881 std::vector<llvm::Constant*> Values(12);
882 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
883 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
884 Values[ 1] =
885 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
886 ObjCTypes.ClassPtrTy);
887 } else {
888 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
889 }
890 Values[ 2] = GetClassName(ID->getIdentifier());
891 // Version is always 0.
892 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
893 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
894 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
895 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000896 Values[ 7] =
897 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
898 "__OBJC,__inst_meth,regular,no_dead_strip",
899 ID->instmeth_begin(),
900 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000901 // cache is always NULL.
902 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
903 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000904 // FIXME: Set ivar_layout
905 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000906 Values[11] = EmitClassExtension(ID);
907 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
908 Values);
909
910 llvm::GlobalVariable *GV =
911 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
912 llvm::GlobalValue::InternalLinkage,
913 Init,
914 std::string("\01L_OBJC_CLASS_")+ClassName,
915 &CGM.getModule());
916 GV->setSection("__OBJC,__class,regular,no_dead_strip");
917 UsedGlobals.push_back(GV);
918 // FIXME: Why?
919 GV->setAlignment(32);
920 DefinedClasses.push_back(GV);
921}
922
923llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
924 llvm::Constant *Protocols,
925 const llvm::Type *InterfaceTy) {
926 const char *ClassName = ID->getName();
927 unsigned Flags = eClassFlags_Meta;
928 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
929
930 if (IsClassHidden(ID->getClassInterface()))
931 Flags |= eClassFlags_Hidden;
932
933 std::vector<llvm::Constant*> Values(12);
934 // The isa for the metaclass is the root of the hierarchy.
935 const ObjCInterfaceDecl *Root = ID->getClassInterface();
936 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
937 Root = Super;
938 Values[ 0] =
939 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
940 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000941 // The super class for the metaclass is emitted as the name of the
942 // super class. The runtime fixes this up to point to the
943 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000944 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
945 Values[ 1] =
946 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
947 ObjCTypes.ClassPtrTy);
948 } else {
949 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
950 }
951 Values[ 2] = GetClassName(ID->getIdentifier());
952 // Version is always 0.
953 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
954 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
955 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
956 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000957 Values[ 7] =
958 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
959 "__OBJC,__inst_meth,regular,no_dead_strip",
960 ID->classmeth_begin(),
961 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000962 // cache is always NULL.
963 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
964 Values[ 9] = Protocols;
965 // ivar_layout for metaclass is always NULL.
966 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
967 // The class extension is always unused for metaclasses.
968 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
969 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
970 Values);
971
972 llvm::GlobalVariable *GV =
973 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
974 llvm::GlobalValue::InternalLinkage,
975 Init,
976 std::string("\01L_OBJC_METACLASS_")+ClassName,
977 &CGM.getModule());
978 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
979 UsedGlobals.push_back(GV);
980 // FIXME: Why?
981 GV->setAlignment(32);
982
983 return GV;
984}
985
986/*
987 struct objc_class_ext {
988 uint32_t size;
989 const char *weak_ivar_layout;
990 struct _objc_property_list *properties;
991 };
992*/
993llvm::Constant *
994CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
995 uint64_t Size =
996 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
997
998 std::vector<llvm::Constant*> Values(3);
999 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001000 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001001 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001002 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
1003 ID->getName(),
1004 ID->getClassInterface()->classprop_begin(),
1005 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001006
1007 // Return null if no extension bits are used.
1008 if (Values[1]->isNullValue() && Values[2]->isNullValue())
1009 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
1010
1011 llvm::Constant *Init =
1012 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1013 llvm::GlobalVariable *GV =
1014 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1015 llvm::GlobalValue::InternalLinkage,
1016 Init,
1017 (std::string("\01L_OBJC_CLASSEXT_") +
1018 ID->getName()),
1019 &CGM.getModule());
1020 // No special section, but goes in llvm.used
1021 UsedGlobals.push_back(GV);
1022
1023 return GV;
1024}
1025
1026/*
1027 struct objc_ivar {
1028 char *ivar_name;
1029 char *ivar_type;
1030 int ivar_offset;
1031 };
1032
1033 struct objc_ivar_list {
1034 int ivar_count;
1035 struct objc_ivar list[count];
1036 };
1037 */
1038llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1039 bool ForClass,
1040 const llvm::Type *InterfaceTy) {
1041 std::vector<llvm::Constant*> Ivars, Ivar(3);
1042
1043 // When emitting the root class GCC emits ivar entries for the
1044 // actual class structure. It is not clear if we need to follow this
1045 // behavior; for now lets try and get away with not doing it. If so,
1046 // the cleanest solution would be to make up an ObjCInterfaceDecl
1047 // for the class.
1048 if (ForClass)
1049 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1050
1051 const llvm::StructLayout *Layout =
1052 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1053 for (ObjCInterfaceDecl::ivar_iterator
1054 i = ID->getClassInterface()->ivar_begin(),
1055 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1056 ObjCIvarDecl *V = *i;
1057 unsigned Offset =
1058 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1059 std::string TypeStr;
1060 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1061 Ivar[0] = GetMethodVarName(V->getIdentifier());
1062 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1063 EncodingRecordTypes);
1064 Ivar[1] = GetMethodVarType(TypeStr);
1065 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1066 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1067 Ivar));
1068 }
1069
1070 // Return null for empty list.
1071 if (Ivars.empty())
1072 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1073
1074 std::vector<llvm::Constant*> Values(2);
1075 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1076 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1077 Ivars.size());
1078 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1079 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1080
1081 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1082 "\01L_OBJC_INSTANCE_VARIABLES_");
1083 llvm::GlobalVariable *GV =
1084 new llvm::GlobalVariable(Init->getType(), false,
1085 llvm::GlobalValue::InternalLinkage,
1086 Init,
1087 std::string(Prefix) + ID->getName(),
1088 &CGM.getModule());
1089 if (ForClass) {
1090 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1091 // FIXME: Why is this only here?
1092 GV->setAlignment(32);
1093 } else {
1094 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1095 }
1096 UsedGlobals.push_back(GV);
1097 return llvm::ConstantExpr::getBitCast(GV,
1098 ObjCTypes.IvarListPtrTy);
1099}
1100
1101/*
1102 struct objc_method {
1103 SEL method_name;
1104 char *method_types;
1105 void *method;
1106 };
1107
1108 struct objc_method_list {
1109 struct objc_method_list *obsolete;
1110 int count;
1111 struct objc_method methods_list[count];
1112 };
1113*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001114llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1115 const char *Section,
1116 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1117 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001118 std::vector<llvm::Constant*> Methods, Method(3);
1119
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001120 for (; begin != end; ++begin) {
1121 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001122
1123 Method[0] =
1124 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1125 ObjCTypes.SelectorPtrTy);
1126 Method[1] = GetMethodVarType(MD);
1127
1128 // FIXME: This is gross, we shouldn't be looking up by name.
1129 std::string Name;
1130 GetNameForMethod(MD, Name);
1131 Method[2] =
1132 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1133 ObjCTypes.Int8PtrTy);
1134 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1135 Method));
1136 }
1137
1138 // Return null for empty list.
1139 if (Methods.empty())
1140 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1141
1142 std::vector<llvm::Constant*> Values(3);
1143 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1144 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1145 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1146 Methods.size());
1147 Values[2] = llvm::ConstantArray::get(AT, Methods);
1148 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1149
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001150 llvm::GlobalVariable *GV =
1151 new llvm::GlobalVariable(Init->getType(), false,
1152 llvm::GlobalValue::InternalLinkage,
1153 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001154 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001155 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001156 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001157 UsedGlobals.push_back(GV);
1158 return llvm::ConstantExpr::getBitCast(GV,
1159 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001160}
1161
1162llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1163 const llvm::Type *ReturnTy =
1164 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1165 const llvm::Type *SelfTy =
1166 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1167
1168 std::vector<const llvm::Type*> ArgTys;
1169 ArgTys.reserve(1 + 2 + OMD->param_size());
1170
1171 // FIXME: This is not something we should have to be dealing with
1172 // here.
1173 bool useStructRet =
1174 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1175 if (useStructRet) {
1176 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1177 ReturnTy = llvm::Type::VoidTy;
1178 }
1179
1180 // Implicit arguments
1181 ArgTys.push_back(SelfTy);
1182 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1183
1184 for (ObjCMethodDecl::param_const_iterator
1185 i = OMD->param_begin(), e = OMD->param_end();
1186 i != e; ++i) {
1187 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1188 if (Ty->isFirstClassType()) {
1189 ArgTys.push_back(Ty);
1190 } else {
1191 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1192 }
1193 }
1194
1195 std::string Name;
1196 GetNameForMethod(OMD, Name);
1197
1198 llvm::Function *Method =
1199 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1200 ArgTys,
1201 OMD->isVariadic()),
1202 llvm::GlobalValue::InternalLinkage,
1203 Name,
1204 &CGM.getModule());
1205
1206 if (useStructRet)
1207 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
1208
1209 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001210}
1211
1212llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001213 // Abuse this interface function as a place to finalize.
1214 FinishModule();
1215
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001216 return NULL;
1217}
1218
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001219/* *** Private Interface *** */
1220
1221/// EmitImageInfo - Emit the image info marker used to encode some module
1222/// level information.
1223///
1224/// See: <rdr://4810609&4810587&4810587>
1225/// struct IMAGE_INFO {
1226/// unsigned version;
1227/// unsigned flags;
1228/// };
1229enum ImageInfoFlags {
1230 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1231 eImageInfo_GarbageCollected = (1 << 1),
1232 eImageInfo_GCOnly = (1 << 2)
1233};
1234
1235void CGObjCMac::EmitImageInfo() {
1236 unsigned version = 0; // Version is unused?
1237 unsigned flags = 0;
1238
1239 // FIXME: Fix and continue?
1240 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1241 flags |= eImageInfo_GarbageCollected;
1242 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1243 flags |= eImageInfo_GCOnly;
1244
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001245 // Emitted as int[2];
1246 llvm::Constant *values[2] = {
1247 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1248 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1249 };
1250 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001251 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001252 new llvm::GlobalVariable(AT, true,
1253 llvm::GlobalValue::InternalLinkage,
1254 llvm::ConstantArray::get(AT, values, 2),
1255 "\01L_OBJC_IMAGE_INFO",
1256 &CGM.getModule());
1257
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001258 if (ObjCABI == 1) {
1259 GV->setSection("__OBJC, __image_info,regular");
1260 } else {
1261 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1262 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001263
1264 UsedGlobals.push_back(GV);
1265}
1266
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001267
1268// struct objc_module {
1269// unsigned long version;
1270// unsigned long size;
1271// const char *name;
1272// Symtab symtab;
1273// };
1274
1275// FIXME: Get from somewhere
1276static const int ModuleVersion = 7;
1277
1278void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001279 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1280
1281 std::vector<llvm::Constant*> Values(4);
1282 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1283 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001284 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001285 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001286 Values[3] = EmitModuleSymbols();
1287
1288 llvm::GlobalVariable *GV =
1289 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1290 llvm::GlobalValue::InternalLinkage,
1291 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1292 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001293 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001294 &CGM.getModule());
1295 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1296 UsedGlobals.push_back(GV);
1297}
1298
1299llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001300 std::vector<llvm::Constant*> Values(5);
1301 unsigned NumClasses = DefinedClasses.size();
1302 unsigned NumCategories = DefinedCategories.size();
1303
1304 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1305 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1306 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1307 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1308
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001309 // The runtime expects exactly the list of defined classes followed
1310 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001311 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001312 for (unsigned i=0; i<NumClasses; i++)
1313 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1314 ObjCTypes.Int8PtrTy);
1315 for (unsigned i=0; i<NumCategories; i++)
1316 Symbols[NumClasses + i] =
1317 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1318 ObjCTypes.Int8PtrTy);
1319
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001320 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001321 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001322 NumClasses + NumCategories),
1323 Symbols);
1324
1325 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1326
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001327 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001328 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001329 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001330 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001331 "\01L_OBJC_SYMBOLS",
1332 &CGM.getModule());
1333 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1334 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001335 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1336}
1337
1338llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1339 const ObjCInterfaceDecl *ID) {
1340 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1341
1342 if (!Entry) {
1343 llvm::Constant *Casted =
1344 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1345 ObjCTypes.ClassPtrTy);
1346 Entry =
1347 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1348 llvm::GlobalValue::InternalLinkage,
1349 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1350 &CGM.getModule());
1351 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1352 UsedGlobals.push_back(Entry);
1353 }
1354
1355 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001356}
1357
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001358llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1359 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1360
1361 if (!Entry) {
1362 llvm::Constant *Casted =
1363 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1364 ObjCTypes.SelectorPtrTy);
1365 Entry =
1366 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1367 llvm::GlobalValue::InternalLinkage,
1368 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1369 &CGM.getModule());
1370 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1371 UsedGlobals.push_back(Entry);
1372 }
1373
1374 return Builder.CreateLoad(Entry, false, "tmp");
1375}
1376
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001377llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1378 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001379
1380 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001381 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001382 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001383 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001384 llvm::GlobalValue::InternalLinkage,
1385 C, "\01L_OBJC_CLASS_NAME_",
1386 &CGM.getModule());
1387 Entry->setSection("__TEXT,__cstring,cstring_literals");
1388 UsedGlobals.push_back(Entry);
1389 }
1390
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001391 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001392}
1393
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001394llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1395 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1396
1397 if (!Entry) {
1398 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1399 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001400 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001401 llvm::GlobalValue::InternalLinkage,
1402 C, "\01L_OBJC_METH_VAR_NAME_",
1403 &CGM.getModule());
1404 Entry->setSection("__TEXT,__cstring,cstring_literals");
1405 UsedGlobals.push_back(Entry);
1406 }
1407
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001408 return getConstantGEP(Entry, 0, 0);
1409}
1410
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001411// FIXME: Merge into a single cstring creation function.
1412llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1413 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1414}
1415
1416// FIXME: Merge into a single cstring creation function.
1417llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1418 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1419}
1420
1421llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1422 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001423
1424 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001425 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001426 Entry =
1427 new llvm::GlobalVariable(C->getType(), false,
1428 llvm::GlobalValue::InternalLinkage,
1429 C, "\01L_OBJC_METH_VAR_TYPE_",
1430 &CGM.getModule());
1431 Entry->setSection("__TEXT,__cstring,cstring_literals");
1432 UsedGlobals.push_back(Entry);
1433 }
1434
1435 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001436}
1437
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001438// FIXME: Merge into a single cstring creation function.
1439llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1440 std::string TypeStr;
1441 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1442 return GetMethodVarType(TypeStr);
1443}
1444
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001445// FIXME: Merge into a single cstring creation function.
1446llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1447 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1448
1449 if (!Entry) {
1450 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1451 Entry =
1452 new llvm::GlobalVariable(C->getType(), false,
1453 llvm::GlobalValue::InternalLinkage,
1454 C, "\01L_OBJC_PROP_NAME_ATTR_",
1455 &CGM.getModule());
1456 Entry->setSection("__TEXT,__cstring,cstring_literals");
1457 UsedGlobals.push_back(Entry);
1458 }
1459
1460 return getConstantGEP(Entry, 0, 0);
1461}
1462
1463// FIXME: Merge into a single cstring creation function.
1464llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1465 std::string TypeStr("MOOO!");
1466 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1467 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1468}
1469
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001470void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1471 std::string &NameOut) {
1472 // FIXME: Find the mangling GCC uses.
1473 std::stringstream s;
1474 s << (D->isInstance() ? "-" : "+");
1475 s << "[";
1476 s << D->getClassInterface()->getName();
1477 s << " ";
1478 s << D->getSelector().getName();
1479 s << "]";
1480 NameOut = s.str();
1481}
1482
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001483void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001484 EmitModuleInfo();
1485
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001486 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001487
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001488 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001489 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001490 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001491 }
1492
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001493 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001494 llvm::GlobalValue *GV =
1495 new llvm::GlobalVariable(AT, false,
1496 llvm::GlobalValue::AppendingLinkage,
1497 llvm::ConstantArray::get(AT, Used),
1498 "llvm.used",
1499 &CGM.getModule());
1500
1501 GV->setSection("llvm.metadata");
1502}
1503
1504/* *** */
1505
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001506ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
1507 : CGM(cgm),
1508 CFStringType(0),
1509 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001510 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001511{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001512 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1513 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001514
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001515 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001516 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001517 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001518 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1519
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001520 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1521 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001522
1523 // FIXME: It would be nice to unify this with the opaque type, so
1524 // that the IR comes out a bit cleaner.
1525 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1526 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001527
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001528 MethodDescriptionTy =
1529 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001530 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001531 NULL);
1532 CGM.getModule().addTypeName("struct._objc_method_description",
1533 MethodDescriptionTy);
1534
1535 MethodDescriptionListTy =
1536 llvm::StructType::get(IntTy,
1537 llvm::ArrayType::get(MethodDescriptionTy, 0),
1538 NULL);
1539 CGM.getModule().addTypeName("struct._objc_method_description_list",
1540 MethodDescriptionListTy);
1541 MethodDescriptionListPtrTy =
1542 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1543
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001544 PropertyTy = llvm::StructType::get(Int8PtrTy,
1545 Int8PtrTy,
1546 NULL);
1547 CGM.getModule().addTypeName("struct._objc_property",
1548 PropertyTy);
1549
1550 PropertyListTy = llvm::StructType::get(IntTy,
1551 IntTy,
1552 llvm::ArrayType::get(PropertyTy, 0),
1553 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001554 CGM.getModule().addTypeName("struct._objc_property_list",
1555 PropertyListTy);
1556 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1557
1558 // Protocol description structures
1559
1560 ProtocolExtensionTy =
1561 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1562 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1563 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1564 PropertyListPtrTy,
1565 NULL);
1566 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1567 ProtocolExtensionTy);
1568 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1569
1570 // Handle recursive construction of Protocl and ProtocolList types
1571
1572 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1573 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1574
1575 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1576 LongTy,
1577 llvm::ArrayType::get(ProtocolTyHolder, 0),
1578 NULL);
1579 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1580
1581 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001582 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001583 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1584 MethodDescriptionListPtrTy,
1585 MethodDescriptionListPtrTy,
1586 NULL);
1587 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1588
1589 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1590 CGM.getModule().addTypeName("struct._objc_protocol_list",
1591 ProtocolListTy);
1592 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1593
1594 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1595 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1596 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001597
1598 // Class description structures
1599
1600 IvarTy = llvm::StructType::get(Int8PtrTy,
1601 Int8PtrTy,
1602 IntTy,
1603 NULL);
1604 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1605
1606 IvarListTy = llvm::OpaqueType::get();
1607 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1608 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1609
1610 MethodTy = llvm::StructType::get(SelectorPtrTy,
1611 Int8PtrTy,
1612 Int8PtrTy,
1613 NULL);
1614 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1615
1616 MethodListTy = llvm::OpaqueType::get();
1617 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1618 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1619
1620 CacheTy = llvm::OpaqueType::get();
1621 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1622 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1623
1624 ClassExtensionTy =
1625 llvm::StructType::get(IntTy,
1626 Int8PtrTy,
1627 PropertyListPtrTy,
1628 NULL);
1629 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1630 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1631
1632 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1633
1634 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1635 llvm::PointerType::getUnqual(ClassTyHolder),
1636 Int8PtrTy,
1637 LongTy,
1638 LongTy,
1639 LongTy,
1640 IvarListPtrTy,
1641 MethodListPtrTy,
1642 CachePtrTy,
1643 ProtocolListPtrTy,
1644 Int8PtrTy,
1645 ClassExtensionPtrTy,
1646 NULL);
1647 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1648
1649 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1650 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1651 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1652
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001653 CategoryTy = llvm::StructType::get(Int8PtrTy,
1654 Int8PtrTy,
1655 MethodListPtrTy,
1656 MethodListPtrTy,
1657 ProtocolListPtrTy,
1658 IntTy,
1659 PropertyListPtrTy,
1660 NULL);
1661 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1662
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001663 // Global metadata structures
1664
1665 SymtabTy = llvm::StructType::get(LongTy,
1666 SelectorPtrTy,
1667 ShortTy,
1668 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001669 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001670 NULL);
1671 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1672 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1673
1674 ModuleTy =
1675 llvm::StructType::get(LongTy,
1676 LongTy,
1677 Int8PtrTy,
1678 SymtabPtrTy,
1679 NULL);
1680 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001681}
1682
1683ObjCTypesHelper::~ObjCTypesHelper() {
1684}
1685
1686const llvm::StructType *ObjCTypesHelper::getCFStringType() {
1687 if (!CFStringType) {
1688 CFStringType =
1689 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
1690 llvm::Type::Int32Ty,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001691 Int8PtrTy,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001692 LongTy,
1693 NULL);
1694
1695 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
1696 }
1697
1698 return CFStringType;
1699}
1700
1701llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
1702 if (!CFConstantStringClassReference) {
1703 llvm::GlobalValue *GV =
1704 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
1705 false,
1706 llvm::GlobalValue::ExternalLinkage,
1707 0, "__CFConstantStringClassReference",
1708 &CGM.getModule());
1709
1710 // Decay to pointer.
1711 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1712 }
1713
1714 return CFConstantStringClassReference;
1715}
1716
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001717llvm::Function *ObjCTypesHelper::getMessageSendFn() {
1718 if (!MessageSendFn) {
1719 std::vector<const llvm::Type*> Params;
1720 Params.push_back(ObjectPtrTy);
1721 Params.push_back(SelectorPtrTy);
1722 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1723 Params,
1724 true),
1725 llvm::Function::ExternalLinkage,
1726 "objc_msgSend",
1727 &CGM.getModule());
1728 }
1729
1730 return MessageSendFn;
1731}
1732
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001733/* *** */
1734
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001735CodeGen::CGObjCRuntime *
1736CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001737 return new CGObjCMac(CGM);
1738}