blob: 04b688f0122702f3b200be3ad628e1ea1743b57f [file] [log] [blame]
Anton Korobeynikov20ff3102008-06-01 14:13:53 +00001//===------- CGObjCGNU.cpp - Emit LLVM Code from ASTs for a Module --------===//
Chris Lattner0f984262008-03-01 08:50:34 +00002//
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//
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000010// This provides Objective-C code generation targetting the GNU runtime. The
11// class in this file generates structures used by the GNU Objective-C runtime
12// library. These structures are defined in objc/objc.h and objc/objc-api.h in
13// the GNU runtime distribution.
Chris Lattner0f984262008-03-01 08:50:34 +000014//
15//===----------------------------------------------------------------------===//
16
17#include "CGObjCRuntime.h"
Chris Lattnerdce14062008-06-26 04:19:03 +000018#include "CodeGenModule.h"
Daniel Dunbar8f2926b2008-08-23 03:46:30 +000019#include "CodeGenFunction.h"
Chris Lattnerdce14062008-06-26 04:19:03 +000020#include "clang/AST/ASTContext.h"
Daniel Dunbare91593e2008-08-11 04:54:23 +000021#include "clang/AST/Decl.h"
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +000022#include "clang/AST/DeclObjC.h"
Daniel Dunbar2bebbf02009-05-03 10:46:44 +000023#include "clang/AST/RecordLayout.h"
Chris Lattner16f00492009-04-26 01:32:48 +000024#include "clang/AST/StmtObjC.h"
Chris Lattner0f984262008-03-01 08:50:34 +000025#include "llvm/Module.h"
Chris Lattner0f984262008-03-01 08:50:34 +000026#include "llvm/ADT/SmallVector.h"
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000027#include "llvm/ADT/StringMap.h"
Daniel Dunbar7ded7f42008-08-15 22:20:32 +000028#include "llvm/Support/Compiler.h"
Daniel Dunbar7ded7f42008-08-15 22:20:32 +000029#include "llvm/Target/TargetData.h"
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000030#include <map>
Chris Lattnere160c9b2009-01-27 05:06:01 +000031
32
Chris Lattnerdce14062008-06-26 04:19:03 +000033using namespace clang;
Daniel Dunbar46f45b92008-09-09 01:06:48 +000034using namespace CodeGen;
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000035using llvm::dyn_cast;
36
37// The version of the runtime that this class targets. Must match the version
38// in the runtime.
39static const int RuntimeVersion = 8;
40static const int ProtocolVersion = 2;
Chris Lattner0f984262008-03-01 08:50:34 +000041
Chris Lattner0f984262008-03-01 08:50:34 +000042namespace {
Chris Lattnerdce14062008-06-26 04:19:03 +000043class CGObjCGNU : public CodeGen::CGObjCRuntime {
Chris Lattner0f984262008-03-01 08:50:34 +000044private:
Chris Lattnerdce14062008-06-26 04:19:03 +000045 CodeGen::CodeGenModule &CGM;
Chris Lattner0f984262008-03-01 08:50:34 +000046 llvm::Module &TheModule;
Chris Lattnere160c9b2009-01-27 05:06:01 +000047 const llvm::PointerType *SelectorTy;
48 const llvm::PointerType *PtrToInt8Ty;
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +000049 const llvm::FunctionType *IMPTy;
Chris Lattnere160c9b2009-01-27 05:06:01 +000050 const llvm::PointerType *IdTy;
51 const llvm::IntegerType *IntTy;
52 const llvm::PointerType *PtrTy;
53 const llvm::IntegerType *LongTy;
54 const llvm::PointerType *PtrToIntTy;
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000055 std::vector<llvm::Constant*> Classes;
56 std::vector<llvm::Constant*> Categories;
57 std::vector<llvm::Constant*> ConstantStrings;
58 llvm::Function *LoadFunction;
59 llvm::StringMap<llvm::Constant*> ExistingProtocols;
60 typedef std::pair<std::string, std::string> TypedSelector;
61 std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
62 llvm::StringMap<llvm::GlobalAlias*> UntypedSelectors;
63 // Some zeros used for GEPs in lots of places.
64 llvm::Constant *Zeros[2];
65 llvm::Constant *NULLPtr;
66private:
67 llvm::Constant *GenerateIvarList(
68 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
69 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
70 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets);
71 llvm::Constant *GenerateMethodList(const std::string &ClassName,
72 const std::string &CategoryName,
Chris Lattnera4210072008-06-26 05:08:00 +000073 const llvm::SmallVectorImpl<Selector> &MethodSels,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000074 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
75 bool isClassMethodList);
Fariborz Jahanianf8c4f542009-03-31 18:27:22 +000076 llvm::Constant *GenerateEmptyProtocol(const std::string &ProtocolName);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000077 llvm::Constant *GenerateProtocolList(
78 const llvm::SmallVectorImpl<std::string> &Protocols);
79 llvm::Constant *GenerateClassStructure(
80 llvm::Constant *MetaClass,
81 llvm::Constant *SuperClass,
82 unsigned info,
Chris Lattnerd002cc62008-06-26 04:47:04 +000083 const char *Name,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +000084 llvm::Constant *Version,
85 llvm::Constant *InstanceSize,
86 llvm::Constant *IVars,
87 llvm::Constant *Methods,
88 llvm::Constant *Protocols);
89 llvm::Constant *GenerateProtocolMethodList(
90 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames,
91 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes);
92 llvm::Constant *MakeConstantString(const std::string &Str, const std::string
93 &Name="");
94 llvm::Constant *MakeGlobal(const llvm::StructType *Ty,
95 std::vector<llvm::Constant*> &V, const std::string &Name="");
96 llvm::Constant *MakeGlobal(const llvm::ArrayType *Ty,
97 std::vector<llvm::Constant*> &V, const std::string &Name="");
Chris Lattner0f984262008-03-01 08:50:34 +000098public:
Chris Lattnerdce14062008-06-26 04:19:03 +000099 CGObjCGNU(CodeGen::CodeGenModule &cgm);
Steve Naroff33fdb732009-03-31 16:53:37 +0000100 virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000101 virtual CodeGen::RValue
102 GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000103 QualType ResultType,
104 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000105 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000106 bool IsClassMessage,
107 const CallArgList &CallArgs);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000108 virtual CodeGen::RValue
109 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000110 QualType ResultType,
111 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000112 const ObjCInterfaceDecl *Class,
Fariborz Jahanian7ce77922009-02-28 20:07:56 +0000113 bool isCategoryImpl,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000114 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000115 bool IsClassMessage,
116 const CallArgList &CallArgs);
Daniel Dunbar45d196b2008-11-01 01:53:16 +0000117 virtual llvm::Value *GetClass(CGBuilderTy &Builder,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000118 const ObjCInterfaceDecl *OID);
Daniel Dunbar45d196b2008-11-01 01:53:16 +0000119 virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel);
Chris Lattner8e67b632008-06-26 04:37:12 +0000120
Fariborz Jahanian679a5022009-01-10 21:06:09 +0000121 virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
122 const ObjCContainerDecl *CD);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000123 virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
124 virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
Daniel Dunbar45d196b2008-11-01 01:53:16 +0000125 virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000126 const ObjCProtocolDecl *PD);
127 virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000128 virtual llvm::Function *ModuleInitFunction();
Daniel Dunbar49f66022008-09-24 03:38:44 +0000129 virtual llvm::Function *GetPropertyGetFunction();
130 virtual llvm::Function *GetPropertySetFunction();
Anders Carlsson2abd89c2008-08-31 04:05:03 +0000131 virtual llvm::Function *EnumerationMutationFunction();
Anders Carlsson64d5d6c2008-09-09 10:04:29 +0000132
Fariborz Jahanianbd71be42008-11-21 00:49:24 +0000133 virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
134 const Stmt &S);
Anders Carlsson64d5d6c2008-09-09 10:04:29 +0000135 virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
136 const ObjCAtThrowStmt &S);
Fariborz Jahanian3e283e32008-11-18 22:37:34 +0000137 virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian6dc23172008-11-18 21:45:40 +0000138 llvm::Value *AddrWeakObj);
Fariborz Jahanian3e283e32008-11-18 22:37:34 +0000139 virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
140 llvm::Value *src, llvm::Value *dst);
Fariborz Jahanian58626502008-11-19 00:59:10 +0000141 virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
142 llvm::Value *src, llvm::Value *dest);
Fariborz Jahanian7eda8362008-11-20 19:23:36 +0000143 virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
144 llvm::Value *src, llvm::Value *dest);
Fariborz Jahanian58626502008-11-19 00:59:10 +0000145 virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
146 llvm::Value *src, llvm::Value *dest);
Fariborz Jahanian598d3f62009-02-03 19:03:09 +0000147 virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
148 QualType ObjectTy,
149 llvm::Value *BaseValue,
150 const ObjCIvarDecl *Ivar,
Fariborz Jahanian598d3f62009-02-03 19:03:09 +0000151 unsigned CVRQualifiers);
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +0000152 virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar2a031922009-04-22 05:08:15 +0000153 const ObjCInterfaceDecl *Interface,
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +0000154 const ObjCIvarDecl *Ivar);
Chris Lattner0f984262008-03-01 08:50:34 +0000155};
156} // end anonymous namespace
157
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000158
159
160static std::string SymbolNameForClass(const std::string &ClassName) {
161 return ".objc_class_" + ClassName;
162}
163
164static std::string SymbolNameForMethod(const std::string &ClassName, const
165 std::string &CategoryName, const std::string &MethodName, bool isClassMethod)
166{
167 return "._objc_method_" + ClassName +"("+CategoryName+")"+
168 (isClassMethod ? "+" : "-") + MethodName;
169}
170
Chris Lattnerdce14062008-06-26 04:19:03 +0000171CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm)
172 : CGM(cgm), TheModule(CGM.getModule()) {
Chris Lattnere160c9b2009-01-27 05:06:01 +0000173 IntTy = cast<llvm::IntegerType>(
174 CGM.getTypes().ConvertType(CGM.getContext().IntTy));
175 LongTy = cast<llvm::IntegerType>(
176 CGM.getTypes().ConvertType(CGM.getContext().LongTy));
Chris Lattnerdce14062008-06-26 04:19:03 +0000177
Sebastian Redl3a5013c2008-12-04 00:10:55 +0000178 Zeros[0] = llvm::ConstantInt::get(LongTy, 0);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000179 Zeros[1] = Zeros[0];
180 NULLPtr = llvm::ConstantPointerNull::get(
181 llvm::PointerType::getUnqual(llvm::Type::Int8Ty));
Chris Lattner391d77a2008-03-30 23:03:07 +0000182 // C string type. Used in lots of places.
183 PtrToInt8Ty =
184 llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
185 // Get the selector Type.
Chris Lattnere160c9b2009-01-27 05:06:01 +0000186 SelectorTy = cast<llvm::PointerType>(
187 CGM.getTypes().ConvertType(CGM.getContext().getObjCSelType()));
188
Chris Lattner391d77a2008-03-30 23:03:07 +0000189 PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
190 PtrTy = PtrToInt8Ty;
191
192 // Object type
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +0000193 IdTy = cast<llvm::PointerType>(
194 CGM.getTypes().ConvertType(CGM.getContext().getObjCIdType()));
Chris Lattner391d77a2008-03-30 23:03:07 +0000195
196 // IMP type
197 std::vector<const llvm::Type*> IMPArgs;
198 IMPArgs.push_back(IdTy);
199 IMPArgs.push_back(SelectorTy);
200 IMPTy = llvm::FunctionType::get(IdTy, IMPArgs, true);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000201}
202// This has to perform the lookup every time, since posing and related
203// techniques can modify the name -> class mapping.
Daniel Dunbar45d196b2008-11-01 01:53:16 +0000204llvm::Value *CGObjCGNU::GetClass(CGBuilderTy &Builder,
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000205 const ObjCInterfaceDecl *OID) {
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000206 llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString());
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +0000207 ClassName = Builder.CreateStructGEP(ClassName, 0);
208
Fariborz Jahanian26c82942009-03-30 18:02:14 +0000209 std::vector<const llvm::Type*> Params(1, PtrToInt8Ty);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000210 llvm::Constant *ClassLookupFn =
Fariborz Jahanian26c82942009-03-30 18:02:14 +0000211 CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy,
212 Params,
213 true),
214 "objc_lookup_class");
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000215 return Builder.CreateCall(ClassLookupFn, ClassName);
Chris Lattner391d77a2008-03-30 23:03:07 +0000216}
217
Chris Lattner8e67b632008-06-26 04:37:12 +0000218/// GetSelector - Return the pointer to the unique'd string for this selector.
Daniel Dunbar45d196b2008-11-01 01:53:16 +0000219llvm::Value *CGObjCGNU::GetSelector(CGBuilderTy &Builder, Selector Sel) {
Chris Lattner8e67b632008-06-26 04:37:12 +0000220 // FIXME: uniquing on the string is wasteful, unique on Sel instead!
Chris Lattner077bf5e2008-11-24 03:33:13 +0000221 llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
Chris Lattner8e67b632008-06-26 04:37:12 +0000222 if (US == 0)
223 US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
224 llvm::GlobalValue::InternalLinkage,
225 ".objc_untyped_selector_alias",
226 NULL, &TheModule);
227
228 return Builder.CreateLoad(US);
229
230}
231
Chris Lattner5e7dcc62008-06-26 04:44:19 +0000232llvm::Constant *CGObjCGNU::MakeConstantString(const std::string &Str,
233 const std::string &Name) {
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000234 llvm::Constant * ConstStr = llvm::ConstantArray::get(Str);
235 ConstStr = new llvm::GlobalVariable(ConstStr->getType(), true,
236 llvm::GlobalValue::InternalLinkage,
237 ConstStr, Name, &TheModule);
238 return llvm::ConstantExpr::getGetElementPtr(ConstStr, Zeros, 2);
239}
240llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::StructType *Ty,
241 std::vector<llvm::Constant*> &V, const std::string &Name) {
242 llvm::Constant *C = llvm::ConstantStruct::get(Ty, V);
243 return new llvm::GlobalVariable(Ty, false,
244 llvm::GlobalValue::InternalLinkage, C, Name, &TheModule);
245}
246llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty,
247 std::vector<llvm::Constant*> &V, const std::string &Name) {
248 llvm::Constant *C = llvm::ConstantArray::get(Ty, V);
249 return new llvm::GlobalVariable(Ty, false,
250 llvm::GlobalValue::InternalLinkage, C, Name, &TheModule);
251}
252
253/// Generate an NSConstantString object.
254//TODO: In case there are any crazy people still using the GNU runtime without
255//an OpenStep implementation, this should let them select their own class for
256//constant strings.
Steve Naroff33fdb732009-03-31 16:53:37 +0000257llvm::Constant *CGObjCGNU::GenerateConstantString(const ObjCStringLiteral *SL) {
258 std::string Str(SL->getString()->getStrData(),
259 SL->getString()->getByteLength());
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000260 std::vector<llvm::Constant*> Ivars;
261 Ivars.push_back(NULLPtr);
Chris Lattner13fd7e52008-06-21 21:44:18 +0000262 Ivars.push_back(MakeConstantString(Str));
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000263 Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000264 llvm::Constant *ObjCStr = MakeGlobal(
265 llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy, NULL),
266 Ivars, ".objc_str");
267 ConstantStrings.push_back(
268 llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty));
269 return ObjCStr;
270}
271
272///Generates a message send where the super is the receiver. This is a message
273///send to self with special delivery semantics indicating which class's method
274///should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000275CodeGen::RValue
276CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000277 QualType ResultType,
278 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000279 const ObjCInterfaceDecl *Class,
Fariborz Jahanian7ce77922009-02-28 20:07:56 +0000280 bool isCategoryImpl,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000281 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000282 bool IsClassMessage,
283 const CallArgList &CallArgs) {
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +0000284 llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
285
286 CallArgList ActualArgs;
287
288 ActualArgs.push_back(
289 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
290 CGF.getContext().getObjCIdType()));
291 ActualArgs.push_back(std::make_pair(RValue::get(cmd),
292 CGF.getContext().getObjCSelType()));
293 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
294
295 CodeGenTypes &Types = CGM.getTypes();
296 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
297 const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false);
298
299
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000300 const ObjCInterfaceDecl *SuperClass = Class->getSuperClass();
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000301 // TODO: This should be cached, not looked up every time.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000302 llvm::Value *ReceiverClass = GetClass(CGF.Builder, SuperClass);
Chris Lattner71238f62009-04-25 23:19:45 +0000303 if (IsClassMessage)
304 {
305 ReceiverClass = CGF.Builder.CreateBitCast(ReceiverClass,
306 llvm::PointerType::getUnqual(IdTy));
307 ReceiverClass = CGF.Builder.CreateBitCast(CGF.Builder.CreateLoad(
308 ReceiverClass), IdTy);
309 }
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000310 // Construct the structure used to look up the IMP
311 llvm::StructType *ObjCSuperTy = llvm::StructType::get(Receiver->getType(),
312 IdTy, NULL);
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000313 llvm::Value *ObjCSuper = CGF.Builder.CreateAlloca(ObjCSuperTy);
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +0000314
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000315 CGF.Builder.CreateStore(Receiver, CGF.Builder.CreateStructGEP(ObjCSuper, 0));
316 CGF.Builder.CreateStore(ReceiverClass, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000317
318 // Get the IMP
Fariborz Jahanian26c82942009-03-30 18:02:14 +0000319 std::vector<const llvm::Type*> Params;
320 Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy));
321 Params.push_back(SelectorTy);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000322 llvm::Constant *lookupFunction =
Fariborz Jahanian26c82942009-03-30 18:02:14 +0000323 CGM.CreateRuntimeFunction(llvm::FunctionType::get(
324 llvm::PointerType::getUnqual(impType), Params, true),
325 "objc_msg_lookup_super");
326
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000327 llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000328 llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000329 lookupArgs+2);
330
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +0000331 return CGF.EmitCall(FnInfo, imp, ActualArgs);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000332}
333
334/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000335CodeGen::RValue
336CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000337 QualType ResultType,
338 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +0000339 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000340 bool IsClassMessage,
341 const CallArgList &CallArgs) {
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +0000342 llvm::Value *cmd = GetSelector(CGF.Builder, Sel);
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +0000343 CallArgList ActualArgs;
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000344
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +0000345 ActualArgs.push_back(
346 std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
347 CGF.getContext().getObjCIdType()));
348 ActualArgs.push_back(std::make_pair(RValue::get(cmd),
349 CGF.getContext().getObjCSelType()));
350 ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
351
352 CodeGenTypes &Types = CGM.getTypes();
353 const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
354 const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false);
355
Fariborz Jahanian26c82942009-03-30 18:02:14 +0000356 std::vector<const llvm::Type*> Params;
357 Params.push_back(Receiver->getType());
358 Params.push_back(SelectorTy);
Chris Lattner0f984262008-03-01 08:50:34 +0000359 llvm::Constant *lookupFunction =
Fariborz Jahanian26c82942009-03-30 18:02:14 +0000360 CGM.CreateRuntimeFunction(llvm::FunctionType::get(
361 llvm::PointerType::getUnqual(impType), Params, true),
362 "objc_msg_lookup");
363
Daniel Dunbar8f2926b2008-08-23 03:46:30 +0000364 llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
Chris Lattner3eae03e2008-05-06 00:56:42 +0000365
Fariborz Jahanianb3716ef2009-02-04 20:31:19 +0000366 return CGF.EmitCall(FnInfo, imp, ActualArgs);
Chris Lattner0f984262008-03-01 08:50:34 +0000367}
368
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000369/// Generates a MethodList. Used in construction of a objc_class and
370/// objc_category structures.
371llvm::Constant *CGObjCGNU::GenerateMethodList(const std::string &ClassName,
Chris Lattnera4210072008-06-26 05:08:00 +0000372 const std::string &CategoryName,
373 const llvm::SmallVectorImpl<Selector> &MethodSels,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000374 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
375 bool isClassMethodList) {
376 // Get the method structure type.
377 llvm::StructType *ObjCMethodTy = llvm::StructType::get(
378 PtrToInt8Ty, // Really a selector, but the runtime creates it us.
379 PtrToInt8Ty, // Method types
380 llvm::PointerType::getUnqual(IMPTy), //Method pointer
381 NULL);
382 std::vector<llvm::Constant*> Methods;
383 std::vector<llvm::Constant*> Elements;
384 for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
385 Elements.clear();
Chris Lattner077bf5e2008-11-24 03:33:13 +0000386 llvm::Constant *C =
387 CGM.GetAddrOfConstantCString(MethodSels[i].getAsString());
Chris Lattnera4210072008-06-26 05:08:00 +0000388 Elements.push_back(llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000389 Elements.push_back(
390 llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
391 llvm::Constant *Method =
392 TheModule.getFunction(SymbolNameForMethod(ClassName, CategoryName,
Chris Lattner077bf5e2008-11-24 03:33:13 +0000393 MethodSels[i].getAsString(),
Chris Lattner550b8db2008-06-26 04:05:20 +0000394 isClassMethodList));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000395 Method = llvm::ConstantExpr::getBitCast(Method,
396 llvm::PointerType::getUnqual(IMPTy));
397 Elements.push_back(Method);
398 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodTy, Elements));
399 }
400
401 // Array of method structures
402 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodTy,
Chris Lattnera4210072008-06-26 05:08:00 +0000403 MethodSels.size());
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000404 llvm::Constant *MethodArray = llvm::ConstantArray::get(ObjCMethodArrayTy,
Chris Lattnerfba67632008-06-26 04:52:29 +0000405 Methods);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000406
407 // Structure containing list pointer, array and array count
408 llvm::SmallVector<const llvm::Type*, 16> ObjCMethodListFields;
409 llvm::PATypeHolder OpaqueNextTy = llvm::OpaqueType::get();
410 llvm::Type *NextPtrTy = llvm::PointerType::getUnqual(OpaqueNextTy);
411 llvm::StructType *ObjCMethodListTy = llvm::StructType::get(NextPtrTy,
412 IntTy,
413 ObjCMethodArrayTy,
414 NULL);
415 // Refine next pointer type to concrete type
416 llvm::cast<llvm::OpaqueType>(
417 OpaqueNextTy.get())->refineAbstractTypeTo(ObjCMethodListTy);
418 ObjCMethodListTy = llvm::cast<llvm::StructType>(OpaqueNextTy.get());
419
420 Methods.clear();
421 Methods.push_back(llvm::ConstantPointerNull::get(
422 llvm::PointerType::getUnqual(ObjCMethodListTy)));
423 Methods.push_back(llvm::ConstantInt::get(llvm::Type::Int32Ty,
424 MethodTypes.size()));
425 Methods.push_back(MethodArray);
426
427 // Create an instance of the structure
428 return MakeGlobal(ObjCMethodListTy, Methods, ".objc_method_list");
429}
430
431/// Generates an IvarList. Used in construction of a objc_class.
432llvm::Constant *CGObjCGNU::GenerateIvarList(
433 const llvm::SmallVectorImpl<llvm::Constant *> &IvarNames,
434 const llvm::SmallVectorImpl<llvm::Constant *> &IvarTypes,
435 const llvm::SmallVectorImpl<llvm::Constant *> &IvarOffsets) {
436 // Get the method structure type.
437 llvm::StructType *ObjCIvarTy = llvm::StructType::get(
438 PtrToInt8Ty,
439 PtrToInt8Ty,
440 IntTy,
441 NULL);
442 std::vector<llvm::Constant*> Ivars;
443 std::vector<llvm::Constant*> Elements;
444 for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
445 Elements.clear();
446 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarNames[i],
447 Zeros, 2));
448 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(IvarTypes[i],
449 Zeros, 2));
450 Elements.push_back(IvarOffsets[i]);
451 Ivars.push_back(llvm::ConstantStruct::get(ObjCIvarTy, Elements));
452 }
453
454 // Array of method structures
455 llvm::ArrayType *ObjCIvarArrayTy = llvm::ArrayType::get(ObjCIvarTy,
456 IvarNames.size());
457
458
459 Elements.clear();
Chris Lattnere160c9b2009-01-27 05:06:01 +0000460 Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size()));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000461 Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars));
462 // Structure containing array and array count
463 llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
464 ObjCIvarArrayTy,
465 NULL);
466
467 // Create an instance of the structure
468 return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list");
469}
470
471/// Generate a class structure
472llvm::Constant *CGObjCGNU::GenerateClassStructure(
473 llvm::Constant *MetaClass,
474 llvm::Constant *SuperClass,
475 unsigned info,
Chris Lattnerd002cc62008-06-26 04:47:04 +0000476 const char *Name,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000477 llvm::Constant *Version,
478 llvm::Constant *InstanceSize,
479 llvm::Constant *IVars,
480 llvm::Constant *Methods,
481 llvm::Constant *Protocols) {
482 // Set up the class structure
483 // Note: Several of these are char*s when they should be ids. This is
484 // because the runtime performs this translation on load.
485 llvm::StructType *ClassTy = llvm::StructType::get(
486 PtrToInt8Ty, // class_pointer
487 PtrToInt8Ty, // super_class
488 PtrToInt8Ty, // name
489 LongTy, // version
490 LongTy, // info
491 LongTy, // instance_size
492 IVars->getType(), // ivars
493 Methods->getType(), // methods
494 // These are all filled in by the runtime, so we pretend
495 PtrTy, // dtable
496 PtrTy, // subclass_list
497 PtrTy, // sibling_class
498 PtrTy, // protocols
499 PtrTy, // gc_object_type
500 NULL);
501 llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
502 llvm::Constant *NullP =
Chris Lattnere160c9b2009-01-27 05:06:01 +0000503 llvm::ConstantPointerNull::get(PtrTy);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000504 // Fill in the structure
505 std::vector<llvm::Constant*> Elements;
506 Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty));
507 Elements.push_back(SuperClass);
Chris Lattnerd002cc62008-06-26 04:47:04 +0000508 Elements.push_back(MakeConstantString(Name, ".class_name"));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000509 Elements.push_back(Zero);
510 Elements.push_back(llvm::ConstantInt::get(LongTy, info));
511 Elements.push_back(InstanceSize);
512 Elements.push_back(IVars);
513 Elements.push_back(Methods);
514 Elements.push_back(NullP);
515 Elements.push_back(NullP);
516 Elements.push_back(NullP);
517 Elements.push_back(llvm::ConstantExpr::getBitCast(Protocols, PtrTy));
518 Elements.push_back(NullP);
519 // Create an instance of the structure
Chris Lattner1565e032008-07-21 06:31:05 +0000520 return MakeGlobal(ClassTy, Elements, SymbolNameForClass(Name));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000521}
522
523llvm::Constant *CGObjCGNU::GenerateProtocolMethodList(
524 const llvm::SmallVectorImpl<llvm::Constant *> &MethodNames,
525 const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes) {
526 // Get the method structure type.
527 llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
528 PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
529 PtrToInt8Ty,
530 NULL);
531 std::vector<llvm::Constant*> Methods;
532 std::vector<llvm::Constant*> Elements;
533 for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
534 Elements.clear();
535 Elements.push_back( llvm::ConstantExpr::getGetElementPtr(MethodNames[i],
536 Zeros, 2));
537 Elements.push_back(
538 llvm::ConstantExpr::getGetElementPtr(MethodTypes[i], Zeros, 2));
539 Methods.push_back(llvm::ConstantStruct::get(ObjCMethodDescTy, Elements));
540 }
541 llvm::ArrayType *ObjCMethodArrayTy = llvm::ArrayType::get(ObjCMethodDescTy,
542 MethodNames.size());
543 llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy, Methods);
544 llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
545 IntTy, ObjCMethodArrayTy, NULL);
546 Methods.clear();
547 Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
548 Methods.push_back(Array);
549 return MakeGlobal(ObjCMethodDescListTy, Methods, ".objc_method_list");
550}
551// Create the protocol list structure used in classes, categories and so on
552llvm::Constant *CGObjCGNU::GenerateProtocolList(
553 const llvm::SmallVectorImpl<std::string> &Protocols) {
554 llvm::ArrayType *ProtocolArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
555 Protocols.size());
556 llvm::StructType *ProtocolListTy = llvm::StructType::get(
557 PtrTy, //Should be a recurisve pointer, but it's always NULL here.
558 LongTy,//FIXME: Should be size_t
559 ProtocolArrayTy,
560 NULL);
561 std::vector<llvm::Constant*> Elements;
562 for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
563 iter != endIter ; iter++) {
Fariborz Jahanianf8c4f542009-03-31 18:27:22 +0000564 llvm::Constant *protocol = ExistingProtocols[*iter];
565 if (!protocol)
566 protocol = GenerateEmptyProtocol(*iter);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000567 llvm::Constant *Ptr =
Fariborz Jahanianf8c4f542009-03-31 18:27:22 +0000568 llvm::ConstantExpr::getBitCast(protocol, PtrToInt8Ty);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000569 Elements.push_back(Ptr);
570 }
571 llvm::Constant * ProtocolArray = llvm::ConstantArray::get(ProtocolArrayTy,
572 Elements);
573 Elements.clear();
574 Elements.push_back(NULLPtr);
Chris Lattnere160c9b2009-01-27 05:06:01 +0000575 Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size()));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000576 Elements.push_back(ProtocolArray);
577 return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list");
578}
579
Daniel Dunbar45d196b2008-11-01 01:53:16 +0000580llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000581 const ObjCProtocolDecl *PD) {
Fariborz Jahanianf8c4f542009-03-31 18:27:22 +0000582 llvm::Value *protocol = ExistingProtocols[PD->getNameAsString()];
583 const llvm::Type *T =
584 CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
585 return Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
586}
587
588llvm::Constant *CGObjCGNU::GenerateEmptyProtocol(
589 const std::string &ProtocolName) {
590 llvm::SmallVector<std::string, 0> EmptyStringVector;
591 llvm::SmallVector<llvm::Constant*, 0> EmptyConstantVector;
592
593 llvm::Constant *ProtocolList = GenerateProtocolList(EmptyStringVector);
594 llvm::Constant *InstanceMethodList =
595 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
596 llvm::Constant *ClassMethodList =
597 GenerateProtocolMethodList(EmptyConstantVector, EmptyConstantVector);
598 // Protocols are objects containing lists of the methods implemented and
599 // protocols adopted.
600 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
601 PtrToInt8Ty,
602 ProtocolList->getType(),
603 InstanceMethodList->getType(),
604 ClassMethodList->getType(),
605 NULL);
606 std::vector<llvm::Constant*> Elements;
607 // The isa pointer must be set to a magic number so the runtime knows it's
608 // the correct layout.
609 Elements.push_back(llvm::ConstantExpr::getIntToPtr(
610 llvm::ConstantInt::get(llvm::Type::Int32Ty, ProtocolVersion), IdTy));
611 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
612 Elements.push_back(ProtocolList);
613 Elements.push_back(InstanceMethodList);
614 Elements.push_back(ClassMethodList);
615 return MakeGlobal(ProtocolTy, Elements, ".objc_protocol");
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000616}
617
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000618void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
619 ASTContext &Context = CGM.getContext();
Chris Lattner8ec03f52008-11-24 03:54:41 +0000620 std::string ProtocolName = PD->getNameAsString();
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000621 llvm::SmallVector<std::string, 16> Protocols;
622 for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
623 E = PD->protocol_end(); PI != E; ++PI)
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000624 Protocols.push_back((*PI)->getNameAsString());
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000625 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
626 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
Douglas Gregor6ab35242009-04-09 21:40:53 +0000627 for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(Context),
628 E = PD->instmeth_end(Context); iter != E; iter++) {
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000629 std::string TypeStr;
630 Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
631 InstanceMethodNames.push_back(
Chris Lattner077bf5e2008-11-24 03:33:13 +0000632 CGM.GetAddrOfConstantCString((*iter)->getSelector().getAsString()));
Daniel Dunbar61432932008-08-13 23:20:05 +0000633 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000634 }
635 // Collect information about class methods:
636 llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
637 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
Douglas Gregor6ab35242009-04-09 21:40:53 +0000638 for (ObjCProtocolDecl::classmeth_iterator
639 iter = PD->classmeth_begin(Context),
640 endIter = PD->classmeth_end(Context) ; iter != endIter ; iter++) {
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000641 std::string TypeStr;
642 Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
643 ClassMethodNames.push_back(
Chris Lattner077bf5e2008-11-24 03:33:13 +0000644 CGM.GetAddrOfConstantCString((*iter)->getSelector().getAsString()));
Daniel Dunbar61432932008-08-13 23:20:05 +0000645 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +0000646 }
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000647
648 llvm::Constant *ProtocolList = GenerateProtocolList(Protocols);
649 llvm::Constant *InstanceMethodList =
650 GenerateProtocolMethodList(InstanceMethodNames, InstanceMethodTypes);
651 llvm::Constant *ClassMethodList =
652 GenerateProtocolMethodList(ClassMethodNames, ClassMethodTypes);
653 // Protocols are objects containing lists of the methods implemented and
654 // protocols adopted.
655 llvm::StructType *ProtocolTy = llvm::StructType::get(IdTy,
656 PtrToInt8Ty,
657 ProtocolList->getType(),
658 InstanceMethodList->getType(),
659 ClassMethodList->getType(),
660 NULL);
661 std::vector<llvm::Constant*> Elements;
662 // The isa pointer must be set to a magic number so the runtime knows it's
663 // the correct layout.
664 Elements.push_back(llvm::ConstantExpr::getIntToPtr(
665 llvm::ConstantInt::get(llvm::Type::Int32Ty, ProtocolVersion), IdTy));
666 Elements.push_back(MakeConstantString(ProtocolName, ".objc_protocol_name"));
667 Elements.push_back(ProtocolList);
668 Elements.push_back(InstanceMethodList);
669 Elements.push_back(ClassMethodList);
670 ExistingProtocols[ProtocolName] =
671 llvm::ConstantExpr::getBitCast(MakeGlobal(ProtocolTy, Elements,
672 ".objc_protocol"), IdTy);
673}
674
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000675void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Chris Lattner8ec03f52008-11-24 03:54:41 +0000676 std::string ClassName = OCD->getClassInterface()->getNameAsString();
677 std::string CategoryName = OCD->getNameAsString();
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000678 // Collect information about instance methods
679 llvm::SmallVector<Selector, 16> InstanceMethodSels;
680 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
Douglas Gregor653f1b12009-04-23 01:02:12 +0000681 for (ObjCCategoryImplDecl::instmeth_iterator
682 iter = OCD->instmeth_begin(CGM.getContext()),
683 endIter = OCD->instmeth_end(CGM.getContext());
684 iter != endIter ; iter++) {
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000685 InstanceMethodSels.push_back((*iter)->getSelector());
686 std::string TypeStr;
687 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
688 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
689 }
690
691 // Collect information about class methods
692 llvm::SmallVector<Selector, 16> ClassMethodSels;
693 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
Douglas Gregor653f1b12009-04-23 01:02:12 +0000694 for (ObjCCategoryImplDecl::classmeth_iterator
695 iter = OCD->classmeth_begin(CGM.getContext()),
696 endIter = OCD->classmeth_end(CGM.getContext());
697 iter != endIter ; iter++) {
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000698 ClassMethodSels.push_back((*iter)->getSelector());
699 std::string TypeStr;
700 CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
701 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
702 }
703
704 // Collect the names of referenced protocols
705 llvm::SmallVector<std::string, 16> Protocols;
706 const ObjCInterfaceDecl *ClassDecl = OCD->getClassInterface();
707 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
708 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
709 E = Protos.end(); I != E; ++I)
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000710 Protocols.push_back((*I)->getNameAsString());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000711
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000712 std::vector<llvm::Constant*> Elements;
713 Elements.push_back(MakeConstantString(CategoryName));
714 Elements.push_back(MakeConstantString(ClassName));
715 // Instance method list
716 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
Chris Lattnera4210072008-06-26 05:08:00 +0000717 ClassName, CategoryName, InstanceMethodSels, InstanceMethodTypes,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000718 false), PtrTy));
719 // Class method list
720 Elements.push_back(llvm::ConstantExpr::getBitCast(GenerateMethodList(
Chris Lattnera4210072008-06-26 05:08:00 +0000721 ClassName, CategoryName, ClassMethodSels, ClassMethodTypes, true),
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000722 PtrTy));
723 // Protocol list
724 Elements.push_back(llvm::ConstantExpr::getBitCast(
725 GenerateProtocolList(Protocols), PtrTy));
726 Categories.push_back(llvm::ConstantExpr::getBitCast(
727 MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, PtrTy,
728 PtrTy, PtrTy, NULL), Elements), PtrTy));
729}
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000730
731void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
732 ASTContext &Context = CGM.getContext();
733
734 // Get the superclass name.
735 const ObjCInterfaceDecl * SuperClassDecl =
736 OID->getClassInterface()->getSuperClass();
Chris Lattner8ec03f52008-11-24 03:54:41 +0000737 std::string SuperClassName;
738 if (SuperClassDecl)
739 SuperClassName = SuperClassDecl->getNameAsString();
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000740
741 // Get the class name
Chris Lattner09dc6662009-04-01 02:00:48 +0000742 ObjCInterfaceDecl *ClassDecl =
743 const_cast<ObjCInterfaceDecl *>(OID->getClassInterface());
Chris Lattner8ec03f52008-11-24 03:54:41 +0000744 std::string ClassName = ClassDecl->getNameAsString();
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000745
Daniel Dunbar2bebbf02009-05-03 10:46:44 +0000746 // Get the size of instances.
747 int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000748
749 // Collect information about instance variables.
750 llvm::SmallVector<llvm::Constant*, 16> IvarNames;
751 llvm::SmallVector<llvm::Constant*, 16> IvarTypes;
752 llvm::SmallVector<llvm::Constant*, 16> IvarOffsets;
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000753 for (ObjCInterfaceDecl::ivar_iterator iter = ClassDecl->ivar_begin(),
754 endIter = ClassDecl->ivar_end() ; iter != endIter ; iter++) {
755 // Store the name
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000756 IvarNames.push_back(CGM.GetAddrOfConstantCString((*iter)
757 ->getNameAsString()));
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000758 // Get the type encoding for this ivar
759 std::string TypeStr;
Daniel Dunbar0d504c12008-10-17 20:21:44 +0000760 Context.getObjCEncodingForType((*iter)->getType(), TypeStr);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000761 IvarTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
762 // Get the offset
Daniel Dunbarc8cbf192009-04-22 08:20:31 +0000763 uint64_t Offset = ComputeIvarBaseOffset(CGM, ClassDecl, *iter);
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000764 IvarOffsets.push_back(
Daniel Dunbarc8cbf192009-04-22 08:20:31 +0000765 llvm::ConstantInt::get(llvm::Type::Int32Ty, Offset));
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000766 }
767
768 // Collect information about instance methods
769 llvm::SmallVector<Selector, 16> InstanceMethodSels;
770 llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
Douglas Gregor653f1b12009-04-23 01:02:12 +0000771 for (ObjCImplementationDecl::instmeth_iterator
772 iter = OID->instmeth_begin(CGM.getContext()),
773 endIter = OID->instmeth_end(CGM.getContext());
774 iter != endIter ; iter++) {
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000775 InstanceMethodSels.push_back((*iter)->getSelector());
776 std::string TypeStr;
777 Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
778 InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
779 }
780
781 // Collect information about class methods
782 llvm::SmallVector<Selector, 16> ClassMethodSels;
783 llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
Douglas Gregor653f1b12009-04-23 01:02:12 +0000784 for (ObjCImplementationDecl::classmeth_iterator
785 iter = OID->classmeth_begin(CGM.getContext()),
786 endIter = OID->classmeth_end(CGM.getContext());
787 iter != endIter ; iter++) {
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000788 ClassMethodSels.push_back((*iter)->getSelector());
789 std::string TypeStr;
790 Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
791 ClassMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
792 }
793 // Collect the names of referenced protocols
794 llvm::SmallVector<std::string, 16> Protocols;
795 const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
796 for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
797 E = Protos.end(); I != E; ++I)
Chris Lattnerd9d22dd2008-11-24 05:29:24 +0000798 Protocols.push_back((*I)->getNameAsString());
Daniel Dunbar7ded7f42008-08-15 22:20:32 +0000799
800
801
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000802 // Get the superclass pointer.
803 llvm::Constant *SuperClass;
Chris Lattner8ec03f52008-11-24 03:54:41 +0000804 if (!SuperClassName.empty()) {
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000805 SuperClass = MakeConstantString(SuperClassName, ".super_class_name");
806 } else {
Chris Lattnere160c9b2009-01-27 05:06:01 +0000807 SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000808 }
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000809 // Empty vector used to construct empty method lists
810 llvm::SmallVector<llvm::Constant*, 1> empty;
811 // Generate the method and instance variable lists
812 llvm::Constant *MethodList = GenerateMethodList(ClassName, "",
Chris Lattnera4210072008-06-26 05:08:00 +0000813 InstanceMethodSels, InstanceMethodTypes, false);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000814 llvm::Constant *ClassMethodList = GenerateMethodList(ClassName, "",
Chris Lattnera4210072008-06-26 05:08:00 +0000815 ClassMethodSels, ClassMethodTypes, true);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000816 llvm::Constant *IvarList = GenerateIvarList(IvarNames, IvarTypes,
817 IvarOffsets);
818 //Generate metaclass for class methods
819 llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
Chris Lattner1565e032008-07-21 06:31:05 +0000820 NULLPtr, 0x2L, /*name*/"", 0, Zeros[0], GenerateIvarList(
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000821 empty, empty, empty), ClassMethodList, NULLPtr);
822 // Generate the class structure
Chris Lattner8ec03f52008-11-24 03:54:41 +0000823 llvm::Constant *ClassStruct =
824 GenerateClassStructure(MetaClassStruct, SuperClass, 0x1L,
825 ClassName.c_str(), 0,
Sebastian Redl3a5013c2008-12-04 00:10:55 +0000826 llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000827 MethodList, GenerateProtocolList(Protocols));
828 // Add class structure to list to be added to the symtab later
829 ClassStruct = llvm::ConstantExpr::getBitCast(ClassStruct, PtrToInt8Ty);
830 Classes.push_back(ClassStruct);
831}
832
833llvm::Function *CGObjCGNU::ModuleInitFunction() {
834 // Only emit an ObjC load function if no Objective-C stuff has been called
835 if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
836 ExistingProtocols.empty() && TypedSelectors.empty() &&
Anton Korobeynikov5f58b912008-06-01 15:14:46 +0000837 UntypedSelectors.empty())
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000838 return NULL;
Eli Friedman1b8956e2008-06-01 16:00:02 +0000839
Chris Lattnere160c9b2009-01-27 05:06:01 +0000840 const llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
841 SelectorTy->getElementType());
842 const llvm::Type *SelStructPtrTy = SelectorTy;
843 bool isSelOpaque = false;
844 if (SelStructTy == 0) {
845 SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, NULL);
846 SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
847 isSelOpaque = true;
848 }
849
Eli Friedman1b8956e2008-06-01 16:00:02 +0000850 // Name the ObjC types to make the IR a bit easier to read
Chris Lattnere160c9b2009-01-27 05:06:01 +0000851 TheModule.addTypeName(".objc_selector", SelStructPtrTy);
Eli Friedman1b8956e2008-06-01 16:00:02 +0000852 TheModule.addTypeName(".objc_id", IdTy);
853 TheModule.addTypeName(".objc_imp", IMPTy);
854
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000855 std::vector<llvm::Constant*> Elements;
Chris Lattner71238f62009-04-25 23:19:45 +0000856 llvm::Constant *Statics = NULLPtr;
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000857 // Generate statics list:
Chris Lattner71238f62009-04-25 23:19:45 +0000858 if (ConstantStrings.size()) {
859 llvm::ArrayType *StaticsArrayTy = llvm::ArrayType::get(PtrToInt8Ty,
860 ConstantStrings.size() + 1);
861 ConstantStrings.push_back(NULLPtr);
862 Elements.push_back(MakeConstantString("NSConstantString",
863 ".objc_static_class_name"));
864 Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
865 ConstantStrings));
866 llvm::StructType *StaticsListTy =
867 llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL);
868 llvm::Type *StaticsListPtrTy = llvm::PointerType::getUnqual(StaticsListTy);
869 Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics");
870 llvm::ArrayType *StaticsListArrayTy =
871 llvm::ArrayType::get(StaticsListPtrTy, 2);
872 Elements.clear();
873 Elements.push_back(Statics);
874 Elements.push_back(llvm::Constant::getNullValue(StaticsListPtrTy));
875 Statics = MakeGlobal(StaticsListArrayTy, Elements, ".objc_statics_ptr");
876 Statics = llvm::ConstantExpr::getBitCast(Statics, PtrTy);
877 }
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000878 // Array of classes, categories, and constant objects
879 llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty,
880 Classes.size() + Categories.size() + 2);
Chris Lattnere160c9b2009-01-27 05:06:01 +0000881 llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy,
Chris Lattner630404b2008-06-26 04:10:42 +0000882 llvm::Type::Int16Ty,
883 llvm::Type::Int16Ty,
884 ClassListTy, NULL);
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000885
886 Elements.clear();
887 // Pointer to an array of selectors used in this module.
888 std::vector<llvm::Constant*> Selectors;
889 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
890 iter = TypedSelectors.begin(), iterEnd = TypedSelectors.end();
891 iter != iterEnd ; ++iter) {
Chris Lattner630404b2008-06-26 04:10:42 +0000892 Elements.push_back(MakeConstantString(iter->first.first, ".objc_sel_name"));
893 Elements.push_back(MakeConstantString(iter->first.second,
894 ".objc_sel_types"));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000895 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
896 Elements.clear();
897 }
898 for (llvm::StringMap<llvm::GlobalAlias*>::iterator
899 iter = UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
Chris Lattner630404b2008-06-26 04:10:42 +0000900 iter != iterEnd; ++iter) {
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000901 Elements.push_back(
Chris Lattner630404b2008-06-26 04:10:42 +0000902 MakeConstantString(iter->getKeyData(), ".objc_sel_name"));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000903 Elements.push_back(NULLPtr);
904 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
905 Elements.clear();
906 }
907 Elements.push_back(NULLPtr);
908 Elements.push_back(NULLPtr);
909 Selectors.push_back(llvm::ConstantStruct::get(SelStructTy, Elements));
910 Elements.clear();
911 // Number of static selectors
912 Elements.push_back(llvm::ConstantInt::get(LongTy, Selectors.size() ));
913 llvm::Constant *SelectorList = MakeGlobal(
914 llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors,
915 ".objc_selector_list");
Chris Lattnere160c9b2009-01-27 05:06:01 +0000916 Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList,
917 SelStructPtrTy));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000918
919 // Now that all of the static selectors exist, create pointers to them.
920 int index = 0;
921 for (std::map<TypedSelector, llvm::GlobalAlias*>::iterator
922 iter=TypedSelectors.begin(), iterEnd =TypedSelectors.end();
923 iter != iterEnd; ++iter) {
924 llvm::Constant *Idxs[] = {Zeros[0],
925 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]};
Chris Lattnere160c9b2009-01-27 05:06:01 +0000926 llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy,
927 true, llvm::GlobalValue::InternalLinkage,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000928 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
929 ".objc_sel_ptr", &TheModule);
Chris Lattnere160c9b2009-01-27 05:06:01 +0000930 // If selectors are defined as an opaque type, cast the pointer to this
931 // type.
932 if (isSelOpaque) {
933 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
934 llvm::PointerType::getUnqual(SelectorTy));
935 }
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000936 (*iter).second->setAliasee(SelPtr);
937 }
938 for (llvm::StringMap<llvm::GlobalAlias*>::iterator
939 iter=UntypedSelectors.begin(), iterEnd = UntypedSelectors.end();
940 iter != iterEnd; iter++) {
941 llvm::Constant *Idxs[] = {Zeros[0],
942 llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]};
Chris Lattnere160c9b2009-01-27 05:06:01 +0000943 llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy, true,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000944 llvm::GlobalValue::InternalLinkage,
945 llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2),
946 ".objc_sel_ptr", &TheModule);
Chris Lattnere160c9b2009-01-27 05:06:01 +0000947 // If selectors are defined as an opaque type, cast the pointer to this
948 // type.
949 if (isSelOpaque) {
950 SelPtr = llvm::ConstantExpr::getBitCast(SelPtr,
951 llvm::PointerType::getUnqual(SelectorTy));
952 }
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000953 (*iter).second->setAliasee(SelPtr);
954 }
955 // Number of classes defined.
956 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty,
957 Classes.size()));
958 // Number of categories defined
959 Elements.push_back(llvm::ConstantInt::get(llvm::Type::Int16Ty,
960 Categories.size()));
961 // Create an array of classes, then categories, then static object instances
962 Classes.insert(Classes.end(), Categories.begin(), Categories.end());
963 // NULL-terminated list of static object instances (mainly constant strings)
964 Classes.push_back(Statics);
965 Classes.push_back(NULLPtr);
966 llvm::Constant *ClassList = llvm::ConstantArray::get(ClassListTy, Classes);
967 Elements.push_back(ClassList);
968 // Construct the symbol table
969 llvm::Constant *SymTab= MakeGlobal(SymTabTy, Elements);
970
971 // The symbol table is contained in a module which has some version-checking
972 // constants
973 llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy,
974 PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), NULL);
975 Elements.clear();
976 // Runtime version used for compatibility checking.
977 Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
Fariborz Jahanian91a0b512009-04-01 19:49:42 +0000978 // sizeof(ModuleTy)
979 llvm::TargetData td = llvm::TargetData::TargetData(&TheModule);
980 Elements.push_back(llvm::ConstantInt::get(LongTy, td.getTypeSizeInBits(ModuleTy)/8));
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000981 //FIXME: Should be the path to the file where this module was declared
982 Elements.push_back(NULLPtr);
983 Elements.push_back(SymTab);
984 llvm::Value *Module = MakeGlobal(ModuleTy, Elements);
985
986 // Create the load function calling the runtime entry point with the module
987 // structure
988 std::vector<const llvm::Type*> VoidArgs;
989 llvm::Function * LoadFunction = llvm::Function::Create(
990 llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false),
991 llvm::GlobalValue::InternalLinkage, ".objc_load_function",
992 &TheModule);
993 llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction);
Daniel Dunbar45d196b2008-11-01 01:53:16 +0000994 CGBuilderTy Builder;
Anton Korobeynikov20ff3102008-06-01 14:13:53 +0000995 Builder.SetInsertPoint(EntryBB);
Fariborz Jahanian26c82942009-03-30 18:02:14 +0000996
997 std::vector<const llvm::Type*> Params(1,
998 llvm::PointerType::getUnqual(ModuleTy));
999 llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
1000 llvm::Type::VoidTy, Params, true), "__objc_exec_class");
Anton Korobeynikov20ff3102008-06-01 14:13:53 +00001001 Builder.CreateCall(Register, Module);
1002 Builder.CreateRetVoid();
1003 return LoadFunction;
1004}
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001005
Fariborz Jahanian679a5022009-01-10 21:06:09 +00001006llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD,
1007 const ObjCContainerDecl *CD) {
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001008 const ObjCCategoryImplDecl *OCD =
Steve Naroff3e0a5402009-01-08 19:41:02 +00001009 dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext());
Chris Lattner077bf5e2008-11-24 03:33:13 +00001010 std::string CategoryName = OCD ? OCD->getNameAsString() : "";
1011 std::string ClassName = OMD->getClassInterface()->getNameAsString();
1012 std::string MethodName = OMD->getSelector().getAsString();
Douglas Gregorf8d49f62009-01-09 17:18:27 +00001013 bool isClassMethod = !OMD->isInstanceMethod();
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00001014
Daniel Dunbar541b63b2009-02-02 23:23:47 +00001015 CodeGenTypes &Types = CGM.getTypes();
Daniel Dunbar45c25ba2008-09-10 04:01:49 +00001016 const llvm::FunctionType *MethodTy =
Daniel Dunbar541b63b2009-02-02 23:23:47 +00001017 Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic());
Anton Korobeynikov20ff3102008-06-01 14:13:53 +00001018 std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName,
1019 MethodName, isClassMethod);
1020
Gabor Greif984d0b42008-04-06 20:42:52 +00001021 llvm::Function *Method = llvm::Function::Create(MethodTy,
Chris Lattner391d77a2008-03-30 23:03:07 +00001022 llvm::GlobalValue::InternalLinkage,
Anton Korobeynikov20ff3102008-06-01 14:13:53 +00001023 FunctionName,
Chris Lattner391d77a2008-03-30 23:03:07 +00001024 &TheModule);
Chris Lattner391d77a2008-03-30 23:03:07 +00001025 return Method;
1026}
1027
Daniel Dunbar49f66022008-09-24 03:38:44 +00001028llvm::Function *CGObjCGNU::GetPropertyGetFunction() {
1029 return 0;
1030}
1031
1032llvm::Function *CGObjCGNU::GetPropertySetFunction() {
1033 return 0;
1034}
1035
1036llvm::Function *CGObjCGNU::EnumerationMutationFunction() {
Fariborz Jahanian26c82942009-03-30 18:02:14 +00001037 std::vector<const llvm::Type*> Params(1, IdTy);
1038 return cast<llvm::Function>(CGM.CreateRuntimeFunction(
1039 llvm::FunctionType::get(llvm::Type::VoidTy, Params, true),
1040 "objc_enumerationMutation"));
Anders Carlsson2abd89c2008-08-31 04:05:03 +00001041}
1042
Fariborz Jahanianbd71be42008-11-21 00:49:24 +00001043void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1044 const Stmt &S) {
1045 CGF.ErrorUnsupported(&S, "@try/@synchronized statement");
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00001046}
1047
1048void CGObjCGNU::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar49f66022008-09-24 03:38:44 +00001049 const ObjCAtThrowStmt &S) {
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00001050 CGF.ErrorUnsupported(&S, "@throw statement");
1051}
1052
Fariborz Jahanian3e283e32008-11-18 22:37:34 +00001053llvm::Value * CGObjCGNU::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian6dc23172008-11-18 21:45:40 +00001054 llvm::Value *AddrWeakObj)
1055{
1056 return 0;
1057}
1058
Fariborz Jahanian3e283e32008-11-18 22:37:34 +00001059void CGObjCGNU::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1060 llvm::Value *src, llvm::Value *dst)
1061{
1062 return;
1063}
1064
Fariborz Jahanian58626502008-11-19 00:59:10 +00001065void CGObjCGNU::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1066 llvm::Value *src, llvm::Value *dst)
1067{
1068 return;
1069}
1070
Fariborz Jahanian7eda8362008-11-20 19:23:36 +00001071void CGObjCGNU::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1072 llvm::Value *src, llvm::Value *dst)
1073{
1074 return;
1075}
1076
Fariborz Jahanian58626502008-11-19 00:59:10 +00001077void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1078 llvm::Value *src, llvm::Value *dst)
1079{
1080 return;
1081}
1082
Fariborz Jahanian598d3f62009-02-03 19:03:09 +00001083LValue CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1084 QualType ObjectTy,
1085 llvm::Value *BaseValue,
1086 const ObjCIvarDecl *Ivar,
Fariborz Jahanian598d3f62009-02-03 19:03:09 +00001087 unsigned CVRQualifiers) {
Daniel Dunbar525c9b72009-04-21 01:19:28 +00001088 const ObjCInterfaceDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl();
Daniel Dunbar97776872009-04-22 07:32:20 +00001089 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
1090 EmitIvarOffset(CGF, ID, Ivar));
Fariborz Jahanian0bb20362009-02-02 20:02:29 +00001091}
1092
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00001093llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar2a031922009-04-22 05:08:15 +00001094 const ObjCInterfaceDecl *Interface,
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00001095 const ObjCIvarDecl *Ivar) {
Daniel Dunbar97776872009-04-22 07:32:20 +00001096 uint64_t Offset = ComputeIvarBaseOffset(CGF.CGM, Interface, Ivar);
Daniel Dunbar84ad77a2009-04-22 09:39:34 +00001097 return llvm::ConstantInt::get(LongTy, Offset);
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00001098}
1099
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001100CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){
Chris Lattnerdce14062008-06-26 04:19:03 +00001101 return new CGObjCGNU(CGM);
Chris Lattner0f984262008-03-01 08:50:34 +00001102}