blob: 205a8f55e911069e1e642cb0b97083fe2b1c2587 [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 Dunbare91593e2008-08-11 04:54:23 +000017#include "clang/AST/Decl.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000018#include "clang/Basic/LangOptions.h"
19
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000020#include "llvm/Support/IRBuilder.h"
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000021
22using namespace clang;
23
24namespace {
25class CGObjCMac : public CodeGen::CGObjCRuntime {
26private:
27 CodeGen::CodeGenModule &CGM;
28
Daniel Dunbarf77ac862008-08-11 21:35:06 +000029 /// UsedGlobals - list of globals to pack into the llvm.used metadata
30 /// to prevent them from being clobbered.
31 std::vector<llvm::GlobalValue*> UsedGlobals;
32
33 /// EmitImageInfo - Emit the image info marker used to encode some module
34 /// level information.
35 void EmitImageInfo();
36
37 /// FinishModule - Write out global data structures at the end of
38 /// processing a translation unit.
39 void FinishModule();
40
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000041public:
42 CGObjCMac(CodeGen::CodeGenModule &cgm);
43 virtual llvm::Constant *GenerateConstantString(const char *String,
44 const size_t length);
45
46 virtual llvm::Value *GenerateMessageSend(llvm::IRBuilder<> &Builder,
47 const llvm::Type *ReturnTy,
48 llvm::Value *Sender,
49 llvm::Value *Receiver,
50 Selector Sel,
51 llvm::Value** ArgV,
52 unsigned ArgC);
53
54 virtual llvm::Value *GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
55 const llvm::Type *ReturnTy,
56 llvm::Value *Sender,
57 const char *SuperClassName,
58 llvm::Value *Receiver,
59 Selector Sel,
60 llvm::Value** ArgV,
61 unsigned ArgC);
62
63 virtual llvm::Value *LookupClass(llvm::IRBuilder<> &Builder,
64 llvm::Value *ClassName);
65
66 virtual llvm::Value *GetSelector(llvm::IRBuilder<> &Builder, Selector Sel);
67
68 virtual llvm::Function *MethodPreamble(const std::string &ClassName,
69 const std::string &CategoryName,
70 const std::string &MethodName,
71 const llvm::Type *ReturnTy,
72 const llvm::Type *SelfTy,
73 const llvm::Type **ArgTy,
74 unsigned ArgC,
75 bool isClassMethod,
76 bool isVarArg);
77
78 virtual void GenerateCategory(const char *ClassName, const char *CategoryName,
79 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
80 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
81 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
82 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
83 const llvm::SmallVectorImpl<std::string> &Protocols);
84
85 virtual void GenerateClass(
86 const char *ClassName,
87 const char *SuperClassName,
88 const int instanceSize,
89 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
90 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
91 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
92 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
93 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
94 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
95 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
96 const llvm::SmallVectorImpl<std::string> &Protocols);
97
98 virtual llvm::Value *GenerateProtocolRef(llvm::IRBuilder<> &Builder,
99 const char *ProtocolName);
100
101 virtual void GenerateProtocol(const char *ProtocolName,
102 const llvm::SmallVectorImpl<std::string> &Protocols,
103 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
104 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
105 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
106 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes);
107
108 virtual llvm::Function *ModuleInitFunction();
109};
110} // end anonymous namespace
111
112CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000113 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000114}
115
116// This has to perform the lookup every time, since posing and related
117// techniques can modify the name -> class mapping.
118llvm::Value *CGObjCMac::LookupClass(llvm::IRBuilder<> &Builder,
119 llvm::Value *ClassName) {
120 assert(0 && "Cannot lookup classes on Mac runtime.");
121 return 0;
122}
123
124/// GetSelector - Return the pointer to the unique'd string for this selector.
125llvm::Value *CGObjCMac::GetSelector(llvm::IRBuilder<> &Builder, Selector Sel) {
126 assert(0 && "Cannot get selector on Mac runtime.");
127 return 0;
128}
129
130/// Generate an NSConstantString object.
131llvm::Constant *CGObjCMac::GenerateConstantString(const char *String,
132 const size_t length) {
133 assert(0 && "Cannot generate constant string for Mac runtime.");
134 return 0;
135}
136
137/// Generates a message send where the super is the receiver. This is
138/// a message send to self with special delivery semantics indicating
139/// which class's method should be called.
140llvm::Value *CGObjCMac::GenerateMessageSendSuper(llvm::IRBuilder<> &Builder,
141 const llvm::Type *ReturnTy,
142 llvm::Value *Sender,
143 const char *SuperClassName,
144 llvm::Value *Receiver,
145 Selector Sel,
146 llvm::Value** ArgV,
147 unsigned ArgC) {
148 assert(0 && "Cannot generate message send to super for Mac runtime.");
149 return 0;
150}
151
152/// Generate code for a message send expression.
153llvm::Value *CGObjCMac::GenerateMessageSend(llvm::IRBuilder<> &Builder,
154 const llvm::Type *ReturnTy,
155 llvm::Value *Sender,
156 llvm::Value *Receiver,
157 Selector Sel,
158 llvm::Value** ArgV,
159 unsigned ArgC) {
160 assert(0 && "Cannot generate message send for Mac runtime.");
161 return 0;
162}
163
164llvm::Value *CGObjCMac::GenerateProtocolRef(llvm::IRBuilder<> &Builder,
165 const char *ProtocolName) {
166 assert(0 && "Cannot get protocol reference on Mac runtime.");
167 return 0;
168}
169
170void CGObjCMac::GenerateProtocol(const char *ProtocolName,
171 const llvm::SmallVectorImpl<std::string> &Protocols,
172 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodNames,
173 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
174 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodNames,
175 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes) {
176 assert(0 && "Cannot generate protocol for Mac runtime.");
177}
178
179void CGObjCMac::GenerateCategory(
180 const char *ClassName,
181 const char *CategoryName,
182 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
183 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
184 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
185 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
186 const llvm::SmallVectorImpl<std::string> &Protocols) {
187 assert(0 && "Cannot generate category for Mac runtime.");
188}
189
190void CGObjCMac::GenerateClass(
191 const char *ClassName,
192 const char *SuperClassName,
193 const int instanceSize,
194 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
195 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
196 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets,
197 const llvm::SmallVectorImpl<Selector> &InstanceMethodSels,
198 const llvm::SmallVectorImpl<llvm::Constant *> &InstanceMethodTypes,
199 const llvm::SmallVectorImpl<Selector> &ClassMethodSels,
200 const llvm::SmallVectorImpl<llvm::Constant *> &ClassMethodTypes,
201 const llvm::SmallVectorImpl<std::string> &Protocols) {
202 assert(0 && "Cannot generate class for Mac runtime.");
203}
204
205llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000206 // Abuse this interface function as a place to finalize.
207 FinishModule();
208
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000209 return NULL;
210}
211
212llvm::Function *CGObjCMac::MethodPreamble(
213 const std::string &ClassName,
214 const std::string &CategoryName,
215 const std::string &MethodName,
216 const llvm::Type *ReturnTy,
217 const llvm::Type *SelfTy,
218 const llvm::Type **ArgTy,
219 unsigned ArgC,
220 bool isClassMethod,
221 bool isVarArg) {
222 assert(0 && "Cannot generate method preamble for Mac runtime.");
223 return 0;
224}
225
Daniel Dunbarf77ac862008-08-11 21:35:06 +0000226/* *** Private Interface *** */
227
228/// EmitImageInfo - Emit the image info marker used to encode some module
229/// level information.
230///
231/// See: <rdr://4810609&4810587&4810587>
232/// struct IMAGE_INFO {
233/// unsigned version;
234/// unsigned flags;
235/// };
236enum ImageInfoFlags {
237 eImageInfo_FixAndContinue = (1 << 0), // FIXME: Not sure what this implies
238 eImageInfo_GarbageCollected = (1 << 1),
239 eImageInfo_GCOnly = (1 << 2)
240};
241
242void CGObjCMac::EmitImageInfo() {
243 unsigned version = 0; // Version is unused?
244 unsigned flags = 0;
245
246 // FIXME: Fix and continue?
247 if (CGM.getLangOptions().getGCMode() != LangOptions::NonGC)
248 flags |= eImageInfo_GarbageCollected;
249 if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly)
250 flags |= eImageInfo_GCOnly;
251
252 fprintf(stderr, "flags: %d (%d)\n", flags, CGM.getLangOptions().getGCMode());
253
254 // Emitted as int[2];
255 llvm::Constant *values[2] = {
256 llvm::ConstantInt::get(llvm::Type::Int32Ty, version),
257 llvm::ConstantInt::get(llvm::Type::Int32Ty, flags)
258 };
259 llvm::ArrayType *AT = llvm::ArrayType::get(llvm::Type::Int32Ty, 2);
260 llvm::GlobalValue *GV =
261 new llvm::GlobalVariable(AT, true,
262 llvm::GlobalValue::InternalLinkage,
263 llvm::ConstantArray::get(AT, values, 2),
264 "\01L_OBJC_IMAGE_INFO",
265 &CGM.getModule());
266
267 GV->setSection("__OBJC, __image_info,regular");
268
269 UsedGlobals.push_back(GV);
270}
271
272void CGObjCMac::FinishModule() {
273 std::vector<llvm::Constant*> Used;
274
275 llvm::Type *I8Ptr = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
276 for (std::vector<llvm::GlobalValue*>::iterator i = UsedGlobals.begin(),
277 e = UsedGlobals.end(); i != e; ++i) {
278 Used.push_back(llvm::ConstantExpr::getBitCast(*i, I8Ptr));
279 }
280
281 llvm::ArrayType *AT = llvm::ArrayType::get(I8Ptr, Used.size());
282 llvm::GlobalValue *GV =
283 new llvm::GlobalVariable(AT, false,
284 llvm::GlobalValue::AppendingLinkage,
285 llvm::ConstantArray::get(AT, Used),
286 "llvm.used",
287 &CGM.getModule());
288
289 GV->setSection("llvm.metadata");
290}
291
292/* *** */
293
Daniel Dunbarc17a4d32008-08-11 02:45:11 +0000294CodeGen::CGObjCRuntime *CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM){
295 return new CGObjCMac(CGM);
296}