blob: ce53b5b23141e925ee21e30a866020f392362483 [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 Dunbarbbce49b2008-08-12 00:12:39 +000017#include "clang/AST/ASTContext.h"
Daniel Dunbare91593e2008-08-11 04:54:23 +000018#include "clang/AST/Decl.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000019#include "clang/Basic/LangOptions.h"
20
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000021#include "llvm/Module.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000022#include "llvm/Support/IRBuilder.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000023
24using namespace clang;
25
26namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000027
28/// ObjCTypesHelper - Helper class that encapsulates lazy
29/// construction of varies types used during ObjC generation.
30class ObjCTypesHelper {
31private:
32 CodeGen::CodeGenModule &CGM;
33
34 const llvm::StructType *CFStringType;
35 llvm::Constant *CFConstantStringClassReference;
36
37public:
38 const llvm::Type *LongTy;
39
40public:
41 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
42 ~ObjCTypesHelper();
43
44 llvm::Constant *getCFConstantStringClassReference();
45 const llvm::StructType *getCFStringType();
46};
47
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000048class CGObjCMac : public CodeGen::CGObjCRuntime {
49private:
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000050 CodeGen::CodeGenModule &CGM;
51 ObjCTypesHelper ObjCTypes;
52 /// ObjCABI - FIXME: Not sure yet.
53 unsigned ObjCABI;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000054
Daniel Dunbarf77ac862008-08-11 21:35:06 +000055 /// UsedGlobals - list of globals to pack into the llvm.used metadata
56 /// to prevent them from being clobbered.
57 std::vector<llvm::GlobalValue*> UsedGlobals;
58
59 /// EmitImageInfo - Emit the image info marker used to encode some module
60 /// level information.
61 void EmitImageInfo();
62
63 /// FinishModule - Write out global data structures at the end of
64 /// processing a translation unit.
65 void FinishModule();
66
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000067public:
68 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000069 virtual llvm::Constant *GenerateConstantString(const std::string &String);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000070
71 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
72 const llvm::Type *ReturnTy,
73 llvm::Value *Sender,
74 llvm::Value *Receiver,
75 Selector Sel,
76 llvm::Value** ArgV,
77 unsigned ArgC);
78
79 virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
80 const llvm::Type *ReturnTy,
81 llvm::Value *Sender,
82 const char *SuperClassName,
83 llvm::Value *Receiver,
84 Selector Sel,
85 llvm::Value** ArgV,
86 unsigned ArgC);
87
88 virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder,
89 llvm::Value *ClassName);
90
91 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
92
93 virtual llvm::Function *MethodPreamble(const std::string &ClassName,
94 const std::string &CategoryName,
95 const std::string &MethodName,
96 const llvm::Type *ReturnTy,
97 const llvm::Type *SelfTy,
98 const llvm::Type **ArgTy,
99 unsigned ArgC,
100 bool isClassMethod,
101 bool isVarArg);
102
103 virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
104 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
105 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
106 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
107 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
108 const llvm::SmallVectorImpl<std::string> &Protocols);
109
110 virtual void GenerateClass(
111 const char *ClassName,
112 const char *SuperClassName,
113 const int instanceSize,
114 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
115 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
116 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
117 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
118 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
119 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
120 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
121 const llvm::SmallVectorImpl<std::string> &Protocols);
122
123 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
124 const char *ProtocolName);
125
126 virtual void GenerateProtocol(const char *ProtocolName,
127 const llvm::SmallVectorImpl<std::string> &Protocols,
128 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
129 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
130 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
131 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes);
132
133 virtual llvm::Function *ModuleInitFunction();
134};
135} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000136
137/* *** Helper Functions *** */
138
139/// getConstantGEP() - Help routine to construct simple GEPs.
140static llvm::Constant *getConstantGEP(llvm::Constant *C,
141 unsigned idx0,
142 unsigned idx1) {
143 llvm::Value *Idxs[] = {
144 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx0),
145 llvm::ConstantInt::get(llvm::Type::Int32Ty, idx1)
146 };
147 return llvm::ConstantExpr::getGetElementPtr(C, Idxs, 2);
148}
149
150/* *** CGObjCMac Public Interface *** */
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000151
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000152CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm)
153 : CGM(cgm),
154 ObjCTypes(cgm),
155 ObjCABI(1)
156{
157 // FIXME: How does this get set in GCC? And what does it even mean?
158 if (ObjCTypes.LongTy != CGM.getTypes().ConvertType(CGM.getContext().IntTy))
159 ObjCABI = 2;
160
161 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000162}
163
164// This has to perform the lookup every time, since posing and related
165// techniques can modify the name -> class mapping.
166llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
167 llvm::Value *ClassName) {
168 assert(0 && "Cannot lookup classes on Mac runtime.");
169 return 0;
170}
171
172/// GetSelector - Return the pointer to the unique'd string for this selector.
173llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
174 assert(0 && "Cannot get selector on Mac runtime.");
175 return 0;
176}
177
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000178/// Generate a constant CFString object.
179/*
180 struct __builtin_CFString {
181 const int *isa; // point to __CFConstantStringClassReference
182 int flags;
183 const char *str;
184 long length;
185 };
186*/
187
188llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) {
189 // FIXME: I have no idea what this constant is (it is a magic
190 // constant in GCC as well). Most likely the encoding of the string
191 // and at least one part of it relates to UTF-16. Is this just the
192 // code for UTF-8? Where is this handled for us?
193 // See: <rdr://2996215>
194 unsigned flags = 0x07c8;
195
196 // FIXME: Use some machinery to unique this. We can't reuse the CGM
197 // one since we put them in a different section.
198 llvm::Constant *StringC = llvm::ConstantArray::get(String);
199 llvm::Constant *StringGV =
200 new llvm::GlobalVariable(StringC->getType(), true,
201 llvm::GlobalValue::InternalLinkage,
202 StringC, ".str", &CGM.getModule());
203 llvm::Constant *Values[4] = {
204 ObjCTypes.getCFConstantStringClassReference(),
205 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags),
206 getConstantGEP(StringGV, 0, 0), // Decay array -> ptr
207 llvm::ConstantInt::get(ObjCTypes.LongTy, String.size())
208 };
209
210 llvm::Constant *CFStringC =
211 llvm::ConstantStruct::get(ObjCTypes.getCFStringType(),
212 std::vector<llvm::Constant*>(Values, Values+4));
213
214 llvm::GlobalVariable *CFStringGV =
215 new llvm::GlobalVariable(CFStringC->getType(), true,
216 llvm::GlobalValue::InternalLinkage,
217 CFStringC, "",
218 &CGM.getModule());
219
220 CFStringGV->setSection("__DATA, __cfstring");
221
222 return CFStringGV;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000223}
224
225/// Generates a message send where the super is the receiver. This is
226/// a message send to self with special delivery semantics indicating
227/// which class's method should be called.
228llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
229 const llvm::Type *ReturnTy,
230 llvm::Value *Sender,
231 const char *SuperClassName,
232 llvm::Value *Receiver,
233 Selector Sel,
234 llvm::Value** ArgV,
235 unsigned ArgC) {
236 assert(0 && "Cannot generate message send to super for Mac runtime.");
237 return 0;
238}
239
240/// Generate code for a message send expression.
241llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
242 const llvm::Type *ReturnTy,
243 llvm::Value *Sender,
244 llvm::Value *Receiver,
245 Selector Sel,
246 llvm::Value** ArgV,
247 unsigned ArgC) {
248 assert(0 && "Cannot generate message send for Mac runtime.");
249 return 0;
250}
251
252llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
253 const char *ProtocolName) {
254 assert(0 && "Cannot get protocol reference on Mac runtime.");
255 return 0;
256}
257
258void CGObjCMac::GenerateProtocol(const char *ProtocolName,
259 const llvm::SmallVectorImpl<std::string> &Protocols,
260 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
261 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
262 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
263 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes) {
264 assert(0 && "Cannot generate protocol for Mac runtime.");
265}
266
267void CGObjCMac::GenerateCategory(
268 const char *ClassName,
269 const char *CategoryName,
270 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
271 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
272 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
273 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
274 const llvm::SmallVectorImpl<std::string> &Protocols) {
275 assert(0 && "Cannot generate category for Mac runtime.");
276}
277
278void CGObjCMac::GenerateClass(
279 const char *ClassName,
280 const char *SuperClassName,
281 const int instanceSize,
282 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
283 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
284 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
285 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
286 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
287 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
288 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
289 const llvm::SmallVectorImpl<std::string> &Protocols) {
290 assert(0 && "Cannot generate class for Mac runtime.");
291}
292
293llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000294 // Abuse this interface function as a place to finalize.
295 FinishModule();
296
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000297 return NULL;
298}
299
300llvm::Function *CGObjCMac::MethodPreamble(
301 const std::string &ClassName,
302 const std::string &CategoryName,
303 const std::string &MethodName,
304 const llvm::Type *ReturnTy,
305 const llvm::Type *SelfTy,
306 const llvm::Type **ArgTy,
307 unsigned ArgC,
308 bool isClassMethod,
309 bool isVarArg) {
310 assert(0 && "Cannot generate method preamble for Mac runtime.");
311 return 0;
312}
313
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000314/* *** Private Interface *** */
315
316/// EmitImageInfo - Emit the image info marker used to encode some module
317/// level information.
318///
319/// See: <rdr://4810609&4810587&4810587>
320/// struct IMAGE_INFO {
321/// unsigned version;
322/// unsigned flags;
323/// };
324enum ImageInfoFlags {
325 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
326 eImageInfo_GarbageCollected = (1 << 1),
327 eImageInfo_GCOnly = (1 << 2)
328};
329
330void CGObjCMac::EmitImageInfo() {
331 unsigned version = 0; // Version is unused?
332 unsigned flags = 0;
333
334 // FIXME: Fix and continue?
335 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
336 flags |= eImageInfo_GarbageCollected;
337 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
338 flags |= eImageInfo_GCOnly;
339
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000340 // Emitted as int[2];
341 llvm::Constant *values[2] = {
342 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
343 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
344 };
345 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
346 llvm::GlobalValue *GV =
347 new llvm::GlobalVariable(AT, true,
348 llvm::GlobalValue::InternalLinkage,
349 llvm::ConstantArray::get(AT, values, 2),
350 "\01L_OBJC_IMAGE_INFO",
351 &CGM.getModule());
352
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000353 if (ObjCABI == 1) {
354 GV->setSection("__OBJC, __image_info,regular");
355 } else {
356 GV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip");
357 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000358
359 UsedGlobals.push_back(GV);
360}
361
362void CGObjCMac::FinishModule() {
363 std::vector<llvm::Constant*> Used;
364
365 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
366 for (std::vector<llvm::GlobalValue*>::iterator i = UsedGlobals.begin(),
367 e = UsedGlobals.end(); i != e; ++i) {
368 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
369 }
370
371 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
372 llvm::GlobalValue *GV =
373 new llvm::GlobalVariable(AT, false,
374 llvm::GlobalValue::AppendingLinkage,
375 llvm::ConstantArray::get(AT, Used),
376 "llvm.used",
377 &CGM.getModule());
378
379 GV->setSection("llvm.metadata");
380}
381
382/* *** */
383
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000384ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
385 : CGM(cgm),
386 CFStringType(0),
387 CFConstantStringClassReference(0),
388 LongTy(CGM.getTypes().ConvertType(CGM.getContext().LongTy))
389{
390}
391
392ObjCTypesHelper::~ObjCTypesHelper() {
393}
394
395const llvm::StructType *ObjCTypesHelper::getCFStringType() {
396 if (!CFStringType) {
397 CFStringType =
398 llvm::StructType::get(llvm::PointerType::getUnqual(llvm::Type::Int32Ty),
399 llvm::Type::Int32Ty,
400 llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
401 LongTy,
402 NULL);
403
404 CGM.getModule().addTypeName("struct.__builtin_CFString", CFStringType);
405 }
406
407 return CFStringType;
408}
409
410llvm::Constant *ObjCTypesHelper::getCFConstantStringClassReference() {
411 if (!CFConstantStringClassReference) {
412 llvm::GlobalValue *GV =
413 new llvm::GlobalVariable(llvm::ArrayType::get(llvm::Type::Int32Ty, 0),
414 false,
415 llvm::GlobalValue::ExternalLinkage,
416 0, "__CFConstantStringClassReference",
417 &CGM.getModule());
418
419 // Decay to pointer.
420 CFConstantStringClassReference = getConstantGEP(GV, 0, 0);
421 }
422
423 return CFConstantStringClassReference;
424}
425
426/* *** */
427
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000428CodeGen::CGObjCRuntime *CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM){
429 return new CGObjCMac(CGM);
430}