blob: 14d9bc42b0110c39b2208fc287f8dbcbbde09d3c [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;
83 /// PropertyListTy - LLVM type for struct objc_property_list.
84 const llvm::Type *PropertyListTy;
85 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
86 const llvm::Type *PropertyListPtrTy;
87 /// ProtocolListTy - LLVM type for struct objc_property_list.
88 const llvm::Type *ProtocolListTy;
89 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
90 const llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +000091 /// CategoryTy - LLVM type for struct objc_category.
92 const llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +000093 /// ClassTy - LLVM type for struct objc_class.
94 const llvm::StructType *ClassTy;
95 /// ClassPtrTy - LLVM type for struct objc_class *.
96 const llvm::Type *ClassPtrTy;
97 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
98 const llvm::StructType *ClassExtensionTy;
99 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
100 const llvm::Type *ClassExtensionPtrTy;
101 /// CacheTy - LLVM type for struct objc_cache.
102 const llvm::Type *CacheTy;
103 /// CachePtrTy - LLVM type for struct objc_cache *.
104 const llvm::Type *CachePtrTy;
105 // IvarTy - LLVM type for struct objc_ivar.
106 const llvm::StructType *IvarTy;
107 /// IvarListTy - LLVM type for struct objc_ivar_list.
108 const llvm::Type *IvarListTy;
109 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
110 const llvm::Type *IvarListPtrTy;
111 // MethodTy - LLVM type for struct objc_method.
112 const llvm::StructType *MethodTy;
113 /// MethodListTy - LLVM type for struct objc_method_list.
114 const llvm::Type *MethodListTy;
115 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
116 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000117
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000118public:
119 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
120 ~ObjCTypesHelper();
121
122 llvm::Constant *getCFConstantStringClassReference();
123 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000124 llvm::Function *getMessageSendFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000125};
126
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000127class CGObjCMac : public CodeGen::CGObjCRuntime {
128private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000129 CodeGen::CodeGenModule &CGM;
130 ObjCTypesHelper ObjCTypes;
131 /// ObjCABI - FIXME: Not sure yet.
132 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000133
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000134 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000135 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000136
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000137 /// MethodVarNames - uniqued method variable names.
138 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
139
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000140 /// MethodVarTypes - uniqued method type signatures. We have to use
141 /// a StringMap here because have no other unique reference.
142 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
143
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000144 /// ClassReferences - uniqued class references.
145 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
146
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000147 /// SelectorReferences - uniqued selector references.
148 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
149
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000150 /// Protocols - Protocols for which an objc_protocol structure has
151 /// been emitted. Forward declarations are handled by creating an
152 /// empty structure whose initializer is filled in when/if defined.
153 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
154
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000155 /// DefinedClasses - List of defined classes.
156 std::vector<llvm::GlobalValue*> DefinedClasses;
157
158 /// DefinedCategories - List of defined categories.
159 std::vector<llvm::GlobalValue*> DefinedCategories;
160
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000161 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000162 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000163 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000164
165 /// EmitImageInfo - Emit the image info marker used to encode some module
166 /// level information.
167 void EmitImageInfo();
168
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000169 /// EmitModuleInfo - Another marker encoding module level
170 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000171 void EmitModuleInfo();
172
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000173 /// EmitModuleSymols - Emit module symbols, the list of defined
174 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000175 llvm::Constant *EmitModuleSymbols();
176
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000177 /// FinishModule - Write out global data structures at the end of
178 /// processing a translation unit.
179 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000180
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000181 /// EmitClassExtension - Generate the class extension structure used
182 /// to store the weak ivar layout and properties. The return value
183 /// has type ClassExtensionPtrTy.
184 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
185
186 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
187 /// for the given class.
188 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
189 const ObjCInterfaceDecl *ID);
190
191 /// EmitIvarList - Emit the ivar list for the given
192 /// implementation. If ForClass is true the list of class ivars
193 /// (i.e. metaclass ivars) is emitted, otherwise the list of
194 /// interface ivars will be emitted. The return value has type
195 /// IvarListPtrTy.
196 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
197 bool ForClass,
198 const llvm::Type *InterfaceTy);
199
200 /// EmitMetaClass - Emit a class structure for the metaclass of the
201 /// given implementation. return value has type ClassPtrTy.
202 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
203 llvm::Constant *Protocols,
204 const llvm::Type *InterfaceTy);
205
206 /// EmitMethodList - Emit the method list for the given
207 /// implementation. If ForClass is true the list of class methods
208 /// will be emitted, otherwise the list of instance methods will be
209 /// generated.The return value has type MethodListPtrTy.
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000210 llvm::Constant *EmitMethodList(const std::string &Name,
211 const char *Section,
212 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
213 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000214
215 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000216 /// method declarations.
217 /// - TypeName: The name for the type containing the methods.
218 /// - IsProtocol: True iff these methods are for a protocol.
219 /// - ClassMethds: True iff these are class methods.
220 /// - Required: When true, only "required" methods are
221 /// listed. Similarly, when false only "optional" methods are
222 /// listed. For classes this should always be true.
223 /// - begin, end: The method list to output.
224 ///
225 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000226 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
227 bool IsProtocol,
228 bool ClassMethods,
229 bool Required,
230 ObjCMethodDecl * const *begin,
231 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000232
233 /// EmitProtocolExtension - Generate the protocol extension
234 /// structure used to store optional instance and class methods, and
235 /// protocol properties. The return value has type
236 /// ProtocolExtensionPtrTy.
237 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
238
239 /// EmitProtocolList - Generate the list of referenced
240 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc93372008-08-21 21:57:41 +0000241 llvm::Constant *EmitProtocolList(const std::string &Name,
242 ObjCProtocolDecl::protocol_iterator begin,
243 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000244
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000245 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
246 /// for the given selector.
247 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
248
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000249 /// GetProtocolRef - Return a reference to the internal protocol
250 /// description, creating an empty one if it has not been
251 /// defined. The return value has type pointer-to ProtocolTy.
252 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
253
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000254 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000255 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000256 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000257
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000258 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000259 /// selector's name. This returns a constant i8* to the start of
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000260 /// the name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000261 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000262 llvm::Constant *GetMethodVarName(IdentifierInfo *);
263 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000264
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000265 /// GetMethodVarType - Return a unique constant for the given
266 /// selector's name. This returns a constant i8* to the start of
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000267 /// the name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000268 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000269 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000270
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000271 /// GetNameForMethod - Return a name for the given method.
272 /// \param[out] NameOut - The return value.
273 void GetNameForMethod(const ObjCMethodDecl *OMD,
274 std::string &NameOut);
275
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000276public:
277 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000278 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000279
280 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
281 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000282 llvm::Value *Receiver,
283 Selector Sel,
284 llvm::Value** ArgV,
285 unsigned ArgC);
286
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000287 virtual llvm::Value *
288 GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
289 const llvm::Type *ReturnTy,
290 const ObjCInterfaceDecl *SuperClass,
291 llvm::Value *Receiver,
292 Selector Sel,
293 llvm::Value** ArgV,
294 unsigned ArgC);
295
296 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000297 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000298
299 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
300
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000301 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000302
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000303 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000304
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000305 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000306
307 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000308 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000309
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000310 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000311
312 virtual llvm::Function *ModuleInitFunction();
313};
314} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000315
316/* *** Helper Functions *** */
317
318/// getConstantGEP() - Help routine to construct simple GEPs.
319static llvm::Constant *getConstantGEP(llvm::Constant *C,
320 unsigned idx0,
321 unsigned idx1) {
322 llvm::Value *Idxs[] = {
323 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
324 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
325 };
326 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
327}
328
329/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000330
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000331CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
332 : CGM(cgm),
333 ObjCTypes(cgm),
334 ObjCABI(1)
335{
336 // FIXME: How does this get set in GCC? And what does it even mean?
337 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
338 ObjCABI = 2;
339
340 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000341}
342
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000343/// GetClass - Return a reference to the class for the given interface
344/// decl.
345llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000346 const ObjCInterfaceDecl *ID) {
347 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000348}
349
350/// GetSelector - Return the pointer to the unique'd string for this selector.
351llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000352 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000353}
354
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000355/// Generate a constant CFString object.
356/*
357 struct __builtin_CFString {
358 const int *isa; // point to __CFConstantStringClassReference
359 int flags;
360 const char *str;
361 long length;
362 };
363*/
364
365llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
366 // FIXME: I have no idea what this constant is (it is a magic
367 // constant in GCC as well). Most likely the encoding of the string
368 // and at least one part of it relates to UTF-16. Is this just the
369 // code for UTF-8? Where is this handled for us?
370 // See: <rdr://2996215>
371 unsigned flags = 0x07c8;
372
373 // FIXME: Use some machinery to unique this. We can't reuse the CGM
374 // one since we put them in a different section.
375 llvm::Constant *StringC = llvm::ConstantArray::get(String);
376 llvm::Constant *StringGV =
377 new llvm::GlobalVariable(StringC->getType(), true,
378 llvm::GlobalValue::InternalLinkage,
379 StringC, ".str", &CGM.getModule());
380 llvm::Constant *Values[4] = {
381 ObjCTypes.getCFConstantStringClassReference(),
382 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
383 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
384 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
385 };
386
387 llvm::Constant *CFStringC =
388 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
389 std::vector<llvm::Constant*>(Values, Values+4));
390
391 llvm::GlobalVariable *CFStringGV =
392 new llvm::GlobalVariable(CFStringC->getType(), true,
393 llvm::GlobalValue::InternalLinkage,
394 CFStringC, "",
395 &CGM.getModule());
396
397 CFStringGV->setSection("__DATA, __cfstring");
398
399 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000400}
401
402/// Generates a message send where the super is the receiver. This is
403/// a message send to self with special delivery semantics indicating
404/// which class's method should be called.
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000405llvm::Value *
406CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
407 const llvm::Type *ReturnTy,
408 const ObjCInterfaceDecl *SuperClass,
409 llvm::Value *Receiver,
410 Selector Sel,
411 llvm::Value** ArgV,
412 unsigned ArgC) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000413 assert(0 && "Cannot generate message send to super for Mac runtime.");
414 return 0;
415}
416
417/// Generate code for a message send expression.
418llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
419 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000420 llvm::Value *Receiver,
421 Selector Sel,
422 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000423 unsigned ArgC) {
424 llvm::Function *F = ObjCTypes.getMessageSendFn();
425 llvm::Value **Args = new llvm::Value*[ArgC+2];
426 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
427 Args[1] = EmitSelector(Builder, Sel);
428 std::copy(ArgV, ArgV+ArgC, Args+2);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000429
430 std::vector<const llvm::Type*> Params;
431 Params.push_back(ObjCTypes.ObjectPtrTy);
432 Params.push_back(ObjCTypes.SelectorPtrTy);
433 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
434 Params,
435 true);
436 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
437 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
438 llvm::CallInst *CI = Builder.CreateCall(C,
439 Args, Args+ArgC+2, "tmp");
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000440 delete[] Args;
441 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000442}
443
444llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000445 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000446 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
447 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000448}
449
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000450/*
451 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
452 struct _objc_protocol {
453 struct _objc_protocol_extension *isa;
454 char *protocol_name;
455 struct _objc_protocol_list *protocol_list;
456 struct _objc__method_prototype_list *instance_methods;
457 struct _objc__method_prototype_list *class_methods
458 };
459
460 See EmitProtocolExtension().
461*/
462void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
463 const char *ProtocolName = PD->getName();
464
465 std::vector<llvm::Constant*> Values(5);
466 Values[0] = EmitProtocolExtension(PD);
467 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000468 Values[2] =
469 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
470 PD->protocol_begin(),
471 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000472 Values[3] = EmitMethodDescList(ProtocolName,
473 true, // IsProtocol
474 false, // ClassMethods
475 true, // Required
476 PD->instmeth_begin(),
477 PD->instmeth_end());
478 Values[4] = EmitMethodDescList(ProtocolName,
479 true, // IsProtocol
480 true, // ClassMethods
481 true, // Required
482 PD->classmeth_begin(),
483 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000484 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
485 Values);
486
487 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
488 if (Entry) {
489 // Already created, just update the initializer
490 Entry->setInitializer(Init);
491 } else {
492 Entry =
493 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
494 llvm::GlobalValue::InternalLinkage,
495 Init,
496 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
497 &CGM.getModule());
498 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
499 UsedGlobals.push_back(Entry);
500 // FIXME: Is this necessary? Why only for protocol?
501 Entry->setAlignment(4);
502 }
503}
504
505llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
506 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
507
508 if (!Entry) {
509 std::vector<llvm::Constant*> Values(5);
510 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
511 Values[1] = GetClassName(PD->getIdentifier());
512 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
513 Values[3] = Values[4] =
514 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
515 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
516 Values);
517
518 Entry =
519 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
520 llvm::GlobalValue::InternalLinkage,
521 Init,
522 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
523 &CGM.getModule());
524 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
525 UsedGlobals.push_back(Entry);
526 // FIXME: Is this necessary? Why only for protocol?
527 Entry->setAlignment(4);
528 }
529
530 return Entry;
531}
532
533/*
534 struct _objc_protocol_extension {
535 uint32_t size;
536 struct objc_method_description_list *optional_instance_methods;
537 struct objc_method_description_list *optional_class_methods;
538 struct objc_property_list *instance_properties;
539 };
540*/
541llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
542 uint64_t Size =
543 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
544 std::vector<llvm::Constant*> Values(4);
545 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000546 Values[1] = EmitMethodDescList(PD->getName(),
547 true, // IsProtocol
548 false, // ClassMethods
549 false, // Required
550 PD->instmeth_begin(),
551 PD->instmeth_end());
552 Values[2] = EmitMethodDescList(PD->getName(),
553 true, // IsProtocol
554 true, // ClassMethods
555 false, // Required
556 PD->classmeth_begin(),
557 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000558 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
559 assert(!PD->getNumPropertyDecl() &&
560 "Cannot emit Obj-C protocol properties for NeXT runtime.");
561
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000562 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000563 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
564 Values[3]->isNullValue())
565 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
566
567 llvm::Constant *Init =
568 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
569 llvm::GlobalVariable *GV =
570 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
571 llvm::GlobalValue::InternalLinkage,
572 Init,
573 (std::string("\01L_OBJC_PROTOCOLEXT_") +
574 PD->getName()),
575 &CGM.getModule());
576 // No special section, but goes in llvm.used
577 UsedGlobals.push_back(GV);
578
579 return GV;
580}
581
582/*
583 struct objc_protocol_list {
584 struct objc_protocol_list *next;
585 long count;
586 Protocol *list[];
587 };
588*/
Daniel Dunbardbc93372008-08-21 21:57:41 +0000589llvm::Constant *
590CGObjCMac::EmitProtocolList(const std::string &Name,
591 ObjCProtocolDecl::protocol_iterator begin,
592 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000593 std::vector<llvm::Constant*> ProtocolRefs;
594
Daniel Dunbardbc93372008-08-21 21:57:41 +0000595 for (; begin != end; ++begin)
596 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000597
598 // Just return null for empty protocol lists
599 if (ProtocolRefs.empty())
600 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
601
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000602 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000603 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
604
605 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000606 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000607 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
608 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
609 Values[2] =
610 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
611 ProtocolRefs.size()),
612 ProtocolRefs);
613
614 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
615 llvm::GlobalVariable *GV =
616 new llvm::GlobalVariable(Init->getType(), false,
617 llvm::GlobalValue::InternalLinkage,
618 Init,
Daniel Dunbardbc93372008-08-21 21:57:41 +0000619 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000620 &CGM.getModule());
621 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
622 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
623}
624
625/*
626 struct objc_method_description_list {
627 int count;
628 struct objc_method_description list[];
629 };
630*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000631llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
632 bool IsProtocol,
633 bool ClassMethods,
634 bool Required,
635 ObjCMethodDecl * const *begin,
636 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000637 std::vector<llvm::Constant*> Methods, Desc(2);
638 for (; begin != end; ++begin) {
639 ObjCMethodDecl *D = *begin;
640 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
641
642 // Skip if this method is required and we are outputting optional
643 // methods, or vice versa.
644 if (Required != IsRequired)
645 continue;
646
647 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
648 ObjCTypes.SelectorPtrTy);
649 Desc[1] = GetMethodVarType(D);
650 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
651 Desc));
652 }
653
654 // Return null for empty list.
655 if (Methods.empty())
656 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
657
658 std::vector<llvm::Constant*> Values(2);
659 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
660 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
661 Methods.size());
662 Values[1] = llvm::ConstantArray::get(AT, Methods);
663 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
664
665 char Prefix[256];
666 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
667 IsProtocol ? "PROTOCOL_" : "",
668 ClassMethods ? "CLASS_" : "INSTANCE_",
669 !Required ? "OPT_" : "");
670 llvm::GlobalVariable *GV =
671 new llvm::GlobalVariable(Init->getType(), false,
672 llvm::GlobalValue::InternalLinkage,
673 Init,
674 std::string(Prefix) + TypeName,
675 &CGM.getModule());
676 if (ClassMethods) {
677 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
678 } else {
679 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
680 }
681 UsedGlobals.push_back(GV);
682 return llvm::ConstantExpr::getBitCast(GV,
683 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000684}
685
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000686/*
687 struct _objc_category {
688 char *category_name;
689 char *class_name;
690 struct _objc_method_list *instance_methods;
691 struct _objc_method_list *class_methods;
692 struct _objc_protocol_list *protocols;
693 uint32_t size; // <rdar://4585769>
694 struct _objc_property_list *instance_properties;
695 };
696 */
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000697void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000698 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.CategoryTy);
699
700 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
701 std::string ExtName(std::string(Interface->getName()) +
702 "_" +
703 OCD->getName());
704
705 std::vector<llvm::Constant*> Values(7);
706 Values[0] = GetClassName(OCD->getIdentifier());
707 Values[1] = GetClassName(Interface->getIdentifier());
708 Values[2] = EmitMethodList(std::string("\01L_OBJC_CATEGORY_INSTANCE_METHODS_") + ExtName,
709 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
710 OCD->instmeth_begin(),
711 OCD->instmeth_end());
712 Values[3] = EmitMethodList(std::string("\01L_OBJC_CATEGORY_CLASS_METHODS_") + ExtName,
713 "__OBJC,__cat_class_meth,regular,no_dead_strip",
714 OCD->classmeth_begin(),
715 OCD->classmeth_end());
716 Values[4] = EmitProtocolList(std::string("\01L_OBJC_CATEGORY_PROTOCOLS_") + ExtName,
717 Interface->protocol_begin(),
718 Interface->protocol_end());
719 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
720 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
721
722 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
723 Values);
724
725 llvm::GlobalVariable *GV =
726 new llvm::GlobalVariable(ObjCTypes.CategoryTy, false,
727 llvm::GlobalValue::InternalLinkage,
728 Init,
729 std::string("\01L_OBJC_CATEGORY_")+ExtName,
730 &CGM.getModule());
731 GV->setSection("__OBJC,__category,regular,no_dead_strip");
732 UsedGlobals.push_back(GV);
733 DefinedCategories.push_back(GV);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000734}
735
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000736// FIXME: Get from somewhere?
737enum ClassFlags {
738 eClassFlags_Factory = 0x00001,
739 eClassFlags_Meta = 0x00002,
740 // <rdr://5142207>
741 eClassFlags_HasCXXStructors = 0x02000,
742 eClassFlags_Hidden = 0x20000,
743 eClassFlags_ABI2_Hidden = 0x00010,
744 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
745};
746
747// <rdr://5142207&4705298&4843145>
748static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
749 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
750 // FIXME: Support -fvisibility
751 switch (attr->getVisibility()) {
752 default:
753 assert(0 && "Unknown visibility");
754 return false;
755 case VisibilityAttr::DefaultVisibility:
756 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
757 return false;
758 case VisibilityAttr::HiddenVisibility:
759 return true;
760 }
761 } else {
762 return false; // FIXME: Support -fvisibility
763 }
764}
765
766/*
767 struct _objc_class {
768 Class isa;
769 Class super_class;
770 const char *name;
771 long version;
772 long info;
773 long instance_size;
774 struct _objc_ivar_list *ivars;
775 struct _objc_method_list *methods;
776 struct _objc_cache *cache;
777 struct _objc_protocol_list *protocols;
778 // Objective-C 1.0 extensions (<rdr://4585769>)
779 const char *ivar_layout;
780 struct _objc_class_ext *ext;
781 };
782
783 See EmitClassExtension();
784 */
785void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
786 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000787 // FIXME: Gross
788 ObjCInterfaceDecl *Interface =
789 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000790 llvm::Constant *Protocols =
791 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
792 Interface->protocol_begin(),
793 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000794 const llvm::Type *InterfaceTy =
795 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
796 unsigned Flags = eClassFlags_Factory;
797 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
798
799 // FIXME: Set CXX-structors flag.
800 if (IsClassHidden(ID->getClassInterface()))
801 Flags |= eClassFlags_Hidden;
802
803 std::vector<llvm::Constant*> Values(12);
804 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
805 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
806 Values[ 1] =
807 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
808 ObjCTypes.ClassPtrTy);
809 } else {
810 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
811 }
812 Values[ 2] = GetClassName(ID->getIdentifier());
813 // Version is always 0.
814 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
815 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
816 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
817 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000818 Values[ 7] = EmitMethodList(std::string("\01L_OBJC_INSTANCE_METHODS_") + ID->getName(),
819 "__OBJC,__inst_meth,regular,no_dead_strip",
820 ID->instmeth_begin(),
821 ID->instmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000822 // cache is always NULL.
823 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
824 Values[ 9] = Protocols;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000825 // FIXME: Set ivar_layout
826 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000827 Values[11] = EmitClassExtension(ID);
828 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
829 Values);
830
831 llvm::GlobalVariable *GV =
832 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
833 llvm::GlobalValue::InternalLinkage,
834 Init,
835 std::string("\01L_OBJC_CLASS_")+ClassName,
836 &CGM.getModule());
837 GV->setSection("__OBJC,__class,regular,no_dead_strip");
838 UsedGlobals.push_back(GV);
839 // FIXME: Why?
840 GV->setAlignment(32);
841 DefinedClasses.push_back(GV);
842}
843
844llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
845 llvm::Constant *Protocols,
846 const llvm::Type *InterfaceTy) {
847 const char *ClassName = ID->getName();
848 unsigned Flags = eClassFlags_Meta;
849 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
850
851 if (IsClassHidden(ID->getClassInterface()))
852 Flags |= eClassFlags_Hidden;
853
854 std::vector<llvm::Constant*> Values(12);
855 // The isa for the metaclass is the root of the hierarchy.
856 const ObjCInterfaceDecl *Root = ID->getClassInterface();
857 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
858 Root = Super;
859 Values[ 0] =
860 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
861 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000862 // The super class for the metaclass is emitted as the name of the
863 // super class. The runtime fixes this up to point to the
864 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000865 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
866 Values[ 1] =
867 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
868 ObjCTypes.ClassPtrTy);
869 } else {
870 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
871 }
872 Values[ 2] = GetClassName(ID->getIdentifier());
873 // Version is always 0.
874 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
875 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
876 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
877 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000878 Values[ 7] = EmitMethodList(std::string("\01L_OBJC_CLASS_METHODS_") + ID->getName(),
879 "__OBJC,__inst_meth,regular,no_dead_strip",
880 ID->classmeth_begin(),
881 ID->classmeth_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000882 // cache is always NULL.
883 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
884 Values[ 9] = Protocols;
885 // ivar_layout for metaclass is always NULL.
886 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
887 // The class extension is always unused for metaclasses.
888 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
889 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
890 Values);
891
892 llvm::GlobalVariable *GV =
893 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
894 llvm::GlobalValue::InternalLinkage,
895 Init,
896 std::string("\01L_OBJC_METACLASS_")+ClassName,
897 &CGM.getModule());
898 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
899 UsedGlobals.push_back(GV);
900 // FIXME: Why?
901 GV->setAlignment(32);
902
903 return GV;
904}
905
906/*
907 struct objc_class_ext {
908 uint32_t size;
909 const char *weak_ivar_layout;
910 struct _objc_property_list *properties;
911 };
912*/
913llvm::Constant *
914CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
915 uint64_t Size =
916 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
917
918 std::vector<llvm::Constant*> Values(3);
919 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000920 // FIXME: Output weak_ivar_layout string.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000921 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
922 // FIXME: Output properties.
923 Values[2] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
924 assert(!ID->getClassInterface()->getNumPropertyDecl() &&
925 "Cannot emit Obj-C class properties for NeXt runtime.");
926
927 // Return null if no extension bits are used.
928 if (Values[1]->isNullValue() && Values[2]->isNullValue())
929 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
930
931 llvm::Constant *Init =
932 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
933 llvm::GlobalVariable *GV =
934 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
935 llvm::GlobalValue::InternalLinkage,
936 Init,
937 (std::string("\01L_OBJC_CLASSEXT_") +
938 ID->getName()),
939 &CGM.getModule());
940 // No special section, but goes in llvm.used
941 UsedGlobals.push_back(GV);
942
943 return GV;
944}
945
946/*
947 struct objc_ivar {
948 char *ivar_name;
949 char *ivar_type;
950 int ivar_offset;
951 };
952
953 struct objc_ivar_list {
954 int ivar_count;
955 struct objc_ivar list[count];
956 };
957 */
958llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
959 bool ForClass,
960 const llvm::Type *InterfaceTy) {
961 std::vector<llvm::Constant*> Ivars, Ivar(3);
962
963 // When emitting the root class GCC emits ivar entries for the
964 // actual class structure. It is not clear if we need to follow this
965 // behavior; for now lets try and get away with not doing it. If so,
966 // the cleanest solution would be to make up an ObjCInterfaceDecl
967 // for the class.
968 if (ForClass)
969 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
970
971 const llvm::StructLayout *Layout =
972 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
973 for (ObjCInterfaceDecl::ivar_iterator
974 i = ID->getClassInterface()->ivar_begin(),
975 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
976 ObjCIvarDecl *V = *i;
977 unsigned Offset =
978 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
979 std::string TypeStr;
980 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
981 Ivar[0] = GetMethodVarName(V->getIdentifier());
982 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
983 EncodingRecordTypes);
984 Ivar[1] = GetMethodVarType(TypeStr);
985 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
986 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
987 Ivar));
988 }
989
990 // Return null for empty list.
991 if (Ivars.empty())
992 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
993
994 std::vector<llvm::Constant*> Values(2);
995 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
996 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
997 Ivars.size());
998 Values[1] = llvm::ConstantArray::get(AT, Ivars);
999 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1000
1001 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
1002 "\01L_OBJC_INSTANCE_VARIABLES_");
1003 llvm::GlobalVariable *GV =
1004 new llvm::GlobalVariable(Init->getType(), false,
1005 llvm::GlobalValue::InternalLinkage,
1006 Init,
1007 std::string(Prefix) + ID->getName(),
1008 &CGM.getModule());
1009 if (ForClass) {
1010 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
1011 // FIXME: Why is this only here?
1012 GV->setAlignment(32);
1013 } else {
1014 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
1015 }
1016 UsedGlobals.push_back(GV);
1017 return llvm::ConstantExpr::getBitCast(GV,
1018 ObjCTypes.IvarListPtrTy);
1019}
1020
1021/*
1022 struct objc_method {
1023 SEL method_name;
1024 char *method_types;
1025 void *method;
1026 };
1027
1028 struct objc_method_list {
1029 struct objc_method_list *obsolete;
1030 int count;
1031 struct objc_method methods_list[count];
1032 };
1033*/
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001034llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name,
1035 const char *Section,
1036 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator begin,
1037 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator end) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001038 std::vector<llvm::Constant*> Methods, Method(3);
1039
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001040 for (; begin != end; ++begin) {
1041 ObjCMethodDecl *MD = *begin;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001042
1043 Method[0] =
1044 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
1045 ObjCTypes.SelectorPtrTy);
1046 Method[1] = GetMethodVarType(MD);
1047
1048 // FIXME: This is gross, we shouldn't be looking up by name.
1049 std::string Name;
1050 GetNameForMethod(MD, Name);
1051 Method[2] =
1052 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
1053 ObjCTypes.Int8PtrTy);
1054 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
1055 Method));
1056 }
1057
1058 // Return null for empty list.
1059 if (Methods.empty())
1060 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1061
1062 std::vector<llvm::Constant*> Values(3);
1063 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1064 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1065 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1066 Methods.size());
1067 Values[2] = llvm::ConstantArray::get(AT, Methods);
1068 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1069
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001070 llvm::GlobalVariable *GV =
1071 new llvm::GlobalVariable(Init->getType(), false,
1072 llvm::GlobalValue::InternalLinkage,
1073 Init,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001074 Name,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001075 &CGM.getModule());
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001076 GV->setSection(Section);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001077 UsedGlobals.push_back(GV);
1078 return llvm::ConstantExpr::getBitCast(GV,
1079 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001080}
1081
1082llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1083 const llvm::Type *ReturnTy =
1084 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1085 const llvm::Type *SelfTy =
1086 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1087
1088 std::vector<const llvm::Type*> ArgTys;
1089 ArgTys.reserve(1 + 2 + OMD->param_size());
1090
1091 // FIXME: This is not something we should have to be dealing with
1092 // here.
1093 bool useStructRet =
1094 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1095 if (useStructRet) {
1096 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1097 ReturnTy = llvm::Type::VoidTy;
1098 }
1099
1100 // Implicit arguments
1101 ArgTys.push_back(SelfTy);
1102 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1103
1104 for (ObjCMethodDecl::param_const_iterator
1105 i = OMD->param_begin(), e = OMD->param_end();
1106 i != e; ++i) {
1107 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1108 if (Ty->isFirstClassType()) {
1109 ArgTys.push_back(Ty);
1110 } else {
1111 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1112 }
1113 }
1114
1115 std::string Name;
1116 GetNameForMethod(OMD, Name);
1117
1118 llvm::Function *Method =
1119 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1120 ArgTys,
1121 OMD->isVariadic()),
1122 llvm::GlobalValue::InternalLinkage,
1123 Name,
1124 &CGM.getModule());
1125
1126 if (useStructRet)
1127 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
1128
1129 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001130}
1131
1132llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001133 // Abuse this interface function as a place to finalize.
1134 FinishModule();
1135
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001136 return NULL;
1137}
1138
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001139/* *** Private Interface *** */
1140
1141/// EmitImageInfo - Emit the image info marker used to encode some module
1142/// level information.
1143///
1144/// See: <rdr://4810609&4810587&4810587>
1145/// struct IMAGE_INFO {
1146/// unsigned version;
1147/// unsigned flags;
1148/// };
1149enum ImageInfoFlags {
1150 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1151 eImageInfo_GarbageCollected = (1 << 1),
1152 eImageInfo_GCOnly = (1 << 2)
1153};
1154
1155void CGObjCMac::EmitImageInfo() {
1156 unsigned version = 0; // Version is unused?
1157 unsigned flags = 0;
1158
1159 // FIXME: Fix and continue?
1160 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1161 flags |= eImageInfo_GarbageCollected;
1162 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1163 flags |= eImageInfo_GCOnly;
1164
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001165 // Emitted as int[2];
1166 llvm::Constant *values[2] = {
1167 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1168 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1169 };
1170 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001171 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001172 new llvm::GlobalVariable(AT, true,
1173 llvm::GlobalValue::InternalLinkage,
1174 llvm::ConstantArray::get(AT, values, 2),
1175 "\01L_OBJC_IMAGE_INFO",
1176 &CGM.getModule());
1177
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001178 if (ObjCABI == 1) {
1179 GV->setSection("__OBJC, __image_info,regular");
1180 } else {
1181 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1182 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001183
1184 UsedGlobals.push_back(GV);
1185}
1186
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001187
1188// struct objc_module {
1189// unsigned long version;
1190// unsigned long size;
1191// const char *name;
1192// Symtab symtab;
1193// };
1194
1195// FIXME: Get from somewhere
1196static const int ModuleVersion = 7;
1197
1198void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001199 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1200
1201 std::vector<llvm::Constant*> Values(4);
1202 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1203 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001204 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001205 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001206 Values[3] = EmitModuleSymbols();
1207
1208 llvm::GlobalVariable *GV =
1209 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1210 llvm::GlobalValue::InternalLinkage,
1211 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1212 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001213 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001214 &CGM.getModule());
1215 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1216 UsedGlobals.push_back(GV);
1217}
1218
1219llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001220 std::vector<llvm::Constant*> Values(5);
1221 unsigned NumClasses = DefinedClasses.size();
1222 unsigned NumCategories = DefinedCategories.size();
1223
1224 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1225 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1226 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1227 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1228
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001229 // The runtime expects exactly the list of defined classes followed
1230 // by the list of defined categories, in a single array.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001231 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001232 for (unsigned i=0; i<NumClasses; i++)
1233 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
1234 ObjCTypes.Int8PtrTy);
1235 for (unsigned i=0; i<NumCategories; i++)
1236 Symbols[NumClasses + i] =
1237 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
1238 ObjCTypes.Int8PtrTy);
1239
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001240 Values[4] =
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001241 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001242 NumClasses + NumCategories),
1243 Symbols);
1244
1245 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1246
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001247 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001248 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001249 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001250 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001251 "\01L_OBJC_SYMBOLS",
1252 &CGM.getModule());
1253 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1254 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001255 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1256}
1257
1258llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1259 const ObjCInterfaceDecl *ID) {
1260 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1261
1262 if (!Entry) {
1263 llvm::Constant *Casted =
1264 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1265 ObjCTypes.ClassPtrTy);
1266 Entry =
1267 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1268 llvm::GlobalValue::InternalLinkage,
1269 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1270 &CGM.getModule());
1271 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1272 UsedGlobals.push_back(Entry);
1273 }
1274
1275 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001276}
1277
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001278llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1279 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1280
1281 if (!Entry) {
1282 llvm::Constant *Casted =
1283 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1284 ObjCTypes.SelectorPtrTy);
1285 Entry =
1286 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1287 llvm::GlobalValue::InternalLinkage,
1288 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1289 &CGM.getModule());
1290 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1291 UsedGlobals.push_back(Entry);
1292 }
1293
1294 return Builder.CreateLoad(Entry, false, "tmp");
1295}
1296
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001297llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1298 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001299
1300 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001301 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001302 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001303 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001304 llvm::GlobalValue::InternalLinkage,
1305 C, "\01L_OBJC_CLASS_NAME_",
1306 &CGM.getModule());
1307 Entry->setSection("__TEXT,__cstring,cstring_literals");
1308 UsedGlobals.push_back(Entry);
1309 }
1310
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001311 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001312}
1313
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001314llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1315 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1316
1317 if (!Entry) {
1318 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1319 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001320 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001321 llvm::GlobalValue::InternalLinkage,
1322 C, "\01L_OBJC_METH_VAR_NAME_",
1323 &CGM.getModule());
1324 Entry->setSection("__TEXT,__cstring,cstring_literals");
1325 UsedGlobals.push_back(Entry);
1326 }
1327
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001328 return getConstantGEP(Entry, 0, 0);
1329}
1330
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001331// FIXME: Merge into a single cstring creation function.
1332llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1333 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1334}
1335
1336// FIXME: Merge into a single cstring creation function.
1337llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1338 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1339}
1340
1341llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1342 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001343
1344 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001345 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001346 Entry =
1347 new llvm::GlobalVariable(C->getType(), false,
1348 llvm::GlobalValue::InternalLinkage,
1349 C, "\01L_OBJC_METH_VAR_TYPE_",
1350 &CGM.getModule());
1351 Entry->setSection("__TEXT,__cstring,cstring_literals");
1352 UsedGlobals.push_back(Entry);
1353 }
1354
1355 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001356}
1357
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001358// FIXME: Merge into a single cstring creation function.
1359llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1360 std::string TypeStr;
1361 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1362 return GetMethodVarType(TypeStr);
1363}
1364
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001365void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1366 std::string &NameOut) {
1367 // FIXME: Find the mangling GCC uses.
1368 std::stringstream s;
1369 s << (D->isInstance() ? "-" : "+");
1370 s << "[";
1371 s << D->getClassInterface()->getName();
1372 s << " ";
1373 s << D->getSelector().getName();
1374 s << "]";
1375 NameOut = s.str();
1376}
1377
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001378void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001379 EmitModuleInfo();
1380
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001381 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001382
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001383 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001384 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001385 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001386 }
1387
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001388 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001389 llvm::GlobalValue *GV =
1390 new llvm::GlobalVariable(AT, false,
1391 llvm::GlobalValue::AppendingLinkage,
1392 llvm::ConstantArray::get(AT, Used),
1393 "llvm.used",
1394 &CGM.getModule());
1395
1396 GV->setSection("llvm.metadata");
1397}
1398
1399/* *** */
1400
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001401ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
1402 : CGM(cgm),
1403 CFStringType(0),
1404 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001405 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001406{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001407 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1408 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001409
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001410 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001411 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001412 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001413 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1414
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001415 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1416 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001417
1418 // FIXME: It would be nice to unify this with the opaque type, so
1419 // that the IR comes out a bit cleaner.
1420 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1421 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001422
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001423 MethodDescriptionTy =
1424 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001425 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001426 NULL);
1427 CGM.getModule().addTypeName("struct._objc_method_description",
1428 MethodDescriptionTy);
1429
1430 MethodDescriptionListTy =
1431 llvm::StructType::get(IntTy,
1432 llvm::ArrayType::get(MethodDescriptionTy, 0),
1433 NULL);
1434 CGM.getModule().addTypeName("struct._objc_method_description_list",
1435 MethodDescriptionListTy);
1436 MethodDescriptionListPtrTy =
1437 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1438
1439 PropertyListTy = llvm::OpaqueType::get();
1440 CGM.getModule().addTypeName("struct._objc_property_list",
1441 PropertyListTy);
1442 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1443
1444 // Protocol description structures
1445
1446 ProtocolExtensionTy =
1447 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1448 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1449 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1450 PropertyListPtrTy,
1451 NULL);
1452 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1453 ProtocolExtensionTy);
1454 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1455
1456 // Handle recursive construction of Protocl and ProtocolList types
1457
1458 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1459 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1460
1461 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1462 LongTy,
1463 llvm::ArrayType::get(ProtocolTyHolder, 0),
1464 NULL);
1465 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1466
1467 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001468 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001469 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1470 MethodDescriptionListPtrTy,
1471 MethodDescriptionListPtrTy,
1472 NULL);
1473 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1474
1475 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1476 CGM.getModule().addTypeName("struct._objc_protocol_list",
1477 ProtocolListTy);
1478 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1479
1480 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1481 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1482 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001483
1484 // Class description structures
1485
1486 IvarTy = llvm::StructType::get(Int8PtrTy,
1487 Int8PtrTy,
1488 IntTy,
1489 NULL);
1490 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1491
1492 IvarListTy = llvm::OpaqueType::get();
1493 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1494 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1495
1496 MethodTy = llvm::StructType::get(SelectorPtrTy,
1497 Int8PtrTy,
1498 Int8PtrTy,
1499 NULL);
1500 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1501
1502 MethodListTy = llvm::OpaqueType::get();
1503 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1504 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1505
1506 CacheTy = llvm::OpaqueType::get();
1507 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1508 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1509
1510 ClassExtensionTy =
1511 llvm::StructType::get(IntTy,
1512 Int8PtrTy,
1513 PropertyListPtrTy,
1514 NULL);
1515 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1516 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1517
1518 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1519
1520 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1521 llvm::PointerType::getUnqual(ClassTyHolder),
1522 Int8PtrTy,
1523 LongTy,
1524 LongTy,
1525 LongTy,
1526 IvarListPtrTy,
1527 MethodListPtrTy,
1528 CachePtrTy,
1529 ProtocolListPtrTy,
1530 Int8PtrTy,
1531 ClassExtensionPtrTy,
1532 NULL);
1533 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1534
1535 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1536 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1537 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1538
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001539 CategoryTy = llvm::StructType::get(Int8PtrTy,
1540 Int8PtrTy,
1541 MethodListPtrTy,
1542 MethodListPtrTy,
1543 ProtocolListPtrTy,
1544 IntTy,
1545 PropertyListPtrTy,
1546 NULL);
1547 CGM.getModule().addTypeName("struct._objc_category", CategoryTy);
1548
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001549 // Global metadata structures
1550
1551 SymtabTy = llvm::StructType::get(LongTy,
1552 SelectorPtrTy,
1553 ShortTy,
1554 ShortTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001555 llvm::ArrayType::get(Int8PtrTy, 0),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001556 NULL);
1557 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1558 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1559
1560 ModuleTy =
1561 llvm::StructType::get(LongTy,
1562 LongTy,
1563 Int8PtrTy,
1564 SymtabPtrTy,
1565 NULL);
1566 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001567}
1568
1569ObjCTypesHelper::~ObjCTypesHelper() {
1570}
1571
1572const llvm::StructType *ObjCTypesHelper::getCFStringType() {
1573 if (!CFStringType) {
1574 CFStringType =
1575 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
1576 llvm::Type::Int32Ty,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001577 Int8PtrTy,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001578 LongTy,
1579 NULL);
1580
1581 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
1582 }
1583
1584 return CFStringType;
1585}
1586
1587llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
1588 if (!CFConstantStringClassReference) {
1589 llvm::GlobalValue *GV =
1590 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
1591 false,
1592 llvm::GlobalValue::ExternalLinkage,
1593 0, "__CFConstantStringClassReference",
1594 &CGM.getModule());
1595
1596 // Decay to pointer.
1597 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1598 }
1599
1600 return CFConstantStringClassReference;
1601}
1602
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001603llvm::Function *ObjCTypesHelper::getMessageSendFn() {
1604 if (!MessageSendFn) {
1605 std::vector<const llvm::Type*> Params;
1606 Params.push_back(ObjectPtrTy);
1607 Params.push_back(SelectorPtrTy);
1608 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1609 Params,
1610 true),
1611 llvm::Function::ExternalLinkage,
1612 "objc_msgSend",
1613 &CGM.getModule());
1614 }
1615
1616 return MessageSendFn;
1617}
1618
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001619/* *** */
1620
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001621CodeGen::CGObjCRuntime *
1622CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001623 return new CGObjCMac(CGM);
1624}