blob: 44f1baeb05116dab9cc200600153075d4a67298d [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.
237 llvm::Constant *EmitProtocolList(const ObjCProtocolDecl *PD);
238
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000239 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
240 /// for the given selector.
241 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
242
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000243 /// GetProtocolRef - Return a reference to the internal protocol
244 /// description, creating an empty one if it has not been
245 /// defined. The return value has type pointer-to ProtocolTy.
246 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
247
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000248 /// GetClassName - Return a unique constant for the given selector's
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000249 /// name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000250 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000251
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000252 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000253 /// selector's name. This returns a constant i8* to the start of
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000254 /// the name. The return value has type char *.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000255 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000256 llvm::Constant *GetMethodVarName(IdentifierInfo *);
257 llvm::Constant *GetMethodVarName(const std::string &Name);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000258
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000259 /// GetMethodVarType - Return a unique constant for the given
260 /// selector's name. This returns a constant i8* to the start of
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000261 /// the name. The return value has type char *.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000262 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000263 llvm::Constant *GetMethodVarType(const std::string &Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000264
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000265 /// GetNameForMethod - Return a name for the given method.
266 /// \param[out] NameOut - The return value.
267 void GetNameForMethod(const ObjCMethodDecl *OMD,
268 std::string &NameOut);
269
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000270public:
271 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000272 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000273
274 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
275 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000276 llvm::Value *Receiver,
277 Selector Sel,
278 llvm::Value** ArgV,
279 unsigned ArgC);
280
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000281 virtual llvm::Value *
282 GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
283 const llvm::Type *ReturnTy,
284 const ObjCInterfaceDecl *SuperClass,
285 llvm::Value *Receiver,
286 Selector Sel,
287 llvm::Value** ArgV,
288 unsigned ArgC);
289
290 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000291 const ObjCInterfaceDecl *ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000292
293 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
294
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000295 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000296
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000297 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000298
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000299 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000300
301 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000302 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000303
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000304 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000305
306 virtual llvm::Function *ModuleInitFunction();
307};
308} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000309
310/* *** Helper Functions *** */
311
312/// getConstantGEP() - Help routine to construct simple GEPs.
313static llvm::Constant *getConstantGEP(llvm::Constant *C,
314 unsigned idx0,
315 unsigned idx1) {
316 llvm::Value *Idxs[] = {
317 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
318 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
319 };
320 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
321}
322
323/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000324
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000325CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
326 : CGM(cgm),
327 ObjCTypes(cgm),
328 ObjCABI(1)
329{
330 // FIXME: How does this get set in GCC? And what does it even mean?
331 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
332 ObjCABI = 2;
333
334 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000335}
336
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000337/// GetClass - Return a reference to the class for the given interface
338/// decl.
339llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000340 const ObjCInterfaceDecl *ID) {
341 return EmitClassRef(Builder, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000342}
343
344/// GetSelector - Return the pointer to the unique'd string for this selector.
345llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000346 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000347}
348
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000349/// Generate a constant CFString object.
350/*
351 struct __builtin_CFString {
352 const int *isa; // point to __CFConstantStringClassReference
353 int flags;
354 const char *str;
355 long length;
356 };
357*/
358
359llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
360 // FIXME: I have no idea what this constant is (it is a magic
361 // constant in GCC as well). Most likely the encoding of the string
362 // and at least one part of it relates to UTF-16. Is this just the
363 // code for UTF-8? Where is this handled for us?
364 // See: <rdr://2996215>
365 unsigned flags = 0x07c8;
366
367 // FIXME: Use some machinery to unique this. We can't reuse the CGM
368 // one since we put them in a different section.
369 llvm::Constant *StringC = llvm::ConstantArray::get(String);
370 llvm::Constant *StringGV =
371 new llvm::GlobalVariable(StringC->getType(), true,
372 llvm::GlobalValue::InternalLinkage,
373 StringC, ".str", &CGM.getModule());
374 llvm::Constant *Values[4] = {
375 ObjCTypes.getCFConstantStringClassReference(),
376 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
377 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
378 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
379 };
380
381 llvm::Constant *CFStringC =
382 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
383 std::vector<llvm::Constant*>(Values, Values+4));
384
385 llvm::GlobalVariable *CFStringGV =
386 new llvm::GlobalVariable(CFStringC->getType(), true,
387 llvm::GlobalValue::InternalLinkage,
388 CFStringC, "",
389 &CGM.getModule());
390
391 CFStringGV->setSection("__DATA, __cfstring");
392
393 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000394}
395
396/// Generates a message send where the super is the receiver. This is
397/// a message send to self with special delivery semantics indicating
398/// which class's method should be called.
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000399llvm::Value *
400CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
401 const llvm::Type *ReturnTy,
402 const ObjCInterfaceDecl *SuperClass,
403 llvm::Value *Receiver,
404 Selector Sel,
405 llvm::Value** ArgV,
406 unsigned ArgC) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000407 assert(0 && "Cannot generate message send to super for Mac runtime.");
408 return 0;
409}
410
411/// Generate code for a message send expression.
412llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
413 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000414 llvm::Value *Receiver,
415 Selector Sel,
416 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000417 unsigned ArgC) {
418 llvm::Function *F = ObjCTypes.getMessageSendFn();
419 llvm::Value **Args = new llvm::Value*[ArgC+2];
420 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
421 Args[1] = EmitSelector(Builder, Sel);
422 std::copy(ArgV, ArgV+ArgC, Args+2);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000423
424 std::vector<const llvm::Type*> Params;
425 Params.push_back(ObjCTypes.ObjectPtrTy);
426 Params.push_back(ObjCTypes.SelectorPtrTy);
427 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
428 Params,
429 true);
430 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
431 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
432 llvm::CallInst *CI = Builder.CreateCall(C,
433 Args, Args+ArgC+2, "tmp");
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000434 delete[] Args;
435 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000436}
437
438llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000439 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000440 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
441 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000442}
443
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000444/*
445 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
446 struct _objc_protocol {
447 struct _objc_protocol_extension *isa;
448 char *protocol_name;
449 struct _objc_protocol_list *protocol_list;
450 struct _objc__method_prototype_list *instance_methods;
451 struct _objc__method_prototype_list *class_methods
452 };
453
454 See EmitProtocolExtension().
455*/
456void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
457 const char *ProtocolName = PD->getName();
458
459 std::vector<llvm::Constant*> Values(5);
460 Values[0] = EmitProtocolExtension(PD);
461 Values[1] = GetClassName(PD->getIdentifier());
462 Values[2] = EmitProtocolList(PD);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000463 Values[3] = EmitMethodDescList(ProtocolName,
464 true, // IsProtocol
465 false, // ClassMethods
466 true, // Required
467 PD->instmeth_begin(),
468 PD->instmeth_end());
469 Values[4] = EmitMethodDescList(ProtocolName,
470 true, // IsProtocol
471 true, // ClassMethods
472 true, // Required
473 PD->classmeth_begin(),
474 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000475 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
476 Values);
477
478 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
479 if (Entry) {
480 // Already created, just update the initializer
481 Entry->setInitializer(Init);
482 } else {
483 Entry =
484 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
485 llvm::GlobalValue::InternalLinkage,
486 Init,
487 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
488 &CGM.getModule());
489 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
490 UsedGlobals.push_back(Entry);
491 // FIXME: Is this necessary? Why only for protocol?
492 Entry->setAlignment(4);
493 }
494}
495
496llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
497 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
498
499 if (!Entry) {
500 std::vector<llvm::Constant*> Values(5);
501 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
502 Values[1] = GetClassName(PD->getIdentifier());
503 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
504 Values[3] = Values[4] =
505 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
506 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
507 Values);
508
509 Entry =
510 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
511 llvm::GlobalValue::InternalLinkage,
512 Init,
513 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
514 &CGM.getModule());
515 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
516 UsedGlobals.push_back(Entry);
517 // FIXME: Is this necessary? Why only for protocol?
518 Entry->setAlignment(4);
519 }
520
521 return Entry;
522}
523
524/*
525 struct _objc_protocol_extension {
526 uint32_t size;
527 struct objc_method_description_list *optional_instance_methods;
528 struct objc_method_description_list *optional_class_methods;
529 struct objc_property_list *instance_properties;
530 };
531*/
532llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
533 uint64_t Size =
534 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
535 std::vector<llvm::Constant*> Values(4);
536 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000537 Values[1] = EmitMethodDescList(PD->getName(),
538 true, // IsProtocol
539 false, // ClassMethods
540 false, // Required
541 PD->instmeth_begin(),
542 PD->instmeth_end());
543 Values[2] = EmitMethodDescList(PD->getName(),
544 true, // IsProtocol
545 true, // ClassMethods
546 false, // Required
547 PD->classmeth_begin(),
548 PD->classmeth_end());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000549 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
550 assert(!PD->getNumPropertyDecl() &&
551 "Cannot emit Obj-C protocol properties for NeXT runtime.");
552
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000553 // Return null if no extension bits are used.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000554 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
555 Values[3]->isNullValue())
556 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
557
558 llvm::Constant *Init =
559 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
560 llvm::GlobalVariable *GV =
561 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
562 llvm::GlobalValue::InternalLinkage,
563 Init,
564 (std::string("\01L_OBJC_PROTOCOLEXT_") +
565 PD->getName()),
566 &CGM.getModule());
567 // No special section, but goes in llvm.used
568 UsedGlobals.push_back(GV);
569
570 return GV;
571}
572
573/*
574 struct objc_protocol_list {
575 struct objc_protocol_list *next;
576 long count;
577 Protocol *list[];
578 };
579*/
580llvm::Constant *CGObjCMac::EmitProtocolList(const ObjCProtocolDecl *PD) {
581 std::vector<llvm::Constant*> ProtocolRefs;
582
583 for (ObjCProtocolDecl::protocol_iterator i = PD->protocol_begin(),
584 e = PD->protocol_end(); i != e; ++i)
585 ProtocolRefs.push_back(GetProtocolRef(*i));
586
587 // Just return null for empty protocol lists
588 if (ProtocolRefs.empty())
589 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
590
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000591 // This list is null terminated.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000592 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
593
594 std::vector<llvm::Constant*> Values(3);
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000595 // This field is only used by the runtime.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000596 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
597 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
598 Values[2] =
599 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
600 ProtocolRefs.size()),
601 ProtocolRefs);
602
603 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
604 llvm::GlobalVariable *GV =
605 new llvm::GlobalVariable(Init->getType(), false,
606 llvm::GlobalValue::InternalLinkage,
607 Init,
608 (std::string("\01L_OBJC_PROTOCOL_REFS_") +
609 PD->getName()),
610 &CGM.getModule());
611 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
612 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
613}
614
615/*
616 struct objc_method_description_list {
617 int count;
618 struct objc_method_description list[];
619 };
620*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000621llvm::Constant *CGObjCMac::EmitMethodDescList(const std::string &TypeName,
622 bool IsProtocol,
623 bool ClassMethods,
624 bool Required,
625 ObjCMethodDecl * const *begin,
626 ObjCMethodDecl * const *end) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000627 std::vector<llvm::Constant*> Methods, Desc(2);
628 for (; begin != end; ++begin) {
629 ObjCMethodDecl *D = *begin;
630 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
631
632 // Skip if this method is required and we are outputting optional
633 // methods, or vice versa.
634 if (Required != IsRequired)
635 continue;
636
637 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
638 ObjCTypes.SelectorPtrTy);
639 Desc[1] = GetMethodVarType(D);
640 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
641 Desc));
642 }
643
644 // Return null for empty list.
645 if (Methods.empty())
646 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
647
648 std::vector<llvm::Constant*> Values(2);
649 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
650 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
651 Methods.size());
652 Values[1] = llvm::ConstantArray::get(AT, Methods);
653 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
654
655 char Prefix[256];
656 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
657 IsProtocol ? "PROTOCOL_" : "",
658 ClassMethods ? "CLASS_" : "INSTANCE_",
659 !Required ? "OPT_" : "");
660 llvm::GlobalVariable *GV =
661 new llvm::GlobalVariable(Init->getType(), false,
662 llvm::GlobalValue::InternalLinkage,
663 Init,
664 std::string(Prefix) + TypeName,
665 &CGM.getModule());
666 if (ClassMethods) {
667 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
668 } else {
669 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
670 }
671 UsedGlobals.push_back(GV);
672 return llvm::ConstantExpr::getBitCast(GV,
673 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000674}
675
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000676void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000677 assert(0 && "Cannot generate category for Mac runtime.");
678}
679
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000680// FIXME: Get from somewhere?
681enum ClassFlags {
682 eClassFlags_Factory = 0x00001,
683 eClassFlags_Meta = 0x00002,
684 // <rdr://5142207>
685 eClassFlags_HasCXXStructors = 0x02000,
686 eClassFlags_Hidden = 0x20000,
687 eClassFlags_ABI2_Hidden = 0x00010,
688 eClassFlags_ABI2_HasCXXStructors = 0x00004 // <rdr://4923634>
689};
690
691// <rdr://5142207&4705298&4843145>
692static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
693 if (const VisibilityAttr *attr = ID->getAttr<VisibilityAttr>()) {
694 // FIXME: Support -fvisibility
695 switch (attr->getVisibility()) {
696 default:
697 assert(0 && "Unknown visibility");
698 return false;
699 case VisibilityAttr::DefaultVisibility:
700 case VisibilityAttr::ProtectedVisibility: // FIXME: What do we do here?
701 return false;
702 case VisibilityAttr::HiddenVisibility:
703 return true;
704 }
705 } else {
706 return false; // FIXME: Support -fvisibility
707 }
708}
709
710/*
711 struct _objc_class {
712 Class isa;
713 Class super_class;
714 const char *name;
715 long version;
716 long info;
717 long instance_size;
718 struct _objc_ivar_list *ivars;
719 struct _objc_method_list *methods;
720 struct _objc_cache *cache;
721 struct _objc_protocol_list *protocols;
722 // Objective-C 1.0 extensions (<rdr://4585769>)
723 const char *ivar_layout;
724 struct _objc_class_ext *ext;
725 };
726
727 See EmitClassExtension();
728 */
729void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
730 const char *ClassName = ID->getName();
731 // FIXME: Support protocols.
732 llvm::Constant *Protocols =
733 llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
734 // FIXME: Gross
735 ObjCInterfaceDecl *Interface =
736 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
737 const llvm::Type *InterfaceTy =
738 CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(Interface));
739 unsigned Flags = eClassFlags_Factory;
740 unsigned Size = CGM.getTargetData().getABITypeSize(InterfaceTy);
741
742 // FIXME: Set CXX-structors flag.
743 if (IsClassHidden(ID->getClassInterface()))
744 Flags |= eClassFlags_Hidden;
745
746 std::vector<llvm::Constant*> Values(12);
747 Values[ 0] = EmitMetaClass(ID, Protocols, InterfaceTy);
748 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
749 Values[ 1] =
750 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
751 ObjCTypes.ClassPtrTy);
752 } else {
753 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
754 }
755 Values[ 2] = GetClassName(ID->getIdentifier());
756 // Version is always 0.
757 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
758 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
759 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
760 Values[ 6] = EmitIvarList(ID, false, InterfaceTy);
761 Values[ 7] = EmitMethodList(ID, false);
762 // cache is always NULL.
763 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
764 Values[ 9] = Protocols;
765 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); // XXX
766 Values[11] = EmitClassExtension(ID);
767 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
768 Values);
769
770 llvm::GlobalVariable *GV =
771 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
772 llvm::GlobalValue::InternalLinkage,
773 Init,
774 std::string("\01L_OBJC_CLASS_")+ClassName,
775 &CGM.getModule());
776 GV->setSection("__OBJC,__class,regular,no_dead_strip");
777 UsedGlobals.push_back(GV);
778 // FIXME: Why?
779 GV->setAlignment(32);
780 DefinedClasses.push_back(GV);
781}
782
783llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
784 llvm::Constant *Protocols,
785 const llvm::Type *InterfaceTy) {
786 const char *ClassName = ID->getName();
787 unsigned Flags = eClassFlags_Meta;
788 unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);
789
790 if (IsClassHidden(ID->getClassInterface()))
791 Flags |= eClassFlags_Hidden;
792
793 std::vector<llvm::Constant*> Values(12);
794 // The isa for the metaclass is the root of the hierarchy.
795 const ObjCInterfaceDecl *Root = ID->getClassInterface();
796 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
797 Root = Super;
798 Values[ 0] =
799 llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
800 ObjCTypes.ClassPtrTy);
801 // FIXME: Document fix-up here.
802 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
803 Values[ 1] =
804 llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
805 ObjCTypes.ClassPtrTy);
806 } else {
807 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
808 }
809 Values[ 2] = GetClassName(ID->getIdentifier());
810 // Version is always 0.
811 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
812 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
813 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
814 Values[ 6] = EmitIvarList(ID, true, InterfaceTy);
815 Values[ 7] = EmitMethodList(ID, true);
816 // cache is always NULL.
817 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
818 Values[ 9] = Protocols;
819 // ivar_layout for metaclass is always NULL.
820 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
821 // The class extension is always unused for metaclasses.
822 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
823 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
824 Values);
825
826 llvm::GlobalVariable *GV =
827 new llvm::GlobalVariable(ObjCTypes.ClassTy, false,
828 llvm::GlobalValue::InternalLinkage,
829 Init,
830 std::string("\01L_OBJC_METACLASS_")+ClassName,
831 &CGM.getModule());
832 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
833 UsedGlobals.push_back(GV);
834 // FIXME: Why?
835 GV->setAlignment(32);
836
837 return GV;
838}
839
840/*
841 struct objc_class_ext {
842 uint32_t size;
843 const char *weak_ivar_layout;
844 struct _objc_property_list *properties;
845 };
846*/
847llvm::Constant *
848CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
849 uint64_t Size =
850 CGM.getTargetData().getABITypeSize(ObjCTypes.ClassExtensionTy);
851
852 std::vector<llvm::Constant*> Values(3);
853 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
854 // FIXME: Output weak_ivar string.
855 Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
856 // FIXME: Output properties.
857 Values[2] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
858 assert(!ID->getClassInterface()->getNumPropertyDecl() &&
859 "Cannot emit Obj-C class properties for NeXt runtime.");
860
861 // Return null if no extension bits are used.
862 if (Values[1]->isNullValue() && Values[2]->isNullValue())
863 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
864
865 llvm::Constant *Init =
866 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
867 llvm::GlobalVariable *GV =
868 new llvm::GlobalVariable(ObjCTypes.ClassExtensionTy, false,
869 llvm::GlobalValue::InternalLinkage,
870 Init,
871 (std::string("\01L_OBJC_CLASSEXT_") +
872 ID->getName()),
873 &CGM.getModule());
874 // No special section, but goes in llvm.used
875 UsedGlobals.push_back(GV);
876
877 return GV;
878}
879
880/*
881 struct objc_ivar {
882 char *ivar_name;
883 char *ivar_type;
884 int ivar_offset;
885 };
886
887 struct objc_ivar_list {
888 int ivar_count;
889 struct objc_ivar list[count];
890 };
891 */
892llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
893 bool ForClass,
894 const llvm::Type *InterfaceTy) {
895 std::vector<llvm::Constant*> Ivars, Ivar(3);
896
897 // When emitting the root class GCC emits ivar entries for the
898 // actual class structure. It is not clear if we need to follow this
899 // behavior; for now lets try and get away with not doing it. If so,
900 // the cleanest solution would be to make up an ObjCInterfaceDecl
901 // for the class.
902 if (ForClass)
903 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
904
905 const llvm::StructLayout *Layout =
906 CGM.getTargetData().getStructLayout(cast<llvm::StructType>(InterfaceTy));
907 for (ObjCInterfaceDecl::ivar_iterator
908 i = ID->getClassInterface()->ivar_begin(),
909 e = ID->getClassInterface()->ivar_end(); i != e; ++i) {
910 ObjCIvarDecl *V = *i;
911 unsigned Offset =
912 Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(V));
913 std::string TypeStr;
914 llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
915 Ivar[0] = GetMethodVarName(V->getIdentifier());
916 CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
917 EncodingRecordTypes);
918 Ivar[1] = GetMethodVarType(TypeStr);
919 Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
920 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,
921 Ivar));
922 }
923
924 // Return null for empty list.
925 if (Ivars.empty())
926 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
927
928 std::vector<llvm::Constant*> Values(2);
929 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
930 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
931 Ivars.size());
932 Values[1] = llvm::ConstantArray::get(AT, Ivars);
933 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
934
935 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_VARIABLES_" :
936 "\01L_OBJC_INSTANCE_VARIABLES_");
937 llvm::GlobalVariable *GV =
938 new llvm::GlobalVariable(Init->getType(), false,
939 llvm::GlobalValue::InternalLinkage,
940 Init,
941 std::string(Prefix) + ID->getName(),
942 &CGM.getModule());
943 if (ForClass) {
944 GV->setSection("__OBJC,__cls_vars,regular,no_dead_strip");
945 // FIXME: Why is this only here?
946 GV->setAlignment(32);
947 } else {
948 GV->setSection("__OBJC,__instance_vars,regular,no_dead_strip");
949 }
950 UsedGlobals.push_back(GV);
951 return llvm::ConstantExpr::getBitCast(GV,
952 ObjCTypes.IvarListPtrTy);
953}
954
955/*
956 struct objc_method {
957 SEL method_name;
958 char *method_types;
959 void *method;
960 };
961
962 struct objc_method_list {
963 struct objc_method_list *obsolete;
964 int count;
965 struct objc_method methods_list[count];
966 };
967*/
968llvm::Constant *CGObjCMac::EmitMethodList(const ObjCImplementationDecl *ID,
969 bool ForClass) {
970 std::vector<llvm::Constant*> Methods, Method(3);
971
972 llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
973 i = ForClass ? ID->classmeth_begin() : ID->instmeth_begin(),
974 e = ForClass ? ID->classmeth_end() : ID->instmeth_end();
975 for (; i != e; ++i) {
976 ObjCMethodDecl *MD = *i;
977
978 Method[0] =
979 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
980 ObjCTypes.SelectorPtrTy);
981 Method[1] = GetMethodVarType(MD);
982
983 // FIXME: This is gross, we shouldn't be looking up by name.
984 std::string Name;
985 GetNameForMethod(MD, Name);
986 Method[2] =
987 llvm::ConstantExpr::getBitCast(CGM.getModule().getFunction(Name),
988 ObjCTypes.Int8PtrTy);
989 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodTy,
990 Method));
991 }
992
993 // Return null for empty list.
994 if (Methods.empty())
995 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
996
997 std::vector<llvm::Constant*> Values(3);
998 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
999 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
1000 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
1001 Methods.size());
1002 Values[2] = llvm::ConstantArray::get(AT, Methods);
1003 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1004
1005 const char *Prefix = (ForClass ? "\01L_OBJC_CLASS_METHODS_" :
1006 "\01L_OBJC_INSTANCE_METHODS_");
1007 llvm::GlobalVariable *GV =
1008 new llvm::GlobalVariable(Init->getType(), false,
1009 llvm::GlobalValue::InternalLinkage,
1010 Init,
1011 std::string(Prefix) + ID->getName(),
1012 &CGM.getModule());
1013 if (ForClass) {
1014 GV->setSection("__OBJC,__cls_meth,regular,no_dead_strip");
1015 } else {
1016 GV->setSection("__OBJC,__inst_meth,regular,no_dead_strip");
1017 }
1018 UsedGlobals.push_back(GV);
1019 return llvm::ConstantExpr::getBitCast(GV,
1020 ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001021}
1022
1023llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
1024 const llvm::Type *ReturnTy =
1025 CGM.getTypes().ConvertReturnType(OMD->getResultType());
1026 const llvm::Type *SelfTy =
1027 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
1028
1029 std::vector<const llvm::Type*> ArgTys;
1030 ArgTys.reserve(1 + 2 + OMD->param_size());
1031
1032 // FIXME: This is not something we should have to be dealing with
1033 // here.
1034 bool useStructRet =
1035 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
1036 if (useStructRet) {
1037 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
1038 ReturnTy = llvm::Type::VoidTy;
1039 }
1040
1041 // Implicit arguments
1042 ArgTys.push_back(SelfTy);
1043 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
1044
1045 for (ObjCMethodDecl::param_const_iterator
1046 i = OMD->param_begin(), e = OMD->param_end();
1047 i != e; ++i) {
1048 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
1049 if (Ty->isFirstClassType()) {
1050 ArgTys.push_back(Ty);
1051 } else {
1052 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
1053 }
1054 }
1055
1056 std::string Name;
1057 GetNameForMethod(OMD, Name);
1058
1059 llvm::Function *Method =
1060 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
1061 ArgTys,
1062 OMD->isVariadic()),
1063 llvm::GlobalValue::InternalLinkage,
1064 Name,
1065 &CGM.getModule());
1066
1067 if (useStructRet)
1068 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
1069
1070 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001071}
1072
1073llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001074 // Abuse this interface function as a place to finalize.
1075 FinishModule();
1076
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001077 return NULL;
1078}
1079
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001080/* *** Private Interface *** */
1081
1082/// EmitImageInfo - Emit the image info marker used to encode some module
1083/// level information.
1084///
1085/// See: <rdr://4810609&4810587&4810587>
1086/// struct IMAGE_INFO {
1087/// unsigned version;
1088/// unsigned flags;
1089/// };
1090enum ImageInfoFlags {
1091 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
1092 eImageInfo_GarbageCollected = (1 << 1),
1093 eImageInfo_GCOnly = (1 << 2)
1094};
1095
1096void CGObjCMac::EmitImageInfo() {
1097 unsigned version = 0; // Version is unused?
1098 unsigned flags = 0;
1099
1100 // FIXME: Fix and continue?
1101 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
1102 flags |= eImageInfo_GarbageCollected;
1103 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
1104 flags |= eImageInfo_GCOnly;
1105
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001106 // Emitted as int[2];
1107 llvm::Constant *values[2] = {
1108 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
1109 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
1110 };
1111 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001112 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001113 new llvm::GlobalVariable(AT, true,
1114 llvm::GlobalValue::InternalLinkage,
1115 llvm::ConstantArray::get(AT, values, 2),
1116 "\01L_OBJC_IMAGE_INFO",
1117 &CGM.getModule());
1118
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001119 if (ObjCABI == 1) {
1120 GV->setSection("__OBJC, __image_info,regular");
1121 } else {
1122 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
1123 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001124
1125 UsedGlobals.push_back(GV);
1126}
1127
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001128
1129// struct objc_module {
1130// unsigned long version;
1131// unsigned long size;
1132// const char *name;
1133// Symtab symtab;
1134// };
1135
1136// FIXME: Get from somewhere
1137static const int ModuleVersion = 7;
1138
1139void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001140 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
1141
1142 std::vector<llvm::Constant*> Values(4);
1143 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
1144 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001145 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001146 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001147 Values[3] = EmitModuleSymbols();
1148
1149 llvm::GlobalVariable *GV =
1150 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
1151 llvm::GlobalValue::InternalLinkage,
1152 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
1153 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001154 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001155 &CGM.getModule());
1156 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
1157 UsedGlobals.push_back(GV);
1158}
1159
1160llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001161 std::vector<llvm::Constant*> Values(5);
1162 unsigned NumClasses = DefinedClasses.size();
1163 unsigned NumCategories = DefinedCategories.size();
1164
1165 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
1166 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
1167 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
1168 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
1169
1170 // FIXME: Is this correct? Document.
1171 std::vector<llvm::Constant*> Symbols(NumClasses + NumCategories);
1172 std::copy(DefinedClasses.begin(), DefinedClasses.end(),
1173 Symbols.begin());
1174 std::copy(DefinedCategories.begin(), DefinedCategories.end(),
1175 Symbols.begin() + NumClasses);
1176 Values[4] =
1177 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ClassPtrTy,
1178 NumClasses + NumCategories),
1179 Symbols);
1180
1181 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
1182
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001183 llvm::GlobalVariable *GV =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001184 new llvm::GlobalVariable(Init->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001185 llvm::GlobalValue::InternalLinkage,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001186 Init,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001187 "\01L_OBJC_SYMBOLS",
1188 &CGM.getModule());
1189 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
1190 UsedGlobals.push_back(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001191 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
1192}
1193
1194llvm::Value *CGObjCMac::EmitClassRef(llvm::IRBuilder<> &Builder,
1195 const ObjCInterfaceDecl *ID) {
1196 llvm::GlobalVariable *&Entry = ClassReferences[ID->getIdentifier()];
1197
1198 if (!Entry) {
1199 llvm::Constant *Casted =
1200 llvm::ConstantExpr::getBitCast(GetClassName(ID->getIdentifier()),
1201 ObjCTypes.ClassPtrTy);
1202 Entry =
1203 new llvm::GlobalVariable(ObjCTypes.ClassPtrTy, false,
1204 llvm::GlobalValue::InternalLinkage,
1205 Casted, "\01L_OBJC_CLASS_REFERENCES_",
1206 &CGM.getModule());
1207 Entry->setSection("__OBJC,__cls_refs,literal_pointers,no_dead_strip");
1208 UsedGlobals.push_back(Entry);
1209 }
1210
1211 return Builder.CreateLoad(Entry, false, "tmp");
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001212}
1213
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001214llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
1215 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
1216
1217 if (!Entry) {
1218 llvm::Constant *Casted =
1219 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
1220 ObjCTypes.SelectorPtrTy);
1221 Entry =
1222 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
1223 llvm::GlobalValue::InternalLinkage,
1224 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
1225 &CGM.getModule());
1226 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
1227 UsedGlobals.push_back(Entry);
1228 }
1229
1230 return Builder.CreateLoad(Entry, false, "tmp");
1231}
1232
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001233llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
1234 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001235
1236 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001237 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001238 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001239 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001240 llvm::GlobalValue::InternalLinkage,
1241 C, "\01L_OBJC_CLASS_NAME_",
1242 &CGM.getModule());
1243 Entry->setSection("__TEXT,__cstring,cstring_literals");
1244 UsedGlobals.push_back(Entry);
1245 }
1246
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001247 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001248}
1249
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001250llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
1251 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
1252
1253 if (!Entry) {
1254 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
1255 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001256 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001257 llvm::GlobalValue::InternalLinkage,
1258 C, "\01L_OBJC_METH_VAR_NAME_",
1259 &CGM.getModule());
1260 Entry->setSection("__TEXT,__cstring,cstring_literals");
1261 UsedGlobals.push_back(Entry);
1262 }
1263
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001264 return getConstantGEP(Entry, 0, 0);
1265}
1266
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001267// FIXME: Merge into a single cstring creation function.
1268llvm::Constant *CGObjCMac::GetMethodVarName(IdentifierInfo *ID) {
1269 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
1270}
1271
1272// FIXME: Merge into a single cstring creation function.
1273llvm::Constant *CGObjCMac::GetMethodVarName(const std::string &Name) {
1274 return GetMethodVarName(&CGM.getContext().Idents.get(Name));
1275}
1276
1277llvm::Constant *CGObjCMac::GetMethodVarType(const std::string &Name) {
1278 llvm::GlobalVariable *&Entry = MethodVarTypes[Name];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001279
1280 if (!Entry) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001281 llvm::Constant *C = llvm::ConstantArray::get(Name);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001282 Entry =
1283 new llvm::GlobalVariable(C->getType(), false,
1284 llvm::GlobalValue::InternalLinkage,
1285 C, "\01L_OBJC_METH_VAR_TYPE_",
1286 &CGM.getModule());
1287 Entry->setSection("__TEXT,__cstring,cstring_literals");
1288 UsedGlobals.push_back(Entry);
1289 }
1290
1291 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001292}
1293
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001294// FIXME: Merge into a single cstring creation function.
1295llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
1296 std::string TypeStr;
1297 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
1298 return GetMethodVarType(TypeStr);
1299}
1300
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00001301void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
1302 std::string &NameOut) {
1303 // FIXME: Find the mangling GCC uses.
1304 std::stringstream s;
1305 s << (D->isInstance() ? "-" : "+");
1306 s << "[";
1307 s << D->getClassInterface()->getName();
1308 s << " ";
1309 s << D->getSelector().getName();
1310 s << "]";
1311 NameOut = s.str();
1312}
1313
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001314void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001315 EmitModuleInfo();
1316
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001317 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001318
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001319 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001320 e = UsedGlobals.end(); i != e; ++i) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001321 Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001322 }
1323
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001324 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size());
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001325 llvm::GlobalValue *GV =
1326 new llvm::GlobalVariable(AT, false,
1327 llvm::GlobalValue::AppendingLinkage,
1328 llvm::ConstantArray::get(AT, Used),
1329 "llvm.used",
1330 &CGM.getModule());
1331
1332 GV->setSection("llvm.metadata");
1333}
1334
1335/* *** */
1336
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001337ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
1338 : CGM(cgm),
1339 CFStringType(0),
1340 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001341 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001342{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001343 CodeGen::CodeGenTypes &Types = CGM.getTypes();
1344 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001345
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001346 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001347 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001348 LongTy = Types.ConvertType(Ctx.LongTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001349 Int8PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
1350
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001351 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
1352 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001353
1354 // FIXME: It would be nice to unify this with the opaque type, so
1355 // that the IR comes out a bit cleaner.
1356 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
1357 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001358
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001359 MethodDescriptionTy =
1360 llvm::StructType::get(SelectorPtrTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001361 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001362 NULL);
1363 CGM.getModule().addTypeName("struct._objc_method_description",
1364 MethodDescriptionTy);
1365
1366 MethodDescriptionListTy =
1367 llvm::StructType::get(IntTy,
1368 llvm::ArrayType::get(MethodDescriptionTy, 0),
1369 NULL);
1370 CGM.getModule().addTypeName("struct._objc_method_description_list",
1371 MethodDescriptionListTy);
1372 MethodDescriptionListPtrTy =
1373 llvm::PointerType::getUnqual(MethodDescriptionListTy);
1374
1375 PropertyListTy = llvm::OpaqueType::get();
1376 CGM.getModule().addTypeName("struct._objc_property_list",
1377 PropertyListTy);
1378 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
1379
1380 // Protocol description structures
1381
1382 ProtocolExtensionTy =
1383 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
1384 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1385 llvm::PointerType::getUnqual(MethodDescriptionListTy),
1386 PropertyListPtrTy,
1387 NULL);
1388 CGM.getModule().addTypeName("struct._objc_protocol_extension",
1389 ProtocolExtensionTy);
1390 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
1391
1392 // Handle recursive construction of Protocl and ProtocolList types
1393
1394 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
1395 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
1396
1397 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
1398 LongTy,
1399 llvm::ArrayType::get(ProtocolTyHolder, 0),
1400 NULL);
1401 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
1402
1403 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001404 Int8PtrTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001405 llvm::PointerType::getUnqual(ProtocolListTyHolder),
1406 MethodDescriptionListPtrTy,
1407 MethodDescriptionListPtrTy,
1408 NULL);
1409 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
1410
1411 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
1412 CGM.getModule().addTypeName("struct._objc_protocol_list",
1413 ProtocolListTy);
1414 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
1415
1416 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
1417 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
1418 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001419
1420 // Class description structures
1421
1422 IvarTy = llvm::StructType::get(Int8PtrTy,
1423 Int8PtrTy,
1424 IntTy,
1425 NULL);
1426 CGM.getModule().addTypeName("struct._objc_ivar", IvarTy);
1427
1428 IvarListTy = llvm::OpaqueType::get();
1429 CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy);
1430 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
1431
1432 MethodTy = llvm::StructType::get(SelectorPtrTy,
1433 Int8PtrTy,
1434 Int8PtrTy,
1435 NULL);
1436 CGM.getModule().addTypeName("struct._objc_method", MethodTy);
1437
1438 MethodListTy = llvm::OpaqueType::get();
1439 CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy);
1440 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
1441
1442 CacheTy = llvm::OpaqueType::get();
1443 CGM.getModule().addTypeName("struct._objc_cache", CacheTy);
1444 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
1445
1446 ClassExtensionTy =
1447 llvm::StructType::get(IntTy,
1448 Int8PtrTy,
1449 PropertyListPtrTy,
1450 NULL);
1451 CGM.getModule().addTypeName("struct._objc_class_extension", ClassExtensionTy);
1452 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
1453
1454 llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get();
1455
1456 T = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder),
1457 llvm::PointerType::getUnqual(ClassTyHolder),
1458 Int8PtrTy,
1459 LongTy,
1460 LongTy,
1461 LongTy,
1462 IvarListPtrTy,
1463 MethodListPtrTy,
1464 CachePtrTy,
1465 ProtocolListPtrTy,
1466 Int8PtrTy,
1467 ClassExtensionPtrTy,
1468 NULL);
1469 cast<llvm::OpaqueType>(ClassTyHolder.get())->refineAbstractTypeTo(T);
1470
1471 ClassTy = cast<llvm::StructType>(ClassTyHolder.get());
1472 CGM.getModule().addTypeName("struct._objc_class", ClassTy);
1473 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
1474
1475 // Global metadata structures
1476
1477 SymtabTy = llvm::StructType::get(LongTy,
1478 SelectorPtrTy,
1479 ShortTy,
1480 ShortTy,
1481 llvm::ArrayType::get(ClassPtrTy, 0),
1482 NULL);
1483 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
1484 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
1485
1486 ModuleTy =
1487 llvm::StructType::get(LongTy,
1488 LongTy,
1489 Int8PtrTy,
1490 SymtabPtrTy,
1491 NULL);
1492 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001493}
1494
1495ObjCTypesHelper::~ObjCTypesHelper() {
1496}
1497
1498const llvm::StructType *ObjCTypesHelper::getCFStringType() {
1499 if (!CFStringType) {
1500 CFStringType =
1501 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
1502 llvm::Type::Int32Ty,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001503 Int8PtrTy,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001504 LongTy,
1505 NULL);
1506
1507 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
1508 }
1509
1510 return CFStringType;
1511}
1512
1513llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
1514 if (!CFConstantStringClassReference) {
1515 llvm::GlobalValue *GV =
1516 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
1517 false,
1518 llvm::GlobalValue::ExternalLinkage,
1519 0, "__CFConstantStringClassReference",
1520 &CGM.getModule());
1521
1522 // Decay to pointer.
1523 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1524 }
1525
1526 return CFConstantStringClassReference;
1527}
1528
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001529llvm::Function *ObjCTypesHelper::getMessageSendFn() {
1530 if (!MessageSendFn) {
1531 std::vector<const llvm::Type*> Params;
1532 Params.push_back(ObjectPtrTy);
1533 Params.push_back(SelectorPtrTy);
1534 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1535 Params,
1536 true),
1537 llvm::Function::ExternalLinkage,
1538 "objc_msgSend",
1539 &CGM.getModule());
1540 }
1541
1542 return MessageSendFn;
1543}
1544
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001545/* *** */
1546
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001547CodeGen::CGObjCRuntime *
1548CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001549 return new CGObjCMac(CGM);
1550}