blob: c05c2263f4694791cd1ba3b50b459cf6f7e0a6b7 [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//
Chris Lattnerfc8f0e12011-04-15 05:22:18 +000010// This provides Objective-C code generation targeting the Apple runtime.
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000011//
12//===----------------------------------------------------------------------===//
13
14#include "CGObjCRuntime.h"
John McCalld16c2cf2011-02-08 08:22:06 +000015#include "CGBlocks.h"
John McCall36f893c2011-01-28 11:13:47 +000016#include "CGCleanup.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000017#include "CGRecordLayout.h"
18#include "CodeGenFunction.h"
19#include "CodeGenModule.h"
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000020#include "clang/AST/ASTContext.h"
Daniel Dunbare91593e2008-08-11 04:54:23 +000021#include "clang/AST/Decl.h"
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000022#include "clang/AST/DeclObjC.h"
Anders Carlsson19cc4ab2009-07-18 19:43:29 +000023#include "clang/AST/RecordLayout.h"
Chris Lattner16f00492009-04-26 01:32:48 +000024#include "clang/AST/StmtObjC.h"
Daniel Dunbarf77ac862008-08-11 21:35:06 +000025#include "clang/Basic/LangOptions.h"
Mark Lacey8b549992013-10-30 21:53:58 +000026#include "clang/CodeGen/CGFunctionInfo.h"
Chandler Carruth06057ce2010-06-15 23:19:56 +000027#include "clang/Frontend/CodeGenOptions.h"
Chandler Carruth55fc8732012-12-04 09:13:33 +000028#include "llvm/ADT/DenseSet.h"
29#include "llvm/ADT/SetVector.h"
30#include "llvm/ADT/SmallPtrSet.h"
31#include "llvm/ADT/SmallString.h"
Stephen Hines651f13c2014-04-23 16:59:28 -070032#include "llvm/IR/CallSite.h"
Chandler Carruth3b844ba2013-01-02 11:45:17 +000033#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/InlineAsm.h"
35#include "llvm/IR/IntrinsicInst.h"
36#include "llvm/IR/LLVMContext.h"
37#include "llvm/IR/Module.h"
Daniel Dunbar33063492009-09-07 00:20:42 +000038#include "llvm/Support/raw_ostream.h"
Torok Edwinf42e4a62009-08-24 13:25:12 +000039#include <cstdio>
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000040
41using namespace clang;
Daniel Dunbar46f45b92008-09-09 01:06:48 +000042using namespace CodeGen;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +000043
44namespace {
Daniel Dunbarbbce49b2008-08-12 00:12:39 +000045
Daniel Dunbar6bff2512009-08-03 17:06:42 +000046// FIXME: We should find a nicer way to make the labels for metadata, string
47// concatenation is lame.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +000048
Fariborz Jahanianee0af742009-01-21 22:04:16 +000049class ObjCCommonTypesHelper {
Owen Andersona1cf15f2009-07-14 23:10:40 +000050protected:
51 llvm::LLVMContext &VMContext;
Daniel Dunbar6bff2512009-08-03 17:06:42 +000052
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +000053private:
John McCall0774cb82011-05-15 01:53:33 +000054 // The types of these functions don't really matter because we
55 // should always bitcast before calling them.
56
57 /// id objc_msgSend (id, SEL, ...)
58 ///
59 /// The default messenger, used for sends whose ABI is unchanged from
60 /// the all-integer/pointer case.
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +000061 llvm::Constant *getMessageSendFn() const {
John McCallf85e1932011-06-15 23:02:42 +000062 // Add the non-lazy-bind attribute, since objc_msgSend is likely to
63 // be called a lot.
Chris Lattner9cbe4f02011-07-09 17:41:47 +000064 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
Bill Wendlingc4c62fd2013-01-31 00:30:05 +000065 return
66 CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
67 params, true),
68 "objc_msgSend",
69 llvm::AttributeSet::get(CGM.getLLVMContext(),
70 llvm::AttributeSet::FunctionIndex,
71 llvm::Attribute::NonLazyBind));
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +000072 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +000073
John McCall0774cb82011-05-15 01:53:33 +000074 /// void objc_msgSend_stret (id, SEL, ...)
75 ///
76 /// The messenger used when the return value is an aggregate returned
77 /// by indirect reference in the first argument, and therefore the
78 /// self and selector parameters are shifted over by one.
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +000079 llvm::Constant *getMessageSendStretFn() const {
Chris Lattner9cbe4f02011-07-09 17:41:47 +000080 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
John McCall0774cb82011-05-15 01:53:33 +000081 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
82 params, true),
83 "objc_msgSend_stret");
Daniel Dunbar6bff2512009-08-03 17:06:42 +000084
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +000085 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +000086
John McCall0774cb82011-05-15 01:53:33 +000087 /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
88 ///
89 /// The messenger used when the return value is returned on the x87
90 /// floating-point stack; without a special entrypoint, the nil case
91 /// would be unbalanced.
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +000092 llvm::Constant *getMessageSendFpretFn() const {
Chris Lattner9cbe4f02011-07-09 17:41:47 +000093 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
Chris Lattner8b418682012-02-07 00:39:47 +000094 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
95 params, true),
John McCall0774cb82011-05-15 01:53:33 +000096 "objc_msgSend_fpret");
Daniel Dunbar6bff2512009-08-03 17:06:42 +000097
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +000098 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +000099
Anders Carlssoneea64802011-10-31 16:27:11 +0000100 /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
101 ///
102 /// The messenger used when the return value is returned in two values on the
103 /// x87 floating point stack; without a special entrypoint, the nil case
104 /// would be unbalanced. Only used on 64-bit X86.
105 llvm::Constant *getMessageSendFp2retFn() const {
106 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
107 llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
108 llvm::Type *resultType =
109 llvm::StructType::get(longDoubleType, longDoubleType, NULL);
110
111 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
112 params, true),
113 "objc_msgSend_fp2ret");
114 }
115
John McCall0774cb82011-05-15 01:53:33 +0000116 /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
117 ///
118 /// The messenger used for super calls, which have different dispatch
119 /// semantics. The class passed is the superclass of the current
120 /// class.
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000121 llvm::Constant *getMessageSendSuperFn() const {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000122 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000123 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000124 params, true),
125 "objc_msgSendSuper");
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000126 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000127
John McCall0774cb82011-05-15 01:53:33 +0000128 /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
129 ///
130 /// A slightly different messenger used for super calls. The class
131 /// passed is the current class.
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000132 llvm::Constant *getMessageSendSuperFn2() const {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000133 llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000134 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000135 params, true),
136 "objc_msgSendSuper2");
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000137 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000138
John McCall0774cb82011-05-15 01:53:33 +0000139 /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
140 /// SEL op, ...)
141 ///
142 /// The messenger used for super calls which return an aggregate indirectly.
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000143 llvm::Constant *getMessageSendSuperStretFn() const {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000144 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
Owen Andersona1cf15f2009-07-14 23:10:40 +0000145 return CGM.CreateRuntimeFunction(
John McCall0774cb82011-05-15 01:53:33 +0000146 llvm::FunctionType::get(CGM.VoidTy, params, true),
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000147 "objc_msgSendSuper_stret");
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000148 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000149
John McCall0774cb82011-05-15 01:53:33 +0000150 /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
151 /// SEL op, ...)
152 ///
153 /// objc_msgSendSuper_stret with the super2 semantics.
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000154 llvm::Constant *getMessageSendSuperStretFn2() const {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000155 llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
Owen Andersona1cf15f2009-07-14 23:10:40 +0000156 return CGM.CreateRuntimeFunction(
John McCall0774cb82011-05-15 01:53:33 +0000157 llvm::FunctionType::get(CGM.VoidTy, params, true),
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000158 "objc_msgSendSuper2_stret");
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000159 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000160
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000161 llvm::Constant *getMessageSendSuperFpretFn() const {
162 // There is no objc_msgSendSuper_fpret? How can that work?
163 return getMessageSendSuperFn();
164 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000165
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000166 llvm::Constant *getMessageSendSuperFpretFn2() const {
167 // There is no objc_msgSendSuper_fpret? How can that work?
168 return getMessageSendSuperFn2();
169 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000170
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000171protected:
172 CodeGen::CodeGenModule &CGM;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000173
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000174public:
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000175 llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
Bob Wilsondc8dab62011-11-30 01:57:58 +0000176 llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
Stephen Hines651f13c2014-04-23 16:59:28 -0700177 llvm::Type *IvarOffsetVarTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000178
Daniel Dunbar2bedbf82008-08-12 05:28:47 +0000179 /// ObjectPtrTy - LLVM type for object handles (typeof(id))
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000180 llvm::Type *ObjectPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000181
Fariborz Jahanian6d657c42008-11-18 20:18:11 +0000182 /// PtrObjectPtrTy - LLVM type for id *
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000183 llvm::Type *PtrObjectPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000184
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000185 /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000186 llvm::Type *SelectorPtrTy;
Douglas Gregor4c86fdb2012-01-17 18:36:30 +0000187
188private:
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000189 /// ProtocolPtrTy - LLVM type for external protocol handles
190 /// (typeof(Protocol))
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000191 llvm::Type *ExternalProtocolPtrTy;
Douglas Gregor4c86fdb2012-01-17 18:36:30 +0000192
193public:
194 llvm::Type *getExternalProtocolPtrTy() {
195 if (!ExternalProtocolPtrTy) {
196 // FIXME: It would be nice to unify this with the opaque type, so that the
197 // IR comes out a bit cleaner.
198 CodeGen::CodeGenTypes &Types = CGM.getTypes();
199 ASTContext &Ctx = CGM.getContext();
200 llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
201 ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
202 }
203
204 return ExternalProtocolPtrTy;
205 }
206
Daniel Dunbar19cd87e2008-08-30 03:02:31 +0000207 // SuperCTy - clang type for struct objc_super.
208 QualType SuperCTy;
209 // SuperPtrCTy - clang type for struct objc_super *.
210 QualType SuperPtrCTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000211
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000212 /// SuperTy - LLVM type for struct objc_super.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000213 llvm::StructType *SuperTy;
Daniel Dunbar14c80b72008-08-23 09:25:55 +0000214 /// SuperPtrTy - LLVM type for struct objc_super *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000215 llvm::Type *SuperPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000216
Fariborz Jahanian30bc5712009-01-22 23:02:58 +0000217 /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
218 /// in GCC parlance).
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000219 llvm::StructType *PropertyTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000220
Fariborz Jahanian30bc5712009-01-22 23:02:58 +0000221 /// PropertyListTy - LLVM type for struct objc_property_list
222 /// (_prop_list_t in GCC parlance).
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000223 llvm::StructType *PropertyListTy;
Fariborz Jahanian30bc5712009-01-22 23:02:58 +0000224 /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000225 llvm::Type *PropertyListPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000226
Fariborz Jahanian30bc5712009-01-22 23:02:58 +0000227 // MethodTy - LLVM type for struct objc_method.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000228 llvm::StructType *MethodTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000229
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000230 /// CacheTy - LLVM type for struct objc_cache.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000231 llvm::Type *CacheTy;
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000232 /// CachePtrTy - LLVM type for struct objc_cache *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000233 llvm::Type *CachePtrTy;
Fariborz Jahanian9d96bce2011-06-22 20:21:51 +0000234
Chris Lattner72db6c32009-04-22 02:44:54 +0000235 llvm::Constant *getGetPropertyFn() {
236 CodeGen::CodeGenTypes &Types = CGM.getTypes();
237 ASTContext &Ctx = CGM.getContext();
238 // id objc_getProperty (id, SEL, ptrdiff_t, bool)
Chris Lattner5f9e2722011-07-23 10:55:15 +0000239 SmallVector<CanQualType,4> Params;
John McCallead608a2010-02-26 00:48:12 +0000240 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
241 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
Chris Lattner72db6c32009-04-22 02:44:54 +0000242 Params.push_back(IdType);
243 Params.push_back(SelType);
David Chisnallab5824e2011-03-22 20:03:13 +0000244 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
Chris Lattner72db6c32009-04-22 02:44:54 +0000245 Params.push_back(Ctx.BoolTy);
Chris Lattner2acc6e32011-07-18 04:24:23 +0000246 llvm::FunctionType *FTy =
Stephen Hines651f13c2014-04-23 16:59:28 -0700247 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, false, Params,
248 FunctionType::ExtInfo(),
John McCall0f3d0972012-07-07 06:41:13 +0000249 RequiredArgs::All));
Chris Lattner72db6c32009-04-22 02:44:54 +0000250 return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
251 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000252
Chris Lattner72db6c32009-04-22 02:44:54 +0000253 llvm::Constant *getSetPropertyFn() {
254 CodeGen::CodeGenTypes &Types = CGM.getTypes();
255 ASTContext &Ctx = CGM.getContext();
256 // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
Chris Lattner5f9e2722011-07-23 10:55:15 +0000257 SmallVector<CanQualType,6> Params;
John McCallead608a2010-02-26 00:48:12 +0000258 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
259 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
Chris Lattner72db6c32009-04-22 02:44:54 +0000260 Params.push_back(IdType);
261 Params.push_back(SelType);
David Chisnallab5824e2011-03-22 20:03:13 +0000262 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
Chris Lattner72db6c32009-04-22 02:44:54 +0000263 Params.push_back(IdType);
264 Params.push_back(Ctx.BoolTy);
265 Params.push_back(Ctx.BoolTy);
Chris Lattner2acc6e32011-07-18 04:24:23 +0000266 llvm::FunctionType *FTy =
Stephen Hines651f13c2014-04-23 16:59:28 -0700267 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
268 Params,
269 FunctionType::ExtInfo(),
John McCall0f3d0972012-07-07 06:41:13 +0000270 RequiredArgs::All));
Chris Lattner72db6c32009-04-22 02:44:54 +0000271 return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
272 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000273
Ted Kremenekebcb57a2012-03-06 20:05:56 +0000274 llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
275 CodeGen::CodeGenTypes &Types = CGM.getTypes();
276 ASTContext &Ctx = CGM.getContext();
277 // void objc_setProperty_atomic(id self, SEL _cmd,
278 // id newValue, ptrdiff_t offset);
279 // void objc_setProperty_nonatomic(id self, SEL _cmd,
280 // id newValue, ptrdiff_t offset);
281 // void objc_setProperty_atomic_copy(id self, SEL _cmd,
282 // id newValue, ptrdiff_t offset);
283 // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
284 // id newValue, ptrdiff_t offset);
285
286 SmallVector<CanQualType,4> Params;
287 CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
288 CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
289 Params.push_back(IdType);
290 Params.push_back(SelType);
291 Params.push_back(IdType);
292 Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
293 llvm::FunctionType *FTy =
Stephen Hines651f13c2014-04-23 16:59:28 -0700294 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
295 Params,
John McCall0f3d0972012-07-07 06:41:13 +0000296 FunctionType::ExtInfo(),
297 RequiredArgs::All));
Ted Kremenekebcb57a2012-03-06 20:05:56 +0000298 const char *name;
299 if (atomic && copy)
300 name = "objc_setProperty_atomic_copy";
301 else if (atomic && !copy)
302 name = "objc_setProperty_atomic";
303 else if (!atomic && copy)
304 name = "objc_setProperty_nonatomic_copy";
305 else
306 name = "objc_setProperty_nonatomic";
307
308 return CGM.CreateRuntimeFunction(FTy, name);
309 }
Fariborz Jahanian6cc59062010-04-12 18:18:10 +0000310
311 llvm::Constant *getCopyStructFn() {
312 CodeGen::CodeGenTypes &Types = CGM.getTypes();
313 ASTContext &Ctx = CGM.getContext();
314 // void objc_copyStruct (void *, const void *, size_t, bool, bool)
Chris Lattner5f9e2722011-07-23 10:55:15 +0000315 SmallVector<CanQualType,5> Params;
Fariborz Jahanian6cc59062010-04-12 18:18:10 +0000316 Params.push_back(Ctx.VoidPtrTy);
317 Params.push_back(Ctx.VoidPtrTy);
318 Params.push_back(Ctx.LongTy);
319 Params.push_back(Ctx.BoolTy);
320 Params.push_back(Ctx.BoolTy);
Chris Lattner2acc6e32011-07-18 04:24:23 +0000321 llvm::FunctionType *FTy =
Stephen Hines651f13c2014-04-23 16:59:28 -0700322 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
323 Params,
324 FunctionType::ExtInfo(),
John McCall0f3d0972012-07-07 06:41:13 +0000325 RequiredArgs::All));
Fariborz Jahanian6cc59062010-04-12 18:18:10 +0000326 return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
327 }
328
Fariborz Jahaniane3173022012-01-06 18:07:23 +0000329 /// This routine declares and returns address of:
330 /// void objc_copyCppObjectAtomic(
331 /// void *dest, const void *src,
332 /// void (*copyHelper) (void *dest, const void *source));
333 llvm::Constant *getCppAtomicObjectFunction() {
334 CodeGen::CodeGenTypes &Types = CGM.getTypes();
335 ASTContext &Ctx = CGM.getContext();
336 /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
337 SmallVector<CanQualType,3> Params;
338 Params.push_back(Ctx.VoidPtrTy);
339 Params.push_back(Ctx.VoidPtrTy);
340 Params.push_back(Ctx.VoidPtrTy);
341 llvm::FunctionType *FTy =
Stephen Hines651f13c2014-04-23 16:59:28 -0700342 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
343 Params,
344 FunctionType::ExtInfo(),
John McCall0f3d0972012-07-07 06:41:13 +0000345 RequiredArgs::All));
Fariborz Jahaniane3173022012-01-06 18:07:23 +0000346 return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
347 }
348
Chris Lattner72db6c32009-04-22 02:44:54 +0000349 llvm::Constant *getEnumerationMutationFn() {
Daniel Dunbarc1ab9002009-07-11 20:32:50 +0000350 CodeGen::CodeGenTypes &Types = CGM.getTypes();
351 ASTContext &Ctx = CGM.getContext();
Chris Lattner72db6c32009-04-22 02:44:54 +0000352 // void objc_enumerationMutation (id)
Chris Lattner5f9e2722011-07-23 10:55:15 +0000353 SmallVector<CanQualType,1> Params;
John McCallead608a2010-02-26 00:48:12 +0000354 Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
Chris Lattner2acc6e32011-07-18 04:24:23 +0000355 llvm::FunctionType *FTy =
Stephen Hines651f13c2014-04-23 16:59:28 -0700356 Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
357 Params,
358 FunctionType::ExtInfo(),
John McCallde5d3c72012-02-17 03:33:10 +0000359 RequiredArgs::All));
Chris Lattner72db6c32009-04-22 02:44:54 +0000360 return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
361 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000362
Fariborz Jahaniandb286862009-01-22 00:37:21 +0000363 /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
Chris Lattner72db6c32009-04-22 02:44:54 +0000364 llvm::Constant *getGcReadWeakFn() {
365 // id objc_read_weak (id *)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000366 llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000367 llvm::FunctionType *FTy =
John McCall0774cb82011-05-15 01:53:33 +0000368 llvm::FunctionType::get(ObjectPtrTy, args, false);
Chris Lattner72db6c32009-04-22 02:44:54 +0000369 return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000370 }
371
Fariborz Jahaniandb286862009-01-22 00:37:21 +0000372 /// GcAssignWeakFn -- LLVM objc_assign_weak function.
Chris Lattner96508e12009-04-17 22:12:36 +0000373 llvm::Constant *getGcAssignWeakFn() {
374 // id objc_assign_weak (id, id *)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000375 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
Chris Lattner96508e12009-04-17 22:12:36 +0000376 llvm::FunctionType *FTy =
John McCall0774cb82011-05-15 01:53:33 +0000377 llvm::FunctionType::get(ObjectPtrTy, args, false);
Chris Lattner96508e12009-04-17 22:12:36 +0000378 return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
379 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000380
Fariborz Jahaniandb286862009-01-22 00:37:21 +0000381 /// GcAssignGlobalFn -- LLVM objc_assign_global function.
Chris Lattnerbbccd612009-04-22 02:38:11 +0000382 llvm::Constant *getGcAssignGlobalFn() {
383 // id objc_assign_global(id, id *)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000384 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
Owen Andersona1cf15f2009-07-14 23:10:40 +0000385 llvm::FunctionType *FTy =
John McCall0774cb82011-05-15 01:53:33 +0000386 llvm::FunctionType::get(ObjectPtrTy, args, false);
Chris Lattnerbbccd612009-04-22 02:38:11 +0000387 return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
388 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000389
Fariborz Jahanian021a7a62010-07-20 20:30:03 +0000390 /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
391 llvm::Constant *getGcAssignThreadLocalFn() {
392 // id objc_assign_threadlocal(id src, id * dest)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000393 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
Fariborz Jahanian021a7a62010-07-20 20:30:03 +0000394 llvm::FunctionType *FTy =
John McCall0774cb82011-05-15 01:53:33 +0000395 llvm::FunctionType::get(ObjectPtrTy, args, false);
Fariborz Jahanian021a7a62010-07-20 20:30:03 +0000396 return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
397 }
398
Fariborz Jahaniandb286862009-01-22 00:37:21 +0000399 /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
Chris Lattnerbbccd612009-04-22 02:38:11 +0000400 llvm::Constant *getGcAssignIvarFn() {
Fariborz Jahanian6c7a1f32009-09-24 22:25:38 +0000401 // id objc_assign_ivar(id, id *, ptrdiff_t)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000402 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
403 CGM.PtrDiffTy };
Owen Andersona1cf15f2009-07-14 23:10:40 +0000404 llvm::FunctionType *FTy =
John McCall0774cb82011-05-15 01:53:33 +0000405 llvm::FunctionType::get(ObjectPtrTy, args, false);
Chris Lattnerbbccd612009-04-22 02:38:11 +0000406 return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
407 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000408
Fariborz Jahanian082b02e2009-07-08 01:18:33 +0000409 /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
410 llvm::Constant *GcMemmoveCollectableFn() {
411 // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000412 llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
John McCall0774cb82011-05-15 01:53:33 +0000413 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
Fariborz Jahanian082b02e2009-07-08 01:18:33 +0000414 return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
415 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000416
Fariborz Jahaniandb286862009-01-22 00:37:21 +0000417 /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
Chris Lattnerbbccd612009-04-22 02:38:11 +0000418 llvm::Constant *getGcAssignStrongCastFn() {
Fariborz Jahanian021a7a62010-07-20 20:30:03 +0000419 // id objc_assign_strongCast(id, id *)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000420 llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
Owen Andersona1cf15f2009-07-14 23:10:40 +0000421 llvm::FunctionType *FTy =
John McCall0774cb82011-05-15 01:53:33 +0000422 llvm::FunctionType::get(ObjectPtrTy, args, false);
Chris Lattnerbbccd612009-04-22 02:38:11 +0000423 return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
424 }
Anders Carlssonf57c5b22009-02-16 22:59:18 +0000425
426 /// ExceptionThrowFn - LLVM objc_exception_throw function.
Chris Lattnerbbccd612009-04-22 02:38:11 +0000427 llvm::Constant *getExceptionThrowFn() {
428 // void objc_exception_throw(id)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000429 llvm::Type *args[] = { ObjectPtrTy };
Chris Lattnerbbccd612009-04-22 02:38:11 +0000430 llvm::FunctionType *FTy =
John McCall0774cb82011-05-15 01:53:33 +0000431 llvm::FunctionType::get(CGM.VoidTy, args, false);
Chris Lattnerbbccd612009-04-22 02:38:11 +0000432 return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
433 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000434
Fariborz Jahanian69677ea2010-05-28 17:34:43 +0000435 /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
436 llvm::Constant *getExceptionRethrowFn() {
437 // void objc_exception_rethrow(void)
John McCall0774cb82011-05-15 01:53:33 +0000438 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
Fariborz Jahanian69677ea2010-05-28 17:34:43 +0000439 return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
440 }
441
Daniel Dunbar1c566672009-02-24 01:43:46 +0000442 /// SyncEnterFn - LLVM object_sync_enter function.
Chris Lattnerb02e53b2009-04-06 16:53:45 +0000443 llvm::Constant *getSyncEnterFn() {
Aaron Ballman2d234d732012-09-06 16:44:16 +0000444 // int objc_sync_enter (id)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000445 llvm::Type *args[] = { ObjectPtrTy };
Chris Lattnerb02e53b2009-04-06 16:53:45 +0000446 llvm::FunctionType *FTy =
Aaron Ballman2d234d732012-09-06 16:44:16 +0000447 llvm::FunctionType::get(CGM.IntTy, args, false);
Chris Lattnerb02e53b2009-04-06 16:53:45 +0000448 return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
449 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000450
Daniel Dunbar1c566672009-02-24 01:43:46 +0000451 /// SyncExitFn - LLVM object_sync_exit function.
Chris Lattnerbbccd612009-04-22 02:38:11 +0000452 llvm::Constant *getSyncExitFn() {
Aaron Ballman2d234d732012-09-06 16:44:16 +0000453 // int objc_sync_exit (id)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000454 llvm::Type *args[] = { ObjectPtrTy };
Chris Lattnerbbccd612009-04-22 02:38:11 +0000455 llvm::FunctionType *FTy =
Aaron Ballman2d234d732012-09-06 16:44:16 +0000456 llvm::FunctionType::get(CGM.IntTy, args, false);
Chris Lattnerbbccd612009-04-22 02:38:11 +0000457 return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
458 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000459
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000460 llvm::Constant *getSendFn(bool IsSuper) const {
461 return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
462 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000463
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000464 llvm::Constant *getSendFn2(bool IsSuper) const {
465 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
466 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000467
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000468 llvm::Constant *getSendStretFn(bool IsSuper) const {
469 return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
470 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000471
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000472 llvm::Constant *getSendStretFn2(bool IsSuper) const {
473 return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
474 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000475
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000476 llvm::Constant *getSendFpretFn(bool IsSuper) const {
477 return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
478 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000479
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +0000480 llvm::Constant *getSendFpretFn2(bool IsSuper) const {
481 return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
482 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000483
Anders Carlssoneea64802011-10-31 16:27:11 +0000484 llvm::Constant *getSendFp2retFn(bool IsSuper) const {
485 return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
486 }
487
488 llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
489 return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
490 }
491
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000492 ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
493 ~ObjCCommonTypesHelper(){}
494};
Daniel Dunbare8b470d2008-08-23 04:28:29 +0000495
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000496/// ObjCTypesHelper - Helper class that encapsulates lazy
497/// construction of varies types used during ObjC generation.
498class ObjCTypesHelper : public ObjCCommonTypesHelper {
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000499public:
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000500 /// SymtabTy - LLVM type for struct objc_symtab.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000501 llvm::StructType *SymtabTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000502 /// SymtabPtrTy - LLVM type for struct objc_symtab *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000503 llvm::Type *SymtabPtrTy;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000504 /// ModuleTy - LLVM type for struct objc_module.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000505 llvm::StructType *ModuleTy;
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000506
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000507 /// ProtocolTy - LLVM type for struct objc_protocol.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000508 llvm::StructType *ProtocolTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000509 /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000510 llvm::Type *ProtocolPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000511 /// ProtocolExtensionTy - LLVM type for struct
512 /// objc_protocol_extension.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000513 llvm::StructType *ProtocolExtensionTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000514 /// ProtocolExtensionTy - LLVM type for struct
515 /// objc_protocol_extension *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000516 llvm::Type *ProtocolExtensionPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000517 /// MethodDescriptionTy - LLVM type for struct
518 /// objc_method_description.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000519 llvm::StructType *MethodDescriptionTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000520 /// MethodDescriptionListTy - LLVM type for struct
521 /// objc_method_description_list.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000522 llvm::StructType *MethodDescriptionListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000523 /// MethodDescriptionListPtrTy - LLVM type for struct
524 /// objc_method_description_list *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000525 llvm::Type *MethodDescriptionListPtrTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000526 /// ProtocolListTy - LLVM type for struct objc_property_list.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000527 llvm::StructType *ProtocolListTy;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000528 /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000529 llvm::Type *ProtocolListPtrTy;
Daniel Dunbar86e253a2008-08-22 20:34:54 +0000530 /// CategoryTy - LLVM type for struct objc_category.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000531 llvm::StructType *CategoryTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000532 /// ClassTy - LLVM type for struct objc_class.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000533 llvm::StructType *ClassTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000534 /// ClassPtrTy - LLVM type for struct objc_class *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000535 llvm::Type *ClassPtrTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000536 /// ClassExtensionTy - LLVM type for struct objc_class_ext.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000537 llvm::StructType *ClassExtensionTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000538 /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000539 llvm::Type *ClassExtensionPtrTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000540 // IvarTy - LLVM type for struct objc_ivar.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000541 llvm::StructType *IvarTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000542 /// IvarListTy - LLVM type for struct objc_ivar_list.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000543 llvm::Type *IvarListTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000544 /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000545 llvm::Type *IvarListPtrTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000546 /// MethodListTy - LLVM type for struct objc_method_list.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000547 llvm::Type *MethodListTy;
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000548 /// MethodListPtrTy - LLVM type for struct objc_method_list *.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000549 llvm::Type *MethodListPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000550
Anders Carlsson124526b2008-09-09 10:10:21 +0000551 /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000552 llvm::Type *ExceptionDataTy;
Fariborz Jahanian9d96bce2011-06-22 20:21:51 +0000553
Anders Carlsson124526b2008-09-09 10:10:21 +0000554 /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
Chris Lattner34b02a12009-04-22 02:26:14 +0000555 llvm::Constant *getExceptionTryEnterFn() {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000556 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
Owen Andersona1cf15f2009-07-14 23:10:40 +0000557 return CGM.CreateRuntimeFunction(
John McCall0774cb82011-05-15 01:53:33 +0000558 llvm::FunctionType::get(CGM.VoidTy, params, false),
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000559 "objc_exception_try_enter");
Chris Lattner34b02a12009-04-22 02:26:14 +0000560 }
Anders Carlsson124526b2008-09-09 10:10:21 +0000561
562 /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
Chris Lattner34b02a12009-04-22 02:26:14 +0000563 llvm::Constant *getExceptionTryExitFn() {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000564 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
Owen Andersona1cf15f2009-07-14 23:10:40 +0000565 return CGM.CreateRuntimeFunction(
John McCall0774cb82011-05-15 01:53:33 +0000566 llvm::FunctionType::get(CGM.VoidTy, params, false),
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000567 "objc_exception_try_exit");
Chris Lattner34b02a12009-04-22 02:26:14 +0000568 }
Anders Carlsson124526b2008-09-09 10:10:21 +0000569
570 /// ExceptionExtractFn - LLVM objc_exception_extract function.
Chris Lattner34b02a12009-04-22 02:26:14 +0000571 llvm::Constant *getExceptionExtractFn() {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000572 llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000573 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000574 params, false),
Chris Lattner34b02a12009-04-22 02:26:14 +0000575 "objc_exception_extract");
Chris Lattner34b02a12009-04-22 02:26:14 +0000576 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000577
Anders Carlsson124526b2008-09-09 10:10:21 +0000578 /// ExceptionMatchFn - LLVM objc_exception_match function.
Chris Lattner34b02a12009-04-22 02:26:14 +0000579 llvm::Constant *getExceptionMatchFn() {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000580 llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000581 return CGM.CreateRuntimeFunction(
John McCall0774cb82011-05-15 01:53:33 +0000582 llvm::FunctionType::get(CGM.Int32Ty, params, false),
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000583 "objc_exception_match");
584
Chris Lattner34b02a12009-04-22 02:26:14 +0000585 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000586
Anders Carlsson124526b2008-09-09 10:10:21 +0000587 /// SetJmpFn - LLVM _setjmp function.
Chris Lattner34b02a12009-04-22 02:26:14 +0000588 llvm::Constant *getSetJmpFn() {
John McCall0774cb82011-05-15 01:53:33 +0000589 // This is specifically the prototype for x86.
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000590 llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
Bill Wendlingc4c62fd2013-01-31 00:30:05 +0000591 return
592 CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
593 params, false),
594 "_setjmp",
595 llvm::AttributeSet::get(CGM.getLLVMContext(),
596 llvm::AttributeSet::FunctionIndex,
597 llvm::Attribute::NonLazyBind));
Chris Lattner34b02a12009-04-22 02:26:14 +0000598 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000599
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000600public:
601 ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000602 ~ObjCTypesHelper() {}
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000603};
604
Fariborz Jahanian30bc5712009-01-22 23:02:58 +0000605/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000606/// modern abi
Fariborz Jahanian30bc5712009-01-22 23:02:58 +0000607class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
Fariborz Jahanian83a8a752009-02-04 20:42:28 +0000608public:
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000609
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000610 // MethodListnfABITy - LLVM for struct _method_list_t
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000611 llvm::StructType *MethodListnfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000612
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000613 // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000614 llvm::Type *MethodListnfABIPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000615
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000616 // ProtocolnfABITy = LLVM for struct _protocol_t
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000617 llvm::StructType *ProtocolnfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000618
Daniel Dunbar948e2582009-02-15 07:36:20 +0000619 // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000620 llvm::Type *ProtocolnfABIPtrTy;
Daniel Dunbar948e2582009-02-15 07:36:20 +0000621
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000622 // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000623 llvm::StructType *ProtocolListnfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000624
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000625 // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000626 llvm::Type *ProtocolListnfABIPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000627
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000628 // ClassnfABITy - LLVM for struct _class_t
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000629 llvm::StructType *ClassnfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000630
Fariborz Jahanianaa23b572009-01-23 23:53:38 +0000631 // ClassnfABIPtrTy - LLVM for struct _class_t*
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000632 llvm::Type *ClassnfABIPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000633
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000634 // IvarnfABITy - LLVM for struct _ivar_t
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000635 llvm::StructType *IvarnfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000636
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000637 // IvarListnfABITy - LLVM for struct _ivar_list_t
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000638 llvm::StructType *IvarListnfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000639
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000640 // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000641 llvm::Type *IvarListnfABIPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000642
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000643 // ClassRonfABITy - LLVM for struct _class_ro_t
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000644 llvm::StructType *ClassRonfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000645
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000646 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000647 llvm::Type *ImpnfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000648
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +0000649 // CategorynfABITy - LLVM for struct _category_t
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000650 llvm::StructType *CategorynfABITy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000651
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +0000652 // New types for nonfragile abi messaging.
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000653
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +0000654 // MessageRefTy - LLVM for:
655 // struct _message_ref_t {
656 // IMP messenger;
657 // SEL name;
658 // };
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000659 llvm::StructType *MessageRefTy;
Fariborz Jahanian83a8a752009-02-04 20:42:28 +0000660 // MessageRefCTy - clang type for struct _message_ref_t
661 QualType MessageRefCTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000662
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +0000663 // MessageRefPtrTy - LLVM for struct _message_ref_t*
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000664 llvm::Type *MessageRefPtrTy;
Fariborz Jahanian83a8a752009-02-04 20:42:28 +0000665 // MessageRefCPtrTy - clang type for struct _message_ref_t*
666 QualType MessageRefCPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000667
Fariborz Jahanianef163782009-02-05 01:13:09 +0000668 // MessengerTy - Type of the messenger (shown as IMP above)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000669 llvm::FunctionType *MessengerTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000670
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +0000671 // SuperMessageRefTy - LLVM for:
672 // struct _super_message_ref_t {
673 // SUPER_IMP messenger;
674 // SEL name;
675 // };
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000676 llvm::StructType *SuperMessageRefTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000677
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +0000678 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000679 llvm::Type *SuperMessageRefPtrTy;
Daniel Dunbar8ecbaf22009-02-24 07:47:38 +0000680
Chris Lattner1c02f862009-04-22 02:53:24 +0000681 llvm::Constant *getMessageSendFixupFn() {
682 // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000683 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000684 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000685 params, true),
Chris Lattner1c02f862009-04-22 02:53:24 +0000686 "objc_msgSend_fixup");
687 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000688
Chris Lattner1c02f862009-04-22 02:53:24 +0000689 llvm::Constant *getMessageSendFpretFixupFn() {
690 // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000691 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000692 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000693 params, true),
Chris Lattner1c02f862009-04-22 02:53:24 +0000694 "objc_msgSend_fpret_fixup");
695 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000696
Chris Lattner1c02f862009-04-22 02:53:24 +0000697 llvm::Constant *getMessageSendStretFixupFn() {
698 // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000699 llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000700 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000701 params, true),
Chris Lattner1c02f862009-04-22 02:53:24 +0000702 "objc_msgSend_stret_fixup");
703 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000704
Chris Lattner1c02f862009-04-22 02:53:24 +0000705 llvm::Constant *getMessageSendSuper2FixupFn() {
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000706 // id objc_msgSendSuper2_fixup (struct objc_super *,
Chris Lattner1c02f862009-04-22 02:53:24 +0000707 // struct _super_message_ref_t*, ...)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000708 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000709 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000710 params, true),
Chris Lattner1c02f862009-04-22 02:53:24 +0000711 "objc_msgSendSuper2_fixup");
712 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000713
Chris Lattner1c02f862009-04-22 02:53:24 +0000714 llvm::Constant *getMessageSendSuper2StretFixupFn() {
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000715 // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
Chris Lattner1c02f862009-04-22 02:53:24 +0000716 // struct _super_message_ref_t*, ...)
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000717 llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000718 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000719 params, true),
Chris Lattner1c02f862009-04-22 02:53:24 +0000720 "objc_msgSendSuper2_stret_fixup");
721 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000722
Chris Lattner8a569112009-04-22 02:15:23 +0000723 llvm::Constant *getObjCEndCatchFn() {
John McCall0774cb82011-05-15 01:53:33 +0000724 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
Chris Lattner8a569112009-04-22 02:15:23 +0000725 "objc_end_catch");
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000726
Chris Lattner8a569112009-04-22 02:15:23 +0000727 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000728
Chris Lattner8a569112009-04-22 02:15:23 +0000729 llvm::Constant *getObjCBeginCatchFn() {
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000730 llvm::Type *params[] = { Int8PtrTy };
Owen Anderson96e0fc72009-07-29 22:16:19 +0000731 return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
John McCall0774cb82011-05-15 01:53:33 +0000732 params, false),
Chris Lattner8a569112009-04-22 02:15:23 +0000733 "objc_begin_catch");
734 }
Daniel Dunbare588b992009-03-01 04:46:24 +0000735
Chris Lattner9cbe4f02011-07-09 17:41:47 +0000736 llvm::StructType *EHTypeTy;
737 llvm::Type *EHTypePtrTy;
Fariborz Jahanian9d96bce2011-06-22 20:21:51 +0000738
Fariborz Jahanian30bc5712009-01-22 23:02:58 +0000739 ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
740 ~ObjCNonFragileABITypesHelper(){}
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000741};
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000742
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000743class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +0000744public:
745 // FIXME - accessibility
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +0000746 class GC_IVAR {
Fariborz Jahanian820e0202009-03-11 00:07:04 +0000747 public:
Eli Friedmane5b46662012-11-06 22:15:52 +0000748 unsigned ivar_bytepos;
749 unsigned ivar_size;
750 GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000751 : ivar_bytepos(bytepos), ivar_size(size) {}
Daniel Dunbar0941b492009-04-23 01:29:05 +0000752
753 // Allow sorting based on byte pos.
754 bool operator<(const GC_IVAR &b) const {
755 return ivar_bytepos < b.ivar_bytepos;
756 }
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +0000757 };
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000758
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +0000759 class SKIP_SCAN {
Daniel Dunbar8b2926c2009-05-03 13:44:42 +0000760 public:
761 unsigned skip;
762 unsigned scan;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000763 SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
Daniel Dunbar8b2926c2009-05-03 13:44:42 +0000764 : skip(_skip), scan(_scan) {}
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +0000765 };
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000766
Fariborz Jahaniane11dba82012-10-25 21:15:04 +0000767 /// opcode for captured block variables layout 'instructions'.
768 /// In the following descriptions, 'I' is the value of the immediate field.
769 /// (field following the opcode).
770 ///
771 enum BLOCK_LAYOUT_OPCODE {
772 /// An operator which affects how the following layout should be
773 /// interpreted.
774 /// I == 0: Halt interpretation and treat everything else as
775 /// a non-pointer. Note that this instruction is equal
776 /// to '\0'.
777 /// I != 0: Currently unused.
778 BLOCK_LAYOUT_OPERATOR = 0,
779
780 /// The next I+1 bytes do not contain a value of object pointer type.
781 /// Note that this can leave the stream unaligned, meaning that
782 /// subsequent word-size instructions do not begin at a multiple of
783 /// the pointer size.
784 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,
785
786 /// The next I+1 words do not contain a value of object pointer type.
787 /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
788 /// when the required skip quantity is a multiple of the pointer size.
789 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,
790
791 /// The next I+1 words are __strong pointers to Objective-C
792 /// objects or blocks.
793 BLOCK_LAYOUT_STRONG = 3,
794
795 /// The next I+1 words are pointers to __block variables.
796 BLOCK_LAYOUT_BYREF = 4,
797
798 /// The next I+1 words are __weak pointers to Objective-C
799 /// objects or blocks.
800 BLOCK_LAYOUT_WEAK = 5,
801
802 /// The next I+1 words are __unsafe_unretained pointers to
803 /// Objective-C objects or blocks.
804 BLOCK_LAYOUT_UNRETAINED = 6
805
806 /// The next I+1 words are block or object pointers with some
807 /// as-yet-unspecified ownership semantics. If we add more
808 /// flavors of ownership semantics, values will be taken from
809 /// this range.
810 ///
811 /// This is included so that older tools can at least continue
812 /// processing the layout past such things.
813 //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
814
815 /// All other opcodes are reserved. Halt interpretation and
816 /// treat everything else as opaque.
817 };
818
819 class RUN_SKIP {
820 public:
821 enum BLOCK_LAYOUT_OPCODE opcode;
Fariborz Jahanian1da01d62012-11-07 20:00:32 +0000822 CharUnits block_var_bytepos;
823 CharUnits block_var_size;
Fariborz Jahaniane11dba82012-10-25 21:15:04 +0000824 RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +0000825 CharUnits BytePos = CharUnits::Zero(),
826 CharUnits Size = CharUnits::Zero())
Fariborz Jahanianc46b4352012-10-27 21:10:38 +0000827 : opcode(Opcode), block_var_bytepos(BytePos), block_var_size(Size) {}
Fariborz Jahaniane11dba82012-10-25 21:15:04 +0000828
829 // Allow sorting based on byte pos.
830 bool operator<(const RUN_SKIP &b) const {
831 return block_var_bytepos < b.block_var_bytepos;
832 }
833 };
834
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000835protected:
Owen Anderson69243822009-07-13 04:10:07 +0000836 llvm::LLVMContext &VMContext;
Fariborz Jahanianee0af742009-01-21 22:04:16 +0000837 // FIXME! May not be needing this after all.
Daniel Dunbarbbce49b2008-08-12 00:12:39 +0000838 unsigned ObjCABI;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000839
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +0000840 // gc ivar layout bitmap calculation helper caches.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000841 SmallVector<GC_IVAR, 16> SkipIvars;
842 SmallVector<GC_IVAR, 16> IvarsInfo;
Fariborz Jahaniane11dba82012-10-25 21:15:04 +0000843
844 // arc/mrr layout of captured block literal variables.
845 SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000846
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000847 /// LazySymbols - Symbols to generate a lazy reference for. See
848 /// DefinedSymbols and FinishModule().
Daniel Dunbar33063492009-09-07 00:20:42 +0000849 llvm::SetVector<IdentifierInfo*> LazySymbols;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000850
Daniel Dunbar242d4dc2008-08-25 06:02:07 +0000851 /// DefinedSymbols - External symbols which are defined by this
852 /// module. The symbols in this list and LazySymbols are used to add
853 /// special linker symbols which ensure that Objective-C modules are
854 /// linked properly.
Daniel Dunbar33063492009-09-07 00:20:42 +0000855 llvm::SetVector<IdentifierInfo*> DefinedSymbols;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000856
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +0000857 /// ClassNames - uniqued class names.
Stephen Hines176edba2014-12-01 14:53:08 -0800858 llvm::StringMap<llvm::GlobalVariable*> ClassNames;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000859
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000860 /// MethodVarNames - uniqued method variable names.
861 llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000862
Fariborz Jahanianb9c5b3d2010-06-21 22:05:18 +0000863 /// DefinedCategoryNames - list of category names in form Class_Category.
864 llvm::SetVector<std::string> DefinedCategoryNames;
865
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000866 /// MethodVarTypes - uniqued method type signatures. We have to use
867 /// a StringMap here because have no other unique reference.
868 llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000869
Daniel Dunbarc45ef602008-08-26 21:51:14 +0000870 /// MethodDefinitions - map of methods which have been defined in
871 /// this translation unit.
872 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000873
Daniel Dunbarc8ef5512008-08-23 00:19:03 +0000874 /// PropertyNames - uniqued method variable names.
875 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000876
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000877 /// ClassReferences - uniqued class references.
878 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000879
Daniel Dunbar259d93d2008-08-12 03:39:23 +0000880 /// SelectorReferences - uniqued selector references.
881 llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000882
Daniel Dunbar6efc0c52008-08-13 03:21:16 +0000883 /// Protocols - Protocols for which an objc_protocol structure has
884 /// been emitted. Forward declarations are handled by creating an
885 /// empty structure whose initializer is filled in when/if defined.
886 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000887
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +0000888 /// DefinedProtocols - Protocols which have actually been
889 /// defined. We should not need this, see FIXME in GenerateProtocol.
890 llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000891
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000892 /// DefinedClasses - List of defined classes.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000893 SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
Stephen Hines651f13c2014-04-23 16:59:28 -0700894
895 /// ImplementedClasses - List of @implemented classes.
896 SmallVector<const ObjCInterfaceDecl*, 16> ImplementedClasses;
Daniel Dunbar74d4b122009-05-15 22:33:15 +0000897
898 /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000899 SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000900
Daniel Dunbar27f9d772008-08-21 04:36:09 +0000901 /// DefinedCategories - List of defined categories.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000902 SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000903
Daniel Dunbar74d4b122009-05-15 22:33:15 +0000904 /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +0000905 SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000906
Fariborz Jahanian56210f72009-01-21 23:34:32 +0000907 /// GetNameForMethod - Return a name for the given method.
908 /// \param[out] NameOut - The return value.
909 void GetNameForMethod(const ObjCMethodDecl *OMD,
910 const ObjCContainerDecl *CD,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000911 SmallVectorImpl<char> &NameOut);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000912
Fariborz Jahanian56210f72009-01-21 23:34:32 +0000913 /// GetMethodVarName - Return a unique constant for the given
914 /// selector's name. The return value has type char *.
915 llvm::Constant *GetMethodVarName(Selector Sel);
916 llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000917
Fariborz Jahanian56210f72009-01-21 23:34:32 +0000918 /// GetMethodVarType - Return a unique constant for the given
Bob Wilsondc8dab62011-11-30 01:57:58 +0000919 /// method's type encoding string. The return value has type char *.
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000920
Fariborz Jahanian56210f72009-01-21 23:34:32 +0000921 // FIXME: This is a horrible name.
Bob Wilsondc8dab62011-11-30 01:57:58 +0000922 llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
923 bool Extended = false);
Daniel Dunbar3e5f0d82009-04-20 06:54:31 +0000924 llvm::Constant *GetMethodVarType(const FieldDecl *D);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000925
Fariborz Jahanian56210f72009-01-21 23:34:32 +0000926 /// GetPropertyName - Return a unique constant for the given
927 /// name. The return value has type char *.
928 llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000929
Fariborz Jahanian56210f72009-01-21 23:34:32 +0000930 // FIXME: This can be dropped once string functions are unified.
931 llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
932 const Decl *Container);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000933
Fariborz Jahanian058a1b72009-01-24 20:21:50 +0000934 /// GetClassName - Return a unique constant for the given selector's
Stephen Hines176edba2014-12-01 14:53:08 -0800935 /// runtime name (which may change via use of objc_runtime_name attribute on
936 /// class or protocol definition. The return value has type char *.
937 llvm::Constant *GetClassName(StringRef RuntimeName);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000938
Argyrios Kyrtzidis9d50c062010-08-09 10:54:20 +0000939 llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
940
Fariborz Jahaniand61a50a2009-03-05 22:39:55 +0000941 /// BuildIvarLayout - Builds ivar layout bitmap for the class
942 /// implementation for the __strong or __weak case.
943 ///
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +0000944 llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
945 bool ForStrongLayout);
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +0000946
Fariborz Jahanianb8fd2eb2010-08-05 00:19:48 +0000947 llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000948
Daniel Dunbard58edcb2009-05-03 14:10:34 +0000949 void BuildAggrIvarRecordLayout(const RecordType *RT,
Eli Friedmane5b46662012-11-06 22:15:52 +0000950 unsigned int BytePos, bool ForStrongLayout,
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000951 bool &HasUnion);
Daniel Dunbar5a5a8032009-05-03 21:05:10 +0000952 void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +0000953 const llvm::StructLayout *Layout,
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +0000954 const RecordDecl *RD,
Bill Wendling795b1002012-02-22 09:30:11 +0000955 ArrayRef<const FieldDecl*> RecFields,
Eli Friedmane5b46662012-11-06 22:15:52 +0000956 unsigned int BytePos, bool ForStrongLayout,
Fariborz Jahanian81adc052009-04-24 16:17:09 +0000957 bool &HasUnion);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +0000958
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +0000959 Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout);
Fariborz Jahanian44fcff92012-11-02 22:51:18 +0000960
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +0000961 void UpdateRunSkipBlockVars(bool IsByref,
962 Qualifiers::ObjCLifetime LifeTime,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +0000963 CharUnits FieldOffset,
964 CharUnits FieldSize);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +0000965
966 void BuildRCBlockVarRecordLayout(const RecordType *RT,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +0000967 CharUnits BytePos, bool &HasUnion,
968 bool ByrefLayout=false);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +0000969
970 void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
971 const RecordDecl *RD,
972 ArrayRef<const FieldDecl*> RecFields,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +0000973 CharUnits BytePos, bool &HasUnion,
974 bool ByrefLayout);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +0000975
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000976 uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
977
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +0000978 llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);
979
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +0000980
Fariborz Jahaniand80d81b2009-03-05 19:17:31 +0000981 /// GetIvarLayoutName - Returns a unique constant for the given
982 /// ivar layout bitmap.
983 llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
984 const ObjCCommonTypesHelper &ObjCTypes);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000985
Fariborz Jahanian5de14dc2009-01-28 22:18:42 +0000986 /// EmitPropertyList - Emit the given property list. The return
987 /// value has type PropertyListPtrTy.
Chris Lattner5f9e2722011-07-23 10:55:15 +0000988 llvm::Constant *EmitPropertyList(Twine Name,
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000989 const Decl *Container,
Fariborz Jahanian5de14dc2009-01-28 22:18:42 +0000990 const ObjCContainerDecl *OCD,
991 const ObjCCommonTypesHelper &ObjCTypes);
Daniel Dunbar6bff2512009-08-03 17:06:42 +0000992
Bob Wilsondc8dab62011-11-30 01:57:58 +0000993 /// EmitProtocolMethodTypes - Generate the array of extended method type
994 /// strings. The return value has type Int8PtrPtrTy.
995 llvm::Constant *EmitProtocolMethodTypes(Twine Name,
Bill Wendlingbb028552012-02-07 09:25:09 +0000996 ArrayRef<llvm::Constant*> MethodTypes,
Bob Wilsondc8dab62011-11-30 01:57:58 +0000997 const ObjCCommonTypesHelper &ObjCTypes);
998
Fariborz Jahanian191dcd72009-12-12 21:26:21 +0000999 /// PushProtocolProperties - Push protocol's property on the input stack.
Bill Wendling3964e622012-02-09 22:16:49 +00001000 void PushProtocolProperties(
1001 llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00001002 SmallVectorImpl<llvm::Constant*> &Properties,
Bill Wendling3964e622012-02-09 22:16:49 +00001003 const Decl *Container,
Stephen Hines651f13c2014-04-23 16:59:28 -07001004 const ObjCProtocolDecl *Proto,
Bill Wendling3964e622012-02-09 22:16:49 +00001005 const ObjCCommonTypesHelper &ObjCTypes);
Fariborz Jahanian191dcd72009-12-12 21:26:21 +00001006
Fariborz Jahanianda320092009-01-29 19:24:30 +00001007 /// GetProtocolRef - Return a reference to the internal protocol
1008 /// description, creating an empty one if it has not been
1009 /// defined. The return value has type ProtocolPtrTy.
1010 llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
Fariborz Jahanianb21f07e2009-03-08 20:18:37 +00001011
Daniel Dunbarfd65d372009-03-09 20:09:19 +00001012 /// CreateMetadataVar - Create a global variable with internal
1013 /// linkage for use by the Objective-C runtime.
1014 ///
1015 /// This is a convenience wrapper which not only creates the
1016 /// variable, but also sets the section and alignment and adds the
Chris Lattnerad64e022009-07-17 23:57:13 +00001017 /// global to the "llvm.used" list.
Daniel Dunbar35bd7632009-03-09 20:50:13 +00001018 ///
1019 /// \param Name - The variable name.
1020 /// \param Init - The variable initializer; this is also used to
1021 /// define the type of the variable.
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001022 /// \param Section - The section the variable should go into, or empty.
Daniel Dunbar35bd7632009-03-09 20:50:13 +00001023 /// \param Align - The alignment for the variable, or 0.
1024 /// \param AddToUsed - Whether the variable should be added to
Daniel Dunbarc1583062009-04-14 17:42:51 +00001025 /// "llvm.used".
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001026 llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,
1027 StringRef Section, unsigned Align,
Daniel Dunbar35bd7632009-03-09 20:50:13 +00001028 bool AddToUsed);
Daniel Dunbarfd65d372009-03-09 20:09:19 +00001029
John McCall944c8432011-05-14 03:10:52 +00001030 CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1031 ReturnValueSlot Return,
1032 QualType ResultType,
1033 llvm::Value *Sel,
1034 llvm::Value *Arg0,
1035 QualType Arg0Ty,
1036 bool IsSuper,
1037 const CallArgList &CallArgs,
1038 const ObjCMethodDecl *OMD,
1039 const ObjCCommonTypesHelper &ObjCTypes);
Daniel Dunbar3e5f0d82009-04-20 06:54:31 +00001040
Daniel Dunbarfce176b2010-04-25 20:39:01 +00001041 /// EmitImageInfo - Emit the image info marker used to encode some module
1042 /// level information.
1043 void EmitImageInfo();
1044
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001045public:
Owen Anderson69243822009-07-13 04:10:07 +00001046 CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
John McCallde5d3c72012-02-17 03:33:10 +00001047 CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001048
Stephen Hines651f13c2014-04-23 16:59:28 -07001049 llvm::Constant *GenerateConstantString(const StringLiteral *SL) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001050
Stephen Hines651f13c2014-04-23 16:59:28 -07001051 llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001052 const ObjCContainerDecl *CD=nullptr) override;
Stephen Hines651f13c2014-04-23 16:59:28 -07001053
1054 void GenerateProtocol(const ObjCProtocolDecl *PD) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001055
Fariborz Jahanianda320092009-01-29 19:24:30 +00001056 /// GetOrEmitProtocol - Get the protocol object for the given
1057 /// declaration, emitting it if necessary. The return value has type
1058 /// ProtocolPtrTy.
1059 virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001060
Fariborz Jahanianda320092009-01-29 19:24:30 +00001061 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1062 /// object for the given declaration, emitting it if needed. These
1063 /// forward references will be filled in with empty bodies if no
1064 /// definition is seen. The return value has type ProtocolPtrTy.
1065 virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
Stephen Hines651f13c2014-04-23 16:59:28 -07001066 llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1067 const CGBlockInfo &blockInfo) override;
1068 llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1069 const CGBlockInfo &blockInfo) override;
1070
1071 llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1072 QualType T) override;
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001073};
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001074
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001075class CGObjCMac : public CGObjCCommonMac {
1076private:
1077 ObjCTypesHelper ObjCTypes;
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001078
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001079 /// EmitModuleInfo - Another marker encoding module level
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001080 /// information.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001081 void EmitModuleInfo();
1082
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001083 /// EmitModuleSymols - Emit module symbols, the list of defined
1084 /// classes and categories. The result has type SymtabPtrTy.
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00001085 llvm::Constant *EmitModuleSymbols();
1086
Daniel Dunbarf77ac862008-08-11 21:35:06 +00001087 /// FinishModule - Write out global data structures at the end of
1088 /// processing a translation unit.
1089 void FinishModule();
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001090
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001091 /// EmitClassExtension - Generate the class extension structure used
1092 /// to store the weak ivar layout and properties. The return value
1093 /// has type ClassExtensionPtrTy.
1094 llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
1095
1096 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1097 /// for the given class.
John McCallbd7370a2013-02-28 19:01:20 +00001098 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001099 const ObjCInterfaceDecl *ID);
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00001100
John McCallbd7370a2013-02-28 19:01:20 +00001101 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
John McCallf85e1932011-06-15 23:02:42 +00001102 IdentifierInfo *II);
Stephen Hines651f13c2014-04-23 16:59:28 -07001103
1104 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1105
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00001106 /// EmitSuperClassRef - Emits reference to class's main metadata class.
1107 llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001108
1109 /// EmitIvarList - Emit the ivar list for the given
1110 /// implementation. If ForClass is true the list of class ivars
1111 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1112 /// interface ivars will be emitted. The return value has type
1113 /// IvarListPtrTy.
1114 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
Fariborz Jahanian46b86c62009-01-28 19:12:34 +00001115 bool ForClass);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001116
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001117 /// EmitMetaClass - Emit a forward reference to the class structure
1118 /// for the metaclass of the given interface. The return value has
1119 /// type ClassPtrTy.
1120 llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1121
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001122 /// EmitMetaClass - Emit a class structure for the metaclass of the
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001123 /// given implementation. The return value has type ClassPtrTy.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001124 llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1125 llvm::Constant *Protocols,
Bill Wendlingbb028552012-02-07 09:25:09 +00001126 ArrayRef<llvm::Constant*> Methods);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001127
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001128 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001129
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001130 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001131
1132 /// EmitMethodList - Emit the method list for the given
Daniel Dunbaraf05bb92008-08-26 08:29:31 +00001133 /// implementation. The return value has type MethodListPtrTy.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001134 llvm::Constant *EmitMethodList(Twine Name,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00001135 const char *Section,
Bill Wendlingbb028552012-02-07 09:25:09 +00001136 ArrayRef<llvm::Constant*> Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001137
1138 /// EmitMethodDescList - Emit a method description list for a list of
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001139 /// method declarations.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001140 /// - TypeName: The name for the type containing the methods.
Sylvestre Ledruf3477c12012-09-27 10:16:10 +00001141 /// - IsProtocol: True iff these methods are for a protocol.
1142 /// - ClassMethds: True iff these are class methods.
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001143 /// - Required: When true, only "required" methods are
1144 /// listed. Similarly, when false only "optional" methods are
1145 /// listed. For classes this should always be true.
1146 /// - begin, end: The method list to output.
1147 ///
1148 /// The return value has type MethodDescriptionListPtrTy.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001149 llvm::Constant *EmitMethodDescList(Twine Name,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001150 const char *Section,
Bill Wendlingbb028552012-02-07 09:25:09 +00001151 ArrayRef<llvm::Constant*> Methods);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001152
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00001153 /// GetOrEmitProtocol - Get the protocol object for the given
1154 /// declaration, emitting it if necessary. The return value has type
1155 /// ProtocolPtrTy.
Stephen Hines651f13c2014-04-23 16:59:28 -07001156 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00001157
1158 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1159 /// object for the given declaration, emitting it if needed. These
1160 /// forward references will be filled in with empty bodies if no
1161 /// definition is seen. The return value has type ProtocolPtrTy.
Stephen Hines651f13c2014-04-23 16:59:28 -07001162 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00001163
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001164 /// EmitProtocolExtension - Generate the protocol extension
1165 /// structure used to store optional instance and class methods, and
1166 /// protocol properties. The return value has type
1167 /// ProtocolExtensionPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +00001168 llvm::Constant *
1169 EmitProtocolExtension(const ObjCProtocolDecl *PD,
Bill Wendlingbb028552012-02-07 09:25:09 +00001170 ArrayRef<llvm::Constant*> OptInstanceMethods,
1171 ArrayRef<llvm::Constant*> OptClassMethods,
1172 ArrayRef<llvm::Constant*> MethodTypesExt);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001173
1174 /// EmitProtocolList - Generate the list of referenced
1175 /// protocols. The return value has type ProtocolListPtrTy.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001176 llvm::Constant *EmitProtocolList(Twine Name,
Daniel Dunbardbc933702008-08-21 21:57:41 +00001177 ObjCProtocolDecl::protocol_iterator begin,
1178 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00001179
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001180 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1181 /// for the given selector.
John McCallbd7370a2013-02-28 19:01:20 +00001182 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
Fariborz Jahanian03b29602010-06-17 19:56:20 +00001183 bool lval=false);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001184
1185public:
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001186 CGObjCMac(CodeGen::CodeGenModule &cgm);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001187
Stephen Hines651f13c2014-04-23 16:59:28 -07001188 llvm::Function *ModuleInitFunction() override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001189
Stephen Hines651f13c2014-04-23 16:59:28 -07001190 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1191 ReturnValueSlot Return,
1192 QualType ResultType,
1193 Selector Sel, llvm::Value *Receiver,
1194 const CallArgList &CallArgs,
1195 const ObjCInterfaceDecl *Class,
1196 const ObjCMethodDecl *Method) override;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001197
Stephen Hines651f13c2014-04-23 16:59:28 -07001198 CodeGen::RValue
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001199 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Stephen Hines651f13c2014-04-23 16:59:28 -07001200 ReturnValueSlot Return, QualType ResultType,
1201 Selector Sel, const ObjCInterfaceDecl *Class,
1202 bool isCategoryImpl, llvm::Value *Receiver,
1203 bool IsClassMessage, const CallArgList &CallArgs,
1204 const ObjCMethodDecl *Method) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001205
Stephen Hines651f13c2014-04-23 16:59:28 -07001206 llvm::Value *GetClass(CodeGenFunction &CGF,
1207 const ObjCInterfaceDecl *ID) override;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001208
Stephen Hines651f13c2014-04-23 16:59:28 -07001209 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
1210 bool lval = false) override;
Fariborz Jahaniandf9ccc62009-05-05 21:36:57 +00001211
1212 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1213 /// untyped one.
Stephen Hines651f13c2014-04-23 16:59:28 -07001214 llvm::Value *GetSelector(CodeGenFunction &CGF,
1215 const ObjCMethodDecl *Method) override;
Fariborz Jahaniandf9ccc62009-05-05 21:36:57 +00001216
Stephen Hines651f13c2014-04-23 16:59:28 -07001217 llvm::Constant *GetEHType(QualType T) override;
John McCall5a180392010-07-24 00:37:23 +00001218
Stephen Hines651f13c2014-04-23 16:59:28 -07001219 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001220
Stephen Hines651f13c2014-04-23 16:59:28 -07001221 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001222
Stephen Hines651f13c2014-04-23 16:59:28 -07001223 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
David Chisnall29254f42012-01-31 18:59:20 +00001224
Stephen Hines651f13c2014-04-23 16:59:28 -07001225 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1226 const ObjCProtocolDecl *PD) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001227
Stephen Hines651f13c2014-04-23 16:59:28 -07001228 llvm::Constant *GetPropertyGetFunction() override;
1229 llvm::Constant *GetPropertySetFunction() override;
1230 llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1231 bool copy) override;
1232 llvm::Constant *GetGetStructFunction() override;
1233 llvm::Constant *GetSetStructFunction() override;
1234 llvm::Constant *GetCppAtomicObjectGetFunction() override;
1235 llvm::Constant *GetCppAtomicObjectSetFunction() override;
1236 llvm::Constant *EnumerationMutationFunction() override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001237
Stephen Hines651f13c2014-04-23 16:59:28 -07001238 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1239 const ObjCAtTryStmt &S) override;
1240 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1241 const ObjCAtSynchronizedStmt &S) override;
John McCallf1549f62010-07-06 01:34:17 +00001242 void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
Stephen Hines651f13c2014-04-23 16:59:28 -07001243 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1244 bool ClearInsertionPoint=true) override;
1245 llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1246 llvm::Value *AddrWeakObj) override;
1247 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1248 llvm::Value *src, llvm::Value *dst) override;
1249 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1250 llvm::Value *src, llvm::Value *dest,
1251 bool threadlocal = false) override;
1252 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1253 llvm::Value *src, llvm::Value *dest,
1254 llvm::Value *ivarOffset) override;
1255 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1256 llvm::Value *src, llvm::Value *dest) override;
1257 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1258 llvm::Value *dest, llvm::Value *src,
1259 llvm::Value *size) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001260
Stephen Hines651f13c2014-04-23 16:59:28 -07001261 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1262 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1263 unsigned CVRQualifiers) override;
1264 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1265 const ObjCInterfaceDecl *Interface,
1266 const ObjCIvarDecl *Ivar) override;
1267
Fariborz Jahanian6f40e222011-05-17 22:21:16 +00001268 /// GetClassGlobal - Return the global variable for the Objective-C
1269 /// class of the given name.
Stephen Hines651f13c2014-04-23 16:59:28 -07001270 llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
1271 bool Weak = false) override {
David Blaikieb219cfc2011-09-23 05:06:16 +00001272 llvm_unreachable("CGObjCMac::GetClassGlobal");
Fariborz Jahanian6f40e222011-05-17 22:21:16 +00001273 }
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001274};
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001275
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00001276class CGObjCNonFragileABIMac : public CGObjCCommonMac {
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001277private:
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00001278 ObjCNonFragileABITypesHelper ObjCTypes;
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00001279 llvm::GlobalVariable* ObjCEmptyCacheVar;
1280 llvm::GlobalVariable* ObjCEmptyVtableVar;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001281
Daniel Dunbar11394522009-04-18 08:51:00 +00001282 /// SuperClassReferences - uniqued super class references.
1283 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001284
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00001285 /// MetaClassReferences - uniqued meta class references.
1286 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
Daniel Dunbare588b992009-03-01 04:46:24 +00001287
1288 /// EHTypeReferences - uniqued class ehtype references.
1289 llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001290
John McCall944c8432011-05-14 03:10:52 +00001291 /// VTableDispatchMethods - List of methods for which we generate
1292 /// vtable-based message dispatch.
1293 llvm::DenseSet<Selector> VTableDispatchMethods;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001294
Fariborz Jahaniana03d0dd2009-11-17 21:37:35 +00001295 /// DefinedMetaClasses - List of defined meta-classes.
1296 std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1297
John McCall944c8432011-05-14 03:10:52 +00001298 /// isVTableDispatchedSelector - Returns true if SEL is a
1299 /// vtable-based selector.
1300 bool isVTableDispatchedSelector(Selector Sel);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001301
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00001302 /// FinishNonFragileABIModule - Write out global data structures at the end of
1303 /// processing a translation unit.
1304 void FinishNonFragileABIModule();
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00001305
Daniel Dunbar463b8762009-05-15 21:48:48 +00001306 /// AddModuleClassList - Add the given list of class pointers to the
1307 /// module with the provided symbol and section names.
Bill Wendlingbb028552012-02-07 09:25:09 +00001308 void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
Daniel Dunbar463b8762009-05-15 21:48:48 +00001309 const char *SymbolName,
1310 const char *SectionName);
1311
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001312 llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1313 unsigned InstanceStart,
1314 unsigned InstanceSize,
1315 const ObjCImplementationDecl *ID);
Stephen Hines176edba2014-12-01 14:53:08 -08001316 llvm::GlobalVariable * BuildClassMetaData(const std::string &ClassName,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001317 llvm::Constant *IsAGV,
Fariborz Jahanian84394a52009-01-24 21:21:53 +00001318 llvm::Constant *SuperClassGV,
Fariborz Jahaniancf555162009-01-31 00:59:10 +00001319 llvm::Constant *ClassRoGV,
Stephen Hines651f13c2014-04-23 16:59:28 -07001320 bool HiddenVisibility,
1321 bool Weak);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001322
Fariborz Jahanian493dab72009-01-26 21:38:32 +00001323 llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001324
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00001325 llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001326
Fariborz Jahanian493dab72009-01-26 21:38:32 +00001327 /// EmitMethodList - Emit the method list for the given
1328 /// implementation. The return value has type MethodListnfABITy.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001329 llvm::Constant *EmitMethodList(Twine Name,
Fariborz Jahanian493dab72009-01-26 21:38:32 +00001330 const char *Section,
Bill Wendlingbb028552012-02-07 09:25:09 +00001331 ArrayRef<llvm::Constant*> Methods);
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00001332 /// EmitIvarList - Emit the ivar list for the given
1333 /// implementation. If ForClass is true the list of class ivars
1334 /// (i.e. metaclass ivars) is emitted, otherwise the list of
1335 /// interface ivars will be emitted. The return value has type
1336 /// IvarListnfABIPtrTy.
1337 llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001338
Fariborz Jahanianed157d32009-02-10 20:21:06 +00001339 llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
Fariborz Jahanian2fa5a272009-01-28 01:36:42 +00001340 const ObjCIvarDecl *Ivar,
Eli Friedmane5b46662012-11-06 22:15:52 +00001341 unsigned long int offset);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001342
Fariborz Jahanianda320092009-01-29 19:24:30 +00001343 /// GetOrEmitProtocol - Get the protocol object for the given
1344 /// declaration, emitting it if necessary. The return value has type
1345 /// ProtocolPtrTy.
Stephen Hines651f13c2014-04-23 16:59:28 -07001346 llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001347
Fariborz Jahanianda320092009-01-29 19:24:30 +00001348 /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1349 /// object for the given declaration, emitting it if needed. These
1350 /// forward references will be filled in with empty bodies if no
1351 /// definition is seen. The return value has type ProtocolPtrTy.
Stephen Hines651f13c2014-04-23 16:59:28 -07001352 llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001353
Fariborz Jahanianda320092009-01-29 19:24:30 +00001354 /// EmitProtocolList - Generate the list of referenced
1355 /// protocols. The return value has type ProtocolListPtrTy.
Chris Lattner5f9e2722011-07-23 10:55:15 +00001356 llvm::Constant *EmitProtocolList(Twine Name,
Fariborz Jahanianda320092009-01-29 19:24:30 +00001357 ObjCProtocolDecl::protocol_iterator begin,
Fariborz Jahanian46551122009-02-04 00:22:57 +00001358 ObjCProtocolDecl::protocol_iterator end);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001359
John McCall944c8432011-05-14 03:10:52 +00001360 CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1361 ReturnValueSlot Return,
1362 QualType ResultType,
1363 Selector Sel,
1364 llvm::Value *Receiver,
1365 QualType Arg0Ty,
1366 bool IsSuper,
1367 const CallArgList &CallArgs,
1368 const ObjCMethodDecl *Method);
Fariborz Jahanian6f40e222011-05-17 22:21:16 +00001369
Daniel Dunbar5a7379a2009-03-01 04:40:10 +00001370 /// GetClassGlobal - Return the global variable for the Objective-C
1371 /// class of the given name.
Stephen Hines651f13c2014-04-23 16:59:28 -07001372 llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
1373 bool Weak = false) override;
1374
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00001375 /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
Daniel Dunbar11394522009-04-18 08:51:00 +00001376 /// for the given class reference.
John McCallbd7370a2013-02-28 19:01:20 +00001377 llvm::Value *EmitClassRef(CodeGenFunction &CGF,
Daniel Dunbar11394522009-04-18 08:51:00 +00001378 const ObjCInterfaceDecl *ID);
John McCallf85e1932011-06-15 23:02:42 +00001379
John McCallbd7370a2013-02-28 19:01:20 +00001380 llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
Stephen Hines176edba2014-12-01 14:53:08 -08001381 IdentifierInfo *II, bool Weak,
1382 const ObjCInterfaceDecl *ID);
Stephen Hines651f13c2014-04-23 16:59:28 -07001383
1384 llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001385
Daniel Dunbar11394522009-04-18 08:51:00 +00001386 /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1387 /// for the given super class reference.
John McCallbd7370a2013-02-28 19:01:20 +00001388 llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001389 const ObjCInterfaceDecl *ID);
1390
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00001391 /// EmitMetaClassRef - Return a Value * of the address of _class_t
1392 /// meta-data
John McCallbd7370a2013-02-28 19:01:20 +00001393 llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
Stephen Hinesc568f1e2014-07-21 00:47:37 -07001394 const ObjCInterfaceDecl *ID, bool Weak);
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00001395
Fariborz Jahanianed157d32009-02-10 20:21:06 +00001396 /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1397 /// the given ivar.
1398 ///
Daniel Dunbar5e88bea2009-04-19 00:31:15 +00001399 llvm::GlobalVariable * ObjCIvarOffsetVariable(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001400 const ObjCInterfaceDecl *ID,
1401 const ObjCIvarDecl *Ivar);
1402
Fariborz Jahanian26cc89f2009-02-11 20:51:17 +00001403 /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1404 /// for the given selector.
John McCallbd7370a2013-02-28 19:01:20 +00001405 llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
Fariborz Jahanian03b29602010-06-17 19:56:20 +00001406 bool lval=false);
Daniel Dunbare588b992009-03-01 04:46:24 +00001407
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00001408 /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
Daniel Dunbare588b992009-03-01 04:46:24 +00001409 /// interface. The return value has type EHTypePtrTy.
John McCall5a180392010-07-24 00:37:23 +00001410 llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00001411 bool ForDefinition);
Daniel Dunbar6ab187a2009-04-07 05:48:37 +00001412
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001413 const char *getMetaclassSymbolPrefix() const {
Daniel Dunbar6ab187a2009-04-07 05:48:37 +00001414 return "OBJC_METACLASS_$_";
1415 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001416
Daniel Dunbar6ab187a2009-04-07 05:48:37 +00001417 const char *getClassSymbolPrefix() const {
1418 return "OBJC_CLASS_$_";
1419 }
1420
Daniel Dunbar9f89f2b2009-05-03 12:57:56 +00001421 void GetClassSizeInfo(const ObjCImplementationDecl *OID,
Daniel Dunbarb02532a2009-04-19 23:41:48 +00001422 uint32_t &InstanceStart,
1423 uint32_t &InstanceSize);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001424
Fariborz Jahanian4523eb02009-05-12 20:06:41 +00001425 // Shamelessly stolen from Analysis/CFRefCount.cpp
Daniel Dunbar74d4b122009-05-15 22:33:15 +00001426 Selector GetNullarySelector(const char* name) const {
Fariborz Jahanian4523eb02009-05-12 20:06:41 +00001427 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1428 return CGM.getContext().Selectors.getSelector(0, &II);
1429 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001430
Daniel Dunbar74d4b122009-05-15 22:33:15 +00001431 Selector GetUnarySelector(const char* name) const {
Fariborz Jahanian4523eb02009-05-12 20:06:41 +00001432 IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1433 return CGM.getContext().Selectors.getSelector(1, &II);
1434 }
Daniel Dunbarb02532a2009-04-19 23:41:48 +00001435
Daniel Dunbar74d4b122009-05-15 22:33:15 +00001436 /// ImplementationIsNonLazy - Check whether the given category or
1437 /// class implementation is "non-lazy".
Fariborz Jahanianecfbdcb2009-05-21 01:03:45 +00001438 bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
Daniel Dunbar74d4b122009-05-15 22:33:15 +00001439
Saleem Abdulrasool961f5702013-02-17 04:03:34 +00001440 bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
Saleem Abdulrasool961f5702013-02-17 04:03:34 +00001441 const ObjCIvarDecl *IV) {
Stephen Hines651f13c2014-04-23 16:59:28 -07001442 // Annotate the load as an invariant load iff inside an instance method
1443 // and ivar belongs to instance method's class and one of its super class.
1444 // This check is needed because the ivar offset is a lazily
Saleem Abdulrasool961f5702013-02-17 04:03:34 +00001445 // initialised value that may depend on objc_msgSend to perform a fixup on
1446 // the first message dispatch.
1447 //
1448 // An additional opportunity to mark the load as invariant arises when the
1449 // base of the ivar access is a parameter to an Objective C method.
1450 // However, because the parameters are not available in the current
1451 // interface, we cannot perform this check.
Stephen Hines651f13c2014-04-23 16:59:28 -07001452 if (const ObjCMethodDecl *MD =
1453 dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
1454 if (MD->isInstanceMethod())
1455 if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
1456 return IV->getContainingInterface()->isSuperClassOf(ID);
Saleem Abdulrasool961f5702013-02-17 04:03:34 +00001457 return false;
1458 }
1459
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001460public:
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00001461 CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00001462 // FIXME. All stubs for now!
Stephen Hines651f13c2014-04-23 16:59:28 -07001463 llvm::Function *ModuleInitFunction() override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001464
Stephen Hines651f13c2014-04-23 16:59:28 -07001465 CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1466 ReturnValueSlot Return,
1467 QualType ResultType, Selector Sel,
1468 llvm::Value *Receiver,
1469 const CallArgList &CallArgs,
1470 const ObjCInterfaceDecl *Class,
1471 const ObjCMethodDecl *Method) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001472
Stephen Hines651f13c2014-04-23 16:59:28 -07001473 CodeGen::RValue
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00001474 GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
Stephen Hines651f13c2014-04-23 16:59:28 -07001475 ReturnValueSlot Return, QualType ResultType,
1476 Selector Sel, const ObjCInterfaceDecl *Class,
1477 bool isCategoryImpl, llvm::Value *Receiver,
1478 bool IsClassMessage, const CallArgList &CallArgs,
1479 const ObjCMethodDecl *Method) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001480
Stephen Hines651f13c2014-04-23 16:59:28 -07001481 llvm::Value *GetClass(CodeGenFunction &CGF,
1482 const ObjCInterfaceDecl *ID) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001483
Stephen Hines651f13c2014-04-23 16:59:28 -07001484 llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
1485 bool lvalue = false) override
John McCallbd7370a2013-02-28 19:01:20 +00001486 { return EmitSelector(CGF, Sel, lvalue); }
Fariborz Jahaniandf9ccc62009-05-05 21:36:57 +00001487
1488 /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1489 /// untyped one.
Stephen Hines651f13c2014-04-23 16:59:28 -07001490 llvm::Value *GetSelector(CodeGenFunction &CGF,
1491 const ObjCMethodDecl *Method) override
John McCallbd7370a2013-02-28 19:01:20 +00001492 { return EmitSelector(CGF, Method->getSelector()); }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001493
Stephen Hines651f13c2014-04-23 16:59:28 -07001494 void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001495
Stephen Hines651f13c2014-04-23 16:59:28 -07001496 void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
David Chisnall29254f42012-01-31 18:59:20 +00001497
Stephen Hines651f13c2014-04-23 16:59:28 -07001498 void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
David Chisnall29254f42012-01-31 18:59:20 +00001499
Stephen Hines651f13c2014-04-23 16:59:28 -07001500 llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1501 const ObjCProtocolDecl *PD) override;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001502
Stephen Hines651f13c2014-04-23 16:59:28 -07001503 llvm::Constant *GetEHType(QualType T) override;
John McCall5a180392010-07-24 00:37:23 +00001504
Stephen Hines651f13c2014-04-23 16:59:28 -07001505 llvm::Constant *GetPropertyGetFunction() override {
Chris Lattner72db6c32009-04-22 02:44:54 +00001506 return ObjCTypes.getGetPropertyFn();
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00001507 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001508 llvm::Constant *GetPropertySetFunction() override {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001509 return ObjCTypes.getSetPropertyFn();
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00001510 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001511
1512 llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1513 bool copy) override {
Ted Kremenekebcb57a2012-03-06 20:05:56 +00001514 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1515 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001516
1517 llvm::Constant *GetSetStructFunction() override {
David Chisnall8fac25d2010-12-26 22:13:16 +00001518 return ObjCTypes.getCopyStructFn();
1519 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001520 llvm::Constant *GetGetStructFunction() override {
Fariborz Jahanian6cc59062010-04-12 18:18:10 +00001521 return ObjCTypes.getCopyStructFn();
1522 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001523 llvm::Constant *GetCppAtomicObjectSetFunction() override {
David Chisnalld397cfe2012-12-17 18:54:24 +00001524 return ObjCTypes.getCppAtomicObjectFunction();
1525 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001526 llvm::Constant *GetCppAtomicObjectGetFunction() override {
Fariborz Jahaniane3173022012-01-06 18:07:23 +00001527 return ObjCTypes.getCppAtomicObjectFunction();
1528 }
Stephen Hines651f13c2014-04-23 16:59:28 -07001529
1530 llvm::Constant *EnumerationMutationFunction() override {
Chris Lattner72db6c32009-04-22 02:44:54 +00001531 return ObjCTypes.getEnumerationMutationFn();
Daniel Dunbar28ed0842009-02-16 18:48:45 +00001532 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001533
Stephen Hines651f13c2014-04-23 16:59:28 -07001534 void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1535 const ObjCAtTryStmt &S) override;
1536 void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1537 const ObjCAtSynchronizedStmt &S) override;
1538 void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1539 bool ClearInsertionPoint=true) override;
1540 llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1541 llvm::Value *AddrWeakObj) override;
1542 void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1543 llvm::Value *src, llvm::Value *dst) override;
1544 void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1545 llvm::Value *src, llvm::Value *dest,
1546 bool threadlocal = false) override;
1547 void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1548 llvm::Value *src, llvm::Value *dest,
1549 llvm::Value *ivarOffset) override;
1550 void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1551 llvm::Value *src, llvm::Value *dest) override;
1552 void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1553 llvm::Value *dest, llvm::Value *src,
1554 llvm::Value *size) override;
1555 LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1556 llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1557 unsigned CVRQualifiers) override;
1558 llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1559 const ObjCInterfaceDecl *Interface,
1560 const ObjCIvarDecl *Ivar) override;
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001561};
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001562
1563/// A helper class for performing the null-initialization of a return
1564/// value.
1565struct NullReturnState {
1566 llvm::BasicBlock *NullBB;
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001567 NullReturnState() : NullBB(nullptr) {}
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001568
John McCall06098582013-02-12 05:53:35 +00001569 /// Perform a null-check of the given receiver.
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001570 void init(CodeGenFunction &CGF, llvm::Value *receiver) {
John McCall06098582013-02-12 05:53:35 +00001571 // Make blocks for the null-receiver and call edges.
1572 NullBB = CGF.createBasicBlock("msgSend.null-receiver");
1573 llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001574
1575 // Check for a null receiver and, if there is one, jump to the
John McCall06098582013-02-12 05:53:35 +00001576 // null-receiver block. There's no point in trying to avoid it:
1577 // we're always going to put *something* there, because otherwise
1578 // we shouldn't have done this null-check in the first place.
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001579 llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1580 CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1581
1582 // Otherwise, start performing the call.
1583 CGF.EmitBlock(callBB);
1584 }
1585
John McCall06098582013-02-12 05:53:35 +00001586 /// Complete the null-return operation. It is valid to call this
1587 /// regardless of whether 'init' has been called.
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001588 RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
1589 const CallArgList &CallArgs,
1590 const ObjCMethodDecl *Method) {
John McCall06098582013-02-12 05:53:35 +00001591 // If we never had to do a null-check, just use the raw result.
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001592 if (!NullBB) return result;
John McCall06098582013-02-12 05:53:35 +00001593
1594 // The continuation block. This will be left null if we don't have an
1595 // IP, which can happen if the method we're calling is marked noreturn.
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001596 llvm::BasicBlock *contBB = nullptr;
1597
John McCall06098582013-02-12 05:53:35 +00001598 // Finish the call path.
1599 llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
1600 if (callBB) {
1601 contBB = CGF.createBasicBlock("msgSend.cont");
1602 CGF.Builder.CreateBr(contBB);
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001603 }
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001604
John McCall06098582013-02-12 05:53:35 +00001605 // Okay, start emitting the null-receiver block.
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001606 CGF.EmitBlock(NullBB);
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001607
John McCall06098582013-02-12 05:53:35 +00001608 // Release any consumed arguments we've got.
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001609 if (Method) {
1610 CallArgList::const_iterator I = CallArgs.begin();
1611 for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1612 e = Method->param_end(); i != e; ++i, ++I) {
1613 const ParmVarDecl *ParamDecl = (*i);
1614 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1615 RValue RV = I->RV;
1616 assert(RV.isScalar() &&
1617 "NullReturnState::complete - arg not on object");
John McCall5b07e802013-03-13 03:10:54 +00001618 CGF.EmitARCRelease(RV.getScalarVal(), ARCImpreciseLifetime);
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001619 }
1620 }
1621 }
John McCall06098582013-02-12 05:53:35 +00001622
1623 // The phi code below assumes that we haven't needed any control flow yet.
1624 assert(CGF.Builder.GetInsertBlock() == NullBB);
1625
1626 // If we've got a void return, just jump to the continuation block.
1627 if (result.isScalar() && resultType->isVoidType()) {
1628 // No jumps required if the message-send was noreturn.
1629 if (contBB) CGF.EmitBlock(contBB);
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001630 return result;
1631 }
1632
John McCall06098582013-02-12 05:53:35 +00001633 // If we've got a scalar return, build a phi.
1634 if (result.isScalar()) {
1635 // Derive the null-initialization value.
1636 llvm::Constant *null = CGF.CGM.EmitNullConstant(resultType);
1637
1638 // If no join is necessary, just flow out.
1639 if (!contBB) return RValue::get(null);
1640
1641 // Otherwise, build a phi.
1642 CGF.EmitBlock(contBB);
1643 llvm::PHINode *phi = CGF.Builder.CreatePHI(null->getType(), 2);
1644 phi->addIncoming(result.getScalarVal(), callBB);
1645 phi->addIncoming(null, NullBB);
1646 return RValue::get(phi);
1647 }
1648
1649 // If we've got an aggregate return, null the buffer out.
1650 // FIXME: maybe we should be doing things differently for all the
1651 // cases where the ABI has us returning (1) non-agg values in
1652 // memory or (2) agg values in registers.
1653 if (result.isAggregate()) {
1654 assert(result.isAggregate() && "null init of non-aggregate result?");
1655 CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1656 if (contBB) CGF.EmitBlock(contBB);
1657 return result;
1658 }
1659
1660 // Complex types.
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001661 CGF.EmitBlock(contBB);
John McCall06098582013-02-12 05:53:35 +00001662 CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();
1663
1664 // Find the scalar type and its zero value.
1665 llvm::Type *scalarTy = callResult.first->getType();
1666 llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1667
1668 // Build phis for both coordinates.
1669 llvm::PHINode *real = CGF.Builder.CreatePHI(scalarTy, 2);
1670 real->addIncoming(callResult.first, callBB);
1671 real->addIncoming(scalarZero, NullBB);
1672 llvm::PHINode *imag = CGF.Builder.CreatePHI(scalarTy, 2);
1673 imag->addIncoming(callResult.second, callBB);
1674 imag->addIncoming(scalarZero, NullBB);
1675 return RValue::getComplex(real, imag);
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001676 }
1677};
1678
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001679} // end anonymous namespace
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001680
1681/* *** Helper Functions *** */
1682
1683/// getConstantGEP() - Help routine to construct simple GEPs.
Owen Andersona1cf15f2009-07-14 23:10:40 +00001684static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001685 llvm::Constant *C,
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001686 unsigned idx0,
1687 unsigned idx1) {
1688 llvm::Value *Idxs[] = {
Owen Anderson0032b272009-08-13 21:57:51 +00001689 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1690 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001691 };
Jay Foada5c04342011-07-21 14:31:17 +00001692 return llvm::ConstantExpr::getGetElementPtr(C, Idxs);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001693}
1694
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00001695/// hasObjCExceptionAttribute - Return true if this class or any super
1696/// class has the __objc_exception__ attribute.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001697static bool hasObjCExceptionAttribute(ASTContext &Context,
Douglas Gregor68584ed2009-06-18 16:11:24 +00001698 const ObjCInterfaceDecl *OID) {
Argyrios Kyrtzidis40b598e2009-06-30 02:34:44 +00001699 if (OID->hasAttr<ObjCExceptionAttr>())
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00001700 return true;
1701 if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
Douglas Gregor68584ed2009-06-18 16:11:24 +00001702 return hasObjCExceptionAttribute(Context, Super);
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00001703 return false;
1704}
1705
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001706/* *** CGObjCMac Public Interface *** */
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001707
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001708CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
Mike Stump1eb44332009-09-09 15:08:12 +00001709 ObjCTypes(cgm) {
Fariborz Jahanianee0af742009-01-21 22:04:16 +00001710 ObjCABI = 1;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001711 EmitImageInfo();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001712}
1713
Daniel Dunbarddb2a3d2008-08-16 00:25:02 +00001714/// GetClass - Return a reference to the class for the given interface
1715/// decl.
John McCallbd7370a2013-02-28 19:01:20 +00001716llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00001717 const ObjCInterfaceDecl *ID) {
John McCallbd7370a2013-02-28 19:01:20 +00001718 return EmitClassRef(CGF, ID);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001719}
1720
1721/// GetSelector - Return the pointer to the unique'd string for this selector.
John McCallbd7370a2013-02-28 19:01:20 +00001722llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel,
Fariborz Jahanian03b29602010-06-17 19:56:20 +00001723 bool lval) {
John McCallbd7370a2013-02-28 19:01:20 +00001724 return EmitSelector(CGF, Sel, lval);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001725}
John McCallbd7370a2013-02-28 19:01:20 +00001726llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001727 *Method) {
John McCallbd7370a2013-02-28 19:01:20 +00001728 return EmitSelector(CGF, Method->getSelector());
Fariborz Jahaniandf9ccc62009-05-05 21:36:57 +00001729}
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001730
Fariborz Jahaniancf5abc72011-06-23 19:00:08 +00001731llvm::Constant *CGObjCMac::GetEHType(QualType T) {
Fariborz Jahanian9d96bce2011-06-22 20:21:51 +00001732 if (T->isObjCIdType() ||
1733 T->isObjCQualifiedIdType()) {
1734 return CGM.GetAddrOfRTTIDescriptor(
Douglas Gregor01a4cf12011-08-11 20:58:55 +00001735 CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
Fariborz Jahanian9d96bce2011-06-22 20:21:51 +00001736 }
Fariborz Jahaniancf5abc72011-06-23 19:00:08 +00001737 if (T->isObjCClassType() ||
1738 T->isObjCQualifiedClassType()) {
1739 return CGM.GetAddrOfRTTIDescriptor(
Douglas Gregor01a4cf12011-08-11 20:58:55 +00001740 CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
Fariborz Jahaniancf5abc72011-06-23 19:00:08 +00001741 }
1742 if (T->isObjCObjectPointerType())
1743 return CGM.GetAddrOfRTTIDescriptor(T, /*ForEH=*/true);
1744
John McCall5a180392010-07-24 00:37:23 +00001745 llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
John McCall5a180392010-07-24 00:37:23 +00001746}
1747
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001748/// Generate a constant CFString object.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001749/*
1750 struct __builtin_CFString {
1751 const int *isa; // point to __CFConstantStringClassReference
1752 int flags;
1753 const char *str;
1754 long length;
1755 };
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00001756*/
1757
Fariborz Jahanian33e982b2010-04-22 20:26:39 +00001758/// or Generate a constant NSString object.
1759/*
1760 struct __builtin_NSString {
1761 const int *isa; // point to __NSConstantStringClassReference
1762 const char *str;
1763 unsigned int length;
1764 };
1765*/
1766
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00001767llvm::Constant *CGObjCCommonMac::GenerateConstantString(
David Chisnall0d13f6f2010-01-23 02:40:42 +00001768 const StringLiteral *SL) {
David Blaikie4e4d0842012-03-11 07:00:24 +00001769 return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
Fariborz Jahanian33e982b2010-04-22 20:26:39 +00001770 CGM.GetAddrOfConstantCFString(SL) :
Fariborz Jahanian4c733072010-10-19 17:19:29 +00001771 CGM.GetAddrOfConstantString(SL));
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001772}
1773
Ted Kremenekebcb57a2012-03-06 20:05:56 +00001774enum {
1775 kCFTaggedObjectID_Integer = (1 << 1) + 1
1776};
1777
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001778/// Generates a message send where the super is the receiver. This is
1779/// a message send to self with special delivery semantics indicating
1780/// which class's method should be called.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001781CodeGen::RValue
1782CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
John McCallef072fd2010-05-22 01:48:05 +00001783 ReturnValueSlot Return,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +00001784 QualType ResultType,
1785 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001786 const ObjCInterfaceDecl *Class,
Fariborz Jahanian7ce77922009-02-28 20:07:56 +00001787 bool isCategoryImpl,
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001788 llvm::Value *Receiver,
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00001789 bool IsClassMessage,
Daniel Dunbard6c93d72009-09-17 04:01:22 +00001790 const CodeGen::CallArgList &CallArgs,
1791 const ObjCMethodDecl *Method) {
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001792 // Create and init a super structure; this is a (receiver, class)
1793 // pair we will pass to objc_msgSendSuper.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001794 llvm::Value *ObjCSuper =
John McCall604da292011-03-04 08:00:29 +00001795 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001796 llvm::Value *ReceiverAsObject =
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001797 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001798 CGF.Builder.CreateStore(ReceiverAsObject,
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001799 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbare8b470d2008-08-23 04:28:29 +00001800
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001801 // If this is a class message the metaclass is passed as the target.
1802 llvm::Value *Target;
1803 if (IsClassMessage) {
Fariborz Jahanian7ce77922009-02-28 20:07:56 +00001804 if (isCategoryImpl) {
1805 // Message sent to 'super' in a class method defined in a category
1806 // implementation requires an odd treatment.
1807 // If we are in a class method, we must retrieve the
1808 // _metaclass_ for the current class, pointed at by
1809 // the class's "isa" pointer. The following assumes that
1810 // isa" is the first ivar in a class (which it must be).
John McCallbd7370a2013-02-28 19:01:20 +00001811 Target = EmitClassRef(CGF, Class->getSuperClass());
Fariborz Jahanian7ce77922009-02-28 20:07:56 +00001812 Target = CGF.Builder.CreateStructGEP(Target, 0);
1813 Target = CGF.Builder.CreateLoad(Target);
Mike Stumpb3589f42009-07-30 22:28:39 +00001814 } else {
Fariborz Jahanian7ce77922009-02-28 20:07:56 +00001815 llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
1816 llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
1817 llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1818 Target = Super;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001819 }
Fariborz Jahanian182f2682009-11-14 02:18:31 +00001820 }
1821 else if (isCategoryImpl)
John McCallbd7370a2013-02-28 19:01:20 +00001822 Target = EmitClassRef(CGF, Class->getSuperClass());
Fariborz Jahanian182f2682009-11-14 02:18:31 +00001823 else {
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00001824 llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1825 ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1826 Target = CGF.Builder.CreateLoad(ClassPtr);
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001827 }
Mike Stumpf5408fe2009-05-16 07:57:57 +00001828 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1829 // ObjCTypes types.
Chris Lattner2acc6e32011-07-18 04:24:23 +00001830 llvm::Type *ClassTy =
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00001831 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00001832 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001833 CGF.Builder.CreateStore(Target,
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001834 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
John McCall944c8432011-05-14 03:10:52 +00001835 return EmitMessageSend(CGF, Return, ResultType,
John McCallbd7370a2013-02-28 19:01:20 +00001836 EmitSelector(CGF, Sel),
John McCall944c8432011-05-14 03:10:52 +00001837 ObjCSuper, ObjCTypes.SuperPtrCTy,
1838 true, CallArgs, Method, ObjCTypes);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001839}
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001840
1841/// Generate code for a message send expression.
Daniel Dunbar8f2926b2008-08-23 03:46:30 +00001842CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
John McCallef072fd2010-05-22 01:48:05 +00001843 ReturnValueSlot Return,
Daniel Dunbar7f8ea5c2008-08-30 05:35:15 +00001844 QualType ResultType,
1845 Selector Sel,
Daniel Dunbarf56f1912008-08-25 08:19:24 +00001846 llvm::Value *Receiver,
Fariborz Jahaniandf9ccc62009-05-05 21:36:57 +00001847 const CallArgList &CallArgs,
David Chisnallc6cd5fd2010-04-28 19:33:36 +00001848 const ObjCInterfaceDecl *Class,
Fariborz Jahaniandf9ccc62009-05-05 21:36:57 +00001849 const ObjCMethodDecl *Method) {
John McCall944c8432011-05-14 03:10:52 +00001850 return EmitMessageSend(CGF, Return, ResultType,
John McCallbd7370a2013-02-28 19:01:20 +00001851 EmitSelector(CGF, Sel),
John McCall944c8432011-05-14 03:10:52 +00001852 Receiver, CGF.getContext().getObjCIdType(),
1853 false, CallArgs, Method, ObjCTypes);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00001854}
1855
Daniel Dunbard6c93d72009-09-17 04:01:22 +00001856CodeGen::RValue
John McCall944c8432011-05-14 03:10:52 +00001857CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1858 ReturnValueSlot Return,
1859 QualType ResultType,
1860 llvm::Value *Sel,
1861 llvm::Value *Arg0,
1862 QualType Arg0Ty,
1863 bool IsSuper,
1864 const CallArgList &CallArgs,
1865 const ObjCMethodDecl *Method,
1866 const ObjCCommonTypesHelper &ObjCTypes) {
Daniel Dunbar19cd87e2008-08-30 03:02:31 +00001867 CallArgList ActualArgs;
Fariborz Jahaniand019d962009-04-24 21:07:43 +00001868 if (!IsSuper)
Benjamin Kramer578faa82011-09-27 21:06:10 +00001869 Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
Eli Friedman04c9a492011-05-02 17:57:46 +00001870 ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1871 ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
John McCallf85e1932011-06-15 23:02:42 +00001872 ActualArgs.addFrom(CallArgs);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001873
John McCallde5d3c72012-02-17 03:33:10 +00001874 // If we're calling a method, use the formal signature.
1875 MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001876
Anders Carlsson7e70fb22010-06-21 20:59:55 +00001877 if (Method)
Stephen Hines651f13c2014-04-23 16:59:28 -07001878 assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
1879 CGM.getContext().getCanonicalType(ResultType) &&
Anders Carlsson7e70fb22010-06-21 20:59:55 +00001880 "Result type mismatch!");
1881
John McCallcba681a2011-05-14 21:12:11 +00001882 NullReturnState nullReturn;
1883
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001884 llvm::Constant *Fn = nullptr;
Stephen Hines651f13c2014-04-23 16:59:28 -07001885 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
Fariborz Jahanian4e1524b2012-01-29 20:27:13 +00001886 if (!IsSuper) nullReturn.init(CGF, Arg0);
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +00001887 Fn = (ObjCABI == 2) ? ObjCTypes.getSendStretFn2(IsSuper)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001888 : ObjCTypes.getSendStretFn(IsSuper);
Daniel Dunbardacf9dd2010-07-14 23:39:36 +00001889 } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1890 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1891 : ObjCTypes.getSendFpretFn(IsSuper);
Anders Carlssoneea64802011-10-31 16:27:11 +00001892 } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1893 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1894 : ObjCTypes.getSendFp2retFn(IsSuper);
Daniel Dunbar5669e572008-10-17 03:24:53 +00001895 } else {
Stephen Hines651f13c2014-04-23 16:59:28 -07001896 // arm64 uses objc_msgSend for stret methods and yet null receiver check
1897 // must be made for it.
1898 if (!IsSuper && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
1899 nullReturn.init(CGF, Arg0);
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +00001900 Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00001901 : ObjCTypes.getSendFn(IsSuper);
Daniel Dunbar5669e572008-10-17 03:24:53 +00001902 }
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001903
1904 bool requiresnullCheck = false;
David Blaikie4e4d0842012-03-11 07:00:24 +00001905 if (CGM.getLangOpts().ObjCAutoRefCount && Method)
Stephen Hines651f13c2014-04-23 16:59:28 -07001906 for (const auto *ParamDecl : Method->params()) {
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001907 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1908 if (!nullReturn.NullBB)
1909 nullReturn.init(CGF, Arg0);
1910 requiresnullCheck = true;
1911 break;
1912 }
1913 }
1914
John McCallde5d3c72012-02-17 03:33:10 +00001915 Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1916 RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
Fariborz Jahanian3c267e62012-01-30 21:40:37 +00001917 return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07001918 requiresnullCheck ? Method : nullptr);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00001919}
1920
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00001921static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
1922 if (FQT.isObjCGCStrong())
1923 return Qualifiers::Strong;
1924
John McCallf85e1932011-06-15 23:02:42 +00001925 if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00001926 return Qualifiers::Weak;
1927
Fariborz Jahanianba83c952012-02-16 00:15:02 +00001928 // check for __unsafe_unretained
1929 if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
1930 return Qualifiers::GCNone;
1931
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00001932 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1933 return Qualifiers::Strong;
1934
1935 if (const PointerType *PT = FQT->getAs<PointerType>())
1936 return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
1937
1938 return Qualifiers::GCNone;
1939}
1940
John McCall6b5a61b2011-02-07 10:33:21 +00001941llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
1942 const CGBlockInfo &blockInfo) {
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00001943
Chris Lattner8b418682012-02-07 00:39:47 +00001944 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
David Blaikie4e4d0842012-03-11 07:00:24 +00001945 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
1946 !CGM.getLangOpts().ObjCAutoRefCount)
John McCall6b5a61b2011-02-07 10:33:21 +00001947 return nullPtr;
1948
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +00001949 bool hasUnion = false;
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00001950 SkipIvars.clear();
1951 IvarsInfo.clear();
John McCall64aa4b32013-04-16 22:48:15 +00001952 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
1953 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00001954
Fariborz Jahanian81979822010-09-09 00:21:45 +00001955 // __isa is the first field in block descriptor and must assume by runtime's
1956 // convention that it is GC'able.
Eli Friedmane5b46662012-11-06 22:15:52 +00001957 IvarsInfo.push_back(GC_IVAR(0, 1));
John McCall6b5a61b2011-02-07 10:33:21 +00001958
1959 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
1960
1961 // Calculate the basic layout of the block structure.
1962 const llvm::StructLayout *layout =
Micah Villmow25a6a842012-10-08 16:25:52 +00001963 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
John McCall6b5a61b2011-02-07 10:33:21 +00001964
1965 // Ignore the optional 'this' capture: C++ objects are not assumed
1966 // to be GC'ed.
1967
1968 // Walk the captured variables.
Stephen Hines651f13c2014-04-23 16:59:28 -07001969 for (const auto &CI : blockDecl->captures()) {
1970 const VarDecl *variable = CI.getVariable();
John McCall6b5a61b2011-02-07 10:33:21 +00001971 QualType type = variable->getType();
1972
1973 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
1974
1975 // Ignore constant captures.
1976 if (capture.isConstant()) continue;
1977
Eli Friedmane5b46662012-11-06 22:15:52 +00001978 uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
John McCall6b5a61b2011-02-07 10:33:21 +00001979
1980 // __block variables are passed by their descriptor address.
Stephen Hines651f13c2014-04-23 16:59:28 -07001981 if (CI.isByRef()) {
Eli Friedmane5b46662012-11-06 22:15:52 +00001982 IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
Fariborz Jahanianc5904b42010-09-11 01:27:29 +00001983 continue;
John McCall6b5a61b2011-02-07 10:33:21 +00001984 }
1985
1986 assert(!type->isArrayType() && "array variable should not be caught");
1987 if (const RecordType *record = type->getAs<RecordType>()) {
1988 BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
Fariborz Jahaniane1a48982010-08-05 21:00:25 +00001989 continue;
1990 }
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +00001991
John McCall6b5a61b2011-02-07 10:33:21 +00001992 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
Eli Friedmane5b46662012-11-06 22:15:52 +00001993 unsigned fieldSize = CGM.getContext().getTypeSize(type);
John McCall6b5a61b2011-02-07 10:33:21 +00001994
1995 if (GCAttr == Qualifiers::Strong)
Eli Friedmane5b46662012-11-06 22:15:52 +00001996 IvarsInfo.push_back(GC_IVAR(fieldOffset,
1997 fieldSize / WordSizeInBits));
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00001998 else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
Eli Friedmane5b46662012-11-06 22:15:52 +00001999 SkipIvars.push_back(GC_IVAR(fieldOffset,
2000 fieldSize / ByteSizeInBits));
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00002001 }
2002
2003 if (IvarsInfo.empty())
John McCall6b5a61b2011-02-07 10:33:21 +00002004 return nullPtr;
2005
2006 // Sort on byte position; captures might not be allocated in order,
2007 // and unions can do funny things.
2008 llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
2009 llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00002010
2011 std::string BitMap;
Fariborz Jahanianb8fd2eb2010-08-05 00:19:48 +00002012 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
David Blaikie4e4d0842012-03-11 07:00:24 +00002013 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00002014 printf("\n block variable layout for block: ");
Roman Divacky31ba6132012-09-06 15:59:27 +00002015 const unsigned char *s = (const unsigned char*)BitMap.c_str();
Bill Wendling13562a12012-02-07 09:06:01 +00002016 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00002017 if (!(s[i] & 0xf0))
2018 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2019 else
2020 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
2021 printf("\n");
2022 }
2023
2024 return C;
Fariborz Jahanian89ecd412010-08-04 16:57:49 +00002025}
2026
Fariborz Jahanianc441cd32012-11-04 18:19:40 +00002027/// getBlockCaptureLifetime - This routine returns life time of the captured
2028/// block variable for the purpose of block layout meta-data generation. FQT is
2029/// the type of the variable captured in the block.
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002030Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
2031 bool ByrefLayout) {
Fariborz Jahanian44fcff92012-11-02 22:51:18 +00002032 if (CGM.getLangOpts().ObjCAutoRefCount)
2033 return FQT.getObjCLifetime();
2034
Fariborz Jahanianc441cd32012-11-04 18:19:40 +00002035 // MRR.
Fariborz Jahanian44fcff92012-11-02 22:51:18 +00002036 if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002037 return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
Fariborz Jahanian44fcff92012-11-02 22:51:18 +00002038
2039 return Qualifiers::OCL_None;
2040}
2041
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002042void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
2043 Qualifiers::ObjCLifetime LifeTime,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002044 CharUnits FieldOffset,
2045 CharUnits FieldSize) {
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002046 // __block variables are passed by their descriptor address.
2047 if (IsByref)
2048 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002049 FieldSize));
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002050 else if (LifeTime == Qualifiers::OCL_Strong)
2051 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002052 FieldSize));
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002053 else if (LifeTime == Qualifiers::OCL_Weak)
2054 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002055 FieldSize));
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002056 else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2057 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002058 FieldSize));
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002059 else
2060 RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2061 FieldOffset,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002062 FieldSize));
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002063}
2064
2065void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
2066 const RecordDecl *RD,
2067 ArrayRef<const FieldDecl*> RecFields,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002068 CharUnits BytePos, bool &HasUnion,
2069 bool ByrefLayout) {
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002070 bool IsUnion = (RD && RD->isUnion());
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002071 CharUnits MaxUnionSize = CharUnits::Zero();
Stephen Hines6bcf27b2014-05-29 04:14:42 -07002072 const FieldDecl *MaxField = nullptr;
2073 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002074 CharUnits MaxFieldOffset = CharUnits::Zero();
2075 CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002076
2077 if (RecFields.empty())
2078 return;
John McCall64aa4b32013-04-16 22:48:15 +00002079 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002080
2081 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2082 const FieldDecl *Field = RecFields[i];
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002083 // Note that 'i' here is actually the field index inside RD of Field,
2084 // although this dependency is hidden.
2085 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002086 CharUnits FieldOffset =
2087 CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002088
2089 // Skip over unnamed or bitfields
2090 if (!Field->getIdentifier() || Field->isBitField()) {
2091 LastFieldBitfieldOrUnnamed = Field;
2092 LastBitfieldOrUnnamedOffset = FieldOffset;
2093 continue;
2094 }
Stephen Hines6bcf27b2014-05-29 04:14:42 -07002095
2096 LastFieldBitfieldOrUnnamed = nullptr;
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002097 QualType FQT = Field->getType();
2098 if (FQT->isRecordType() || FQT->isUnionType()) {
2099 if (FQT->isUnionType())
2100 HasUnion = true;
2101
2102 BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(),
2103 BytePos + FieldOffset, HasUnion);
2104 continue;
2105 }
2106
2107 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2108 const ConstantArrayType *CArray =
2109 dyn_cast_or_null<ConstantArrayType>(Array);
2110 uint64_t ElCount = CArray->getSize().getZExtValue();
2111 assert(CArray && "only array with known element size is supported");
2112 FQT = CArray->getElementType();
2113 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2114 const ConstantArrayType *CArray =
2115 dyn_cast_or_null<ConstantArrayType>(Array);
2116 ElCount *= CArray->getSize().getZExtValue();
2117 FQT = CArray->getElementType();
2118 }
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002119 if (FQT->isRecordType() && ElCount) {
2120 int OldIndex = RunSkipBlockVars.size() - 1;
2121 const RecordType *RT = FQT->getAs<RecordType>();
2122 BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2123 HasUnion);
2124
2125 // Replicate layout information for each array element. Note that
2126 // one element is already done.
2127 uint64_t ElIx = 1;
2128 for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002129 CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002130 for (int i = OldIndex+1; i <= FirstIndex; ++i)
2131 RunSkipBlockVars.push_back(
2132 RUN_SKIP(RunSkipBlockVars[i].opcode,
2133 RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2134 RunSkipBlockVars[i].block_var_size));
2135 }
2136 continue;
2137 }
2138 }
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002139 CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002140 if (IsUnion) {
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002141 CharUnits UnionIvarSize = FieldSize;
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002142 if (UnionIvarSize > MaxUnionSize) {
2143 MaxUnionSize = UnionIvarSize;
2144 MaxField = Field;
2145 MaxFieldOffset = FieldOffset;
2146 }
2147 } else {
2148 UpdateRunSkipBlockVars(false,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002149 getBlockCaptureLifetime(FQT, ByrefLayout),
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002150 BytePos + FieldOffset,
2151 FieldSize);
2152 }
2153 }
2154
2155 if (LastFieldBitfieldOrUnnamed) {
2156 if (LastFieldBitfieldOrUnnamed->isBitField()) {
2157 // Last field was a bitfield. Must update the info.
2158 uint64_t BitFieldSize
2159 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002160 unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
Eli Friedmane5b46662012-11-06 22:15:52 +00002161 ((BitFieldSize % ByteSizeInBits) != 0);
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002162 CharUnits Size = CharUnits::fromQuantity(UnsSize);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002163 Size += LastBitfieldOrUnnamedOffset;
2164 UpdateRunSkipBlockVars(false,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002165 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2166 ByrefLayout),
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002167 BytePos + LastBitfieldOrUnnamedOffset,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002168 Size);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002169 } else {
2170 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
2171 // Last field was unnamed. Must update skip info.
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002172 CharUnits FieldSize
2173 = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002174 UpdateRunSkipBlockVars(false,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002175 getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2176 ByrefLayout),
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002177 BytePos + LastBitfieldOrUnnamedOffset,
2178 FieldSize);
2179 }
2180 }
2181
2182 if (MaxField)
2183 UpdateRunSkipBlockVars(false,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002184 getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002185 BytePos + MaxFieldOffset,
2186 MaxUnionSize);
2187}
2188
2189void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002190 CharUnits BytePos,
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002191 bool &HasUnion,
2192 bool ByrefLayout) {
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002193 const RecordDecl *RD = RT->getDecl();
Stephen Hines651f13c2014-04-23 16:59:28 -07002194 SmallVector<const FieldDecl*, 16> Fields(RD->fields());
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002195 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
2196 const llvm::StructLayout *RecLayout =
2197 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2198
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002199 BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002200}
2201
Fariborz Jahanianf22ae652012-11-01 18:32:55 +00002202/// InlineLayoutInstruction - This routine produce an inline instruction for the
2203/// block variable layout if it can. If not, it returns 0. Rules are as follow:
2204/// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit world,
2205/// an inline layout of value 0x0000000000000xyz is interpreted as follows:
2206/// x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by
2207/// y captured object of BLOCK_LAYOUT_BYREF. Followed by
2208/// z captured object of BLOCK_LAYOUT_WEAK. If any of the above is missing, zero
2209/// replaces it. For example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no
2210/// BLOCK_LAYOUT_BYREF and no BLOCK_LAYOUT_WEAK objects are captured.
2211uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2212 SmallVectorImpl<unsigned char> &Layout) {
2213 uint64_t Result = 0;
2214 if (Layout.size() <= 3) {
2215 unsigned size = Layout.size();
2216 unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2217 unsigned char inst;
2218 enum BLOCK_LAYOUT_OPCODE opcode ;
2219 switch (size) {
2220 case 3:
2221 inst = Layout[0];
2222 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2223 if (opcode == BLOCK_LAYOUT_STRONG)
2224 strong_word_count = (inst & 0xF)+1;
2225 else
2226 return 0;
2227 inst = Layout[1];
2228 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2229 if (opcode == BLOCK_LAYOUT_BYREF)
2230 byref_word_count = (inst & 0xF)+1;
2231 else
2232 return 0;
2233 inst = Layout[2];
2234 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2235 if (opcode == BLOCK_LAYOUT_WEAK)
2236 weak_word_count = (inst & 0xF)+1;
2237 else
2238 return 0;
2239 break;
2240
2241 case 2:
2242 inst = Layout[0];
2243 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2244 if (opcode == BLOCK_LAYOUT_STRONG) {
2245 strong_word_count = (inst & 0xF)+1;
2246 inst = Layout[1];
2247 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2248 if (opcode == BLOCK_LAYOUT_BYREF)
2249 byref_word_count = (inst & 0xF)+1;
2250 else if (opcode == BLOCK_LAYOUT_WEAK)
2251 weak_word_count = (inst & 0xF)+1;
2252 else
2253 return 0;
2254 }
2255 else if (opcode == BLOCK_LAYOUT_BYREF) {
2256 byref_word_count = (inst & 0xF)+1;
2257 inst = Layout[1];
2258 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2259 if (opcode == BLOCK_LAYOUT_WEAK)
2260 weak_word_count = (inst & 0xF)+1;
2261 else
2262 return 0;
2263 }
2264 else
2265 return 0;
2266 break;
2267
2268 case 1:
2269 inst = Layout[0];
2270 opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2271 if (opcode == BLOCK_LAYOUT_STRONG)
2272 strong_word_count = (inst & 0xF)+1;
2273 else if (opcode == BLOCK_LAYOUT_BYREF)
2274 byref_word_count = (inst & 0xF)+1;
2275 else if (opcode == BLOCK_LAYOUT_WEAK)
2276 weak_word_count = (inst & 0xF)+1;
2277 else
2278 return 0;
2279 break;
2280
2281 default:
2282 return 0;
2283 }
2284
2285 // Cannot inline when any of the word counts is 15. Because this is one less
2286 // than the actual work count (so 15 means 16 actual word counts),
2287 // and we can only display 0 thru 15 word counts.
2288 if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2289 return 0;
2290
2291 unsigned count =
2292 (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2293
2294 if (size == count) {
2295 if (strong_word_count)
2296 Result = strong_word_count;
2297 Result <<= 4;
2298 if (byref_word_count)
2299 Result += byref_word_count;
2300 Result <<= 4;
2301 if (weak_word_count)
2302 Result += weak_word_count;
2303 }
2304 }
2305 return Result;
2306}
2307
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002308llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
2309 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2310 if (RunSkipBlockVars.empty())
2311 return nullPtr;
John McCall64aa4b32013-04-16 22:48:15 +00002312 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2313 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002314 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2315
2316 // Sort on byte position; captures might not be allocated in order,
2317 // and unions can do funny things.
2318 llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2319 SmallVector<unsigned char, 16> Layout;
2320
2321 unsigned size = RunSkipBlockVars.size();
2322 for (unsigned i = 0; i < size; i++) {
2323 enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2324 CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2325 CharUnits end_byte_pos = start_byte_pos;
2326 unsigned j = i+1;
2327 while (j < size) {
2328 if (opcode == RunSkipBlockVars[j].opcode) {
2329 end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2330 i++;
2331 }
2332 else
2333 break;
2334 }
2335 CharUnits size_in_bytes =
2336 end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2337 if (j < size) {
2338 CharUnits gap =
2339 RunSkipBlockVars[j].block_var_bytepos -
2340 RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2341 size_in_bytes += gap;
2342 }
2343 CharUnits residue_in_bytes = CharUnits::Zero();
2344 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2345 residue_in_bytes = size_in_bytes % WordSizeInBytes;
2346 size_in_bytes -= residue_in_bytes;
2347 opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2348 }
2349
2350 unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
2351 while (size_in_words >= 16) {
2352 // Note that value in imm. is one less that the actual
2353 // value. So, 0xf means 16 words follow!
2354 unsigned char inst = (opcode << 4) | 0xf;
2355 Layout.push_back(inst);
2356 size_in_words -= 16;
2357 }
2358 if (size_in_words > 0) {
2359 // Note that value in imm. is one less that the actual
2360 // value. So, we subtract 1 away!
2361 unsigned char inst = (opcode << 4) | (size_in_words-1);
2362 Layout.push_back(inst);
2363 }
2364 if (residue_in_bytes > CharUnits::Zero()) {
2365 unsigned char inst =
2366 (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.getQuantity()-1);
2367 Layout.push_back(inst);
2368 }
2369 }
2370
2371 int e = Layout.size()-1;
2372 while (e >= 0) {
2373 unsigned char inst = Layout[e--];
2374 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2375 if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2376 Layout.pop_back();
2377 else
2378 break;
2379 }
2380
2381 uint64_t Result = InlineLayoutInstruction(Layout);
2382 if (Result != 0) {
2383 // Block variable layout instruction has been inlined.
2384 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2385 if (ComputeByrefLayout)
2386 printf("\n Inline instruction for BYREF variable layout: ");
2387 else
2388 printf("\n Inline instruction for block variable layout: ");
Benjamin Kramer23bde7d2013-04-22 16:10:38 +00002389 printf("0x0%" PRIx64 "\n", Result);
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002390 }
2391 if (WordSizeInBytes == 8) {
2392 const llvm::APInt Instruction(64, Result);
2393 return llvm::Constant::getIntegerValue(CGM.Int64Ty, Instruction);
2394 }
2395 else {
2396 const llvm::APInt Instruction(32, Result);
2397 return llvm::Constant::getIntegerValue(CGM.Int32Ty, Instruction);
2398 }
2399 }
2400
2401 unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2402 Layout.push_back(inst);
2403 std::string BitMap;
2404 for (unsigned i = 0, e = Layout.size(); i != e; i++)
2405 BitMap += Layout[i];
2406
2407 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2408 if (ComputeByrefLayout)
2409 printf("\n BYREF variable layout: ");
2410 else
2411 printf("\n block variable layout: ");
2412 for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
2413 unsigned char inst = BitMap[i];
2414 enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2415 unsigned delta = 1;
2416 switch (opcode) {
2417 case BLOCK_LAYOUT_OPERATOR:
2418 printf("BL_OPERATOR:");
2419 delta = 0;
2420 break;
2421 case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2422 printf("BL_NON_OBJECT_BYTES:");
2423 break;
2424 case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2425 printf("BL_NON_OBJECT_WORD:");
2426 break;
2427 case BLOCK_LAYOUT_STRONG:
2428 printf("BL_STRONG:");
2429 break;
2430 case BLOCK_LAYOUT_BYREF:
2431 printf("BL_BYREF:");
2432 break;
2433 case BLOCK_LAYOUT_WEAK:
2434 printf("BL_WEAK:");
2435 break;
2436 case BLOCK_LAYOUT_UNRETAINED:
2437 printf("BL_UNRETAINED:");
2438 break;
2439 }
2440 // Actual value of word count is one more that what is in the imm.
2441 // field of the instruction
2442 printf("%d", (inst & 0xf) + delta);
2443 if (i < e-1)
2444 printf(", ");
2445 else
2446 printf("\n");
2447 }
2448 }
Stephen Hines176edba2014-12-01 14:53:08 -08002449
2450 llvm::GlobalVariable *Entry = CreateMetadataVar(
2451 "OBJC_CLASS_NAME_",
2452 llvm::ConstantDataArray::getString(VMContext, BitMap, false),
2453 "__TEXT,__objc_classname,cstring_literals", 1, true);
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002454 return getConstantGEP(VMContext, Entry, 0, 0);
2455}
2456
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002457llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
2458 const CGBlockInfo &blockInfo) {
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002459 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2460
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002461 RunSkipBlockVars.clear();
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002462 bool hasUnion = false;
2463
John McCall64aa4b32013-04-16 22:48:15 +00002464 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2465 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002466 unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2467
2468 const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2469
2470 // Calculate the basic layout of the block structure.
2471 const llvm::StructLayout *layout =
2472 CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
2473
2474 // Ignore the optional 'this' capture: C++ objects are not assumed
2475 // to be GC'ed.
Fariborz Jahanianff685c52012-12-04 17:20:57 +00002476 if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
2477 UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,
2478 blockInfo.BlockHeaderForcedGapOffset,
2479 blockInfo.BlockHeaderForcedGapSize);
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002480 // Walk the captured variables.
Stephen Hines651f13c2014-04-23 16:59:28 -07002481 for (const auto &CI : blockDecl->captures()) {
2482 const VarDecl *variable = CI.getVariable();
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002483 QualType type = variable->getType();
2484
2485 const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2486
2487 // Ignore constant captures.
2488 if (capture.isConstant()) continue;
2489
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002490 CharUnits fieldOffset =
2491 CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002492
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002493 assert(!type->isArrayType() && "array variable should not be caught");
Stephen Hines651f13c2014-04-23 16:59:28 -07002494 if (!CI.isByRef())
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002495 if (const RecordType *record = type->getAs<RecordType>()) {
2496 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2497 continue;
2498 }
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002499 CharUnits fieldSize;
Stephen Hines651f13c2014-04-23 16:59:28 -07002500 if (CI.isByRef())
Fariborz Jahanian1da01d62012-11-07 20:00:32 +00002501 fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2502 else
2503 fieldSize = CGM.getContext().getTypeSizeInChars(type);
Stephen Hines651f13c2014-04-23 16:59:28 -07002504 UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
Fariborz Jahanianc6abe9e2012-10-30 20:05:29 +00002505 fieldOffset, fieldSize);
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002506 }
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002507 return getBitmapBlockLayout(false);
2508}
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002509
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002510
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002511llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
2512 QualType T) {
2513 assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2514 assert(!T->isArrayType() && "__block array variable should not be caught");
2515 CharUnits fieldOffset;
2516 RunSkipBlockVars.clear();
2517 bool hasUnion = false;
2518 if (const RecordType *record = T->getAs<RecordType>()) {
2519 BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion, true /*ByrefLayout */);
2520 llvm::Constant *Result = getBitmapBlockLayout(true);
2521 return Result;
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002522 }
Fariborz Jahanian3ca23d72012-11-14 17:15:51 +00002523 llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2524 return nullPtr;
Fariborz Jahanianc46b4352012-10-27 21:10:38 +00002525}
2526
John McCallbd7370a2013-02-28 19:01:20 +00002527llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
Daniel Dunbaraf2f62c2008-08-13 00:59:25 +00002528 const ObjCProtocolDecl *PD) {
Daniel Dunbarc67876d2008-09-04 04:33:15 +00002529 // FIXME: I don't understand why gcc generates this, or where it is
Mike Stumpf5408fe2009-05-16 07:57:57 +00002530 // resolved. Investigate. Its also wasteful to look this up over and over.
Daniel Dunbarc67876d2008-09-04 04:33:15 +00002531 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2532
Owen Anderson3c4972d2009-07-29 18:54:39 +00002533 return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
Douglas Gregor4c86fdb2012-01-17 18:36:30 +00002534 ObjCTypes.getExternalProtocolPtrTy());
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00002535}
2536
Fariborz Jahanianda320092009-01-29 19:24:30 +00002537void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
Mike Stumpf5408fe2009-05-16 07:57:57 +00002538 // FIXME: We shouldn't need this, the protocol decl should contain enough
2539 // information to tell us whether this was a declaration or a definition.
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002540 DefinedProtocols.insert(PD->getIdentifier());
2541
2542 // If we have generated a forward reference to this protocol, emit
2543 // it now. Otherwise do nothing, the protocol objects are lazily
2544 // emitted.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002545 if (Protocols.count(PD->getIdentifier()))
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002546 GetOrEmitProtocol(PD);
2547}
2548
Fariborz Jahanianda320092009-01-29 19:24:30 +00002549llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002550 if (DefinedProtocols.count(PD->getIdentifier()))
2551 return GetOrEmitProtocol(PD);
Douglas Gregorf968d832011-05-27 01:19:52 +00002552
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002553 return GetOrEmitProtocolRef(PD);
2554}
2555
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002556/*
Stephen Hines651f13c2014-04-23 16:59:28 -07002557// Objective-C 1.0 extensions
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002558struct _objc_protocol {
2559struct _objc_protocol_extension *isa;
2560char *protocol_name;
2561struct _objc_protocol_list *protocol_list;
2562struct _objc__method_prototype_list *instance_methods;
2563struct _objc__method_prototype_list *class_methods
2564};
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002565
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002566See EmitProtocolExtension().
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002567*/
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002568llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
John McCall50651b92012-03-30 21:29:05 +00002569 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002570
2571 // Early exit if a defining object has already been generated.
2572 if (Entry && Entry->hasInitializer())
2573 return Entry;
2574
Douglas Gregor1d784b22012-01-01 19:51:50 +00002575 // Use the protocol definition, if there is one.
2576 if (const ObjCProtocolDecl *Def = PD->getDefinition())
2577 PD = Def;
2578
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00002579 // FIXME: I don't understand why gcc generates this, or where it is
Mike Stumpf5408fe2009-05-16 07:57:57 +00002580 // resolved. Investigate. Its also wasteful to look this up over and over.
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00002581 LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2582
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002583 // Construct method lists.
2584 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2585 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
Bob Wilsondc8dab62011-11-30 01:57:58 +00002586 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
Stephen Hines651f13c2014-04-23 16:59:28 -07002587 for (const auto *MD : PD->instance_methods()) {
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002588 llvm::Constant *C = GetMethodDescriptionConstant(MD);
Douglas Gregorf968d832011-05-27 01:19:52 +00002589 if (!C)
2590 return GetOrEmitProtocolRef(PD);
2591
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002592 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2593 OptInstanceMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00002594 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002595 } else {
2596 InstanceMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00002597 MethodTypesExt.push_back(GetMethodVarType(MD, true));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002598 }
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002599 }
2600
Stephen Hines651f13c2014-04-23 16:59:28 -07002601 for (const auto *MD : PD->class_methods()) {
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002602 llvm::Constant *C = GetMethodDescriptionConstant(MD);
Douglas Gregorf968d832011-05-27 01:19:52 +00002603 if (!C)
2604 return GetOrEmitProtocolRef(PD);
2605
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002606 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2607 OptClassMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00002608 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002609 } else {
2610 ClassMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00002611 MethodTypesExt.push_back(GetMethodVarType(MD, true));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002612 }
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002613 }
2614
Bob Wilsondc8dab62011-11-30 01:57:58 +00002615 MethodTypesExt.insert(MethodTypesExt.end(),
2616 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2617
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00002618 llvm::Constant *Values[] = {
Stephen Hines176edba2014-12-01 14:53:08 -08002619 EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2620 MethodTypesExt),
2621 GetClassName(PD->getObjCRuntimeNameAsString()),
2622 EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),
2623 PD->protocol_begin(), PD->protocol_end()),
2624 EmitMethodDescList("OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
2625 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2626 InstanceMethods),
2627 EmitMethodDescList("OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
2628 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2629 ClassMethods)};
Owen Anderson08e25242009-07-27 22:29:56 +00002630 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002631 Values);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002632
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002633 if (Entry) {
Stephen Hines651f13c2014-04-23 16:59:28 -07002634 // Already created, update the initializer.
Stephen Hines6bcf27b2014-05-29 04:14:42 -07002635 assert(Entry->hasPrivateLinkage());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002636 Entry->setInitializer(Init);
2637 } else {
Stephen Hines176edba2014-12-01 14:53:08 -08002638 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
2639 false, llvm::GlobalValue::PrivateLinkage,
2640 Init, "OBJC_PROTOCOL_" + PD->getName());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002641 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002642 // FIXME: Is this necessary? Why only for protocol?
2643 Entry->setAlignment(4);
John McCall50651b92012-03-30 21:29:05 +00002644
2645 Protocols[PD->getIdentifier()] = Entry;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002646 }
Stephen Hines651f13c2014-04-23 16:59:28 -07002647 CGM.addCompilerUsedGlobal(Entry);
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002648
2649 return Entry;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002650}
2651
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002652llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002653 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
2654
2655 if (!Entry) {
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00002656 // We use the initializer as a marker of whether this is a forward
2657 // reference or not. At module finalization we add the empty
2658 // contents for protocols which were referenced but never defined.
Stephen Hines176edba2014-12-01 14:53:08 -08002659 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
2660 false, llvm::GlobalValue::PrivateLinkage,
2661 nullptr, "OBJC_PROTOCOL_" + PD->getName());
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002662 Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002663 // FIXME: Is this necessary? Why only for protocol?
2664 Entry->setAlignment(4);
2665 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002666
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002667 return Entry;
2668}
2669
2670/*
2671 struct _objc_protocol_extension {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002672 uint32_t size;
2673 struct objc_method_description_list *optional_instance_methods;
2674 struct objc_method_description_list *optional_class_methods;
2675 struct objc_property_list *instance_properties;
Bob Wilsondc8dab62011-11-30 01:57:58 +00002676 const char ** extendedMethodTypes;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002677 };
2678*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002679llvm::Constant *
2680CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
Bill Wendlingbb028552012-02-07 09:25:09 +00002681 ArrayRef<llvm::Constant*> OptInstanceMethods,
2682 ArrayRef<llvm::Constant*> OptClassMethods,
2683 ArrayRef<llvm::Constant*> MethodTypesExt) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002684 uint64_t Size =
Micah Villmow25a6a842012-10-08 16:25:52 +00002685 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00002686 llvm::Constant *Values[] = {
Stephen Hines176edba2014-12-01 14:53:08 -08002687 llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2688 EmitMethodDescList("OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" + PD->getName(),
2689 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2690 OptInstanceMethods),
2691 EmitMethodDescList("OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
2692 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2693 OptClassMethods),
2694 EmitPropertyList("OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD,
2695 ObjCTypes),
2696 EmitProtocolMethodTypes("OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
2697 MethodTypesExt, ObjCTypes)};
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002698
Daniel Dunbar27f9d772008-08-21 04:36:09 +00002699 // Return null if no extension bits are used.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002700 if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
Bob Wilsondc8dab62011-11-30 01:57:58 +00002701 Values[3]->isNullValue() && Values[4]->isNullValue())
Owen Andersonc9c88b42009-07-31 20:28:54 +00002702 return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002703
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002704 llvm::Constant *Init =
Owen Anderson08e25242009-07-27 22:29:56 +00002705 llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002706
Daniel Dunbar63c5b502009-03-09 21:49:58 +00002707 // No special section, but goes in llvm.used
Stephen Hinesc568f1e2014-07-21 00:47:37 -07002708 return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(), Init,
2709 StringRef(), 0, true);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002710}
2711
2712/*
2713 struct objc_protocol_list {
Bill Wendling3964e622012-02-09 22:16:49 +00002714 struct objc_protocol_list *next;
2715 long count;
2716 Protocol *list[];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002717 };
2718*/
Daniel Dunbardbc933702008-08-21 21:57:41 +00002719llvm::Constant *
Chris Lattner5f9e2722011-07-23 10:55:15 +00002720CGObjCMac::EmitProtocolList(Twine Name,
Daniel Dunbardbc933702008-08-21 21:57:41 +00002721 ObjCProtocolDecl::protocol_iterator begin,
2722 ObjCProtocolDecl::protocol_iterator end) {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002723 SmallVector<llvm::Constant *, 16> ProtocolRefs;
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002724
Daniel Dunbardbc933702008-08-21 21:57:41 +00002725 for (; begin != end; ++begin)
2726 ProtocolRefs.push_back(GetProtocolRef(*begin));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002727
2728 // Just return null for empty protocol lists
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002729 if (ProtocolRefs.empty())
Owen Andersonc9c88b42009-07-31 20:28:54 +00002730 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002731
Daniel Dunbar27f9d772008-08-21 04:36:09 +00002732 // This list is null terminated.
Owen Andersonc9c88b42009-07-31 20:28:54 +00002733 ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002734
Chris Lattnerc5cbb902011-06-20 04:01:35 +00002735 llvm::Constant *Values[3];
Daniel Dunbar27f9d772008-08-21 04:36:09 +00002736 // This field is only used by the runtime.
Owen Andersonc9c88b42009-07-31 20:28:54 +00002737 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
Owen Anderson4a28d5d2009-07-24 23:12:58 +00002738 Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002739 ProtocolRefs.size() - 1);
2740 Values[2] =
2741 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2742 ProtocolRefs.size()),
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002743 ProtocolRefs);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002744
Chris Lattnerc5cbb902011-06-20 04:01:35 +00002745 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002746 llvm::GlobalVariable *GV =
Daniel Dunbar63c5b502009-03-09 21:49:58 +00002747 CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
Daniel Dunbar58a29122009-03-09 22:18:41 +00002748 4, false);
Owen Anderson3c4972d2009-07-29 18:54:39 +00002749 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002750}
2751
Bill Wendlingbb028552012-02-07 09:25:09 +00002752void CGObjCCommonMac::
2753PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002754 SmallVectorImpl<llvm::Constant *> &Properties,
Bill Wendlingbb028552012-02-07 09:25:09 +00002755 const Decl *Container,
Stephen Hines651f13c2014-04-23 16:59:28 -07002756 const ObjCProtocolDecl *Proto,
Bill Wendlingbb028552012-02-07 09:25:09 +00002757 const ObjCCommonTypesHelper &ObjCTypes) {
Stephen Hines651f13c2014-04-23 16:59:28 -07002758 for (const auto *P : Proto->protocols())
2759 PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
2760 for (const auto *PD : Proto->properties()) {
Stephen Hines176edba2014-12-01 14:53:08 -08002761 if (!PropertySet.insert(PD->getIdentifier()).second)
Fariborz Jahanian191dcd72009-12-12 21:26:21 +00002762 continue;
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00002763 llvm::Constant *Prop[] = {
2764 GetPropertyName(PD->getIdentifier()),
2765 GetPropertyTypeString(PD, Container)
2766 };
Fariborz Jahanian191dcd72009-12-12 21:26:21 +00002767 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2768 }
2769}
2770
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002771/*
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002772 struct _objc_property {
Bill Wendling3964e622012-02-09 22:16:49 +00002773 const char * const name;
2774 const char * const attributes;
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002775 };
2776
2777 struct _objc_property_list {
Bill Wendling3964e622012-02-09 22:16:49 +00002778 uint32_t entsize; // sizeof (struct _objc_property)
2779 uint32_t prop_count;
2780 struct _objc_property[prop_count];
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002781 };
2782*/
Chris Lattner5f9e2722011-07-23 10:55:15 +00002783llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002784 const Decl *Container,
2785 const ObjCContainerDecl *OCD,
2786 const ObjCCommonTypesHelper &ObjCTypes) {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002787 SmallVector<llvm::Constant *, 16> Properties;
Fariborz Jahanian191dcd72009-12-12 21:26:21 +00002788 llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
Stephen Hines651f13c2014-04-23 16:59:28 -07002789 for (const auto *PD : OCD->properties()) {
Fariborz Jahanian191dcd72009-12-12 21:26:21 +00002790 PropertySet.insert(PD->getIdentifier());
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00002791 llvm::Constant *Prop[] = {
2792 GetPropertyName(PD->getIdentifier()),
2793 GetPropertyTypeString(PD, Container)
2794 };
Owen Anderson08e25242009-07-27 22:29:56 +00002795 Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002796 Prop));
2797 }
Fariborz Jahanian6afbdf52010-06-22 16:33:55 +00002798 if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
Stephen Hines651f13c2014-04-23 16:59:28 -07002799 for (const auto *P : OID->all_referenced_protocols())
2800 PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
Fariborz Jahanian6afbdf52010-06-22 16:33:55 +00002801 }
2802 else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
Stephen Hines651f13c2014-04-23 16:59:28 -07002803 for (const auto *P : CD->protocols())
2804 PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
Fariborz Jahanian6afbdf52010-06-22 16:33:55 +00002805 }
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002806
2807 // Return null for empty list.
2808 if (Properties.empty())
Owen Andersonc9c88b42009-07-31 20:28:54 +00002809 return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002810
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002811 unsigned PropertySize =
Micah Villmow25a6a842012-10-08 16:25:52 +00002812 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00002813 llvm::Constant *Values[3];
Owen Anderson4a28d5d2009-07-24 23:12:58 +00002814 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
2815 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002816 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002817 Properties.size());
Owen Anderson7db6d832009-07-28 18:33:04 +00002818 Values[2] = llvm::ConstantArray::get(AT, Properties);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00002819 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002820
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002821 llvm::GlobalVariable *GV =
2822 CreateMetadataVar(Name, Init,
2823 (ObjCABI == 2) ? "__DATA, __objc_const" :
Daniel Dunbar0bf21992009-04-15 02:56:18 +00002824 "__OBJC,__property,regular,no_dead_strip",
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002825 (ObjCABI == 2) ? 8 : 4,
Daniel Dunbar0bf21992009-04-15 02:56:18 +00002826 true);
Owen Anderson3c4972d2009-07-29 18:54:39 +00002827 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002828}
2829
Bill Wendlingbb028552012-02-07 09:25:09 +00002830llvm::Constant *
2831CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2832 ArrayRef<llvm::Constant*> MethodTypes,
2833 const ObjCCommonTypesHelper &ObjCTypes) {
Bob Wilsondc8dab62011-11-30 01:57:58 +00002834 // Return null for empty list.
2835 if (MethodTypes.empty())
2836 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2837
2838 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2839 MethodTypes.size());
2840 llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2841
Stephen Hinesc568f1e2014-07-21 00:47:37 -07002842 llvm::GlobalVariable *GV = CreateMetadataVar(
2843 Name, Init, (ObjCABI == 2) ? "__DATA, __objc_const" : StringRef(),
2844 (ObjCABI == 2) ? 8 : 4, true);
Bob Wilsondc8dab62011-11-30 01:57:58 +00002845 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2846}
2847
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00002848/*
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002849 struct objc_method_description_list {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002850 int count;
2851 struct objc_method_description list[];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002852 };
2853*/
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002854llvm::Constant *
2855CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00002856 llvm::Constant *Desc[] = {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002857 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00002858 ObjCTypes.SelectorPtrTy),
2859 GetMethodVarType(MD)
2860 };
Douglas Gregorf968d832011-05-27 01:19:52 +00002861 if (!Desc[1])
Stephen Hines6bcf27b2014-05-29 04:14:42 -07002862 return nullptr;
2863
Owen Anderson08e25242009-07-27 22:29:56 +00002864 return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002865 Desc);
2866}
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002867
Bill Wendlingbb028552012-02-07 09:25:09 +00002868llvm::Constant *
2869CGObjCMac::EmitMethodDescList(Twine Name, const char *Section,
2870 ArrayRef<llvm::Constant*> Methods) {
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002871 // Return null for empty list.
2872 if (Methods.empty())
Owen Andersonc9c88b42009-07-31 20:28:54 +00002873 return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002874
Chris Lattnerc5cbb902011-06-20 04:01:35 +00002875 llvm::Constant *Values[2];
Owen Anderson4a28d5d2009-07-24 23:12:58 +00002876 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002877 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002878 Methods.size());
Owen Anderson7db6d832009-07-28 18:33:04 +00002879 Values[1] = llvm::ConstantArray::get(AT, Methods);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00002880 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002881
Daniel Dunbar0bf21992009-04-15 02:56:18 +00002882 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002883 return llvm::ConstantExpr::getBitCast(GV,
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00002884 ObjCTypes.MethodDescriptionListPtrTy);
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00002885}
2886
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002887/*
2888 struct _objc_category {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002889 char *category_name;
2890 char *class_name;
2891 struct _objc_method_list *instance_methods;
2892 struct _objc_method_list *class_methods;
2893 struct _objc_protocol_list *protocols;
2894 uint32_t size; // <rdar://4585769>
2895 struct _objc_property_list *instance_properties;
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002896 };
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002897*/
Daniel Dunbar7ded7f42008-08-15 22:20:32 +00002898void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Micah Villmow25a6a842012-10-08 16:25:52 +00002899 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002900
Mike Stumpf5408fe2009-05-16 07:57:57 +00002901 // FIXME: This is poor design, the OCD should have a pointer to the category
2902 // decl. Additionally, note that Category can be null for the @implementation
2903 // w/o an @interface case. Sema should just create one for us as it does for
2904 // @implementation so everyone else can live life under a clear blue sky.
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002905 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002906 const ObjCCategoryDecl *Category =
Daniel Dunbar86e2f402008-08-26 23:03:11 +00002907 Interface->FindCategoryDeclaration(OCD->getIdentifier());
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00002908
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00002909 SmallString<256> ExtName;
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00002910 llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
2911 << OCD->getName();
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002912
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002913 SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
Stephen Hines651f13c2014-04-23 16:59:28 -07002914 for (const auto *I : OCD->instance_methods())
Daniel Dunbarc45ef602008-08-26 21:51:14 +00002915 // Instance methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07002916 InstanceMethods.push_back(GetMethodConstant(I));
2917
2918 for (const auto *I : OCD->class_methods())
Daniel Dunbarc45ef602008-08-26 21:51:14 +00002919 // Class methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07002920 ClassMethods.push_back(GetMethodConstant(I));
Daniel Dunbarc45ef602008-08-26 21:51:14 +00002921
Chris Lattnerc5cbb902011-06-20 04:01:35 +00002922 llvm::Constant *Values[7];
Stephen Hines176edba2014-12-01 14:53:08 -08002923 Values[0] = GetClassName(OCD->getName());
2924 Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString());
Fariborz Jahanian679cd7f2009-04-29 20:40:05 +00002925 LazySymbols.insert(Interface->getIdentifier());
Stephen Hines176edba2014-12-01 14:53:08 -08002926 Values[2] = EmitMethodList("OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2927 "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2928 InstanceMethods);
2929 Values[3] = EmitMethodList("OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2930 "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2931 ClassMethods);
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002932 if (Category) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002933 Values[4] =
Stephen Hines176edba2014-12-01 14:53:08 -08002934 EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2935 Category->protocol_begin(), Category->protocol_end());
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002936 } else {
Owen Andersonc9c88b42009-07-31 20:28:54 +00002937 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
Daniel Dunbarae226fa2008-08-27 02:31:56 +00002938 }
Owen Anderson4a28d5d2009-07-24 23:12:58 +00002939 Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Daniel Dunbar86e2f402008-08-26 23:03:11 +00002940
2941 // If there is no category @interface then there can be no properties.
2942 if (Category) {
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00002943 Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
Fariborz Jahanian5de14dc2009-01-28 22:18:42 +00002944 OCD, Category, ObjCTypes);
Daniel Dunbar86e2f402008-08-26 23:03:11 +00002945 } else {
Owen Andersonc9c88b42009-07-31 20:28:54 +00002946 Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
Daniel Dunbar86e2f402008-08-26 23:03:11 +00002947 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002948
Owen Anderson08e25242009-07-27 22:29:56 +00002949 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002950 Values);
2951
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002952 llvm::GlobalVariable *GV =
Stephen Hines176edba2014-12-01 14:53:08 -08002953 CreateMetadataVar("OBJC_CATEGORY_" + ExtName.str(), Init,
2954 "__OBJC,__category,regular,no_dead_strip", 4, true);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00002955 DefinedCategories.push_back(GV);
Fariborz Jahanianb9c5b3d2010-06-21 22:05:18 +00002956 DefinedCategoryNames.insert(ExtName.str());
Fariborz Jahanian64089ce2011-04-22 22:02:28 +00002957 // method definition entries must be clear for next implementation.
2958 MethodDefinitions.clear();
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00002959}
2960
John McCall621915c2012-10-17 04:53:23 +00002961enum FragileClassFlags {
2962 FragileABI_Class_Factory = 0x00001,
2963 FragileABI_Class_Meta = 0x00002,
2964 FragileABI_Class_HasCXXStructors = 0x02000,
2965 FragileABI_Class_Hidden = 0x20000
2966};
2967
2968enum NonFragileClassFlags {
2969 /// Is a meta-class.
2970 NonFragileABI_Class_Meta = 0x00001,
2971
2972 /// Is a root class.
2973 NonFragileABI_Class_Root = 0x00002,
2974
2975 /// Has a C++ constructor and destructor.
2976 NonFragileABI_Class_HasCXXStructors = 0x00004,
2977
2978 /// Has hidden visibility.
2979 NonFragileABI_Class_Hidden = 0x00010,
2980
2981 /// Has the exception attribute.
2982 NonFragileABI_Class_Exception = 0x00020,
2983
2984 /// (Obsolete) ARC-specific: this class has a .release_ivars method
2985 NonFragileABI_Class_HasIvarReleaser = 0x00040,
2986
2987 /// Class implementation was compiled under ARC.
John McCallb03527a2012-10-17 04:53:31 +00002988 NonFragileABI_Class_CompiledByARC = 0x00080,
2989
2990 /// Class has non-trivial destructors, but zero-initialization is okay.
2991 NonFragileABI_Class_HasCXXDestructorOnly = 0x00100
Daniel Dunbar27f9d772008-08-21 04:36:09 +00002992};
2993
Daniel Dunbar27f9d772008-08-21 04:36:09 +00002994/*
2995 struct _objc_class {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00002996 Class isa;
2997 Class super_class;
2998 const char *name;
2999 long version;
3000 long info;
3001 long instance_size;
3002 struct _objc_ivar_list *ivars;
3003 struct _objc_method_list *methods;
3004 struct _objc_cache *cache;
3005 struct _objc_protocol_list *protocols;
3006 // Objective-C 1.0 extensions (<rdr://4585769>)
3007 const char *ivar_layout;
3008 struct _objc_class_ext *ext;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003009 };
3010
3011 See EmitClassExtension();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003012*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003013void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00003014 DefinedSymbols.insert(ID->getIdentifier());
3015
Chris Lattner8ec03f52008-11-24 03:54:41 +00003016 std::string ClassName = ID->getNameAsString();
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003017 // FIXME: Gross
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003018 ObjCInterfaceDecl *Interface =
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003019 const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003020 llvm::Constant *Protocols =
Stephen Hines176edba2014-12-01 14:53:08 -08003021 EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),
3022 Interface->all_referenced_protocol_begin(),
3023 Interface->all_referenced_protocol_end());
John McCall621915c2012-10-17 04:53:23 +00003024 unsigned Flags = FragileABI_Class_Factory;
John McCallb03527a2012-10-17 04:53:31 +00003025 if (ID->hasNonZeroConstructors() || ID->hasDestructors())
John McCall621915c2012-10-17 04:53:23 +00003026 Flags |= FragileABI_Class_HasCXXStructors;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003027 unsigned Size =
Ken Dyck5f022d82011-02-09 01:59:34 +00003028 CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003029
3030 // FIXME: Set CXX-structors flag.
John McCall1fb0caa2010-10-22 21:05:15 +00003031 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
John McCall621915c2012-10-17 04:53:23 +00003032 Flags |= FragileABI_Class_Hidden;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003033
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00003034 SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
Stephen Hines651f13c2014-04-23 16:59:28 -07003035 for (const auto *I : ID->instance_methods())
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003036 // Instance methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07003037 InstanceMethods.push_back(GetMethodConstant(I));
3038
3039 for (const auto *I : ID->class_methods())
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003040 // Class methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07003041 ClassMethods.push_back(GetMethodConstant(I));
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003042
Stephen Hines651f13c2014-04-23 16:59:28 -07003043 for (const auto *PID : ID->property_impls()) {
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003044 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3045 ObjCPropertyDecl *PD = PID->getPropertyDecl();
3046
3047 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
3048 if (llvm::Constant *C = GetMethodConstant(MD))
3049 InstanceMethods.push_back(C);
3050 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
3051 if (llvm::Constant *C = GetMethodConstant(MD))
3052 InstanceMethods.push_back(C);
3053 }
3054 }
3055
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003056 llvm::Constant *Values[12];
Daniel Dunbar5384b092009-05-03 08:56:52 +00003057 Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003058 if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00003059 // Record a reference to the super class.
3060 LazySymbols.insert(Super->getIdentifier());
3061
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003062 Values[ 1] =
Stephen Hines176edba2014-12-01 14:53:08 -08003063 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003064 ObjCTypes.ClassPtrTy);
3065 } else {
Owen Andersonc9c88b42009-07-31 20:28:54 +00003066 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003067 }
Stephen Hines176edba2014-12-01 14:53:08 -08003068 Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003069 // Version is always 0.
Owen Anderson4a28d5d2009-07-24 23:12:58 +00003070 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3071 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3072 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Fariborz Jahanian46b86c62009-01-28 19:12:34 +00003073 Values[ 6] = EmitIvarList(ID, false);
Stephen Hines176edba2014-12-01 14:53:08 -08003074 Values[7] = EmitMethodList("OBJC_INSTANCE_METHODS_" + ID->getName(),
3075 "__OBJC,__inst_meth,regular,no_dead_strip",
3076 InstanceMethods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003077 // cache is always NULL.
Owen Andersonc9c88b42009-07-31 20:28:54 +00003078 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003079 Values[ 9] = Protocols;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003080 Values[10] = BuildIvarLayout(ID, true);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003081 Values[11] = EmitClassExtension(ID);
Owen Anderson08e25242009-07-27 22:29:56 +00003082 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003083 Values);
Stephen Hines176edba2014-12-01 14:53:08 -08003084 std::string Name("OBJC_CLASS_");
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00003085 Name += ClassName;
3086 const char *Section = "__OBJC,__class,regular,no_dead_strip";
3087 // Check for a forward reference.
Stephen Hines651f13c2014-04-23 16:59:28 -07003088 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00003089 if (GV) {
3090 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3091 "Forward metaclass reference has incorrect type.");
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00003092 GV->setInitializer(Init);
3093 GV->setSection(Section);
3094 GV->setAlignment(4);
Stephen Hines651f13c2014-04-23 16:59:28 -07003095 CGM.addCompilerUsedGlobal(GV);
3096 } else
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00003097 GV = CreateMetadataVar(Name, Init, Section, 4, true);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003098 DefinedClasses.push_back(GV);
Stephen Hines651f13c2014-04-23 16:59:28 -07003099 ImplementedClasses.push_back(Interface);
Fariborz Jahanian64089ce2011-04-22 22:02:28 +00003100 // method definition entries must be clear for next implementation.
3101 MethodDefinitions.clear();
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003102}
3103
3104llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
3105 llvm::Constant *Protocols,
Bill Wendlingbb028552012-02-07 09:25:09 +00003106 ArrayRef<llvm::Constant*> Methods) {
John McCall621915c2012-10-17 04:53:23 +00003107 unsigned Flags = FragileABI_Class_Meta;
Micah Villmow25a6a842012-10-08 16:25:52 +00003108 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003109
John McCall1fb0caa2010-10-22 21:05:15 +00003110 if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
John McCall621915c2012-10-17 04:53:23 +00003111 Flags |= FragileABI_Class_Hidden;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003112
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003113 llvm::Constant *Values[12];
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003114 // The isa for the metaclass is the root of the hierarchy.
3115 const ObjCInterfaceDecl *Root = ID->getClassInterface();
3116 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
3117 Root = Super;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003118 Values[ 0] =
Stephen Hines176edba2014-12-01 14:53:08 -08003119 llvm::ConstantExpr::getBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003120 ObjCTypes.ClassPtrTy);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00003121 // The super class for the metaclass is emitted as the name of the
3122 // super class. The runtime fixes this up to point to the
3123 // *metaclass* for the super class.
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003124 if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003125 Values[ 1] =
Stephen Hines176edba2014-12-01 14:53:08 -08003126 llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003127 ObjCTypes.ClassPtrTy);
3128 } else {
Owen Andersonc9c88b42009-07-31 20:28:54 +00003129 Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003130 }
Stephen Hines176edba2014-12-01 14:53:08 -08003131 Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003132 // Version is always 0.
Owen Anderson4a28d5d2009-07-24 23:12:58 +00003133 Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3134 Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3135 Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
Fariborz Jahanian46b86c62009-01-28 19:12:34 +00003136 Values[ 6] = EmitIvarList(ID, true);
Stephen Hines176edba2014-12-01 14:53:08 -08003137 Values[7] =
3138 EmitMethodList("OBJC_CLASS_METHODS_" + ID->getNameAsString(),
3139 "__OBJC,__cls_meth,regular,no_dead_strip", Methods);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003140 // cache is always NULL.
Owen Andersonc9c88b42009-07-31 20:28:54 +00003141 Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003142 Values[ 9] = Protocols;
3143 // ivar_layout for metaclass is always NULL.
Owen Andersonc9c88b42009-07-31 20:28:54 +00003144 Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003145 // The class extension is always unused for metaclasses.
Owen Andersonc9c88b42009-07-31 20:28:54 +00003146 Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
Owen Anderson08e25242009-07-27 22:29:56 +00003147 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003148 Values);
3149
Stephen Hines176edba2014-12-01 14:53:08 -08003150 std::string Name("OBJC_METACLASS_");
Benjamin Kramer94be8ea2012-07-31 11:45:39 +00003151 Name += ID->getName();
Daniel Dunbarf56f1912008-08-25 08:19:24 +00003152
3153 // Check for a forward reference.
Stephen Hines651f13c2014-04-23 16:59:28 -07003154 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
Daniel Dunbarf56f1912008-08-25 08:19:24 +00003155 if (GV) {
3156 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3157 "Forward metaclass reference has incorrect type.");
Daniel Dunbarf56f1912008-08-25 08:19:24 +00003158 GV->setInitializer(Init);
3159 } else {
Owen Anderson1c431b32009-07-08 19:05:04 +00003160 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
Stephen Hines651f13c2014-04-23 16:59:28 -07003161 llvm::GlobalValue::PrivateLinkage,
Owen Anderson1c431b32009-07-08 19:05:04 +00003162 Init, Name);
Daniel Dunbarf56f1912008-08-25 08:19:24 +00003163 }
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003164 GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
Daniel Dunbar58a29122009-03-09 22:18:41 +00003165 GV->setAlignment(4);
Stephen Hines651f13c2014-04-23 16:59:28 -07003166 CGM.addCompilerUsedGlobal(GV);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003167
3168 return GV;
3169}
3170
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003171llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
Stephen Hines176edba2014-12-01 14:53:08 -08003172 std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
Daniel Dunbarf56f1912008-08-25 08:19:24 +00003173
Mike Stumpf5408fe2009-05-16 07:57:57 +00003174 // FIXME: Should we look these up somewhere other than the module. Its a bit
3175 // silly since we only generate these while processing an implementation, so
3176 // exactly one pointer would work if know when we entered/exitted an
3177 // implementation block.
Daniel Dunbarf56f1912008-08-25 08:19:24 +00003178
3179 // Check for an existing forward reference.
Fariborz Jahanianb0d27942009-01-07 20:11:22 +00003180 // Previously, metaclass with internal linkage may have been defined.
3181 // pass 'true' as 2nd argument so it is returned.
Stephen Hines651f13c2014-04-23 16:59:28 -07003182 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3183 if (!GV)
3184 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003185 llvm::GlobalValue::PrivateLinkage, nullptr,
3186 Name);
Stephen Hines651f13c2014-04-23 16:59:28 -07003187
3188 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3189 "Forward metaclass reference has incorrect type.");
Stephen Hines651f13c2014-04-23 16:59:28 -07003190 return GV;
Daniel Dunbarf56f1912008-08-25 08:19:24 +00003191}
3192
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00003193llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
Stephen Hines176edba2014-12-01 14:53:08 -08003194 std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
Stephen Hines651f13c2014-04-23 16:59:28 -07003195 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3196
3197 if (!GV)
3198 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003199 llvm::GlobalValue::PrivateLinkage, nullptr,
3200 Name);
Stephen Hines651f13c2014-04-23 16:59:28 -07003201
3202 assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3203 "Forward class metadata reference has incorrect type.");
Stephen Hines651f13c2014-04-23 16:59:28 -07003204 return GV;
Fariborz Jahanianb0069ee2009-11-12 20:14:24 +00003205}
3206
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003207/*
3208 struct objc_class_ext {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003209 uint32_t size;
3210 const char *weak_ivar_layout;
3211 struct _objc_property_list *properties;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003212 };
3213*/
3214llvm::Constant *
3215CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003216 uint64_t Size =
Micah Villmow25a6a842012-10-08 16:25:52 +00003217 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003218
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003219 llvm::Constant *Values[3];
Owen Anderson4a28d5d2009-07-24 23:12:58 +00003220 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Fariborz Jahanianc71303d2009-04-22 23:00:43 +00003221 Values[1] = BuildIvarLayout(ID, false);
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00003222 Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
Fariborz Jahanian5de14dc2009-01-28 22:18:42 +00003223 ID, ID->getClassInterface(), ObjCTypes);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003224
3225 // Return null if no extension bits are used.
3226 if (Values[1]->isNullValue() && Values[2]->isNullValue())
Owen Andersonc9c88b42009-07-31 20:28:54 +00003227 return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003228
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003229 llvm::Constant *Init =
Owen Anderson08e25242009-07-27 22:29:56 +00003230 llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
Stephen Hines176edba2014-12-01 14:53:08 -08003231 return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), Init,
3232 "__OBJC,__class_ext,regular,no_dead_strip", 4, true);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003233}
3234
3235/*
3236 struct objc_ivar {
Bill Wendling795b1002012-02-22 09:30:11 +00003237 char *ivar_name;
3238 char *ivar_type;
3239 int ivar_offset;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003240 };
3241
3242 struct objc_ivar_list {
Bill Wendling795b1002012-02-22 09:30:11 +00003243 int ivar_count;
3244 struct objc_ivar list[count];
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003245 };
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003246*/
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003247llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
Fariborz Jahanian46b86c62009-01-28 19:12:34 +00003248 bool ForClass) {
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00003249 std::vector<llvm::Constant*> Ivars;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003250
3251 // When emitting the root class GCC emits ivar entries for the
3252 // actual class structure. It is not clear if we need to follow this
3253 // behavior; for now lets try and get away with not doing it. If so,
3254 // the cleanest solution would be to make up an ObjCInterfaceDecl
3255 // for the class.
3256 if (ForClass)
Owen Andersonc9c88b42009-07-31 20:28:54 +00003257 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003258
Jordy Rosedb8264e2011-07-22 02:08:32 +00003259 const ObjCInterfaceDecl *OID = ID->getClassInterface();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003260
Jordy Rosedb8264e2011-07-22 02:08:32 +00003261 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
Fariborz Jahanianbf9eb882011-06-28 18:05:25 +00003262 IVD; IVD = IVD->getNextIvar()) {
Fariborz Jahanian8e6ac1d2009-06-04 01:19:09 +00003263 // Ignore unnamed bit-fields.
3264 if (!IVD->getDeclName())
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003265 continue;
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00003266 llvm::Constant *Ivar[] = {
3267 GetMethodVarName(IVD->getIdentifier()),
3268 GetMethodVarType(IVD),
3269 llvm::ConstantInt::get(ObjCTypes.IntTy,
Eli Friedmane5b46662012-11-06 22:15:52 +00003270 ComputeIvarBaseOffset(CGM, OID, IVD))
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00003271 };
Owen Anderson08e25242009-07-27 22:29:56 +00003272 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003273 }
3274
3275 // Return null for empty list.
3276 if (Ivars.empty())
Owen Andersonc9c88b42009-07-31 20:28:54 +00003277 return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003278
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003279 llvm::Constant *Values[2];
Owen Anderson4a28d5d2009-07-24 23:12:58 +00003280 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
Owen Anderson96e0fc72009-07-29 22:16:19 +00003281 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003282 Ivars.size());
Owen Anderson7db6d832009-07-28 18:33:04 +00003283 Values[1] = llvm::ConstantArray::get(AT, Ivars);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003284 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003285
Daniel Dunbar63c5b502009-03-09 21:49:58 +00003286 llvm::GlobalVariable *GV;
3287 if (ForClass)
Stephen Hines176edba2014-12-01 14:53:08 -08003288 GV =
3289 CreateMetadataVar("OBJC_CLASS_VARIABLES_" + ID->getName(), Init,
3290 "__OBJC,__class_vars,regular,no_dead_strip", 4, true);
Daniel Dunbar63c5b502009-03-09 21:49:58 +00003291 else
Stephen Hines176edba2014-12-01 14:53:08 -08003292 GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), Init,
3293 "__OBJC,__instance_vars,regular,no_dead_strip", 4,
3294 true);
Owen Anderson3c4972d2009-07-29 18:54:39 +00003295 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003296}
3297
3298/*
3299 struct objc_method {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003300 SEL method_name;
3301 char *method_types;
3302 void *method;
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003303 };
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003304
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003305 struct objc_method_list {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003306 struct objc_method_list *obsolete;
3307 int count;
3308 struct objc_method methods_list[count];
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003309 };
3310*/
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003311
3312/// GetMethodConstant - Return a struct objc_method constant for the
3313/// given method if it has been defined. The result is null if the
3314/// method has not been defined. The return value has type MethodPtrTy.
Daniel Dunbarae226fa2008-08-27 02:31:56 +00003315llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
Argyrios Kyrtzidis9d50c062010-08-09 10:54:20 +00003316 llvm::Function *Fn = GetMethodDefinition(MD);
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003317 if (!Fn)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003318 return nullptr;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003319
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00003320 llvm::Constant *Method[] = {
Owen Anderson3c4972d2009-07-29 18:54:39 +00003321 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00003322 ObjCTypes.SelectorPtrTy),
3323 GetMethodVarType(MD),
3324 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3325 };
Owen Anderson08e25242009-07-27 22:29:56 +00003326 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003327}
3328
Chris Lattner5f9e2722011-07-23 10:55:15 +00003329llvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
Daniel Dunbar86e253a2008-08-22 20:34:54 +00003330 const char *Section,
Bill Wendlingbb028552012-02-07 09:25:09 +00003331 ArrayRef<llvm::Constant*> Methods) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003332 // Return null for empty list.
3333 if (Methods.empty())
Owen Andersonc9c88b42009-07-31 20:28:54 +00003334 return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003335
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003336 llvm::Constant *Values[3];
Owen Andersonc9c88b42009-07-31 20:28:54 +00003337 Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Owen Anderson4a28d5d2009-07-24 23:12:58 +00003338 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
Owen Anderson96e0fc72009-07-29 22:16:19 +00003339 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003340 Methods.size());
Owen Anderson7db6d832009-07-28 18:33:04 +00003341 Values[2] = llvm::ConstantArray::get(AT, Methods);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003342 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00003343
Daniel Dunbar0bf21992009-04-15 02:56:18 +00003344 llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00003345 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00003346}
3347
Fariborz Jahanian493dab72009-01-26 21:38:32 +00003348llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003349 const ObjCContainerDecl *CD) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00003350 SmallString<256> Name;
Fariborz Jahanian679a5022009-01-10 21:06:09 +00003351 GetNameForMethod(OMD, CD, Name);
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00003352
Daniel Dunbar541b63b2009-02-02 23:23:47 +00003353 CodeGenTypes &Types = CGM.getTypes();
Chris Lattner2acc6e32011-07-18 04:24:23 +00003354 llvm::FunctionType *MethodTy =
John McCallde5d3c72012-02-17 03:33:10 +00003355 Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003356 llvm::Function *Method =
Daniel Dunbar45c25ba2008-09-10 04:01:49 +00003357 llvm::Function::Create(MethodTy,
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00003358 llvm::GlobalValue::InternalLinkage,
Daniel Dunbarc575ce72009-10-19 01:21:19 +00003359 Name.str(),
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00003360 &CGM.getModule());
Daniel Dunbarc45ef602008-08-26 21:51:14 +00003361 MethodDefinitions.insert(std::make_pair(OMD, Method));
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00003362
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00003363 return Method;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00003364}
3365
Stephen Hinesc568f1e2014-07-21 00:47:37 -07003366llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3367 llvm::Constant *Init,
3368 StringRef Section,
3369 unsigned Align,
3370 bool AddToUsed) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00003371 llvm::Type *Ty = Init->getType();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003372 llvm::GlobalVariable *GV =
Owen Anderson1c431b32009-07-08 19:05:04 +00003373 new llvm::GlobalVariable(CGM.getModule(), Ty, false,
Stephen Hines651f13c2014-04-23 16:59:28 -07003374 llvm::GlobalValue::PrivateLinkage, Init, Name);
Stephen Hinesc568f1e2014-07-21 00:47:37 -07003375 if (!Section.empty())
Daniel Dunbarfd65d372009-03-09 20:09:19 +00003376 GV->setSection(Section);
Daniel Dunbar35bd7632009-03-09 20:50:13 +00003377 if (Align)
3378 GV->setAlignment(Align);
3379 if (AddToUsed)
Stephen Hines651f13c2014-04-23 16:59:28 -07003380 CGM.addCompilerUsedGlobal(GV);
Daniel Dunbarfd65d372009-03-09 20:09:19 +00003381 return GV;
3382}
3383
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003384llvm::Function *CGObjCMac::ModuleInitFunction() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00003385 // Abuse this interface function as a place to finalize.
3386 FinishModule();
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003387 return nullptr;
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00003388}
3389
Chris Lattner74391b42009-03-22 21:03:39 +00003390llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
Chris Lattner72db6c32009-04-22 02:44:54 +00003391 return ObjCTypes.getGetPropertyFn();
Daniel Dunbar49f66022008-09-24 03:38:44 +00003392}
3393
Chris Lattner74391b42009-03-22 21:03:39 +00003394llvm::Constant *CGObjCMac::GetPropertySetFunction() {
Chris Lattner72db6c32009-04-22 02:44:54 +00003395 return ObjCTypes.getSetPropertyFn();
Daniel Dunbar49f66022008-09-24 03:38:44 +00003396}
3397
Ted Kremenekebcb57a2012-03-06 20:05:56 +00003398llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
3399 bool copy) {
3400 return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3401}
3402
David Chisnall8fac25d2010-12-26 22:13:16 +00003403llvm::Constant *CGObjCMac::GetGetStructFunction() {
3404 return ObjCTypes.getCopyStructFn();
3405}
3406llvm::Constant *CGObjCMac::GetSetStructFunction() {
Fariborz Jahanian6cc59062010-04-12 18:18:10 +00003407 return ObjCTypes.getCopyStructFn();
3408}
3409
David Chisnalld397cfe2012-12-17 18:54:24 +00003410llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3411 return ObjCTypes.getCppAtomicObjectFunction();
3412}
3413llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
Fariborz Jahaniane3173022012-01-06 18:07:23 +00003414 return ObjCTypes.getCppAtomicObjectFunction();
3415}
3416
Chris Lattner74391b42009-03-22 21:03:39 +00003417llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
Chris Lattner72db6c32009-04-22 02:44:54 +00003418 return ObjCTypes.getEnumerationMutationFn();
Anders Carlsson2abd89c2008-08-31 04:05:03 +00003419}
3420
John McCallf1549f62010-07-06 01:34:17 +00003421void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
3422 return EmitTryOrSynchronizedStmt(CGF, S);
3423}
3424
3425void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
3426 const ObjCAtSynchronizedStmt &S) {
3427 return EmitTryOrSynchronizedStmt(CGF, S);
3428}
3429
John McCallcc505292010-07-21 06:59:36 +00003430namespace {
John McCall1f0fca52010-07-21 07:22:38 +00003431 struct PerformFragileFinally : EHScopeStack::Cleanup {
John McCallcc505292010-07-21 06:59:36 +00003432 const Stmt &S;
John McCall0b251722010-08-04 05:59:32 +00003433 llvm::Value *SyncArgSlot;
John McCallcc505292010-07-21 06:59:36 +00003434 llvm::Value *CallTryExitVar;
3435 llvm::Value *ExceptionData;
3436 ObjCTypesHelper &ObjCTypes;
3437 PerformFragileFinally(const Stmt *S,
John McCall0b251722010-08-04 05:59:32 +00003438 llvm::Value *SyncArgSlot,
John McCallcc505292010-07-21 06:59:36 +00003439 llvm::Value *CallTryExitVar,
3440 llvm::Value *ExceptionData,
3441 ObjCTypesHelper *ObjCTypes)
John McCall0b251722010-08-04 05:59:32 +00003442 : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
John McCallcc505292010-07-21 06:59:36 +00003443 ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3444
Stephen Hines651f13c2014-04-23 16:59:28 -07003445 void Emit(CodeGenFunction &CGF, Flags flags) override {
John McCallcc505292010-07-21 06:59:36 +00003446 // Check whether we need to call objc_exception_try_exit.
3447 // In optimized code, this branch will always be folded.
3448 llvm::BasicBlock *FinallyCallExit =
3449 CGF.createBasicBlock("finally.call_exit");
3450 llvm::BasicBlock *FinallyNoCallExit =
3451 CGF.createBasicBlock("finally.no_call_exit");
3452 CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
3453 FinallyCallExit, FinallyNoCallExit);
3454
3455 CGF.EmitBlock(FinallyCallExit);
John McCallbd7370a2013-02-28 19:01:20 +00003456 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
3457 ExceptionData);
John McCallcc505292010-07-21 06:59:36 +00003458
3459 CGF.EmitBlock(FinallyNoCallExit);
3460
3461 if (isa<ObjCAtTryStmt>(S)) {
3462 if (const ObjCAtFinallyStmt* FinallyStmt =
John McCalld96a8e72010-08-11 00:16:14 +00003463 cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
John McCall73c56bb2013-04-03 00:56:07 +00003464 // Don't try to do the @finally if this is an EH cleanup.
3465 if (flags.isForEHCleanup()) return;
3466
John McCalld96a8e72010-08-11 00:16:14 +00003467 // Save the current cleanup destination in case there's
3468 // control flow inside the finally statement.
3469 llvm::Value *CurCleanupDest =
3470 CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
3471
John McCallcc505292010-07-21 06:59:36 +00003472 CGF.EmitStmt(FinallyStmt->getFinallyBody());
3473
John McCalld96a8e72010-08-11 00:16:14 +00003474 if (CGF.HaveInsertPoint()) {
3475 CGF.Builder.CreateStore(CurCleanupDest,
3476 CGF.getNormalCleanupDestSlot());
3477 } else {
3478 // Currently, the end of the cleanup must always exist.
3479 CGF.EnsureInsertPoint();
3480 }
3481 }
John McCallcc505292010-07-21 06:59:36 +00003482 } else {
3483 // Emit objc_sync_exit(expr); as finally's sole statement for
3484 // @synchronized.
John McCall0b251722010-08-04 05:59:32 +00003485 llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
John McCallbd7370a2013-02-28 19:01:20 +00003486 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
John McCallcc505292010-07-21 06:59:36 +00003487 }
3488 }
3489 };
John McCall87bb5822010-07-31 23:20:56 +00003490
3491 class FragileHazards {
3492 CodeGenFunction &CGF;
Chris Lattner5f9e2722011-07-23 10:55:15 +00003493 SmallVector<llvm::Value*, 20> Locals;
John McCall87bb5822010-07-31 23:20:56 +00003494 llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
3495
3496 llvm::InlineAsm *ReadHazard;
3497 llvm::InlineAsm *WriteHazard;
3498
3499 llvm::FunctionType *GetAsmFnType();
3500
3501 void collectLocals();
3502 void emitReadHazard(CGBuilderTy &Builder);
3503
3504 public:
3505 FragileHazards(CodeGenFunction &CGF);
John McCall0b251722010-08-04 05:59:32 +00003506
John McCall87bb5822010-07-31 23:20:56 +00003507 void emitWriteHazard();
John McCall0b251722010-08-04 05:59:32 +00003508 void emitHazardsInNewBlocks();
John McCall87bb5822010-07-31 23:20:56 +00003509 };
3510}
3511
3512/// Create the fragile-ABI read and write hazards based on the current
3513/// state of the function, which is presumed to be immediately prior
3514/// to a @try block. These hazards are used to maintain correct
3515/// semantics in the face of optimization and the fragile ABI's
3516/// cavalier use of setjmp/longjmp.
3517FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
3518 collectLocals();
3519
3520 if (Locals.empty()) return;
3521
3522 // Collect all the blocks in the function.
3523 for (llvm::Function::iterator
3524 I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
3525 BlocksBeforeTry.insert(&*I);
3526
3527 llvm::FunctionType *AsmFnTy = GetAsmFnType();
3528
3529 // Create a read hazard for the allocas. This inhibits dead-store
3530 // optimizations and forces the values to memory. This hazard is
3531 // inserted before any 'throwing' calls in the protected scope to
3532 // reflect the possibility that the variables might be read from the
3533 // catch block if the call throws.
3534 {
3535 std::string Constraint;
3536 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3537 if (I) Constraint += ',';
3538 Constraint += "*m";
3539 }
3540
3541 ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3542 }
3543
3544 // Create a write hazard for the allocas. This inhibits folding
3545 // loads across the hazard. This hazard is inserted at the
3546 // beginning of the catch path to reflect the possibility that the
3547 // variables might have been written within the protected scope.
3548 {
3549 std::string Constraint;
3550 for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3551 if (I) Constraint += ',';
3552 Constraint += "=*m";
3553 }
3554
3555 WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3556 }
3557}
3558
3559/// Emit a write hazard at the current location.
3560void FragileHazards::emitWriteHazard() {
3561 if (Locals.empty()) return;
3562
John McCallbd7370a2013-02-28 19:01:20 +00003563 CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
John McCall87bb5822010-07-31 23:20:56 +00003564}
3565
John McCall87bb5822010-07-31 23:20:56 +00003566void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
3567 assert(!Locals.empty());
John McCallbd7370a2013-02-28 19:01:20 +00003568 llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
3569 call->setDoesNotThrow();
3570 call->setCallingConv(CGF.getRuntimeCC());
John McCall87bb5822010-07-31 23:20:56 +00003571}
3572
3573/// Emit read hazards in all the protected blocks, i.e. all the blocks
3574/// which have been inserted since the beginning of the try.
John McCall0b251722010-08-04 05:59:32 +00003575void FragileHazards::emitHazardsInNewBlocks() {
John McCall87bb5822010-07-31 23:20:56 +00003576 if (Locals.empty()) return;
3577
3578 CGBuilderTy Builder(CGF.getLLVMContext());
3579
3580 // Iterate through all blocks, skipping those prior to the try.
3581 for (llvm::Function::iterator
3582 FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
3583 llvm::BasicBlock &BB = *FI;
3584 if (BlocksBeforeTry.count(&BB)) continue;
3585
3586 // Walk through all the calls in the block.
3587 for (llvm::BasicBlock::iterator
3588 BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3589 llvm::Instruction &I = *BI;
3590
3591 // Ignore instructions that aren't non-intrinsic calls.
3592 // These are the only calls that can possibly call longjmp.
3593 if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
3594 if (isa<llvm::IntrinsicInst>(I))
3595 continue;
3596
3597 // Ignore call sites marked nounwind. This may be questionable,
3598 // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
3599 llvm::CallSite CS(&I);
3600 if (CS.doesNotThrow()) continue;
3601
John McCall0b251722010-08-04 05:59:32 +00003602 // Insert a read hazard before the call. This will ensure that
3603 // any writes to the locals are performed before making the
3604 // call. If the call throws, then this is sufficient to
3605 // guarantee correctness as long as it doesn't also write to any
3606 // locals.
John McCall87bb5822010-07-31 23:20:56 +00003607 Builder.SetInsertPoint(&BB, BI);
3608 emitReadHazard(Builder);
3609 }
3610 }
3611}
3612
3613static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
3614 if (V) S.insert(V);
3615}
3616
3617void FragileHazards::collectLocals() {
3618 // Compute a set of allocas to ignore.
3619 llvm::DenseSet<llvm::Value*> AllocasToIgnore;
3620 addIfPresent(AllocasToIgnore, CGF.ReturnValue);
3621 addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
John McCall87bb5822010-07-31 23:20:56 +00003622
3623 // Collect all the allocas currently in the function. This is
3624 // probably way too aggressive.
3625 llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
3626 for (llvm::BasicBlock::iterator
3627 I = Entry.begin(), E = Entry.end(); I != E; ++I)
3628 if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3629 Locals.push_back(&*I);
3630}
3631
3632llvm::FunctionType *FragileHazards::GetAsmFnType() {
Chris Lattner5f9e2722011-07-23 10:55:15 +00003633 SmallVector<llvm::Type *, 16> tys(Locals.size());
John McCall0774cb82011-05-15 01:53:33 +00003634 for (unsigned i = 0, e = Locals.size(); i != e; ++i)
3635 tys[i] = Locals[i]->getType();
3636 return llvm::FunctionType::get(CGF.VoidTy, tys, false);
John McCallcc505292010-07-21 06:59:36 +00003637}
3638
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003639/*
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003640
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003641 Objective-C setjmp-longjmp (sjlj) Exception Handling
3642 --
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003643
John McCallf1549f62010-07-06 01:34:17 +00003644 A catch buffer is a setjmp buffer plus:
3645 - a pointer to the exception that was caught
3646 - a pointer to the previous exception data buffer
3647 - two pointers of reserved storage
3648 Therefore catch buffers form a stack, with a pointer to the top
3649 of the stack kept in thread-local storage.
3650
3651 objc_exception_try_enter pushes a catch buffer onto the EH stack.
3652 objc_exception_try_exit pops the given catch buffer, which is
3653 required to be the top of the EH stack.
3654 objc_exception_throw pops the top of the EH stack, writes the
3655 thrown exception into the appropriate field, and longjmps
3656 to the setjmp buffer. It crashes the process (with a printf
3657 and an abort()) if there are no catch buffers on the stack.
3658 objc_exception_extract just reads the exception pointer out of the
3659 catch buffer.
3660
3661 There's no reason an implementation couldn't use a light-weight
3662 setjmp here --- something like __builtin_setjmp, but API-compatible
3663 with the heavyweight setjmp. This will be more important if we ever
3664 want to implement correct ObjC/C++ exception interactions for the
3665 fragile ABI.
3666
3667 Note that for this use of setjmp/longjmp to be correct, we may need
3668 to mark some local variables volatile: if a non-volatile local
3669 variable is modified between the setjmp and the longjmp, it has
3670 indeterminate value. For the purposes of LLVM IR, it may be
3671 sufficient to make loads and stores within the @try (to variables
3672 declared outside the @try) volatile. This is necessary for
3673 optimized correctness, but is not currently being done; this is
3674 being tracked as rdar://problem/8160285
3675
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003676 The basic framework for a @try-catch-finally is as follows:
3677 {
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003678 objc_exception_data d;
3679 id _rethrow = null;
Anders Carlsson190d00e2009-02-07 21:26:04 +00003680 bool _call_try_exit = true;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003681
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003682 objc_exception_try_enter(&d);
3683 if (!setjmp(d.jmp_buf)) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003684 ... try body ...
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003685 } else {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003686 // exception path
3687 id _caught = objc_exception_extract(&d);
3688
3689 // enter new try scope for handlers
3690 if (!setjmp(d.jmp_buf)) {
3691 ... match exception and execute catch blocks ...
3692
3693 // fell off end, rethrow.
3694 _rethrow = _caught;
3695 ... jump-through-finally to finally_rethrow ...
3696 } else {
3697 // exception in catch block
3698 _rethrow = objc_exception_extract(&d);
3699 _call_try_exit = false;
3700 ... jump-through-finally to finally_rethrow ...
3701 }
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003702 }
Daniel Dunbar898d5082008-09-30 01:06:03 +00003703 ... jump-through-finally to finally_end ...
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003704
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003705 finally:
Anders Carlsson190d00e2009-02-07 21:26:04 +00003706 if (_call_try_exit)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003707 objc_exception_try_exit(&d);
Anders Carlsson190d00e2009-02-07 21:26:04 +00003708
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003709 ... finally block ....
Daniel Dunbar898d5082008-09-30 01:06:03 +00003710 ... dispatch to finally destination ...
3711
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003712 finally_rethrow:
Daniel Dunbar898d5082008-09-30 01:06:03 +00003713 objc_exception_throw(_rethrow);
3714
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003715 finally_end:
3716 }
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003717
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003718 This framework differs slightly from the one gcc uses, in that gcc
3719 uses _rethrow to determine if objc_exception_try_exit should be called
3720 and if the object should be rethrown. This breaks in the face of
3721 throwing nil and introduces unnecessary branches.
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003722
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003723 We specialize this framework for a few particular circumstances:
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003724
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003725 - If there are no catch blocks, then we avoid emitting the second
3726 exception handling context.
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003727
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003728 - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
3729 e)) we avoid emitting the code to rethrow an uncaught exception.
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003730
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003731 - FIXME: If there is no @finally block we can do a few more
3732 simplifications.
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003733
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003734 Rethrows and Jumps-Through-Finally
3735 --
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003736
John McCallf1549f62010-07-06 01:34:17 +00003737 '@throw;' is supported by pushing the currently-caught exception
3738 onto ObjCEHStack while the @catch blocks are emitted.
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003739
John McCallf1549f62010-07-06 01:34:17 +00003740 Branches through the @finally block are handled with an ordinary
3741 normal cleanup. We do not register an EH cleanup; fragile-ABI ObjC
3742 exceptions are not compatible with C++ exceptions, and this is
3743 hardly the only place where this will go wrong.
Daniel Dunbar898d5082008-09-30 01:06:03 +00003744
John McCallf1549f62010-07-06 01:34:17 +00003745 @synchronized(expr) { stmt; } is emitted as if it were:
3746 id synch_value = expr;
3747 objc_sync_enter(synch_value);
3748 @try { stmt; } @finally { objc_sync_exit(synch_value); }
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003749*/
3750
Fariborz Jahanianbd71be42008-11-21 00:49:24 +00003751void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
3752 const Stmt &S) {
3753 bool isTry = isa<ObjCAtTryStmt>(S);
John McCallf1549f62010-07-06 01:34:17 +00003754
3755 // A destination for the fall-through edges of the catch handlers to
3756 // jump to.
3757 CodeGenFunction::JumpDest FinallyEnd =
3758 CGF.getJumpDestInCurrentScope("finally.end");
3759
3760 // A destination for the rethrow edge of the catch handlers to jump
3761 // to.
3762 CodeGenFunction::JumpDest FinallyRethrow =
3763 CGF.getJumpDestInCurrentScope("finally.rethrow");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003764
Daniel Dunbar1c566672009-02-24 01:43:46 +00003765 // For @synchronized, call objc_sync_enter(sync.expr). The
3766 // evaluation of the expression must occur before we enter the
John McCall0b251722010-08-04 05:59:32 +00003767 // @synchronized. We can't avoid a temp here because we need the
3768 // value to be preserved. If the backend ever does liveness
3769 // correctly after setjmp, this will be unnecessary.
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003770 llvm::Value *SyncArgSlot = nullptr;
Daniel Dunbar1c566672009-02-24 01:43:46 +00003771 if (!isTry) {
John McCall0b251722010-08-04 05:59:32 +00003772 llvm::Value *SyncArg =
Daniel Dunbar1c566672009-02-24 01:43:46 +00003773 CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
3774 SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00003775 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
John McCall0b251722010-08-04 05:59:32 +00003776
3777 SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
3778 CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
Daniel Dunbar1c566672009-02-24 01:43:46 +00003779 }
Daniel Dunbar898d5082008-09-30 01:06:03 +00003780
John McCall0b251722010-08-04 05:59:32 +00003781 // Allocate memory for the setjmp buffer. This needs to be kept
3782 // live throughout the try and catch blocks.
3783 llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
3784 "exceptiondata.ptr");
3785
John McCall87bb5822010-07-31 23:20:56 +00003786 // Create the fragile hazards. Note that this will not capture any
3787 // of the allocas required for exception processing, but will
3788 // capture the current basic block (which extends all the way to the
3789 // setjmp call) as "before the @try".
3790 FragileHazards Hazards(CGF);
3791
John McCallf1549f62010-07-06 01:34:17 +00003792 // Create a flag indicating whether the cleanup needs to call
3793 // objc_exception_try_exit. This is true except when
3794 // - no catches match and we're branching through the cleanup
3795 // just to rethrow the exception, or
3796 // - a catch matched and we're falling out of the catch handler.
John McCall0b251722010-08-04 05:59:32 +00003797 // The setjmp-safety rule here is that we should always store to this
3798 // variable in a place that dominates the branch through the cleanup
3799 // without passing through any setjmps.
John McCallf1549f62010-07-06 01:34:17 +00003800 llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
Anders Carlsson190d00e2009-02-07 21:26:04 +00003801 "_call_try_exit");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003802
John McCall9e2213d2010-10-04 23:42:51 +00003803 // A slot containing the exception to rethrow. Only needed when we
3804 // have both a @catch and a @finally.
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003805 llvm::Value *PropagatingExnVar = nullptr;
John McCall9e2213d2010-10-04 23:42:51 +00003806
John McCallf1549f62010-07-06 01:34:17 +00003807 // Push a normal cleanup to leave the try scope.
John McCall73c56bb2013-04-03 00:56:07 +00003808 CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
John McCall0b251722010-08-04 05:59:32 +00003809 SyncArgSlot,
John McCall1f0fca52010-07-21 07:22:38 +00003810 CallTryExitVar,
3811 ExceptionData,
3812 &ObjCTypes);
John McCallf1549f62010-07-06 01:34:17 +00003813
3814 // Enter a try block:
3815 // - Call objc_exception_try_enter to push ExceptionData on top of
3816 // the EH stack.
John McCallbd7370a2013-02-28 19:01:20 +00003817 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
John McCallf1549f62010-07-06 01:34:17 +00003818
3819 // - Call setjmp on the exception data buffer.
3820 llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
3821 llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
3822 llvm::Value *SetJmpBuffer =
Jay Foad0f6ac7c2011-07-22 08:16:57 +00003823 CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
John McCallf1549f62010-07-06 01:34:17 +00003824 llvm::CallInst *SetJmpResult =
John McCallbd7370a2013-02-28 19:01:20 +00003825 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
Bill Wendling6446c3e2011-12-19 23:53:28 +00003826 SetJmpResult->setCanReturnTwice();
John McCallf1549f62010-07-06 01:34:17 +00003827
3828 // If setjmp returned 0, enter the protected block; otherwise,
3829 // branch to the handler.
Daniel Dunbar55e87422008-11-11 02:29:29 +00003830 llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
3831 llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
John McCallf1549f62010-07-06 01:34:17 +00003832 llvm::Value *DidCatch =
John McCalld96a8e72010-08-11 00:16:14 +00003833 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3834 CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
Anders Carlsson80f25672008-09-09 17:59:25 +00003835
John McCallf1549f62010-07-06 01:34:17 +00003836 // Emit the protected block.
Anders Carlsson80f25672008-09-09 17:59:25 +00003837 CGF.EmitBlock(TryBlock);
John McCall0b251722010-08-04 05:59:32 +00003838 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003839 CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
John McCallf1549f62010-07-06 01:34:17 +00003840 : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
John McCall0b251722010-08-04 05:59:32 +00003841
3842 CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003843
John McCallf1549f62010-07-06 01:34:17 +00003844 // Emit the exception handler block.
Daniel Dunbare4b5ee02008-09-27 23:30:04 +00003845 CGF.EmitBlock(TryHandler);
Daniel Dunbar55e40722008-09-27 07:03:52 +00003846
John McCall87bb5822010-07-31 23:20:56 +00003847 // Don't optimize loads of the in-scope locals across this point.
3848 Hazards.emitWriteHazard();
3849
John McCallf1549f62010-07-06 01:34:17 +00003850 // For a @synchronized (or a @try with no catches), just branch
3851 // through the cleanup to the rethrow block.
3852 if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
3853 // Tell the cleanup not to re-pop the exit.
John McCall0b251722010-08-04 05:59:32 +00003854 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
Anders Carlssonf3a79a92009-02-09 20:38:58 +00003855 CGF.EmitBranchThroughCleanup(FinallyRethrow);
John McCallf1549f62010-07-06 01:34:17 +00003856
3857 // Otherwise, we have to match against the caught exceptions.
3858 } else {
John McCall0b251722010-08-04 05:59:32 +00003859 // Retrieve the exception object. We may emit multiple blocks but
3860 // nothing can cross this so the value is already in SSA form.
3861 llvm::CallInst *Caught =
John McCallbd7370a2013-02-28 19:01:20 +00003862 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
3863 ExceptionData, "caught");
John McCall0b251722010-08-04 05:59:32 +00003864
John McCallf1549f62010-07-06 01:34:17 +00003865 // Push the exception to rethrow onto the EH value stack for the
3866 // benefit of any @throws in the handlers.
3867 CGF.ObjCEHValueStack.push_back(Caught);
3868
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +00003869 const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003870
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003871 bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
John McCallf1549f62010-07-06 01:34:17 +00003872
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003873 llvm::BasicBlock *CatchBlock = nullptr;
3874 llvm::BasicBlock *CatchHandler = nullptr;
John McCall0b251722010-08-04 05:59:32 +00003875 if (HasFinally) {
John McCall9e2213d2010-10-04 23:42:51 +00003876 // Save the currently-propagating exception before
3877 // objc_exception_try_enter clears the exception slot.
3878 PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
3879 "propagating_exception");
3880 CGF.Builder.CreateStore(Caught, PropagatingExnVar);
3881
John McCall0b251722010-08-04 05:59:32 +00003882 // Enter a new exception try block (in case a @catch block
3883 // throws an exception).
John McCallbd7370a2013-02-28 19:01:20 +00003884 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
3885 ExceptionData);
Anders Carlsson80f25672008-09-09 17:59:25 +00003886
John McCall0b251722010-08-04 05:59:32 +00003887 llvm::CallInst *SetJmpResult =
John McCallbd7370a2013-02-28 19:01:20 +00003888 CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(),
3889 SetJmpBuffer, "setjmp.result");
Bill Wendling6446c3e2011-12-19 23:53:28 +00003890 SetJmpResult->setCanReturnTwice();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003891
John McCall0b251722010-08-04 05:59:32 +00003892 llvm::Value *Threw =
3893 CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3894
3895 CatchBlock = CGF.createBasicBlock("catch");
3896 CatchHandler = CGF.createBasicBlock("catch_for_catch");
3897 CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3898
3899 CGF.EmitBlock(CatchBlock);
3900 }
3901
3902 CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003903
Daniel Dunbar55e40722008-09-27 07:03:52 +00003904 // Handle catch list. As a special case we check if everything is
3905 // matched and avoid generating code for falling off the end if
3906 // so.
3907 bool AllMatched = false;
Douglas Gregor8f5e3dd2010-04-23 22:50:49 +00003908 for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
3909 const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
Anders Carlsson80f25672008-09-09 17:59:25 +00003910
Douglas Gregorc00d8e12010-04-26 16:46:50 +00003911 const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
Stephen Hines6bcf27b2014-05-29 04:14:42 -07003912 const ObjCObjectPointerType *OPT = nullptr;
Daniel Dunbar129271a2008-09-27 07:36:24 +00003913
Anders Carlsson80f25672008-09-09 17:59:25 +00003914 // catch(...) always matches.
Daniel Dunbar55e40722008-09-27 07:03:52 +00003915 if (!CatchParam) {
3916 AllMatched = true;
3917 } else {
John McCall183700f2009-09-21 23:43:11 +00003918 OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003919
John McCallf1549f62010-07-06 01:34:17 +00003920 // catch(id e) always matches under this ABI, since only
3921 // ObjC exceptions end up here in the first place.
Daniel Dunbar97f61d12008-09-27 22:21:14 +00003922 // FIXME: For the time being we also match id<X>; this should
3923 // be rejected by Sema instead.
Eli Friedman818e96f2009-07-11 00:57:02 +00003924 if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
Daniel Dunbar55e40722008-09-27 07:03:52 +00003925 AllMatched = true;
Anders Carlsson80f25672008-09-09 17:59:25 +00003926 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003927
John McCallf1549f62010-07-06 01:34:17 +00003928 // If this is a catch-all, we don't need to test anything.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003929 if (AllMatched) {
John McCallf1549f62010-07-06 01:34:17 +00003930 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3931
Anders Carlssondde0a942008-09-11 09:15:33 +00003932 if (CatchParam) {
John McCallb6bbcc92010-10-15 04:57:14 +00003933 CGF.EmitAutoVarDecl(*CatchParam);
Daniel Dunbara448fb22008-11-11 23:11:34 +00003934 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
John McCallf1549f62010-07-06 01:34:17 +00003935
3936 // These types work out because ConvertType(id) == i8*.
Steve Naroff7ba138a2009-03-03 19:52:17 +00003937 CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
Anders Carlssondde0a942008-09-11 09:15:33 +00003938 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003939
Anders Carlssondde0a942008-09-11 09:15:33 +00003940 CGF.EmitStmt(CatchStmt->getCatchBody());
John McCallf1549f62010-07-06 01:34:17 +00003941
3942 // The scope of the catch variable ends right here.
3943 CatchVarCleanups.ForceCleanup();
3944
Anders Carlssonf3a79a92009-02-09 20:38:58 +00003945 CGF.EmitBranchThroughCleanup(FinallyEnd);
Anders Carlsson80f25672008-09-09 17:59:25 +00003946 break;
3947 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003948
Steve Naroff14108da2009-07-10 23:34:53 +00003949 assert(OPT && "Unexpected non-object pointer type in @catch");
John McCall506b57e2010-05-17 21:00:27 +00003950 const ObjCObjectType *ObjTy = OPT->getObjectType();
John McCallf1549f62010-07-06 01:34:17 +00003951
3952 // FIXME: @catch (Class c) ?
John McCall506b57e2010-05-17 21:00:27 +00003953 ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
3954 assert(IDecl && "Catch parameter must have Objective-C type!");
Anders Carlsson80f25672008-09-09 17:59:25 +00003955
3956 // Check if the @catch block matches the exception object.
John McCallbd7370a2013-02-28 19:01:20 +00003957 llvm::Value *Class = EmitClassRef(CGF, IDecl);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003958
John McCallbd7370a2013-02-28 19:01:20 +00003959 llvm::Value *matchArgs[] = { Class, Caught };
John McCallf1549f62010-07-06 01:34:17 +00003960 llvm::CallInst *Match =
John McCallbd7370a2013-02-28 19:01:20 +00003961 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionMatchFn(),
3962 matchArgs, "match");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003963
John McCallf1549f62010-07-06 01:34:17 +00003964 llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
3965 llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003966
3967 CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
Daniel Dunbare4b5ee02008-09-27 23:30:04 +00003968 MatchedBlock, NextCatchBlock);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003969
Anders Carlsson80f25672008-09-09 17:59:25 +00003970 // Emit the @catch block.
3971 CGF.EmitBlock(MatchedBlock);
John McCallf1549f62010-07-06 01:34:17 +00003972
3973 // Collect any cleanups for the catch variable. The scope lasts until
3974 // the end of the catch body.
John McCall0b251722010-08-04 05:59:32 +00003975 CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
John McCallf1549f62010-07-06 01:34:17 +00003976
John McCallb6bbcc92010-10-15 04:57:14 +00003977 CGF.EmitAutoVarDecl(*CatchParam);
Daniel Dunbara448fb22008-11-11 23:11:34 +00003978 assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
Daniel Dunbar18ccc772008-09-28 01:03:14 +00003979
John McCallf1549f62010-07-06 01:34:17 +00003980 // Initialize the catch variable.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003981 llvm::Value *Tmp =
3982 CGF.Builder.CreateBitCast(Caught,
Benjamin Kramer578faa82011-09-27 21:06:10 +00003983 CGF.ConvertType(CatchParam->getType()));
Steve Naroff7ba138a2009-03-03 19:52:17 +00003984 CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003985
Anders Carlssondde0a942008-09-11 09:15:33 +00003986 CGF.EmitStmt(CatchStmt->getCatchBody());
John McCallf1549f62010-07-06 01:34:17 +00003987
3988 // We're done with the catch variable.
3989 CatchVarCleanups.ForceCleanup();
3990
Anders Carlssonf3a79a92009-02-09 20:38:58 +00003991 CGF.EmitBranchThroughCleanup(FinallyEnd);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00003992
Anders Carlsson80f25672008-09-09 17:59:25 +00003993 CGF.EmitBlock(NextCatchBlock);
3994 }
3995
John McCallf1549f62010-07-06 01:34:17 +00003996 CGF.ObjCEHValueStack.pop_back();
3997
John McCall0b251722010-08-04 05:59:32 +00003998 // If nothing wanted anything to do with the caught exception,
3999 // kill the extract call.
4000 if (Caught->use_empty())
4001 Caught->eraseFromParent();
4002
4003 if (!AllMatched)
4004 CGF.EmitBranchThroughCleanup(FinallyRethrow);
4005
4006 if (HasFinally) {
4007 // Emit the exception handler for the @catch blocks.
4008 CGF.EmitBlock(CatchHandler);
4009
4010 // In theory we might now need a write hazard, but actually it's
4011 // unnecessary because there's no local-accessing code between
4012 // the try's write hazard and here.
4013 //Hazards.emitWriteHazard();
4014
John McCall9e2213d2010-10-04 23:42:51 +00004015 // Extract the new exception and save it to the
4016 // propagating-exception slot.
4017 assert(PropagatingExnVar);
4018 llvm::CallInst *NewCaught =
John McCallbd7370a2013-02-28 19:01:20 +00004019 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4020 ExceptionData, "caught");
John McCall9e2213d2010-10-04 23:42:51 +00004021 CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
4022
John McCall0b251722010-08-04 05:59:32 +00004023 // Don't pop the catch handler; the throw already did.
4024 CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
Anders Carlssonf3a79a92009-02-09 20:38:58 +00004025 CGF.EmitBranchThroughCleanup(FinallyRethrow);
Daniel Dunbar55e40722008-09-27 07:03:52 +00004026 }
Anders Carlsson80f25672008-09-09 17:59:25 +00004027 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004028
John McCall87bb5822010-07-31 23:20:56 +00004029 // Insert read hazards as required in the new blocks.
John McCall0b251722010-08-04 05:59:32 +00004030 Hazards.emitHazardsInNewBlocks();
John McCall87bb5822010-07-31 23:20:56 +00004031
John McCallf1549f62010-07-06 01:34:17 +00004032 // Pop the cleanup.
John McCall0b251722010-08-04 05:59:32 +00004033 CGF.Builder.restoreIP(TryFallthroughIP);
4034 if (CGF.HaveInsertPoint())
4035 CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
John McCallf1549f62010-07-06 01:34:17 +00004036 CGF.PopCleanupBlock();
John McCall0b251722010-08-04 05:59:32 +00004037 CGF.EmitBlock(FinallyEnd.getBlock(), true);
Anders Carlssonf3a79a92009-02-09 20:38:58 +00004038
John McCallf1549f62010-07-06 01:34:17 +00004039 // Emit the rethrow block.
John McCall87bb5822010-07-31 23:20:56 +00004040 CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
John McCallff8e1152010-07-23 21:56:41 +00004041 CGF.EmitBlock(FinallyRethrow.getBlock(), true);
John McCallf1549f62010-07-06 01:34:17 +00004042 if (CGF.HaveInsertPoint()) {
John McCall9e2213d2010-10-04 23:42:51 +00004043 // If we have a propagating-exception variable, check it.
4044 llvm::Value *PropagatingExn;
4045 if (PropagatingExnVar) {
4046 PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
John McCall0b251722010-08-04 05:59:32 +00004047
John McCall9e2213d2010-10-04 23:42:51 +00004048 // Otherwise, just look in the buffer for the exception to throw.
4049 } else {
4050 llvm::CallInst *Caught =
John McCallbd7370a2013-02-28 19:01:20 +00004051 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4052 ExceptionData);
John McCall9e2213d2010-10-04 23:42:51 +00004053 PropagatingExn = Caught;
4054 }
4055
John McCallbd7370a2013-02-28 19:01:20 +00004056 CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
4057 PropagatingExn);
John McCallf1549f62010-07-06 01:34:17 +00004058 CGF.Builder.CreateUnreachable();
Fariborz Jahanianf2878e52008-11-21 19:21:53 +00004059 }
Anders Carlsson80f25672008-09-09 17:59:25 +00004060
John McCall87bb5822010-07-31 23:20:56 +00004061 CGF.Builder.restoreIP(SavedIP);
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00004062}
4063
4064void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian6a3c70e2013-01-10 19:02:56 +00004065 const ObjCAtThrowStmt &S,
4066 bool ClearInsertionPoint) {
Anders Carlsson2b1e3112008-09-09 16:16:55 +00004067 llvm::Value *ExceptionAsObject;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004068
Anders Carlsson2b1e3112008-09-09 16:16:55 +00004069 if (const Expr *ThrowExpr = S.getThrowExpr()) {
John McCall2b014d62011-10-01 10:32:24 +00004070 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004071 ExceptionAsObject =
Benjamin Kramer578faa82011-09-27 21:06:10 +00004072 CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
Anders Carlsson2b1e3112008-09-09 16:16:55 +00004073 } else {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004074 assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
Daniel Dunbar18ccc772008-09-28 01:03:14 +00004075 "Unexpected rethrow outside @catch block.");
Anders Carlsson273558f2009-02-07 21:37:21 +00004076 ExceptionAsObject = CGF.ObjCEHValueStack.back();
Anders Carlsson2b1e3112008-09-09 16:16:55 +00004077 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004078
John McCallbd7370a2013-02-28 19:01:20 +00004079 CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
John McCallf1549f62010-07-06 01:34:17 +00004080 ->setDoesNotReturn();
Anders Carlsson80f25672008-09-09 17:59:25 +00004081 CGF.Builder.CreateUnreachable();
Daniel Dunbara448fb22008-11-11 23:11:34 +00004082
4083 // Clear the insertion point to indicate we are in unreachable code.
Fariborz Jahanian6a3c70e2013-01-10 19:02:56 +00004084 if (ClearInsertionPoint)
4085 CGF.Builder.ClearInsertionPoint();
Anders Carlsson64d5d6c2008-09-09 10:04:29 +00004086}
4087
Fariborz Jahanian3e283e32008-11-18 22:37:34 +00004088/// EmitObjCWeakRead - Code gen for loading value of a __weak
Fariborz Jahanian6dc23172008-11-18 21:45:40 +00004089/// object: objc_read_weak (id *src)
4090///
Fariborz Jahanian3e283e32008-11-18 22:37:34 +00004091llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
Mike Stump1eb44332009-09-09 15:08:12 +00004092 llvm::Value *AddrWeakObj) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00004093 llvm::Type* DestTy =
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004094 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
4095 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
4096 ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00004097 llvm::Value *read_weak =
4098 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
4099 AddrWeakObj, "weakread");
Eli Friedman8339b352009-03-07 03:57:15 +00004100 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
Fariborz Jahanian6dc23172008-11-18 21:45:40 +00004101 return read_weak;
4102}
4103
Fariborz Jahanian3e283e32008-11-18 22:37:34 +00004104/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4105/// objc_assign_weak (id src, id *dst)
4106///
4107void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
Mike Stump1eb44332009-09-09 15:08:12 +00004108 llvm::Value *src, llvm::Value *dst) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00004109 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004110 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00004111 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004112 assert(Size <= 8 && "does not support size > 8");
4113 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004114 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00004115 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4116 }
Fariborz Jahaniandbd32c22008-11-19 17:34:06 +00004117 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4118 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00004119 llvm::Value *args[] = { src, dst };
4120 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4121 args, "weakassign");
Fariborz Jahanian3e283e32008-11-18 22:37:34 +00004122 return;
4123}
4124
Fariborz Jahanian58626502008-11-19 00:59:10 +00004125/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4126/// objc_assign_global (id src, id *dst)
4127///
4128void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian021a7a62010-07-20 20:30:03 +00004129 llvm::Value *src, llvm::Value *dst,
4130 bool threadlocal) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00004131 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004132 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00004133 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004134 assert(Size <= 8 && "does not support size > 8");
4135 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004136 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00004137 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4138 }
Fariborz Jahaniandbd32c22008-11-19 17:34:06 +00004139 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4140 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00004141 llvm::Value *args[] = { src, dst };
Fariborz Jahanian021a7a62010-07-20 20:30:03 +00004142 if (!threadlocal)
John McCallbd7370a2013-02-28 19:01:20 +00004143 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4144 args, "globalassign");
Fariborz Jahanian021a7a62010-07-20 20:30:03 +00004145 else
John McCallbd7370a2013-02-28 19:01:20 +00004146 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4147 args, "threadlocalassign");
Fariborz Jahanian58626502008-11-19 00:59:10 +00004148 return;
4149}
4150
Fariborz Jahanian7eda8362008-11-20 19:23:36 +00004151/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
Fariborz Jahanian6c7a1f32009-09-24 22:25:38 +00004152/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
Fariborz Jahanian7eda8362008-11-20 19:23:36 +00004153///
4154void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian6c7a1f32009-09-24 22:25:38 +00004155 llvm::Value *src, llvm::Value *dst,
4156 llvm::Value *ivarOffset) {
4157 assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
Chris Lattner2acc6e32011-07-18 04:24:23 +00004158 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004159 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00004160 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004161 assert(Size <= 8 && "does not support size > 8");
4162 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004163 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00004164 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4165 }
Fariborz Jahanian7eda8362008-11-20 19:23:36 +00004166 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4167 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00004168 llvm::Value *args[] = { src, dst, ivarOffset };
4169 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
Fariborz Jahanian7eda8362008-11-20 19:23:36 +00004170 return;
4171}
4172
Fariborz Jahanian58626502008-11-19 00:59:10 +00004173/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
4174/// objc_assign_strongCast (id src, id *dst)
4175///
4176void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
Mike Stump1eb44332009-09-09 15:08:12 +00004177 llvm::Value *src, llvm::Value *dst) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00004178 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004179 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00004180 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004181 assert(Size <= 8 && "does not support size > 8");
4182 src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004183 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00004184 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4185 }
Fariborz Jahaniandbd32c22008-11-19 17:34:06 +00004186 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4187 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00004188 llvm::Value *args[] = { src, dst };
4189 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4190 args, "weakassign");
Fariborz Jahanian58626502008-11-19 00:59:10 +00004191 return;
4192}
4193
Fariborz Jahanian082b02e2009-07-08 01:18:33 +00004194void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004195 llvm::Value *DestPtr,
4196 llvm::Value *SrcPtr,
Fariborz Jahanian55bcace2010-06-15 22:44:06 +00004197 llvm::Value *size) {
Fariborz Jahanian082b02e2009-07-08 01:18:33 +00004198 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4199 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00004200 llvm::Value *args[] = { DestPtr, SrcPtr, size };
4201 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
Fariborz Jahanian082b02e2009-07-08 01:18:33 +00004202}
4203
Fariborz Jahanian0bb20362009-02-02 20:02:29 +00004204/// EmitObjCValueForIvar - Code Gen for ivar reference.
4205///
Fariborz Jahanian598d3f62009-02-03 19:03:09 +00004206LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4207 QualType ObjectTy,
4208 llvm::Value *BaseValue,
4209 const ObjCIvarDecl *Ivar,
Fariborz Jahanian598d3f62009-02-03 19:03:09 +00004210 unsigned CVRQualifiers) {
John McCallc12c5bb2010-05-15 11:32:37 +00004211 const ObjCInterfaceDecl *ID =
4212 ObjectTy->getAs<ObjCObjectType>()->getInterface();
Daniel Dunbar97776872009-04-22 07:32:20 +00004213 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4214 EmitIvarOffset(CGF, ID, Ivar));
Fariborz Jahanian0bb20362009-02-02 20:02:29 +00004215}
4216
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00004217llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
Daniel Dunbar2a031922009-04-22 05:08:15 +00004218 const ObjCInterfaceDecl *Interface,
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00004219 const ObjCIvarDecl *Ivar) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004220 uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4221 return llvm::ConstantInt::get(
4222 CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4223 Offset);
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00004224}
4225
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004226/* *** Private Interface *** */
4227
4228/// EmitImageInfo - Emit the image info marker used to encode some module
4229/// level information.
4230///
4231/// See: <rdr://4810609&4810587&4810587>
4232/// struct IMAGE_INFO {
4233/// unsigned version;
4234/// unsigned flags;
4235/// };
4236enum ImageInfoFlags {
Stephen Hines651f13c2014-04-23 16:59:28 -07004237 eImageInfo_FixAndContinue = (1 << 0), // This flag is no longer set by clang.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004238 eImageInfo_GarbageCollected = (1 << 1),
4239 eImageInfo_GCOnly = (1 << 2),
Stephen Hines651f13c2014-04-23 16:59:28 -07004240 eImageInfo_OptimizedByDyld = (1 << 3), // This flag is set by the dyld shared cache.
Daniel Dunbarc7c6dc02009-04-20 07:11:47 +00004241
Daniel Dunbarfce176b2010-04-25 20:39:01 +00004242 // A flag indicating that the module has no instances of a @synthesize of a
4243 // superclass variable. <rdar://problem/6803242>
Stephen Hines651f13c2014-04-23 16:59:28 -07004244 eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
Bill Wendling09822512012-04-24 11:04:57 +00004245 eImageInfo_ImageIsSimulated = (1 << 5)
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004246};
4247
Daniel Dunbarfce176b2010-04-25 20:39:01 +00004248void CGObjCCommonMac::EmitImageInfo() {
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004249 unsigned version = 0; // Version is unused?
Bill Wendling3973acc2012-02-16 01:13:30 +00004250 const char *Section = (ObjCABI == 1) ?
4251 "__OBJC, __image_info,regular" :
4252 "__DATA, __objc_imageinfo, regular, no_dead_strip";
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004253
Bill Wendling3973acc2012-02-16 01:13:30 +00004254 // Generate module-level named metadata to convey this information to the
4255 // linker and code-gen.
4256 llvm::Module &Mod = CGM.getModule();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004257
Bill Wendling3973acc2012-02-16 01:13:30 +00004258 // Add the ObjC ABI version to the module flags.
4259 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
4260 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
4261 version);
4262 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
4263 llvm::MDString::get(VMContext,Section));
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004264
David Blaikie4e4d0842012-03-11 07:00:24 +00004265 if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
Bill Wendling3973acc2012-02-16 01:13:30 +00004266 // Non-GC overrides those files which specify GC.
4267 Mod.addModuleFlag(llvm::Module::Override,
4268 "Objective-C Garbage Collection", (uint32_t)0);
4269 } else {
4270 // Add the ObjC garbage collection value.
4271 Mod.addModuleFlag(llvm::Module::Error,
4272 "Objective-C Garbage Collection",
4273 eImageInfo_GarbageCollected);
Daniel Dunbar63c5b502009-03-09 21:49:58 +00004274
David Blaikie4e4d0842012-03-11 07:00:24 +00004275 if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
Bill Wendling3973acc2012-02-16 01:13:30 +00004276 // Add the ObjC GC Only value.
4277 Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
4278 eImageInfo_GCOnly);
4279
4280 // Require that GC be specified and set to eImageInfo_GarbageCollected.
4281 llvm::Value *Ops[2] = {
4282 llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
4283 llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
4284 eImageInfo_GarbageCollected)
4285 };
4286 Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
4287 llvm::MDNode::get(VMContext, Ops));
4288 }
4289 }
Bill Wendling09822512012-04-24 11:04:57 +00004290
4291 // Indicate whether we're compiling this to run on a simulator.
4292 const llvm::Triple &Triple = CGM.getTarget().getTriple();
Cameron Esfahani57b1da12013-09-14 01:09:11 +00004293 if (Triple.isiOS() &&
Bill Wendling09822512012-04-24 11:04:57 +00004294 (Triple.getArch() == llvm::Triple::x86 ||
4295 Triple.getArch() == llvm::Triple::x86_64))
4296 Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
4297 eImageInfo_ImageIsSimulated);
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004298}
4299
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004300// struct objc_module {
4301// unsigned long version;
4302// unsigned long size;
4303// const char *name;
4304// Symtab symtab;
4305// };
4306
4307// FIXME: Get from somewhere
4308static const int ModuleVersion = 7;
4309
4310void CGObjCMac::EmitModuleInfo() {
Micah Villmow25a6a842012-10-08 16:25:52 +00004311 uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004312
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00004313 llvm::Constant *Values[] = {
4314 llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4315 llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4316 // This used to be the filename, now it is unused. <rdr://4327263>
Stephen Hines176edba2014-12-01 14:53:08 -08004317 GetClassName(StringRef("")),
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00004318 EmitModuleSymbols()
4319 };
Stephen Hines176edba2014-12-01 14:53:08 -08004320 CreateMetadataVar("OBJC_MODULES",
Owen Anderson08e25242009-07-27 22:29:56 +00004321 llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
Stephen Hines176edba2014-12-01 14:53:08 -08004322 "__OBJC,__module_info,regular,no_dead_strip", 4, true);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004323}
4324
4325llvm::Constant *CGObjCMac::EmitModuleSymbols() {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004326 unsigned NumClasses = DefinedClasses.size();
4327 unsigned NumCategories = DefinedCategories.size();
4328
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00004329 // Return null if no symbols were defined.
4330 if (!NumClasses && !NumCategories)
Owen Andersonc9c88b42009-07-31 20:28:54 +00004331 return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00004332
Chris Lattnerc5cbb902011-06-20 04:01:35 +00004333 llvm::Constant *Values[5];
Owen Anderson4a28d5d2009-07-24 23:12:58 +00004334 Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
Owen Andersonc9c88b42009-07-31 20:28:54 +00004335 Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
Owen Anderson4a28d5d2009-07-24 23:12:58 +00004336 Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4337 Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004338
Daniel Dunbar86e253a2008-08-22 20:34:54 +00004339 // The runtime expects exactly the list of defined classes followed
4340 // by the list of defined categories, in a single array.
Chris Lattner0b239712012-02-06 22:16:34 +00004341 SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
Stephen Hines651f13c2014-04-23 16:59:28 -07004342 for (unsigned i=0; i<NumClasses; i++) {
4343 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4344 assert(ID);
4345 if (ObjCImplementationDecl *IMP = ID->getImplementation())
4346 // We are implementing a weak imported interface. Give it external linkage
4347 if (ID->isWeakImported() && !IMP->isWeakImported())
4348 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4349
Owen Anderson3c4972d2009-07-29 18:54:39 +00004350 Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
Daniel Dunbar86e253a2008-08-22 20:34:54 +00004351 ObjCTypes.Int8PtrTy);
Stephen Hines651f13c2014-04-23 16:59:28 -07004352 }
Daniel Dunbar86e253a2008-08-22 20:34:54 +00004353 for (unsigned i=0; i<NumCategories; i++)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004354 Symbols[NumClasses + i] =
Owen Anderson3c4972d2009-07-29 18:54:39 +00004355 llvm::ConstantExpr::getBitCast(DefinedCategories[i],
Daniel Dunbar86e253a2008-08-22 20:34:54 +00004356 ObjCTypes.Int8PtrTy);
4357
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004358 Values[4] =
Owen Anderson96e0fc72009-07-29 22:16:19 +00004359 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Chris Lattner0b239712012-02-06 22:16:34 +00004360 Symbols.size()),
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004361 Symbols);
4362
Chris Lattnerc5cbb902011-06-20 04:01:35 +00004363 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004364
Stephen Hines176edba2014-12-01 14:53:08 -08004365 llvm::GlobalVariable *GV = CreateMetadataVar(
4366 "OBJC_SYMBOLS", Init, "__OBJC,__symbols,regular,no_dead_strip", 4, true);
Owen Anderson3c4972d2009-07-29 18:54:39 +00004367 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004368}
4369
John McCallbd7370a2013-02-28 19:01:20 +00004370llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4371 IdentifierInfo *II) {
John McCallf85e1932011-06-15 23:02:42 +00004372 LazySymbols.insert(II);
4373
4374 llvm::GlobalVariable *&Entry = ClassReferences[II];
4375
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004376 if (!Entry) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004377 llvm::Constant *Casted =
Stephen Hines176edba2014-12-01 14:53:08 -08004378 llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
John McCallf85e1932011-06-15 23:02:42 +00004379 ObjCTypes.ClassPtrTy);
Stephen Hines176edba2014-12-01 14:53:08 -08004380 Entry = CreateMetadataVar(
4381 "OBJC_CLASS_REFERENCES_", Casted,
4382 "__OBJC,__cls_refs,literal_pointers,no_dead_strip", 4, true);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004383 }
John McCallf85e1932011-06-15 23:02:42 +00004384
John McCallbd7370a2013-02-28 19:01:20 +00004385 return CGF.Builder.CreateLoad(Entry);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004386}
4387
John McCallbd7370a2013-02-28 19:01:20 +00004388llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
John McCallf85e1932011-06-15 23:02:42 +00004389 const ObjCInterfaceDecl *ID) {
John McCallbd7370a2013-02-28 19:01:20 +00004390 return EmitClassRefFromId(CGF, ID->getIdentifier());
John McCallf85e1932011-06-15 23:02:42 +00004391}
4392
John McCallbd7370a2013-02-28 19:01:20 +00004393llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
John McCallf85e1932011-06-15 23:02:42 +00004394 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
John McCallbd7370a2013-02-28 19:01:20 +00004395 return EmitClassRefFromId(CGF, II);
John McCallf85e1932011-06-15 23:02:42 +00004396}
4397
John McCallbd7370a2013-02-28 19:01:20 +00004398llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel,
Fariborz Jahanian03b29602010-06-17 19:56:20 +00004399 bool lvalue) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004400 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004401
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004402 if (!Entry) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004403 llvm::Constant *Casted =
Owen Anderson3c4972d2009-07-29 18:54:39 +00004404 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004405 ObjCTypes.SelectorPtrTy);
Stephen Hines176edba2014-12-01 14:53:08 -08004406 Entry = CreateMetadataVar(
4407 "OBJC_SELECTOR_REFERENCES_", Casted,
4408 "__OBJC,__message_refs,literal_pointers,no_dead_strip", 4, true);
Michael Gottesman8f98bf92013-02-05 23:08:45 +00004409 Entry->setExternallyInitialized(true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004410 }
4411
Fariborz Jahanian03b29602010-06-17 19:56:20 +00004412 if (lvalue)
4413 return Entry;
John McCallbd7370a2013-02-28 19:01:20 +00004414 return CGF.Builder.CreateLoad(Entry);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004415}
4416
Stephen Hines176edba2014-12-01 14:53:08 -08004417llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
4418 llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
4419 if (!Entry)
4420 Entry = CreateMetadataVar(
4421 "OBJC_CLASS_NAME_",
4422 llvm::ConstantDataArray::getString(VMContext, RuntimeName),
4423 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
4424 : "__TEXT,__cstring,cstring_literals"),
4425 1, true);
4426 return getConstantGEP(VMContext, Entry, 0, 0);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004427}
4428
Argyrios Kyrtzidis9d50c062010-08-09 10:54:20 +00004429llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4430 llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4431 I = MethodDefinitions.find(MD);
4432 if (I != MethodDefinitions.end())
4433 return I->second;
4434
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004435 return nullptr;
Argyrios Kyrtzidis9d50c062010-08-09 10:54:20 +00004436}
4437
Fariborz Jahaniand80d81b2009-03-05 19:17:31 +00004438/// GetIvarLayoutName - Returns a unique constant for the given
4439/// ivar layout bitmap.
4440llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004441 const ObjCCommonTypesHelper &ObjCTypes) {
Owen Andersonc9c88b42009-07-31 20:28:54 +00004442 return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Fariborz Jahaniand80d81b2009-03-05 19:17:31 +00004443}
4444
Daniel Dunbard58edcb2009-05-03 14:10:34 +00004445void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
Eli Friedmane5b46662012-11-06 22:15:52 +00004446 unsigned int BytePos,
Daniel Dunbard58edcb2009-05-03 14:10:34 +00004447 bool ForStrongLayout,
4448 bool &HasUnion) {
4449 const RecordDecl *RD = RT->getDecl();
4450 // FIXME - Use iterator.
Stephen Hines651f13c2014-04-23 16:59:28 -07004451 SmallVector<const FieldDecl*, 16> Fields(RD->fields());
Chris Lattner2acc6e32011-07-18 04:24:23 +00004452 llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004453 const llvm::StructLayout *RecLayout =
Micah Villmow25a6a842012-10-08 16:25:52 +00004454 CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004455
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004456 BuildAggrIvarLayout(nullptr, RecLayout, RD, Fields, BytePos, ForStrongLayout,
4457 HasUnion);
Daniel Dunbard58edcb2009-05-03 14:10:34 +00004458}
4459
Daniel Dunbar5a5a8032009-05-03 21:05:10 +00004460void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004461 const llvm::StructLayout *Layout,
4462 const RecordDecl *RD,
Bill Wendling795b1002012-02-22 09:30:11 +00004463 ArrayRef<const FieldDecl*> RecFields,
Eli Friedmane5b46662012-11-06 22:15:52 +00004464 unsigned int BytePos, bool ForStrongLayout,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004465 bool &HasUnion) {
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004466 bool IsUnion = (RD && RD->isUnion());
Eli Friedmane5b46662012-11-06 22:15:52 +00004467 uint64_t MaxUnionIvarSize = 0;
4468 uint64_t MaxSkippedUnionIvarSize = 0;
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004469 const FieldDecl *MaxField = nullptr;
4470 const FieldDecl *MaxSkippedField = nullptr;
4471 const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
Eli Friedmane5b46662012-11-06 22:15:52 +00004472 uint64_t MaxFieldOffset = 0;
4473 uint64_t MaxSkippedFieldOffset = 0;
4474 uint64_t LastBitfieldOrUnnamedOffset = 0;
4475 uint64_t FirstFieldDelta = 0;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004476
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +00004477 if (RecFields.empty())
4478 return;
John McCall64aa4b32013-04-16 22:48:15 +00004479 unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
4480 unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
David Blaikie4e4d0842012-03-11 07:00:24 +00004481 if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004482 const FieldDecl *FirstField = RecFields[0];
4483 FirstFieldDelta =
4484 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
John McCallf85e1932011-06-15 23:02:42 +00004485 }
4486
Chris Lattnerf1690852009-03-31 08:48:01 +00004487 for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
Jordy Rosedb8264e2011-07-22 02:08:32 +00004488 const FieldDecl *Field = RecFields[i];
Eli Friedmane5b46662012-11-06 22:15:52 +00004489 uint64_t FieldOffset;
Anders Carlssonfc514ab2009-07-24 17:23:54 +00004490 if (RD) {
Daniel Dunbarf8f8eba2010-04-14 17:02:21 +00004491 // Note that 'i' here is actually the field index inside RD of Field,
4492 // although this dependency is hidden.
4493 const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
Eli Friedmane5b46662012-11-06 22:15:52 +00004494 FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
Anders Carlssonfc514ab2009-07-24 17:23:54 +00004495 } else
John McCallf85e1932011-06-15 23:02:42 +00004496 FieldOffset =
4497 ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
Daniel Dunbar25d583e2009-05-03 14:17:18 +00004498
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +00004499 // Skip over unnamed or bitfields
Fariborz Jahanian7fb16272009-04-21 18:33:06 +00004500 if (!Field->getIdentifier() || Field->isBitField()) {
Argyrios Kyrtzidis0dc75092010-09-06 12:00:10 +00004501 LastFieldBitfieldOrUnnamed = Field;
4502 LastBitfieldOrUnnamedOffset = FieldOffset;
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +00004503 continue;
Fariborz Jahanian7fb16272009-04-21 18:33:06 +00004504 }
Daniel Dunbar25d583e2009-05-03 14:17:18 +00004505
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004506 LastFieldBitfieldOrUnnamed = nullptr;
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +00004507 QualType FQT = Field->getType();
Fariborz Jahanian667423a2009-03-25 22:36:49 +00004508 if (FQT->isRecordType() || FQT->isUnionType()) {
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +00004509 if (FQT->isUnionType())
4510 HasUnion = true;
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004511
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004512 BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
Daniel Dunbar25d583e2009-05-03 14:17:18 +00004513 BytePos + FieldOffset,
Daniel Dunbard58edcb2009-05-03 14:10:34 +00004514 ForStrongLayout, HasUnion);
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +00004515 continue;
4516 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004517
Chris Lattnerf1690852009-03-31 08:48:01 +00004518 if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004519 const ConstantArrayType *CArray =
Daniel Dunbar5e563dd2009-05-03 13:55:09 +00004520 dyn_cast_or_null<ConstantArrayType>(Array);
Fariborz Jahanian7fb16272009-04-21 18:33:06 +00004521 uint64_t ElCount = CArray->getSize().getZExtValue();
Daniel Dunbar5e563dd2009-05-03 13:55:09 +00004522 assert(CArray && "only array with known element size is supported");
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004523 FQT = CArray->getElementType();
Fariborz Jahanian667423a2009-03-25 22:36:49 +00004524 while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4525 const ConstantArrayType *CArray =
Daniel Dunbar5e563dd2009-05-03 13:55:09 +00004526 dyn_cast_or_null<ConstantArrayType>(Array);
Fariborz Jahanian7fb16272009-04-21 18:33:06 +00004527 ElCount *= CArray->getSize().getZExtValue();
Fariborz Jahanian667423a2009-03-25 22:36:49 +00004528 FQT = CArray->getElementType();
4529 }
Fariborz Jahanianf96bdf42011-01-03 19:23:18 +00004530 if (FQT->isRecordType() && ElCount) {
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004531 int OldIndex = IvarsInfo.size() - 1;
4532 int OldSkIndex = SkipIvars.size() -1;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004533
Ted Kremenek6217b802009-07-29 21:53:49 +00004534 const RecordType *RT = FQT->getAs<RecordType>();
Daniel Dunbar25d583e2009-05-03 14:17:18 +00004535 BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
Daniel Dunbard58edcb2009-05-03 14:10:34 +00004536 ForStrongLayout, HasUnion);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004537
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004538 // Replicate layout information for each array element. Note that
4539 // one element is already done.
4540 uint64_t ElIx = 1;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004541 for (int FirstIndex = IvarsInfo.size() - 1,
4542 FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004543 uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
Daniel Dunbar8b2926c2009-05-03 13:44:42 +00004544 for (int i = OldIndex+1; i <= FirstIndex; ++i)
4545 IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
4546 IvarsInfo[i].ivar_size));
4547 for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
4548 SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
4549 SkipIvars[i].ivar_size));
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004550 }
4551 continue;
4552 }
Fariborz Jahaniana5a10c32009-03-10 16:22:08 +00004553 }
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004554 // At this point, we are done with Record/Union and array there of.
4555 // For other arrays we are down to its element type.
John McCall0953e762009-09-24 19:53:00 +00004556 Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
Daniel Dunbar5e563dd2009-05-03 13:55:09 +00004557
Eli Friedmane5b46662012-11-06 22:15:52 +00004558 unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
John McCall0953e762009-09-24 19:53:00 +00004559 if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4560 || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
Daniel Dunbar487993b2009-05-03 13:32:01 +00004561 if (IsUnion) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004562 uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
Daniel Dunbar487993b2009-05-03 13:32:01 +00004563 if (UnionIvarSize > MaxUnionIvarSize) {
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004564 MaxUnionIvarSize = UnionIvarSize;
4565 MaxField = Field;
Daniel Dunbar900c1982009-05-03 23:31:46 +00004566 MaxFieldOffset = FieldOffset;
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004567 }
Daniel Dunbar487993b2009-05-03 13:32:01 +00004568 } else {
Eli Friedmane5b46662012-11-06 22:15:52 +00004569 IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
4570 FieldSize / WordSizeInBits));
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004571 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004572 } else if ((ForStrongLayout &&
John McCall0953e762009-09-24 19:53:00 +00004573 (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
4574 || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
Daniel Dunbar487993b2009-05-03 13:32:01 +00004575 if (IsUnion) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004576 // FIXME: Why the asymmetry? We divide by word size in bits on other
4577 // side.
4578 uint64_t UnionIvarSize = FieldSize / ByteSizeInBits;
Daniel Dunbar487993b2009-05-03 13:32:01 +00004579 if (UnionIvarSize > MaxSkippedUnionIvarSize) {
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004580 MaxSkippedUnionIvarSize = UnionIvarSize;
4581 MaxSkippedField = Field;
Daniel Dunbar900c1982009-05-03 23:31:46 +00004582 MaxSkippedFieldOffset = FieldOffset;
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004583 }
Daniel Dunbar487993b2009-05-03 13:32:01 +00004584 } else {
Eli Friedmane5b46662012-11-06 22:15:52 +00004585 // FIXME: Why the asymmetry, we divide by byte size in bits here?
4586 SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
4587 FieldSize / ByteSizeInBits));
Fariborz Jahanian820e0202009-03-11 00:07:04 +00004588 }
4589 }
4590 }
Daniel Dunbard58edcb2009-05-03 14:10:34 +00004591
Argyrios Kyrtzidis0dc75092010-09-06 12:00:10 +00004592 if (LastFieldBitfieldOrUnnamed) {
4593 if (LastFieldBitfieldOrUnnamed->isBitField()) {
4594 // Last field was a bitfield. Must update skip info.
Richard Smitha6b8b2c2011-10-10 18:28:20 +00004595 uint64_t BitFieldSize
4596 = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
Argyrios Kyrtzidis0dc75092010-09-06 12:00:10 +00004597 GC_IVAR skivar;
4598 skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
Eli Friedmane5b46662012-11-06 22:15:52 +00004599 skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
4600 + ((BitFieldSize % ByteSizeInBits) != 0);
Argyrios Kyrtzidis0dc75092010-09-06 12:00:10 +00004601 SkipIvars.push_back(skivar);
4602 } else {
4603 assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
4604 // Last field was unnamed. Must update skip info.
Eli Friedmane5b46662012-11-06 22:15:52 +00004605 unsigned FieldSize
4606 = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
Argyrios Kyrtzidis0dc75092010-09-06 12:00:10 +00004607 SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
Eli Friedmane5b46662012-11-06 22:15:52 +00004608 FieldSize / ByteSizeInBits));
Argyrios Kyrtzidis0dc75092010-09-06 12:00:10 +00004609 }
Fariborz Jahanian7fb16272009-04-21 18:33:06 +00004610 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004611
Daniel Dunbar8b2926c2009-05-03 13:44:42 +00004612 if (MaxField)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004613 IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
Daniel Dunbar8b2926c2009-05-03 13:44:42 +00004614 MaxUnionIvarSize));
4615 if (MaxSkippedField)
Daniel Dunbar900c1982009-05-03 23:31:46 +00004616 SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
Daniel Dunbar8b2926c2009-05-03 13:44:42 +00004617 MaxSkippedUnionIvarSize));
Fariborz Jahaniand61a50a2009-03-05 22:39:55 +00004618}
4619
Fariborz Jahanianb8fd2eb2010-08-05 00:19:48 +00004620/// BuildIvarLayoutBitmap - This routine is the horsework for doing all
4621/// the computations and returning the layout bitmap (for ivar or blocks) in
4622/// the given argument BitMap string container. Routine reads
4623/// two containers, IvarsInfo and SkipIvars which are assumed to be
4624/// filled already by the caller.
Chris Lattner94010692012-02-05 02:30:40 +00004625llvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004626 unsigned int WordsToScan, WordsToSkip;
Chris Lattner8b418682012-02-07 00:39:47 +00004627 llvm::Type *PtrTy = CGM.Int8PtrTy;
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004628
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004629 // Build the string of skip/scan nibbles
Chris Lattner5f9e2722011-07-23 10:55:15 +00004630 SmallVector<SKIP_SCAN, 32> SkipScanIvars;
Eli Friedmane5b46662012-11-06 22:15:52 +00004631 unsigned int WordSize =
4632 CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy);
4633 if (IvarsInfo[0].ivar_bytepos == 0) {
4634 WordsToSkip = 0;
4635 WordsToScan = IvarsInfo[0].ivar_size;
4636 } else {
4637 WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
4638 WordsToScan = IvarsInfo[0].ivar_size;
4639 }
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004640 for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004641 unsigned int TailPrevGCObjC =
4642 IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004643 if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004644 // consecutive 'scanned' object pointers.
Eli Friedmane5b46662012-11-06 22:15:52 +00004645 WordsToScan += IvarsInfo[i].ivar_size;
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004646 } else {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004647 // Skip over 'gc'able object pointer which lay over each other.
4648 if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
4649 continue;
4650 // Must skip over 1 or more words. We save current skip/scan values
4651 // and start a new pair.
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +00004652 SKIP_SCAN SkScan;
4653 SkScan.skip = WordsToSkip;
4654 SkScan.scan = WordsToScan;
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004655 SkipScanIvars.push_back(SkScan);
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004656
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004657 // Skip the hole.
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +00004658 SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
4659 SkScan.scan = 0;
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004660 SkipScanIvars.push_back(SkScan);
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004661 WordsToSkip = 0;
Eli Friedmane5b46662012-11-06 22:15:52 +00004662 WordsToScan = IvarsInfo[i].ivar_size;
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004663 }
4664 }
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004665 if (WordsToScan > 0) {
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +00004666 SKIP_SCAN SkScan;
4667 SkScan.skip = WordsToSkip;
4668 SkScan.scan = WordsToScan;
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004669 SkipScanIvars.push_back(SkScan);
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004670 }
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004671
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004672 if (!SkipIvars.empty()) {
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004673 unsigned int LastIndex = SkipIvars.size()-1;
Eli Friedmane5b46662012-11-06 22:15:52 +00004674 int LastByteSkipped =
4675 SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004676 LastIndex = IvarsInfo.size()-1;
Eli Friedmane5b46662012-11-06 22:15:52 +00004677 int LastByteScanned =
4678 IvarsInfo[LastIndex].ivar_bytepos +
4679 IvarsInfo[LastIndex].ivar_size * WordSize;
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004680 // Compute number of bytes to skip at the tail end of the last ivar scanned.
Benjamin Kramer54d76db2009-12-25 15:43:36 +00004681 if (LastByteSkipped > LastByteScanned) {
Eli Friedmane5b46662012-11-06 22:15:52 +00004682 unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +00004683 SKIP_SCAN SkScan;
Eli Friedmane5b46662012-11-06 22:15:52 +00004684 SkScan.skip = TotalWords - (LastByteScanned/WordSize);
Fariborz Jahanianc8ce9c82009-03-12 22:50:49 +00004685 SkScan.scan = 0;
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004686 SkipScanIvars.push_back(SkScan);
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004687 }
4688 }
4689 // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
4690 // as 0xMN.
Fariborz Jahanian81adc052009-04-24 16:17:09 +00004691 int SkipScan = SkipScanIvars.size()-1;
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004692 for (int i = 0; i <= SkipScan; i++) {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004693 if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
4694 && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
4695 // 0xM0 followed by 0x0N detected.
4696 SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
4697 for (int j = i+1; j < SkipScan; j++)
4698 SkipScanIvars[j] = SkipScanIvars[j+1];
4699 --SkipScan;
4700 }
4701 }
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004702
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004703 // Generate the string.
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004704 for (int i = 0; i <= SkipScan; i++) {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004705 unsigned char byte;
4706 unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
4707 unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
4708 unsigned int skip_big = SkipScanIvars[i].skip / 0xf;
4709 unsigned int scan_big = SkipScanIvars[i].scan / 0xf;
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004710
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004711 // first skip big.
4712 for (unsigned int ix = 0; ix < skip_big; ix++)
4713 BitMap += (unsigned char)(0xf0);
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004714
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004715 // next (skip small, scan)
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004716 if (skip_small) {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004717 byte = skip_small << 4;
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004718 if (scan_big > 0) {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004719 byte |= 0xf;
4720 --scan_big;
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004721 } else if (scan_small) {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004722 byte |= scan_small;
4723 scan_small = 0;
4724 }
4725 BitMap += byte;
4726 }
4727 // next scan big
4728 for (unsigned int ix = 0; ix < scan_big; ix++)
4729 BitMap += (unsigned char)(0x0f);
4730 // last scan small
Daniel Dunbar31682fd2009-05-03 23:21:22 +00004731 if (scan_small) {
Fariborz Jahanian9397e1d2009-03-11 20:59:05 +00004732 byte = scan_small;
4733 BitMap += byte;
4734 }
4735 }
4736 // null terminate string.
Fariborz Jahanian667423a2009-03-25 22:36:49 +00004737 unsigned char zero = 0;
4738 BitMap += zero;
Stephen Hines176edba2014-12-01 14:53:08 -08004739
4740 llvm::GlobalVariable *Entry = CreateMetadataVar(
4741 "OBJC_CLASS_NAME_",
4742 llvm::ConstantDataArray::getString(VMContext, BitMap, false),
4743 ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
4744 : "__TEXT,__cstring,cstring_literals"),
4745 1, true);
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004746 return getConstantGEP(VMContext, Entry, 0, 0);
4747}
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004748
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004749/// BuildIvarLayout - Builds ivar layout bitmap for the class
4750/// implementation for the __strong or __weak case.
4751/// The layout map displays which words in ivar list must be skipped
4752/// and which must be scanned by GC (see below). String is built of bytes.
4753/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
4754/// of words to skip and right nibble is count of words to scan. So, each
4755/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
4756/// represented by a 0x00 byte which also ends the string.
4757/// 1. when ForStrongLayout is true, following ivars are scanned:
4758/// - id, Class
4759/// - object *
4760/// - __strong anything
4761///
4762/// 2. When ForStrongLayout is false, following ivars are scanned:
4763/// - __weak anything
4764///
4765llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
4766 const ObjCImplementationDecl *OMD,
4767 bool ForStrongLayout) {
4768 bool hasUnion = false;
4769
Chris Lattner8b418682012-02-07 00:39:47 +00004770 llvm::Type *PtrTy = CGM.Int8PtrTy;
David Blaikie4e4d0842012-03-11 07:00:24 +00004771 if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4772 !CGM.getLangOpts().ObjCAutoRefCount)
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004773 return llvm::Constant::getNullValue(PtrTy);
4774
Jordy Rosedb8264e2011-07-22 02:08:32 +00004775 const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4776 SmallVector<const FieldDecl*, 32> RecFields;
David Blaikie4e4d0842012-03-11 07:00:24 +00004777 if (CGM.getLangOpts().ObjCAutoRefCount) {
Jordy Rosedb8264e2011-07-22 02:08:32 +00004778 for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
Fariborz Jahanianbf9eb882011-06-28 18:05:25 +00004779 IVD; IVD = IVD->getNextIvar())
4780 RecFields.push_back(cast<FieldDecl>(IVD));
4781 }
4782 else {
Jordy Rosedb8264e2011-07-22 02:08:32 +00004783 SmallVector<const ObjCIvarDecl*, 32> Ivars;
John McCallf85e1932011-06-15 23:02:42 +00004784 CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004785
Jordy Rosedb8264e2011-07-22 02:08:32 +00004786 // FIXME: This is not ideal; we shouldn't have to do this copy.
4787 RecFields.append(Ivars.begin(), Ivars.end());
Fariborz Jahanianbf9eb882011-06-28 18:05:25 +00004788 }
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004789
4790 if (RecFields.empty())
4791 return llvm::Constant::getNullValue(PtrTy);
4792
4793 SkipIvars.clear();
4794 IvarsInfo.clear();
4795
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004796 BuildAggrIvarLayout(OMD, nullptr, nullptr, RecFields, 0, ForStrongLayout,
4797 hasUnion);
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004798 if (IvarsInfo.empty())
4799 return llvm::Constant::getNullValue(PtrTy);
Fariborz Jahanianb8fd2eb2010-08-05 00:19:48 +00004800 // Sort on byte position in case we encounterred a union nested in
4801 // the ivar list.
4802 if (hasUnion && !IvarsInfo.empty())
4803 std::sort(IvarsInfo.begin(), IvarsInfo.end());
4804 if (hasUnion && !SkipIvars.empty())
4805 std::sort(SkipIvars.begin(), SkipIvars.end());
4806
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004807 std::string BitMap;
Fariborz Jahanianb8fd2eb2010-08-05 00:19:48 +00004808 llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004809
David Blaikie4e4d0842012-03-11 07:00:24 +00004810 if (CGM.getLangOpts().ObjCGCBitmapPrint) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004811 printf("\n%s ivar layout for class '%s': ",
Fariborz Jahanian3d2ad662009-04-20 22:03:45 +00004812 ForStrongLayout ? "strong" : "weak",
Stephen Hines176edba2014-12-01 14:53:08 -08004813 OMD->getClassInterface()->getName().str().c_str());
Roman Divacky31ba6132012-09-06 15:59:27 +00004814 const unsigned char *s = (const unsigned char*)BitMap.c_str();
Bill Wendling13562a12012-02-07 09:06:01 +00004815 for (unsigned i = 0, e = BitMap.size(); i < e; i++)
Fariborz Jahanian3d2ad662009-04-20 22:03:45 +00004816 if (!(s[i] & 0xf0))
4817 printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
4818 else
4819 printf("0x%x%s", s[i], s[i] != 0 ? ", " : "");
4820 printf("\n");
4821 }
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004822 return C;
Fariborz Jahaniand61a50a2009-03-05 22:39:55 +00004823}
4824
Fariborz Jahanian56210f72009-01-21 23:34:32 +00004825llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004826 llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4827
Chris Lattner0b239712012-02-06 22:16:34 +00004828 // FIXME: Avoid std::string in "Sel.getAsString()"
Daniel Dunbar63c5b502009-03-09 21:49:58 +00004829 if (!Entry)
Stephen Hines176edba2014-12-01 14:53:08 -08004830 Entry = CreateMetadataVar(
4831 "OBJC_METH_VAR_NAME_",
4832 llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4833 ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals"
4834 : "__TEXT,__cstring,cstring_literals"),
4835 1, true);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004836
Owen Andersona1cf15f2009-07-14 23:10:40 +00004837 return getConstantGEP(VMContext, Entry, 0, 0);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00004838}
4839
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004840// FIXME: Merge into a single cstring creation function.
Fariborz Jahanian56210f72009-01-21 23:34:32 +00004841llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004842 return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
4843}
4844
Daniel Dunbar3e5f0d82009-04-20 06:54:31 +00004845llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
Devang Patel7794bb82009-03-04 18:21:39 +00004846 std::string TypeStr;
4847 CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
4848
4849 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00004850
Daniel Dunbar63c5b502009-03-09 21:49:58 +00004851 if (!Entry)
Stephen Hines176edba2014-12-01 14:53:08 -08004852 Entry = CreateMetadataVar(
4853 "OBJC_METH_VAR_TYPE_",
4854 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4855 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
4856 : "__TEXT,__cstring,cstring_literals"),
4857 1, true);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004858
Owen Andersona1cf15f2009-07-14 23:10:40 +00004859 return getConstantGEP(VMContext, Entry, 0, 0);
Daniel Dunbar259d93d2008-08-12 03:39:23 +00004860}
4861
Bob Wilsondc8dab62011-11-30 01:57:58 +00004862llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
4863 bool Extended) {
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004864 std::string TypeStr;
Bill Wendlinga4dc6932012-02-09 22:45:21 +00004865 if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004866 return nullptr;
Devang Patel7794bb82009-03-04 18:21:39 +00004867
4868 llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4869
Daniel Dunbarb90bb002009-04-14 23:14:47 +00004870 if (!Entry)
Stephen Hines176edba2014-12-01 14:53:08 -08004871 Entry = CreateMetadataVar(
4872 "OBJC_METH_VAR_TYPE_",
4873 llvm::ConstantDataArray::getString(VMContext, TypeStr),
4874 ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
4875 : "__TEXT,__cstring,cstring_literals"),
4876 1, true);
Devang Patel7794bb82009-03-04 18:21:39 +00004877
Owen Andersona1cf15f2009-07-14 23:10:40 +00004878 return getConstantGEP(VMContext, Entry, 0, 0);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004879}
4880
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00004881// FIXME: Merge into a single cstring creation function.
Fariborz Jahanian56210f72009-01-21 23:34:32 +00004882llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00004883 llvm::GlobalVariable *&Entry = PropertyNames[Ident];
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004884
Daniel Dunbar63c5b502009-03-09 21:49:58 +00004885 if (!Entry)
Stephen Hinesc568f1e2014-07-21 00:47:37 -07004886 Entry = CreateMetadataVar(
Stephen Hines176edba2014-12-01 14:53:08 -08004887 "OBJC_PROP_NAME_ATTR_",
Stephen Hinesc568f1e2014-07-21 00:47:37 -07004888 llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
4889 "__TEXT,__cstring,cstring_literals", 1, true);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00004890
Owen Andersona1cf15f2009-07-14 23:10:40 +00004891 return getConstantGEP(VMContext, Entry, 0, 0);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00004892}
4893
4894// FIXME: Merge into a single cstring creation function.
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00004895// FIXME: This Decl should be more precise.
Daniel Dunbar63c5b502009-03-09 21:49:58 +00004896llvm::Constant *
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004897CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
4898 const Decl *Container) {
Daniel Dunbarc56f34a2008-08-28 04:38:10 +00004899 std::string TypeStr;
4900 CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
Daniel Dunbarc8ef5512008-08-23 00:19:03 +00004901 return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4902}
4903
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004904void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
Fariborz Jahanian56210f72009-01-21 23:34:32 +00004905 const ObjCContainerDecl *CD,
Chris Lattner5f9e2722011-07-23 10:55:15 +00004906 SmallVectorImpl<char> &Name) {
Daniel Dunbarc575ce72009-10-19 01:21:19 +00004907 llvm::raw_svector_ostream OS(Name);
Fariborz Jahanian679a5022009-01-10 21:06:09 +00004908 assert (CD && "Missing container decl in GetNameForMethod");
Daniel Dunbarc575ce72009-10-19 01:21:19 +00004909 OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4910 << '[' << CD->getName();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004911 if (const ObjCCategoryImplDecl *CID =
Daniel Dunbarc575ce72009-10-19 01:21:19 +00004912 dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
Benjamin Kramerf9780592012-02-07 11:57:45 +00004913 OS << '(' << *CID << ')';
Daniel Dunbarc575ce72009-10-19 01:21:19 +00004914 OS << ' ' << D->getSelector().getAsString() << ']';
Daniel Dunbarb7ec2462008-08-16 03:19:19 +00004915}
4916
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004917void CGObjCMac::FinishModule() {
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004918 EmitModuleInfo();
4919
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00004920 // Emit the dummy bodies for any protocols which were referenced but
4921 // never defined.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004922 for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
Chris Lattnerad64e022009-07-17 23:57:13 +00004923 I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4924 if (I->second->hasInitializer())
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00004925 continue;
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004926
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00004927 llvm::Constant *Values[5];
Owen Andersonc9c88b42009-07-31 20:28:54 +00004928 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
Stephen Hines176edba2014-12-01 14:53:08 -08004929 Values[1] = GetClassName(I->first->getName());
Owen Andersonc9c88b42009-07-31 20:28:54 +00004930 Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00004931 Values[3] = Values[4] =
Owen Andersonc9c88b42009-07-31 20:28:54 +00004932 llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
Owen Anderson08e25242009-07-27 22:29:56 +00004933 I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00004934 Values));
Stephen Hines651f13c2014-04-23 16:59:28 -07004935 CGM.addCompilerUsedGlobal(I->second);
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00004936 }
4937
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00004938 // Add assembler directives to add lazy undefined symbol references
4939 // for classes which are referenced but not defined. This is
4940 // important for correct linker interaction.
Daniel Dunbar33063492009-09-07 00:20:42 +00004941 //
4942 // FIXME: It would be nice if we had an LLVM construct for this.
4943 if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00004944 SmallString<256> Asm;
Daniel Dunbar33063492009-09-07 00:20:42 +00004945 Asm += CGM.getModule().getModuleInlineAsm();
4946 if (!Asm.empty() && Asm.back() != '\n')
4947 Asm += '\n';
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00004948
Daniel Dunbar33063492009-09-07 00:20:42 +00004949 llvm::raw_svector_ostream OS(Asm);
Daniel Dunbar33063492009-09-07 00:20:42 +00004950 for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
4951 e = DefinedSymbols.end(); I != e; ++I)
Daniel Dunbar01eb9b92009-10-18 21:17:35 +00004952 OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
4953 << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
Chris Lattnerafd5eda2010-04-17 18:26:20 +00004954 for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
Fariborz Jahanianb9c5b3d2010-06-21 22:05:18 +00004955 e = LazySymbols.end(); I != e; ++I) {
Chris Lattnerafd5eda2010-04-17 18:26:20 +00004956 OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
Fariborz Jahanianb9c5b3d2010-06-21 22:05:18 +00004957 }
4958
Bill Wendling13562a12012-02-07 09:06:01 +00004959 for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
Fariborz Jahanianb9c5b3d2010-06-21 22:05:18 +00004960 OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
4961 << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
4962 }
Chris Lattnerafd5eda2010-04-17 18:26:20 +00004963
Daniel Dunbar33063492009-09-07 00:20:42 +00004964 CGM.getModule().setModuleInlineAsm(OS.str());
Daniel Dunbar242d4dc2008-08-25 06:02:07 +00004965 }
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004966}
4967
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004968CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
Fariborz Jahanianee0af742009-01-21 22:04:16 +00004969 : CGObjCCommonMac(cgm),
Mike Stump1eb44332009-09-09 15:08:12 +00004970 ObjCTypes(cgm) {
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004971 ObjCEmptyCacheVar = ObjCEmptyVtableVar = nullptr;
Fariborz Jahanianee0af742009-01-21 22:04:16 +00004972 ObjCABI = 2;
4973}
4974
Daniel Dunbarf77ac862008-08-11 21:35:06 +00004975/* *** */
4976
Fariborz Jahanianee0af742009-01-21 22:04:16 +00004977ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07004978 : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
Douglas Gregor65a1e672012-01-17 23:38:32 +00004979{
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004980 CodeGen::CodeGenTypes &Types = CGM.getTypes();
4981 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004982
Daniel Dunbar27f9d772008-08-21 04:36:09 +00004983 ShortTy = Types.ConvertType(Ctx.ShortTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00004984 IntTy = Types.ConvertType(Ctx.IntTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004985 LongTy = Types.ConvertType(Ctx.LongTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00004986 LongLongTy = Types.ConvertType(Ctx.LongLongTy);
Chris Lattner8b418682012-02-07 00:39:47 +00004987 Int8PtrTy = CGM.Int8PtrTy;
4988 Int8PtrPtrTy = CGM.Int8PtrPtrTy;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00004989
Stephen Hines651f13c2014-04-23 16:59:28 -07004990 // arm64 targets use "int" ivar offset variables. All others,
4991 // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
Stephen Hines176edba2014-12-01 14:53:08 -08004992 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
Stephen Hines651f13c2014-04-23 16:59:28 -07004993 IvarOffsetVarTy = IntTy;
4994 else
4995 IvarOffsetVarTy = LongTy;
4996
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004997 ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
Owen Anderson96e0fc72009-07-29 22:16:19 +00004998 PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00004999 SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005000
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005001 // I'm not sure I like this. The implicit coordination is a bit
5002 // gross. We should solve this in a reasonable fashion because this
5003 // is a pretty common task (match some runtime data structure with
5004 // an LLVM data structure).
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005005
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005006 // FIXME: This is leaked.
5007 // FIXME: Merge with rewriter code?
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005008
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005009 // struct _objc_super {
5010 // id self;
5011 // Class cls;
5012 // }
Abramo Bagnara465d41b2010-05-11 21:36:43 +00005013 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
Daniel Dunbardaa3ac52010-04-29 16:29:11 +00005014 Ctx.getTranslationUnitDecl(),
Abramo Bagnaraba877ad2011-03-09 14:09:51 +00005015 SourceLocation(), SourceLocation(),
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005016 &Ctx.Idents.get("_objc_super"));
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005017 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5018 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5019 false, ICIS_NoInit));
5020 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5021 nullptr, Ctx.getObjCClassType(), nullptr,
5022 nullptr, false, ICIS_NoInit));
Douglas Gregor838db382010-02-11 01:19:42 +00005023 RD->completeDefinition();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005024
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005025 SuperCTy = Ctx.getTagDeclType(RD);
5026 SuperPtrCTy = Ctx.getPointerType(SuperCTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005027
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005028 SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005029 SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5030
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005031 // struct _prop_t {
5032 // char *name;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005033 // char *attributes;
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005034 // }
Chris Lattnerc1c20112011-08-12 17:43:31 +00005035 PropertyTy = llvm::StructType::create("struct._prop_t",
5036 Int8PtrTy, Int8PtrTy, NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005037
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005038 // struct _prop_list_t {
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005039 // uint32_t entsize; // sizeof(struct _prop_t)
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005040 // uint32_t count_of_properties;
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005041 // struct _prop_t prop_list[count_of_properties];
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005042 // }
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005043 PropertyListTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005044 llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
5045 llvm::ArrayType::get(PropertyTy, 0), NULL);
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005046 // struct _prop_list_t *
Owen Anderson96e0fc72009-07-29 22:16:19 +00005047 PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005048
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005049 // struct _objc_method {
5050 // SEL _cmd;
5051 // char *method_type;
5052 // char *_imp;
5053 // }
Chris Lattnerc1c20112011-08-12 17:43:31 +00005054 MethodTy = llvm::StructType::create("struct._objc_method",
5055 SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5056 NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005057
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005058 // struct _objc_cache *
Chris Lattnerc1c20112011-08-12 17:43:31 +00005059 CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
Owen Anderson96e0fc72009-07-29 22:16:19 +00005060 CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
Fariborz Jahanian9d96bce2011-06-22 20:21:51 +00005061
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005062}
Daniel Dunbar4e2d7d02008-08-12 06:48:42 +00005063
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005064ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
Mike Stump1eb44332009-09-09 15:08:12 +00005065 : ObjCCommonTypesHelper(cgm) {
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005066 // struct _objc_method_description {
5067 // SEL name;
5068 // char *types;
5069 // }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005070 MethodDescriptionTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005071 llvm::StructType::create("struct._objc_method_description",
5072 SelectorPtrTy, Int8PtrTy, NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005073
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005074 // struct _objc_method_description_list {
5075 // int count;
5076 // struct _objc_method_description[1];
5077 // }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005078 MethodDescriptionListTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005079 llvm::StructType::create("struct._objc_method_description_list",
5080 IntTy,
5081 llvm::ArrayType::get(MethodDescriptionTy, 0),NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005082
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005083 // struct _objc_method_description_list *
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005084 MethodDescriptionListPtrTy =
Owen Anderson96e0fc72009-07-29 22:16:19 +00005085 llvm::PointerType::getUnqual(MethodDescriptionListTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005086
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005087 // Protocol description structures
5088
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005089 // struct _objc_protocol_extension {
5090 // uint32_t size; // sizeof(struct _objc_protocol_extension)
5091 // struct _objc_method_description_list *optional_instance_methods;
5092 // struct _objc_method_description_list *optional_class_methods;
5093 // struct _objc_property_list *instance_properties;
Bob Wilsondc8dab62011-11-30 01:57:58 +00005094 // const char ** extendedMethodTypes;
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005095 // }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005096 ProtocolExtensionTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005097 llvm::StructType::create("struct._objc_protocol_extension",
5098 IntTy, MethodDescriptionListPtrTy,
5099 MethodDescriptionListPtrTy, PropertyListPtrTy,
Bob Wilsondc8dab62011-11-30 01:57:58 +00005100 Int8PtrPtrTy, NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005101
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005102 // struct _objc_protocol_extension *
Owen Anderson96e0fc72009-07-29 22:16:19 +00005103 ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005104
Daniel Dunbar0c0e7a62008-10-29 22:36:39 +00005105 // Handle recursive construction of Protocol and ProtocolList types
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005106
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005107 ProtocolTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005108 llvm::StructType::create(VMContext, "struct._objc_protocol");
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005109
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005110 ProtocolListTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005111 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005112 ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005113 LongTy,
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005114 llvm::ArrayType::get(ProtocolTy, 0),
Fariborz Jahanianee0af742009-01-21 22:04:16 +00005115 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005116
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005117 // struct _objc_protocol {
5118 // struct _objc_protocol_extension *isa;
5119 // char *protocol_name;
5120 // struct _objc_protocol **_objc_protocol_list;
5121 // struct _objc_method_description_list *instance_methods;
5122 // struct _objc_method_description_list *class_methods;
5123 // }
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005124 ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5125 llvm::PointerType::getUnqual(ProtocolListTy),
5126 MethodDescriptionListPtrTy,
5127 MethodDescriptionListPtrTy,
5128 NULL);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005129
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005130 // struct _objc_protocol_list *
Owen Anderson96e0fc72009-07-29 22:16:19 +00005131 ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00005132
Owen Anderson96e0fc72009-07-29 22:16:19 +00005133 ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005134
5135 // Class description structures
5136
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005137 // struct _objc_ivar {
5138 // char *ivar_name;
5139 // char *ivar_type;
5140 // int ivar_offset;
5141 // }
Chris Lattnerc1c20112011-08-12 17:43:31 +00005142 IvarTy = llvm::StructType::create("struct._objc_ivar",
5143 Int8PtrTy, Int8PtrTy, IntTy, NULL);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005144
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005145 // struct _objc_ivar_list *
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005146 IvarListTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005147 llvm::StructType::create(VMContext, "struct._objc_ivar_list");
Owen Anderson96e0fc72009-07-29 22:16:19 +00005148 IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005149
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005150 // struct _objc_method_list *
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005151 MethodListTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005152 llvm::StructType::create(VMContext, "struct._objc_method_list");
Owen Anderson96e0fc72009-07-29 22:16:19 +00005153 MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005154
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005155 // struct _objc_class_extension *
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005156 ClassExtensionTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005157 llvm::StructType::create("struct._objc_class_extension",
5158 IntTy, Int8PtrTy, PropertyListPtrTy, NULL);
Owen Anderson96e0fc72009-07-29 22:16:19 +00005159 ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005160
Chris Lattnerc1c20112011-08-12 17:43:31 +00005161 ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005162
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005163 // struct _objc_class {
5164 // Class isa;
5165 // Class super_class;
5166 // char *name;
5167 // long version;
5168 // long info;
5169 // long instance_size;
5170 // struct _objc_ivar_list *ivars;
5171 // struct _objc_method_list *methods;
5172 // struct _objc_cache *cache;
5173 // struct _objc_protocol_list *protocols;
5174 // char *ivar_layout;
5175 // struct _objc_class_ext *ext;
5176 // };
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005177 ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5178 llvm::PointerType::getUnqual(ClassTy),
5179 Int8PtrTy,
5180 LongTy,
5181 LongTy,
5182 LongTy,
5183 IvarListPtrTy,
5184 MethodListPtrTy,
5185 CachePtrTy,
5186 ProtocolListPtrTy,
5187 Int8PtrTy,
5188 ClassExtensionPtrTy,
5189 NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005190
Owen Anderson96e0fc72009-07-29 22:16:19 +00005191 ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005192
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005193 // struct _objc_category {
5194 // char *category_name;
5195 // char *class_name;
5196 // struct _objc_method_list *instance_method;
5197 // struct _objc_method_list *class_method;
5198 // uint32_t size; // sizeof(struct _objc_category)
5199 // struct _objc_property_list *instance_properties;// category's @property
5200 // }
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005201 CategoryTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005202 llvm::StructType::create("struct._objc_category",
5203 Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5204 MethodListPtrTy, ProtocolListPtrTy,
5205 IntTy, PropertyListPtrTy, NULL);
Daniel Dunbar86e253a2008-08-22 20:34:54 +00005206
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005207 // Global metadata structures
5208
Fariborz Jahanian10a42312009-01-21 00:39:53 +00005209 // struct _objc_symtab {
5210 // long sel_ref_cnt;
5211 // SEL *refs;
5212 // short cls_def_cnt;
5213 // short cat_def_cnt;
5214 // char *defs[cls_def_cnt + cat_def_cnt];
5215 // }
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005216 SymtabTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005217 llvm::StructType::create("struct._objc_symtab",
5218 LongTy, SelectorPtrTy, ShortTy, ShortTy,
5219 llvm::ArrayType::get(Int8PtrTy, 0), NULL);
Owen Anderson96e0fc72009-07-29 22:16:19 +00005220 SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
Daniel Dunbar27f9d772008-08-21 04:36:09 +00005221
Fariborz Jahaniandb286862009-01-22 00:37:21 +00005222 // struct _objc_module {
5223 // long version;
5224 // long size; // sizeof(struct _objc_module)
5225 // char *name;
5226 // struct _objc_symtab* symtab;
5227 // }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005228 ModuleTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005229 llvm::StructType::create("struct._objc_module",
5230 LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL);
Daniel Dunbar14c80b72008-08-23 09:25:55 +00005231
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005232
Mike Stumpf5408fe2009-05-16 07:57:57 +00005233 // FIXME: This is the size of the setjmp buffer and should be target
5234 // specific. 18 is what's used on 32-bit X86.
Anders Carlsson124526b2008-09-09 10:10:21 +00005235 uint64_t SetJmpBufferSize = 18;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005236
Anders Carlsson124526b2008-09-09 10:10:21 +00005237 // Exceptions
Chris Lattner8b418682012-02-07 00:39:47 +00005238 llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005239
5240 ExceptionDataTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005241 llvm::StructType::create("struct._objc_exception_data",
Chris Lattner8b418682012-02-07 00:39:47 +00005242 llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5243 StackPtrTy, NULL);
Anders Carlsson124526b2008-09-09 10:10:21 +00005244
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00005245}
5246
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005247ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
Mike Stump1eb44332009-09-09 15:08:12 +00005248 : ObjCCommonTypesHelper(cgm) {
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005249 // struct _method_list_t {
5250 // uint32_t entsize; // sizeof(struct _objc_method)
5251 // uint32_t method_count;
5252 // struct _objc_method method_list[method_count];
5253 // }
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005254 MethodListnfABITy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005255 llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
5256 llvm::ArrayType::get(MethodTy, 0), NULL);
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005257 // struct method_list_t *
Owen Anderson96e0fc72009-07-29 22:16:19 +00005258 MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005259
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005260 // struct _protocol_t {
5261 // id isa; // NULL
5262 // const char * const protocol_name;
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005263 // const struct _protocol_list_t * protocol_list; // super protocols
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005264 // const struct method_list_t * const instance_methods;
5265 // const struct method_list_t * const class_methods;
5266 // const struct method_list_t *optionalInstanceMethods;
5267 // const struct method_list_t *optionalClassMethods;
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005268 // const struct _prop_list_t * properties;
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005269 // const uint32_t size; // sizeof(struct _protocol_t)
5270 // const uint32_t flags; // = 0
Bob Wilsondc8dab62011-11-30 01:57:58 +00005271 // const char ** extendedMethodTypes;
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005272 // }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005273
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005274 // Holder for struct _protocol_list_t *
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005275 ProtocolListnfABITy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005276 llvm::StructType::create(VMContext, "struct._objc_protocol_list");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005277
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005278 ProtocolnfABITy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005279 llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
5280 llvm::PointerType::getUnqual(ProtocolListnfABITy),
5281 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5282 MethodListnfABIPtrTy, MethodListnfABIPtrTy,
Bob Wilsondc8dab62011-11-30 01:57:58 +00005283 PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5284 NULL);
Daniel Dunbar948e2582009-02-15 07:36:20 +00005285
5286 // struct _protocol_t*
Owen Anderson96e0fc72009-07-29 22:16:19 +00005287 ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005288
Fariborz Jahanianda320092009-01-29 19:24:30 +00005289 // struct _protocol_list_t {
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005290 // long protocol_count; // Note, this is 32/64 bit
Daniel Dunbar948e2582009-02-15 07:36:20 +00005291 // struct _protocol_t *[protocol_count];
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005292 // }
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005293 ProtocolListnfABITy->setBody(LongTy,
5294 llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5295 NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005296
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005297 // struct _objc_protocol_list*
Owen Anderson96e0fc72009-07-29 22:16:19 +00005298 ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005299
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005300 // struct _ivar_t {
Stephen Hines651f13c2014-04-23 16:59:28 -07005301 // unsigned [long] int *offset; // pointer to ivar offset location
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005302 // char *name;
5303 // char *type;
5304 // uint32_t alignment;
5305 // uint32_t size;
5306 // }
Stephen Hines651f13c2014-04-23 16:59:28 -07005307 IvarnfABITy = llvm::StructType::create(
5308 "struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5309 Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005310
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005311 // struct _ivar_list_t {
5312 // uint32 entsize; // sizeof(struct _ivar_t)
5313 // uint32 count;
5314 // struct _iver_t list[count];
5315 // }
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005316 IvarListnfABITy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005317 llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
5318 llvm::ArrayType::get(IvarnfABITy, 0), NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005319
Owen Anderson96e0fc72009-07-29 22:16:19 +00005320 IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005321
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005322 // struct _class_ro_t {
Fariborz Jahanian30bc5712009-01-22 23:02:58 +00005323 // uint32_t const flags;
5324 // uint32_t const instanceStart;
5325 // uint32_t const instanceSize;
5326 // uint32_t const reserved; // only when building for 64bit targets
5327 // const uint8_t * const ivarLayout;
5328 // const char *const name;
5329 // const struct _method_list_t * const baseMethods;
5330 // const struct _objc_protocol_list *const baseProtocols;
5331 // const struct _ivar_list_t *const ivars;
5332 // const uint8_t * const weakIvarLayout;
5333 // const struct _prop_list_t * const properties;
5334 // }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005335
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005336 // FIXME. Add 'reserved' field in 64bit abi mode!
Chris Lattnerc1c20112011-08-12 17:43:31 +00005337 ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
5338 IntTy, IntTy, IntTy, Int8PtrTy,
5339 Int8PtrTy, MethodListnfABIPtrTy,
5340 ProtocolListnfABIPtrTy,
5341 IvarListnfABIPtrTy,
5342 Int8PtrTy, PropertyListPtrTy, NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005343
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005344 // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005345 llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
John McCall0774cb82011-05-15 01:53:33 +00005346 ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5347 ->getPointerTo();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005348
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005349 // struct _class_t {
5350 // struct _class_t *isa;
5351 // struct _class_t * const superclass;
5352 // void *cache;
5353 // IMP *vtable;
5354 // struct class_ro_t *ro;
5355 // }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005356
Chris Lattnerc1c20112011-08-12 17:43:31 +00005357 ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005358 ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5359 llvm::PointerType::getUnqual(ClassnfABITy),
5360 CachePtrTy,
5361 llvm::PointerType::getUnqual(ImpnfABITy),
5362 llvm::PointerType::getUnqual(ClassRonfABITy),
5363 NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005364
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005365 // LLVM for struct _class_t *
Owen Anderson96e0fc72009-07-29 22:16:19 +00005366 ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005367
Fariborz Jahaniand55b6fc2009-01-23 01:46:23 +00005368 // struct _category_t {
5369 // const char * const name;
5370 // struct _class_t *const cls;
5371 // const struct _method_list_t * const instance_methods;
5372 // const struct _method_list_t * const class_methods;
5373 // const struct _protocol_list_t * const protocols;
5374 // const struct _prop_list_t * const properties;
Fariborz Jahanian45c2ba02009-01-23 17:41:22 +00005375 // }
Chris Lattnerc1c20112011-08-12 17:43:31 +00005376 CategorynfABITy = llvm::StructType::create("struct._category_t",
5377 Int8PtrTy, ClassnfABIPtrTy,
5378 MethodListnfABIPtrTy,
5379 MethodListnfABIPtrTy,
5380 ProtocolListnfABIPtrTy,
5381 PropertyListPtrTy,
5382 NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005383
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +00005384 // New types for nonfragile abi messaging.
Fariborz Jahanian83a8a752009-02-04 20:42:28 +00005385 CodeGen::CodeGenTypes &Types = CGM.getTypes();
5386 ASTContext &Ctx = CGM.getContext();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005387
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +00005388 // MessageRefTy - LLVM for:
5389 // struct _message_ref_t {
5390 // IMP messenger;
5391 // SEL name;
5392 // };
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005393
Fariborz Jahanian83a8a752009-02-04 20:42:28 +00005394 // First the clang type for struct _message_ref_t
Abramo Bagnara465d41b2010-05-11 21:36:43 +00005395 RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
Daniel Dunbardaa3ac52010-04-29 16:29:11 +00005396 Ctx.getTranslationUnitDecl(),
Abramo Bagnaraba877ad2011-03-09 14:09:51 +00005397 SourceLocation(), SourceLocation(),
Fariborz Jahanian83a8a752009-02-04 20:42:28 +00005398 &Ctx.Idents.get("_message_ref_t"));
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005399 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5400 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
Richard Smithca523302012-06-10 03:12:00 +00005401 ICIS_NoInit));
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005402 RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5403 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5404 false, ICIS_NoInit));
Douglas Gregor838db382010-02-11 01:19:42 +00005405 RD->completeDefinition();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005406
Fariborz Jahanian83a8a752009-02-04 20:42:28 +00005407 MessageRefCTy = Ctx.getTagDeclType(RD);
5408 MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5409 MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005410
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +00005411 // MessageRefPtrTy - LLVM for struct _message_ref_t*
Owen Anderson96e0fc72009-07-29 22:16:19 +00005412 MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005413
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +00005414 // SuperMessageRefTy - LLVM for:
5415 // struct _super_message_ref_t {
5416 // SUPER_IMP messenger;
5417 // SEL name;
5418 // };
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005419 SuperMessageRefTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005420 llvm::StructType::create("struct._super_message_ref_t",
5421 ImpnfABITy, SelectorPtrTy, NULL);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005422
Fariborz Jahanian2e4672b2009-02-03 23:49:23 +00005423 // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005424 SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
Fariborz Jahanian9d96bce2011-06-22 20:21:51 +00005425
Daniel Dunbare588b992009-03-01 04:46:24 +00005426
5427 // struct objc_typeinfo {
5428 // const void** vtable; // objc_ehtype_vtable + 2
5429 // const char* name; // c++ typeinfo string
5430 // Class cls;
5431 // };
Chris Lattner9cbe4f02011-07-09 17:41:47 +00005432 EHTypeTy =
Chris Lattnerc1c20112011-08-12 17:43:31 +00005433 llvm::StructType::create("struct._objc_typeinfo",
5434 llvm::PointerType::getUnqual(Int8PtrTy),
5435 Int8PtrTy, ClassnfABIPtrTy, NULL);
Owen Anderson96e0fc72009-07-29 22:16:19 +00005436 EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00005437}
5438
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005439llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005440 FinishNonFragileABIModule();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005441
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005442 return nullptr;
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005443}
5444
Bill Wendlingbb028552012-02-07 09:25:09 +00005445void CGObjCNonFragileABIMac::
5446AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
5447 const char *SymbolName,
5448 const char *SectionName) {
Daniel Dunbar463b8762009-05-15 21:48:48 +00005449 unsigned NumClasses = Container.size();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005450
Daniel Dunbar463b8762009-05-15 21:48:48 +00005451 if (!NumClasses)
5452 return;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005453
Chris Lattner0b239712012-02-06 22:16:34 +00005454 SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
Daniel Dunbar463b8762009-05-15 21:48:48 +00005455 for (unsigned i=0; i<NumClasses; i++)
Owen Anderson3c4972d2009-07-29 18:54:39 +00005456 Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
Daniel Dunbar463b8762009-05-15 21:48:48 +00005457 ObjCTypes.Int8PtrTy);
Chris Lattner0b239712012-02-06 22:16:34 +00005458 llvm::Constant *Init =
Owen Anderson96e0fc72009-07-29 22:16:19 +00005459 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
Chris Lattner0b239712012-02-06 22:16:34 +00005460 Symbols.size()),
Daniel Dunbar463b8762009-05-15 21:48:48 +00005461 Symbols);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005462
Daniel Dunbar463b8762009-05-15 21:48:48 +00005463 llvm::GlobalVariable *GV =
Owen Anderson1c431b32009-07-08 19:05:04 +00005464 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
Stephen Hines651f13c2014-04-23 16:59:28 -07005465 llvm::GlobalValue::PrivateLinkage,
Daniel Dunbar463b8762009-05-15 21:48:48 +00005466 Init,
Owen Anderson1c431b32009-07-08 19:05:04 +00005467 SymbolName);
Micah Villmow25a6a842012-10-08 16:25:52 +00005468 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
Daniel Dunbar463b8762009-05-15 21:48:48 +00005469 GV->setSection(SectionName);
Stephen Hines651f13c2014-04-23 16:59:28 -07005470 CGM.addCompilerUsedGlobal(GV);
Daniel Dunbar463b8762009-05-15 21:48:48 +00005471}
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005472
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005473void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5474 // nonfragile abi has no module definition.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005475
Daniel Dunbar463b8762009-05-15 21:48:48 +00005476 // Build list of all implemented class addresses in array
Fariborz Jahanianf87a0cc2009-01-30 20:55:31 +00005477 // L_OBJC_LABEL_CLASS_$.
Stephen Hines651f13c2014-04-23 16:59:28 -07005478
5479 for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5480 const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5481 assert(ID);
5482 if (ObjCImplementationDecl *IMP = ID->getImplementation())
5483 // We are implementing a weak imported interface. Give it external linkage
Stephen Hines176edba2014-12-01 14:53:08 -08005484 if (ID->isWeakImported() && !IMP->isWeakImported()) {
Stephen Hines651f13c2014-04-23 16:59:28 -07005485 DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
Stephen Hines176edba2014-12-01 14:53:08 -08005486 DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5487 }
Stephen Hines651f13c2014-04-23 16:59:28 -07005488 }
Stephen Hines176edba2014-12-01 14:53:08 -08005489
5490 AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$",
Daniel Dunbar463b8762009-05-15 21:48:48 +00005491 "__DATA, __objc_classlist, regular, no_dead_strip");
Stephen Hines651f13c2014-04-23 16:59:28 -07005492
Stephen Hines176edba2014-12-01 14:53:08 -08005493 AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$",
Daniel Dunbar74d4b122009-05-15 22:33:15 +00005494 "__DATA, __objc_nlclslist, regular, no_dead_strip");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005495
Fariborz Jahanianf87a0cc2009-01-30 20:55:31 +00005496 // Build list of all implemented category addresses in array
5497 // L_OBJC_LABEL_CATEGORY_$.
Stephen Hines176edba2014-12-01 14:53:08 -08005498 AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$",
Daniel Dunbar463b8762009-05-15 21:48:48 +00005499 "__DATA, __objc_catlist, regular, no_dead_strip");
Stephen Hines176edba2014-12-01 14:53:08 -08005500 AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$",
Daniel Dunbar74d4b122009-05-15 22:33:15 +00005501 "__DATA, __objc_nlcatlist, regular, no_dead_strip");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005502
Daniel Dunbarfce176b2010-04-25 20:39:01 +00005503 EmitImageInfo();
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005504}
5505
John McCall944c8432011-05-14 03:10:52 +00005506/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
5507/// VTableDispatchMethods; false otherwise. What this means is that
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005508/// except for the 19 selectors in the list, we generate 32bit-style
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +00005509/// message dispatch call for all the rest.
John McCall944c8432011-05-14 03:10:52 +00005510bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5511 // At various points we've experimented with using vtable-based
5512 // dispatch for all methods.
Daniel Dunbarf643b9b2010-04-24 17:56:46 +00005513 switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
Daniel Dunbarf643b9b2010-04-24 17:56:46 +00005514 case CodeGenOptions::Legacy:
Fariborz Jahanian776dbf92010-04-19 17:53:30 +00005515 return false;
John McCall944c8432011-05-14 03:10:52 +00005516 case CodeGenOptions::NonLegacy:
5517 return true;
Daniel Dunbarf643b9b2010-04-24 17:56:46 +00005518 case CodeGenOptions::Mixed:
5519 break;
5520 }
5521
5522 // If so, see whether this selector is in the white-list of things which must
5523 // use the new dispatch convention. We lazily build a dense set for this.
John McCall944c8432011-05-14 03:10:52 +00005524 if (VTableDispatchMethods.empty()) {
5525 VTableDispatchMethods.insert(GetNullarySelector("alloc"));
5526 VTableDispatchMethods.insert(GetNullarySelector("class"));
5527 VTableDispatchMethods.insert(GetNullarySelector("self"));
5528 VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
5529 VTableDispatchMethods.insert(GetNullarySelector("length"));
5530 VTableDispatchMethods.insert(GetNullarySelector("count"));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005531
John McCall944c8432011-05-14 03:10:52 +00005532 // These are vtable-based if GC is disabled.
5533 // Optimistically use vtable dispatch for hybrid compiles.
David Blaikie4e4d0842012-03-11 07:00:24 +00005534 if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
John McCall944c8432011-05-14 03:10:52 +00005535 VTableDispatchMethods.insert(GetNullarySelector("retain"));
5536 VTableDispatchMethods.insert(GetNullarySelector("release"));
5537 VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
5538 }
5539
5540 VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
5541 VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
5542 VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
5543 VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
5544 VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
5545 VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
5546 VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
5547
5548 // These are vtable-based if GC is enabled.
5549 // Optimistically use vtable dispatch for hybrid compiles.
David Blaikie4e4d0842012-03-11 07:00:24 +00005550 if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
John McCall944c8432011-05-14 03:10:52 +00005551 VTableDispatchMethods.insert(GetNullarySelector("hash"));
5552 VTableDispatchMethods.insert(GetUnarySelector("addObject"));
5553
5554 // "countByEnumeratingWithState:objects:count"
5555 IdentifierInfo *KeyIdents[] = {
5556 &CGM.getContext().Idents.get("countByEnumeratingWithState"),
5557 &CGM.getContext().Idents.get("objects"),
5558 &CGM.getContext().Idents.get("count")
5559 };
5560 VTableDispatchMethods.insert(
5561 CGM.getContext().Selectors.getSelector(3, KeyIdents));
5562 }
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +00005563 }
Daniel Dunbarf643b9b2010-04-24 17:56:46 +00005564
John McCall944c8432011-05-14 03:10:52 +00005565 return VTableDispatchMethods.count(Sel);
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +00005566}
5567
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005568/// BuildClassRoTInitializer - generate meta-data for:
5569/// struct _class_ro_t {
5570/// uint32_t const flags;
5571/// uint32_t const instanceStart;
5572/// uint32_t const instanceSize;
5573/// uint32_t const reserved; // only when building for 64bit targets
5574/// const uint8_t * const ivarLayout;
5575/// const char *const name;
5576/// const struct _method_list_t * const baseMethods;
Fariborz Jahanianda320092009-01-29 19:24:30 +00005577/// const struct _protocol_list_t *const baseProtocols;
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005578/// const struct _ivar_list_t *const ivars;
5579/// const uint8_t * const weakIvarLayout;
5580/// const struct _prop_list_t * const properties;
5581/// }
5582///
5583llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005584 unsigned flags,
5585 unsigned InstanceStart,
5586 unsigned InstanceSize,
5587 const ObjCImplementationDecl *ID) {
Stephen Hines176edba2014-12-01 14:53:08 -08005588 std::string ClassName = ID->getObjCRuntimeNameAsString();
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00005589 llvm::Constant *Values[10]; // 11 for 64bit targets!
John McCallf85e1932011-06-15 23:02:42 +00005590
David Blaikie4e4d0842012-03-11 07:00:24 +00005591 if (CGM.getLangOpts().ObjCAutoRefCount)
John McCall621915c2012-10-17 04:53:23 +00005592 flags |= NonFragileABI_Class_CompiledByARC;
John McCallf85e1932011-06-15 23:02:42 +00005593
Owen Anderson4a28d5d2009-07-24 23:12:58 +00005594 Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5595 Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5596 Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005597 // FIXME. For 64bit targets add 0 here.
John McCall621915c2012-10-17 04:53:23 +00005598 Values[ 3] = (flags & NonFragileABI_Class_Meta)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005599 ? GetIvarLayoutName(nullptr, ObjCTypes)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005600 : BuildIvarLayout(ID, true);
Stephen Hines176edba2014-12-01 14:53:08 -08005601 Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005602 // const struct _method_list_t * const baseMethods;
5603 std::vector<llvm::Constant*> Methods;
5604 std::string MethodListName("\01l_OBJC_$_");
John McCall621915c2012-10-17 04:53:23 +00005605 if (flags & NonFragileABI_Class_Meta) {
Stephen Hines176edba2014-12-01 14:53:08 -08005606 MethodListName += "CLASS_METHODS_";
5607 MethodListName += ID->getObjCRuntimeNameAsString();
Stephen Hines651f13c2014-04-23 16:59:28 -07005608 for (const auto *I : ID->class_methods())
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005609 // Class methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07005610 Methods.push_back(GetMethodConstant(I));
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005611 } else {
Stephen Hines176edba2014-12-01 14:53:08 -08005612 MethodListName += "INSTANCE_METHODS_";
5613 MethodListName += ID->getObjCRuntimeNameAsString();
Stephen Hines651f13c2014-04-23 16:59:28 -07005614 for (const auto *I : ID->instance_methods())
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005615 // Instance methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07005616 Methods.push_back(GetMethodConstant(I));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005617
Stephen Hines651f13c2014-04-23 16:59:28 -07005618 for (const auto *PID : ID->property_impls()) {
Fariborz Jahanian939abce2009-01-28 22:46:49 +00005619 if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5620 ObjCPropertyDecl *PD = PID->getPropertyDecl();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005621
Fariborz Jahanian939abce2009-01-28 22:46:49 +00005622 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5623 if (llvm::Constant *C = GetMethodConstant(MD))
5624 Methods.push_back(C);
5625 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5626 if (llvm::Constant *C = GetMethodConstant(MD))
5627 Methods.push_back(C);
5628 }
5629 }
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005630 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005631 Values[ 5] = EmitMethodList(MethodListName,
5632 "__DATA, __objc_const", Methods);
5633
Fariborz Jahanianda320092009-01-29 19:24:30 +00005634 const ObjCInterfaceDecl *OID = ID->getClassInterface();
5635 assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005636 Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
Stephen Hines176edba2014-12-01 14:53:08 -08005637 + OID->getObjCRuntimeNameAsString(),
Ted Kremenek53b94412010-09-01 01:21:15 +00005638 OID->all_referenced_protocol_begin(),
5639 OID->all_referenced_protocol_end());
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005640
John McCall621915c2012-10-17 04:53:23 +00005641 if (flags & NonFragileABI_Class_Meta) {
Owen Andersonc9c88b42009-07-31 20:28:54 +00005642 Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005643 Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes);
Owen Andersonc9c88b42009-07-31 20:28:54 +00005644 Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
John McCall621915c2012-10-17 04:53:23 +00005645 } else {
5646 Values[ 7] = EmitIvarList(ID);
5647 Values[ 8] = BuildIvarLayout(ID, false);
Stephen Hines176edba2014-12-01 14:53:08 -08005648 Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00005649 ID, ID->getClassInterface(), ObjCTypes);
John McCall621915c2012-10-17 04:53:23 +00005650 }
Owen Anderson08e25242009-07-27 22:29:56 +00005651 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005652 Values);
5653 llvm::GlobalVariable *CLASS_RO_GV =
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005654 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
Stephen Hines651f13c2014-04-23 16:59:28 -07005655 llvm::GlobalValue::PrivateLinkage,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005656 Init,
John McCall621915c2012-10-17 04:53:23 +00005657 (flags & NonFragileABI_Class_Meta) ?
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005658 std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
5659 std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
Fariborz Jahanian09796d62009-01-31 02:43:27 +00005660 CLASS_RO_GV->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00005661 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
Fariborz Jahanian1bf0afb2009-01-28 01:05:23 +00005662 CLASS_RO_GV->setSection("__DATA, __objc_const");
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005663 return CLASS_RO_GV;
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005664
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005665}
5666
5667/// BuildClassMetaData - This routine defines that to-level meta-data
5668/// for the given ClassName for:
5669/// struct _class_t {
5670/// struct _class_t *isa;
5671/// struct _class_t * const superclass;
5672/// void *cache;
5673/// IMP *vtable;
5674/// struct class_ro_t *ro;
5675/// }
5676///
Stephen Hines651f13c2014-04-23 16:59:28 -07005677llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
Stephen Hines176edba2014-12-01 14:53:08 -08005678 const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
Stephen Hines651f13c2014-04-23 16:59:28 -07005679 llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00005680 llvm::Constant *Values[] = {
5681 IsAGV,
5682 SuperClassGV,
5683 ObjCEmptyCacheVar, // &ObjCEmptyCacheVar
5684 ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5685 ClassRoGV // &CLASS_RO_GV
5686 };
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005687 if (!Values[1])
5688 Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
Fariborz Jahanian3da9a8f2013-10-24 17:40:28 +00005689 if (!Values[3])
5690 Values[3] = llvm::Constant::getNullValue(
5691 llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005692 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005693 Values);
Stephen Hines651f13c2014-04-23 16:59:28 -07005694 llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
Daniel Dunbar5a7379a2009-03-01 04:40:10 +00005695 GV->setInitializer(Init);
Fariborz Jahaniandd0db2a2009-01-31 01:07:39 +00005696 GV->setSection("__DATA, __objc_data");
Fariborz Jahanian09796d62009-01-31 02:43:27 +00005697 GV->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00005698 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
Fariborz Jahaniancf555162009-01-31 00:59:10 +00005699 if (HiddenVisibility)
5700 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
Fariborz Jahanian84394a52009-01-24 21:21:53 +00005701 return GV;
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005702}
5703
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005704bool
Fariborz Jahanianecfbdcb2009-05-21 01:03:45 +00005705CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005706 return OD->getClassMethod(GetNullarySelector("load")) != nullptr;
Daniel Dunbar74d4b122009-05-15 22:33:15 +00005707}
5708
Daniel Dunbar9f89f2b2009-05-03 12:57:56 +00005709void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
Daniel Dunbarb02532a2009-04-19 23:41:48 +00005710 uint32_t &InstanceStart,
5711 uint32_t &InstanceSize) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005712 const ASTRecordLayout &RL =
Daniel Dunbarb4c79e02009-05-04 21:26:30 +00005713 CGM.getContext().getASTObjCImplementationLayout(OID);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005714
Daniel Dunbar6e8575b2009-05-04 23:23:09 +00005715 // InstanceSize is really instance end.
Ken Dyckec299032011-02-11 02:20:09 +00005716 InstanceSize = RL.getDataSize().getQuantity();
Daniel Dunbar6e8575b2009-05-04 23:23:09 +00005717
5718 // If there are no fields, the start is the same as the end.
5719 if (!RL.getFieldCount())
5720 InstanceStart = InstanceSize;
5721 else
Ken Dyckfb67ccd2011-04-14 00:43:09 +00005722 InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
Daniel Dunbarb02532a2009-04-19 23:41:48 +00005723}
5724
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005725void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
Stephen Hines176edba2014-12-01 14:53:08 -08005726 std::string ClassName = ID->getObjCRuntimeNameAsString();
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005727 if (!ObjCEmptyCacheVar) {
5728 ObjCEmptyCacheVar = new llvm::GlobalVariable(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005729 CGM.getModule(),
5730 ObjCTypes.CacheTy,
5731 false,
5732 llvm::GlobalValue::ExternalLinkage,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005733 nullptr,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005734 "_objc_empty_cache");
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005735
Fariborz Jahanian3da9a8f2013-10-24 17:40:28 +00005736 // Make this entry NULL for any iOS device target, any iOS simulator target,
5737 // OS X with deployment target 10.9 or later.
5738 const llvm::Triple &Triple = CGM.getTarget().getTriple();
5739 if (Triple.isiOS() || (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9)))
5740 // This entry will be null.
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005741 ObjCEmptyVtableVar = nullptr;
Fariborz Jahanian3da9a8f2013-10-24 17:40:28 +00005742 else
5743 ObjCEmptyVtableVar = new llvm::GlobalVariable(
5744 CGM.getModule(),
5745 ObjCTypes.ImpnfABITy,
5746 false,
5747 llvm::GlobalValue::ExternalLinkage,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005748 nullptr,
Fariborz Jahanian3da9a8f2013-10-24 17:40:28 +00005749 "_objc_empty_vtable");
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005750 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005751 assert(ID->getClassInterface() &&
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005752 "CGObjCNonFragileABIMac::GenerateClass - class is 0");
Daniel Dunbar6c1aac82009-04-20 20:18:54 +00005753 // FIXME: Is this correct (that meta class size is never computed)?
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005754 uint32_t InstanceStart =
Micah Villmow25a6a842012-10-08 16:25:52 +00005755 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005756 uint32_t InstanceSize = InstanceStart;
John McCall621915c2012-10-17 04:53:23 +00005757 uint32_t flags = NonFragileABI_Class_Meta;
Stephen Hines176edba2014-12-01 14:53:08 -08005758 llvm::SmallString<64> ObjCMetaClassName(getMetaclassSymbolPrefix());
5759 llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix());
5760 llvm::SmallString<64> TClassName;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005761
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005762 llvm::GlobalVariable *SuperClassGV, *IsAGV;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005763
John McCallb03527a2012-10-17 04:53:31 +00005764 // Build the flags for the metaclass.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005765 bool classIsHidden =
John McCall1fb0caa2010-10-22 21:05:15 +00005766 ID->getClassInterface()->getVisibility() == HiddenVisibility;
Fariborz Jahaniancf555162009-01-31 00:59:10 +00005767 if (classIsHidden)
John McCall621915c2012-10-17 04:53:23 +00005768 flags |= NonFragileABI_Class_Hidden;
John McCallb03527a2012-10-17 04:53:31 +00005769
5770 // FIXME: why is this flag set on the metaclass?
5771 // ObjC metaclasses have no fields and don't really get constructed.
5772 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
John McCall621915c2012-10-17 04:53:23 +00005773 flags |= NonFragileABI_Class_HasCXXStructors;
John McCallb03527a2012-10-17 04:53:31 +00005774 if (!ID->hasNonZeroConstructors())
5775 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5776 }
5777
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005778 if (!ID->getClassInterface()->getSuperClass()) {
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005779 // class is root
John McCall621915c2012-10-17 04:53:23 +00005780 flags |= NonFragileABI_Class_Root;
Stephen Hines176edba2014-12-01 14:53:08 -08005781 TClassName = ObjCClassName;
5782 TClassName += ClassName;
5783 SuperClassGV = GetClassGlobal(TClassName.str(),
Stephen Hines651f13c2014-04-23 16:59:28 -07005784 ID->getClassInterface()->isWeakImported());
Stephen Hines176edba2014-12-01 14:53:08 -08005785 TClassName = ObjCMetaClassName;
5786 TClassName += ClassName;
5787 IsAGV = GetClassGlobal(TClassName.str(),
Stephen Hines651f13c2014-04-23 16:59:28 -07005788 ID->getClassInterface()->isWeakImported());
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005789 } else {
Fariborz Jahanian84394a52009-01-24 21:21:53 +00005790 // Has a root. Current class is not a root.
Fariborz Jahanianfab98c42009-02-26 18:23:47 +00005791 const ObjCInterfaceDecl *Root = ID->getClassInterface();
5792 while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
5793 Root = Super;
Stephen Hines176edba2014-12-01 14:53:08 -08005794 TClassName = ObjCMetaClassName ;
5795 TClassName += Root->getObjCRuntimeNameAsString();
5796 IsAGV = GetClassGlobal(TClassName.str(),
Stephen Hines651f13c2014-04-23 16:59:28 -07005797 Root->isWeakImported());
Stephen Hines176edba2014-12-01 14:53:08 -08005798
Fariborz Jahanianfab98c42009-02-26 18:23:47 +00005799 // work on super class metadata symbol.
Stephen Hines176edba2014-12-01 14:53:08 -08005800 TClassName = ObjCMetaClassName;
5801 TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
Stephen Hines651f13c2014-04-23 16:59:28 -07005802 SuperClassGV = GetClassGlobal(
Stephen Hines176edba2014-12-01 14:53:08 -08005803 TClassName.str(),
5804 ID->getClassInterface()->getSuperClass()->isWeakImported());
Fariborz Jahanian058a1b72009-01-24 20:21:50 +00005805 }
5806 llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5807 InstanceStart,
5808 InstanceSize,ID);
Stephen Hines176edba2014-12-01 14:53:08 -08005809 TClassName = ObjCMetaClassName;
5810 TClassName += ClassName;
Stephen Hines651f13c2014-04-23 16:59:28 -07005811 llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
Stephen Hines176edba2014-12-01 14:53:08 -08005812 TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
5813 ID->getClassInterface()->isWeakImported());
Fariborz Jahaniana03d0dd2009-11-17 21:37:35 +00005814 DefinedMetaClasses.push_back(MetaTClass);
Daniel Dunbar6ab187a2009-04-07 05:48:37 +00005815
Fariborz Jahanian84394a52009-01-24 21:21:53 +00005816 // Metadata for the class
John McCall621915c2012-10-17 04:53:23 +00005817 flags = 0;
Fariborz Jahaniancf555162009-01-31 00:59:10 +00005818 if (classIsHidden)
John McCall621915c2012-10-17 04:53:23 +00005819 flags |= NonFragileABI_Class_Hidden;
John McCallb03527a2012-10-17 04:53:31 +00005820
5821 if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
John McCall621915c2012-10-17 04:53:23 +00005822 flags |= NonFragileABI_Class_HasCXXStructors;
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00005823
John McCallb03527a2012-10-17 04:53:31 +00005824 // Set a flag to enable a runtime optimization when a class has
5825 // fields that require destruction but which don't require
5826 // anything except zero-initialization during construction. This
5827 // is most notably true of __strong and __weak types, but you can
5828 // also imagine there being C++ types with non-trivial default
5829 // constructors that merely set all fields to null.
5830 if (!ID->hasNonZeroConstructors())
5831 flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5832 }
5833
Douglas Gregor68584ed2009-06-18 16:11:24 +00005834 if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
John McCall621915c2012-10-17 04:53:23 +00005835 flags |= NonFragileABI_Class_Exception;
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00005836
Fariborz Jahanian493dab72009-01-26 21:38:32 +00005837 if (!ID->getClassInterface()->getSuperClass()) {
John McCall621915c2012-10-17 04:53:23 +00005838 flags |= NonFragileABI_Class_Root;
Stephen Hines6bcf27b2014-05-29 04:14:42 -07005839 SuperClassGV = nullptr;
Chris Lattnerb7b58b12009-04-19 06:02:28 +00005840 } else {
Fariborz Jahanian84394a52009-01-24 21:21:53 +00005841 // Has a root. Current class is not a root.
Stephen Hines176edba2014-12-01 14:53:08 -08005842 TClassName = ObjCClassName;
5843 TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
Stephen Hines651f13c2014-04-23 16:59:28 -07005844 SuperClassGV = GetClassGlobal(
Stephen Hines176edba2014-12-01 14:53:08 -08005845 TClassName.str(),
5846 ID->getClassInterface()->getSuperClass()->isWeakImported());
Fariborz Jahanian84394a52009-01-24 21:21:53 +00005847 }
Daniel Dunbar9f89f2b2009-05-03 12:57:56 +00005848 GetClassSizeInfo(ID, InstanceStart, InstanceSize);
Fariborz Jahanian84394a52009-01-24 21:21:53 +00005849 CLASS_RO_GV = BuildClassRoTInitializer(flags,
Fariborz Jahanianf6a077e2009-01-24 23:43:01 +00005850 InstanceStart,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005851 InstanceSize,
Fariborz Jahanianf6a077e2009-01-24 23:43:01 +00005852 ID);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005853
Stephen Hines176edba2014-12-01 14:53:08 -08005854 TClassName = ObjCClassName;
5855 TClassName += ClassName;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005856 llvm::GlobalVariable *ClassMD =
Stephen Hines176edba2014-12-01 14:53:08 -08005857 BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
Stephen Hines651f13c2014-04-23 16:59:28 -07005858 classIsHidden,
5859 ID->getClassInterface()->isWeakImported());
Fariborz Jahanianf87a0cc2009-01-30 20:55:31 +00005860 DefinedClasses.push_back(ClassMD);
Stephen Hines651f13c2014-04-23 16:59:28 -07005861 ImplementedClasses.push_back(ID->getClassInterface());
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00005862
Daniel Dunbar74d4b122009-05-15 22:33:15 +00005863 // Determine if this class is also "non-lazy".
5864 if (ImplementationIsNonLazy(ID))
5865 DefinedNonLazyClasses.push_back(ClassMD);
5866
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00005867 // Force the definition of the EHType if necessary.
John McCall621915c2012-10-17 04:53:23 +00005868 if (flags & NonFragileABI_Class_Exception)
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00005869 GetInterfaceEHType(ID->getClassInterface(), true);
Fariborz Jahanian64089ce2011-04-22 22:02:28 +00005870 // Make sure method definition entries are all clear for next implementation.
5871 MethodDefinitions.clear();
Fariborz Jahanianaa23b572009-01-23 23:53:38 +00005872}
5873
Fariborz Jahanian8cfd3972009-01-30 18:58:59 +00005874/// GenerateProtocolRef - This routine is called to generate code for
5875/// a protocol reference expression; as in:
5876/// @code
5877/// @protocol(Proto1);
5878/// @endcode
5879/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
5880/// which will hold address of the protocol meta-data.
5881///
John McCallbd7370a2013-02-28 19:01:20 +00005882llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005883 const ObjCProtocolDecl *PD) {
5884
Fariborz Jahanian960cd062009-04-10 18:47:34 +00005885 // This routine is called for @protocol only. So, we must build definition
5886 // of protocol's meta-data (not a reference to it!)
5887 //
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005888 llvm::Constant *Init =
5889 llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
Douglas Gregor4c86fdb2012-01-17 18:36:30 +00005890 ObjCTypes.getExternalProtocolPtrTy());
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005891
Fariborz Jahanian8cfd3972009-01-30 18:58:59 +00005892 std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
Stephen Hines176edba2014-12-01 14:53:08 -08005893 ProtocolName += PD->getObjCRuntimeNameAsString();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005894
Fariborz Jahanian8cfd3972009-01-30 18:58:59 +00005895 llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
5896 if (PTGV)
John McCallbd7370a2013-02-28 19:01:20 +00005897 return CGF.Builder.CreateLoad(PTGV);
Fariborz Jahanian8cfd3972009-01-30 18:58:59 +00005898 PTGV = new llvm::GlobalVariable(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005899 CGM.getModule(),
5900 Init->getType(), false,
5901 llvm::GlobalValue::WeakAnyLinkage,
5902 Init,
5903 ProtocolName);
Fariborz Jahanian8cfd3972009-01-30 18:58:59 +00005904 PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
5905 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
Stephen Hines651f13c2014-04-23 16:59:28 -07005906 CGM.addCompilerUsedGlobal(PTGV);
John McCallbd7370a2013-02-28 19:01:20 +00005907 return CGF.Builder.CreateLoad(PTGV);
Fariborz Jahanian8cfd3972009-01-30 18:58:59 +00005908}
5909
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00005910/// GenerateCategory - Build metadata for a category implementation.
5911/// struct _category_t {
5912/// const char * const name;
5913/// struct _class_t *const cls;
5914/// const struct _method_list_t * const instance_methods;
5915/// const struct _method_list_t * const class_methods;
5916/// const struct _protocol_list_t * const protocols;
5917/// const struct _prop_list_t * const properties;
5918/// }
5919///
Daniel Dunbar74d4b122009-05-15 22:33:15 +00005920void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00005921 const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005922 const char *Prefix = "\01l_OBJC_$_CATEGORY_";
Stephen Hines176edba2014-12-01 14:53:08 -08005923
5924 llvm::SmallString<64> ExtCatName(Prefix);
5925 ExtCatName += Interface->getObjCRuntimeNameAsString();
5926 ExtCatName += "_$_";
5927 ExtCatName += OCD->getNameAsString();
5928
5929 llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
5930 ExtClassName += Interface->getObjCRuntimeNameAsString();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005931
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00005932 llvm::Constant *Values[6];
Stephen Hines176edba2014-12-01 14:53:08 -08005933 Values[0] = GetClassName(OCD->getIdentifier()->getName());
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00005934 // meta-class entry symbol
Stephen Hines651f13c2014-04-23 16:59:28 -07005935 llvm::GlobalVariable *ClassGV =
Stephen Hines176edba2014-12-01 14:53:08 -08005936 GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
Stephen Hines651f13c2014-04-23 16:59:28 -07005937
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00005938 Values[1] = ClassGV;
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005939 std::vector<llvm::Constant*> Methods;
Stephen Hines176edba2014-12-01 14:53:08 -08005940 llvm::SmallString<64> MethodListName(Prefix);
5941
5942 MethodListName += "INSTANCE_METHODS_";
5943 MethodListName += Interface->getObjCRuntimeNameAsString();
5944 MethodListName += "_$_";
5945 MethodListName += OCD->getName();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005946
Stephen Hines651f13c2014-04-23 16:59:28 -07005947 for (const auto *I : OCD->instance_methods())
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005948 // Instance methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07005949 Methods.push_back(GetMethodConstant(I));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005950
Stephen Hines176edba2014-12-01 14:53:08 -08005951 Values[2] = EmitMethodList(MethodListName.str(),
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005952 "__DATA, __objc_const",
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005953 Methods);
5954
5955 MethodListName = Prefix;
Stephen Hines176edba2014-12-01 14:53:08 -08005956 MethodListName += "CLASS_METHODS_";
5957 MethodListName += Interface->getObjCRuntimeNameAsString();
5958 MethodListName += "_$_";
5959 MethodListName += OCD->getNameAsString();
5960
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005961 Methods.clear();
Stephen Hines651f13c2014-04-23 16:59:28 -07005962 for (const auto *I : OCD->class_methods())
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005963 // Class methods should always be defined.
Stephen Hines651f13c2014-04-23 16:59:28 -07005964 Methods.push_back(GetMethodConstant(I));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005965
Stephen Hines176edba2014-12-01 14:53:08 -08005966 Values[3] = EmitMethodList(MethodListName.str(),
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005967 "__DATA, __objc_const",
Fariborz Jahanianf6317dd2009-01-26 22:58:07 +00005968 Methods);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005969 const ObjCCategoryDecl *Category =
Fariborz Jahanian5de14dc2009-01-28 22:18:42 +00005970 Interface->FindCategoryDeclaration(OCD->getIdentifier());
Fariborz Jahanian943ed6f2009-02-13 17:52:22 +00005971 if (Category) {
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00005972 SmallString<256> ExtName;
Stephen Hines176edba2014-12-01 14:53:08 -08005973 llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00005974 << OCD->getName();
Fariborz Jahanian943ed6f2009-02-13 17:52:22 +00005975 Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
Stephen Hines176edba2014-12-01 14:53:08 -08005976 + Interface->getObjCRuntimeNameAsString() + "_$_"
5977 + Category->getName(),
5978 Category->protocol_begin(),
5979 Category->protocol_end());
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00005980 Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
5981 OCD, Category, ObjCTypes);
Mike Stumpb3589f42009-07-30 22:28:39 +00005982 } else {
Owen Andersonc9c88b42009-07-31 20:28:54 +00005983 Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
5984 Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
Fariborz Jahanian943ed6f2009-02-13 17:52:22 +00005985 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005986
5987 llvm::Constant *Init =
5988 llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00005989 Values);
5990 llvm::GlobalVariable *GCATV
Daniel Dunbar6bff2512009-08-03 17:06:42 +00005991 = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00005992 false,
Stephen Hines651f13c2014-04-23 16:59:28 -07005993 llvm::GlobalValue::PrivateLinkage,
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00005994 Init,
Stephen Hines176edba2014-12-01 14:53:08 -08005995 ExtCatName.str());
Fariborz Jahanian09796d62009-01-31 02:43:27 +00005996 GCATV->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00005997 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
Fariborz Jahanian1bf0afb2009-01-28 01:05:23 +00005998 GCATV->setSection("__DATA, __objc_const");
Stephen Hines651f13c2014-04-23 16:59:28 -07005999 CGM.addCompilerUsedGlobal(GCATV);
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00006000 DefinedCategories.push_back(GCATV);
Daniel Dunbar74d4b122009-05-15 22:33:15 +00006001
6002 // Determine if this category is also "non-lazy".
6003 if (ImplementationIsNonLazy(OCD))
6004 DefinedNonLazyCategories.push_back(GCATV);
Fariborz Jahanian64089ce2011-04-22 22:02:28 +00006005 // method definition entries must be clear for next implementation.
6006 MethodDefinitions.clear();
Fariborz Jahanianeb062d92009-01-26 18:32:24 +00006007}
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006008
6009/// GetMethodConstant - Return a struct objc_method constant for the
6010/// given method if it has been defined. The result is null if the
6011/// method has not been defined. The return value has type MethodPtrTy.
6012llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006013 const ObjCMethodDecl *MD) {
Argyrios Kyrtzidis9d50c062010-08-09 10:54:20 +00006014 llvm::Function *Fn = GetMethodDefinition(MD);
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006015 if (!Fn)
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006016 return nullptr;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006017
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00006018 llvm::Constant *Method[] = {
Owen Anderson3c4972d2009-07-29 18:54:39 +00006019 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00006020 ObjCTypes.SelectorPtrTy),
6021 GetMethodVarType(MD),
6022 llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
6023 };
Owen Anderson08e25242009-07-27 22:29:56 +00006024 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006025}
6026
6027/// EmitMethodList - Build meta-data for method declarations
6028/// struct _method_list_t {
6029/// uint32_t entsize; // sizeof(struct _objc_method)
6030/// uint32_t method_count;
6031/// struct _objc_method method_list[method_count];
6032/// }
6033///
Bill Wendlingbb028552012-02-07 09:25:09 +00006034llvm::Constant *
6035CGObjCNonFragileABIMac::EmitMethodList(Twine Name,
6036 const char *Section,
6037 ArrayRef<llvm::Constant*> Methods) {
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006038 // Return null for empty list.
6039 if (Methods.empty())
Owen Andersonc9c88b42009-07-31 20:28:54 +00006040 return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006041
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006042 llvm::Constant *Values[3];
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006043 // sizeof(struct _objc_method)
Micah Villmow25a6a842012-10-08 16:25:52 +00006044 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
Owen Anderson4a28d5d2009-07-24 23:12:58 +00006045 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006046 // method_count
Owen Anderson4a28d5d2009-07-24 23:12:58 +00006047 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
Owen Anderson96e0fc72009-07-29 22:16:19 +00006048 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006049 Methods.size());
Owen Anderson7db6d832009-07-28 18:33:04 +00006050 Values[2] = llvm::ConstantArray::get(AT, Methods);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006051 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006052
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006053 llvm::GlobalVariable *GV =
Owen Anderson1c431b32009-07-08 19:05:04 +00006054 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
Stephen Hines651f13c2014-04-23 16:59:28 -07006055 llvm::GlobalValue::PrivateLinkage, Init, Name);
Micah Villmow25a6a842012-10-08 16:25:52 +00006056 GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006057 GV->setSection(Section);
Stephen Hines651f13c2014-04-23 16:59:28 -07006058 CGM.addCompilerUsedGlobal(GV);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006059 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
Fariborz Jahanian493dab72009-01-26 21:38:32 +00006060}
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006061
Fariborz Jahanianed157d32009-02-10 20:21:06 +00006062/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6063/// the given ivar.
Daniel Dunbare83be122010-04-02 21:14:02 +00006064llvm::GlobalVariable *
6065CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6066 const ObjCIvarDecl *Ivar) {
Stephen Hines176edba2014-12-01 14:53:08 -08006067
Daniel Dunbare83be122010-04-02 21:14:02 +00006068 const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
Stephen Hines176edba2014-12-01 14:53:08 -08006069 llvm::SmallString<64> Name("OBJC_IVAR_$_");
6070 Name += Container->getObjCRuntimeNameAsString();
6071 Name += ".";
6072 Name += Ivar->getName();
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006073 llvm::GlobalVariable *IvarOffsetGV =
Fariborz Jahanianed157d32009-02-10 20:21:06 +00006074 CGM.getModule().getGlobalVariable(Name);
6075 if (!IvarOffsetGV)
Stephen Hines651f13c2014-04-23 16:59:28 -07006076 IvarOffsetGV = new llvm::GlobalVariable(
Stephen Hines176edba2014-12-01 14:53:08 -08006077 CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
6078 llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
Fariborz Jahanianed157d32009-02-10 20:21:06 +00006079 return IvarOffsetGV;
6080}
6081
Daniel Dunbare83be122010-04-02 21:14:02 +00006082llvm::Constant *
6083CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6084 const ObjCIvarDecl *Ivar,
Eli Friedmane5b46662012-11-06 22:15:52 +00006085 unsigned long int Offset) {
Daniel Dunbar737c5022009-04-19 00:44:02 +00006086 llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
Stephen Hines651f13c2014-04-23 16:59:28 -07006087 IvarOffsetGV->setInitializer(
6088 llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
Fariborz Jahanian09796d62009-01-31 02:43:27 +00006089 IvarOffsetGV->setAlignment(
Stephen Hines651f13c2014-04-23 16:59:28 -07006090 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
Daniel Dunbar737c5022009-04-19 00:44:02 +00006091
Mike Stumpf5408fe2009-05-16 07:57:57 +00006092 // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
6093 // well (i.e., in ObjCIvarOffsetVariable).
Daniel Dunbar737c5022009-04-19 00:44:02 +00006094 if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6095 Ivar->getAccessControl() == ObjCIvarDecl::Package ||
John McCall1fb0caa2010-10-22 21:05:15 +00006096 ID->getVisibility() == HiddenVisibility)
Fariborz Jahanian2fa5a272009-01-28 01:36:42 +00006097 IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
Daniel Dunbar04d40782009-04-14 06:00:08 +00006098 else
Fariborz Jahanian77c9fd22009-04-06 18:30:00 +00006099 IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
Bill Wendling1f382512011-05-04 21:37:25 +00006100 IvarOffsetGV->setSection("__DATA, __objc_ivar");
Fariborz Jahanian45012a72009-02-03 00:09:52 +00006101 return IvarOffsetGV;
Fariborz Jahanian1bf0afb2009-01-28 01:05:23 +00006102}
6103
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006104/// EmitIvarList - Emit the ivar list for the given
Daniel Dunbar11394522009-04-18 08:51:00 +00006105/// implementation. The return value has type
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006106/// IvarListnfABIPtrTy.
6107/// struct _ivar_t {
Stephen Hines651f13c2014-04-23 16:59:28 -07006108/// unsigned [long] int *offset; // pointer to ivar offset location
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006109/// char *name;
6110/// char *type;
6111/// uint32_t alignment;
6112/// uint32_t size;
6113/// }
6114/// struct _ivar_list_t {
6115/// uint32 entsize; // sizeof(struct _ivar_t)
6116/// uint32 count;
6117/// struct _iver_t list[count];
6118/// }
6119///
Daniel Dunbar3e5f0d82009-04-20 06:54:31 +00006120
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006121llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006122 const ObjCImplementationDecl *ID) {
6123
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00006124 std::vector<llvm::Constant*> Ivars;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006125
Jordy Rosedb8264e2011-07-22 02:08:32 +00006126 const ObjCInterfaceDecl *OID = ID->getClassInterface();
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006127 assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006128
Fariborz Jahanian1bf0afb2009-01-28 01:05:23 +00006129 // FIXME. Consolidate this with similar code in GenerateClass.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006130
Jordy Rosedb8264e2011-07-22 02:08:32 +00006131 for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
Fariborz Jahanianbf9eb882011-06-28 18:05:25 +00006132 IVD; IVD = IVD->getNextIvar()) {
Fariborz Jahanian8e6ac1d2009-06-04 01:19:09 +00006133 // Ignore unnamed bit-fields.
6134 if (!IVD->getDeclName())
6135 continue;
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00006136 llvm::Constant *Ivar[5];
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006137 Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
Daniel Dunbar9f89f2b2009-05-03 12:57:56 +00006138 ComputeIvarBaseOffset(CGM, ID, IVD));
Daniel Dunbar3fea0c02009-04-22 08:22:17 +00006139 Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6140 Ivar[2] = GetMethodVarType(IVD);
Chris Lattner2acc6e32011-07-18 04:24:23 +00006141 llvm::Type *FieldTy =
Daniel Dunbar3fea0c02009-04-22 08:22:17 +00006142 CGM.getTypes().ConvertTypeForMem(IVD->getType());
Micah Villmow25a6a842012-10-08 16:25:52 +00006143 unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006144 unsigned Align = CGM.getContext().getPreferredTypeAlign(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006145 IVD->getType().getTypePtr()) >> 3;
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006146 Align = llvm::Log2_32(Align);
Owen Anderson4a28d5d2009-07-24 23:12:58 +00006147 Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
Daniel Dunbar91636d62009-04-20 00:33:43 +00006148 // NOTE. Size of a bitfield does not match gcc's, because of the
6149 // way bitfields are treated special in each. But I am told that
6150 // 'size' for bitfield ivars is ignored by the runtime so it does
6151 // not matter. If it matters, there is enough info to get the
6152 // bitfield right!
Owen Anderson4a28d5d2009-07-24 23:12:58 +00006153 Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Owen Anderson08e25242009-07-27 22:29:56 +00006154 Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006155 }
6156 // Return null for empty list.
6157 if (Ivars.empty())
Owen Andersonc9c88b42009-07-31 20:28:54 +00006158 return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006159
6160 llvm::Constant *Values[3];
Micah Villmow25a6a842012-10-08 16:25:52 +00006161 unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
Owen Anderson4a28d5d2009-07-24 23:12:58 +00006162 Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6163 Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
Owen Anderson96e0fc72009-07-29 22:16:19 +00006164 llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006165 Ivars.size());
Owen Anderson7db6d832009-07-28 18:33:04 +00006166 Values[2] = llvm::ConstantArray::get(AT, Ivars);
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006167 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006168 const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
6169 llvm::GlobalVariable *GV =
Owen Anderson1c431b32009-07-08 19:05:04 +00006170 new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
Stephen Hines651f13c2014-04-23 16:59:28 -07006171 llvm::GlobalValue::PrivateLinkage,
Fariborz Jahanian98abf4b2009-01-27 19:38:51 +00006172 Init,
Stephen Hines176edba2014-12-01 14:53:08 -08006173 Prefix + OID->getObjCRuntimeNameAsString());
Fariborz Jahanian09796d62009-01-31 02:43:27 +00006174 GV->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00006175 CGM.getDataLayout().getABITypeAlignment(Init->getType()));
Fariborz Jahanian1bf0afb2009-01-28 01:05:23 +00006176 GV->setSection("__DATA, __objc_const");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006177
Stephen Hines651f13c2014-04-23 16:59:28 -07006178 CGM.addCompilerUsedGlobal(GV);
Owen Anderson3c4972d2009-07-29 18:54:39 +00006179 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
Fariborz Jahanianda320092009-01-29 19:24:30 +00006180}
6181
6182llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006183 const ObjCProtocolDecl *PD) {
Fariborz Jahanianda320092009-01-29 19:24:30 +00006184 llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006185
Fariborz Jahanianda320092009-01-29 19:24:30 +00006186 if (!Entry) {
6187 // We use the initializer as a marker of whether this is a forward
6188 // reference or not. At module finalization we add the empty
6189 // contents for protocols which were referenced but never defined.
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006190 Entry =
Stephen Hines651f13c2014-04-23 16:59:28 -07006191 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
Stephen Hines176edba2014-12-01 14:53:08 -08006192 false, llvm::GlobalValue::ExternalLinkage,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006193 nullptr,
Stephen Hines176edba2014-12-01 14:53:08 -08006194 "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
Fariborz Jahanianda320092009-01-29 19:24:30 +00006195 Entry->setSection("__DATA,__datacoal_nt,coalesced");
Fariborz Jahanianda320092009-01-29 19:24:30 +00006196 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006197
Fariborz Jahanianda320092009-01-29 19:24:30 +00006198 return Entry;
6199}
6200
6201/// GetOrEmitProtocol - Generate the protocol meta-data:
6202/// @code
6203/// struct _protocol_t {
6204/// id isa; // NULL
6205/// const char * const protocol_name;
6206/// const struct _protocol_list_t * protocol_list; // super protocols
6207/// const struct method_list_t * const instance_methods;
6208/// const struct method_list_t * const class_methods;
6209/// const struct method_list_t *optionalInstanceMethods;
6210/// const struct method_list_t *optionalClassMethods;
6211/// const struct _prop_list_t * properties;
6212/// const uint32_t size; // sizeof(struct _protocol_t)
6213/// const uint32_t flags; // = 0
Bob Wilsondc8dab62011-11-30 01:57:58 +00006214/// const char ** extendedMethodTypes;
Fariborz Jahanianda320092009-01-29 19:24:30 +00006215/// }
6216/// @endcode
6217///
6218
6219llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006220 const ObjCProtocolDecl *PD) {
John McCall50651b92012-03-30 21:29:05 +00006221 llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006222
Fariborz Jahanianda320092009-01-29 19:24:30 +00006223 // Early exit if a defining object has already been generated.
6224 if (Entry && Entry->hasInitializer())
6225 return Entry;
6226
Douglas Gregor1d784b22012-01-01 19:51:50 +00006227 // Use the protocol definition, if there is one.
6228 if (const ObjCProtocolDecl *Def = PD->getDefinition())
6229 PD = Def;
6230
Fariborz Jahanianda320092009-01-29 19:24:30 +00006231 // Construct method lists.
6232 std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6233 std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
Bob Wilsondc8dab62011-11-30 01:57:58 +00006234 std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
Stephen Hines651f13c2014-04-23 16:59:28 -07006235 for (const auto *MD : PD->instance_methods()) {
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00006236 llvm::Constant *C = GetMethodDescriptionConstant(MD);
Douglas Gregorf968d832011-05-27 01:19:52 +00006237 if (!C)
6238 return GetOrEmitProtocolRef(PD);
6239
Fariborz Jahanianda320092009-01-29 19:24:30 +00006240 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6241 OptInstanceMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00006242 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
Fariborz Jahanianda320092009-01-29 19:24:30 +00006243 } else {
6244 InstanceMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00006245 MethodTypesExt.push_back(GetMethodVarType(MD, true));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006246 }
Fariborz Jahanianda320092009-01-29 19:24:30 +00006247 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006248
Stephen Hines651f13c2014-04-23 16:59:28 -07006249 for (const auto *MD : PD->class_methods()) {
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00006250 llvm::Constant *C = GetMethodDescriptionConstant(MD);
Douglas Gregorf968d832011-05-27 01:19:52 +00006251 if (!C)
6252 return GetOrEmitProtocolRef(PD);
6253
Fariborz Jahanianda320092009-01-29 19:24:30 +00006254 if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6255 OptClassMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00006256 OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
Fariborz Jahanianda320092009-01-29 19:24:30 +00006257 } else {
6258 ClassMethods.push_back(C);
Bob Wilsondc8dab62011-11-30 01:57:58 +00006259 MethodTypesExt.push_back(GetMethodVarType(MD, true));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006260 }
Fariborz Jahanianda320092009-01-29 19:24:30 +00006261 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006262
Bob Wilsondc8dab62011-11-30 01:57:58 +00006263 MethodTypesExt.insert(MethodTypesExt.end(),
6264 OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6265
6266 llvm::Constant *Values[11];
Fariborz Jahanianda320092009-01-29 19:24:30 +00006267 // isa is NULL
Owen Andersonc9c88b42009-07-31 20:28:54 +00006268 Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
Stephen Hines176edba2014-12-01 14:53:08 -08006269 Values[1] = GetClassName(PD->getObjCRuntimeNameAsString());
6270 Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getObjCRuntimeNameAsString(),
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00006271 PD->protocol_begin(),
6272 PD->protocol_end());
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006273
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00006274 Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
Stephen Hines176edba2014-12-01 14:53:08 -08006275 + PD->getObjCRuntimeNameAsString(),
Fariborz Jahanianda320092009-01-29 19:24:30 +00006276 "__DATA, __objc_const",
6277 InstanceMethods);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006278 Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
Stephen Hines176edba2014-12-01 14:53:08 -08006279 + PD->getObjCRuntimeNameAsString(),
Fariborz Jahanianda320092009-01-29 19:24:30 +00006280 "__DATA, __objc_const",
6281 ClassMethods);
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00006282 Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
Stephen Hines176edba2014-12-01 14:53:08 -08006283 + PD->getObjCRuntimeNameAsString(),
Fariborz Jahanianda320092009-01-29 19:24:30 +00006284 "__DATA, __objc_const",
6285 OptInstanceMethods);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006286 Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
Stephen Hines176edba2014-12-01 14:53:08 -08006287 + PD->getObjCRuntimeNameAsString(),
Fariborz Jahanianda320092009-01-29 19:24:30 +00006288 "__DATA, __objc_const",
6289 OptClassMethods);
Stephen Hines176edba2014-12-01 14:53:08 -08006290 Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006291 nullptr, PD, ObjCTypes);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006292 uint32_t Size =
Micah Villmow25a6a842012-10-08 16:25:52 +00006293 CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
Owen Anderson4a28d5d2009-07-24 23:12:58 +00006294 Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
Owen Andersonc9c88b42009-07-31 20:28:54 +00006295 Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
Bob Wilsondc8dab62011-11-30 01:57:58 +00006296 Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
Stephen Hines176edba2014-12-01 14:53:08 -08006297 + PD->getObjCRuntimeNameAsString(),
Bob Wilsondc8dab62011-11-30 01:57:58 +00006298 MethodTypesExt, ObjCTypes);
Owen Anderson08e25242009-07-27 22:29:56 +00006299 llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
Fariborz Jahanianda320092009-01-29 19:24:30 +00006300 Values);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006301
Fariborz Jahanianda320092009-01-29 19:24:30 +00006302 if (Entry) {
Stephen Hines176edba2014-12-01 14:53:08 -08006303 // Already created, fix the linkage and update the initializer.
6304 Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
Fariborz Jahanianda320092009-01-29 19:24:30 +00006305 Entry->setInitializer(Init);
6306 } else {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006307 Entry =
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00006308 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6309 false, llvm::GlobalValue::WeakAnyLinkage, Init,
Stephen Hines176edba2014-12-01 14:53:08 -08006310 "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
Fariborz Jahanian09796d62009-01-31 02:43:27 +00006311 Entry->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00006312 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
Fariborz Jahanianda320092009-01-29 19:24:30 +00006313 Entry->setSection("__DATA,__datacoal_nt,coalesced");
John McCall50651b92012-03-30 21:29:05 +00006314
6315 Protocols[PD->getIdentifier()] = Entry;
Fariborz Jahanianda320092009-01-29 19:24:30 +00006316 }
Fariborz Jahanian8448c2c2009-01-29 20:10:59 +00006317 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
Stephen Hines651f13c2014-04-23 16:59:28 -07006318 CGM.addCompilerUsedGlobal(Entry);
Chris Lattnerad64e022009-07-17 23:57:13 +00006319
Fariborz Jahanian8448c2c2009-01-29 20:10:59 +00006320 // Use this protocol meta-data to build protocol list table in section
6321 // __DATA, __objc_protolist
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00006322 llvm::GlobalVariable *PTGV =
6323 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6324 false, llvm::GlobalValue::WeakAnyLinkage, Entry,
Stephen Hines176edba2014-12-01 14:53:08 -08006325 "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
Fariborz Jahanian09796d62009-01-31 02:43:27 +00006326 PTGV->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00006327 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
Daniel Dunbar0bf21992009-04-15 02:56:18 +00006328 PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
Fariborz Jahanian8448c2c2009-01-29 20:10:59 +00006329 PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
Stephen Hines651f13c2014-04-23 16:59:28 -07006330 CGM.addCompilerUsedGlobal(PTGV);
Fariborz Jahanianda320092009-01-29 19:24:30 +00006331 return Entry;
6332}
6333
6334/// EmitProtocolList - Generate protocol list meta-data:
6335/// @code
6336/// struct _protocol_list_t {
6337/// long protocol_count; // Note, this is 32/64 bit
6338/// struct _protocol_t[protocol_count];
6339/// }
6340/// @endcode
6341///
6342llvm::Constant *
Chris Lattner5f9e2722011-07-23 10:55:15 +00006343CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00006344 ObjCProtocolDecl::protocol_iterator begin,
6345 ObjCProtocolDecl::protocol_iterator end) {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006346 SmallVector<llvm::Constant *, 16> ProtocolRefs;
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006347
Fariborz Jahanianda320092009-01-29 19:24:30 +00006348 // Just return null for empty protocol lists
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006349 if (begin == end)
Owen Andersonc9c88b42009-07-31 20:28:54 +00006350 return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006351
Daniel Dunbar948e2582009-02-15 07:36:20 +00006352 // FIXME: We shouldn't need to do this lookup here, should we?
Dylan Noblesmithf7ccbad2012-02-05 02:13:05 +00006353 SmallString<256> TmpName;
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00006354 Name.toVector(TmpName);
6355 llvm::GlobalVariable *GV =
6356 CGM.getModule().getGlobalVariable(TmpName.str(), true);
Fariborz Jahanianda320092009-01-29 19:24:30 +00006357 if (GV)
Daniel Dunbar9c29bf52009-10-18 20:48:59 +00006358 return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006359
Daniel Dunbar948e2582009-02-15 07:36:20 +00006360 for (; begin != end; ++begin)
6361 ProtocolRefs.push_back(GetProtocolRef(*begin)); // Implemented???
6362
Fariborz Jahanianda320092009-01-29 19:24:30 +00006363 // This list is null terminated.
Owen Andersonc9c88b42009-07-31 20:28:54 +00006364 ProtocolRefs.push_back(llvm::Constant::getNullValue(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006365 ObjCTypes.ProtocolnfABIPtrTy));
6366
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006367 llvm::Constant *Values[2];
Owen Andersona1cf15f2009-07-14 23:10:40 +00006368 Values[0] =
Owen Anderson4a28d5d2009-07-24 23:12:58 +00006369 llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006370 Values[1] =
Bill Wendling3964e622012-02-09 22:16:49 +00006371 llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6372 ProtocolRefs.size()),
6373 ProtocolRefs);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006374
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006375 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
Owen Anderson1c431b32009-07-08 19:05:04 +00006376 GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
Stephen Hines651f13c2014-04-23 16:59:28 -07006377 llvm::GlobalValue::PrivateLinkage,
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006378 Init, Name);
Fariborz Jahanianda320092009-01-29 19:24:30 +00006379 GV->setSection("__DATA, __objc_const");
Fariborz Jahanian09796d62009-01-31 02:43:27 +00006380 GV->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00006381 CGM.getDataLayout().getABITypeAlignment(Init->getType()));
Stephen Hines651f13c2014-04-23 16:59:28 -07006382 CGM.addCompilerUsedGlobal(GV);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006383 return llvm::ConstantExpr::getBitCast(GV,
Daniel Dunbar948e2582009-02-15 07:36:20 +00006384 ObjCTypes.ProtocolListnfABIPtrTy);
Fariborz Jahanianda320092009-01-29 19:24:30 +00006385}
6386
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00006387/// GetMethodDescriptionConstant - This routine build following meta-data:
6388/// struct _objc_method {
6389/// SEL _cmd;
6390/// char *method_type;
6391/// char *_imp;
6392/// }
6393
6394llvm::Constant *
6395CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00006396 llvm::Constant *Desc[3];
Owen Andersona1cf15f2009-07-14 23:10:40 +00006397 Desc[0] =
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006398 llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6399 ObjCTypes.SelectorPtrTy);
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00006400 Desc[1] = GetMethodVarType(MD);
Douglas Gregorf968d832011-05-27 01:19:52 +00006401 if (!Desc[1])
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006402 return nullptr;
6403
Fariborz Jahanian8cfd3972009-01-30 18:58:59 +00006404 // Protocol methods have no implementation. So, this entry is always NULL.
Owen Andersonc9c88b42009-07-31 20:28:54 +00006405 Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
Owen Anderson08e25242009-07-27 22:29:56 +00006406 return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
Fariborz Jahanian3819a0b2009-01-30 00:46:37 +00006407}
Fariborz Jahanian45012a72009-02-03 00:09:52 +00006408
6409/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
6410/// This code gen. amounts to generating code for:
6411/// @code
6412/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
6413/// @encode
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006414///
Fariborz Jahanian598d3f62009-02-03 19:03:09 +00006415LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
John McCall506b57e2010-05-17 21:00:27 +00006416 CodeGen::CodeGenFunction &CGF,
6417 QualType ObjectTy,
6418 llvm::Value *BaseValue,
6419 const ObjCIvarDecl *Ivar,
6420 unsigned CVRQualifiers) {
6421 ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
Fariborz Jahaniancd285d02012-02-20 22:42:22 +00006422 llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
Daniel Dunbar97776872009-04-22 07:32:20 +00006423 return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
Fariborz Jahaniancd285d02012-02-20 22:42:22 +00006424 Offset);
Fariborz Jahanian45012a72009-02-03 00:09:52 +00006425}
6426
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00006427llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006428 CodeGen::CodeGenFunction &CGF,
6429 const ObjCInterfaceDecl *Interface,
6430 const ObjCIvarDecl *Ivar) {
Stephen Hines651f13c2014-04-23 16:59:28 -07006431 llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6432 IvarOffsetValue = CGF.Builder.CreateLoad(IvarOffsetValue, "ivar");
6433 if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6434 cast<llvm::LoadInst>(IvarOffsetValue)
6435 ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
Stephen Hines176edba2014-12-01 14:53:08 -08006436 llvm::MDNode::get(VMContext, None));
Stephen Hines651f13c2014-04-23 16:59:28 -07006437
6438 // This could be 32bit int or 64bit integer depending on the architecture.
6439 // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
6440 // as this is what caller always expectes.
6441 if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6442 IvarOffsetValue = CGF.Builder.CreateIntCast(
6443 IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");
6444 return IvarOffsetValue;
Fariborz Jahanianf63aa3f2009-02-10 19:02:04 +00006445}
6446
John McCallb1e81442011-05-13 23:16:18 +00006447static void appendSelectorForMessageRefTable(std::string &buffer,
6448 Selector selector) {
6449 if (selector.isUnarySelector()) {
6450 buffer += selector.getNameForSlot(0);
6451 return;
6452 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006453
John McCallb1e81442011-05-13 23:16:18 +00006454 for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
6455 buffer += selector.getNameForSlot(i);
6456 buffer += '_';
6457 }
6458}
6459
John McCall944c8432011-05-14 03:10:52 +00006460/// Emit a "v-table" message send. We emit a weak hidden-visibility
6461/// struct, initially containing the selector pointer and a pointer to
6462/// a "fixup" variant of the appropriate objc_msgSend. To call, we
6463/// load and call the function pointer, passing the address of the
6464/// struct as the second parameter. The runtime determines whether
6465/// the selector is currently emitted using vtable dispatch; if so, it
6466/// substitutes a stub function which simply tail-calls through the
6467/// appropriate vtable slot, and if not, it substitues a stub function
6468/// which tail-calls objc_msgSend. Both stubs adjust the selector
6469/// argument to correctly point to the selector.
6470RValue
6471CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
6472 ReturnValueSlot returnSlot,
6473 QualType resultType,
6474 Selector selector,
6475 llvm::Value *arg0,
6476 QualType arg0Type,
6477 bool isSuper,
6478 const CallArgList &formalArgs,
6479 const ObjCMethodDecl *method) {
John McCallb1e81442011-05-13 23:16:18 +00006480 // Compute the actual arguments.
6481 CallArgList args;
6482
John McCall944c8432011-05-14 03:10:52 +00006483 // First argument: the receiver / super-call structure.
John McCallb1e81442011-05-13 23:16:18 +00006484 if (!isSuper)
John McCall944c8432011-05-14 03:10:52 +00006485 arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
6486 args.add(RValue::get(arg0), arg0Type);
John McCallb1e81442011-05-13 23:16:18 +00006487
John McCall944c8432011-05-14 03:10:52 +00006488 // Second argument: a pointer to the message ref structure. Leave
6489 // the actual argument value blank for now.
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006490 args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
John McCallb1e81442011-05-13 23:16:18 +00006491
6492 args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6493
John McCallde5d3c72012-02-17 03:33:10 +00006494 MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
John McCallb1e81442011-05-13 23:16:18 +00006495
John McCallcba681a2011-05-14 21:12:11 +00006496 NullReturnState nullReturn;
6497
John McCall944c8432011-05-14 03:10:52 +00006498 // Find the function to call and the mangled name for the message
6499 // ref structure. Using a different mangled name wouldn't actually
6500 // be a problem; it would just be a waste.
6501 //
6502 // The runtime currently never uses vtable dispatch for anything
6503 // except normal, non-super message-sends.
6504 // FIXME: don't use this for that.
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006505 llvm::Constant *fn = nullptr;
John McCallb1e81442011-05-13 23:16:18 +00006506 std::string messageRefName("\01l_");
Stephen Hines651f13c2014-04-23 16:59:28 -07006507 if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
John McCallb1e81442011-05-13 23:16:18 +00006508 if (isSuper) {
6509 fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6510 messageRefName += "objc_msgSendSuper2_stret_fixup";
Chris Lattner9b7d6702010-08-18 16:09:06 +00006511 } else {
John McCallcba681a2011-05-14 21:12:11 +00006512 nullReturn.init(CGF, arg0);
John McCallb1e81442011-05-13 23:16:18 +00006513 fn = ObjCTypes.getMessageSendStretFixupFn();
6514 messageRefName += "objc_msgSend_stret_fixup";
Chris Lattner9b7d6702010-08-18 16:09:06 +00006515 }
John McCallb1e81442011-05-13 23:16:18 +00006516 } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
6517 fn = ObjCTypes.getMessageSendFpretFixupFn();
6518 messageRefName += "objc_msgSend_fpret_fixup";
Mike Stumpb3589f42009-07-30 22:28:39 +00006519 } else {
John McCallb1e81442011-05-13 23:16:18 +00006520 if (isSuper) {
6521 fn = ObjCTypes.getMessageSendSuper2FixupFn();
6522 messageRefName += "objc_msgSendSuper2_fixup";
Chris Lattner9b7d6702010-08-18 16:09:06 +00006523 } else {
John McCallb1e81442011-05-13 23:16:18 +00006524 fn = ObjCTypes.getMessageSendFixupFn();
6525 messageRefName += "objc_msgSend_fixup";
Chris Lattner9b7d6702010-08-18 16:09:06 +00006526 }
Fariborz Jahanian83a8a752009-02-04 20:42:28 +00006527 }
John McCallb1e81442011-05-13 23:16:18 +00006528 assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
6529 messageRefName += '_';
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006530
John McCallb1e81442011-05-13 23:16:18 +00006531 // Append the selector name, except use underscores anywhere we
6532 // would have used colons.
6533 appendSelectorForMessageRefTable(messageRefName, selector);
6534
6535 llvm::GlobalVariable *messageRef
6536 = CGM.getModule().getGlobalVariable(messageRefName);
6537 if (!messageRef) {
John McCall944c8432011-05-14 03:10:52 +00006538 // Build the message ref structure.
John McCallb1e81442011-05-13 23:16:18 +00006539 llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
Chris Lattnerc5cbb902011-06-20 04:01:35 +00006540 llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
John McCallb1e81442011-05-13 23:16:18 +00006541 messageRef = new llvm::GlobalVariable(CGM.getModule(),
6542 init->getType(),
6543 /*constant*/ false,
6544 llvm::GlobalValue::WeakAnyLinkage,
6545 init,
6546 messageRefName);
6547 messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
6548 messageRef->setAlignment(16);
6549 messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
6550 }
Fariborz Jahanian3c52d362012-01-30 23:39:30 +00006551
6552 bool requiresnullCheck = false;
David Blaikie4e4d0842012-03-11 07:00:24 +00006553 if (CGM.getLangOpts().ObjCAutoRefCount && method)
Stephen Hines651f13c2014-04-23 16:59:28 -07006554 for (const auto *ParamDecl : method->params()) {
Fariborz Jahanian3c52d362012-01-30 23:39:30 +00006555 if (ParamDecl->hasAttr<NSConsumedAttr>()) {
6556 if (!nullReturn.NullBB)
6557 nullReturn.init(CGF, arg0);
6558 requiresnullCheck = true;
6559 break;
6560 }
6561 }
6562
John McCallb1e81442011-05-13 23:16:18 +00006563 llvm::Value *mref =
6564 CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
6565
John McCall944c8432011-05-14 03:10:52 +00006566 // Update the message ref argument.
John McCallb1e81442011-05-13 23:16:18 +00006567 args[1].RV = RValue::get(mref);
6568
6569 // Load the function to call from the message ref table.
6570 llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
6571 callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
6572
John McCallde5d3c72012-02-17 03:33:10 +00006573 callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
John McCallb1e81442011-05-13 23:16:18 +00006574
John McCallde5d3c72012-02-17 03:33:10 +00006575 RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006576 return nullReturn.complete(CGF, result, resultType, formalArgs,
6577 requiresnullCheck ? method : nullptr);
Fariborz Jahanian46551122009-02-04 00:22:57 +00006578}
6579
6580/// Generate code for a message send expression in the nonfragile abi.
Daniel Dunbard6c93d72009-09-17 04:01:22 +00006581CodeGen::RValue
6582CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
John McCallef072fd2010-05-22 01:48:05 +00006583 ReturnValueSlot Return,
Daniel Dunbard6c93d72009-09-17 04:01:22 +00006584 QualType ResultType,
6585 Selector Sel,
6586 llvm::Value *Receiver,
Daniel Dunbard6c93d72009-09-17 04:01:22 +00006587 const CallArgList &CallArgs,
David Chisnallc6cd5fd2010-04-28 19:33:36 +00006588 const ObjCInterfaceDecl *Class,
Daniel Dunbard6c93d72009-09-17 04:01:22 +00006589 const ObjCMethodDecl *Method) {
John McCall944c8432011-05-14 03:10:52 +00006590 return isVTableDispatchedSelector(Sel)
6591 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006592 Receiver, CGF.getContext().getObjCIdType(),
John McCall944c8432011-05-14 03:10:52 +00006593 false, CallArgs, Method)
6594 : EmitMessageSend(CGF, Return, ResultType,
John McCallbd7370a2013-02-28 19:01:20 +00006595 EmitSelector(CGF, Sel),
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006596 Receiver, CGF.getContext().getObjCIdType(),
John McCall944c8432011-05-14 03:10:52 +00006597 false, CallArgs, Method, ObjCTypes);
Fariborz Jahanian46551122009-02-04 00:22:57 +00006598}
6599
Daniel Dunbar5a7379a2009-03-01 04:40:10 +00006600llvm::GlobalVariable *
Stephen Hines651f13c2014-04-23 16:59:28 -07006601CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, bool Weak) {
6602 llvm::GlobalValue::LinkageTypes L =
6603 Weak ? llvm::GlobalValue::ExternalWeakLinkage
6604 : llvm::GlobalValue::ExternalLinkage;
6605
Daniel Dunbar5a7379a2009-03-01 04:40:10 +00006606 llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
6607
Stephen Hines651f13c2014-04-23 16:59:28 -07006608 if (!GV)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006609 GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006610 false, L, nullptr, Name);
Daniel Dunbar5a7379a2009-03-01 04:40:10 +00006611
Stephen Hines651f13c2014-04-23 16:59:28 -07006612 assert(GV->getLinkage() == L);
Daniel Dunbar5a7379a2009-03-01 04:40:10 +00006613 return GV;
6614}
6615
John McCallbd7370a2013-02-28 19:01:20 +00006616llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
Stephen Hines651f13c2014-04-23 16:59:28 -07006617 IdentifierInfo *II,
Stephen Hines176edba2014-12-01 14:53:08 -08006618 bool Weak,
6619 const ObjCInterfaceDecl *ID) {
John McCallf85e1932011-06-15 23:02:42 +00006620 llvm::GlobalVariable *&Entry = ClassReferences[II];
6621
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006622 if (!Entry) {
Stephen Hines176edba2014-12-01 14:53:08 -08006623 std::string ClassName(
6624 getClassSymbolPrefix() +
6625 (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str());
Stephen Hines651f13c2014-04-23 16:59:28 -07006626 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
Stephen Hines176edba2014-12-01 14:53:08 -08006627 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6628 false, llvm::GlobalValue::PrivateLinkage,
6629 ClassGV, "OBJC_CLASSLIST_REFERENCES_$_");
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006630 Entry->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00006631 CGM.getDataLayout().getABITypeAlignment(
John McCallf85e1932011-06-15 23:02:42 +00006632 ObjCTypes.ClassnfABIPtrTy));
Daniel Dunbar11394522009-04-18 08:51:00 +00006633 Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
Stephen Hines651f13c2014-04-23 16:59:28 -07006634 CGM.addCompilerUsedGlobal(Entry);
Daniel Dunbar11394522009-04-18 08:51:00 +00006635 }
John McCallbd7370a2013-02-28 19:01:20 +00006636 return CGF.Builder.CreateLoad(Entry);
Daniel Dunbar11394522009-04-18 08:51:00 +00006637}
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006638
John McCallbd7370a2013-02-28 19:01:20 +00006639llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
John McCallf85e1932011-06-15 23:02:42 +00006640 const ObjCInterfaceDecl *ID) {
Stephen Hines176edba2014-12-01 14:53:08 -08006641 return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID);
John McCallf85e1932011-06-15 23:02:42 +00006642}
6643
6644llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
John McCallbd7370a2013-02-28 19:01:20 +00006645 CodeGenFunction &CGF) {
John McCallf85e1932011-06-15 23:02:42 +00006646 IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
Stephen Hines176edba2014-12-01 14:53:08 -08006647 return EmitClassRefFromId(CGF, II, false, 0);
John McCallf85e1932011-06-15 23:02:42 +00006648}
6649
Daniel Dunbar11394522009-04-18 08:51:00 +00006650llvm::Value *
John McCallbd7370a2013-02-28 19:01:20 +00006651CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
Daniel Dunbar11394522009-04-18 08:51:00 +00006652 const ObjCInterfaceDecl *ID) {
6653 llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006654
Daniel Dunbar11394522009-04-18 08:51:00 +00006655 if (!Entry) {
Stephen Hines176edba2014-12-01 14:53:08 -08006656 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6657 ClassName += ID->getObjCRuntimeNameAsString();
6658 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
Stephen Hines651f13c2014-04-23 16:59:28 -07006659 ID->isWeakImported());
Stephen Hines176edba2014-12-01 14:53:08 -08006660 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6661 false, llvm::GlobalValue::PrivateLinkage,
6662 ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
Daniel Dunbar11394522009-04-18 08:51:00 +00006663 Entry->setAlignment(
Micah Villmow25a6a842012-10-08 16:25:52 +00006664 CGM.getDataLayout().getABITypeAlignment(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006665 ObjCTypes.ClassnfABIPtrTy));
Daniel Dunbar11394522009-04-18 08:51:00 +00006666 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
Stephen Hines651f13c2014-04-23 16:59:28 -07006667 CGM.addCompilerUsedGlobal(Entry);
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006668 }
John McCallbd7370a2013-02-28 19:01:20 +00006669 return CGF.Builder.CreateLoad(Entry);
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006670}
6671
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006672/// EmitMetaClassRef - Return a Value * of the address of _class_t
6673/// meta-data
6674///
John McCallbd7370a2013-02-28 19:01:20 +00006675llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
Stephen Hinesc568f1e2014-07-21 00:47:37 -07006676 const ObjCInterfaceDecl *ID,
6677 bool Weak) {
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006678 llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
Stephen Hines651f13c2014-04-23 16:59:28 -07006679 if (!Entry) {
Stephen Hines176edba2014-12-01 14:53:08 -08006680 llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix());
6681 MetaClassName += ID->getObjCRuntimeNameAsString();
Stephen Hinesc568f1e2014-07-21 00:47:37 -07006682 llvm::GlobalVariable *MetaClassGV =
Stephen Hines176edba2014-12-01 14:53:08 -08006683 GetClassGlobal(MetaClassName.str(), Weak);
6684
Stephen Hines651f13c2014-04-23 16:59:28 -07006685 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6686 false, llvm::GlobalValue::PrivateLinkage,
Stephen Hines176edba2014-12-01 14:53:08 -08006687 MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
Stephen Hines651f13c2014-04-23 16:59:28 -07006688 Entry->setAlignment(
6689 CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABIPtrTy));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006690
Stephen Hines651f13c2014-04-23 16:59:28 -07006691 Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6692 CGM.addCompilerUsedGlobal(Entry);
6693 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006694
John McCallbd7370a2013-02-28 19:01:20 +00006695 return CGF.Builder.CreateLoad(Entry);
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006696}
6697
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006698/// GetClass - Return a reference to the class for the given interface
6699/// decl.
John McCallbd7370a2013-02-28 19:01:20 +00006700llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006701 const ObjCInterfaceDecl *ID) {
Douglas Gregor0a0d2b12011-03-23 00:50:03 +00006702 if (ID->isWeakImported()) {
Stephen Hines176edba2014-12-01 14:53:08 -08006703 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6704 ClassName += ID->getObjCRuntimeNameAsString();
6705 llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true);
Stephen Hines651f13c2014-04-23 16:59:28 -07006706 (void)ClassGV;
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006707 assert(ClassGV->hasExternalWeakLinkage());
Fariborz Jahanian269f8bc2009-11-17 22:42:00 +00006708 }
6709
John McCallbd7370a2013-02-28 19:01:20 +00006710 return EmitClassRef(CGF, ID);
Fariborz Jahanian0e81f4b2009-02-05 20:41:40 +00006711}
6712
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006713/// Generates a message send where the super is the receiver. This is
6714/// a message send to self with special delivery semantics indicating
6715/// which class's method should be called.
6716CodeGen::RValue
6717CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
John McCallef072fd2010-05-22 01:48:05 +00006718 ReturnValueSlot Return,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006719 QualType ResultType,
6720 Selector Sel,
6721 const ObjCInterfaceDecl *Class,
6722 bool isCategoryImpl,
6723 llvm::Value *Receiver,
6724 bool IsClassMessage,
Daniel Dunbard6c93d72009-09-17 04:01:22 +00006725 const CodeGen::CallArgList &CallArgs,
6726 const ObjCMethodDecl *Method) {
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006727 // ...
6728 // Create and init a super structure; this is a (receiver, class)
6729 // pair we will pass to objc_msgSendSuper.
6730 llvm::Value *ObjCSuper =
John McCall604da292011-03-04 08:00:29 +00006731 CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006732
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006733 llvm::Value *ReceiverAsObject =
6734 CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
6735 CGF.Builder.CreateStore(ReceiverAsObject,
6736 CGF.Builder.CreateStructGEP(ObjCSuper, 0));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006737
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006738 // If this is a class message the metaclass is passed as the target.
Fariborz Jahanian7ce77922009-02-28 20:07:56 +00006739 llvm::Value *Target;
Fariborz Jahanianb9966bd2012-10-10 23:11:18 +00006740 if (IsClassMessage)
Stephen Hines176edba2014-12-01 14:53:08 -08006741 Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
Fariborz Jahanianb9966bd2012-10-10 23:11:18 +00006742 else
John McCallbd7370a2013-02-28 19:01:20 +00006743 Target = EmitSuperClassRef(CGF, Class);
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006744
Mike Stumpf5408fe2009-05-16 07:57:57 +00006745 // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
6746 // ObjCTypes types.
Chris Lattner2acc6e32011-07-18 04:24:23 +00006747 llvm::Type *ClassTy =
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006748 CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
6749 Target = CGF.Builder.CreateBitCast(Target, ClassTy);
6750 CGF.Builder.CreateStore(Target,
6751 CGF.Builder.CreateStructGEP(ObjCSuper, 1));
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006752
John McCall944c8432011-05-14 03:10:52 +00006753 return (isVTableDispatchedSelector(Sel))
6754 ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006755 ObjCSuper, ObjCTypes.SuperPtrCTy,
John McCall944c8432011-05-14 03:10:52 +00006756 true, CallArgs, Method)
6757 : EmitMessageSend(CGF, Return, ResultType,
John McCallbd7370a2013-02-28 19:01:20 +00006758 EmitSelector(CGF, Sel),
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006759 ObjCSuper, ObjCTypes.SuperPtrCTy,
John McCall944c8432011-05-14 03:10:52 +00006760 true, CallArgs, Method, ObjCTypes);
Fariborz Jahanian7a06aae2009-02-06 20:09:23 +00006761}
Fariborz Jahanian26cc89f2009-02-11 20:51:17 +00006762
John McCallbd7370a2013-02-28 19:01:20 +00006763llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
Fariborz Jahanian03b29602010-06-17 19:56:20 +00006764 Selector Sel, bool lval) {
Fariborz Jahanian26cc89f2009-02-11 20:51:17 +00006765 llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006766
Fariborz Jahanian26cc89f2009-02-11 20:51:17 +00006767 if (!Entry) {
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006768 llvm::Constant *Casted =
6769 llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
6770 ObjCTypes.SelectorPtrTy);
Stephen Hines176edba2014-12-01 14:53:08 -08006771 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy,
6772 false, llvm::GlobalValue::PrivateLinkage,
6773 Casted, "OBJC_SELECTOR_REFERENCES_");
Michael Gottesman8f98bf92013-02-05 23:08:45 +00006774 Entry->setExternallyInitialized(true);
Fariborz Jahaniand0f8a8d2009-05-11 19:25:47 +00006775 Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
Stephen Hines651f13c2014-04-23 16:59:28 -07006776 CGM.addCompilerUsedGlobal(Entry);
Fariborz Jahanian26cc89f2009-02-11 20:51:17 +00006777 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006778
Fariborz Jahanian03b29602010-06-17 19:56:20 +00006779 if (lval)
6780 return Entry;
John McCallbd7370a2013-02-28 19:01:20 +00006781 llvm::LoadInst* LI = CGF.Builder.CreateLoad(Entry);
Pete Cooperb6d71142011-11-10 21:45:06 +00006782
6783 LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
Stephen Hines176edba2014-12-01 14:53:08 -08006784 llvm::MDNode::get(VMContext, None));
Pete Cooperb6d71142011-11-10 21:45:06 +00006785 return LI;
Fariborz Jahanian26cc89f2009-02-11 20:51:17 +00006786}
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006787/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
Fariborz Jahanian6c7a1f32009-09-24 22:25:38 +00006788/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006789///
6790void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
Mike Stump1eb44332009-09-09 15:08:12 +00006791 llvm::Value *src,
Fariborz Jahanian6c7a1f32009-09-24 22:25:38 +00006792 llvm::Value *dst,
6793 llvm::Value *ivarOffset) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00006794 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006795 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00006796 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006797 assert(Size <= 8 && "does not support size > 8");
6798 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6799 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00006800 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6801 }
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006802 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6803 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00006804 llvm::Value *args[] = { src, dst, ivarOffset };
6805 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006806}
6807
6808/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
6809/// objc_assign_strongCast (id src, id *dst)
6810///
6811void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006812 CodeGen::CodeGenFunction &CGF,
Mike Stump1eb44332009-09-09 15:08:12 +00006813 llvm::Value *src, llvm::Value *dst) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00006814 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006815 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00006816 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006817 assert(Size <= 8 && "does not support size > 8");
6818 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006819 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00006820 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6821 }
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006822 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6823 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00006824 llvm::Value *args[] = { src, dst };
6825 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
6826 args, "weakassign");
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006827}
6828
Fariborz Jahanian082b02e2009-07-08 01:18:33 +00006829void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006830 CodeGen::CodeGenFunction &CGF,
6831 llvm::Value *DestPtr,
6832 llvm::Value *SrcPtr,
Fariborz Jahanian55bcace2010-06-15 22:44:06 +00006833 llvm::Value *Size) {
Fariborz Jahanian082b02e2009-07-08 01:18:33 +00006834 SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
6835 DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00006836 llvm::Value *args[] = { DestPtr, SrcPtr, Size };
6837 CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
Fariborz Jahanian082b02e2009-07-08 01:18:33 +00006838}
6839
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006840/// EmitObjCWeakRead - Code gen for loading value of a __weak
6841/// object: objc_read_weak (id *src)
6842///
6843llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006844 CodeGen::CodeGenFunction &CGF,
Mike Stump1eb44332009-09-09 15:08:12 +00006845 llvm::Value *AddrWeakObj) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00006846 llvm::Type* DestTy =
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006847 cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
6848 AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00006849 llvm::Value *read_weak =
6850 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
6851 AddrWeakObj, "weakread");
Eli Friedman8339b352009-03-07 03:57:15 +00006852 read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006853 return read_weak;
6854}
6855
6856/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
6857/// objc_assign_weak (id src, id *dst)
6858///
6859void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
Mike Stump1eb44332009-09-09 15:08:12 +00006860 llvm::Value *src, llvm::Value *dst) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00006861 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006862 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00006863 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006864 assert(Size <= 8 && "does not support size > 8");
6865 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6866 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00006867 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6868 }
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006869 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6870 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00006871 llvm::Value *args[] = { src, dst };
6872 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
6873 args, "weakassign");
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006874}
6875
6876/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
6877/// objc_assign_global (id src, id *dst)
6878///
6879void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian021a7a62010-07-20 20:30:03 +00006880 llvm::Value *src, llvm::Value *dst,
6881 bool threadlocal) {
Chris Lattner2acc6e32011-07-18 04:24:23 +00006882 llvm::Type * SrcTy = src->getType();
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006883 if (!isa<llvm::PointerType>(SrcTy)) {
Micah Villmow25a6a842012-10-08 16:25:52 +00006884 unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
Fariborz Jahanian0a855d02009-03-23 19:10:40 +00006885 assert(Size <= 8 && "does not support size > 8");
6886 src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6887 : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
Fariborz Jahanian3b8a6522009-03-13 00:42:52 +00006888 src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6889 }
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006890 src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6891 dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00006892 llvm::Value *args[] = { src, dst };
Fariborz Jahanian021a7a62010-07-20 20:30:03 +00006893 if (!threadlocal)
John McCallbd7370a2013-02-28 19:01:20 +00006894 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
6895 args, "globalassign");
Fariborz Jahanian021a7a62010-07-20 20:30:03 +00006896 else
John McCallbd7370a2013-02-28 19:01:20 +00006897 CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
6898 args, "threadlocalassign");
Fariborz Jahanian6948aea2009-02-16 22:52:32 +00006899}
Fariborz Jahanian26cc89f2009-02-11 20:51:17 +00006900
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006901void
John McCallf1549f62010-07-06 01:34:17 +00006902CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6903 const ObjCAtSynchronizedStmt &S) {
David Chisnall05dc91b2011-03-25 17:46:35 +00006904 EmitAtSynchronizedStmt(CGF, S,
6905 cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
6906 cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
John McCallf1549f62010-07-06 01:34:17 +00006907}
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006908
John McCall5a180392010-07-24 00:37:23 +00006909llvm::Constant *
Fariborz Jahaniancf5abc72011-06-23 19:00:08 +00006910CGObjCNonFragileABIMac::GetEHType(QualType T) {
John McCall5a180392010-07-24 00:37:23 +00006911 // There's a particular fixed type info for 'id'.
6912 if (T->isObjCIdType() ||
6913 T->isObjCQualifiedIdType()) {
6914 llvm::Constant *IDEHType =
6915 CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
6916 if (!IDEHType)
6917 IDEHType =
6918 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
6919 false,
6920 llvm::GlobalValue::ExternalLinkage,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006921 nullptr, "OBJC_EHTYPE_id");
John McCall5a180392010-07-24 00:37:23 +00006922 return IDEHType;
6923 }
6924
6925 // All other types should be Objective-C interface pointer types.
6926 const ObjCObjectPointerType *PT =
6927 T->getAs<ObjCObjectPointerType>();
6928 assert(PT && "Invalid @catch type.");
6929 const ObjCInterfaceType *IT = PT->getInterfaceType();
6930 assert(IT && "Invalid @catch type.");
6931 return GetInterfaceEHType(IT->getDecl(), false);
6932}
6933
John McCallf1549f62010-07-06 01:34:17 +00006934void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6935 const ObjCAtTryStmt &S) {
David Chisnall05dc91b2011-03-25 17:46:35 +00006936 EmitTryCatchStmt(CGF, S,
6937 cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
6938 cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
6939 cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
Daniel Dunbar8ecbaf22009-02-24 07:47:38 +00006940}
6941
Anders Carlssonf57c5b22009-02-16 22:59:18 +00006942/// EmitThrowStmt - Generate code for a throw statement.
6943void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
Fariborz Jahanian6a3c70e2013-01-10 19:02:56 +00006944 const ObjCAtThrowStmt &S,
6945 bool ClearInsertionPoint) {
Anders Carlssonf57c5b22009-02-16 22:59:18 +00006946 if (const Expr *ThrowExpr = S.getThrowExpr()) {
John McCall2b014d62011-10-01 10:32:24 +00006947 llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
Benjamin Kramer578faa82011-09-27 21:06:10 +00006948 Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
John McCallbd7370a2013-02-28 19:01:20 +00006949 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
John McCall7ec404c2010-10-16 08:21:07 +00006950 .setDoesNotReturn();
Anders Carlssonf57c5b22009-02-16 22:59:18 +00006951 } else {
John McCallbd7370a2013-02-28 19:01:20 +00006952 CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
John McCall7ec404c2010-10-16 08:21:07 +00006953 .setDoesNotReturn();
Anders Carlssonf57c5b22009-02-16 22:59:18 +00006954 }
6955
John McCall7ec404c2010-10-16 08:21:07 +00006956 CGF.Builder.CreateUnreachable();
Fariborz Jahanian6a3c70e2013-01-10 19:02:56 +00006957 if (ClearInsertionPoint)
6958 CGF.Builder.ClearInsertionPoint();
Anders Carlssonf57c5b22009-02-16 22:59:18 +00006959}
Daniel Dunbare588b992009-03-01 04:46:24 +00006960
John McCall5a180392010-07-24 00:37:23 +00006961llvm::Constant *
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006962CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00006963 bool ForDefinition) {
Daniel Dunbare588b992009-03-01 04:46:24 +00006964 llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
Daniel Dunbare588b992009-03-01 04:46:24 +00006965
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00006966 // If we don't need a definition, return the entry if found or check
6967 // if we use an external reference.
6968 if (!ForDefinition) {
6969 if (Entry)
6970 return Entry;
Daniel Dunbar7e075cb2009-04-07 06:43:45 +00006971
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00006972 // If this type (or a super class) has the __objc_exception__
6973 // attribute, emit an external reference.
Douglas Gregor68584ed2009-06-18 16:11:24 +00006974 if (hasObjCExceptionAttribute(CGM.getContext(), ID))
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006975 return Entry =
Stephen Hines176edba2014-12-01 14:53:08 -08006976 new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
6977 llvm::GlobalValue::ExternalLinkage,
6978 nullptr,
6979 ("OBJC_EHTYPE_$_" +
6980 ID->getObjCRuntimeNameAsString()));
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00006981 }
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006982
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00006983 // Otherwise we need to either make a new entry or fill in the
6984 // initializer.
6985 assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
Stephen Hines176edba2014-12-01 14:53:08 -08006986 llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6987 ClassName += ID->getObjCRuntimeNameAsString();
Daniel Dunbare588b992009-03-01 04:46:24 +00006988 std::string VTableName = "objc_ehtype_vtable";
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006989 llvm::GlobalVariable *VTableGV =
Daniel Dunbare588b992009-03-01 04:46:24 +00006990 CGM.getModule().getGlobalVariable(VTableName);
6991 if (!VTableGV)
Daniel Dunbar6bff2512009-08-03 17:06:42 +00006992 VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
6993 false,
Daniel Dunbare588b992009-03-01 04:46:24 +00006994 llvm::GlobalValue::ExternalLinkage,
Stephen Hines6bcf27b2014-05-29 04:14:42 -07006995 nullptr, VTableName);
Daniel Dunbare588b992009-03-01 04:46:24 +00006996
Chris Lattner8b418682012-02-07 00:39:47 +00006997 llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
Daniel Dunbare588b992009-03-01 04:46:24 +00006998
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00006999 llvm::Constant *Values[] = {
7000 llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
Stephen Hines176edba2014-12-01 14:53:08 -08007001 GetClassName(ID->getObjCRuntimeNameAsString()),
7002 GetClassGlobal(ClassName.str())
Benjamin Kramer1d236ab2011-10-15 12:20:02 +00007003 };
Owen Andersona1cf15f2009-07-14 23:10:40 +00007004 llvm::Constant *Init =
Owen Anderson08e25242009-07-27 22:29:56 +00007005 llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
Daniel Dunbare588b992009-03-01 04:46:24 +00007006
Stephen Hines651f13c2014-04-23 16:59:28 -07007007 llvm::GlobalValue::LinkageTypes L = ForDefinition
7008 ? llvm::GlobalValue::ExternalLinkage
7009 : llvm::GlobalValue::WeakAnyLinkage;
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00007010 if (Entry) {
7011 Entry->setInitializer(Init);
7012 } else {
Stephen Hines176edba2014-12-01 14:53:08 -08007013 llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_");
7014 EHTYPEName += ID->getObjCRuntimeNameAsString();
Owen Anderson1c431b32009-07-08 19:05:04 +00007015 Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
Stephen Hines651f13c2014-04-23 16:59:28 -07007016 L,
Daniel Dunbar6bff2512009-08-03 17:06:42 +00007017 Init,
Stephen Hines176edba2014-12-01 14:53:08 -08007018 EHTYPEName.str());
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00007019 }
Stephen Hines651f13c2014-04-23 16:59:28 -07007020 assert(Entry->getLinkage() == L);
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00007021
John McCall0b5a4832013-02-19 01:57:29 +00007022 if (ID->getVisibility() == HiddenVisibility)
Daniel Dunbar6ab187a2009-04-07 05:48:37 +00007023 Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
Micah Villmow25a6a842012-10-08 16:25:52 +00007024 Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
Daniel Dunbar4b429ae2010-04-25 20:39:32 +00007025 ObjCTypes.EHTypeTy));
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00007026
Stephen Hines651f13c2014-04-23 16:59:28 -07007027 if (ForDefinition)
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00007028 Entry->setSection("__DATA,__objc_const");
Stephen Hines651f13c2014-04-23 16:59:28 -07007029 else
Daniel Dunbar8158a2f2009-04-08 04:21:03 +00007030 Entry->setSection("__DATA,__datacoal_nt,coalesced");
Daniel Dunbare588b992009-03-01 04:46:24 +00007031
7032 return Entry;
7033}
Daniel Dunbar6bff2512009-08-03 17:06:42 +00007034
Daniel Dunbarbbce49b2008-08-12 00:12:39 +00007035/* *** */
7036
Daniel Dunbar6efc0c52008-08-13 03:21:16 +00007037CodeGen::CGObjCRuntime *
7038CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
John McCall260611a2012-06-20 06:18:46 +00007039 switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7040 case ObjCRuntime::FragileMacOSX:
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00007041 return new CGObjCMac(CGM);
John McCall260611a2012-06-20 06:18:46 +00007042
7043 case ObjCRuntime::MacOSX:
7044 case ObjCRuntime::iOS:
7045 return new CGObjCNonFragileABIMac(CGM);
7046
David Chisnall11d3f4c2012-07-03 20:49:52 +00007047 case ObjCRuntime::GNUstep:
7048 case ObjCRuntime::GCC:
John McCallf7226fb2012-07-12 02:07:58 +00007049 case ObjCRuntime::ObjFW:
John McCall260611a2012-06-20 06:18:46 +00007050 llvm_unreachable("these runtimes are not Mac runtimes");
7051 }
7052 llvm_unreachable("bad runtime");
Daniel Dunbarc17a4d32008-08-11 02:45:11 +00007053}