blob: 8cb1536b140bda006debea781106e6f32f5cb624 [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 Dunbar6efc0c52008-08-13 03:21:16 +000046 const llvm::Type *IntTy, *LongTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000047
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000048 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
49 const llvm::Type *ObjectPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000050 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Daniel Dunbar2bedbf82008-08-12 05:28:47 +000051 const llvm::Type *SelectorPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000052 /// ProtocolPtrTy - LLVM type for external protocol handles
53 /// (typeof(Protocol))
54 const llvm::Type *ExternalProtocolPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +000055
56 /// SymtabTy - LLVM type for struct objc_symtab.
57 const llvm::StructType *SymtabTy;
58 /// ModuleTy - LLVM type for struct objc_module.
59 const llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +000060
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000061 /// ProtocolTy - LLVM type for struct objc_protocol.
62 const llvm::StructType *ProtocolTy;
63 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
64 const llvm::Type *ProtocolPtrTy;
65 /// ProtocolExtensionTy - LLVM type for struct
66 /// objc_protocol_extension.
67 const llvm::StructType *ProtocolExtensionTy;
68 /// ProtocolExtensionTy - LLVM type for struct
69 /// objc_protocol_extension *.
70 const llvm::Type *ProtocolExtensionPtrTy;
71 /// MethodDescriptionTy - LLVM type for struct
72 /// objc_method_description.
73 const llvm::StructType *MethodDescriptionTy;
74 /// MethodDescriptionListTy - LLVM type for struct
75 /// objc_method_description_list.
76 const llvm::StructType *MethodDescriptionListTy;
77 /// MethodDescriptionListPtrTy - LLVM type for struct
78 /// objc_method_description_list *.
79 const llvm::Type *MethodDescriptionListPtrTy;
80 /// PropertyListTy - LLVM type for struct objc_property_list.
81 const llvm::Type *PropertyListTy;
82 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
83 const llvm::Type *PropertyListPtrTy;
84 /// ProtocolListTy - LLVM type for struct objc_property_list.
85 const llvm::Type *ProtocolListTy;
86 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
87 const llvm::Type *ProtocolListPtrTy;
88
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000089public:
90 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
91 ~ObjCTypesHelper();
92
93 llvm::Constant *getCFConstantStringClassReference();
94 const llvm::StructType *getCFStringType();
Daniel Dunbar259d93d2008-08-12 03:39:23 +000095 llvm::Function *getMessageSendFn();
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000096};
97
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000098class CGObjCMac : public CodeGen::CGObjCRuntime {
99private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000100 CodeGen::CodeGenModule &CGM;
101 ObjCTypesHelper ObjCTypes;
102 /// ObjCABI - FIXME: Not sure yet.
103 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000104
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000105 /// ClassNames - uniqued class names.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000106 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000107
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000108 /// MethodVarNames - uniqued method variable names.
109 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
110
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000111 /// MethodVarTypes - uniqued method type signatures. We have to use
112 /// a StringMap here because have no other unique reference.
113 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
114
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000115 /// SelectorReferences - uniqued selector references.
116 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
117
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000118 /// Protocols - Protocols for which an objc_protocol structure has
119 /// been emitted. Forward declarations are handled by creating an
120 /// empty structure whose initializer is filled in when/if defined.
121 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
122
123 /// UsedGlobals - List of globals to pack into the llvm.used metadata
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000124 /// to prevent them from being clobbered.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000125 std::vector<llvm::GlobalVariable*> UsedGlobals;
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000126
127 /// EmitImageInfo - Emit the image info marker used to encode some module
128 /// level information.
129 void EmitImageInfo();
130
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000131 /// EmitModuleInfo - Another marker encoding module level
132 /// information.
133
134 // FIXME: Not sure yet of the difference between this and
135 // IMAGE_INFO. otool looks at this before printing out Obj-C info
136 // though...
137 void EmitModuleInfo();
138
139 /// EmitModuleSymols - Emit module symbols, the result is a constant
140 /// of type pointer-to SymtabTy. // FIXME: Describe more completely
141 /// once known.
142 llvm::Constant *EmitModuleSymbols();
143
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000144 /// FinishModule - Write out global data structures at the end of
145 /// processing a translation unit.
146 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000147
148 /// EmitMethodList - Emit a method description list for a list of
149 /// method declarations.
150 /// - TypeName: The name for the type containing the methods.
151 /// - IsProtocol: True iff these methods are for a protocol.
152 /// - ClassMethds: True iff these are class methods.
153 /// - Required: When true, only "required" methods are
154 /// listed. Similarly, when false only "optional" methods are
155 /// listed. For classes this should always be true.
156 /// - begin, end: The method list to output.
157 ///
158 /// The return value has type MethodDescriptionListPtrTy.
159 llvm::Constant *EmitMethodList(const std::string &TypeName,
160 bool IsProtocol,
161 bool ClassMethods,
162 bool Required,
163 ObjCMethodDecl * const *begin,
164 ObjCMethodDecl * const *end);
165
166 /// EmitProtocolExtension - Generate the protocol extension
167 /// structure used to store optional instance and class methods, and
168 /// protocol properties. The return value has type
169 /// ProtocolExtensionPtrTy.
170 llvm::Constant *EmitProtocolExtension(const ObjCProtocolDecl *PD);
171
172 /// EmitProtocolList - Generate the list of referenced
173 /// protocols. The return value has type ProtocolListPtrTy.
174 llvm::Constant *EmitProtocolList(const ObjCProtocolDecl *PD);
175
176 /// GetProtocolRef - Return a reference to the internal protocol
177 /// description, creating an empty one if it has not been
178 /// defined. The return value has type pointer-to ProtocolTy.
179 llvm::GlobalVariable *GetProtocolRef(const ObjCProtocolDecl *PD);
180
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000181 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
182 /// for the given selector.
183 llvm::Value *EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel);
184
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000185 /// GetClassName - Return a unique constant for the given selector's
186 /// name.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000187 llvm::Constant *GetClassName(IdentifierInfo *Ident);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000188
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000189 /// GetMethodVarName - Return a unique constant for the given
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000190 /// selector's name. This returns a constant i8* to the start of
191 /// the name.
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000192 llvm::Constant *GetMethodVarName(Selector Sel);
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000193
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000194 /// GetMethodVarType - Return a unique constant for the given
195 /// selector's name. This returns a constant i8* to the start of
196 /// the name.
197 llvm::Constant *GetMethodVarType(ObjCMethodDecl *D);
198
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000199 /// GetNameForMethod - Return a name for the given method.
200 /// \param[out] NameOut - The return value.
201 void GetNameForMethod(const ObjCMethodDecl *OMD,
202 std::string &NameOut);
203
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000204public:
205 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000206 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000207
208 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
209 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000210 llvm::Value *Receiver,
211 Selector Sel,
212 llvm::Value** ArgV,
213 unsigned ArgC);
214
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000215 virtual llvm::Value *
216 GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
217 const llvm::Type *ReturnTy,
218 const ObjCInterfaceDecl *SuperClass,
219 llvm::Value *Receiver,
220 Selector Sel,
221 llvm::Value** ArgV,
222 unsigned ArgC);
223
224 virtual llvm::Value *GetClass(llvm::IRBuilder<> &Builder,
225 const ObjCInterfaceDecl *SuperClass);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000226
227 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
228
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000229 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000230
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000231 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000232
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000233 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000234
235 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000236 const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000237
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000238 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000239
240 virtual llvm::Function *ModuleInitFunction();
241};
242} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000243
244/* *** Helper Functions *** */
245
246/// getConstantGEP() - Help routine to construct simple GEPs.
247static llvm::Constant *getConstantGEP(llvm::Constant *C,
248 unsigned idx0,
249 unsigned idx1) {
250 llvm::Value *Idxs[] = {
251 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
252 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
253 };
254 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
255}
256
257/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000258
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000259CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
260 : CGM(cgm),
261 ObjCTypes(cgm),
262 ObjCABI(1)
263{
264 // FIXME: How does this get set in GCC? And what does it even mean?
265 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
266 ObjCABI = 2;
267
268 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000269}
270
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000271/// GetClass - Return a reference to the class for the given interface
272/// decl.
273llvm::Value *CGObjCMac::GetClass(llvm::IRBuilder<> &Builder,
274 const ObjCInterfaceDecl *OID) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000275 assert(0 && "Cannot lookup classes on Mac runtime.");
276 return 0;
277}
278
279/// GetSelector - Return the pointer to the unique'd string for this selector.
280llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000281 return EmitSelector(Builder, Sel);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000282}
283
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000284/// Generate a constant CFString object.
285/*
286 struct __builtin_CFString {
287 const int *isa; // point to __CFConstantStringClassReference
288 int flags;
289 const char *str;
290 long length;
291 };
292*/
293
294llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
295 // FIXME: I have no idea what this constant is (it is a magic
296 // constant in GCC as well). Most likely the encoding of the string
297 // and at least one part of it relates to UTF-16. Is this just the
298 // code for UTF-8? Where is this handled for us?
299 // See: <rdr://2996215>
300 unsigned flags = 0x07c8;
301
302 // FIXME: Use some machinery to unique this. We can't reuse the CGM
303 // one since we put them in a different section.
304 llvm::Constant *StringC = llvm::ConstantArray::get(String);
305 llvm::Constant *StringGV =
306 new llvm::GlobalVariable(StringC->getType(), true,
307 llvm::GlobalValue::InternalLinkage,
308 StringC, ".str", &CGM.getModule());
309 llvm::Constant *Values[4] = {
310 ObjCTypes.getCFConstantStringClassReference(),
311 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
312 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
313 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
314 };
315
316 llvm::Constant *CFStringC =
317 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
318 std::vector<llvm::Constant*>(Values, Values+4));
319
320 llvm::GlobalVariable *CFStringGV =
321 new llvm::GlobalVariable(CFStringC->getType(), true,
322 llvm::GlobalValue::InternalLinkage,
323 CFStringC, "",
324 &CGM.getModule());
325
326 CFStringGV->setSection("__DATA, __cfstring");
327
328 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000329}
330
331/// Generates a message send where the super is the receiver. This is
332/// a message send to self with special delivery semantics indicating
333/// which class's method should be called.
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000334llvm::Value *
335CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
336 const llvm::Type *ReturnTy,
337 const ObjCInterfaceDecl *SuperClass,
338 llvm::Value *Receiver,
339 Selector Sel,
340 llvm::Value** ArgV,
341 unsigned ArgC) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000342 assert(0 && "Cannot generate message send to super for Mac runtime.");
343 return 0;
344}
345
346/// Generate code for a message send expression.
347llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
348 const llvm::Type *ReturnTy,
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000349 llvm::Value *Receiver,
350 Selector Sel,
351 llvm::Value** ArgV,
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000352 unsigned ArgC) {
353 llvm::Function *F = ObjCTypes.getMessageSendFn();
354 llvm::Value **Args = new llvm::Value*[ArgC+2];
355 Args[0] = Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy, "tmp");
356 Args[1] = EmitSelector(Builder, Sel);
357 std::copy(ArgV, ArgV+ArgC, Args+2);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000358
359 std::vector<const llvm::Type*> Params;
360 Params.push_back(ObjCTypes.ObjectPtrTy);
361 Params.push_back(ObjCTypes.SelectorPtrTy);
362 llvm::FunctionType *CallFTy = llvm::FunctionType::get(ReturnTy,
363 Params,
364 true);
365 llvm::Type *PCallFTy = llvm::PointerType::getUnqual(CallFTy);
366 llvm::Constant *C = llvm::ConstantExpr::getBitCast(F, PCallFTy);
367 llvm::CallInst *CI = Builder.CreateCall(C,
368 Args, Args+ArgC+2, "tmp");
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000369 delete[] Args;
370 return Builder.CreateBitCast(CI, ReturnTy, "tmp");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000371}
372
373llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000374 const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000375 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
376 ObjCTypes.ExternalProtocolPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000377}
378
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000379/*
380 // APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
381 struct _objc_protocol {
382 struct _objc_protocol_extension *isa;
383 char *protocol_name;
384 struct _objc_protocol_list *protocol_list;
385 struct _objc__method_prototype_list *instance_methods;
386 struct _objc__method_prototype_list *class_methods
387 };
388
389 See EmitProtocolExtension().
390*/
391void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
392 const char *ProtocolName = PD->getName();
393
394 std::vector<llvm::Constant*> Values(5);
395 Values[0] = EmitProtocolExtension(PD);
396 Values[1] = GetClassName(PD->getIdentifier());
397 Values[2] = EmitProtocolList(PD);
398 Values[3] = EmitMethodList(ProtocolName,
399 true, // IsProtocol
400 false, // ClassMethods
401 true, // Required
402 PD->instmeth_begin(),
403 PD->instmeth_end());
404 Values[4] = EmitMethodList(ProtocolName,
405 true, // IsProtocol
406 true, // ClassMethods
407 true, // Required
408 PD->classmeth_begin(),
409 PD->classmeth_end());
410 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
411 Values);
412
413 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
414 if (Entry) {
415 // Already created, just update the initializer
416 Entry->setInitializer(Init);
417 } else {
418 Entry =
419 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
420 llvm::GlobalValue::InternalLinkage,
421 Init,
422 std::string("\01L_OBJC_PROTOCOL_")+ProtocolName,
423 &CGM.getModule());
424 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
425 UsedGlobals.push_back(Entry);
426 // FIXME: Is this necessary? Why only for protocol?
427 Entry->setAlignment(4);
428 }
429}
430
431llvm::GlobalVariable *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
432 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
433
434 if (!Entry) {
435 std::vector<llvm::Constant*> Values(5);
436 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
437 Values[1] = GetClassName(PD->getIdentifier());
438 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
439 Values[3] = Values[4] =
440 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
441 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
442 Values);
443
444 Entry =
445 new llvm::GlobalVariable(ObjCTypes.ProtocolTy, false,
446 llvm::GlobalValue::InternalLinkage,
447 Init,
448 std::string("\01L_OBJC_PROTOCOL_")+PD->getName(),
449 &CGM.getModule());
450 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
451 UsedGlobals.push_back(Entry);
452 // FIXME: Is this necessary? Why only for protocol?
453 Entry->setAlignment(4);
454 }
455
456 return Entry;
457}
458
459/*
460 struct _objc_protocol_extension {
461 uint32_t size;
462 struct objc_method_description_list *optional_instance_methods;
463 struct objc_method_description_list *optional_class_methods;
464 struct objc_property_list *instance_properties;
465 };
466*/
467llvm::Constant *CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD) {
468 uint64_t Size =
469 CGM.getTargetData().getABITypeSize(ObjCTypes.ProtocolExtensionTy);
470 std::vector<llvm::Constant*> Values(4);
471 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
472 Values[1] = EmitMethodList(PD->getName(),
473 true, // IsProtocol
474 false, // ClassMethods
475 false, // Required
476 PD->instmeth_begin(),
477 PD->instmeth_end());
478 Values[2] = EmitMethodList(PD->getName(),
479 true, // IsProtocol
480 true, // ClassMethods
481 false, // Required
482 PD->classmeth_begin(),
483 PD->classmeth_end());
484 Values[3] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
485 assert(!PD->getNumPropertyDecl() &&
486 "Cannot emit Obj-C protocol properties for NeXT runtime.");
487
488 // Return null if no extension bits are used
489 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
490 Values[3]->isNullValue())
491 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
492
493 llvm::Constant *Init =
494 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
495 llvm::GlobalVariable *GV =
496 new llvm::GlobalVariable(ObjCTypes.ProtocolExtensionTy, false,
497 llvm::GlobalValue::InternalLinkage,
498 Init,
499 (std::string("\01L_OBJC_PROTOCOLEXT_") +
500 PD->getName()),
501 &CGM.getModule());
502 // No special section, but goes in llvm.used
503 UsedGlobals.push_back(GV);
504
505 return GV;
506}
507
508/*
509 struct objc_protocol_list {
510 struct objc_protocol_list *next;
511 long count;
512 Protocol *list[];
513 };
514*/
515llvm::Constant *CGObjCMac::EmitProtocolList(const ObjCProtocolDecl *PD) {
516 std::vector<llvm::Constant*> ProtocolRefs;
517
518 for (ObjCProtocolDecl::protocol_iterator i = PD->protocol_begin(),
519 e = PD->protocol_end(); i != e; ++i)
520 ProtocolRefs.push_back(GetProtocolRef(*i));
521
522 // Just return null for empty protocol lists
523 if (ProtocolRefs.empty())
524 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
525
526 // This list is null terminated?
527 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
528
529 std::vector<llvm::Constant*> Values(3);
530 // XXX: What is this for?
531 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
532 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
533 Values[2] =
534 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
535 ProtocolRefs.size()),
536 ProtocolRefs);
537
538 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
539 llvm::GlobalVariable *GV =
540 new llvm::GlobalVariable(Init->getType(), false,
541 llvm::GlobalValue::InternalLinkage,
542 Init,
543 (std::string("\01L_OBJC_PROTOCOL_REFS_") +
544 PD->getName()),
545 &CGM.getModule());
546 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
547 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
548}
549
550/*
551 struct objc_method_description_list {
552 int count;
553 struct objc_method_description list[];
554 };
555*/
556llvm::Constant *CGObjCMac::EmitMethodList(const std::string &TypeName,
557 bool IsProtocol,
558 bool ClassMethods,
559 bool Required,
560 ObjCMethodDecl * const *begin,
561 ObjCMethodDecl * const *end) {
562 std::vector<llvm::Constant*> Methods, Desc(2);
563 for (; begin != end; ++begin) {
564 ObjCMethodDecl *D = *begin;
565 bool IsRequired = D->getImplementationControl() != ObjCMethodDecl::Optional;
566
567 // Skip if this method is required and we are outputting optional
568 // methods, or vice versa.
569 if (Required != IsRequired)
570 continue;
571
572 Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(D->getSelector()),
573 ObjCTypes.SelectorPtrTy);
574 Desc[1] = GetMethodVarType(D);
575 Methods.push_back(llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
576 Desc));
577 }
578
579 // Return null for empty list.
580 if (Methods.empty())
581 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
582
583 std::vector<llvm::Constant*> Values(2);
584 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
585 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
586 Methods.size());
587 Values[1] = llvm::ConstantArray::get(AT, Methods);
588 llvm::Constant *Init = llvm::ConstantStruct::get(Values);
589
590 char Prefix[256];
591 sprintf(Prefix, "\01L_OBJC_%s%sMETHODS_%s",
592 IsProtocol ? "PROTOCOL_" : "",
593 ClassMethods ? "CLASS_" : "INSTANCE_",
594 !Required ? "OPT_" : "");
595 llvm::GlobalVariable *GV =
596 new llvm::GlobalVariable(Init->getType(), false,
597 llvm::GlobalValue::InternalLinkage,
598 Init,
599 std::string(Prefix) + TypeName,
600 &CGM.getModule());
601 if (ClassMethods) {
602 GV->setSection("__OBJC,__cat_cls_meth,regular,no_dead_strip");
603 } else {
604 GV->setSection("__OBJC,__cat_inst_meth,regular,no_dead_strip");
605 }
606 UsedGlobals.push_back(GV);
607 return llvm::ConstantExpr::getBitCast(GV,
608 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000609}
610
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000611void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000612 assert(0 && "Cannot generate category for Mac runtime.");
613}
614
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000615void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ClassDecl) {
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000616 //assert(0 && "Cannot generate class for Mac runtime.");
617}
618
619llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD) {
620 const llvm::Type *ReturnTy =
621 CGM.getTypes().ConvertReturnType(OMD->getResultType());
622 const llvm::Type *SelfTy =
623 CGM.getTypes().ConvertType(OMD->getSelfDecl()->getType());
624
625 std::vector<const llvm::Type*> ArgTys;
626 ArgTys.reserve(1 + 2 + OMD->param_size());
627
628 // FIXME: This is not something we should have to be dealing with
629 // here.
630 bool useStructRet =
631 CodeGen::CodeGenFunction::hasAggregateLLVMType(OMD->getResultType());
632 if (useStructRet) {
633 ArgTys.push_back(llvm::PointerType::getUnqual(ReturnTy));
634 ReturnTy = llvm::Type::VoidTy;
635 }
636
637 // Implicit arguments
638 ArgTys.push_back(SelfTy);
639 ArgTys.push_back(ObjCTypes.SelectorPtrTy);
640
641 for (ObjCMethodDecl::param_const_iterator
642 i = OMD->param_begin(), e = OMD->param_end();
643 i != e; ++i) {
644 const llvm::Type *Ty = CGM.getTypes().ConvertType((*i)->getType());
645 if (Ty->isFirstClassType()) {
646 ArgTys.push_back(Ty);
647 } else {
648 ArgTys.push_back(llvm::PointerType::getUnqual(Ty));
649 }
650 }
651
652 std::string Name;
653 GetNameForMethod(OMD, Name);
654
655 llvm::Function *Method =
656 llvm::Function::Create(llvm::FunctionType::get(ReturnTy,
657 ArgTys,
658 OMD->isVariadic()),
659 llvm::GlobalValue::InternalLinkage,
660 Name,
661 &CGM.getModule());
662
663 if (useStructRet)
664 Method->addParamAttr(1, llvm::ParamAttr::StructRet);
665
666 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000667}
668
669llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000670 // Abuse this interface function as a place to finalize.
671 FinishModule();
672
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000673 return NULL;
674}
675
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000676/* *** Private Interface *** */
677
678/// EmitImageInfo - Emit the image info marker used to encode some module
679/// level information.
680///
681/// See: <rdr://4810609&4810587&4810587>
682/// struct IMAGE_INFO {
683/// unsigned version;
684/// unsigned flags;
685/// };
686enum ImageInfoFlags {
687 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
688 eImageInfo_GarbageCollected = (1 << 1),
689 eImageInfo_GCOnly = (1 << 2)
690};
691
692void CGObjCMac::EmitImageInfo() {
693 unsigned version = 0; // Version is unused?
694 unsigned flags = 0;
695
696 // FIXME: Fix and continue?
697 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
698 flags |= eImageInfo_GarbageCollected;
699 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
700 flags |= eImageInfo_GCOnly;
701
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000702 // Emitted as int[2];
703 llvm::Constant *values[2] = {
704 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
705 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
706 };
707 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000708 llvm::GlobalVariable *GV =
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000709 new llvm::GlobalVariable(AT, true,
710 llvm::GlobalValue::InternalLinkage,
711 llvm::ConstantArray::get(AT, values, 2),
712 "\01L_OBJC_IMAGE_INFO",
713 &CGM.getModule());
714
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000715 if (ObjCABI == 1) {
716 GV->setSection("__OBJC, __image_info,regular");
717 } else {
718 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
719 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000720
721 UsedGlobals.push_back(GV);
722}
723
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000724
725// struct objc_module {
726// unsigned long version;
727// unsigned long size;
728// const char *name;
729// Symtab symtab;
730// };
731
732// FIXME: Get from somewhere
733static const int ModuleVersion = 7;
734
735void CGObjCMac::EmitModuleInfo() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000736 uint64_t Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ModuleTy);
737
738 std::vector<llvm::Constant*> Values(4);
739 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion);
740 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000741 // This used to be the filename, now it is unused. <rdr://4327263>
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000742 Values[2] = GetClassName(&CGM.getContext().Idents.get(""));
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000743 Values[3] = EmitModuleSymbols();
744
745 llvm::GlobalVariable *GV =
746 new llvm::GlobalVariable(ObjCTypes.ModuleTy, false,
747 llvm::GlobalValue::InternalLinkage,
748 llvm::ConstantStruct::get(ObjCTypes.ModuleTy,
749 Values),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000750 "\01L_OBJC_MODULES",
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000751 &CGM.getModule());
752 GV->setSection("__OBJC,__module_info,regular,no_dead_strip");
753 UsedGlobals.push_back(GV);
754}
755
756llvm::Constant *CGObjCMac::EmitModuleSymbols() {
757 // FIXME: Is this ever used?
758 llvm::GlobalVariable *GV =
759 new llvm::GlobalVariable(ObjCTypes.SymtabTy, false,
760 llvm::GlobalValue::InternalLinkage,
761 llvm::Constant::getNullValue(ObjCTypes.SymtabTy),
762 "\01L_OBJC_SYMBOLS",
763 &CGM.getModule());
764 GV->setSection("__OBJC,__symbols,regular,no_dead_strip");
765 UsedGlobals.push_back(GV);
766 return GV;
767}
768
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000769llvm::Value *CGObjCMac::EmitSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
770 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
771
772 if (!Entry) {
773 llvm::Constant *Casted =
774 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
775 ObjCTypes.SelectorPtrTy);
776 Entry =
777 new llvm::GlobalVariable(ObjCTypes.SelectorPtrTy, false,
778 llvm::GlobalValue::InternalLinkage,
779 Casted, "\01L_OBJC_SELECTOR_REFERENCES_",
780 &CGM.getModule());
781 Entry->setSection("__OBJC,__message_refs,literal_pointers,no_dead_strip");
782 UsedGlobals.push_back(Entry);
783 }
784
785 return Builder.CreateLoad(Entry, false, "tmp");
786}
787
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000788llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) {
789 llvm::GlobalVariable *&Entry = ClassNames[Ident];
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000790
791 if (!Entry) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000792 llvm::Constant *C = llvm::ConstantArray::get(Ident->getName());
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000793 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000794 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000795 llvm::GlobalValue::InternalLinkage,
796 C, "\01L_OBJC_CLASS_NAME_",
797 &CGM.getModule());
798 Entry->setSection("__TEXT,__cstring,cstring_literals");
799 UsedGlobals.push_back(Entry);
800 }
801
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000802 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000803}
804
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000805llvm::Constant *CGObjCMac::GetMethodVarName(Selector Sel) {
806 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
807
808 if (!Entry) {
809 llvm::Constant *C = llvm::ConstantArray::get(Sel.getName());
810 Entry =
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000811 new llvm::GlobalVariable(C->getType(), false,
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000812 llvm::GlobalValue::InternalLinkage,
813 C, "\01L_OBJC_METH_VAR_NAME_",
814 &CGM.getModule());
815 Entry->setSection("__TEXT,__cstring,cstring_literals");
816 UsedGlobals.push_back(Entry);
817 }
818
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000819 return getConstantGEP(Entry, 0, 0);
820}
821
822llvm::Constant *CGObjCMac::GetMethodVarType(ObjCMethodDecl *D) {
823 std::string TypeStr;
824 CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr);
825 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
826
827 if (!Entry) {
828 llvm::Constant *C = llvm::ConstantArray::get(TypeStr);
829 Entry =
830 new llvm::GlobalVariable(C->getType(), false,
831 llvm::GlobalValue::InternalLinkage,
832 C, "\01L_OBJC_METH_VAR_TYPE_",
833 &CGM.getModule());
834 Entry->setSection("__TEXT,__cstring,cstring_literals");
835 UsedGlobals.push_back(Entry);
836 }
837
838 return getConstantGEP(Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000839}
840
Daniel Dunbarb7ec2462008-08-16 03:19:19 +0000841void CGObjCMac::GetNameForMethod(const ObjCMethodDecl *D,
842 std::string &NameOut) {
843 // FIXME: Find the mangling GCC uses.
844 std::stringstream s;
845 s << (D->isInstance() ? "-" : "+");
846 s << "[";
847 s << D->getClassInterface()->getName();
848 s << " ";
849 s << D->getSelector().getName();
850 s << "]";
851 NameOut = s.str();
852}
853
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000854void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000855 EmitModuleInfo();
856
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000857 std::vector<llvm::Constant*> Used;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000858
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000859 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000860 for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(),
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000861 e = UsedGlobals.end(); i != e; ++i) {
862 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
863 }
864
865 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
866 llvm::GlobalValue *GV =
867 new llvm::GlobalVariable(AT, false,
868 llvm::GlobalValue::AppendingLinkage,
869 llvm::ConstantArray::get(AT, Used),
870 "llvm.used",
871 &CGM.getModule());
872
873 GV->setSection("llvm.metadata");
874}
875
876/* *** */
877
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000878ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
879 : CGM(cgm),
880 CFStringType(0),
881 CFConstantStringClassReference(0),
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000882 MessageSendFn(0)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000883{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000884 CodeGen::CodeGenTypes &Types = CGM.getTypes();
885 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000886
887 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000888 LongTy = Types.ConvertType(Ctx.LongTy);
889 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
890 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000891
892 // FIXME: It would be nice to unify this with the opaque type, so
893 // that the IR comes out a bit cleaner.
894 const llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
895 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000896
897 SymtabTy = llvm::StructType::get(LongTy,
898 SelectorPtrTy,
899 Types.ConvertType(Ctx.ShortTy),
900 Types.ConvertType(Ctx.ShortTy),
901 NULL);
902 CGM.getModule().addTypeName("struct._objc_symtab", SymtabTy);
903
904 ModuleTy =
905 llvm::StructType::get(LongTy,
906 LongTy,
907 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
908 llvm::PointerType::getUnqual(SymtabTy),
909 NULL);
910 CGM.getModule().addTypeName("struct._objc_module", ModuleTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000911
912 MethodDescriptionTy =
913 llvm::StructType::get(SelectorPtrTy,
914 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
915 NULL);
916 CGM.getModule().addTypeName("struct._objc_method_description",
917 MethodDescriptionTy);
918
919 MethodDescriptionListTy =
920 llvm::StructType::get(IntTy,
921 llvm::ArrayType::get(MethodDescriptionTy, 0),
922 NULL);
923 CGM.getModule().addTypeName("struct._objc_method_description_list",
924 MethodDescriptionListTy);
925 MethodDescriptionListPtrTy =
926 llvm::PointerType::getUnqual(MethodDescriptionListTy);
927
928 PropertyListTy = llvm::OpaqueType::get();
929 CGM.getModule().addTypeName("struct._objc_property_list",
930 PropertyListTy);
931 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
932
933 // Protocol description structures
934
935 ProtocolExtensionTy =
936 llvm::StructType::get(Types.ConvertType(Ctx.IntTy),
937 llvm::PointerType::getUnqual(MethodDescriptionListTy),
938 llvm::PointerType::getUnqual(MethodDescriptionListTy),
939 PropertyListPtrTy,
940 NULL);
941 CGM.getModule().addTypeName("struct._objc_protocol_extension",
942 ProtocolExtensionTy);
943 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
944
945 // Handle recursive construction of Protocl and ProtocolList types
946
947 llvm::PATypeHolder ProtocolTyHolder = llvm::OpaqueType::get();
948 llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get();
949
950 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolListTyHolder),
951 LongTy,
952 llvm::ArrayType::get(ProtocolTyHolder, 0),
953 NULL);
954 cast<llvm::OpaqueType>(ProtocolListTyHolder.get())->refineAbstractTypeTo(T);
955
956 T = llvm::StructType::get(llvm::PointerType::getUnqual(ProtocolExtensionTy),
957 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
958 llvm::PointerType::getUnqual(ProtocolListTyHolder),
959 MethodDescriptionListPtrTy,
960 MethodDescriptionListPtrTy,
961 NULL);
962 cast<llvm::OpaqueType>(ProtocolTyHolder.get())->refineAbstractTypeTo(T);
963
964 ProtocolListTy = cast<llvm::StructType>(ProtocolListTyHolder.get());
965 CGM.getModule().addTypeName("struct._objc_protocol_list",
966 ProtocolListTy);
967 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
968
969 ProtocolTy = cast<llvm::StructType>(ProtocolTyHolder.get());
970 CGM.getModule().addTypeName("struct.__objc_protocol", ProtocolTy);
971 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000972}
973
974ObjCTypesHelper::~ObjCTypesHelper() {
975}
976
977const llvm::StructType *ObjCTypesHelper::getCFStringType() {
978 if (!CFStringType) {
979 CFStringType =
980 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
981 llvm::Type::Int32Ty,
982 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
983 LongTy,
984 NULL);
985
986 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
987 }
988
989 return CFStringType;
990}
991
992llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
993 if (!CFConstantStringClassReference) {
994 llvm::GlobalValue *GV =
995 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
996 false,
997 llvm::GlobalValue::ExternalLinkage,
998 0, "__CFConstantStringClassReference",
999 &CGM.getModule());
1000
1001 // Decay to pointer.
1002 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
1003 }
1004
1005 return CFConstantStringClassReference;
1006}
1007
Daniel Dunbar259d93d2008-08-12 03:39:23 +00001008llvm::Function *ObjCTypesHelper::getMessageSendFn() {
1009 if (!MessageSendFn) {
1010 std::vector<const llvm::Type*> Params;
1011 Params.push_back(ObjectPtrTy);
1012 Params.push_back(SelectorPtrTy);
1013 MessageSendFn = llvm::Function::Create(llvm::FunctionType::get(ObjectPtrTy,
1014 Params,
1015 true),
1016 llvm::Function::ExternalLinkage,
1017 "objc_msgSend",
1018 &CGM.getModule());
1019 }
1020
1021 return MessageSendFn;
1022}
1023
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001024/* *** */
1025
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001026CodeGen::CGObjCRuntime *
1027CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001028 return new CGObjCMac(CGM);
1029}