blob: 51558f86fa377420ecc19afd0253c660b203b7c7 [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 Dunbar27f9d772008-08-21 04:36:09 +000091 /// ClassTy - LLVM type for struct objc_class.
92 const llvm::StructType *ClassTy;
93 /// ClassPtrTy - LLVM type for struct objc_class *.
94 const llvm::Type *ClassPtrTy;
95 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
96 const llvm::StructType *ClassExtensionTy;
97 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
98 const llvm::Type *ClassExtensionPtrTy;
99 /// CacheTy - LLVM type for struct objc_cache.
100 const llvm::Type *CacheTy;
101 /// CachePtrTy - LLVM type for struct objc_cache *.
102 const llvm::Type *CachePtrTy;
103 // IvarTy - LLVM type for struct objc_ivar.
104 const llvm::StructType *IvarTy;
105 /// IvarListTy - LLVM type for struct objc_ivar_list.
106 const llvm::Type *IvarListTy;
107 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
108 const llvm::Type *IvarListPtrTy;
109 // MethodTy - LLVM type for struct objc_method.
110 const llvm::StructType *MethodTy;
111 /// MethodListTy - LLVM type for struct objc_method_list.
112 const llvm::Type *MethodListTy;
113 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
114 const llvm::Type *MethodListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000115
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000116public:
117 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
118 ~ObjCTypesHelper();
119
120 llvm::Constant *getCFConstantStringClassReference();
121 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000122 llvm::Function *getMessageSendFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000123};
124
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000125class CGObjCMac : public CodeGen::CGObjCRuntime {
126private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000127 CodeGen::CodeGenModule &CGM;
128 ObjCTypesHelper ObjCTypes;
129 /// ObjCABI - FIXME: Not sure yet.
130 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000131
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000132 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000133 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000134
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000135 /// MethodVarNames - uniqued method variable names.
136 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
137
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000138 /// MethodVarTypes - uniqued method type signatures. We have to use
139 /// a StringMap here because have no other unique reference.
140 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
141
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000142 /// ClassReferences - uniqued class references.
143 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
144
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000145 /// SelectorReferences - uniqued selector references.
146 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
147
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000148 /// Protocols - Protocols for which an objc_protocol structure has
149 /// been emitted. Forward declarations are handled by creating an
150 /// empty structure whose initializer is filled in when/if defined.
151 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
152
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000153 /// DefinedClasses - List of defined classes.
154 std::vector<llvm::GlobalValue*> DefinedClasses;
155
156 /// DefinedCategories - List of defined categories.
157 std::vector<llvm::GlobalValue*> DefinedCategories;
158
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000159 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000160 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000161 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000162
163 /// EmitImageInfo - Emit the image info marker used to encode some module
164 /// level information.
165 void EmitImageInfo();
166
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000167 /// EmitModuleInfo - Another marker encoding module level
168 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000169 void EmitModuleInfo();
170
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000171 /// EmitModuleSymols - Emit module symbols, the list of defined
172 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000173 llvm::Constant *EmitModuleSymbols();
174
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000175 /// FinishModule - Write out global data structures at the end of
176 /// processing a translation unit.
177 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000178
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000179 /// EmitClassExtension - Generate the class extension structure used
180 /// to store the weak ivar layout and properties. The return value
181 /// has type ClassExtensionPtrTy.
182 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
183
184 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
185 /// for the given class.
186 llvm::Value *EmitClassRef(llvm::IRBuilder<> &Builder,
187 const ObjCInterfaceDecl *ID);
188
189 /// EmitIvarList - Emit the ivar list for the given
190 /// implementation. If ForClass is true the list of class ivars
191 /// (i.e. metaclass ivars) is emitted, otherwise the list of
192 /// interface ivars will be emitted. The return value has type
193 /// IvarListPtrTy.
194 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
195 bool ForClass,
196 const llvm::Type *InterfaceTy);
197
198 /// EmitMetaClass - Emit a class structure for the metaclass of the
199 /// given implementation. return value has type ClassPtrTy.
200 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
201 llvm::Constant *Protocols,
202 const llvm::Type *InterfaceTy);
203
204 /// EmitMethodList - Emit the method list for the given
205 /// implementation. If ForClass is true the list of class methods
206 /// will be emitted, otherwise the list of instance methods will be
207 /// generated.The return value has type MethodListPtrTy.
208 llvm::Constant *EmitMethodList(const ObjCImplementationDecl *ID,
209 bool ForClass);
210
211 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000212 /// method declarations.
213 /// - TypeName: The name for the type containing the methods.
214 /// - IsProtocol: True iff these methods are for a protocol.
215 /// - ClassMethds: True iff these are class methods.
216 /// - Required: When true, only "required" methods are
217 /// listed. Similarly, when false only "optional" methods are
218 /// listed. For classes this should always be true.
219 /// - begin, end: The method list to output.
220 ///
221 /// The return value has type MethodDescriptionListPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000222 llvm::Constant *EmitMethodDescList(const std::string &TypeName,
223 bool IsProtocol,
224 bool ClassMethods,
225 bool Required,
226 ObjCMethodDecl * const *begin,
227 ObjCMethodDecl * const *end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000228
229 /// EmitProtocolExtension - Generate the protocol extension
230 /// structure used to store optional instance and class methods, and
231 /// protocol properties. The return value has type
232 /// ProtocolExtensionPtrTy.
233 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
234
235 /// EmitProtocolList - Generate the list of referenced
236 /// protocols. The return value has type ProtocolListPtrTy.
Daniel Dunbardbc93372008-08-21 21:57:41 +0000237 llvm::Constant *EmitProtocolList(const std::string &Name,
238 ObjCProtocolDecl::protocol_iterator begin,
239 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000240
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000241 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
242 /// for the given selector.
243 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
244
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000245 /// GetProtocolRef - Return a reference to the internal protocol
246 /// description, creating an empty one if it has not been
247 /// defined. The return value has type pointer-to ProtocolTy.
248 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
249
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000250 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000251 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000252 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000253
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000254 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000255 /// selector's name. This returns a constant i8* to the start of
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000256 /// the name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000257 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000258 llvm::Constant *GetMethodVarName(IdentifierInfo *);
259 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000260
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000261 /// GetMethodVarType - Return a unique constant for the given
262 /// selector's name. This returns a constant i8* to the start of
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000263 /// the name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000264 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000265 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000266
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000267 /// GetNameForMethod - Return a name for the given method.
268 /// \param[out] NameOut - The return value.
269 void GetNameForMethod(const ObjCMethodDecl *OMD,
270 std::string &NameOut);
271
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000272public:
273 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000274 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000275
276 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
277 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000278 llvm::Value *Receiver,
279 Selector Sel,
280 llvm::Value** ArgV,
281 unsigned ArgC);
282
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000283 virtual llvm::Value *
284 GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
285 const llvm::Type *ReturnTy,
286 const ObjCInterfaceDecl *SuperClass,
287 llvm::Value *Receiver,
288 Selector Sel,
289 llvm::Value** ArgV,
290 unsigned ArgC);
291
292 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000293 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000294
295 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
296
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000297 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000298
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000299 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000300
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000301 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000302
303 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000304 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000305
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000306 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000307
308 virtual llvm::Function *ModuleInitFunction();
309};
310} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000311
312/* *** Helper Functions *** */
313
314/// getConstantGEP() - Help routine to construct simple GEPs.
315static llvm::Constant *getConstantGEP(llvm::Constant *C,
316 unsigned idx0,
317 unsigned idx1) {
318 llvm::Value *Idxs[] = {
319 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
320 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
321 };
322 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
323}
324
325/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000326
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000327CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
328 : CGM(cgm),
329 ObjCTypes(cgm),
330 ObjCABI(1)
331{
332 // FIXME: How does this get set in GCC? And what does it even mean?
333 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
334 ObjCABI = 2;
335
336 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000337}
338
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000339/// GetClass - Return a reference to the class for the given interface
340/// decl.
341llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000342 const ObjCInterfaceDecl *ID) {
343 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000344}
345
346/// GetSelector - Return the pointer to the unique'd string for this selector.
347llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000348 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000349}
350
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000351/// Generate a constant CFString object.
352/*
353 struct __builtin_CFString {
354 const int *isa; // point to __CFConstantStringClassReference
355 int flags;
356 const char *str;
357 long length;
358 };
359*/
360
361llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
362 // FIXME: I have no idea what this constant is (it is a magic
363 // constant in GCC as well). Most likely the encoding of the string
364 // and at least one part of it relates to UTF-16. Is this just the
365 // code for UTF-8? Where is this handled for us?
366 // See: <rdr://2996215>
367 unsigned flags = 0x07c8;
368
369 // FIXME: Use some machinery to unique this. We can't reuse the CGM
370 // one since we put them in a different section.
371 llvm::Constant *StringC = llvm::ConstantArray::get(String);
372 llvm::Constant *StringGV =
373 new llvm::GlobalVariable(StringC->getType(), true,
374 llvm::GlobalValue::InternalLinkage,
375 StringC, ".str", &CGM.getModule());
376 llvm::Constant *Values[4] = {
377 ObjCTypes.getCFConstantStringClassReference(),
378 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
379 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
380 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
381 };
382
383 llvm::Constant *CFStringC =
384 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
385 std::vector<llvm::Constant*>(Values, Values+4));
386
387 llvm::GlobalVariable *CFStringGV =
388 new llvm::GlobalVariable(CFStringC->getType(), true,
389 llvm::GlobalValue::InternalLinkage,
390 CFStringC, "",
391 &CGM.getModule());
392
393 CFStringGV->setSection("__DATA, __cfstring");
394
395 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000396}
397
398/// Generates a message send where the super is the receiver. This is
399/// a message send to self with special delivery semantics indicating
400/// which class's method should be called.
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000401llvm::Value *
402CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
403 const llvm::Type *ReturnTy,
404 const ObjCInterfaceDecl *SuperClass,
405 llvm::Value *Receiver,
406 Selector Sel,
407 llvm::Value** ArgV,
408 unsigned ArgC) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000409 assert(0 && "Cannot generate message send to super for Mac runtime.");
410 return 0;
411}
412
413/// Generate code for a message send expression.
414llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
415 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000416 llvm::Value *Receiver,
417 Selector Sel,
418 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000419 unsigned ArgC) {
420 llvm::Function *F = ObjCTypes.getMessageSendFn();
421 llvm::Value **Args = new llvm::Value*[ArgC+2];
422 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
423 Args[1] = EmitSelector(Builder, Sel);
424 std::copy(ArgV, ArgV+ArgC, Args+2);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000425
426 std::vector<const llvm::Type*> Params;
427 Params.push_back(ObjCTypes.ObjectPtrTy);
428 Params.push_back(ObjCTypes.SelectorPtrTy);
429 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
430 Params,
431 true);
432 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
433 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
434 llvm::CallInst *CI = Builder.CreateCall(C,
435 Args, Args+ArgC+2, "tmp");
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000436 delete[] Args;
437 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000438}
439
440llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000441 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000442 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
443 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000444}
445
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000446/*
447 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
448 struct _objc_protocol {
449 struct _objc_protocol_extension *isa;
450 char *protocol_name;
451 struct _objc_protocol_list *protocol_list;
452 struct _objc__method_prototype_list *instance_methods;
453 struct _objc__method_prototype_list *class_methods
454 };
455
456 See EmitProtocolExtension().
457*/
458void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
459 const char *ProtocolName = PD->getName();
460
461 std::vector<llvm::Constant*> Values(5);
462 Values[0] = EmitProtocolExtension(PD);
463 Values[1] = GetClassName(PD->getIdentifier());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000464 Values[2] =
465 EmitProtocolList(std::string("\01L_OBJC_PROTOCOL_REFS_")+PD->getName(),
466 PD->protocol_begin(),
467 PD->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000468 Values[3] = EmitMethodDescList(ProtocolName,
469 true, // IsProtocol
470 false, // ClassMethods
471 true, // Required
472 PD->instmeth_begin(),
473 PD->instmeth_end());
474 Values[4] = EmitMethodDescList(ProtocolName,
475 true, // IsProtocol
476 true, // ClassMethods
477 true, // Required
478 PD->classmeth_begin(),
479 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000480 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
481 Values);
482
483 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
484 if (Entry) {
485 // Already created, just update the initializer
486 Entry->setInitializer(Init);
487 } else {
488 Entry =
489 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
490 llvm::GlobalValue::InternalLinkage,
491 Init,
492 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
493 &CGM.getModule());
494 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
495 UsedGlobals.push_back(Entry);
496 // FIXME: Is this necessary? Why only for protocol?
497 Entry->setAlignment(4);
498 }
499}
500
501llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
502 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
503
504 if (!Entry) {
505 std::vector<llvm::Constant*> Values(5);
506 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
507 Values[1] = GetClassName(PD->getIdentifier());
508 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
509 Values[3] = Values[4] =
510 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
511 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
512 Values);
513
514 Entry =
515 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
516 llvm::GlobalValue::InternalLinkage,
517 Init,
518 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
519 &CGM.getModule());
520 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
521 UsedGlobals.push_back(Entry);
522 // FIXME: Is this necessary? Why only for protocol?
523 Entry->setAlignment(4);
524 }
525
526 return Entry;
527}
528
529/*
530 struct _objc_protocol_extension {
531 uint32_t size;
532 struct objc_method_description_list *optional_instance_methods;
533 struct objc_method_description_list *optional_class_methods;
534 struct objc_property_list *instance_properties;
535 };
536*/
537llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
538 uint64_t Size =
539 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
540 std::vector<llvm::Constant*> Values(4);
541 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000542 Values[1] = EmitMethodDescList(PD->getName(),
543 true, // IsProtocol
544 false, // ClassMethods
545 false, // Required
546 PD->instmeth_begin(),
547 PD->instmeth_end());
548 Values[2] = EmitMethodDescList(PD->getName(),
549 true, // IsProtocol
550 true, // ClassMethods
551 false, // Required
552 PD->classmeth_begin(),
553 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000554 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
555 assert(!PD->getNumPropertyDecl() &&
556 "Cannot emit Obj-C protocol properties for NeXT runtime.");
557
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000558 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000559 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
560 Values[3]->isNullValue())
561 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
562
563 llvm::Constant *Init =
564 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
565 llvm::GlobalVariable *GV =
566 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
567 llvm::GlobalValue::InternalLinkage,
568 Init,
569 (std::string("\01L_OBJC_PROTOCOLEXT_") +
570 PD->getName()),
571 &CGM.getModule());
572 // No special section, but goes in llvm.used
573 UsedGlobals.push_back(GV);
574
575 return GV;
576}
577
578/*
579 struct objc_protocol_list {
580 struct objc_protocol_list *next;
581 long count;
582 Protocol *list[];
583 };
584*/
Daniel Dunbardbc93372008-08-21 21:57:41 +0000585llvm::Constant *
586CGObjCMac::EmitProtocolList(const std::string &Name,
587 ObjCProtocolDecl::protocol_iterator begin,
588 ObjCProtocolDecl::protocol_iterator end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000589 std::vector<llvm::Constant*> ProtocolRefs;
590
Daniel Dunbardbc93372008-08-21 21:57:41 +0000591 for (; begin != end; ++begin)
592 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000593
594 // Just return null for empty protocol lists
595 if (ProtocolRefs.empty())
596 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
597
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000598 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000599 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
600
601 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000602 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000603 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
604 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
605 Values[2] =
606 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
607 ProtocolRefs.size()),
608 ProtocolRefs);
609
610 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
611 llvm::GlobalVariable *GV =
612 new llvm::GlobalVariable(Init->getType(), false,
613 llvm::GlobalValue::InternalLinkage,
614 Init,
Daniel Dunbardbc93372008-08-21 21:57:41 +0000615 Name,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000616 &CGM.getModule());
617 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
618 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
619}
620
621/*
622 struct objc_method_description_list {
623 int count;
624 struct objc_method_description list[];
625 };
626*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000627llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
628 bool IsProtocol,
629 bool ClassMethods,
630 bool Required,
631 ObjCMethodDecl * const *begin,
632 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000633 std::vector<llvm::Constant*> Methods, Desc(2);
634 for (; begin != end; ++begin) {
635 ObjCMethodDecl *D = *begin;
636 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
637
638 // Skip if this method is required and we are outputting optional
639 // methods, or vice versa.
640 if (Required != IsRequired)
641 continue;
642
643 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
644 ObjCTypes.SelectorPtrTy);
645 Desc[1] = GetMethodVarType(D);
646 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
647 Desc));
648 }
649
650 // Return null for empty list.
651 if (Methods.empty())
652 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
653
654 std::vector<llvm::Constant*> Values(2);
655 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
656 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
657 Methods.size());
658 Values[1] = llvm::ConstantArray::get(AT, Methods);
659 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
660
661 char Prefix[256];
662 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
663 IsProtocol ? "PROTOCOL_" : "",
664 ClassMethods ? "CLASS_" : "INSTANCE_",
665 !Required ? "OPT_" : "");
666 llvm::GlobalVariable *GV =
667 new llvm::GlobalVariable(Init->getType(), false,
668 llvm::GlobalValue::InternalLinkage,
669 Init,
670 std::string(Prefix) + TypeName,
671 &CGM.getModule());
672 if (ClassMethods) {
673 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
674 } else {
675 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
676 }
677 UsedGlobals.push_back(GV);
678 return llvm::ConstantExpr::getBitCast(GV,
679 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000680}
681
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000682void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000683 assert(0 && "Cannot generate category for Mac runtime.");
684}
685
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000686// FIXME: Get from somewhere?
687enum ClassFlags {
688 eClassFlags_Factory = 0x00001,
689 eClassFlags_Meta = 0x00002,
690 // <rdr://5142207>
691 eClassFlags_HasCXXStructors = 0x02000,
692 eClassFlags_Hidden = 0x20000,
693 eClassFlags_ABI2_Hidden = 0x00010,
694 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
695};
696
697// <rdr://5142207&4705298&4843145>
698static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
699 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
700 // FIXME: Support -fvisibility
701 switch (attr->getVisibility()) {
702 default:
703 assert(0 && "Unknown visibility");
704 return false;
705 case VisibilityAttr::DefaultVisibility:
706 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
707 return false;
708 case VisibilityAttr::HiddenVisibility:
709 return true;
710 }
711 } else {
712 return false; // FIXME: Support -fvisibility
713 }
714}
715
716/*
717 struct _objc_class {
718 Class isa;
719 Class super_class;
720 const char *name;
721 long version;
722 long info;
723 long instance_size;
724 struct _objc_ivar_list *ivars;
725 struct _objc_method_list *methods;
726 struct _objc_cache *cache;
727 struct _objc_protocol_list *protocols;
728 // Objective-C 1.0 extensions (<rdr://4585769>)
729 const char *ivar_layout;
730 struct _objc_class_ext *ext;
731 };
732
733 See EmitClassExtension();
734 */
735void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
736 const char *ClassName = ID->getName();
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000737 // FIXME: Gross
738 ObjCInterfaceDecl *Interface =
739 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbardbc93372008-08-21 21:57:41 +0000740 llvm::Constant *Protocols =
741 EmitProtocolList(std::string("\01L_OBJC_CLASS_PROTOCOLS_") + ID->getName(),
742 Interface->protocol_begin(),
743 Interface->protocol_end());
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000744 const llvm::Type *InterfaceTy =
745 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
746 unsigned Flags = eClassFlags_Factory;
747 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
748
749 // FIXME: Set CXX-structors flag.
750 if (IsClassHidden(ID->getClassInterface()))
751 Flags |= eClassFlags_Hidden;
752
753 std::vector<llvm::Constant*> Values(12);
754 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
755 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
756 Values[ 1] =
757 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
758 ObjCTypes.ClassPtrTy);
759 } else {
760 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
761 }
762 Values[ 2] = GetClassName(ID->getIdentifier());
763 // Version is always 0.
764 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
765 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
766 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
767 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
768 Values[ 7] = EmitMethodList(ID, false);
769 // cache is always NULL.
770 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
771 Values[ 9] = Protocols;
772 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); // XXX
773 Values[11] = EmitClassExtension(ID);
774 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
775 Values);
776
777 llvm::GlobalVariable *GV =
778 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
779 llvm::GlobalValue::InternalLinkage,
780 Init,
781 std::string("\01L_OBJC_CLASS_")+ClassName,
782 &CGM.getModule());
783 GV->setSection("__OBJC,__class,regular,no_dead_strip");
784 UsedGlobals.push_back(GV);
785 // FIXME: Why?
786 GV->setAlignment(32);
787 DefinedClasses.push_back(GV);
788}
789
790llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
791 llvm::Constant *Protocols,
792 const llvm::Type *InterfaceTy) {
793 const char *ClassName = ID->getName();
794 unsigned Flags = eClassFlags_Meta;
795 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
796
797 if (IsClassHidden(ID->getClassInterface()))
798 Flags |= eClassFlags_Hidden;
799
800 std::vector<llvm::Constant*> Values(12);
801 // The isa for the metaclass is the root of the hierarchy.
802 const ObjCInterfaceDecl *Root = ID->getClassInterface();
803 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
804 Root = Super;
805 Values[ 0] =
806 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
807 ObjCTypes.ClassPtrTy);
808 // FIXME: Document fix-up here.
809 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
810 Values[ 1] =
811 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
812 ObjCTypes.ClassPtrTy);
813 } else {
814 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
815 }
816 Values[ 2] = GetClassName(ID->getIdentifier());
817 // Version is always 0.
818 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
819 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
820 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
821 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
822 Values[ 7] = EmitMethodList(ID, true);
823 // cache is always NULL.
824 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
825 Values[ 9] = Protocols;
826 // ivar_layout for metaclass is always NULL.
827 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
828 // The class extension is always unused for metaclasses.
829 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
830 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
831 Values);
832
833 llvm::GlobalVariable *GV =
834 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
835 llvm::GlobalValue::InternalLinkage,
836 Init,
837 std::string("\01L_OBJC_METACLASS_")+ClassName,
838 &CGM.getModule());
839 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
840 UsedGlobals.push_back(GV);
841 // FIXME: Why?
842 GV->setAlignment(32);
843
844 return GV;
845}
846
847/*
848 struct objc_class_ext {
849 uint32_t size;
850 const char *weak_ivar_layout;
851 struct _objc_property_list *properties;
852 };
853*/
854llvm::Constant *
855CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
856 uint64_t Size =
857 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
858
859 std::vector<llvm::Constant*> Values(3);
860 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
861 // FIXME: Output weak_ivar string.
862 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
863 // FIXME: Output properties.
864 Values[2] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
865 assert(!ID->getClassInterface()->getNumPropertyDecl() &&
866 "Cannot emit Obj-C class properties for NeXt runtime.");
867
868 // Return null if no extension bits are used.
869 if (Values[1]->isNullValue() && Values[2]->isNullValue())
870 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
871
872 llvm::Constant *Init =
873 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
874 llvm::GlobalVariable *GV =
875 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
876 llvm::GlobalValue::InternalLinkage,
877 Init,
878 (std::string("\01L_OBJC_CLASSEXT_") +
879 ID->getName()),
880 &CGM.getModule());
881 // No special section, but goes in llvm.used
882 UsedGlobals.push_back(GV);
883
884 return GV;
885}
886
887/*
888 struct objc_ivar {
889 char *ivar_name;
890 char *ivar_type;
891 int ivar_offset;
892 };
893
894 struct objc_ivar_list {
895 int ivar_count;
896 struct objc_ivar list[count];
897 };
898 */
899llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
900 bool ForClass,
901 const llvm::Type *InterfaceTy) {
902 std::vector<llvm::Constant*> Ivars, Ivar(3);
903
904 // When emitting the root class GCC emits ivar entries for the
905 // actual class structure. It is not clear if we need to follow this
906 // behavior; for now lets try and get away with not doing it. If so,
907 // the cleanest solution would be to make up an ObjCInterfaceDecl
908 // for the class.
909 if (ForClass)
910 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
911
912 const llvm::StructLayout *Layout =
913 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
914 for (ObjCInterfaceDecl::ivar_iterator
915 i = ID->getClassInterface()->ivar_begin(),
916 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
917 ObjCIvarDecl *V = *i;
918 unsigned Offset =
919 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
920 std::string TypeStr;
921 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
922 Ivar[0] = GetMethodVarName(V->getIdentifier());
923 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
924 EncodingRecordTypes);
925 Ivar[1] = GetMethodVarType(TypeStr);
926 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
927 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
928 Ivar));
929 }
930
931 // Return null for empty list.
932 if (Ivars.empty())
933 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
934
935 std::vector<llvm::Constant*> Values(2);
936 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
937 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
938 Ivars.size());
939 Values[1] = llvm::ConstantArray::get(AT, Ivars);
940 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
941
942 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
943 "\01L_OBJC_INSTANCE_VARIABLES_");
944 llvm::GlobalVariable *GV =
945 new llvm::GlobalVariable(Init->getType(), false,
946 llvm::GlobalValue::InternalLinkage,
947 Init,
948 std::string(Prefix) + ID->getName(),
949 &CGM.getModule());
950 if (ForClass) {
951 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
952 // FIXME: Why is this only here?
953 GV->setAlignment(32);
954 } else {
955 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
956 }
957 UsedGlobals.push_back(GV);
958 return llvm::ConstantExpr::getBitCast(GV,
959 ObjCTypes.IvarListPtrTy);
960}
961
962/*
963 struct objc_method {
964 SEL method_name;
965 char *method_types;
966 void *method;
967 };
968
969 struct objc_method_list {
970 struct objc_method_list *obsolete;
971 int count;
972 struct objc_method methods_list[count];
973 };
974*/
975llvm::Constant *CGObjCMac::EmitMethodList(const ObjCImplementationDecl *ID,
976 bool ForClass) {
977 std::vector<llvm::Constant*> Methods, Method(3);
978
979 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
980 i = ForClass ? ID->classmeth_begin() : ID->instmeth_begin(),
981 e = ForClass ? ID->classmeth_end() : ID->instmeth_end();
982 for (; i != e; ++i) {
983 ObjCMethodDecl *MD = *i;
984
985 Method[0] =
986 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
987 ObjCTypes.SelectorPtrTy);
988 Method[1] = GetMethodVarType(MD);
989
990 // FIXME: This is gross, we shouldn't be looking up by name.
991 std::string Name;
992 GetNameForMethod(MD, Name);
993 Method[2] =
994 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
995 ObjCTypes.Int8PtrTy);
996 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
997 Method));
998 }
999
1000 // Return null for empty list.
1001 if (Methods.empty())
1002 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
1003
1004 std::vector<llvm::Constant*> Values(3);
1005 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
1006 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1007 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1008 Methods.size());
1009 Values[2] = llvm::ConstantArray::get(AT, Methods);
1010 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1011
1012 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_METHODS_" :
1013 "\01L_OBJC_INSTANCE_METHODS_");
1014 llvm::GlobalVariable *GV =
1015 new llvm::GlobalVariable(Init->getType(), false,
1016 llvm::GlobalValue::InternalLinkage,
1017 Init,
1018 std::string(Prefix) + ID->getName(),
1019 &CGM.getModule());
1020 if (ForClass) {
1021 GV->setSection("__OBJC,__cls_meth,regular,no_dead_strip");
1022 } else {
1023 GV->setSection("__OBJC,__inst_meth,regular,no_dead_strip");
1024 }
1025 UsedGlobals.push_back(GV);
1026 return llvm::ConstantExpr::getBitCast(GV,
1027 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001028}
1029
1030llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1031 const llvm::Type *ReturnTy =
1032 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1033 const llvm::Type *SelfTy =
1034 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1035
1036 std::vector<const llvm::Type*> ArgTys;
1037 ArgTys.reserve(1 + 2 + OMD->param_size());
1038
1039 // FIXME: This is not something we should have to be dealing with
1040 // here.
1041 bool useStructRet =
1042 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1043 if (useStructRet) {
1044 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1045 ReturnTy = llvm::Type::VoidTy;
1046 }
1047
1048 // Implicit arguments
1049 ArgTys.push_back(SelfTy);
1050 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1051
1052 for (ObjCMethodDecl::param_const_iterator
1053 i = OMD->param_begin(), e = OMD->param_end();
1054 i != e; ++i) {
1055 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1056 if (Ty->isFirstClassType()) {
1057 ArgTys.push_back(Ty);
1058 } else {
1059 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1060 }
1061 }
1062
1063 std::string Name;
1064 GetNameForMethod(OMD, Name);
1065
1066 llvm::Function *Method =
1067 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1068 ArgTys,
1069 OMD->isVariadic()),
1070 llvm::GlobalValue::InternalLinkage,
1071 Name,
1072 &CGM.getModule());
1073
1074 if (useStructRet)
1075 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
1076
1077 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001078}
1079
1080llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001081 // Abuse this interface function as a place to finalize.
1082 FinishModule();
1083
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001084 return NULL;
1085}
1086
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001087/* *** Private Interface *** */
1088
1089/// EmitImageInfo - Emit the image info marker used to encode some module
1090/// level information.
1091///
1092/// See: <rdr://4810609&4810587&4810587>
1093/// struct IMAGE_INFO {
1094/// unsigned version;
1095/// unsigned flags;
1096/// };
1097enum ImageInfoFlags {
1098 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1099 eImageInfo_GarbageCollected = (1 << 1),
1100 eImageInfo_GCOnly = (1 << 2)
1101};
1102
1103void CGObjCMac::EmitImageInfo() {
1104 unsigned version = 0; // Version is unused?
1105 unsigned flags = 0;
1106
1107 // FIXME: Fix and continue?
1108 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1109 flags |= eImageInfo_GarbageCollected;
1110 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1111 flags |= eImageInfo_GCOnly;
1112
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001113 // Emitted as int[2];
1114 llvm::Constant *values[2] = {
1115 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1116 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1117 };
1118 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001119 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001120 new llvm::GlobalVariable(AT, true,
1121 llvm::GlobalValue::InternalLinkage,
1122 llvm::ConstantArray::get(AT, values, 2),
1123 "\01L_OBJC_IMAGE_INFO",
1124 &CGM.getModule());
1125
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001126 if (ObjCABI == 1) {
1127 GV->setSection("__OBJC, __image_info,regular");
1128 } else {
1129 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1130 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001131
1132 UsedGlobals.push_back(GV);
1133}
1134
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001135
1136// struct objc_module {
1137// unsigned long version;
1138// unsigned long size;
1139// const char *name;
1140// Symtab symtab;
1141// };
1142
1143// FIXME: Get from somewhere
1144static const int ModuleVersion = 7;
1145
1146void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001147 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1148
1149 std::vector<llvm::Constant*> Values(4);
1150 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1151 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001152 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001153 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001154 Values[3] = EmitModuleSymbols();
1155
1156 llvm::GlobalVariable *GV =
1157 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1158 llvm::GlobalValue::InternalLinkage,
1159 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1160 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001161 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001162 &CGM.getModule());
1163 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1164 UsedGlobals.push_back(GV);
1165}
1166
1167llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001168 std::vector<llvm::Constant*> Values(5);
1169 unsigned NumClasses = DefinedClasses.size();
1170 unsigned NumCategories = DefinedCategories.size();
1171
1172 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1173 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1174 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1175 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1176
1177 // FIXME: Is this correct? Document.
1178 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
1179 std::copy(DefinedClasses.begin(), DefinedClasses.end(),
1180 Symbols.begin());
1181 std::copy(DefinedCategories.begin(), DefinedCategories.end(),
1182 Symbols.begin() + NumClasses);
1183 Values[4] =
1184 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ClassPtrTy,
1185 NumClasses + NumCategories),
1186 Symbols);
1187
1188 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1189
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001190 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001191 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001192 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001193 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001194 "\01L_OBJC_SYMBOLS",
1195 &CGM.getModule());
1196 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1197 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001198 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1199}
1200
1201llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1202 const ObjCInterfaceDecl *ID) {
1203 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1204
1205 if (!Entry) {
1206 llvm::Constant *Casted =
1207 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1208 ObjCTypes.ClassPtrTy);
1209 Entry =
1210 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1211 llvm::GlobalValue::InternalLinkage,
1212 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1213 &CGM.getModule());
1214 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1215 UsedGlobals.push_back(Entry);
1216 }
1217
1218 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001219}
1220
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001221llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1222 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1223
1224 if (!Entry) {
1225 llvm::Constant *Casted =
1226 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1227 ObjCTypes.SelectorPtrTy);
1228 Entry =
1229 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1230 llvm::GlobalValue::InternalLinkage,
1231 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1232 &CGM.getModule());
1233 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1234 UsedGlobals.push_back(Entry);
1235 }
1236
1237 return Builder.CreateLoad(Entry, false, "tmp");
1238}
1239
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001240llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1241 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001242
1243 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001244 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001245 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001246 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001247 llvm::GlobalValue::InternalLinkage,
1248 C, "\01L_OBJC_CLASS_NAME_",
1249 &CGM.getModule());
1250 Entry->setSection("__TEXT,__cstring,cstring_literals");
1251 UsedGlobals.push_back(Entry);
1252 }
1253
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001254 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001255}
1256
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001257llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1258 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1259
1260 if (!Entry) {
1261 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1262 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001263 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001264 llvm::GlobalValue::InternalLinkage,
1265 C, "\01L_OBJC_METH_VAR_NAME_",
1266 &CGM.getModule());
1267 Entry->setSection("__TEXT,__cstring,cstring_literals");
1268 UsedGlobals.push_back(Entry);
1269 }
1270
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001271 return getConstantGEP(Entry, 0, 0);
1272}
1273
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001274// FIXME: Merge into a single cstring creation function.
1275llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1276 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1277}
1278
1279// FIXME: Merge into a single cstring creation function.
1280llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1281 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1282}
1283
1284llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1285 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001286
1287 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001288 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001289 Entry =
1290 new llvm::GlobalVariable(C->getType(), false,
1291 llvm::GlobalValue::InternalLinkage,
1292 C, "\01L_OBJC_METH_VAR_TYPE_",
1293 &CGM.getModule());
1294 Entry->setSection("__TEXT,__cstring,cstring_literals");
1295 UsedGlobals.push_back(Entry);
1296 }
1297
1298 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001299}
1300
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001301// FIXME: Merge into a single cstring creation function.
1302llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1303 std::string TypeStr;
1304 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1305 return GetMethodVarType(TypeStr);
1306}
1307
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001308void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1309 std::string &NameOut) {
1310 // FIXME: Find the mangling GCC uses.
1311 std::stringstream s;
1312 s << (D->isInstance() ? "-" : "+");
1313 s << "[";
1314 s << D->getClassInterface()->getName();
1315 s << " ";
1316 s << D->getSelector().getName();
1317 s << "]";
1318 NameOut = s.str();
1319}
1320
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001321void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001322 EmitModuleInfo();
1323
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001324 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001325
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001326 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001327 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001328 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001329 }
1330
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001331 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001332 llvm::GlobalValue *GV =
1333 new llvm::GlobalVariable(AT, false,
1334 llvm::GlobalValue::AppendingLinkage,
1335 llvm::ConstantArray::get(AT, Used),
1336 "llvm.used",
1337 &CGM.getModule());
1338
1339 GV->setSection("llvm.metadata");
1340}
1341
1342/* *** */
1343
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001344ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
1345 : CGM(cgm),
1346 CFStringType(0),
1347 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001348 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001349{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001350 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1351 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001352
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001353 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001354 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001355 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001356 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1357
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001358 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1359 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001360
1361 // FIXME: It would be nice to unify this with the opaque type, so
1362 // that the IR comes out a bit cleaner.
1363 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1364 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001365
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001366 MethodDescriptionTy =
1367 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001368 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001369 NULL);
1370 CGM.getModule().addTypeName("struct._objc_method_description",
1371 MethodDescriptionTy);
1372
1373 MethodDescriptionListTy =
1374 llvm::StructType::get(IntTy,
1375 llvm::ArrayType::get(MethodDescriptionTy, 0),
1376 NULL);
1377 CGM.getModule().addTypeName("struct._objc_method_description_list",
1378 MethodDescriptionListTy);
1379 MethodDescriptionListPtrTy =
1380 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1381
1382 PropertyListTy = llvm::OpaqueType::get();
1383 CGM.getModule().addTypeName("struct._objc_property_list",
1384 PropertyListTy);
1385 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1386
1387 // Protocol description structures
1388
1389 ProtocolExtensionTy =
1390 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1391 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1392 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1393 PropertyListPtrTy,
1394 NULL);
1395 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1396 ProtocolExtensionTy);
1397 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1398
1399 // Handle recursive construction of Protocl and ProtocolList types
1400
1401 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1402 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1403
1404 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1405 LongTy,
1406 llvm::ArrayType::get(ProtocolTyHolder, 0),
1407 NULL);
1408 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1409
1410 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001411 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001412 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1413 MethodDescriptionListPtrTy,
1414 MethodDescriptionListPtrTy,
1415 NULL);
1416 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1417
1418 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1419 CGM.getModule().addTypeName("struct._objc_protocol_list",
1420 ProtocolListTy);
1421 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1422
1423 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1424 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1425 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001426
1427 // Class description structures
1428
1429 IvarTy = llvm::StructType::get(Int8PtrTy,
1430 Int8PtrTy,
1431 IntTy,
1432 NULL);
1433 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1434
1435 IvarListTy = llvm::OpaqueType::get();
1436 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1437 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1438
1439 MethodTy = llvm::StructType::get(SelectorPtrTy,
1440 Int8PtrTy,
1441 Int8PtrTy,
1442 NULL);
1443 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1444
1445 MethodListTy = llvm::OpaqueType::get();
1446 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1447 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1448
1449 CacheTy = llvm::OpaqueType::get();
1450 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1451 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1452
1453 ClassExtensionTy =
1454 llvm::StructType::get(IntTy,
1455 Int8PtrTy,
1456 PropertyListPtrTy,
1457 NULL);
1458 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1459 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1460
1461 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1462
1463 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1464 llvm::PointerType::getUnqual(ClassTyHolder),
1465 Int8PtrTy,
1466 LongTy,
1467 LongTy,
1468 LongTy,
1469 IvarListPtrTy,
1470 MethodListPtrTy,
1471 CachePtrTy,
1472 ProtocolListPtrTy,
1473 Int8PtrTy,
1474 ClassExtensionPtrTy,
1475 NULL);
1476 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1477
1478 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1479 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1480 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1481
1482 // Global metadata structures
1483
1484 SymtabTy = llvm::StructType::get(LongTy,
1485 SelectorPtrTy,
1486 ShortTy,
1487 ShortTy,
1488 llvm::ArrayType::get(ClassPtrTy, 0),
1489 NULL);
1490 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1491 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1492
1493 ModuleTy =
1494 llvm::StructType::get(LongTy,
1495 LongTy,
1496 Int8PtrTy,
1497 SymtabPtrTy,
1498 NULL);
1499 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001500}
1501
1502ObjCTypesHelper::~ObjCTypesHelper() {
1503}
1504
1505const llvm::StructType *ObjCTypesHelper::getCFStringType() {
1506 if (!CFStringType) {
1507 CFStringType =
1508 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
1509 llvm::Type::Int32Ty,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001510 Int8PtrTy,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001511 LongTy,
1512 NULL);
1513
1514 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
1515 }
1516
1517 return CFStringType;
1518}
1519
1520llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
1521 if (!CFConstantStringClassReference) {
1522 llvm::GlobalValue *GV =
1523 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
1524 false,
1525 llvm::GlobalValue::ExternalLinkage,
1526 0, "__CFConstantStringClassReference",
1527 &CGM.getModule());
1528
1529 // Decay to pointer.
1530 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1531 }
1532
1533 return CFConstantStringClassReference;
1534}
1535
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001536llvm::Function *ObjCTypesHelper::getMessageSendFn() {
1537 if (!MessageSendFn) {
1538 std::vector<const llvm::Type*> Params;
1539 Params.push_back(ObjectPtrTy);
1540 Params.push_back(SelectorPtrTy);
1541 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1542 Params,
1543 true),
1544 llvm::Function::ExternalLinkage,
1545 "objc_msgSend",
1546 &CGM.getModule());
1547 }
1548
1549 return MessageSendFn;
1550}
1551
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001552/* *** */
1553
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001554CodeGen::CGObjCRuntime *
1555CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001556 return new CGObjCMac(CGM);
1557}