blob: 1ad55491d94008dc83db2e394b63ffbb507c6ac9 [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
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000300 virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
301 const ObjCMessageExpr *E,
302 llvm::Value *Receiver);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000303
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000304 virtual CodeGen::RValue
305 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
306 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000307 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000308 llvm::Value *Receiver);
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000309
310 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000311 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000312
313 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
314
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000315 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000316
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000317 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000318
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000319 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000320
321 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000322 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000323
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000324 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000325
326 virtual llvm::Function *ModuleInitFunction();
327};
328} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000329
330/* *** Helper Functions *** */
331
332/// getConstantGEP() - Help routine to construct simple GEPs.
333static llvm::Constant *getConstantGEP(llvm::Constant *C,
334 unsigned idx0,
335 unsigned idx1) {
336 llvm::Value *Idxs[] = {
337 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
338 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
339 };
340 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
341}
342
343/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000344
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000345CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
346 : CGM(cgm),
347 ObjCTypes(cgm),
348 ObjCABI(1)
349{
350 // FIXME: How does this get set in GCC? And what does it even mean?
351 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
352 ObjCABI = 2;
353
354 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000355}
356
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000357/// GetClass - Return a reference to the class for the given interface
358/// decl.
359llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000360 const ObjCInterfaceDecl *ID) {
361 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000362}
363
364/// GetSelector - Return the pointer to the unique'd string for this selector.
365llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000366 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000367}
368
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000369/// Generate a constant CFString object.
370/*
371 struct __builtin_CFString {
372 const int *isa; // point to __CFConstantStringClassReference
373 int flags;
374 const char *str;
375 long length;
376 };
377*/
378
379llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
380 // FIXME: I have no idea what this constant is (it is a magic
381 // constant in GCC as well). Most likely the encoding of the string
382 // and at least one part of it relates to UTF-16. Is this just the
383 // code for UTF-8? Where is this handled for us?
384 // See: <rdr://2996215>
385 unsigned flags = 0x07c8;
386
387 // FIXME: Use some machinery to unique this. We can't reuse the CGM
388 // one since we put them in a different section.
389 llvm::Constant *StringC = llvm::ConstantArray::get(String);
390 llvm::Constant *StringGV =
391 new llvm::GlobalVariable(StringC->getType(), true,
392 llvm::GlobalValue::InternalLinkage,
393 StringC, ".str", &CGM.getModule());
394 llvm::Constant *Values[4] = {
395 ObjCTypes.getCFConstantStringClassReference(),
396 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
397 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
398 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
399 };
400
401 llvm::Constant *CFStringC =
402 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
403 std::vector<llvm::Constant*>(Values, Values+4));
404
405 llvm::GlobalVariable *CFStringGV =
406 new llvm::GlobalVariable(CFStringC->getType(), true,
407 llvm::GlobalValue::InternalLinkage,
408 CFStringC, "",
409 &CGM.getModule());
410
411 CFStringGV->setSection("__DATA, __cfstring");
412
413 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000414}
415
416/// Generates a message send where the super is the receiver. This is
417/// a message send to self with special delivery semantics indicating
418/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000419CodeGen::RValue
420CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
421 const ObjCMessageExpr *E,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000422 const ObjCInterfaceDecl *SuperClass,
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000423 llvm::Value *Receiver) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000424 assert(0 && "Cannot generate message send to super for Mac runtime.");
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000425 return CodeGen::RValue::get(0);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000426}
427
428/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000429CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
430 const ObjCMessageExpr *E,
431 llvm::Value *Receiver) {
432 const llvm::Type *ReturnTy = CGM.getTypes().ConvertType(E->getType());
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000433 llvm::Function *F = ObjCTypes.getMessageSendFn();
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000434 llvm::Value *Args[2];
435 Args[0] = CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
436 Args[1] = EmitSelector(CGF.Builder, E->getSelector());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000437
438 std::vector<const llvm::Type*> Params;
439 Params.push_back(ObjCTypes.ObjectPtrTy);
440 Params.push_back(ObjCTypes.SelectorPtrTy);
441 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
442 Params,
443 true);
444 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
445 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000446 return CGF.EmitCallExprExt(C, E->getType(),
447 E->arg_begin(),
448 E->arg_end(),
449 Args, 2);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000450}
451
452llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000453 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000454 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
455 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000456}
457
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000458/*
459 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
460 struct _objc_protocol {
461 struct _objc_protocol_extension *isa;
462 char *protocol_name;
463 struct _objc_protocol_list *protocol_list;
464 struct _objc__method_prototype_list *instance_methods;
465 struct _objc__method_prototype_list *class_methods
466 };
467
468 See EmitProtocolExtension().
469*/
470void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
471 const char *ProtocolName = PD->getName();
472
473 std::vector<llvm::Constant*> Values(5);
474 Values[0] = EmitProtocolExtension(PD);
475 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000476 Values[2] =
477 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
478 PD->protocol_begin(),
479 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000480 Values[3] = EmitMethodDescList(ProtocolName,
481 true, // IsProtocol
482 false, // ClassMethods
483 true, // Required
484 PD->instmeth_begin(),
485 PD->instmeth_end());
486 Values[4] = EmitMethodDescList(ProtocolName,
487 true, // IsProtocol
488 true, // ClassMethods
489 true, // Required
490 PD->classmeth_begin(),
491 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000492 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
493 Values);
494
495 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
496 if (Entry) {
497 // Already created, just update the initializer
498 Entry->setInitializer(Init);
499 } else {
500 Entry =
501 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
502 llvm::GlobalValue::InternalLinkage,
503 Init,
504 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
505 &CGM.getModule());
506 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
507 UsedGlobals.push_back(Entry);
508 // FIXME: Is this necessary? Why only for protocol?
509 Entry->setAlignment(4);
510 }
511}
512
513llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
514 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
515
516 if (!Entry) {
517 std::vector<llvm::Constant*> Values(5);
518 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
519 Values[1] = GetClassName(PD->getIdentifier());
520 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
521 Values[3] = Values[4] =
522 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
523 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
524 Values);
525
526 Entry =
527 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
528 llvm::GlobalValue::InternalLinkage,
529 Init,
530 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
531 &CGM.getModule());
532 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
533 UsedGlobals.push_back(Entry);
534 // FIXME: Is this necessary? Why only for protocol?
535 Entry->setAlignment(4);
536 }
537
538 return Entry;
539}
540
541/*
542 struct _objc_protocol_extension {
543 uint32_t size;
544 struct objc_method_description_list *optional_instance_methods;
545 struct objc_method_description_list *optional_class_methods;
546 struct objc_property_list *instance_properties;
547 };
548*/
549llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
550 uint64_t Size =
551 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
552 std::vector<llvm::Constant*> Values(4);
553 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000554 Values[1] = EmitMethodDescList(PD->getName(),
555 true, // IsProtocol
556 false, // ClassMethods
557 false, // Required
558 PD->instmeth_begin(),
559 PD->instmeth_end());
560 Values[2] = EmitMethodDescList(PD->getName(),
561 true, // IsProtocol
562 true, // ClassMethods
563 false, // Required
564 PD->classmeth_begin(),
565 PD->classmeth_end());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000566 Values[3] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_PROTO_LIST_") +
567 PD->getName(),
568 PD->classprop_begin(),
569 PD->classprop_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000570
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000571 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000572 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
573 Values[3]->isNullValue())
574 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
575
576 llvm::Constant *Init =
577 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
578 llvm::GlobalVariable *GV =
579 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
580 llvm::GlobalValue::InternalLinkage,
581 Init,
582 (std::string("\01L_OBJC_PROTOCOLEXT_") +
583 PD->getName()),
584 &CGM.getModule());
585 // No special section, but goes in llvm.used
586 UsedGlobals.push_back(GV);
587
588 return GV;
589}
590
591/*
592 struct objc_protocol_list {
593 struct objc_protocol_list *next;
594 long count;
595 Protocol *list[];
596 };
597*/
Daniel Dunbardbc93372008-08-21 21:57:41 +0000598llvm::Constant *
599CGObjCMac::EmitProtocolList(const std::string &Name,
600 ObjCProtocolDecl::protocol_iterator begin,
601 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000602 std::vector<llvm::Constant*> ProtocolRefs;
603
Daniel Dunbardbc93372008-08-21 21:57:41 +0000604 for (; begin != end; ++begin)
605 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000606
607 // Just return null for empty protocol lists
608 if (ProtocolRefs.empty())
609 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
610
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000611 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000612 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
613
614 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000615 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000616 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
617 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
618 Values[2] =
619 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
620 ProtocolRefs.size()),
621 ProtocolRefs);
622
623 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
624 llvm::GlobalVariable *GV =
625 new llvm::GlobalVariable(Init->getType(), false,
626 llvm::GlobalValue::InternalLinkage,
627 Init,
Daniel Dunbardbc93372008-08-21 21:57:41 +0000628 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000629 &CGM.getModule());
630 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
631 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
632}
633
634/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000635 struct _objc_property {
636 const char * const name;
637 const char * const attributes;
638 };
639
640 struct _objc_property_list {
641 uint32_t entsize; // sizeof (struct _objc_property)
642 uint32_t prop_count;
643 struct _objc_property[prop_count];
644 };
645*/
646llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
647 ObjCPropertyDecl * const *begin,
648 ObjCPropertyDecl * const *end) {
649 std::vector<llvm::Constant*> Properties, Prop(2);
650 for (; begin != end; ++begin) {
651 const ObjCPropertyDecl *PD = *begin;
652 Prop[0] = GetPropertyName(PD->getIdentifier());
653 Prop[1] = GetPropertyType(PD);
654 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
655 Prop));
656 }
657
658 // Return null for empty list.
659 if (Properties.empty())
660 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
661
662 unsigned PropertySize =
663 CGM.getTargetData().getABITypeSize(ObjCTypes.PropertyTy);
664 std::vector<llvm::Constant*> Values(3);
665 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
666 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
667 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
668 Properties.size());
669 Values[2] = llvm::ConstantArray::get(AT, Properties);
670 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
671
672 llvm::GlobalVariable *GV =
673 new llvm::GlobalVariable(Init->getType(), false,
674 llvm::GlobalValue::InternalLinkage,
675 Init,
676 Name,
677 &CGM.getModule());
678 // No special section on property lists?
679 UsedGlobals.push_back(GV);
680 return llvm::ConstantExpr::getBitCast(GV,
681 ObjCTypes.PropertyListPtrTy);
682
683}
684
685/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000686 struct objc_method_description_list {
687 int count;
688 struct objc_method_description list[];
689 };
690*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000691llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
692 bool IsProtocol,
693 bool ClassMethods,
694 bool Required,
695 ObjCMethodDecl * const *begin,
696 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000697 std::vector<llvm::Constant*> Methods, Desc(2);
698 for (; begin != end; ++begin) {
699 ObjCMethodDecl *D = *begin;
700 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
701
702 // Skip if this method is required and we are outputting optional
703 // methods, or vice versa.
704 if (Required != IsRequired)
705 continue;
706
707 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
708 ObjCTypes.SelectorPtrTy);
709 Desc[1] = GetMethodVarType(D);
710 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
711 Desc));
712 }
713
714 // Return null for empty list.
715 if (Methods.empty())
716 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
717
718 std::vector<llvm::Constant*> Values(2);
719 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
720 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
721 Methods.size());
722 Values[1] = llvm::ConstantArray::get(AT, Methods);
723 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
724
725 char Prefix[256];
726 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
727 IsProtocol ? "PROTOCOL_" : "",
728 ClassMethods ? "CLASS_" : "INSTANCE_",
729 !Required ? "OPT_" : "");
730 llvm::GlobalVariable *GV =
731 new llvm::GlobalVariable(Init->getType(), false,
732 llvm::GlobalValue::InternalLinkage,
733 Init,
734 std::string(Prefix) + TypeName,
735 &CGM.getModule());
736 if (ClassMethods) {
737 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
738 } else {
739 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
740 }
741 UsedGlobals.push_back(GV);
742 return llvm::ConstantExpr::getBitCast(GV,
743 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000744}
745
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000746/*
747 struct _objc_category {
748 char *category_name;
749 char *class_name;
750 struct _objc_method_list *instance_methods;
751 struct _objc_method_list *class_methods;
752 struct _objc_protocol_list *protocols;
753 uint32_t size; // <rdar://4585769>
754 struct _objc_property_list *instance_properties;
755 };
756 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000757void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000758 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
759
760 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
761 std::string ExtName(std::string(Interface->getName()) +
762 "_" +
763 OCD->getName());
764
765 std::vector<llvm::Constant*> Values(7);
766 Values[0] = GetClassName(OCD->getIdentifier());
767 Values[1] = GetClassName(Interface->getIdentifier());
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000768 Values[2] =
769 EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") +
770 ExtName,
771 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
772 OCD->instmeth_begin(),
773 OCD->instmeth_end());
774 Values[3] =
775 EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
776 "__OBJC,__cat_class_meth,regular,no_dead_strip",
777 OCD->classmeth_begin(),
778 OCD->classmeth_end());
779 Values[4] =
780 EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
781 Interface->protocol_begin(),
782 Interface->protocol_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000783 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000784 Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
785 Interface->classprop_begin(),
786 Interface->classprop_end());
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000787
788 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
789 Values);
790
791 llvm::GlobalVariable *GV =
792 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
793 llvm::GlobalValue::InternalLinkage,
794 Init,
795 std::string("\01L_OBJC_CATEGORY_")+ExtName,
796 &CGM.getModule());
797 GV->setSection("__OBJC,__category,regular,no_dead_strip");
798 UsedGlobals.push_back(GV);
799 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000800}
801
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000802// FIXME: Get from somewhere?
803enum ClassFlags {
804 eClassFlags_Factory = 0x00001,
805 eClassFlags_Meta = 0x00002,
806 // <rdr://5142207>
807 eClassFlags_HasCXXStructors = 0x02000,
808 eClassFlags_Hidden = 0x20000,
809 eClassFlags_ABI2_Hidden = 0x00010,
810 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
811};
812
813// <rdr://5142207&4705298&4843145>
814static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
815 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
816 // FIXME: Support -fvisibility
817 switch (attr->getVisibility()) {
818 default:
819 assert(0 && "Unknown visibility");
820 return false;
821 case VisibilityAttr::DefaultVisibility:
822 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
823 return false;
824 case VisibilityAttr::HiddenVisibility:
825 return true;
826 }
827 } else {
828 return false; // FIXME: Support -fvisibility
829 }
830}
831
832/*
833 struct _objc_class {
834 Class isa;
835 Class super_class;
836 const char *name;
837 long version;
838 long info;
839 long instance_size;
840 struct _objc_ivar_list *ivars;
841 struct _objc_method_list *methods;
842 struct _objc_cache *cache;
843 struct _objc_protocol_list *protocols;
844 // Objective-C 1.0 extensions (<rdr://4585769>)
845 const char *ivar_layout;
846 struct _objc_class_ext *ext;
847 };
848
849 See EmitClassExtension();
850 */
851void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
852 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000853 // FIXME: Gross
854 ObjCInterfaceDecl *Interface =
855 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000856 llvm::Constant *Protocols =
857 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
858 Interface->protocol_begin(),
859 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000860 const llvm::Type *InterfaceTy =
861 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
862 unsigned Flags = eClassFlags_Factory;
863 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
864
865 // FIXME: Set CXX-structors flag.
866 if (IsClassHidden(ID->getClassInterface()))
867 Flags |= eClassFlags_Hidden;
868
869 std::vector<llvm::Constant*> Values(12);
870 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
871 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
872 Values[ 1] =
873 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
874 ObjCTypes.ClassPtrTy);
875 } else {
876 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
877 }
878 Values[ 2] = GetClassName(ID->getIdentifier());
879 // Version is always 0.
880 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
881 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
882 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
883 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000884 Values[ 7] =
885 EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
886 "__OBJC,__inst_meth,regular,no_dead_strip",
887 ID->instmeth_begin(),
888 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000889 // cache is always NULL.
890 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
891 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000892 // FIXME: Set ivar_layout
893 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000894 Values[11] = EmitClassExtension(ID);
895 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
896 Values);
897
898 llvm::GlobalVariable *GV =
899 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
900 llvm::GlobalValue::InternalLinkage,
901 Init,
902 std::string("\01L_OBJC_CLASS_")+ClassName,
903 &CGM.getModule());
904 GV->setSection("__OBJC,__class,regular,no_dead_strip");
905 UsedGlobals.push_back(GV);
906 // FIXME: Why?
907 GV->setAlignment(32);
908 DefinedClasses.push_back(GV);
909}
910
911llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
912 llvm::Constant *Protocols,
913 const llvm::Type *InterfaceTy) {
914 const char *ClassName = ID->getName();
915 unsigned Flags = eClassFlags_Meta;
916 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
917
918 if (IsClassHidden(ID->getClassInterface()))
919 Flags |= eClassFlags_Hidden;
920
921 std::vector<llvm::Constant*> Values(12);
922 // The isa for the metaclass is the root of the hierarchy.
923 const ObjCInterfaceDecl *Root = ID->getClassInterface();
924 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
925 Root = Super;
926 Values[ 0] =
927 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
928 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000929 // The super class for the metaclass is emitted as the name of the
930 // super class. The runtime fixes this up to point to the
931 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000932 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
933 Values[ 1] =
934 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
935 ObjCTypes.ClassPtrTy);
936 } else {
937 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
938 }
939 Values[ 2] = GetClassName(ID->getIdentifier());
940 // Version is always 0.
941 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
942 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
943 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
944 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000945 Values[ 7] =
946 EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
947 "__OBJC,__inst_meth,regular,no_dead_strip",
948 ID->classmeth_begin(),
949 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000950 // cache is always NULL.
951 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
952 Values[ 9] = Protocols;
953 // ivar_layout for metaclass is always NULL.
954 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
955 // The class extension is always unused for metaclasses.
956 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
957 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
958 Values);
959
960 llvm::GlobalVariable *GV =
961 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
962 llvm::GlobalValue::InternalLinkage,
963 Init,
964 std::string("\01L_OBJC_METACLASS_")+ClassName,
965 &CGM.getModule());
966 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
967 UsedGlobals.push_back(GV);
968 // FIXME: Why?
969 GV->setAlignment(32);
970
971 return GV;
972}
973
974/*
975 struct objc_class_ext {
976 uint32_t size;
977 const char *weak_ivar_layout;
978 struct _objc_property_list *properties;
979 };
980*/
981llvm::Constant *
982CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
983 uint64_t Size =
984 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
985
986 std::vector<llvm::Constant*> Values(3);
987 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000988 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000989 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000990 Values[2] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") +
991 ID->getName(),
992 ID->getClassInterface()->classprop_begin(),
993 ID->getClassInterface()->classprop_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000994
995 // Return null if no extension bits are used.
996 if (Values[1]->isNullValue() && Values[2]->isNullValue())
997 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
998
999 llvm::Constant *Init =
1000 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
1001 llvm::GlobalVariable *GV =
1002 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
1003 llvm::GlobalValue::InternalLinkage,
1004 Init,
1005 (std::string("\01L_OBJC_CLASSEXT_") +
1006 ID->getName()),
1007 &CGM.getModule());
1008 // No special section, but goes in llvm.used
1009 UsedGlobals.push_back(GV);
1010
1011 return GV;
1012}
1013
1014/*
1015 struct objc_ivar {
1016 char *ivar_name;
1017 char *ivar_type;
1018 int ivar_offset;
1019 };
1020
1021 struct objc_ivar_list {
1022 int ivar_count;
1023 struct objc_ivar list[count];
1024 };
1025 */
1026llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
1027 bool ForClass,
1028 const llvm::Type *InterfaceTy) {
1029 std::vector<llvm::Constant*> Ivars, Ivar(3);
1030
1031 // When emitting the root class GCC emits ivar entries for the
1032 // actual class structure. It is not clear if we need to follow this
1033 // behavior; for now lets try and get away with not doing it. If so,
1034 // the cleanest solution would be to make up an ObjCInterfaceDecl
1035 // for the class.
1036 if (ForClass)
1037 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1038
1039 const llvm::StructLayout *Layout =
1040 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
1041 for (ObjCInterfaceDecl::ivar_iterator
1042 i = ID->getClassInterface()->ivar_begin(),
1043 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
1044 ObjCIvarDecl *V = *i;
1045 unsigned Offset =
1046 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
1047 std::string TypeStr;
1048 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
1049 Ivar[0] = GetMethodVarName(V->getIdentifier());
1050 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
1051 EncodingRecordTypes);
1052 Ivar[1] = GetMethodVarType(TypeStr);
1053 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
1054 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
1055 Ivar));
1056 }
1057
1058 // Return null for empty list.
1059 if (Ivars.empty())
1060 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
1061
1062 std::vector<llvm::Constant*> Values(2);
1063 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
1064 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
1065 Ivars.size());
1066 Values[1] = llvm::ConstantArray::get(AT, Ivars);
1067 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1068
1069 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1070 "\01L_OBJC_INSTANCE_VARIABLES_");
1071 llvm::GlobalVariable *GV =
1072 new llvm::GlobalVariable(Init->getType(), false,
1073 llvm::GlobalValue::InternalLinkage,
1074 Init,
1075 std::string(Prefix) + ID->getName(),
1076 &CGM.getModule());
1077 if (ForClass) {
1078 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1079 // FIXME: Why is this only here?
1080 GV->setAlignment(32);
1081 } else {
1082 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1083 }
1084 UsedGlobals.push_back(GV);
1085 return llvm::ConstantExpr::getBitCast(GV,
1086 ObjCTypes.IvarListPtrTy);
1087}
1088
1089/*
1090 struct objc_method {
1091 SEL method_name;
1092 char *method_types;
1093 void *method;
1094 };
1095
1096 struct objc_method_list {
1097 struct objc_method_list *obsolete;
1098 int count;
1099 struct objc_method methods_list[count];
1100 };
1101*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001102llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1103 const char *Section,
1104 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1105 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001106 std::vector<llvm::Constant*> Methods, Method(3);
1107
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001108 for (; begin != end; ++begin) {
1109 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001110
1111 Method[0] =
1112 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1113 ObjCTypes.SelectorPtrTy);
1114 Method[1] = GetMethodVarType(MD);
1115
1116 // FIXME: This is gross, we shouldn't be looking up by name.
1117 std::string Name;
1118 GetNameForMethod(MD, Name);
1119 Method[2] =
1120 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1121 ObjCTypes.Int8PtrTy);
1122 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1123 Method));
1124 }
1125
1126 // Return null for empty list.
1127 if (Methods.empty())
1128 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1129
1130 std::vector<llvm::Constant*> Values(3);
1131 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1132 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1133 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1134 Methods.size());
1135 Values[2] = llvm::ConstantArray::get(AT, Methods);
1136 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1137
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001138 llvm::GlobalVariable *GV =
1139 new llvm::GlobalVariable(Init->getType(), false,
1140 llvm::GlobalValue::InternalLinkage,
1141 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001142 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001143 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001144 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001145 UsedGlobals.push_back(GV);
1146 return llvm::ConstantExpr::getBitCast(GV,
1147 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001148}
1149
1150llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1151 const llvm::Type *ReturnTy =
1152 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1153 const llvm::Type *SelfTy =
1154 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1155
1156 std::vector<const llvm::Type*> ArgTys;
1157 ArgTys.reserve(1 + 2 + OMD->param_size());
1158
1159 // FIXME: This is not something we should have to be dealing with
1160 // here.
1161 bool useStructRet =
1162 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1163 if (useStructRet) {
1164 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1165 ReturnTy = llvm::Type::VoidTy;
1166 }
1167
1168 // Implicit arguments
1169 ArgTys.push_back(SelfTy);
1170 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1171
1172 for (ObjCMethodDecl::param_const_iterator
1173 i = OMD->param_begin(), e = OMD->param_end();
1174 i != e; ++i) {
1175 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001176 if (Ty->isSingleValueType()) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001177 ArgTys.push_back(Ty);
1178 } else {
1179 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1180 }
1181 }
1182
1183 std::string Name;
1184 GetNameForMethod(OMD, Name);
1185
1186 llvm::Function *Method =
1187 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1188 ArgTys,
1189 OMD->isVariadic()),
1190 llvm::GlobalValue::InternalLinkage,
1191 Name,
1192 &CGM.getModule());
1193
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001194 unsigned Offset = 3; // Return plus self and selector implicit args.
1195 if (useStructRet) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001196 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001197 ++Offset;
1198 }
1199
1200 // FIXME: This is horrible, we need to be reusing the machinery in
1201 // CodeGenModule.cpp (SetFunctionAttributes).
1202 for (ObjCMethodDecl::param_const_iterator
1203 i = OMD->param_begin(), e = OMD->param_end();
1204 i != e; ++i, ++Offset) {
1205 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1206 if (!Ty->isSingleValueType())
1207 Method->addParamAttr(Offset, llvm::ParamAttr::ByVal);
1208 }
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001209
1210 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001211}
1212
1213llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001214 // Abuse this interface function as a place to finalize.
1215 FinishModule();
1216
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001217 return NULL;
1218}
1219
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001220/* *** Private Interface *** */
1221
1222/// EmitImageInfo - Emit the image info marker used to encode some module
1223/// level information.
1224///
1225/// See: <rdr://4810609&4810587&4810587>
1226/// struct IMAGE_INFO {
1227/// unsigned version;
1228/// unsigned flags;
1229/// };
1230enum ImageInfoFlags {
1231 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1232 eImageInfo_GarbageCollected = (1 << 1),
1233 eImageInfo_GCOnly = (1 << 2)
1234};
1235
1236void CGObjCMac::EmitImageInfo() {
1237 unsigned version = 0; // Version is unused?
1238 unsigned flags = 0;
1239
1240 // FIXME: Fix and continue?
1241 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1242 flags |= eImageInfo_GarbageCollected;
1243 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1244 flags |= eImageInfo_GCOnly;
1245
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001246 // Emitted as int[2];
1247 llvm::Constant *values[2] = {
1248 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1249 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1250 };
1251 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001252 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001253 new llvm::GlobalVariable(AT, true,
1254 llvm::GlobalValue::InternalLinkage,
1255 llvm::ConstantArray::get(AT, values, 2),
1256 "\01L_OBJC_IMAGE_INFO",
1257 &CGM.getModule());
1258
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001259 if (ObjCABI == 1) {
1260 GV->setSection("__OBJC, __image_info,regular");
1261 } else {
1262 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1263 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001264
1265 UsedGlobals.push_back(GV);
1266}
1267
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001268
1269// struct objc_module {
1270// unsigned long version;
1271// unsigned long size;
1272// const char *name;
1273// Symtab symtab;
1274// };
1275
1276// FIXME: Get from somewhere
1277static const int ModuleVersion = 7;
1278
1279void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001280 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1281
1282 std::vector<llvm::Constant*> Values(4);
1283 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1284 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001285 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001286 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001287 Values[3] = EmitModuleSymbols();
1288
1289 llvm::GlobalVariable *GV =
1290 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1291 llvm::GlobalValue::InternalLinkage,
1292 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1293 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001294 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001295 &CGM.getModule());
1296 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1297 UsedGlobals.push_back(GV);
1298}
1299
1300llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001301 std::vector<llvm::Constant*> Values(5);
1302 unsigned NumClasses = DefinedClasses.size();
1303 unsigned NumCategories = DefinedCategories.size();
1304
1305 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1306 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1307 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1308 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1309
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001310 // The runtime expects exactly the list of defined classes followed
1311 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001312 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001313 for (unsigned i=0; i<NumClasses; i++)
1314 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1315 ObjCTypes.Int8PtrTy);
1316 for (unsigned i=0; i<NumCategories; i++)
1317 Symbols[NumClasses + i] =
1318 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1319 ObjCTypes.Int8PtrTy);
1320
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001321 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001322 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001323 NumClasses + NumCategories),
1324 Symbols);
1325
1326 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1327
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001328 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001329 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001330 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001331 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001332 "\01L_OBJC_SYMBOLS",
1333 &CGM.getModule());
1334 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1335 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001336 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1337}
1338
1339llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1340 const ObjCInterfaceDecl *ID) {
1341 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1342
1343 if (!Entry) {
1344 llvm::Constant *Casted =
1345 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1346 ObjCTypes.ClassPtrTy);
1347 Entry =
1348 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1349 llvm::GlobalValue::InternalLinkage,
1350 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1351 &CGM.getModule());
1352 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1353 UsedGlobals.push_back(Entry);
1354 }
1355
1356 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001357}
1358
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001359llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1360 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1361
1362 if (!Entry) {
1363 llvm::Constant *Casted =
1364 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1365 ObjCTypes.SelectorPtrTy);
1366 Entry =
1367 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1368 llvm::GlobalValue::InternalLinkage,
1369 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1370 &CGM.getModule());
1371 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1372 UsedGlobals.push_back(Entry);
1373 }
1374
1375 return Builder.CreateLoad(Entry, false, "tmp");
1376}
1377
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001378llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1379 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001380
1381 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001382 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001383 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001384 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001385 llvm::GlobalValue::InternalLinkage,
1386 C, "\01L_OBJC_CLASS_NAME_",
1387 &CGM.getModule());
1388 Entry->setSection("__TEXT,__cstring,cstring_literals");
1389 UsedGlobals.push_back(Entry);
1390 }
1391
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001392 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001393}
1394
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001395llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1396 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1397
1398 if (!Entry) {
1399 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1400 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001401 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001402 llvm::GlobalValue::InternalLinkage,
1403 C, "\01L_OBJC_METH_VAR_NAME_",
1404 &CGM.getModule());
1405 Entry->setSection("__TEXT,__cstring,cstring_literals");
1406 UsedGlobals.push_back(Entry);
1407 }
1408
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001409 return getConstantGEP(Entry, 0, 0);
1410}
1411
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001412// FIXME: Merge into a single cstring creation function.
1413llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1414 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1415}
1416
1417// FIXME: Merge into a single cstring creation function.
1418llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1419 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1420}
1421
1422llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1423 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001424
1425 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001426 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001427 Entry =
1428 new llvm::GlobalVariable(C->getType(), false,
1429 llvm::GlobalValue::InternalLinkage,
1430 C, "\01L_OBJC_METH_VAR_TYPE_",
1431 &CGM.getModule());
1432 Entry->setSection("__TEXT,__cstring,cstring_literals");
1433 UsedGlobals.push_back(Entry);
1434 }
1435
1436 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001437}
1438
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001439// FIXME: Merge into a single cstring creation function.
1440llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1441 std::string TypeStr;
1442 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1443 return GetMethodVarType(TypeStr);
1444}
1445
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001446// FIXME: Merge into a single cstring creation function.
1447llvm::Constant *CGObjCMac::GetPropertyName(IdentifierInfo *Ident) {
1448 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
1449
1450 if (!Entry) {
1451 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
1452 Entry =
1453 new llvm::GlobalVariable(C->getType(), false,
1454 llvm::GlobalValue::InternalLinkage,
1455 C, "\01L_OBJC_PROP_NAME_ATTR_",
1456 &CGM.getModule());
1457 Entry->setSection("__TEXT,__cstring,cstring_literals");
1458 UsedGlobals.push_back(Entry);
1459 }
1460
1461 return getConstantGEP(Entry, 0, 0);
1462}
1463
1464// FIXME: Merge into a single cstring creation function.
1465llvm::Constant *CGObjCMac::GetPropertyType(const ObjCPropertyDecl *PD) {
1466 std::string TypeStr("MOOO!");
1467 //CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1468 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
1469}
1470
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001471void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1472 std::string &NameOut) {
1473 // FIXME: Find the mangling GCC uses.
1474 std::stringstream s;
1475 s << (D->isInstance() ? "-" : "+");
1476 s << "[";
1477 s << D->getClassInterface()->getName();
1478 s << " ";
1479 s << D->getSelector().getName();
1480 s << "]";
1481 NameOut = s.str();
1482}
1483
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001484void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001485 EmitModuleInfo();
1486
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001487 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001488
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001489 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001490 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001491 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001492 }
1493
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001494 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001495 llvm::GlobalValue *GV =
1496 new llvm::GlobalVariable(AT, false,
1497 llvm::GlobalValue::AppendingLinkage,
1498 llvm::ConstantArray::get(AT, Used),
1499 "llvm.used",
1500 &CGM.getModule());
1501
1502 GV->setSection("llvm.metadata");
1503}
1504
1505/* *** */
1506
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001507ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
1508 : CGM(cgm),
1509 CFStringType(0),
1510 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001511 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001512{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001513 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1514 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001515
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001516 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001517 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001518 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001519 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1520
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001521 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1522 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001523
1524 // FIXME: It would be nice to unify this with the opaque type, so
1525 // that the IR comes out a bit cleaner.
1526 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1527 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001528
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001529 MethodDescriptionTy =
1530 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001531 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001532 NULL);
1533 CGM.getModule().addTypeName("struct._objc_method_description",
1534 MethodDescriptionTy);
1535
1536 MethodDescriptionListTy =
1537 llvm::StructType::get(IntTy,
1538 llvm::ArrayType::get(MethodDescriptionTy, 0),
1539 NULL);
1540 CGM.getModule().addTypeName("struct._objc_method_description_list",
1541 MethodDescriptionListTy);
1542 MethodDescriptionListPtrTy =
1543 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1544
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00001545 PropertyTy = llvm::StructType::get(Int8PtrTy,
1546 Int8PtrTy,
1547 NULL);
1548 CGM.getModule().addTypeName("struct._objc_property",
1549 PropertyTy);
1550
1551 PropertyListTy = llvm::StructType::get(IntTy,
1552 IntTy,
1553 llvm::ArrayType::get(PropertyTy, 0),
1554 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001555 CGM.getModule().addTypeName("struct._objc_property_list",
1556 PropertyListTy);
1557 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1558
1559 // Protocol description structures
1560
1561 ProtocolExtensionTy =
1562 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1563 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1564 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1565 PropertyListPtrTy,
1566 NULL);
1567 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1568 ProtocolExtensionTy);
1569 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1570
1571 // Handle recursive construction of Protocl and ProtocolList types
1572
1573 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1574 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1575
1576 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1577 LongTy,
1578 llvm::ArrayType::get(ProtocolTyHolder, 0),
1579 NULL);
1580 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1581
1582 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001583 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001584 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1585 MethodDescriptionListPtrTy,
1586 MethodDescriptionListPtrTy,
1587 NULL);
1588 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1589
1590 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1591 CGM.getModule().addTypeName("struct._objc_protocol_list",
1592 ProtocolListTy);
1593 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1594
1595 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1596 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1597 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001598
1599 // Class description structures
1600
1601 IvarTy = llvm::StructType::get(Int8PtrTy,
1602 Int8PtrTy,
1603 IntTy,
1604 NULL);
1605 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1606
1607 IvarListTy = llvm::OpaqueType::get();
1608 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1609 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1610
1611 MethodTy = llvm::StructType::get(SelectorPtrTy,
1612 Int8PtrTy,
1613 Int8PtrTy,
1614 NULL);
1615 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1616
1617 MethodListTy = llvm::OpaqueType::get();
1618 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1619 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1620
1621 CacheTy = llvm::OpaqueType::get();
1622 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1623 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1624
1625 ClassExtensionTy =
1626 llvm::StructType::get(IntTy,
1627 Int8PtrTy,
1628 PropertyListPtrTy,
1629 NULL);
1630 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1631 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1632
1633 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1634
1635 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1636 llvm::PointerType::getUnqual(ClassTyHolder),
1637 Int8PtrTy,
1638 LongTy,
1639 LongTy,
1640 LongTy,
1641 IvarListPtrTy,
1642 MethodListPtrTy,
1643 CachePtrTy,
1644 ProtocolListPtrTy,
1645 Int8PtrTy,
1646 ClassExtensionPtrTy,
1647 NULL);
1648 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1649
1650 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1651 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1652 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1653
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001654 CategoryTy = llvm::StructType::get(Int8PtrTy,
1655 Int8PtrTy,
1656 MethodListPtrTy,
1657 MethodListPtrTy,
1658 ProtocolListPtrTy,
1659 IntTy,
1660 PropertyListPtrTy,
1661 NULL);
1662 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1663
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001664 // Global metadata structures
1665
1666 SymtabTy = llvm::StructType::get(LongTy,
1667 SelectorPtrTy,
1668 ShortTy,
1669 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001670 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001671 NULL);
1672 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1673 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1674
1675 ModuleTy =
1676 llvm::StructType::get(LongTy,
1677 LongTy,
1678 Int8PtrTy,
1679 SymtabPtrTy,
1680 NULL);
1681 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001682}
1683
1684ObjCTypesHelper::~ObjCTypesHelper() {
1685}
1686
1687const llvm::StructType *ObjCTypesHelper::getCFStringType() {
1688 if (!CFStringType) {
1689 CFStringType =
1690 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
1691 llvm::Type::Int32Ty,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001692 Int8PtrTy,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001693 LongTy,
1694 NULL);
1695
1696 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
1697 }
1698
1699 return CFStringType;
1700}
1701
1702llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
1703 if (!CFConstantStringClassReference) {
1704 llvm::GlobalValue *GV =
1705 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
1706 false,
1707 llvm::GlobalValue::ExternalLinkage,
1708 0, "__CFConstantStringClassReference",
1709 &CGM.getModule());
1710
1711 // Decay to pointer.
1712 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1713 }
1714
1715 return CFConstantStringClassReference;
1716}
1717
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001718llvm::Function *ObjCTypesHelper::getMessageSendFn() {
1719 if (!MessageSendFn) {
1720 std::vector<const llvm::Type*> Params;
1721 Params.push_back(ObjectPtrTy);
1722 Params.push_back(SelectorPtrTy);
1723 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1724 Params,
1725 true),
1726 llvm::Function::ExternalLinkage,
1727 "objc_msgSend",
1728 &CGM.getModule());
1729 }
1730
1731 return MessageSendFn;
1732}
1733
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001734/* *** */
1735
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001736CodeGen::CGObjCRuntime *
1737CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001738 return new CGObjCMac(CGM);
1739}