xref: /aosp_15_r20/external/clang/lib/CodeGen/CGObjCMac.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This provides Objective-C code generation targeting the Apple runtime.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li 
14*67e74705SXin Li #include "CGObjCRuntime.h"
15*67e74705SXin Li #include "CGBlocks.h"
16*67e74705SXin Li #include "CGCleanup.h"
17*67e74705SXin Li #include "CGRecordLayout.h"
18*67e74705SXin Li #include "CodeGenFunction.h"
19*67e74705SXin Li #include "CodeGenModule.h"
20*67e74705SXin Li #include "clang/AST/ASTContext.h"
21*67e74705SXin Li #include "clang/AST/Decl.h"
22*67e74705SXin Li #include "clang/AST/DeclObjC.h"
23*67e74705SXin Li #include "clang/AST/RecordLayout.h"
24*67e74705SXin Li #include "clang/AST/StmtObjC.h"
25*67e74705SXin Li #include "clang/Basic/LangOptions.h"
26*67e74705SXin Li #include "clang/CodeGen/CGFunctionInfo.h"
27*67e74705SXin Li #include "clang/Frontend/CodeGenOptions.h"
28*67e74705SXin Li #include "llvm/ADT/DenseSet.h"
29*67e74705SXin Li #include "llvm/ADT/SetVector.h"
30*67e74705SXin Li #include "llvm/ADT/SmallPtrSet.h"
31*67e74705SXin Li #include "llvm/ADT/SmallString.h"
32*67e74705SXin Li #include "llvm/IR/CallSite.h"
33*67e74705SXin Li #include "llvm/IR/DataLayout.h"
34*67e74705SXin Li #include "llvm/IR/InlineAsm.h"
35*67e74705SXin Li #include "llvm/IR/IntrinsicInst.h"
36*67e74705SXin Li #include "llvm/IR/LLVMContext.h"
37*67e74705SXin Li #include "llvm/IR/Module.h"
38*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
39*67e74705SXin Li #include <cstdio>
40*67e74705SXin Li 
41*67e74705SXin Li using namespace clang;
42*67e74705SXin Li using namespace CodeGen;
43*67e74705SXin Li 
44*67e74705SXin Li namespace {
45*67e74705SXin Li 
46*67e74705SXin Li // FIXME: We should find a nicer way to make the labels for metadata, string
47*67e74705SXin Li // concatenation is lame.
48*67e74705SXin Li 
49*67e74705SXin Li class ObjCCommonTypesHelper {
50*67e74705SXin Li protected:
51*67e74705SXin Li   llvm::LLVMContext &VMContext;
52*67e74705SXin Li 
53*67e74705SXin Li private:
54*67e74705SXin Li   // The types of these functions don't really matter because we
55*67e74705SXin Li   // should always bitcast before calling them.
56*67e74705SXin Li 
57*67e74705SXin Li   /// id objc_msgSend (id, SEL, ...)
58*67e74705SXin Li   ///
59*67e74705SXin Li   /// The default messenger, used for sends whose ABI is unchanged from
60*67e74705SXin Li   /// the all-integer/pointer case.
getMessageSendFn() const61*67e74705SXin Li   llvm::Constant *getMessageSendFn() const {
62*67e74705SXin Li     // Add the non-lazy-bind attribute, since objc_msgSend is likely to
63*67e74705SXin Li     // be called a lot.
64*67e74705SXin Li     llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
65*67e74705SXin Li     return
66*67e74705SXin Li       CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
67*67e74705SXin Li                                                         params, true),
68*67e74705SXin Li                                 "objc_msgSend",
69*67e74705SXin Li                                 llvm::AttributeSet::get(CGM.getLLVMContext(),
70*67e74705SXin Li                                               llvm::AttributeSet::FunctionIndex,
71*67e74705SXin Li                                                  llvm::Attribute::NonLazyBind));
72*67e74705SXin Li   }
73*67e74705SXin Li 
74*67e74705SXin Li   /// void objc_msgSend_stret (id, SEL, ...)
75*67e74705SXin Li   ///
76*67e74705SXin Li   /// The messenger used when the return value is an aggregate returned
77*67e74705SXin Li   /// by indirect reference in the first argument, and therefore the
78*67e74705SXin Li   /// self and selector parameters are shifted over by one.
getMessageSendStretFn() const79*67e74705SXin Li   llvm::Constant *getMessageSendStretFn() const {
80*67e74705SXin Li     llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
82*67e74705SXin Li                                                              params, true),
83*67e74705SXin Li                                      "objc_msgSend_stret");
84*67e74705SXin Li 
85*67e74705SXin Li   }
86*67e74705SXin Li 
87*67e74705SXin Li   /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
88*67e74705SXin Li   ///
89*67e74705SXin Li   /// The messenger used when the return value is returned on the x87
90*67e74705SXin Li   /// floating-point stack; without a special entrypoint, the nil case
91*67e74705SXin Li   /// would be unbalanced.
getMessageSendFpretFn() const92*67e74705SXin Li   llvm::Constant *getMessageSendFpretFn() const {
93*67e74705SXin Li     llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
94*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
95*67e74705SXin Li                                                              params, true),
96*67e74705SXin Li                                      "objc_msgSend_fpret");
97*67e74705SXin Li 
98*67e74705SXin Li   }
99*67e74705SXin Li 
100*67e74705SXin Li   /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
101*67e74705SXin Li   ///
102*67e74705SXin Li   /// The messenger used when the return value is returned in two values on the
103*67e74705SXin Li   /// x87 floating point stack; without a special entrypoint, the nil case
104*67e74705SXin Li   /// would be unbalanced. Only used on 64-bit X86.
getMessageSendFp2retFn() const105*67e74705SXin Li   llvm::Constant *getMessageSendFp2retFn() const {
106*67e74705SXin Li     llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
107*67e74705SXin Li     llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
108*67e74705SXin Li     llvm::Type *resultType =
109*67e74705SXin Li       llvm::StructType::get(longDoubleType, longDoubleType, nullptr);
110*67e74705SXin Li 
111*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
112*67e74705SXin Li                                                              params, true),
113*67e74705SXin Li                                      "objc_msgSend_fp2ret");
114*67e74705SXin Li   }
115*67e74705SXin Li 
116*67e74705SXin Li   /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
117*67e74705SXin Li   ///
118*67e74705SXin Li   /// The messenger used for super calls, which have different dispatch
119*67e74705SXin Li   /// semantics.  The class passed is the superclass of the current
120*67e74705SXin Li   /// class.
getMessageSendSuperFn() const121*67e74705SXin Li   llvm::Constant *getMessageSendSuperFn() const {
122*67e74705SXin Li     llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
123*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
124*67e74705SXin Li                                                              params, true),
125*67e74705SXin Li                                      "objc_msgSendSuper");
126*67e74705SXin Li   }
127*67e74705SXin Li 
128*67e74705SXin Li   /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
129*67e74705SXin Li   ///
130*67e74705SXin Li   /// A slightly different messenger used for super calls.  The class
131*67e74705SXin Li   /// passed is the current class.
getMessageSendSuperFn2() const132*67e74705SXin Li   llvm::Constant *getMessageSendSuperFn2() const {
133*67e74705SXin Li     llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
134*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
135*67e74705SXin Li                                                              params, true),
136*67e74705SXin Li                                      "objc_msgSendSuper2");
137*67e74705SXin Li   }
138*67e74705SXin Li 
139*67e74705SXin Li   /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
140*67e74705SXin Li   ///                              SEL op, ...)
141*67e74705SXin Li   ///
142*67e74705SXin Li   /// The messenger used for super calls which return an aggregate indirectly.
getMessageSendSuperStretFn() const143*67e74705SXin Li   llvm::Constant *getMessageSendSuperStretFn() const {
144*67e74705SXin Li     llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
145*67e74705SXin Li     return CGM.CreateRuntimeFunction(
146*67e74705SXin Li       llvm::FunctionType::get(CGM.VoidTy, params, true),
147*67e74705SXin Li       "objc_msgSendSuper_stret");
148*67e74705SXin Li   }
149*67e74705SXin Li 
150*67e74705SXin Li   /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
151*67e74705SXin Li   ///                               SEL op, ...)
152*67e74705SXin Li   ///
153*67e74705SXin Li   /// objc_msgSendSuper_stret with the super2 semantics.
getMessageSendSuperStretFn2() const154*67e74705SXin Li   llvm::Constant *getMessageSendSuperStretFn2() const {
155*67e74705SXin Li     llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
156*67e74705SXin Li     return CGM.CreateRuntimeFunction(
157*67e74705SXin Li       llvm::FunctionType::get(CGM.VoidTy, params, true),
158*67e74705SXin Li       "objc_msgSendSuper2_stret");
159*67e74705SXin Li   }
160*67e74705SXin Li 
getMessageSendSuperFpretFn() const161*67e74705SXin Li   llvm::Constant *getMessageSendSuperFpretFn() const {
162*67e74705SXin Li     // There is no objc_msgSendSuper_fpret? How can that work?
163*67e74705SXin Li     return getMessageSendSuperFn();
164*67e74705SXin Li   }
165*67e74705SXin Li 
getMessageSendSuperFpretFn2() const166*67e74705SXin Li   llvm::Constant *getMessageSendSuperFpretFn2() const {
167*67e74705SXin Li     // There is no objc_msgSendSuper_fpret? How can that work?
168*67e74705SXin Li     return getMessageSendSuperFn2();
169*67e74705SXin Li   }
170*67e74705SXin Li 
171*67e74705SXin Li protected:
172*67e74705SXin Li   CodeGen::CodeGenModule &CGM;
173*67e74705SXin Li 
174*67e74705SXin Li public:
175*67e74705SXin Li   llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
176*67e74705SXin Li   llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
177*67e74705SXin Li   llvm::Type *IvarOffsetVarTy;
178*67e74705SXin Li 
179*67e74705SXin Li   /// ObjectPtrTy - LLVM type for object handles (typeof(id))
180*67e74705SXin Li   llvm::Type *ObjectPtrTy;
181*67e74705SXin Li 
182*67e74705SXin Li   /// PtrObjectPtrTy - LLVM type for id *
183*67e74705SXin Li   llvm::Type *PtrObjectPtrTy;
184*67e74705SXin Li 
185*67e74705SXin Li   /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
186*67e74705SXin Li   llvm::Type *SelectorPtrTy;
187*67e74705SXin Li 
188*67e74705SXin Li private:
189*67e74705SXin Li   /// ProtocolPtrTy - LLVM type for external protocol handles
190*67e74705SXin Li   /// (typeof(Protocol))
191*67e74705SXin Li   llvm::Type *ExternalProtocolPtrTy;
192*67e74705SXin Li 
193*67e74705SXin Li public:
getExternalProtocolPtrTy()194*67e74705SXin Li   llvm::Type *getExternalProtocolPtrTy() {
195*67e74705SXin Li     if (!ExternalProtocolPtrTy) {
196*67e74705SXin Li       // FIXME: It would be nice to unify this with the opaque type, so that the
197*67e74705SXin Li       // IR comes out a bit cleaner.
198*67e74705SXin Li       CodeGen::CodeGenTypes &Types = CGM.getTypes();
199*67e74705SXin Li       ASTContext &Ctx = CGM.getContext();
200*67e74705SXin Li       llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
201*67e74705SXin Li       ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
202*67e74705SXin Li     }
203*67e74705SXin Li 
204*67e74705SXin Li     return ExternalProtocolPtrTy;
205*67e74705SXin Li   }
206*67e74705SXin Li 
207*67e74705SXin Li   // SuperCTy - clang type for struct objc_super.
208*67e74705SXin Li   QualType SuperCTy;
209*67e74705SXin Li   // SuperPtrCTy - clang type for struct objc_super *.
210*67e74705SXin Li   QualType SuperPtrCTy;
211*67e74705SXin Li 
212*67e74705SXin Li   /// SuperTy - LLVM type for struct objc_super.
213*67e74705SXin Li   llvm::StructType *SuperTy;
214*67e74705SXin Li   /// SuperPtrTy - LLVM type for struct objc_super *.
215*67e74705SXin Li   llvm::Type *SuperPtrTy;
216*67e74705SXin Li 
217*67e74705SXin Li   /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
218*67e74705SXin Li   /// in GCC parlance).
219*67e74705SXin Li   llvm::StructType *PropertyTy;
220*67e74705SXin Li 
221*67e74705SXin Li   /// PropertyListTy - LLVM type for struct objc_property_list
222*67e74705SXin Li   /// (_prop_list_t in GCC parlance).
223*67e74705SXin Li   llvm::StructType *PropertyListTy;
224*67e74705SXin Li   /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
225*67e74705SXin Li   llvm::Type *PropertyListPtrTy;
226*67e74705SXin Li 
227*67e74705SXin Li   // MethodTy - LLVM type for struct objc_method.
228*67e74705SXin Li   llvm::StructType *MethodTy;
229*67e74705SXin Li 
230*67e74705SXin Li   /// CacheTy - LLVM type for struct objc_cache.
231*67e74705SXin Li   llvm::Type *CacheTy;
232*67e74705SXin Li   /// CachePtrTy - LLVM type for struct objc_cache *.
233*67e74705SXin Li   llvm::Type *CachePtrTy;
234*67e74705SXin Li 
getGetPropertyFn()235*67e74705SXin Li   llvm::Constant *getGetPropertyFn() {
236*67e74705SXin Li     CodeGen::CodeGenTypes &Types = CGM.getTypes();
237*67e74705SXin Li     ASTContext &Ctx = CGM.getContext();
238*67e74705SXin Li     // id objc_getProperty (id, SEL, ptrdiff_t, bool)
239*67e74705SXin Li     CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
240*67e74705SXin Li     CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
241*67e74705SXin Li     CanQualType Params[] = {
242*67e74705SXin Li         IdType, SelType,
243*67e74705SXin Li         Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), Ctx.BoolTy};
244*67e74705SXin Li     llvm::FunctionType *FTy =
245*67e74705SXin Li         Types.GetFunctionType(
246*67e74705SXin Li           Types.arrangeBuiltinFunctionDeclaration(IdType, Params));
247*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
248*67e74705SXin Li   }
249*67e74705SXin Li 
getSetPropertyFn()250*67e74705SXin Li   llvm::Constant *getSetPropertyFn() {
251*67e74705SXin Li     CodeGen::CodeGenTypes &Types = CGM.getTypes();
252*67e74705SXin Li     ASTContext &Ctx = CGM.getContext();
253*67e74705SXin Li     // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
254*67e74705SXin Li     CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
255*67e74705SXin Li     CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
256*67e74705SXin Li     CanQualType Params[] = {
257*67e74705SXin Li         IdType,
258*67e74705SXin Li         SelType,
259*67e74705SXin Li         Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(),
260*67e74705SXin Li         IdType,
261*67e74705SXin Li         Ctx.BoolTy,
262*67e74705SXin Li         Ctx.BoolTy};
263*67e74705SXin Li     llvm::FunctionType *FTy =
264*67e74705SXin Li         Types.GetFunctionType(
265*67e74705SXin Li           Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
266*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
267*67e74705SXin Li   }
268*67e74705SXin Li 
getOptimizedSetPropertyFn(bool atomic,bool copy)269*67e74705SXin Li   llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
270*67e74705SXin Li     CodeGen::CodeGenTypes &Types = CGM.getTypes();
271*67e74705SXin Li     ASTContext &Ctx = CGM.getContext();
272*67e74705SXin Li     // void objc_setProperty_atomic(id self, SEL _cmd,
273*67e74705SXin Li     //                              id newValue, ptrdiff_t offset);
274*67e74705SXin Li     // void objc_setProperty_nonatomic(id self, SEL _cmd,
275*67e74705SXin Li     //                                 id newValue, ptrdiff_t offset);
276*67e74705SXin Li     // void objc_setProperty_atomic_copy(id self, SEL _cmd,
277*67e74705SXin Li     //                                   id newValue, ptrdiff_t offset);
278*67e74705SXin Li     // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
279*67e74705SXin Li     //                                      id newValue, ptrdiff_t offset);
280*67e74705SXin Li 
281*67e74705SXin Li     SmallVector<CanQualType,4> Params;
282*67e74705SXin Li     CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
283*67e74705SXin Li     CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
284*67e74705SXin Li     Params.push_back(IdType);
285*67e74705SXin Li     Params.push_back(SelType);
286*67e74705SXin Li     Params.push_back(IdType);
287*67e74705SXin Li     Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
288*67e74705SXin Li     llvm::FunctionType *FTy =
289*67e74705SXin Li         Types.GetFunctionType(
290*67e74705SXin Li           Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
291*67e74705SXin Li     const char *name;
292*67e74705SXin Li     if (atomic && copy)
293*67e74705SXin Li       name = "objc_setProperty_atomic_copy";
294*67e74705SXin Li     else if (atomic && !copy)
295*67e74705SXin Li       name = "objc_setProperty_atomic";
296*67e74705SXin Li     else if (!atomic && copy)
297*67e74705SXin Li       name = "objc_setProperty_nonatomic_copy";
298*67e74705SXin Li     else
299*67e74705SXin Li       name = "objc_setProperty_nonatomic";
300*67e74705SXin Li 
301*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, name);
302*67e74705SXin Li   }
303*67e74705SXin Li 
getCopyStructFn()304*67e74705SXin Li   llvm::Constant *getCopyStructFn() {
305*67e74705SXin Li     CodeGen::CodeGenTypes &Types = CGM.getTypes();
306*67e74705SXin Li     ASTContext &Ctx = CGM.getContext();
307*67e74705SXin Li     // void objc_copyStruct (void *, const void *, size_t, bool, bool)
308*67e74705SXin Li     SmallVector<CanQualType,5> Params;
309*67e74705SXin Li     Params.push_back(Ctx.VoidPtrTy);
310*67e74705SXin Li     Params.push_back(Ctx.VoidPtrTy);
311*67e74705SXin Li     Params.push_back(Ctx.LongTy);
312*67e74705SXin Li     Params.push_back(Ctx.BoolTy);
313*67e74705SXin Li     Params.push_back(Ctx.BoolTy);
314*67e74705SXin Li     llvm::FunctionType *FTy =
315*67e74705SXin Li         Types.GetFunctionType(
316*67e74705SXin Li           Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
317*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
318*67e74705SXin Li   }
319*67e74705SXin Li 
320*67e74705SXin Li   /// This routine declares and returns address of:
321*67e74705SXin Li   /// void objc_copyCppObjectAtomic(
322*67e74705SXin Li   ///         void *dest, const void *src,
323*67e74705SXin Li   ///         void (*copyHelper) (void *dest, const void *source));
getCppAtomicObjectFunction()324*67e74705SXin Li   llvm::Constant *getCppAtomicObjectFunction() {
325*67e74705SXin Li     CodeGen::CodeGenTypes &Types = CGM.getTypes();
326*67e74705SXin Li     ASTContext &Ctx = CGM.getContext();
327*67e74705SXin Li     /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
328*67e74705SXin Li     SmallVector<CanQualType,3> Params;
329*67e74705SXin Li     Params.push_back(Ctx.VoidPtrTy);
330*67e74705SXin Li     Params.push_back(Ctx.VoidPtrTy);
331*67e74705SXin Li     Params.push_back(Ctx.VoidPtrTy);
332*67e74705SXin Li     llvm::FunctionType *FTy =
333*67e74705SXin Li         Types.GetFunctionType(
334*67e74705SXin Li           Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
335*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
336*67e74705SXin Li   }
337*67e74705SXin Li 
getEnumerationMutationFn()338*67e74705SXin Li   llvm::Constant *getEnumerationMutationFn() {
339*67e74705SXin Li     CodeGen::CodeGenTypes &Types = CGM.getTypes();
340*67e74705SXin Li     ASTContext &Ctx = CGM.getContext();
341*67e74705SXin Li     // void objc_enumerationMutation (id)
342*67e74705SXin Li     SmallVector<CanQualType,1> Params;
343*67e74705SXin Li     Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
344*67e74705SXin Li     llvm::FunctionType *FTy =
345*67e74705SXin Li         Types.GetFunctionType(
346*67e74705SXin Li           Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
347*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
348*67e74705SXin Li   }
349*67e74705SXin Li 
getLookUpClassFn()350*67e74705SXin Li   llvm::Constant *getLookUpClassFn() {
351*67e74705SXin Li     CodeGen::CodeGenTypes &Types = CGM.getTypes();
352*67e74705SXin Li     ASTContext &Ctx = CGM.getContext();
353*67e74705SXin Li     // Class objc_lookUpClass (const char *)
354*67e74705SXin Li     SmallVector<CanQualType,1> Params;
355*67e74705SXin Li     Params.push_back(
356*67e74705SXin Li       Ctx.getCanonicalType(Ctx.getPointerType(Ctx.CharTy.withConst())));
357*67e74705SXin Li     llvm::FunctionType *FTy =
358*67e74705SXin Li         Types.GetFunctionType(Types.arrangeBuiltinFunctionDeclaration(
359*67e74705SXin Li                                 Ctx.getCanonicalType(Ctx.getObjCClassType()),
360*67e74705SXin Li                                 Params));
361*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_lookUpClass");
362*67e74705SXin Li   }
363*67e74705SXin Li 
364*67e74705SXin Li   /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
getGcReadWeakFn()365*67e74705SXin Li   llvm::Constant *getGcReadWeakFn() {
366*67e74705SXin Li     // id objc_read_weak (id *)
367*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
368*67e74705SXin Li     llvm::FunctionType *FTy =
369*67e74705SXin Li       llvm::FunctionType::get(ObjectPtrTy, args, false);
370*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
371*67e74705SXin Li   }
372*67e74705SXin Li 
373*67e74705SXin Li   /// GcAssignWeakFn -- LLVM objc_assign_weak function.
getGcAssignWeakFn()374*67e74705SXin Li   llvm::Constant *getGcAssignWeakFn() {
375*67e74705SXin Li     // id objc_assign_weak (id, id *)
376*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
377*67e74705SXin Li     llvm::FunctionType *FTy =
378*67e74705SXin Li       llvm::FunctionType::get(ObjectPtrTy, args, false);
379*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
380*67e74705SXin Li   }
381*67e74705SXin Li 
382*67e74705SXin Li   /// GcAssignGlobalFn -- LLVM objc_assign_global function.
getGcAssignGlobalFn()383*67e74705SXin Li   llvm::Constant *getGcAssignGlobalFn() {
384*67e74705SXin Li     // id objc_assign_global(id, id *)
385*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
386*67e74705SXin Li     llvm::FunctionType *FTy =
387*67e74705SXin Li       llvm::FunctionType::get(ObjectPtrTy, args, false);
388*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
389*67e74705SXin Li   }
390*67e74705SXin Li 
391*67e74705SXin Li   /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
getGcAssignThreadLocalFn()392*67e74705SXin Li   llvm::Constant *getGcAssignThreadLocalFn() {
393*67e74705SXin Li     // id objc_assign_threadlocal(id src, id * dest)
394*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
395*67e74705SXin Li     llvm::FunctionType *FTy =
396*67e74705SXin Li       llvm::FunctionType::get(ObjectPtrTy, args, false);
397*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
398*67e74705SXin Li   }
399*67e74705SXin Li 
400*67e74705SXin Li   /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
getGcAssignIvarFn()401*67e74705SXin Li   llvm::Constant *getGcAssignIvarFn() {
402*67e74705SXin Li     // id objc_assign_ivar(id, id *, ptrdiff_t)
403*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
404*67e74705SXin Li                            CGM.PtrDiffTy };
405*67e74705SXin Li     llvm::FunctionType *FTy =
406*67e74705SXin Li       llvm::FunctionType::get(ObjectPtrTy, args, false);
407*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
408*67e74705SXin Li   }
409*67e74705SXin Li 
410*67e74705SXin Li   /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
GcMemmoveCollectableFn()411*67e74705SXin Li   llvm::Constant *GcMemmoveCollectableFn() {
412*67e74705SXin Li     // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
413*67e74705SXin Li     llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
414*67e74705SXin Li     llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
415*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
416*67e74705SXin Li   }
417*67e74705SXin Li 
418*67e74705SXin Li   /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
getGcAssignStrongCastFn()419*67e74705SXin Li   llvm::Constant *getGcAssignStrongCastFn() {
420*67e74705SXin Li     // id objc_assign_strongCast(id, id *)
421*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
422*67e74705SXin Li     llvm::FunctionType *FTy =
423*67e74705SXin Li       llvm::FunctionType::get(ObjectPtrTy, args, false);
424*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
425*67e74705SXin Li   }
426*67e74705SXin Li 
427*67e74705SXin Li   /// ExceptionThrowFn - LLVM objc_exception_throw function.
getExceptionThrowFn()428*67e74705SXin Li   llvm::Constant *getExceptionThrowFn() {
429*67e74705SXin Li     // void objc_exception_throw(id)
430*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy };
431*67e74705SXin Li     llvm::FunctionType *FTy =
432*67e74705SXin Li       llvm::FunctionType::get(CGM.VoidTy, args, false);
433*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
434*67e74705SXin Li   }
435*67e74705SXin Li 
436*67e74705SXin Li   /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
getExceptionRethrowFn()437*67e74705SXin Li   llvm::Constant *getExceptionRethrowFn() {
438*67e74705SXin Li     // void objc_exception_rethrow(void)
439*67e74705SXin Li     llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
440*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
441*67e74705SXin Li   }
442*67e74705SXin Li 
443*67e74705SXin Li   /// SyncEnterFn - LLVM object_sync_enter function.
getSyncEnterFn()444*67e74705SXin Li   llvm::Constant *getSyncEnterFn() {
445*67e74705SXin Li     // int objc_sync_enter (id)
446*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy };
447*67e74705SXin Li     llvm::FunctionType *FTy =
448*67e74705SXin Li       llvm::FunctionType::get(CGM.IntTy, args, false);
449*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
450*67e74705SXin Li   }
451*67e74705SXin Li 
452*67e74705SXin Li   /// SyncExitFn - LLVM object_sync_exit function.
getSyncExitFn()453*67e74705SXin Li   llvm::Constant *getSyncExitFn() {
454*67e74705SXin Li     // int objc_sync_exit (id)
455*67e74705SXin Li     llvm::Type *args[] = { ObjectPtrTy };
456*67e74705SXin Li     llvm::FunctionType *FTy =
457*67e74705SXin Li       llvm::FunctionType::get(CGM.IntTy, args, false);
458*67e74705SXin Li     return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
459*67e74705SXin Li   }
460*67e74705SXin Li 
getSendFn(bool IsSuper) const461*67e74705SXin Li   llvm::Constant *getSendFn(bool IsSuper) const {
462*67e74705SXin Li     return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
463*67e74705SXin Li   }
464*67e74705SXin Li 
getSendFn2(bool IsSuper) const465*67e74705SXin Li   llvm::Constant *getSendFn2(bool IsSuper) const {
466*67e74705SXin Li     return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
467*67e74705SXin Li   }
468*67e74705SXin Li 
getSendStretFn(bool IsSuper) const469*67e74705SXin Li   llvm::Constant *getSendStretFn(bool IsSuper) const {
470*67e74705SXin Li     return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
471*67e74705SXin Li   }
472*67e74705SXin Li 
getSendStretFn2(bool IsSuper) const473*67e74705SXin Li   llvm::Constant *getSendStretFn2(bool IsSuper) const {
474*67e74705SXin Li     return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
475*67e74705SXin Li   }
476*67e74705SXin Li 
getSendFpretFn(bool IsSuper) const477*67e74705SXin Li   llvm::Constant *getSendFpretFn(bool IsSuper) const {
478*67e74705SXin Li     return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
479*67e74705SXin Li   }
480*67e74705SXin Li 
getSendFpretFn2(bool IsSuper) const481*67e74705SXin Li   llvm::Constant *getSendFpretFn2(bool IsSuper) const {
482*67e74705SXin Li     return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
483*67e74705SXin Li   }
484*67e74705SXin Li 
getSendFp2retFn(bool IsSuper) const485*67e74705SXin Li   llvm::Constant *getSendFp2retFn(bool IsSuper) const {
486*67e74705SXin Li     return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
487*67e74705SXin Li   }
488*67e74705SXin Li 
getSendFp2RetFn2(bool IsSuper) const489*67e74705SXin Li   llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
490*67e74705SXin Li     return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
491*67e74705SXin Li   }
492*67e74705SXin Li 
493*67e74705SXin Li   ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
494*67e74705SXin Li };
495*67e74705SXin Li 
496*67e74705SXin Li /// ObjCTypesHelper - Helper class that encapsulates lazy
497*67e74705SXin Li /// construction of varies types used during ObjC generation.
498*67e74705SXin Li class ObjCTypesHelper : public ObjCCommonTypesHelper {
499*67e74705SXin Li public:
500*67e74705SXin Li   /// SymtabTy - LLVM type for struct objc_symtab.
501*67e74705SXin Li   llvm::StructType *SymtabTy;
502*67e74705SXin Li   /// SymtabPtrTy - LLVM type for struct objc_symtab *.
503*67e74705SXin Li   llvm::Type *SymtabPtrTy;
504*67e74705SXin Li   /// ModuleTy - LLVM type for struct objc_module.
505*67e74705SXin Li   llvm::StructType *ModuleTy;
506*67e74705SXin Li 
507*67e74705SXin Li   /// ProtocolTy - LLVM type for struct objc_protocol.
508*67e74705SXin Li   llvm::StructType *ProtocolTy;
509*67e74705SXin Li   /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
510*67e74705SXin Li   llvm::Type *ProtocolPtrTy;
511*67e74705SXin Li   /// ProtocolExtensionTy - LLVM type for struct
512*67e74705SXin Li   /// objc_protocol_extension.
513*67e74705SXin Li   llvm::StructType *ProtocolExtensionTy;
514*67e74705SXin Li   /// ProtocolExtensionTy - LLVM type for struct
515*67e74705SXin Li   /// objc_protocol_extension *.
516*67e74705SXin Li   llvm::Type *ProtocolExtensionPtrTy;
517*67e74705SXin Li   /// MethodDescriptionTy - LLVM type for struct
518*67e74705SXin Li   /// objc_method_description.
519*67e74705SXin Li   llvm::StructType *MethodDescriptionTy;
520*67e74705SXin Li   /// MethodDescriptionListTy - LLVM type for struct
521*67e74705SXin Li   /// objc_method_description_list.
522*67e74705SXin Li   llvm::StructType *MethodDescriptionListTy;
523*67e74705SXin Li   /// MethodDescriptionListPtrTy - LLVM type for struct
524*67e74705SXin Li   /// objc_method_description_list *.
525*67e74705SXin Li   llvm::Type *MethodDescriptionListPtrTy;
526*67e74705SXin Li   /// ProtocolListTy - LLVM type for struct objc_property_list.
527*67e74705SXin Li   llvm::StructType *ProtocolListTy;
528*67e74705SXin Li   /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
529*67e74705SXin Li   llvm::Type *ProtocolListPtrTy;
530*67e74705SXin Li   /// CategoryTy - LLVM type for struct objc_category.
531*67e74705SXin Li   llvm::StructType *CategoryTy;
532*67e74705SXin Li   /// ClassTy - LLVM type for struct objc_class.
533*67e74705SXin Li   llvm::StructType *ClassTy;
534*67e74705SXin Li   /// ClassPtrTy - LLVM type for struct objc_class *.
535*67e74705SXin Li   llvm::Type *ClassPtrTy;
536*67e74705SXin Li   /// ClassExtensionTy - LLVM type for struct objc_class_ext.
537*67e74705SXin Li   llvm::StructType *ClassExtensionTy;
538*67e74705SXin Li   /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
539*67e74705SXin Li   llvm::Type *ClassExtensionPtrTy;
540*67e74705SXin Li   // IvarTy - LLVM type for struct objc_ivar.
541*67e74705SXin Li   llvm::StructType *IvarTy;
542*67e74705SXin Li   /// IvarListTy - LLVM type for struct objc_ivar_list.
543*67e74705SXin Li   llvm::Type *IvarListTy;
544*67e74705SXin Li   /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
545*67e74705SXin Li   llvm::Type *IvarListPtrTy;
546*67e74705SXin Li   /// MethodListTy - LLVM type for struct objc_method_list.
547*67e74705SXin Li   llvm::Type *MethodListTy;
548*67e74705SXin Li   /// MethodListPtrTy - LLVM type for struct objc_method_list *.
549*67e74705SXin Li   llvm::Type *MethodListPtrTy;
550*67e74705SXin Li 
551*67e74705SXin Li   /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
552*67e74705SXin Li   llvm::Type *ExceptionDataTy;
553*67e74705SXin Li 
554*67e74705SXin Li   /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
getExceptionTryEnterFn()555*67e74705SXin Li   llvm::Constant *getExceptionTryEnterFn() {
556*67e74705SXin Li     llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
557*67e74705SXin Li     return CGM.CreateRuntimeFunction(
558*67e74705SXin Li       llvm::FunctionType::get(CGM.VoidTy, params, false),
559*67e74705SXin Li       "objc_exception_try_enter");
560*67e74705SXin Li   }
561*67e74705SXin Li 
562*67e74705SXin Li   /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
getExceptionTryExitFn()563*67e74705SXin Li   llvm::Constant *getExceptionTryExitFn() {
564*67e74705SXin Li     llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
565*67e74705SXin Li     return CGM.CreateRuntimeFunction(
566*67e74705SXin Li       llvm::FunctionType::get(CGM.VoidTy, params, false),
567*67e74705SXin Li       "objc_exception_try_exit");
568*67e74705SXin Li   }
569*67e74705SXin Li 
570*67e74705SXin Li   /// ExceptionExtractFn - LLVM objc_exception_extract function.
getExceptionExtractFn()571*67e74705SXin Li   llvm::Constant *getExceptionExtractFn() {
572*67e74705SXin Li     llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
573*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
574*67e74705SXin Li                                                              params, false),
575*67e74705SXin Li                                      "objc_exception_extract");
576*67e74705SXin Li   }
577*67e74705SXin Li 
578*67e74705SXin Li   /// ExceptionMatchFn - LLVM objc_exception_match function.
getExceptionMatchFn()579*67e74705SXin Li   llvm::Constant *getExceptionMatchFn() {
580*67e74705SXin Li     llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
581*67e74705SXin Li     return CGM.CreateRuntimeFunction(
582*67e74705SXin Li       llvm::FunctionType::get(CGM.Int32Ty, params, false),
583*67e74705SXin Li       "objc_exception_match");
584*67e74705SXin Li   }
585*67e74705SXin Li 
586*67e74705SXin Li   /// SetJmpFn - LLVM _setjmp function.
getSetJmpFn()587*67e74705SXin Li   llvm::Constant *getSetJmpFn() {
588*67e74705SXin Li     // This is specifically the prototype for x86.
589*67e74705SXin Li     llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
590*67e74705SXin Li     return
591*67e74705SXin Li       CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
592*67e74705SXin Li                                                         params, false),
593*67e74705SXin Li                                 "_setjmp",
594*67e74705SXin Li                                 llvm::AttributeSet::get(CGM.getLLVMContext(),
595*67e74705SXin Li                                               llvm::AttributeSet::FunctionIndex,
596*67e74705SXin Li                                                  llvm::Attribute::NonLazyBind));
597*67e74705SXin Li   }
598*67e74705SXin Li 
599*67e74705SXin Li public:
600*67e74705SXin Li   ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
601*67e74705SXin Li };
602*67e74705SXin Li 
603*67e74705SXin Li /// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
604*67e74705SXin Li /// modern abi
605*67e74705SXin Li class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
606*67e74705SXin Li public:
607*67e74705SXin Li   // MethodListnfABITy - LLVM for struct _method_list_t
608*67e74705SXin Li   llvm::StructType *MethodListnfABITy;
609*67e74705SXin Li 
610*67e74705SXin Li   // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
611*67e74705SXin Li   llvm::Type *MethodListnfABIPtrTy;
612*67e74705SXin Li 
613*67e74705SXin Li   // ProtocolnfABITy = LLVM for struct _protocol_t
614*67e74705SXin Li   llvm::StructType *ProtocolnfABITy;
615*67e74705SXin Li 
616*67e74705SXin Li   // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
617*67e74705SXin Li   llvm::Type *ProtocolnfABIPtrTy;
618*67e74705SXin Li 
619*67e74705SXin Li   // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
620*67e74705SXin Li   llvm::StructType *ProtocolListnfABITy;
621*67e74705SXin Li 
622*67e74705SXin Li   // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
623*67e74705SXin Li   llvm::Type *ProtocolListnfABIPtrTy;
624*67e74705SXin Li 
625*67e74705SXin Li   // ClassnfABITy - LLVM for struct _class_t
626*67e74705SXin Li   llvm::StructType *ClassnfABITy;
627*67e74705SXin Li 
628*67e74705SXin Li   // ClassnfABIPtrTy - LLVM for struct _class_t*
629*67e74705SXin Li   llvm::Type *ClassnfABIPtrTy;
630*67e74705SXin Li 
631*67e74705SXin Li   // IvarnfABITy - LLVM for struct _ivar_t
632*67e74705SXin Li   llvm::StructType *IvarnfABITy;
633*67e74705SXin Li 
634*67e74705SXin Li   // IvarListnfABITy - LLVM for struct _ivar_list_t
635*67e74705SXin Li   llvm::StructType *IvarListnfABITy;
636*67e74705SXin Li 
637*67e74705SXin Li   // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
638*67e74705SXin Li   llvm::Type *IvarListnfABIPtrTy;
639*67e74705SXin Li 
640*67e74705SXin Li   // ClassRonfABITy - LLVM for struct _class_ro_t
641*67e74705SXin Li   llvm::StructType *ClassRonfABITy;
642*67e74705SXin Li 
643*67e74705SXin Li   // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
644*67e74705SXin Li   llvm::Type *ImpnfABITy;
645*67e74705SXin Li 
646*67e74705SXin Li   // CategorynfABITy - LLVM for struct _category_t
647*67e74705SXin Li   llvm::StructType *CategorynfABITy;
648*67e74705SXin Li 
649*67e74705SXin Li   // New types for nonfragile abi messaging.
650*67e74705SXin Li 
651*67e74705SXin Li   // MessageRefTy - LLVM for:
652*67e74705SXin Li   // struct _message_ref_t {
653*67e74705SXin Li   //   IMP messenger;
654*67e74705SXin Li   //   SEL name;
655*67e74705SXin Li   // };
656*67e74705SXin Li   llvm::StructType *MessageRefTy;
657*67e74705SXin Li   // MessageRefCTy - clang type for struct _message_ref_t
658*67e74705SXin Li   QualType MessageRefCTy;
659*67e74705SXin Li 
660*67e74705SXin Li   // MessageRefPtrTy - LLVM for struct _message_ref_t*
661*67e74705SXin Li   llvm::Type *MessageRefPtrTy;
662*67e74705SXin Li   // MessageRefCPtrTy - clang type for struct _message_ref_t*
663*67e74705SXin Li   QualType MessageRefCPtrTy;
664*67e74705SXin Li 
665*67e74705SXin Li   // SuperMessageRefTy - LLVM for:
666*67e74705SXin Li   // struct _super_message_ref_t {
667*67e74705SXin Li   //   SUPER_IMP messenger;
668*67e74705SXin Li   //   SEL name;
669*67e74705SXin Li   // };
670*67e74705SXin Li   llvm::StructType *SuperMessageRefTy;
671*67e74705SXin Li 
672*67e74705SXin Li   // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
673*67e74705SXin Li   llvm::Type *SuperMessageRefPtrTy;
674*67e74705SXin Li 
getMessageSendFixupFn()675*67e74705SXin Li   llvm::Constant *getMessageSendFixupFn() {
676*67e74705SXin Li     // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
677*67e74705SXin Li     llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
678*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
679*67e74705SXin Li                                                              params, true),
680*67e74705SXin Li                                      "objc_msgSend_fixup");
681*67e74705SXin Li   }
682*67e74705SXin Li 
getMessageSendFpretFixupFn()683*67e74705SXin Li   llvm::Constant *getMessageSendFpretFixupFn() {
684*67e74705SXin Li     // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
685*67e74705SXin Li     llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
686*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
687*67e74705SXin Li                                                              params, true),
688*67e74705SXin Li                                      "objc_msgSend_fpret_fixup");
689*67e74705SXin Li   }
690*67e74705SXin Li 
getMessageSendStretFixupFn()691*67e74705SXin Li   llvm::Constant *getMessageSendStretFixupFn() {
692*67e74705SXin Li     // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
693*67e74705SXin Li     llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
694*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
695*67e74705SXin Li                                                              params, true),
696*67e74705SXin Li                                      "objc_msgSend_stret_fixup");
697*67e74705SXin Li   }
698*67e74705SXin Li 
getMessageSendSuper2FixupFn()699*67e74705SXin Li   llvm::Constant *getMessageSendSuper2FixupFn() {
700*67e74705SXin Li     // id objc_msgSendSuper2_fixup (struct objc_super *,
701*67e74705SXin Li     //                              struct _super_message_ref_t*, ...)
702*67e74705SXin Li     llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
703*67e74705SXin Li     return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
704*67e74705SXin Li                                                               params, true),
705*67e74705SXin Li                                       "objc_msgSendSuper2_fixup");
706*67e74705SXin Li   }
707*67e74705SXin Li 
getMessageSendSuper2StretFixupFn()708*67e74705SXin Li   llvm::Constant *getMessageSendSuper2StretFixupFn() {
709*67e74705SXin Li     // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
710*67e74705SXin Li     //                                   struct _super_message_ref_t*, ...)
711*67e74705SXin Li     llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
712*67e74705SXin Li     return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
713*67e74705SXin Li                                                               params, true),
714*67e74705SXin Li                                       "objc_msgSendSuper2_stret_fixup");
715*67e74705SXin Li   }
716*67e74705SXin Li 
getObjCEndCatchFn()717*67e74705SXin Li   llvm::Constant *getObjCEndCatchFn() {
718*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
719*67e74705SXin Li                                      "objc_end_catch");
720*67e74705SXin Li 
721*67e74705SXin Li   }
722*67e74705SXin Li 
getObjCBeginCatchFn()723*67e74705SXin Li   llvm::Constant *getObjCBeginCatchFn() {
724*67e74705SXin Li     llvm::Type *params[] = { Int8PtrTy };
725*67e74705SXin Li     return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
726*67e74705SXin Li                                                              params, false),
727*67e74705SXin Li                                      "objc_begin_catch");
728*67e74705SXin Li   }
729*67e74705SXin Li 
730*67e74705SXin Li   llvm::StructType *EHTypeTy;
731*67e74705SXin Li   llvm::Type *EHTypePtrTy;
732*67e74705SXin Li 
733*67e74705SXin Li   ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
734*67e74705SXin Li };
735*67e74705SXin Li 
736*67e74705SXin Li class CGObjCCommonMac : public CodeGen::CGObjCRuntime {
737*67e74705SXin Li public:
738*67e74705SXin Li   class SKIP_SCAN {
739*67e74705SXin Li   public:
740*67e74705SXin Li     unsigned skip;
741*67e74705SXin Li     unsigned scan;
SKIP_SCAN(unsigned _skip=0,unsigned _scan=0)742*67e74705SXin Li     SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
743*67e74705SXin Li       : skip(_skip), scan(_scan) {}
744*67e74705SXin Li   };
745*67e74705SXin Li 
746*67e74705SXin Li   /// opcode for captured block variables layout 'instructions'.
747*67e74705SXin Li   /// In the following descriptions, 'I' is the value of the immediate field.
748*67e74705SXin Li   /// (field following the opcode).
749*67e74705SXin Li   ///
750*67e74705SXin Li   enum BLOCK_LAYOUT_OPCODE {
751*67e74705SXin Li     /// An operator which affects how the following layout should be
752*67e74705SXin Li     /// interpreted.
753*67e74705SXin Li     ///   I == 0: Halt interpretation and treat everything else as
754*67e74705SXin Li     ///           a non-pointer.  Note that this instruction is equal
755*67e74705SXin Li     ///           to '\0'.
756*67e74705SXin Li     ///   I != 0: Currently unused.
757*67e74705SXin Li     BLOCK_LAYOUT_OPERATOR            = 0,
758*67e74705SXin Li 
759*67e74705SXin Li     /// The next I+1 bytes do not contain a value of object pointer type.
760*67e74705SXin Li     /// Note that this can leave the stream unaligned, meaning that
761*67e74705SXin Li     /// subsequent word-size instructions do not begin at a multiple of
762*67e74705SXin Li     /// the pointer size.
763*67e74705SXin Li     BLOCK_LAYOUT_NON_OBJECT_BYTES    = 1,
764*67e74705SXin Li 
765*67e74705SXin Li     /// The next I+1 words do not contain a value of object pointer type.
766*67e74705SXin Li     /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
767*67e74705SXin Li     /// when the required skip quantity is a multiple of the pointer size.
768*67e74705SXin Li     BLOCK_LAYOUT_NON_OBJECT_WORDS    = 2,
769*67e74705SXin Li 
770*67e74705SXin Li     /// The next I+1 words are __strong pointers to Objective-C
771*67e74705SXin Li     /// objects or blocks.
772*67e74705SXin Li     BLOCK_LAYOUT_STRONG              = 3,
773*67e74705SXin Li 
774*67e74705SXin Li     /// The next I+1 words are pointers to __block variables.
775*67e74705SXin Li     BLOCK_LAYOUT_BYREF               = 4,
776*67e74705SXin Li 
777*67e74705SXin Li     /// The next I+1 words are __weak pointers to Objective-C
778*67e74705SXin Li     /// objects or blocks.
779*67e74705SXin Li     BLOCK_LAYOUT_WEAK                = 5,
780*67e74705SXin Li 
781*67e74705SXin Li     /// The next I+1 words are __unsafe_unretained pointers to
782*67e74705SXin Li     /// Objective-C objects or blocks.
783*67e74705SXin Li     BLOCK_LAYOUT_UNRETAINED          = 6
784*67e74705SXin Li 
785*67e74705SXin Li     /// The next I+1 words are block or object pointers with some
786*67e74705SXin Li     /// as-yet-unspecified ownership semantics.  If we add more
787*67e74705SXin Li     /// flavors of ownership semantics, values will be taken from
788*67e74705SXin Li     /// this range.
789*67e74705SXin Li     ///
790*67e74705SXin Li     /// This is included so that older tools can at least continue
791*67e74705SXin Li     /// processing the layout past such things.
792*67e74705SXin Li     //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
793*67e74705SXin Li 
794*67e74705SXin Li     /// All other opcodes are reserved.  Halt interpretation and
795*67e74705SXin Li     /// treat everything else as opaque.
796*67e74705SXin Li   };
797*67e74705SXin Li 
798*67e74705SXin Li   class RUN_SKIP {
799*67e74705SXin Li   public:
800*67e74705SXin Li     enum BLOCK_LAYOUT_OPCODE opcode;
801*67e74705SXin Li     CharUnits block_var_bytepos;
802*67e74705SXin Li     CharUnits block_var_size;
RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode=BLOCK_LAYOUT_OPERATOR,CharUnits BytePos=CharUnits::Zero (),CharUnits Size=CharUnits::Zero ())803*67e74705SXin Li     RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
804*67e74705SXin Li              CharUnits BytePos = CharUnits::Zero(),
805*67e74705SXin Li              CharUnits Size = CharUnits::Zero())
806*67e74705SXin Li     : opcode(Opcode), block_var_bytepos(BytePos),  block_var_size(Size) {}
807*67e74705SXin Li 
808*67e74705SXin Li     // Allow sorting based on byte pos.
operator <(const RUN_SKIP & b) const809*67e74705SXin Li     bool operator<(const RUN_SKIP &b) const {
810*67e74705SXin Li       return block_var_bytepos < b.block_var_bytepos;
811*67e74705SXin Li     }
812*67e74705SXin Li   };
813*67e74705SXin Li 
814*67e74705SXin Li protected:
815*67e74705SXin Li   llvm::LLVMContext &VMContext;
816*67e74705SXin Li   // FIXME! May not be needing this after all.
817*67e74705SXin Li   unsigned ObjCABI;
818*67e74705SXin Li 
819*67e74705SXin Li   // arc/mrr layout of captured block literal variables.
820*67e74705SXin Li   SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
821*67e74705SXin Li 
822*67e74705SXin Li   /// LazySymbols - Symbols to generate a lazy reference for. See
823*67e74705SXin Li   /// DefinedSymbols and FinishModule().
824*67e74705SXin Li   llvm::SetVector<IdentifierInfo*> LazySymbols;
825*67e74705SXin Li 
826*67e74705SXin Li   /// DefinedSymbols - External symbols which are defined by this
827*67e74705SXin Li   /// module. The symbols in this list and LazySymbols are used to add
828*67e74705SXin Li   /// special linker symbols which ensure that Objective-C modules are
829*67e74705SXin Li   /// linked properly.
830*67e74705SXin Li   llvm::SetVector<IdentifierInfo*> DefinedSymbols;
831*67e74705SXin Li 
832*67e74705SXin Li   /// ClassNames - uniqued class names.
833*67e74705SXin Li   llvm::StringMap<llvm::GlobalVariable*> ClassNames;
834*67e74705SXin Li 
835*67e74705SXin Li   /// MethodVarNames - uniqued method variable names.
836*67e74705SXin Li   llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
837*67e74705SXin Li 
838*67e74705SXin Li   /// DefinedCategoryNames - list of category names in form Class_Category.
839*67e74705SXin Li   llvm::SmallSetVector<std::string, 16> DefinedCategoryNames;
840*67e74705SXin Li 
841*67e74705SXin Li   /// MethodVarTypes - uniqued method type signatures. We have to use
842*67e74705SXin Li   /// a StringMap here because have no other unique reference.
843*67e74705SXin Li   llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
844*67e74705SXin Li 
845*67e74705SXin Li   /// MethodDefinitions - map of methods which have been defined in
846*67e74705SXin Li   /// this translation unit.
847*67e74705SXin Li   llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
848*67e74705SXin Li 
849*67e74705SXin Li   /// PropertyNames - uniqued method variable names.
850*67e74705SXin Li   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
851*67e74705SXin Li 
852*67e74705SXin Li   /// ClassReferences - uniqued class references.
853*67e74705SXin Li   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
854*67e74705SXin Li 
855*67e74705SXin Li   /// SelectorReferences - uniqued selector references.
856*67e74705SXin Li   llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
857*67e74705SXin Li 
858*67e74705SXin Li   /// Protocols - Protocols for which an objc_protocol structure has
859*67e74705SXin Li   /// been emitted. Forward declarations are handled by creating an
860*67e74705SXin Li   /// empty structure whose initializer is filled in when/if defined.
861*67e74705SXin Li   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
862*67e74705SXin Li 
863*67e74705SXin Li   /// DefinedProtocols - Protocols which have actually been
864*67e74705SXin Li   /// defined. We should not need this, see FIXME in GenerateProtocol.
865*67e74705SXin Li   llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
866*67e74705SXin Li 
867*67e74705SXin Li   /// DefinedClasses - List of defined classes.
868*67e74705SXin Li   SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
869*67e74705SXin Li 
870*67e74705SXin Li   /// ImplementedClasses - List of @implemented classes.
871*67e74705SXin Li   SmallVector<const ObjCInterfaceDecl*, 16> ImplementedClasses;
872*67e74705SXin Li 
873*67e74705SXin Li   /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
874*67e74705SXin Li   SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
875*67e74705SXin Li 
876*67e74705SXin Li   /// DefinedCategories - List of defined categories.
877*67e74705SXin Li   SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
878*67e74705SXin Li 
879*67e74705SXin Li   /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
880*67e74705SXin Li   SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
881*67e74705SXin Li 
882*67e74705SXin Li   /// GetNameForMethod - Return a name for the given method.
883*67e74705SXin Li   /// \param[out] NameOut - The return value.
884*67e74705SXin Li   void GetNameForMethod(const ObjCMethodDecl *OMD,
885*67e74705SXin Li                         const ObjCContainerDecl *CD,
886*67e74705SXin Li                         SmallVectorImpl<char> &NameOut);
887*67e74705SXin Li 
888*67e74705SXin Li   /// GetMethodVarName - Return a unique constant for the given
889*67e74705SXin Li   /// selector's name. The return value has type char *.
890*67e74705SXin Li   llvm::Constant *GetMethodVarName(Selector Sel);
891*67e74705SXin Li   llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
892*67e74705SXin Li 
893*67e74705SXin Li   /// GetMethodVarType - Return a unique constant for the given
894*67e74705SXin Li   /// method's type encoding string. The return value has type char *.
895*67e74705SXin Li 
896*67e74705SXin Li   // FIXME: This is a horrible name.
897*67e74705SXin Li   llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
898*67e74705SXin Li                                    bool Extended = false);
899*67e74705SXin Li   llvm::Constant *GetMethodVarType(const FieldDecl *D);
900*67e74705SXin Li 
901*67e74705SXin Li   /// GetPropertyName - Return a unique constant for the given
902*67e74705SXin Li   /// name. The return value has type char *.
903*67e74705SXin Li   llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
904*67e74705SXin Li 
905*67e74705SXin Li   // FIXME: This can be dropped once string functions are unified.
906*67e74705SXin Li   llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
907*67e74705SXin Li                                         const Decl *Container);
908*67e74705SXin Li 
909*67e74705SXin Li   /// GetClassName - Return a unique constant for the given selector's
910*67e74705SXin Li   /// runtime name (which may change via use of objc_runtime_name attribute on
911*67e74705SXin Li   /// class or protocol definition. The return value has type char *.
912*67e74705SXin Li   llvm::Constant *GetClassName(StringRef RuntimeName);
913*67e74705SXin Li 
914*67e74705SXin Li   llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
915*67e74705SXin Li 
916*67e74705SXin Li   /// BuildIvarLayout - Builds ivar layout bitmap for the class
917*67e74705SXin Li   /// implementation for the __strong or __weak case.
918*67e74705SXin Li   ///
919*67e74705SXin Li   /// \param hasMRCWeakIvars - Whether we are compiling in MRC and there
920*67e74705SXin Li   ///   are any weak ivars defined directly in the class.  Meaningless unless
921*67e74705SXin Li   ///   building a weak layout.  Does not guarantee that the layout will
922*67e74705SXin Li   ///   actually have any entries, because the ivar might be under-aligned.
923*67e74705SXin Li   llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
924*67e74705SXin Li                                   CharUnits beginOffset,
925*67e74705SXin Li                                   CharUnits endOffset,
926*67e74705SXin Li                                   bool forStrongLayout,
927*67e74705SXin Li                                   bool hasMRCWeakIvars);
928*67e74705SXin Li 
BuildStrongIvarLayout(const ObjCImplementationDecl * OI,CharUnits beginOffset,CharUnits endOffset)929*67e74705SXin Li   llvm::Constant *BuildStrongIvarLayout(const ObjCImplementationDecl *OI,
930*67e74705SXin Li                                         CharUnits beginOffset,
931*67e74705SXin Li                                         CharUnits endOffset) {
932*67e74705SXin Li     return BuildIvarLayout(OI, beginOffset, endOffset, true, false);
933*67e74705SXin Li   }
934*67e74705SXin Li 
BuildWeakIvarLayout(const ObjCImplementationDecl * OI,CharUnits beginOffset,CharUnits endOffset,bool hasMRCWeakIvars)935*67e74705SXin Li   llvm::Constant *BuildWeakIvarLayout(const ObjCImplementationDecl *OI,
936*67e74705SXin Li                                       CharUnits beginOffset,
937*67e74705SXin Li                                       CharUnits endOffset,
938*67e74705SXin Li                                       bool hasMRCWeakIvars) {
939*67e74705SXin Li     return BuildIvarLayout(OI, beginOffset, endOffset, false, hasMRCWeakIvars);
940*67e74705SXin Li   }
941*67e74705SXin Li 
942*67e74705SXin Li   Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout);
943*67e74705SXin Li 
944*67e74705SXin Li   void UpdateRunSkipBlockVars(bool IsByref,
945*67e74705SXin Li                               Qualifiers::ObjCLifetime LifeTime,
946*67e74705SXin Li                               CharUnits FieldOffset,
947*67e74705SXin Li                               CharUnits FieldSize);
948*67e74705SXin Li 
949*67e74705SXin Li   void BuildRCBlockVarRecordLayout(const RecordType *RT,
950*67e74705SXin Li                                    CharUnits BytePos, bool &HasUnion,
951*67e74705SXin Li                                    bool ByrefLayout=false);
952*67e74705SXin Li 
953*67e74705SXin Li   void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
954*67e74705SXin Li                            const RecordDecl *RD,
955*67e74705SXin Li                            ArrayRef<const FieldDecl*> RecFields,
956*67e74705SXin Li                            CharUnits BytePos, bool &HasUnion,
957*67e74705SXin Li                            bool ByrefLayout);
958*67e74705SXin Li 
959*67e74705SXin Li   uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
960*67e74705SXin Li 
961*67e74705SXin Li   llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);
962*67e74705SXin Li 
963*67e74705SXin Li   /// GetIvarLayoutName - Returns a unique constant for the given
964*67e74705SXin Li   /// ivar layout bitmap.
965*67e74705SXin Li   llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
966*67e74705SXin Li                                     const ObjCCommonTypesHelper &ObjCTypes);
967*67e74705SXin Li 
968*67e74705SXin Li   /// EmitPropertyList - Emit the given property list. The return
969*67e74705SXin Li   /// value has type PropertyListPtrTy.
970*67e74705SXin Li   llvm::Constant *EmitPropertyList(Twine Name,
971*67e74705SXin Li                                    const Decl *Container,
972*67e74705SXin Li                                    const ObjCContainerDecl *OCD,
973*67e74705SXin Li                                    const ObjCCommonTypesHelper &ObjCTypes,
974*67e74705SXin Li                                    bool IsClassProperty);
975*67e74705SXin Li 
976*67e74705SXin Li   /// EmitProtocolMethodTypes - Generate the array of extended method type
977*67e74705SXin Li   /// strings. The return value has type Int8PtrPtrTy.
978*67e74705SXin Li   llvm::Constant *EmitProtocolMethodTypes(Twine Name,
979*67e74705SXin Li                                           ArrayRef<llvm::Constant*> MethodTypes,
980*67e74705SXin Li                                        const ObjCCommonTypesHelper &ObjCTypes);
981*67e74705SXin Li 
982*67e74705SXin Li   /// PushProtocolProperties - Push protocol's property on the input stack.
983*67e74705SXin Li   void PushProtocolProperties(
984*67e74705SXin Li     llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
985*67e74705SXin Li     SmallVectorImpl<llvm::Constant*> &Properties,
986*67e74705SXin Li     const Decl *Container,
987*67e74705SXin Li     const ObjCProtocolDecl *Proto,
988*67e74705SXin Li     const ObjCCommonTypesHelper &ObjCTypes,
989*67e74705SXin Li     bool IsClassProperty);
990*67e74705SXin Li 
991*67e74705SXin Li   /// GetProtocolRef - Return a reference to the internal protocol
992*67e74705SXin Li   /// description, creating an empty one if it has not been
993*67e74705SXin Li   /// defined. The return value has type ProtocolPtrTy.
994*67e74705SXin Li   llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
995*67e74705SXin Li 
996*67e74705SXin Li   /// Return a reference to the given Class using runtime calls rather than
997*67e74705SXin Li   /// by a symbol reference.
998*67e74705SXin Li   llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,
999*67e74705SXin Li                                       const ObjCInterfaceDecl *ID,
1000*67e74705SXin Li                                       ObjCCommonTypesHelper &ObjCTypes);
1001*67e74705SXin Li 
1002*67e74705SXin Li public:
1003*67e74705SXin Li   /// CreateMetadataVar - Create a global variable with internal
1004*67e74705SXin Li   /// linkage for use by the Objective-C runtime.
1005*67e74705SXin Li   ///
1006*67e74705SXin Li   /// This is a convenience wrapper which not only creates the
1007*67e74705SXin Li   /// variable, but also sets the section and alignment and adds the
1008*67e74705SXin Li   /// global to the "llvm.used" list.
1009*67e74705SXin Li   ///
1010*67e74705SXin Li   /// \param Name - The variable name.
1011*67e74705SXin Li   /// \param Init - The variable initializer; this is also used to
1012*67e74705SXin Li   /// define the type of the variable.
1013*67e74705SXin Li   /// \param Section - The section the variable should go into, or empty.
1014*67e74705SXin Li   /// \param Align - The alignment for the variable, or 0.
1015*67e74705SXin Li   /// \param AddToUsed - Whether the variable should be added to
1016*67e74705SXin Li   /// "llvm.used".
1017*67e74705SXin Li   llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,
1018*67e74705SXin Li                                           StringRef Section, CharUnits Align,
1019*67e74705SXin Li                                           bool AddToUsed);
1020*67e74705SXin Li 
1021*67e74705SXin Li protected:
1022*67e74705SXin Li   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1023*67e74705SXin Li                                   ReturnValueSlot Return,
1024*67e74705SXin Li                                   QualType ResultType,
1025*67e74705SXin Li                                   llvm::Value *Sel,
1026*67e74705SXin Li                                   llvm::Value *Arg0,
1027*67e74705SXin Li                                   QualType Arg0Ty,
1028*67e74705SXin Li                                   bool IsSuper,
1029*67e74705SXin Li                                   const CallArgList &CallArgs,
1030*67e74705SXin Li                                   const ObjCMethodDecl *OMD,
1031*67e74705SXin Li                                   const ObjCInterfaceDecl *ClassReceiver,
1032*67e74705SXin Li                                   const ObjCCommonTypesHelper &ObjCTypes);
1033*67e74705SXin Li 
1034*67e74705SXin Li   /// EmitImageInfo - Emit the image info marker used to encode some module
1035*67e74705SXin Li   /// level information.
1036*67e74705SXin Li   void EmitImageInfo();
1037*67e74705SXin Li 
1038*67e74705SXin Li public:
CGObjCCommonMac(CodeGen::CodeGenModule & cgm)1039*67e74705SXin Li   CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
1040*67e74705SXin Li     CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
1041*67e74705SXin Li 
isNonFragileABI() const1042*67e74705SXin Li   bool isNonFragileABI() const {
1043*67e74705SXin Li     return ObjCABI == 2;
1044*67e74705SXin Li   }
1045*67e74705SXin Li 
1046*67e74705SXin Li   ConstantAddress GenerateConstantString(const StringLiteral *SL) override;
1047*67e74705SXin Li 
1048*67e74705SXin Li   llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
1049*67e74705SXin Li                                  const ObjCContainerDecl *CD=nullptr) override;
1050*67e74705SXin Li 
1051*67e74705SXin Li   void GenerateProtocol(const ObjCProtocolDecl *PD) override;
1052*67e74705SXin Li 
1053*67e74705SXin Li   /// GetOrEmitProtocol - Get the protocol object for the given
1054*67e74705SXin Li   /// declaration, emitting it if necessary. The return value has type
1055*67e74705SXin Li   /// ProtocolPtrTy.
1056*67e74705SXin Li   virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
1057*67e74705SXin Li 
1058*67e74705SXin Li   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1059*67e74705SXin Li   /// object for the given declaration, emitting it if needed. These
1060*67e74705SXin Li   /// forward references will be filled in with empty bodies if no
1061*67e74705SXin Li   /// definition is seen. The return value has type ProtocolPtrTy.
1062*67e74705SXin Li   virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
1063*67e74705SXin Li   llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1064*67e74705SXin Li                                      const CGBlockInfo &blockInfo) override;
1065*67e74705SXin Li   llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1066*67e74705SXin Li                                      const CGBlockInfo &blockInfo) override;
1067*67e74705SXin Li 
1068*67e74705SXin Li   llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1069*67e74705SXin Li                                    QualType T) override;
1070*67e74705SXin Li };
1071*67e74705SXin Li 
1072*67e74705SXin Li class CGObjCMac : public CGObjCCommonMac {
1073*67e74705SXin Li private:
1074*67e74705SXin Li   ObjCTypesHelper ObjCTypes;
1075*67e74705SXin Li 
1076*67e74705SXin Li   /// EmitModuleInfo - Another marker encoding module level
1077*67e74705SXin Li   /// information.
1078*67e74705SXin Li   void EmitModuleInfo();
1079*67e74705SXin Li 
1080*67e74705SXin Li   /// EmitModuleSymols - Emit module symbols, the list of defined
1081*67e74705SXin Li   /// classes and categories. The result has type SymtabPtrTy.
1082*67e74705SXin Li   llvm::Constant *EmitModuleSymbols();
1083*67e74705SXin Li 
1084*67e74705SXin Li   /// FinishModule - Write out global data structures at the end of
1085*67e74705SXin Li   /// processing a translation unit.
1086*67e74705SXin Li   void FinishModule();
1087*67e74705SXin Li 
1088*67e74705SXin Li   /// EmitClassExtension - Generate the class extension structure used
1089*67e74705SXin Li   /// to store the weak ivar layout and properties. The return value
1090*67e74705SXin Li   /// has type ClassExtensionPtrTy.
1091*67e74705SXin Li   llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID,
1092*67e74705SXin Li                                      CharUnits instanceSize,
1093*67e74705SXin Li                                      bool hasMRCWeakIvars,
1094*67e74705SXin Li                                      bool isClassProperty);
1095*67e74705SXin Li 
1096*67e74705SXin Li   /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1097*67e74705SXin Li   /// for the given class.
1098*67e74705SXin Li   llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1099*67e74705SXin Li                             const ObjCInterfaceDecl *ID);
1100*67e74705SXin Li 
1101*67e74705SXin Li   llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1102*67e74705SXin Li                                   IdentifierInfo *II);
1103*67e74705SXin Li 
1104*67e74705SXin Li   llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1105*67e74705SXin Li 
1106*67e74705SXin Li   /// EmitSuperClassRef - Emits reference to class's main metadata class.
1107*67e74705SXin Li   llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
1108*67e74705SXin Li 
1109*67e74705SXin Li   /// EmitIvarList - Emit the ivar list for the given
1110*67e74705SXin Li   /// implementation. If ForClass is true the list of class ivars
1111*67e74705SXin Li   /// (i.e. metaclass ivars) is emitted, otherwise the list of
1112*67e74705SXin Li   /// interface ivars will be emitted. The return value has type
1113*67e74705SXin Li   /// IvarListPtrTy.
1114*67e74705SXin Li   llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1115*67e74705SXin Li                                bool ForClass);
1116*67e74705SXin Li 
1117*67e74705SXin Li   /// EmitMetaClass - Emit a forward reference to the class structure
1118*67e74705SXin Li   /// for the metaclass of the given interface. The return value has
1119*67e74705SXin Li   /// type ClassPtrTy.
1120*67e74705SXin Li   llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1121*67e74705SXin Li 
1122*67e74705SXin Li   /// EmitMetaClass - Emit a class structure for the metaclass of the
1123*67e74705SXin Li   /// given implementation. The return value has type ClassPtrTy.
1124*67e74705SXin Li   llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1125*67e74705SXin Li                                 llvm::Constant *Protocols,
1126*67e74705SXin Li                                 ArrayRef<llvm::Constant*> Methods);
1127*67e74705SXin Li 
1128*67e74705SXin Li   llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1129*67e74705SXin Li 
1130*67e74705SXin Li   llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1131*67e74705SXin Li 
1132*67e74705SXin Li   /// EmitMethodList - Emit the method list for the given
1133*67e74705SXin Li   /// implementation. The return value has type MethodListPtrTy.
1134*67e74705SXin Li   llvm::Constant *EmitMethodList(Twine Name, StringRef Section,
1135*67e74705SXin Li                                  ArrayRef<llvm::Constant *> Methods);
1136*67e74705SXin Li 
1137*67e74705SXin Li   /// EmitMethodDescList - Emit a method description list for a list of
1138*67e74705SXin Li   /// method declarations.
1139*67e74705SXin Li   ///  - TypeName: The name for the type containing the methods.
1140*67e74705SXin Li   ///  - IsProtocol: True iff these methods are for a protocol.
1141*67e74705SXin Li   ///  - ClassMethds: True iff these are class methods.
1142*67e74705SXin Li   ///  - Required: When true, only "required" methods are
1143*67e74705SXin Li   ///    listed. Similarly, when false only "optional" methods are
1144*67e74705SXin Li   ///    listed. For classes this should always be true.
1145*67e74705SXin Li   ///  - begin, end: The method list to output.
1146*67e74705SXin Li   ///
1147*67e74705SXin Li   /// The return value has type MethodDescriptionListPtrTy.
1148*67e74705SXin Li   llvm::Constant *EmitMethodDescList(Twine Name, StringRef Section,
1149*67e74705SXin Li                                      ArrayRef<llvm::Constant *> Methods);
1150*67e74705SXin Li 
1151*67e74705SXin Li   /// GetOrEmitProtocol - Get the protocol object for the given
1152*67e74705SXin Li   /// declaration, emitting it if necessary. The return value has type
1153*67e74705SXin Li   /// ProtocolPtrTy.
1154*67e74705SXin Li   llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1155*67e74705SXin Li 
1156*67e74705SXin Li   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1157*67e74705SXin Li   /// object for the given declaration, emitting it if needed. These
1158*67e74705SXin Li   /// forward references will be filled in with empty bodies if no
1159*67e74705SXin Li   /// definition is seen. The return value has type ProtocolPtrTy.
1160*67e74705SXin Li   llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1161*67e74705SXin Li 
1162*67e74705SXin Li   /// EmitProtocolExtension - Generate the protocol extension
1163*67e74705SXin Li   /// structure used to store optional instance and class methods, and
1164*67e74705SXin Li   /// protocol properties. The return value has type
1165*67e74705SXin Li   /// ProtocolExtensionPtrTy.
1166*67e74705SXin Li   llvm::Constant *
1167*67e74705SXin Li   EmitProtocolExtension(const ObjCProtocolDecl *PD,
1168*67e74705SXin Li                         ArrayRef<llvm::Constant*> OptInstanceMethods,
1169*67e74705SXin Li                         ArrayRef<llvm::Constant*> OptClassMethods,
1170*67e74705SXin Li                         ArrayRef<llvm::Constant*> MethodTypesExt);
1171*67e74705SXin Li 
1172*67e74705SXin Li   /// EmitProtocolList - Generate the list of referenced
1173*67e74705SXin Li   /// protocols. The return value has type ProtocolListPtrTy.
1174*67e74705SXin Li   llvm::Constant *EmitProtocolList(Twine Name,
1175*67e74705SXin Li                                    ObjCProtocolDecl::protocol_iterator begin,
1176*67e74705SXin Li                                    ObjCProtocolDecl::protocol_iterator end);
1177*67e74705SXin Li 
1178*67e74705SXin Li   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1179*67e74705SXin Li   /// for the given selector.
1180*67e74705SXin Li   llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1181*67e74705SXin Li   Address EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel);
1182*67e74705SXin Li 
1183*67e74705SXin Li public:
1184*67e74705SXin Li   CGObjCMac(CodeGen::CodeGenModule &cgm);
1185*67e74705SXin Li 
1186*67e74705SXin Li   llvm::Function *ModuleInitFunction() override;
1187*67e74705SXin Li 
1188*67e74705SXin Li   CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1189*67e74705SXin Li                                       ReturnValueSlot Return,
1190*67e74705SXin Li                                       QualType ResultType,
1191*67e74705SXin Li                                       Selector Sel, llvm::Value *Receiver,
1192*67e74705SXin Li                                       const CallArgList &CallArgs,
1193*67e74705SXin Li                                       const ObjCInterfaceDecl *Class,
1194*67e74705SXin Li                                       const ObjCMethodDecl *Method) override;
1195*67e74705SXin Li 
1196*67e74705SXin Li   CodeGen::RValue
1197*67e74705SXin Li   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1198*67e74705SXin Li                            ReturnValueSlot Return, QualType ResultType,
1199*67e74705SXin Li                            Selector Sel, const ObjCInterfaceDecl *Class,
1200*67e74705SXin Li                            bool isCategoryImpl, llvm::Value *Receiver,
1201*67e74705SXin Li                            bool IsClassMessage, const CallArgList &CallArgs,
1202*67e74705SXin Li                            const ObjCMethodDecl *Method) override;
1203*67e74705SXin Li 
1204*67e74705SXin Li   llvm::Value *GetClass(CodeGenFunction &CGF,
1205*67e74705SXin Li                         const ObjCInterfaceDecl *ID) override;
1206*67e74705SXin Li 
1207*67e74705SXin Li   llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override;
1208*67e74705SXin Li   Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override;
1209*67e74705SXin Li 
1210*67e74705SXin Li   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1211*67e74705SXin Li   /// untyped one.
1212*67e74705SXin Li   llvm::Value *GetSelector(CodeGenFunction &CGF,
1213*67e74705SXin Li                            const ObjCMethodDecl *Method) override;
1214*67e74705SXin Li 
1215*67e74705SXin Li   llvm::Constant *GetEHType(QualType T) override;
1216*67e74705SXin Li 
1217*67e74705SXin Li   void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1218*67e74705SXin Li 
1219*67e74705SXin Li   void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1220*67e74705SXin Li 
RegisterAlias(const ObjCCompatibleAliasDecl * OAD)1221*67e74705SXin Li   void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1222*67e74705SXin Li 
1223*67e74705SXin Li   llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1224*67e74705SXin Li                                    const ObjCProtocolDecl *PD) override;
1225*67e74705SXin Li 
1226*67e74705SXin Li   llvm::Constant *GetPropertyGetFunction() override;
1227*67e74705SXin Li   llvm::Constant *GetPropertySetFunction() override;
1228*67e74705SXin Li   llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1229*67e74705SXin Li                                                   bool copy) override;
1230*67e74705SXin Li   llvm::Constant *GetGetStructFunction() override;
1231*67e74705SXin Li   llvm::Constant *GetSetStructFunction() override;
1232*67e74705SXin Li   llvm::Constant *GetCppAtomicObjectGetFunction() override;
1233*67e74705SXin Li   llvm::Constant *GetCppAtomicObjectSetFunction() override;
1234*67e74705SXin Li   llvm::Constant *EnumerationMutationFunction() override;
1235*67e74705SXin Li 
1236*67e74705SXin Li   void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1237*67e74705SXin Li                    const ObjCAtTryStmt &S) override;
1238*67e74705SXin Li   void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1239*67e74705SXin Li                             const ObjCAtSynchronizedStmt &S) override;
1240*67e74705SXin Li   void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1241*67e74705SXin Li   void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1242*67e74705SXin Li                      bool ClearInsertionPoint=true) override;
1243*67e74705SXin Li   llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1244*67e74705SXin Li                                  Address AddrWeakObj) override;
1245*67e74705SXin Li   void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1246*67e74705SXin Li                           llvm::Value *src, Address dst) override;
1247*67e74705SXin Li   void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1248*67e74705SXin Li                             llvm::Value *src, Address dest,
1249*67e74705SXin Li                             bool threadlocal = false) override;
1250*67e74705SXin Li   void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1251*67e74705SXin Li                           llvm::Value *src, Address dest,
1252*67e74705SXin Li                           llvm::Value *ivarOffset) override;
1253*67e74705SXin Li   void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1254*67e74705SXin Li                                 llvm::Value *src, Address dest) override;
1255*67e74705SXin Li   void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1256*67e74705SXin Li                                 Address dest, Address src,
1257*67e74705SXin Li                                 llvm::Value *size) override;
1258*67e74705SXin Li 
1259*67e74705SXin Li   LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1260*67e74705SXin Li                               llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1261*67e74705SXin Li                               unsigned CVRQualifiers) override;
1262*67e74705SXin Li   llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1263*67e74705SXin Li                               const ObjCInterfaceDecl *Interface,
1264*67e74705SXin Li                               const ObjCIvarDecl *Ivar) override;
1265*67e74705SXin Li 
1266*67e74705SXin Li   /// GetClassGlobal - Return the global variable for the Objective-C
1267*67e74705SXin Li   /// class of the given name.
GetClassGlobal(StringRef Name,bool Weak=false)1268*67e74705SXin Li   llvm::GlobalVariable *GetClassGlobal(StringRef Name,
1269*67e74705SXin Li                                        bool Weak = false) override {
1270*67e74705SXin Li     llvm_unreachable("CGObjCMac::GetClassGlobal");
1271*67e74705SXin Li   }
1272*67e74705SXin Li };
1273*67e74705SXin Li 
1274*67e74705SXin Li class CGObjCNonFragileABIMac : public CGObjCCommonMac {
1275*67e74705SXin Li private:
1276*67e74705SXin Li   ObjCNonFragileABITypesHelper ObjCTypes;
1277*67e74705SXin Li   llvm::GlobalVariable* ObjCEmptyCacheVar;
1278*67e74705SXin Li   llvm::GlobalVariable* ObjCEmptyVtableVar;
1279*67e74705SXin Li 
1280*67e74705SXin Li   /// SuperClassReferences - uniqued super class references.
1281*67e74705SXin Li   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1282*67e74705SXin Li 
1283*67e74705SXin Li   /// MetaClassReferences - uniqued meta class references.
1284*67e74705SXin Li   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1285*67e74705SXin Li 
1286*67e74705SXin Li   /// EHTypeReferences - uniqued class ehtype references.
1287*67e74705SXin Li   llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1288*67e74705SXin Li 
1289*67e74705SXin Li   /// VTableDispatchMethods - List of methods for which we generate
1290*67e74705SXin Li   /// vtable-based message dispatch.
1291*67e74705SXin Li   llvm::DenseSet<Selector> VTableDispatchMethods;
1292*67e74705SXin Li 
1293*67e74705SXin Li   /// DefinedMetaClasses - List of defined meta-classes.
1294*67e74705SXin Li   std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1295*67e74705SXin Li 
1296*67e74705SXin Li   /// isVTableDispatchedSelector - Returns true if SEL is a
1297*67e74705SXin Li   /// vtable-based selector.
1298*67e74705SXin Li   bool isVTableDispatchedSelector(Selector Sel);
1299*67e74705SXin Li 
1300*67e74705SXin Li   /// FinishNonFragileABIModule - Write out global data structures at the end of
1301*67e74705SXin Li   /// processing a translation unit.
1302*67e74705SXin Li   void FinishNonFragileABIModule();
1303*67e74705SXin Li 
1304*67e74705SXin Li   /// AddModuleClassList - Add the given list of class pointers to the
1305*67e74705SXin Li   /// module with the provided symbol and section names.
1306*67e74705SXin Li   void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,
1307*67e74705SXin Li                           StringRef SymbolName, StringRef SectionName);
1308*67e74705SXin Li 
1309*67e74705SXin Li   llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1310*67e74705SXin Li                                               unsigned InstanceStart,
1311*67e74705SXin Li                                               unsigned InstanceSize,
1312*67e74705SXin Li                                               const ObjCImplementationDecl *ID);
1313*67e74705SXin Li   llvm::GlobalVariable * BuildClassMetaData(const std::string &ClassName,
1314*67e74705SXin Li                                             llvm::Constant *IsAGV,
1315*67e74705SXin Li                                             llvm::Constant *SuperClassGV,
1316*67e74705SXin Li                                             llvm::Constant *ClassRoGV,
1317*67e74705SXin Li                                             bool HiddenVisibility,
1318*67e74705SXin Li                                             bool Weak);
1319*67e74705SXin Li 
1320*67e74705SXin Li   llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1321*67e74705SXin Li 
1322*67e74705SXin Li   llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1323*67e74705SXin Li 
1324*67e74705SXin Li   /// EmitMethodList - Emit the method list for the given
1325*67e74705SXin Li   /// implementation. The return value has type MethodListnfABITy.
1326*67e74705SXin Li   llvm::Constant *EmitMethodList(Twine Name, StringRef Section,
1327*67e74705SXin Li                                  ArrayRef<llvm::Constant *> Methods);
1328*67e74705SXin Li   /// EmitIvarList - Emit the ivar list for the given
1329*67e74705SXin Li   /// implementation. If ForClass is true the list of class ivars
1330*67e74705SXin Li   /// (i.e. metaclass ivars) is emitted, otherwise the list of
1331*67e74705SXin Li   /// interface ivars will be emitted. The return value has type
1332*67e74705SXin Li   /// IvarListnfABIPtrTy.
1333*67e74705SXin Li   llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1334*67e74705SXin Li 
1335*67e74705SXin Li   llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1336*67e74705SXin Li                                     const ObjCIvarDecl *Ivar,
1337*67e74705SXin Li                                     unsigned long int offset);
1338*67e74705SXin Li 
1339*67e74705SXin Li   /// GetOrEmitProtocol - Get the protocol object for the given
1340*67e74705SXin Li   /// declaration, emitting it if necessary. The return value has type
1341*67e74705SXin Li   /// ProtocolPtrTy.
1342*67e74705SXin Li   llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1343*67e74705SXin Li 
1344*67e74705SXin Li   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1345*67e74705SXin Li   /// object for the given declaration, emitting it if needed. These
1346*67e74705SXin Li   /// forward references will be filled in with empty bodies if no
1347*67e74705SXin Li   /// definition is seen. The return value has type ProtocolPtrTy.
1348*67e74705SXin Li   llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1349*67e74705SXin Li 
1350*67e74705SXin Li   /// EmitProtocolList - Generate the list of referenced
1351*67e74705SXin Li   /// protocols. The return value has type ProtocolListPtrTy.
1352*67e74705SXin Li   llvm::Constant *EmitProtocolList(Twine Name,
1353*67e74705SXin Li                                    ObjCProtocolDecl::protocol_iterator begin,
1354*67e74705SXin Li                                    ObjCProtocolDecl::protocol_iterator end);
1355*67e74705SXin Li 
1356*67e74705SXin Li   CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1357*67e74705SXin Li                                         ReturnValueSlot Return,
1358*67e74705SXin Li                                         QualType ResultType,
1359*67e74705SXin Li                                         Selector Sel,
1360*67e74705SXin Li                                         llvm::Value *Receiver,
1361*67e74705SXin Li                                         QualType Arg0Ty,
1362*67e74705SXin Li                                         bool IsSuper,
1363*67e74705SXin Li                                         const CallArgList &CallArgs,
1364*67e74705SXin Li                                         const ObjCMethodDecl *Method);
1365*67e74705SXin Li 
1366*67e74705SXin Li   /// GetClassGlobal - Return the global variable for the Objective-C
1367*67e74705SXin Li   /// class of the given name.
1368*67e74705SXin Li   llvm::GlobalVariable *GetClassGlobal(StringRef Name,
1369*67e74705SXin Li                                        bool Weak = false) override;
1370*67e74705SXin Li 
1371*67e74705SXin Li   /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1372*67e74705SXin Li   /// for the given class reference.
1373*67e74705SXin Li   llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1374*67e74705SXin Li                             const ObjCInterfaceDecl *ID);
1375*67e74705SXin Li 
1376*67e74705SXin Li   llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1377*67e74705SXin Li                                   IdentifierInfo *II, bool Weak,
1378*67e74705SXin Li                                   const ObjCInterfaceDecl *ID);
1379*67e74705SXin Li 
1380*67e74705SXin Li   llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1381*67e74705SXin Li 
1382*67e74705SXin Li   /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1383*67e74705SXin Li   /// for the given super class reference.
1384*67e74705SXin Li   llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1385*67e74705SXin Li                                  const ObjCInterfaceDecl *ID);
1386*67e74705SXin Li 
1387*67e74705SXin Li   /// EmitMetaClassRef - Return a Value * of the address of _class_t
1388*67e74705SXin Li   /// meta-data
1389*67e74705SXin Li   llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1390*67e74705SXin Li                                 const ObjCInterfaceDecl *ID, bool Weak);
1391*67e74705SXin Li 
1392*67e74705SXin Li   /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1393*67e74705SXin Li   /// the given ivar.
1394*67e74705SXin Li   ///
1395*67e74705SXin Li   llvm::GlobalVariable * ObjCIvarOffsetVariable(
1396*67e74705SXin Li     const ObjCInterfaceDecl *ID,
1397*67e74705SXin Li     const ObjCIvarDecl *Ivar);
1398*67e74705SXin Li 
1399*67e74705SXin Li   /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1400*67e74705SXin Li   /// for the given selector.
1401*67e74705SXin Li   llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1402*67e74705SXin Li   Address EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel);
1403*67e74705SXin Li 
1404*67e74705SXin Li   /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1405*67e74705SXin Li   /// interface. The return value has type EHTypePtrTy.
1406*67e74705SXin Li   llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1407*67e74705SXin Li                                   bool ForDefinition);
1408*67e74705SXin Li 
getMetaclassSymbolPrefix() const1409*67e74705SXin Li   StringRef getMetaclassSymbolPrefix() const { return "OBJC_METACLASS_$_"; }
1410*67e74705SXin Li 
getClassSymbolPrefix() const1411*67e74705SXin Li   StringRef getClassSymbolPrefix() const { return "OBJC_CLASS_$_"; }
1412*67e74705SXin Li 
1413*67e74705SXin Li   void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1414*67e74705SXin Li                         uint32_t &InstanceStart,
1415*67e74705SXin Li                         uint32_t &InstanceSize);
1416*67e74705SXin Li 
1417*67e74705SXin Li   // Shamelessly stolen from Analysis/CFRefCount.cpp
GetNullarySelector(const char * name) const1418*67e74705SXin Li   Selector GetNullarySelector(const char* name) const {
1419*67e74705SXin Li     IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1420*67e74705SXin Li     return CGM.getContext().Selectors.getSelector(0, &II);
1421*67e74705SXin Li   }
1422*67e74705SXin Li 
GetUnarySelector(const char * name) const1423*67e74705SXin Li   Selector GetUnarySelector(const char* name) const {
1424*67e74705SXin Li     IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1425*67e74705SXin Li     return CGM.getContext().Selectors.getSelector(1, &II);
1426*67e74705SXin Li   }
1427*67e74705SXin Li 
1428*67e74705SXin Li   /// ImplementationIsNonLazy - Check whether the given category or
1429*67e74705SXin Li   /// class implementation is "non-lazy".
1430*67e74705SXin Li   bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1431*67e74705SXin Li 
IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction & CGF,const ObjCIvarDecl * IV)1432*67e74705SXin Li   bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
1433*67e74705SXin Li                                    const ObjCIvarDecl *IV) {
1434*67e74705SXin Li     // Annotate the load as an invariant load iff inside an instance method
1435*67e74705SXin Li     // and ivar belongs to instance method's class and one of its super class.
1436*67e74705SXin Li     // This check is needed because the ivar offset is a lazily
1437*67e74705SXin Li     // initialised value that may depend on objc_msgSend to perform a fixup on
1438*67e74705SXin Li     // the first message dispatch.
1439*67e74705SXin Li     //
1440*67e74705SXin Li     // An additional opportunity to mark the load as invariant arises when the
1441*67e74705SXin Li     // base of the ivar access is a parameter to an Objective C method.
1442*67e74705SXin Li     // However, because the parameters are not available in the current
1443*67e74705SXin Li     // interface, we cannot perform this check.
1444*67e74705SXin Li     if (const ObjCMethodDecl *MD =
1445*67e74705SXin Li           dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
1446*67e74705SXin Li       if (MD->isInstanceMethod())
1447*67e74705SXin Li         if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
1448*67e74705SXin Li           return IV->getContainingInterface()->isSuperClassOf(ID);
1449*67e74705SXin Li     return false;
1450*67e74705SXin Li   }
1451*67e74705SXin Li 
1452*67e74705SXin Li public:
1453*67e74705SXin Li   CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1454*67e74705SXin Li   // FIXME. All stubs for now!
1455*67e74705SXin Li   llvm::Function *ModuleInitFunction() override;
1456*67e74705SXin Li 
1457*67e74705SXin Li   CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1458*67e74705SXin Li                                       ReturnValueSlot Return,
1459*67e74705SXin Li                                       QualType ResultType, Selector Sel,
1460*67e74705SXin Li                                       llvm::Value *Receiver,
1461*67e74705SXin Li                                       const CallArgList &CallArgs,
1462*67e74705SXin Li                                       const ObjCInterfaceDecl *Class,
1463*67e74705SXin Li                                       const ObjCMethodDecl *Method) override;
1464*67e74705SXin Li 
1465*67e74705SXin Li   CodeGen::RValue
1466*67e74705SXin Li   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1467*67e74705SXin Li                            ReturnValueSlot Return, QualType ResultType,
1468*67e74705SXin Li                            Selector Sel, const ObjCInterfaceDecl *Class,
1469*67e74705SXin Li                            bool isCategoryImpl, llvm::Value *Receiver,
1470*67e74705SXin Li                            bool IsClassMessage, const CallArgList &CallArgs,
1471*67e74705SXin Li                            const ObjCMethodDecl *Method) override;
1472*67e74705SXin Li 
1473*67e74705SXin Li   llvm::Value *GetClass(CodeGenFunction &CGF,
1474*67e74705SXin Li                         const ObjCInterfaceDecl *ID) override;
1475*67e74705SXin Li 
GetSelector(CodeGenFunction & CGF,Selector Sel)1476*67e74705SXin Li   llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override
1477*67e74705SXin Li     { return EmitSelector(CGF, Sel); }
GetAddrOfSelector(CodeGenFunction & CGF,Selector Sel)1478*67e74705SXin Li   Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override
1479*67e74705SXin Li     { return EmitSelectorAddr(CGF, Sel); }
1480*67e74705SXin Li 
1481*67e74705SXin Li   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1482*67e74705SXin Li   /// untyped one.
GetSelector(CodeGenFunction & CGF,const ObjCMethodDecl * Method)1483*67e74705SXin Li   llvm::Value *GetSelector(CodeGenFunction &CGF,
1484*67e74705SXin Li                            const ObjCMethodDecl *Method) override
1485*67e74705SXin Li     { return EmitSelector(CGF, Method->getSelector()); }
1486*67e74705SXin Li 
1487*67e74705SXin Li   void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1488*67e74705SXin Li 
1489*67e74705SXin Li   void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1490*67e74705SXin Li 
RegisterAlias(const ObjCCompatibleAliasDecl * OAD)1491*67e74705SXin Li   void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1492*67e74705SXin Li 
1493*67e74705SXin Li   llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1494*67e74705SXin Li                                    const ObjCProtocolDecl *PD) override;
1495*67e74705SXin Li 
1496*67e74705SXin Li   llvm::Constant *GetEHType(QualType T) override;
1497*67e74705SXin Li 
GetPropertyGetFunction()1498*67e74705SXin Li   llvm::Constant *GetPropertyGetFunction() override {
1499*67e74705SXin Li     return ObjCTypes.getGetPropertyFn();
1500*67e74705SXin Li   }
GetPropertySetFunction()1501*67e74705SXin Li   llvm::Constant *GetPropertySetFunction() override {
1502*67e74705SXin Li     return ObjCTypes.getSetPropertyFn();
1503*67e74705SXin Li   }
1504*67e74705SXin Li 
GetOptimizedPropertySetFunction(bool atomic,bool copy)1505*67e74705SXin Li   llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1506*67e74705SXin Li                                                   bool copy) override {
1507*67e74705SXin Li     return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1508*67e74705SXin Li   }
1509*67e74705SXin Li 
GetSetStructFunction()1510*67e74705SXin Li   llvm::Constant *GetSetStructFunction() override {
1511*67e74705SXin Li     return ObjCTypes.getCopyStructFn();
1512*67e74705SXin Li   }
1513*67e74705SXin Li 
GetGetStructFunction()1514*67e74705SXin Li   llvm::Constant *GetGetStructFunction() override {
1515*67e74705SXin Li     return ObjCTypes.getCopyStructFn();
1516*67e74705SXin Li   }
1517*67e74705SXin Li 
GetCppAtomicObjectSetFunction()1518*67e74705SXin Li   llvm::Constant *GetCppAtomicObjectSetFunction() override {
1519*67e74705SXin Li     return ObjCTypes.getCppAtomicObjectFunction();
1520*67e74705SXin Li   }
1521*67e74705SXin Li 
GetCppAtomicObjectGetFunction()1522*67e74705SXin Li   llvm::Constant *GetCppAtomicObjectGetFunction() override {
1523*67e74705SXin Li     return ObjCTypes.getCppAtomicObjectFunction();
1524*67e74705SXin Li   }
1525*67e74705SXin Li 
EnumerationMutationFunction()1526*67e74705SXin Li   llvm::Constant *EnumerationMutationFunction() override {
1527*67e74705SXin Li     return ObjCTypes.getEnumerationMutationFn();
1528*67e74705SXin Li   }
1529*67e74705SXin Li 
1530*67e74705SXin Li   void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1531*67e74705SXin Li                    const ObjCAtTryStmt &S) override;
1532*67e74705SXin Li   void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1533*67e74705SXin Li                             const ObjCAtSynchronizedStmt &S) override;
1534*67e74705SXin Li   void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1535*67e74705SXin Li                      bool ClearInsertionPoint=true) override;
1536*67e74705SXin Li   llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1537*67e74705SXin Li                                  Address AddrWeakObj) override;
1538*67e74705SXin Li   void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1539*67e74705SXin Li                           llvm::Value *src, Address edst) override;
1540*67e74705SXin Li   void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1541*67e74705SXin Li                             llvm::Value *src, Address dest,
1542*67e74705SXin Li                             bool threadlocal = false) override;
1543*67e74705SXin Li   void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1544*67e74705SXin Li                           llvm::Value *src, Address dest,
1545*67e74705SXin Li                           llvm::Value *ivarOffset) override;
1546*67e74705SXin Li   void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1547*67e74705SXin Li                                 llvm::Value *src, Address dest) override;
1548*67e74705SXin Li   void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1549*67e74705SXin Li                                 Address dest, Address src,
1550*67e74705SXin Li                                 llvm::Value *size) override;
1551*67e74705SXin Li   LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1552*67e74705SXin Li                               llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1553*67e74705SXin Li                               unsigned CVRQualifiers) override;
1554*67e74705SXin Li   llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1555*67e74705SXin Li                               const ObjCInterfaceDecl *Interface,
1556*67e74705SXin Li                               const ObjCIvarDecl *Ivar) override;
1557*67e74705SXin Li };
1558*67e74705SXin Li 
1559*67e74705SXin Li /// A helper class for performing the null-initialization of a return
1560*67e74705SXin Li /// value.
1561*67e74705SXin Li struct NullReturnState {
1562*67e74705SXin Li   llvm::BasicBlock *NullBB;
NullReturnState__anon33e85b2f0111::NullReturnState1563*67e74705SXin Li   NullReturnState() : NullBB(nullptr) {}
1564*67e74705SXin Li 
1565*67e74705SXin Li   /// Perform a null-check of the given receiver.
init__anon33e85b2f0111::NullReturnState1566*67e74705SXin Li   void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1567*67e74705SXin Li     // Make blocks for the null-receiver and call edges.
1568*67e74705SXin Li     NullBB = CGF.createBasicBlock("msgSend.null-receiver");
1569*67e74705SXin Li     llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1570*67e74705SXin Li 
1571*67e74705SXin Li     // Check for a null receiver and, if there is one, jump to the
1572*67e74705SXin Li     // null-receiver block.  There's no point in trying to avoid it:
1573*67e74705SXin Li     // we're always going to put *something* there, because otherwise
1574*67e74705SXin Li     // we shouldn't have done this null-check in the first place.
1575*67e74705SXin Li     llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1576*67e74705SXin Li     CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1577*67e74705SXin Li 
1578*67e74705SXin Li     // Otherwise, start performing the call.
1579*67e74705SXin Li     CGF.EmitBlock(callBB);
1580*67e74705SXin Li   }
1581*67e74705SXin Li 
1582*67e74705SXin Li   /// Complete the null-return operation.  It is valid to call this
1583*67e74705SXin Li   /// regardless of whether 'init' has been called.
complete__anon33e85b2f0111::NullReturnState1584*67e74705SXin Li   RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
1585*67e74705SXin Li                   const CallArgList &CallArgs,
1586*67e74705SXin Li                   const ObjCMethodDecl *Method) {
1587*67e74705SXin Li     // If we never had to do a null-check, just use the raw result.
1588*67e74705SXin Li     if (!NullBB) return result;
1589*67e74705SXin Li 
1590*67e74705SXin Li     // The continuation block.  This will be left null if we don't have an
1591*67e74705SXin Li     // IP, which can happen if the method we're calling is marked noreturn.
1592*67e74705SXin Li     llvm::BasicBlock *contBB = nullptr;
1593*67e74705SXin Li 
1594*67e74705SXin Li     // Finish the call path.
1595*67e74705SXin Li     llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
1596*67e74705SXin Li     if (callBB) {
1597*67e74705SXin Li       contBB = CGF.createBasicBlock("msgSend.cont");
1598*67e74705SXin Li       CGF.Builder.CreateBr(contBB);
1599*67e74705SXin Li     }
1600*67e74705SXin Li 
1601*67e74705SXin Li     // Okay, start emitting the null-receiver block.
1602*67e74705SXin Li     CGF.EmitBlock(NullBB);
1603*67e74705SXin Li 
1604*67e74705SXin Li     // Release any consumed arguments we've got.
1605*67e74705SXin Li     if (Method) {
1606*67e74705SXin Li       CallArgList::const_iterator I = CallArgs.begin();
1607*67e74705SXin Li       for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1608*67e74705SXin Li            e = Method->param_end(); i != e; ++i, ++I) {
1609*67e74705SXin Li         const ParmVarDecl *ParamDecl = (*i);
1610*67e74705SXin Li         if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1611*67e74705SXin Li           RValue RV = I->RV;
1612*67e74705SXin Li           assert(RV.isScalar() &&
1613*67e74705SXin Li                  "NullReturnState::complete - arg not on object");
1614*67e74705SXin Li           CGF.EmitARCRelease(RV.getScalarVal(), ARCImpreciseLifetime);
1615*67e74705SXin Li         }
1616*67e74705SXin Li       }
1617*67e74705SXin Li     }
1618*67e74705SXin Li 
1619*67e74705SXin Li     // The phi code below assumes that we haven't needed any control flow yet.
1620*67e74705SXin Li     assert(CGF.Builder.GetInsertBlock() == NullBB);
1621*67e74705SXin Li 
1622*67e74705SXin Li     // If we've got a void return, just jump to the continuation block.
1623*67e74705SXin Li     if (result.isScalar() && resultType->isVoidType()) {
1624*67e74705SXin Li       // No jumps required if the message-send was noreturn.
1625*67e74705SXin Li       if (contBB) CGF.EmitBlock(contBB);
1626*67e74705SXin Li       return result;
1627*67e74705SXin Li     }
1628*67e74705SXin Li 
1629*67e74705SXin Li     // If we've got a scalar return, build a phi.
1630*67e74705SXin Li     if (result.isScalar()) {
1631*67e74705SXin Li       // Derive the null-initialization value.
1632*67e74705SXin Li       llvm::Constant *null = CGF.CGM.EmitNullConstant(resultType);
1633*67e74705SXin Li 
1634*67e74705SXin Li       // If no join is necessary, just flow out.
1635*67e74705SXin Li       if (!contBB) return RValue::get(null);
1636*67e74705SXin Li 
1637*67e74705SXin Li       // Otherwise, build a phi.
1638*67e74705SXin Li       CGF.EmitBlock(contBB);
1639*67e74705SXin Li       llvm::PHINode *phi = CGF.Builder.CreatePHI(null->getType(), 2);
1640*67e74705SXin Li       phi->addIncoming(result.getScalarVal(), callBB);
1641*67e74705SXin Li       phi->addIncoming(null, NullBB);
1642*67e74705SXin Li       return RValue::get(phi);
1643*67e74705SXin Li     }
1644*67e74705SXin Li 
1645*67e74705SXin Li     // If we've got an aggregate return, null the buffer out.
1646*67e74705SXin Li     // FIXME: maybe we should be doing things differently for all the
1647*67e74705SXin Li     // cases where the ABI has us returning (1) non-agg values in
1648*67e74705SXin Li     // memory or (2) agg values in registers.
1649*67e74705SXin Li     if (result.isAggregate()) {
1650*67e74705SXin Li       assert(result.isAggregate() && "null init of non-aggregate result?");
1651*67e74705SXin Li       CGF.EmitNullInitialization(result.getAggregateAddress(), resultType);
1652*67e74705SXin Li       if (contBB) CGF.EmitBlock(contBB);
1653*67e74705SXin Li       return result;
1654*67e74705SXin Li     }
1655*67e74705SXin Li 
1656*67e74705SXin Li     // Complex types.
1657*67e74705SXin Li     CGF.EmitBlock(contBB);
1658*67e74705SXin Li     CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();
1659*67e74705SXin Li 
1660*67e74705SXin Li     // Find the scalar type and its zero value.
1661*67e74705SXin Li     llvm::Type *scalarTy = callResult.first->getType();
1662*67e74705SXin Li     llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1663*67e74705SXin Li 
1664*67e74705SXin Li     // Build phis for both coordinates.
1665*67e74705SXin Li     llvm::PHINode *real = CGF.Builder.CreatePHI(scalarTy, 2);
1666*67e74705SXin Li     real->addIncoming(callResult.first, callBB);
1667*67e74705SXin Li     real->addIncoming(scalarZero, NullBB);
1668*67e74705SXin Li     llvm::PHINode *imag = CGF.Builder.CreatePHI(scalarTy, 2);
1669*67e74705SXin Li     imag->addIncoming(callResult.second, callBB);
1670*67e74705SXin Li     imag->addIncoming(scalarZero, NullBB);
1671*67e74705SXin Li     return RValue::getComplex(real, imag);
1672*67e74705SXin Li   }
1673*67e74705SXin Li };
1674*67e74705SXin Li 
1675*67e74705SXin Li } // end anonymous namespace
1676*67e74705SXin Li 
1677*67e74705SXin Li /* *** Helper Functions *** */
1678*67e74705SXin Li 
1679*67e74705SXin Li /// getConstantGEP() - Help routine to construct simple GEPs.
getConstantGEP(llvm::LLVMContext & VMContext,llvm::GlobalVariable * C,unsigned idx0,unsigned idx1)1680*67e74705SXin Li static llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1681*67e74705SXin Li                                       llvm::GlobalVariable *C, unsigned idx0,
1682*67e74705SXin Li                                       unsigned idx1) {
1683*67e74705SXin Li   llvm::Value *Idxs[] = {
1684*67e74705SXin Li     llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1685*67e74705SXin Li     llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1686*67e74705SXin Li   };
1687*67e74705SXin Li   return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1688*67e74705SXin Li }
1689*67e74705SXin Li 
1690*67e74705SXin Li /// hasObjCExceptionAttribute - Return true if this class or any super
1691*67e74705SXin Li /// class has the __objc_exception__ attribute.
hasObjCExceptionAttribute(ASTContext & Context,const ObjCInterfaceDecl * OID)1692*67e74705SXin Li static bool hasObjCExceptionAttribute(ASTContext &Context,
1693*67e74705SXin Li                                       const ObjCInterfaceDecl *OID) {
1694*67e74705SXin Li   if (OID->hasAttr<ObjCExceptionAttr>())
1695*67e74705SXin Li     return true;
1696*67e74705SXin Li   if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1697*67e74705SXin Li     return hasObjCExceptionAttribute(Context, Super);
1698*67e74705SXin Li   return false;
1699*67e74705SXin Li }
1700*67e74705SXin Li 
1701*67e74705SXin Li /* *** CGObjCMac Public Interface *** */
1702*67e74705SXin Li 
CGObjCMac(CodeGen::CodeGenModule & cgm)1703*67e74705SXin Li CGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1704*67e74705SXin Li                                                     ObjCTypes(cgm) {
1705*67e74705SXin Li   ObjCABI = 1;
1706*67e74705SXin Li   EmitImageInfo();
1707*67e74705SXin Li }
1708*67e74705SXin Li 
1709*67e74705SXin Li /// GetClass - Return a reference to the class for the given interface
1710*67e74705SXin Li /// decl.
GetClass(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)1711*67e74705SXin Li llvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
1712*67e74705SXin Li                                  const ObjCInterfaceDecl *ID) {
1713*67e74705SXin Li   return EmitClassRef(CGF, ID);
1714*67e74705SXin Li }
1715*67e74705SXin Li 
1716*67e74705SXin Li /// GetSelector - Return the pointer to the unique'd string for this selector.
GetSelector(CodeGenFunction & CGF,Selector Sel)1717*67e74705SXin Li llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
1718*67e74705SXin Li   return EmitSelector(CGF, Sel);
1719*67e74705SXin Li }
GetAddrOfSelector(CodeGenFunction & CGF,Selector Sel)1720*67e74705SXin Li Address CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
1721*67e74705SXin Li   return EmitSelectorAddr(CGF, Sel);
1722*67e74705SXin Li }
GetSelector(CodeGenFunction & CGF,const ObjCMethodDecl * Method)1723*67e74705SXin Li llvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
1724*67e74705SXin Li                                     *Method) {
1725*67e74705SXin Li   return EmitSelector(CGF, Method->getSelector());
1726*67e74705SXin Li }
1727*67e74705SXin Li 
GetEHType(QualType T)1728*67e74705SXin Li llvm::Constant *CGObjCMac::GetEHType(QualType T) {
1729*67e74705SXin Li   if (T->isObjCIdType() ||
1730*67e74705SXin Li       T->isObjCQualifiedIdType()) {
1731*67e74705SXin Li     return CGM.GetAddrOfRTTIDescriptor(
1732*67e74705SXin Li               CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1733*67e74705SXin Li   }
1734*67e74705SXin Li   if (T->isObjCClassType() ||
1735*67e74705SXin Li       T->isObjCQualifiedClassType()) {
1736*67e74705SXin Li     return CGM.GetAddrOfRTTIDescriptor(
1737*67e74705SXin Li              CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1738*67e74705SXin Li   }
1739*67e74705SXin Li   if (T->isObjCObjectPointerType())
1740*67e74705SXin Li     return CGM.GetAddrOfRTTIDescriptor(T,  /*ForEH=*/true);
1741*67e74705SXin Li 
1742*67e74705SXin Li   llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1743*67e74705SXin Li }
1744*67e74705SXin Li 
1745*67e74705SXin Li /// Generate a constant CFString object.
1746*67e74705SXin Li /*
1747*67e74705SXin Li   struct __builtin_CFString {
1748*67e74705SXin Li   const int *isa; // point to __CFConstantStringClassReference
1749*67e74705SXin Li   int flags;
1750*67e74705SXin Li   const char *str;
1751*67e74705SXin Li   long length;
1752*67e74705SXin Li   };
1753*67e74705SXin Li */
1754*67e74705SXin Li 
1755*67e74705SXin Li /// or Generate a constant NSString object.
1756*67e74705SXin Li /*
1757*67e74705SXin Li    struct __builtin_NSString {
1758*67e74705SXin Li      const int *isa; // point to __NSConstantStringClassReference
1759*67e74705SXin Li      const char *str;
1760*67e74705SXin Li      unsigned int length;
1761*67e74705SXin Li    };
1762*67e74705SXin Li */
1763*67e74705SXin Li 
GenerateConstantString(const StringLiteral * SL)1764*67e74705SXin Li ConstantAddress CGObjCCommonMac::GenerateConstantString(
1765*67e74705SXin Li   const StringLiteral *SL) {
1766*67e74705SXin Li   return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1767*67e74705SXin Li           CGM.GetAddrOfConstantCFString(SL) :
1768*67e74705SXin Li           CGM.GetAddrOfConstantString(SL));
1769*67e74705SXin Li }
1770*67e74705SXin Li 
1771*67e74705SXin Li enum {
1772*67e74705SXin Li   kCFTaggedObjectID_Integer = (1 << 1) + 1
1773*67e74705SXin Li };
1774*67e74705SXin Li 
1775*67e74705SXin Li /// Generates a message send where the super is the receiver.  This is
1776*67e74705SXin Li /// a message send to self with special delivery semantics indicating
1777*67e74705SXin Li /// which class's method should be called.
1778*67e74705SXin Li CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,const ObjCInterfaceDecl * Class,bool isCategoryImpl,llvm::Value * Receiver,bool IsClassMessage,const CodeGen::CallArgList & CallArgs,const ObjCMethodDecl * Method)1779*67e74705SXin Li CGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1780*67e74705SXin Li                                     ReturnValueSlot Return,
1781*67e74705SXin Li                                     QualType ResultType,
1782*67e74705SXin Li                                     Selector Sel,
1783*67e74705SXin Li                                     const ObjCInterfaceDecl *Class,
1784*67e74705SXin Li                                     bool isCategoryImpl,
1785*67e74705SXin Li                                     llvm::Value *Receiver,
1786*67e74705SXin Li                                     bool IsClassMessage,
1787*67e74705SXin Li                                     const CodeGen::CallArgList &CallArgs,
1788*67e74705SXin Li                                     const ObjCMethodDecl *Method) {
1789*67e74705SXin Li   // Create and init a super structure; this is a (receiver, class)
1790*67e74705SXin Li   // pair we will pass to objc_msgSendSuper.
1791*67e74705SXin Li   Address ObjCSuper =
1792*67e74705SXin Li     CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(),
1793*67e74705SXin Li                          "objc_super");
1794*67e74705SXin Li   llvm::Value *ReceiverAsObject =
1795*67e74705SXin Li     CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1796*67e74705SXin Li   CGF.Builder.CreateStore(
1797*67e74705SXin Li       ReceiverAsObject,
1798*67e74705SXin Li       CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
1799*67e74705SXin Li 
1800*67e74705SXin Li   // If this is a class message the metaclass is passed as the target.
1801*67e74705SXin Li   llvm::Value *Target;
1802*67e74705SXin Li   if (IsClassMessage) {
1803*67e74705SXin Li     if (isCategoryImpl) {
1804*67e74705SXin Li       // Message sent to 'super' in a class method defined in a category
1805*67e74705SXin Li       // implementation requires an odd treatment.
1806*67e74705SXin Li       // If we are in a class method, we must retrieve the
1807*67e74705SXin Li       // _metaclass_ for the current class, pointed at by
1808*67e74705SXin Li       // the class's "isa" pointer.  The following assumes that
1809*67e74705SXin Li       // isa" is the first ivar in a class (which it must be).
1810*67e74705SXin Li       Target = EmitClassRef(CGF, Class->getSuperClass());
1811*67e74705SXin Li       Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0);
1812*67e74705SXin Li       Target = CGF.Builder.CreateAlignedLoad(Target, CGF.getPointerAlign());
1813*67e74705SXin Li     } else {
1814*67e74705SXin Li       llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
1815*67e74705SXin Li       llvm::Value *SuperPtr =
1816*67e74705SXin Li           CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1);
1817*67e74705SXin Li       llvm::Value *Super =
1818*67e74705SXin Li         CGF.Builder.CreateAlignedLoad(SuperPtr, CGF.getPointerAlign());
1819*67e74705SXin Li       Target = Super;
1820*67e74705SXin Li     }
1821*67e74705SXin Li   } else if (isCategoryImpl)
1822*67e74705SXin Li     Target = EmitClassRef(CGF, Class->getSuperClass());
1823*67e74705SXin Li   else {
1824*67e74705SXin Li     llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1825*67e74705SXin Li     ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1);
1826*67e74705SXin Li     Target = CGF.Builder.CreateAlignedLoad(ClassPtr, CGF.getPointerAlign());
1827*67e74705SXin Li   }
1828*67e74705SXin Li   // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1829*67e74705SXin Li   // ObjCTypes types.
1830*67e74705SXin Li   llvm::Type *ClassTy =
1831*67e74705SXin Li     CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1832*67e74705SXin Li   Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1833*67e74705SXin Li   CGF.Builder.CreateStore(Target,
1834*67e74705SXin Li           CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
1835*67e74705SXin Li   return EmitMessageSend(CGF, Return, ResultType,
1836*67e74705SXin Li                          EmitSelector(CGF, Sel),
1837*67e74705SXin Li                          ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
1838*67e74705SXin Li                          true, CallArgs, Method, Class, ObjCTypes);
1839*67e74705SXin Li }
1840*67e74705SXin Li 
1841*67e74705SXin Li /// Generate code for a message send expression.
GenerateMessageSend(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,llvm::Value * Receiver,const CallArgList & CallArgs,const ObjCInterfaceDecl * Class,const ObjCMethodDecl * Method)1842*67e74705SXin Li CodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1843*67e74705SXin Li                                                ReturnValueSlot Return,
1844*67e74705SXin Li                                                QualType ResultType,
1845*67e74705SXin Li                                                Selector Sel,
1846*67e74705SXin Li                                                llvm::Value *Receiver,
1847*67e74705SXin Li                                                const CallArgList &CallArgs,
1848*67e74705SXin Li                                                const ObjCInterfaceDecl *Class,
1849*67e74705SXin Li                                                const ObjCMethodDecl *Method) {
1850*67e74705SXin Li   return EmitMessageSend(CGF, Return, ResultType,
1851*67e74705SXin Li                          EmitSelector(CGF, Sel),
1852*67e74705SXin Li                          Receiver, CGF.getContext().getObjCIdType(),
1853*67e74705SXin Li                          false, CallArgs, Method, Class, ObjCTypes);
1854*67e74705SXin Li }
1855*67e74705SXin Li 
isWeakLinkedClass(const ObjCInterfaceDecl * ID)1856*67e74705SXin Li static bool isWeakLinkedClass(const ObjCInterfaceDecl *ID) {
1857*67e74705SXin Li   do {
1858*67e74705SXin Li     if (ID->isWeakImported())
1859*67e74705SXin Li       return true;
1860*67e74705SXin Li   } while ((ID = ID->getSuperClass()));
1861*67e74705SXin Li 
1862*67e74705SXin Li   return false;
1863*67e74705SXin Li }
1864*67e74705SXin Li 
1865*67e74705SXin Li CodeGen::RValue
EmitMessageSend(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,llvm::Value * Sel,llvm::Value * Arg0,QualType Arg0Ty,bool IsSuper,const CallArgList & CallArgs,const ObjCMethodDecl * Method,const ObjCInterfaceDecl * ClassReceiver,const ObjCCommonTypesHelper & ObjCTypes)1866*67e74705SXin Li CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1867*67e74705SXin Li                                  ReturnValueSlot Return,
1868*67e74705SXin Li                                  QualType ResultType,
1869*67e74705SXin Li                                  llvm::Value *Sel,
1870*67e74705SXin Li                                  llvm::Value *Arg0,
1871*67e74705SXin Li                                  QualType Arg0Ty,
1872*67e74705SXin Li                                  bool IsSuper,
1873*67e74705SXin Li                                  const CallArgList &CallArgs,
1874*67e74705SXin Li                                  const ObjCMethodDecl *Method,
1875*67e74705SXin Li                                  const ObjCInterfaceDecl *ClassReceiver,
1876*67e74705SXin Li                                  const ObjCCommonTypesHelper &ObjCTypes) {
1877*67e74705SXin Li   CallArgList ActualArgs;
1878*67e74705SXin Li   if (!IsSuper)
1879*67e74705SXin Li     Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
1880*67e74705SXin Li   ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1881*67e74705SXin Li   ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1882*67e74705SXin Li   ActualArgs.addFrom(CallArgs);
1883*67e74705SXin Li 
1884*67e74705SXin Li   // If we're calling a method, use the formal signature.
1885*67e74705SXin Li   MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1886*67e74705SXin Li 
1887*67e74705SXin Li   if (Method)
1888*67e74705SXin Li     assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
1889*67e74705SXin Li                CGM.getContext().getCanonicalType(ResultType) &&
1890*67e74705SXin Li            "Result type mismatch!");
1891*67e74705SXin Li 
1892*67e74705SXin Li   bool ReceiverCanBeNull = true;
1893*67e74705SXin Li 
1894*67e74705SXin Li   // Super dispatch assumes that self is non-null; even the messenger
1895*67e74705SXin Li   // doesn't have a null check internally.
1896*67e74705SXin Li   if (IsSuper) {
1897*67e74705SXin Li     ReceiverCanBeNull = false;
1898*67e74705SXin Li 
1899*67e74705SXin Li   // If this is a direct dispatch of a class method, check whether the class,
1900*67e74705SXin Li   // or anything in its hierarchy, was weak-linked.
1901*67e74705SXin Li   } else if (ClassReceiver && Method && Method->isClassMethod()) {
1902*67e74705SXin Li     ReceiverCanBeNull = isWeakLinkedClass(ClassReceiver);
1903*67e74705SXin Li 
1904*67e74705SXin Li   // If we're emitting a method, and self is const (meaning just ARC, for now),
1905*67e74705SXin Li   // and the receiver is a load of self, then self is a valid object.
1906*67e74705SXin Li   } else if (auto CurMethod =
1907*67e74705SXin Li                dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl)) {
1908*67e74705SXin Li     auto Self = CurMethod->getSelfDecl();
1909*67e74705SXin Li     if (Self->getType().isConstQualified()) {
1910*67e74705SXin Li       if (auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
1911*67e74705SXin Li         llvm::Value *SelfAddr = CGF.GetAddrOfLocalVar(Self).getPointer();
1912*67e74705SXin Li         if (SelfAddr == LI->getPointerOperand()) {
1913*67e74705SXin Li           ReceiverCanBeNull = false;
1914*67e74705SXin Li         }
1915*67e74705SXin Li       }
1916*67e74705SXin Li     }
1917*67e74705SXin Li   }
1918*67e74705SXin Li 
1919*67e74705SXin Li   NullReturnState nullReturn;
1920*67e74705SXin Li 
1921*67e74705SXin Li   llvm::Constant *Fn = nullptr;
1922*67e74705SXin Li   if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
1923*67e74705SXin Li     if (ReceiverCanBeNull) nullReturn.init(CGF, Arg0);
1924*67e74705SXin Li     Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
1925*67e74705SXin Li       : ObjCTypes.getSendStretFn(IsSuper);
1926*67e74705SXin Li   } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1927*67e74705SXin Li     Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1928*67e74705SXin Li       : ObjCTypes.getSendFpretFn(IsSuper);
1929*67e74705SXin Li   } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1930*67e74705SXin Li     Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1931*67e74705SXin Li       : ObjCTypes.getSendFp2retFn(IsSuper);
1932*67e74705SXin Li   } else {
1933*67e74705SXin Li     // arm64 uses objc_msgSend for stret methods and yet null receiver check
1934*67e74705SXin Li     // must be made for it.
1935*67e74705SXin Li     if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
1936*67e74705SXin Li       nullReturn.init(CGF, Arg0);
1937*67e74705SXin Li     Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1938*67e74705SXin Li       : ObjCTypes.getSendFn(IsSuper);
1939*67e74705SXin Li   }
1940*67e74705SXin Li 
1941*67e74705SXin Li   // Emit a null-check if there's a consumed argument other than the receiver.
1942*67e74705SXin Li   bool RequiresNullCheck = false;
1943*67e74705SXin Li   if (ReceiverCanBeNull && CGM.getLangOpts().ObjCAutoRefCount && Method) {
1944*67e74705SXin Li     for (const auto *ParamDecl : Method->parameters()) {
1945*67e74705SXin Li       if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1946*67e74705SXin Li         if (!nullReturn.NullBB)
1947*67e74705SXin Li           nullReturn.init(CGF, Arg0);
1948*67e74705SXin Li         RequiresNullCheck = true;
1949*67e74705SXin Li         break;
1950*67e74705SXin Li       }
1951*67e74705SXin Li     }
1952*67e74705SXin Li   }
1953*67e74705SXin Li 
1954*67e74705SXin Li   llvm::Instruction *CallSite;
1955*67e74705SXin Li   Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1956*67e74705SXin Li   RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs,
1957*67e74705SXin Li                                CGCalleeInfo(), &CallSite);
1958*67e74705SXin Li 
1959*67e74705SXin Li   // Mark the call as noreturn if the method is marked noreturn and the
1960*67e74705SXin Li   // receiver cannot be null.
1961*67e74705SXin Li   if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
1962*67e74705SXin Li     llvm::CallSite(CallSite).setDoesNotReturn();
1963*67e74705SXin Li   }
1964*67e74705SXin Li 
1965*67e74705SXin Li   return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1966*67e74705SXin Li                              RequiresNullCheck ? Method : nullptr);
1967*67e74705SXin Li }
1968*67e74705SXin Li 
GetGCAttrTypeForType(ASTContext & Ctx,QualType FQT,bool pointee=false)1969*67e74705SXin Li static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT,
1970*67e74705SXin Li                                            bool pointee = false) {
1971*67e74705SXin Li   // Note that GC qualification applies recursively to C pointer types
1972*67e74705SXin Li   // that aren't otherwise decorated.  This is weird, but it's probably
1973*67e74705SXin Li   // an intentional workaround to the unreliable placement of GC qualifiers.
1974*67e74705SXin Li   if (FQT.isObjCGCStrong())
1975*67e74705SXin Li     return Qualifiers::Strong;
1976*67e74705SXin Li 
1977*67e74705SXin Li   if (FQT.isObjCGCWeak())
1978*67e74705SXin Li     return Qualifiers::Weak;
1979*67e74705SXin Li 
1980*67e74705SXin Li   if (auto ownership = FQT.getObjCLifetime()) {
1981*67e74705SXin Li     // Ownership does not apply recursively to C pointer types.
1982*67e74705SXin Li     if (pointee) return Qualifiers::GCNone;
1983*67e74705SXin Li     switch (ownership) {
1984*67e74705SXin Li     case Qualifiers::OCL_Weak: return Qualifiers::Weak;
1985*67e74705SXin Li     case Qualifiers::OCL_Strong: return Qualifiers::Strong;
1986*67e74705SXin Li     case Qualifiers::OCL_ExplicitNone: return Qualifiers::GCNone;
1987*67e74705SXin Li     case Qualifiers::OCL_Autoreleasing: llvm_unreachable("autoreleasing ivar?");
1988*67e74705SXin Li     case Qualifiers::OCL_None: llvm_unreachable("known nonzero");
1989*67e74705SXin Li     }
1990*67e74705SXin Li     llvm_unreachable("bad objc ownership");
1991*67e74705SXin Li   }
1992*67e74705SXin Li 
1993*67e74705SXin Li   // Treat unqualified retainable pointers as strong.
1994*67e74705SXin Li   if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1995*67e74705SXin Li     return Qualifiers::Strong;
1996*67e74705SXin Li 
1997*67e74705SXin Li   // Walk into C pointer types, but only in GC.
1998*67e74705SXin Li   if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) {
1999*67e74705SXin Li     if (const PointerType *PT = FQT->getAs<PointerType>())
2000*67e74705SXin Li       return GetGCAttrTypeForType(Ctx, PT->getPointeeType(), /*pointee*/ true);
2001*67e74705SXin Li   }
2002*67e74705SXin Li 
2003*67e74705SXin Li   return Qualifiers::GCNone;
2004*67e74705SXin Li }
2005*67e74705SXin Li 
2006*67e74705SXin Li namespace {
2007*67e74705SXin Li   struct IvarInfo {
2008*67e74705SXin Li     CharUnits Offset;
2009*67e74705SXin Li     uint64_t SizeInWords;
IvarInfo__anon33e85b2f0311::IvarInfo2010*67e74705SXin Li     IvarInfo(CharUnits offset, uint64_t sizeInWords)
2011*67e74705SXin Li       : Offset(offset), SizeInWords(sizeInWords) {}
2012*67e74705SXin Li 
2013*67e74705SXin Li     // Allow sorting based on byte pos.
operator <__anon33e85b2f0311::IvarInfo2014*67e74705SXin Li     bool operator<(const IvarInfo &other) const {
2015*67e74705SXin Li       return Offset < other.Offset;
2016*67e74705SXin Li     }
2017*67e74705SXin Li   };
2018*67e74705SXin Li 
2019*67e74705SXin Li   /// A helper class for building GC layout strings.
2020*67e74705SXin Li   class IvarLayoutBuilder {
2021*67e74705SXin Li     CodeGenModule &CGM;
2022*67e74705SXin Li 
2023*67e74705SXin Li     /// The start of the layout.  Offsets will be relative to this value,
2024*67e74705SXin Li     /// and entries less than this value will be silently discarded.
2025*67e74705SXin Li     CharUnits InstanceBegin;
2026*67e74705SXin Li 
2027*67e74705SXin Li     /// The end of the layout.  Offsets will never exceed this value.
2028*67e74705SXin Li     CharUnits InstanceEnd;
2029*67e74705SXin Li 
2030*67e74705SXin Li     /// Whether we're generating the strong layout or the weak layout.
2031*67e74705SXin Li     bool ForStrongLayout;
2032*67e74705SXin Li 
2033*67e74705SXin Li     /// Whether the offsets in IvarsInfo might be out-of-order.
2034*67e74705SXin Li     bool IsDisordered = false;
2035*67e74705SXin Li 
2036*67e74705SXin Li     llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2037*67e74705SXin Li 
2038*67e74705SXin Li   public:
IvarLayoutBuilder(CodeGenModule & CGM,CharUnits instanceBegin,CharUnits instanceEnd,bool forStrongLayout)2039*67e74705SXin Li     IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2040*67e74705SXin Li                       CharUnits instanceEnd, bool forStrongLayout)
2041*67e74705SXin Li       : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2042*67e74705SXin Li         ForStrongLayout(forStrongLayout) {
2043*67e74705SXin Li     }
2044*67e74705SXin Li 
2045*67e74705SXin Li     void visitRecord(const RecordType *RT, CharUnits offset);
2046*67e74705SXin Li 
2047*67e74705SXin Li     template <class Iterator, class GetOffsetFn>
2048*67e74705SXin Li     void visitAggregate(Iterator begin, Iterator end,
2049*67e74705SXin Li                         CharUnits aggrOffset,
2050*67e74705SXin Li                         const GetOffsetFn &getOffset);
2051*67e74705SXin Li 
2052*67e74705SXin Li     void visitField(const FieldDecl *field, CharUnits offset);
2053*67e74705SXin Li 
2054*67e74705SXin Li     /// Add the layout of a block implementation.
2055*67e74705SXin Li     void visitBlock(const CGBlockInfo &blockInfo);
2056*67e74705SXin Li 
2057*67e74705SXin Li     /// Is there any information for an interesting bitmap?
hasBitmapData() const2058*67e74705SXin Li     bool hasBitmapData() const { return !IvarsInfo.empty(); }
2059*67e74705SXin Li 
2060*67e74705SXin Li     llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2061*67e74705SXin Li                                 llvm::SmallVectorImpl<unsigned char> &buffer);
2062*67e74705SXin Li 
dump(ArrayRef<unsigned char> buffer)2063*67e74705SXin Li     static void dump(ArrayRef<unsigned char> buffer) {
2064*67e74705SXin Li       const unsigned char *s = buffer.data();
2065*67e74705SXin Li       for (unsigned i = 0, e = buffer.size(); i < e; i++)
2066*67e74705SXin Li         if (!(s[i] & 0xf0))
2067*67e74705SXin Li           printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2068*67e74705SXin Li         else
2069*67e74705SXin Li           printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
2070*67e74705SXin Li       printf("\n");
2071*67e74705SXin Li     }
2072*67e74705SXin Li   };
2073*67e74705SXin Li } // end anonymous namespace
2074*67e74705SXin Li 
BuildGCBlockLayout(CodeGenModule & CGM,const CGBlockInfo & blockInfo)2075*67e74705SXin Li llvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2076*67e74705SXin Li                                                 const CGBlockInfo &blockInfo) {
2077*67e74705SXin Li 
2078*67e74705SXin Li   llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2079*67e74705SXin Li   if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
2080*67e74705SXin Li     return nullPtr;
2081*67e74705SXin Li 
2082*67e74705SXin Li   IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,
2083*67e74705SXin Li                             /*for strong layout*/ true);
2084*67e74705SXin Li 
2085*67e74705SXin Li   builder.visitBlock(blockInfo);
2086*67e74705SXin Li 
2087*67e74705SXin Li   if (!builder.hasBitmapData())
2088*67e74705SXin Li     return nullPtr;
2089*67e74705SXin Li 
2090*67e74705SXin Li   llvm::SmallVector<unsigned char, 32> buffer;
2091*67e74705SXin Li   llvm::Constant *C = builder.buildBitmap(*this, buffer);
2092*67e74705SXin Li   if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2093*67e74705SXin Li     printf("\n block variable layout for block: ");
2094*67e74705SXin Li     builder.dump(buffer);
2095*67e74705SXin Li   }
2096*67e74705SXin Li 
2097*67e74705SXin Li   return C;
2098*67e74705SXin Li }
2099*67e74705SXin Li 
visitBlock(const CGBlockInfo & blockInfo)2100*67e74705SXin Li void IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {
2101*67e74705SXin Li   // __isa is the first field in block descriptor and must assume by runtime's
2102*67e74705SXin Li   // convention that it is GC'able.
2103*67e74705SXin Li   IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));
2104*67e74705SXin Li 
2105*67e74705SXin Li   const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2106*67e74705SXin Li 
2107*67e74705SXin Li   // Ignore the optional 'this' capture: C++ objects are not assumed
2108*67e74705SXin Li   // to be GC'ed.
2109*67e74705SXin Li 
2110*67e74705SXin Li   CharUnits lastFieldOffset;
2111*67e74705SXin Li 
2112*67e74705SXin Li   // Walk the captured variables.
2113*67e74705SXin Li   for (const auto &CI : blockDecl->captures()) {
2114*67e74705SXin Li     const VarDecl *variable = CI.getVariable();
2115*67e74705SXin Li     QualType type = variable->getType();
2116*67e74705SXin Li 
2117*67e74705SXin Li     const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2118*67e74705SXin Li 
2119*67e74705SXin Li     // Ignore constant captures.
2120*67e74705SXin Li     if (capture.isConstant()) continue;
2121*67e74705SXin Li 
2122*67e74705SXin Li     CharUnits fieldOffset = capture.getOffset();
2123*67e74705SXin Li 
2124*67e74705SXin Li     // Block fields are not necessarily ordered; if we detect that we're
2125*67e74705SXin Li     // adding them out-of-order, make sure we sort later.
2126*67e74705SXin Li     if (fieldOffset < lastFieldOffset)
2127*67e74705SXin Li       IsDisordered = true;
2128*67e74705SXin Li     lastFieldOffset = fieldOffset;
2129*67e74705SXin Li 
2130*67e74705SXin Li     // __block variables are passed by their descriptor address.
2131*67e74705SXin Li     if (CI.isByRef()) {
2132*67e74705SXin Li       IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
2133*67e74705SXin Li       continue;
2134*67e74705SXin Li     }
2135*67e74705SXin Li 
2136*67e74705SXin Li     assert(!type->isArrayType() && "array variable should not be caught");
2137*67e74705SXin Li     if (const RecordType *record = type->getAs<RecordType>()) {
2138*67e74705SXin Li       visitRecord(record, fieldOffset);
2139*67e74705SXin Li       continue;
2140*67e74705SXin Li     }
2141*67e74705SXin Li 
2142*67e74705SXin Li     Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
2143*67e74705SXin Li 
2144*67e74705SXin Li     if (GCAttr == Qualifiers::Strong) {
2145*67e74705SXin Li       assert(CGM.getContext().getTypeSize(type)
2146*67e74705SXin Li                 == CGM.getTarget().getPointerWidth(0));
2147*67e74705SXin Li       IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
2148*67e74705SXin Li     }
2149*67e74705SXin Li   }
2150*67e74705SXin Li }
2151*67e74705SXin Li 
2152*67e74705SXin Li /// getBlockCaptureLifetime - This routine returns life time of the captured
2153*67e74705SXin Li /// block variable for the purpose of block layout meta-data generation. FQT is
2154*67e74705SXin Li /// the type of the variable captured in the block.
getBlockCaptureLifetime(QualType FQT,bool ByrefLayout)2155*67e74705SXin Li Qualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
2156*67e74705SXin Li                                                                   bool ByrefLayout) {
2157*67e74705SXin Li   // If it has an ownership qualifier, we're done.
2158*67e74705SXin Li   if (auto lifetime = FQT.getObjCLifetime())
2159*67e74705SXin Li     return lifetime;
2160*67e74705SXin Li 
2161*67e74705SXin Li   // If it doesn't, and this is ARC, it has no ownership.
2162*67e74705SXin Li   if (CGM.getLangOpts().ObjCAutoRefCount)
2163*67e74705SXin Li     return Qualifiers::OCL_None;
2164*67e74705SXin Li 
2165*67e74705SXin Li   // In MRC, retainable pointers are owned by non-__block variables.
2166*67e74705SXin Li   if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2167*67e74705SXin Li     return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2168*67e74705SXin Li 
2169*67e74705SXin Li   return Qualifiers::OCL_None;
2170*67e74705SXin Li }
2171*67e74705SXin Li 
UpdateRunSkipBlockVars(bool IsByref,Qualifiers::ObjCLifetime LifeTime,CharUnits FieldOffset,CharUnits FieldSize)2172*67e74705SXin Li void CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
2173*67e74705SXin Li                                              Qualifiers::ObjCLifetime LifeTime,
2174*67e74705SXin Li                                              CharUnits FieldOffset,
2175*67e74705SXin Li                                              CharUnits FieldSize) {
2176*67e74705SXin Li   // __block variables are passed by their descriptor address.
2177*67e74705SXin Li   if (IsByref)
2178*67e74705SXin Li     RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2179*67e74705SXin Li                                         FieldSize));
2180*67e74705SXin Li   else if (LifeTime == Qualifiers::OCL_Strong)
2181*67e74705SXin Li     RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2182*67e74705SXin Li                                         FieldSize));
2183*67e74705SXin Li   else if (LifeTime == Qualifiers::OCL_Weak)
2184*67e74705SXin Li     RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2185*67e74705SXin Li                                         FieldSize));
2186*67e74705SXin Li   else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2187*67e74705SXin Li     RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2188*67e74705SXin Li                                         FieldSize));
2189*67e74705SXin Li   else
2190*67e74705SXin Li     RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2191*67e74705SXin Li                                         FieldOffset,
2192*67e74705SXin Li                                         FieldSize));
2193*67e74705SXin Li }
2194*67e74705SXin Li 
BuildRCRecordLayout(const llvm::StructLayout * RecLayout,const RecordDecl * RD,ArrayRef<const FieldDecl * > RecFields,CharUnits BytePos,bool & HasUnion,bool ByrefLayout)2195*67e74705SXin Li void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
2196*67e74705SXin Li                                           const RecordDecl *RD,
2197*67e74705SXin Li                                           ArrayRef<const FieldDecl*> RecFields,
2198*67e74705SXin Li                                           CharUnits BytePos, bool &HasUnion,
2199*67e74705SXin Li                                           bool ByrefLayout) {
2200*67e74705SXin Li   bool IsUnion = (RD && RD->isUnion());
2201*67e74705SXin Li   CharUnits MaxUnionSize = CharUnits::Zero();
2202*67e74705SXin Li   const FieldDecl *MaxField = nullptr;
2203*67e74705SXin Li   const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
2204*67e74705SXin Li   CharUnits MaxFieldOffset = CharUnits::Zero();
2205*67e74705SXin Li   CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2206*67e74705SXin Li 
2207*67e74705SXin Li   if (RecFields.empty())
2208*67e74705SXin Li     return;
2209*67e74705SXin Li   unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2210*67e74705SXin Li 
2211*67e74705SXin Li   for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2212*67e74705SXin Li     const FieldDecl *Field = RecFields[i];
2213*67e74705SXin Li     // Note that 'i' here is actually the field index inside RD of Field,
2214*67e74705SXin Li     // although this dependency is hidden.
2215*67e74705SXin Li     const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2216*67e74705SXin Li     CharUnits FieldOffset =
2217*67e74705SXin Li       CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
2218*67e74705SXin Li 
2219*67e74705SXin Li     // Skip over unnamed or bitfields
2220*67e74705SXin Li     if (!Field->getIdentifier() || Field->isBitField()) {
2221*67e74705SXin Li       LastFieldBitfieldOrUnnamed = Field;
2222*67e74705SXin Li       LastBitfieldOrUnnamedOffset = FieldOffset;
2223*67e74705SXin Li       continue;
2224*67e74705SXin Li     }
2225*67e74705SXin Li 
2226*67e74705SXin Li     LastFieldBitfieldOrUnnamed = nullptr;
2227*67e74705SXin Li     QualType FQT = Field->getType();
2228*67e74705SXin Li     if (FQT->isRecordType() || FQT->isUnionType()) {
2229*67e74705SXin Li       if (FQT->isUnionType())
2230*67e74705SXin Li         HasUnion = true;
2231*67e74705SXin Li 
2232*67e74705SXin Li       BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(),
2233*67e74705SXin Li                                   BytePos + FieldOffset, HasUnion);
2234*67e74705SXin Li       continue;
2235*67e74705SXin Li     }
2236*67e74705SXin Li 
2237*67e74705SXin Li     if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2238*67e74705SXin Li       const ConstantArrayType *CArray =
2239*67e74705SXin Li         dyn_cast_or_null<ConstantArrayType>(Array);
2240*67e74705SXin Li       uint64_t ElCount = CArray->getSize().getZExtValue();
2241*67e74705SXin Li       assert(CArray && "only array with known element size is supported");
2242*67e74705SXin Li       FQT = CArray->getElementType();
2243*67e74705SXin Li       while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2244*67e74705SXin Li         const ConstantArrayType *CArray =
2245*67e74705SXin Li           dyn_cast_or_null<ConstantArrayType>(Array);
2246*67e74705SXin Li         ElCount *= CArray->getSize().getZExtValue();
2247*67e74705SXin Li         FQT = CArray->getElementType();
2248*67e74705SXin Li       }
2249*67e74705SXin Li       if (FQT->isRecordType() && ElCount) {
2250*67e74705SXin Li         int OldIndex = RunSkipBlockVars.size() - 1;
2251*67e74705SXin Li         const RecordType *RT = FQT->getAs<RecordType>();
2252*67e74705SXin Li         BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2253*67e74705SXin Li                                     HasUnion);
2254*67e74705SXin Li 
2255*67e74705SXin Li         // Replicate layout information for each array element. Note that
2256*67e74705SXin Li         // one element is already done.
2257*67e74705SXin Li         uint64_t ElIx = 1;
2258*67e74705SXin Li         for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2259*67e74705SXin Li           CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
2260*67e74705SXin Li           for (int i = OldIndex+1; i <= FirstIndex; ++i)
2261*67e74705SXin Li             RunSkipBlockVars.push_back(
2262*67e74705SXin Li               RUN_SKIP(RunSkipBlockVars[i].opcode,
2263*67e74705SXin Li               RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2264*67e74705SXin Li               RunSkipBlockVars[i].block_var_size));
2265*67e74705SXin Li         }
2266*67e74705SXin Li         continue;
2267*67e74705SXin Li       }
2268*67e74705SXin Li     }
2269*67e74705SXin Li     CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
2270*67e74705SXin Li     if (IsUnion) {
2271*67e74705SXin Li       CharUnits UnionIvarSize = FieldSize;
2272*67e74705SXin Li       if (UnionIvarSize > MaxUnionSize) {
2273*67e74705SXin Li         MaxUnionSize = UnionIvarSize;
2274*67e74705SXin Li         MaxField = Field;
2275*67e74705SXin Li         MaxFieldOffset = FieldOffset;
2276*67e74705SXin Li       }
2277*67e74705SXin Li     } else {
2278*67e74705SXin Li       UpdateRunSkipBlockVars(false,
2279*67e74705SXin Li                              getBlockCaptureLifetime(FQT, ByrefLayout),
2280*67e74705SXin Li                              BytePos + FieldOffset,
2281*67e74705SXin Li                              FieldSize);
2282*67e74705SXin Li     }
2283*67e74705SXin Li   }
2284*67e74705SXin Li 
2285*67e74705SXin Li   if (LastFieldBitfieldOrUnnamed) {
2286*67e74705SXin Li     if (LastFieldBitfieldOrUnnamed->isBitField()) {
2287*67e74705SXin Li       // Last field was a bitfield. Must update the info.
2288*67e74705SXin Li       uint64_t BitFieldSize
2289*67e74705SXin Li         = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
2290*67e74705SXin Li       unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2291*67e74705SXin Li                         ((BitFieldSize % ByteSizeInBits) != 0);
2292*67e74705SXin Li       CharUnits Size = CharUnits::fromQuantity(UnsSize);
2293*67e74705SXin Li       Size += LastBitfieldOrUnnamedOffset;
2294*67e74705SXin Li       UpdateRunSkipBlockVars(false,
2295*67e74705SXin Li                              getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2296*67e74705SXin Li                                                      ByrefLayout),
2297*67e74705SXin Li                              BytePos + LastBitfieldOrUnnamedOffset,
2298*67e74705SXin Li                              Size);
2299*67e74705SXin Li     } else {
2300*67e74705SXin Li       assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
2301*67e74705SXin Li       // Last field was unnamed. Must update skip info.
2302*67e74705SXin Li       CharUnits FieldSize
2303*67e74705SXin Li         = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
2304*67e74705SXin Li       UpdateRunSkipBlockVars(false,
2305*67e74705SXin Li                              getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2306*67e74705SXin Li                                                      ByrefLayout),
2307*67e74705SXin Li                              BytePos + LastBitfieldOrUnnamedOffset,
2308*67e74705SXin Li                              FieldSize);
2309*67e74705SXin Li     }
2310*67e74705SXin Li   }
2311*67e74705SXin Li 
2312*67e74705SXin Li   if (MaxField)
2313*67e74705SXin Li     UpdateRunSkipBlockVars(false,
2314*67e74705SXin Li                            getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),
2315*67e74705SXin Li                            BytePos + MaxFieldOffset,
2316*67e74705SXin Li                            MaxUnionSize);
2317*67e74705SXin Li }
2318*67e74705SXin Li 
BuildRCBlockVarRecordLayout(const RecordType * RT,CharUnits BytePos,bool & HasUnion,bool ByrefLayout)2319*67e74705SXin Li void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
2320*67e74705SXin Li                                                   CharUnits BytePos,
2321*67e74705SXin Li                                                   bool &HasUnion,
2322*67e74705SXin Li                                                   bool ByrefLayout) {
2323*67e74705SXin Li   const RecordDecl *RD = RT->getDecl();
2324*67e74705SXin Li   SmallVector<const FieldDecl*, 16> Fields(RD->fields());
2325*67e74705SXin Li   llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
2326*67e74705SXin Li   const llvm::StructLayout *RecLayout =
2327*67e74705SXin Li     CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2328*67e74705SXin Li 
2329*67e74705SXin Li   BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2330*67e74705SXin Li }
2331*67e74705SXin Li 
2332*67e74705SXin Li /// InlineLayoutInstruction - This routine produce an inline instruction for the
2333*67e74705SXin Li /// block variable layout if it can. If not, it returns 0. Rules are as follow:
2334*67e74705SXin Li /// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit world,
2335*67e74705SXin Li /// an inline layout of value 0x0000000000000xyz is interpreted as follows:
2336*67e74705SXin Li /// x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by
2337*67e74705SXin Li /// y captured object of BLOCK_LAYOUT_BYREF. Followed by
2338*67e74705SXin Li /// z captured object of BLOCK_LAYOUT_WEAK. If any of the above is missing, zero
2339*67e74705SXin Li /// replaces it. For example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no
2340*67e74705SXin Li /// BLOCK_LAYOUT_BYREF and no BLOCK_LAYOUT_WEAK objects are captured.
InlineLayoutInstruction(SmallVectorImpl<unsigned char> & Layout)2341*67e74705SXin Li uint64_t CGObjCCommonMac::InlineLayoutInstruction(
2342*67e74705SXin Li                                     SmallVectorImpl<unsigned char> &Layout) {
2343*67e74705SXin Li   uint64_t Result = 0;
2344*67e74705SXin Li   if (Layout.size() <= 3) {
2345*67e74705SXin Li     unsigned size = Layout.size();
2346*67e74705SXin Li     unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2347*67e74705SXin Li     unsigned char inst;
2348*67e74705SXin Li     enum BLOCK_LAYOUT_OPCODE opcode ;
2349*67e74705SXin Li     switch (size) {
2350*67e74705SXin Li       case 3:
2351*67e74705SXin Li         inst = Layout[0];
2352*67e74705SXin Li         opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2353*67e74705SXin Li         if (opcode == BLOCK_LAYOUT_STRONG)
2354*67e74705SXin Li           strong_word_count = (inst & 0xF)+1;
2355*67e74705SXin Li         else
2356*67e74705SXin Li           return 0;
2357*67e74705SXin Li         inst = Layout[1];
2358*67e74705SXin Li         opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2359*67e74705SXin Li         if (opcode == BLOCK_LAYOUT_BYREF)
2360*67e74705SXin Li           byref_word_count = (inst & 0xF)+1;
2361*67e74705SXin Li         else
2362*67e74705SXin Li           return 0;
2363*67e74705SXin Li         inst = Layout[2];
2364*67e74705SXin Li         opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2365*67e74705SXin Li         if (opcode == BLOCK_LAYOUT_WEAK)
2366*67e74705SXin Li           weak_word_count = (inst & 0xF)+1;
2367*67e74705SXin Li         else
2368*67e74705SXin Li           return 0;
2369*67e74705SXin Li         break;
2370*67e74705SXin Li 
2371*67e74705SXin Li       case 2:
2372*67e74705SXin Li         inst = Layout[0];
2373*67e74705SXin Li         opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2374*67e74705SXin Li         if (opcode == BLOCK_LAYOUT_STRONG) {
2375*67e74705SXin Li           strong_word_count = (inst & 0xF)+1;
2376*67e74705SXin Li           inst = Layout[1];
2377*67e74705SXin Li           opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2378*67e74705SXin Li           if (opcode == BLOCK_LAYOUT_BYREF)
2379*67e74705SXin Li             byref_word_count = (inst & 0xF)+1;
2380*67e74705SXin Li           else if (opcode == BLOCK_LAYOUT_WEAK)
2381*67e74705SXin Li             weak_word_count = (inst & 0xF)+1;
2382*67e74705SXin Li           else
2383*67e74705SXin Li             return 0;
2384*67e74705SXin Li         }
2385*67e74705SXin Li         else if (opcode == BLOCK_LAYOUT_BYREF) {
2386*67e74705SXin Li           byref_word_count = (inst & 0xF)+1;
2387*67e74705SXin Li           inst = Layout[1];
2388*67e74705SXin Li           opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2389*67e74705SXin Li           if (opcode == BLOCK_LAYOUT_WEAK)
2390*67e74705SXin Li             weak_word_count = (inst & 0xF)+1;
2391*67e74705SXin Li           else
2392*67e74705SXin Li             return 0;
2393*67e74705SXin Li         }
2394*67e74705SXin Li         else
2395*67e74705SXin Li           return 0;
2396*67e74705SXin Li         break;
2397*67e74705SXin Li 
2398*67e74705SXin Li       case 1:
2399*67e74705SXin Li         inst = Layout[0];
2400*67e74705SXin Li         opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2401*67e74705SXin Li         if (opcode == BLOCK_LAYOUT_STRONG)
2402*67e74705SXin Li           strong_word_count = (inst & 0xF)+1;
2403*67e74705SXin Li         else if (opcode == BLOCK_LAYOUT_BYREF)
2404*67e74705SXin Li           byref_word_count = (inst & 0xF)+1;
2405*67e74705SXin Li         else if (opcode == BLOCK_LAYOUT_WEAK)
2406*67e74705SXin Li           weak_word_count = (inst & 0xF)+1;
2407*67e74705SXin Li         else
2408*67e74705SXin Li           return 0;
2409*67e74705SXin Li         break;
2410*67e74705SXin Li 
2411*67e74705SXin Li       default:
2412*67e74705SXin Li         return 0;
2413*67e74705SXin Li     }
2414*67e74705SXin Li 
2415*67e74705SXin Li     // Cannot inline when any of the word counts is 15. Because this is one less
2416*67e74705SXin Li     // than the actual work count (so 15 means 16 actual word counts),
2417*67e74705SXin Li     // and we can only display 0 thru 15 word counts.
2418*67e74705SXin Li     if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2419*67e74705SXin Li       return 0;
2420*67e74705SXin Li 
2421*67e74705SXin Li     unsigned count =
2422*67e74705SXin Li       (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2423*67e74705SXin Li 
2424*67e74705SXin Li     if (size == count) {
2425*67e74705SXin Li       if (strong_word_count)
2426*67e74705SXin Li         Result = strong_word_count;
2427*67e74705SXin Li       Result <<= 4;
2428*67e74705SXin Li       if (byref_word_count)
2429*67e74705SXin Li         Result += byref_word_count;
2430*67e74705SXin Li       Result <<= 4;
2431*67e74705SXin Li       if (weak_word_count)
2432*67e74705SXin Li         Result += weak_word_count;
2433*67e74705SXin Li     }
2434*67e74705SXin Li   }
2435*67e74705SXin Li   return Result;
2436*67e74705SXin Li }
2437*67e74705SXin Li 
getBitmapBlockLayout(bool ComputeByrefLayout)2438*67e74705SXin Li llvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
2439*67e74705SXin Li   llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2440*67e74705SXin Li   if (RunSkipBlockVars.empty())
2441*67e74705SXin Li     return nullPtr;
2442*67e74705SXin Li   unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2443*67e74705SXin Li   unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2444*67e74705SXin Li   unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2445*67e74705SXin Li 
2446*67e74705SXin Li   // Sort on byte position; captures might not be allocated in order,
2447*67e74705SXin Li   // and unions can do funny things.
2448*67e74705SXin Li   llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2449*67e74705SXin Li   SmallVector<unsigned char, 16> Layout;
2450*67e74705SXin Li 
2451*67e74705SXin Li   unsigned size = RunSkipBlockVars.size();
2452*67e74705SXin Li   for (unsigned i = 0; i < size; i++) {
2453*67e74705SXin Li     enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2454*67e74705SXin Li     CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2455*67e74705SXin Li     CharUnits end_byte_pos = start_byte_pos;
2456*67e74705SXin Li     unsigned j = i+1;
2457*67e74705SXin Li     while (j < size) {
2458*67e74705SXin Li       if (opcode == RunSkipBlockVars[j].opcode) {
2459*67e74705SXin Li         end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2460*67e74705SXin Li         i++;
2461*67e74705SXin Li       }
2462*67e74705SXin Li       else
2463*67e74705SXin Li         break;
2464*67e74705SXin Li     }
2465*67e74705SXin Li     CharUnits size_in_bytes =
2466*67e74705SXin Li     end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2467*67e74705SXin Li     if (j < size) {
2468*67e74705SXin Li       CharUnits gap =
2469*67e74705SXin Li       RunSkipBlockVars[j].block_var_bytepos -
2470*67e74705SXin Li       RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2471*67e74705SXin Li       size_in_bytes += gap;
2472*67e74705SXin Li     }
2473*67e74705SXin Li     CharUnits residue_in_bytes = CharUnits::Zero();
2474*67e74705SXin Li     if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2475*67e74705SXin Li       residue_in_bytes = size_in_bytes % WordSizeInBytes;
2476*67e74705SXin Li       size_in_bytes -= residue_in_bytes;
2477*67e74705SXin Li       opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2478*67e74705SXin Li     }
2479*67e74705SXin Li 
2480*67e74705SXin Li     unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
2481*67e74705SXin Li     while (size_in_words >= 16) {
2482*67e74705SXin Li       // Note that value in imm. is one less that the actual
2483*67e74705SXin Li       // value. So, 0xf means 16 words follow!
2484*67e74705SXin Li       unsigned char inst = (opcode << 4) | 0xf;
2485*67e74705SXin Li       Layout.push_back(inst);
2486*67e74705SXin Li       size_in_words -= 16;
2487*67e74705SXin Li     }
2488*67e74705SXin Li     if (size_in_words > 0) {
2489*67e74705SXin Li       // Note that value in imm. is one less that the actual
2490*67e74705SXin Li       // value. So, we subtract 1 away!
2491*67e74705SXin Li       unsigned char inst = (opcode << 4) | (size_in_words-1);
2492*67e74705SXin Li       Layout.push_back(inst);
2493*67e74705SXin Li     }
2494*67e74705SXin Li     if (residue_in_bytes > CharUnits::Zero()) {
2495*67e74705SXin Li       unsigned char inst =
2496*67e74705SXin Li       (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.getQuantity()-1);
2497*67e74705SXin Li       Layout.push_back(inst);
2498*67e74705SXin Li     }
2499*67e74705SXin Li   }
2500*67e74705SXin Li 
2501*67e74705SXin Li   while (!Layout.empty()) {
2502*67e74705SXin Li     unsigned char inst = Layout.back();
2503*67e74705SXin Li     enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2504*67e74705SXin Li     if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2505*67e74705SXin Li       Layout.pop_back();
2506*67e74705SXin Li     else
2507*67e74705SXin Li       break;
2508*67e74705SXin Li   }
2509*67e74705SXin Li 
2510*67e74705SXin Li   uint64_t Result = InlineLayoutInstruction(Layout);
2511*67e74705SXin Li   if (Result != 0) {
2512*67e74705SXin Li     // Block variable layout instruction has been inlined.
2513*67e74705SXin Li     if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2514*67e74705SXin Li       if (ComputeByrefLayout)
2515*67e74705SXin Li         printf("\n Inline BYREF variable layout: ");
2516*67e74705SXin Li       else
2517*67e74705SXin Li         printf("\n Inline block variable layout: ");
2518*67e74705SXin Li       printf("0x0%" PRIx64 "", Result);
2519*67e74705SXin Li       if (auto numStrong = (Result & 0xF00) >> 8)
2520*67e74705SXin Li         printf(", BL_STRONG:%d", (int) numStrong);
2521*67e74705SXin Li       if (auto numByref = (Result & 0x0F0) >> 4)
2522*67e74705SXin Li         printf(", BL_BYREF:%d", (int) numByref);
2523*67e74705SXin Li       if (auto numWeak = (Result & 0x00F) >> 0)
2524*67e74705SXin Li         printf(", BL_WEAK:%d", (int) numWeak);
2525*67e74705SXin Li       printf(", BL_OPERATOR:0\n");
2526*67e74705SXin Li     }
2527*67e74705SXin Li     return llvm::ConstantInt::get(CGM.IntPtrTy, Result);
2528*67e74705SXin Li   }
2529*67e74705SXin Li 
2530*67e74705SXin Li   unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2531*67e74705SXin Li   Layout.push_back(inst);
2532*67e74705SXin Li   std::string BitMap;
2533*67e74705SXin Li   for (unsigned i = 0, e = Layout.size(); i != e; i++)
2534*67e74705SXin Li     BitMap += Layout[i];
2535*67e74705SXin Li 
2536*67e74705SXin Li   if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2537*67e74705SXin Li     if (ComputeByrefLayout)
2538*67e74705SXin Li       printf("\n Byref variable layout: ");
2539*67e74705SXin Li     else
2540*67e74705SXin Li       printf("\n Block variable layout: ");
2541*67e74705SXin Li     for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
2542*67e74705SXin Li       unsigned char inst = BitMap[i];
2543*67e74705SXin Li       enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2544*67e74705SXin Li       unsigned delta = 1;
2545*67e74705SXin Li       switch (opcode) {
2546*67e74705SXin Li         case BLOCK_LAYOUT_OPERATOR:
2547*67e74705SXin Li           printf("BL_OPERATOR:");
2548*67e74705SXin Li           delta = 0;
2549*67e74705SXin Li           break;
2550*67e74705SXin Li         case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2551*67e74705SXin Li           printf("BL_NON_OBJECT_BYTES:");
2552*67e74705SXin Li           break;
2553*67e74705SXin Li         case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2554*67e74705SXin Li           printf("BL_NON_OBJECT_WORD:");
2555*67e74705SXin Li           break;
2556*67e74705SXin Li         case BLOCK_LAYOUT_STRONG:
2557*67e74705SXin Li           printf("BL_STRONG:");
2558*67e74705SXin Li           break;
2559*67e74705SXin Li         case BLOCK_LAYOUT_BYREF:
2560*67e74705SXin Li           printf("BL_BYREF:");
2561*67e74705SXin Li           break;
2562*67e74705SXin Li         case BLOCK_LAYOUT_WEAK:
2563*67e74705SXin Li           printf("BL_WEAK:");
2564*67e74705SXin Li           break;
2565*67e74705SXin Li         case BLOCK_LAYOUT_UNRETAINED:
2566*67e74705SXin Li           printf("BL_UNRETAINED:");
2567*67e74705SXin Li           break;
2568*67e74705SXin Li       }
2569*67e74705SXin Li       // Actual value of word count is one more that what is in the imm.
2570*67e74705SXin Li       // field of the instruction
2571*67e74705SXin Li       printf("%d", (inst & 0xf) + delta);
2572*67e74705SXin Li       if (i < e-1)
2573*67e74705SXin Li         printf(", ");
2574*67e74705SXin Li       else
2575*67e74705SXin Li         printf("\n");
2576*67e74705SXin Li     }
2577*67e74705SXin Li   }
2578*67e74705SXin Li 
2579*67e74705SXin Li   llvm::GlobalVariable *Entry = CreateMetadataVar(
2580*67e74705SXin Li       "OBJC_CLASS_NAME_",
2581*67e74705SXin Li       llvm::ConstantDataArray::getString(VMContext, BitMap, false),
2582*67e74705SXin Li       "__TEXT,__objc_classname,cstring_literals", CharUnits::One(), true);
2583*67e74705SXin Li   return getConstantGEP(VMContext, Entry, 0, 0);
2584*67e74705SXin Li }
2585*67e74705SXin Li 
BuildRCBlockLayout(CodeGenModule & CGM,const CGBlockInfo & blockInfo)2586*67e74705SXin Li llvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
2587*67e74705SXin Li                                                     const CGBlockInfo &blockInfo) {
2588*67e74705SXin Li   assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2589*67e74705SXin Li 
2590*67e74705SXin Li   RunSkipBlockVars.clear();
2591*67e74705SXin Li   bool hasUnion = false;
2592*67e74705SXin Li 
2593*67e74705SXin Li   unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2594*67e74705SXin Li   unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2595*67e74705SXin Li   unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2596*67e74705SXin Li 
2597*67e74705SXin Li   const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2598*67e74705SXin Li 
2599*67e74705SXin Li   // Calculate the basic layout of the block structure.
2600*67e74705SXin Li   const llvm::StructLayout *layout =
2601*67e74705SXin Li   CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
2602*67e74705SXin Li 
2603*67e74705SXin Li   // Ignore the optional 'this' capture: C++ objects are not assumed
2604*67e74705SXin Li   // to be GC'ed.
2605*67e74705SXin Li   if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
2606*67e74705SXin Li     UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,
2607*67e74705SXin Li                            blockInfo.BlockHeaderForcedGapOffset,
2608*67e74705SXin Li                            blockInfo.BlockHeaderForcedGapSize);
2609*67e74705SXin Li   // Walk the captured variables.
2610*67e74705SXin Li   for (const auto &CI : blockDecl->captures()) {
2611*67e74705SXin Li     const VarDecl *variable = CI.getVariable();
2612*67e74705SXin Li     QualType type = variable->getType();
2613*67e74705SXin Li 
2614*67e74705SXin Li     const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2615*67e74705SXin Li 
2616*67e74705SXin Li     // Ignore constant captures.
2617*67e74705SXin Li     if (capture.isConstant()) continue;
2618*67e74705SXin Li 
2619*67e74705SXin Li     CharUnits fieldOffset =
2620*67e74705SXin Li        CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
2621*67e74705SXin Li 
2622*67e74705SXin Li     assert(!type->isArrayType() && "array variable should not be caught");
2623*67e74705SXin Li     if (!CI.isByRef())
2624*67e74705SXin Li       if (const RecordType *record = type->getAs<RecordType>()) {
2625*67e74705SXin Li         BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2626*67e74705SXin Li         continue;
2627*67e74705SXin Li       }
2628*67e74705SXin Li     CharUnits fieldSize;
2629*67e74705SXin Li     if (CI.isByRef())
2630*67e74705SXin Li       fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2631*67e74705SXin Li     else
2632*67e74705SXin Li       fieldSize = CGM.getContext().getTypeSizeInChars(type);
2633*67e74705SXin Li     UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
2634*67e74705SXin Li                            fieldOffset, fieldSize);
2635*67e74705SXin Li   }
2636*67e74705SXin Li   return getBitmapBlockLayout(false);
2637*67e74705SXin Li }
2638*67e74705SXin Li 
BuildByrefLayout(CodeGen::CodeGenModule & CGM,QualType T)2639*67e74705SXin Li llvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
2640*67e74705SXin Li                                                   QualType T) {
2641*67e74705SXin Li   assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2642*67e74705SXin Li   assert(!T->isArrayType() && "__block array variable should not be caught");
2643*67e74705SXin Li   CharUnits fieldOffset;
2644*67e74705SXin Li   RunSkipBlockVars.clear();
2645*67e74705SXin Li   bool hasUnion = false;
2646*67e74705SXin Li   if (const RecordType *record = T->getAs<RecordType>()) {
2647*67e74705SXin Li     BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion, true /*ByrefLayout */);
2648*67e74705SXin Li     llvm::Constant *Result = getBitmapBlockLayout(true);
2649*67e74705SXin Li     if (isa<llvm::ConstantInt>(Result))
2650*67e74705SXin Li       Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.Int8PtrTy);
2651*67e74705SXin Li     return Result;
2652*67e74705SXin Li   }
2653*67e74705SXin Li   llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2654*67e74705SXin Li   return nullPtr;
2655*67e74705SXin Li }
2656*67e74705SXin Li 
GenerateProtocolRef(CodeGenFunction & CGF,const ObjCProtocolDecl * PD)2657*67e74705SXin Li llvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
2658*67e74705SXin Li                                             const ObjCProtocolDecl *PD) {
2659*67e74705SXin Li   // FIXME: I don't understand why gcc generates this, or where it is
2660*67e74705SXin Li   // resolved. Investigate. Its also wasteful to look this up over and over.
2661*67e74705SXin Li   LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2662*67e74705SXin Li 
2663*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2664*67e74705SXin Li                                         ObjCTypes.getExternalProtocolPtrTy());
2665*67e74705SXin Li }
2666*67e74705SXin Li 
GenerateProtocol(const ObjCProtocolDecl * PD)2667*67e74705SXin Li void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
2668*67e74705SXin Li   // FIXME: We shouldn't need this, the protocol decl should contain enough
2669*67e74705SXin Li   // information to tell us whether this was a declaration or a definition.
2670*67e74705SXin Li   DefinedProtocols.insert(PD->getIdentifier());
2671*67e74705SXin Li 
2672*67e74705SXin Li   // If we have generated a forward reference to this protocol, emit
2673*67e74705SXin Li   // it now. Otherwise do nothing, the protocol objects are lazily
2674*67e74705SXin Li   // emitted.
2675*67e74705SXin Li   if (Protocols.count(PD->getIdentifier()))
2676*67e74705SXin Li     GetOrEmitProtocol(PD);
2677*67e74705SXin Li }
2678*67e74705SXin Li 
GetProtocolRef(const ObjCProtocolDecl * PD)2679*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
2680*67e74705SXin Li   if (DefinedProtocols.count(PD->getIdentifier()))
2681*67e74705SXin Li     return GetOrEmitProtocol(PD);
2682*67e74705SXin Li 
2683*67e74705SXin Li   return GetOrEmitProtocolRef(PD);
2684*67e74705SXin Li }
2685*67e74705SXin Li 
EmitClassRefViaRuntime(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID,ObjCCommonTypesHelper & ObjCTypes)2686*67e74705SXin Li llvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
2687*67e74705SXin Li                CodeGenFunction &CGF,
2688*67e74705SXin Li                const ObjCInterfaceDecl *ID,
2689*67e74705SXin Li                ObjCCommonTypesHelper &ObjCTypes) {
2690*67e74705SXin Li   llvm::Constant *lookUpClassFn = ObjCTypes.getLookUpClassFn();
2691*67e74705SXin Li 
2692*67e74705SXin Li   llvm::Value *className =
2693*67e74705SXin Li       CGF.CGM.GetAddrOfConstantCString(ID->getObjCRuntimeNameAsString())
2694*67e74705SXin Li         .getPointer();
2695*67e74705SXin Li   ASTContext &ctx = CGF.CGM.getContext();
2696*67e74705SXin Li   className =
2697*67e74705SXin Li       CGF.Builder.CreateBitCast(className,
2698*67e74705SXin Li                                 CGF.ConvertType(
2699*67e74705SXin Li                                   ctx.getPointerType(ctx.CharTy.withConst())));
2700*67e74705SXin Li   llvm::CallInst *call = CGF.Builder.CreateCall(lookUpClassFn, className);
2701*67e74705SXin Li   call->setDoesNotThrow();
2702*67e74705SXin Li   return call;
2703*67e74705SXin Li }
2704*67e74705SXin Li 
2705*67e74705SXin Li /*
2706*67e74705SXin Li // Objective-C 1.0 extensions
2707*67e74705SXin Li struct _objc_protocol {
2708*67e74705SXin Li struct _objc_protocol_extension *isa;
2709*67e74705SXin Li char *protocol_name;
2710*67e74705SXin Li struct _objc_protocol_list *protocol_list;
2711*67e74705SXin Li struct _objc__method_prototype_list *instance_methods;
2712*67e74705SXin Li struct _objc__method_prototype_list *class_methods
2713*67e74705SXin Li };
2714*67e74705SXin Li 
2715*67e74705SXin Li See EmitProtocolExtension().
2716*67e74705SXin Li */
GetOrEmitProtocol(const ObjCProtocolDecl * PD)2717*67e74705SXin Li llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
2718*67e74705SXin Li   llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
2719*67e74705SXin Li 
2720*67e74705SXin Li   // Early exit if a defining object has already been generated.
2721*67e74705SXin Li   if (Entry && Entry->hasInitializer())
2722*67e74705SXin Li     return Entry;
2723*67e74705SXin Li 
2724*67e74705SXin Li   // Use the protocol definition, if there is one.
2725*67e74705SXin Li   if (const ObjCProtocolDecl *Def = PD->getDefinition())
2726*67e74705SXin Li     PD = Def;
2727*67e74705SXin Li 
2728*67e74705SXin Li   // FIXME: I don't understand why gcc generates this, or where it is
2729*67e74705SXin Li   // resolved. Investigate. Its also wasteful to look this up over and over.
2730*67e74705SXin Li   LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2731*67e74705SXin Li 
2732*67e74705SXin Li   // Construct method lists.
2733*67e74705SXin Li   std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2734*67e74705SXin Li   std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
2735*67e74705SXin Li   std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
2736*67e74705SXin Li   for (const auto *MD : PD->instance_methods()) {
2737*67e74705SXin Li     llvm::Constant *C = GetMethodDescriptionConstant(MD);
2738*67e74705SXin Li     if (!C)
2739*67e74705SXin Li       return GetOrEmitProtocolRef(PD);
2740*67e74705SXin Li 
2741*67e74705SXin Li     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2742*67e74705SXin Li       OptInstanceMethods.push_back(C);
2743*67e74705SXin Li       OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2744*67e74705SXin Li     } else {
2745*67e74705SXin Li       InstanceMethods.push_back(C);
2746*67e74705SXin Li       MethodTypesExt.push_back(GetMethodVarType(MD, true));
2747*67e74705SXin Li     }
2748*67e74705SXin Li   }
2749*67e74705SXin Li 
2750*67e74705SXin Li   for (const auto *MD : PD->class_methods()) {
2751*67e74705SXin Li     llvm::Constant *C = GetMethodDescriptionConstant(MD);
2752*67e74705SXin Li     if (!C)
2753*67e74705SXin Li       return GetOrEmitProtocolRef(PD);
2754*67e74705SXin Li 
2755*67e74705SXin Li     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2756*67e74705SXin Li       OptClassMethods.push_back(C);
2757*67e74705SXin Li       OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2758*67e74705SXin Li     } else {
2759*67e74705SXin Li       ClassMethods.push_back(C);
2760*67e74705SXin Li       MethodTypesExt.push_back(GetMethodVarType(MD, true));
2761*67e74705SXin Li     }
2762*67e74705SXin Li   }
2763*67e74705SXin Li 
2764*67e74705SXin Li   MethodTypesExt.insert(MethodTypesExt.end(),
2765*67e74705SXin Li                         OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2766*67e74705SXin Li 
2767*67e74705SXin Li   llvm::Constant *Values[] = {
2768*67e74705SXin Li       EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2769*67e74705SXin Li                             MethodTypesExt),
2770*67e74705SXin Li       GetClassName(PD->getObjCRuntimeNameAsString()),
2771*67e74705SXin Li       EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),
2772*67e74705SXin Li                        PD->protocol_begin(), PD->protocol_end()),
2773*67e74705SXin Li       EmitMethodDescList("OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
2774*67e74705SXin Li                          "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2775*67e74705SXin Li                          InstanceMethods),
2776*67e74705SXin Li       EmitMethodDescList("OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
2777*67e74705SXin Li                          "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2778*67e74705SXin Li                          ClassMethods)};
2779*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2780*67e74705SXin Li                                                    Values);
2781*67e74705SXin Li 
2782*67e74705SXin Li   if (Entry) {
2783*67e74705SXin Li     // Already created, update the initializer.
2784*67e74705SXin Li     assert(Entry->hasPrivateLinkage());
2785*67e74705SXin Li     Entry->setInitializer(Init);
2786*67e74705SXin Li   } else {
2787*67e74705SXin Li     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
2788*67e74705SXin Li                                      false, llvm::GlobalValue::PrivateLinkage,
2789*67e74705SXin Li                                      Init, "OBJC_PROTOCOL_" + PD->getName());
2790*67e74705SXin Li     Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2791*67e74705SXin Li     // FIXME: Is this necessary? Why only for protocol?
2792*67e74705SXin Li     Entry->setAlignment(4);
2793*67e74705SXin Li 
2794*67e74705SXin Li     Protocols[PD->getIdentifier()] = Entry;
2795*67e74705SXin Li   }
2796*67e74705SXin Li   CGM.addCompilerUsedGlobal(Entry);
2797*67e74705SXin Li 
2798*67e74705SXin Li   return Entry;
2799*67e74705SXin Li }
2800*67e74705SXin Li 
GetOrEmitProtocolRef(const ObjCProtocolDecl * PD)2801*67e74705SXin Li llvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
2802*67e74705SXin Li   llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
2803*67e74705SXin Li 
2804*67e74705SXin Li   if (!Entry) {
2805*67e74705SXin Li     // We use the initializer as a marker of whether this is a forward
2806*67e74705SXin Li     // reference or not. At module finalization we add the empty
2807*67e74705SXin Li     // contents for protocols which were referenced but never defined.
2808*67e74705SXin Li     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
2809*67e74705SXin Li                                      false, llvm::GlobalValue::PrivateLinkage,
2810*67e74705SXin Li                                      nullptr, "OBJC_PROTOCOL_" + PD->getName());
2811*67e74705SXin Li     Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2812*67e74705SXin Li     // FIXME: Is this necessary? Why only for protocol?
2813*67e74705SXin Li     Entry->setAlignment(4);
2814*67e74705SXin Li   }
2815*67e74705SXin Li 
2816*67e74705SXin Li   return Entry;
2817*67e74705SXin Li }
2818*67e74705SXin Li 
2819*67e74705SXin Li /*
2820*67e74705SXin Li   struct _objc_protocol_extension {
2821*67e74705SXin Li   uint32_t size;
2822*67e74705SXin Li   struct objc_method_description_list *optional_instance_methods;
2823*67e74705SXin Li   struct objc_method_description_list *optional_class_methods;
2824*67e74705SXin Li   struct objc_property_list *instance_properties;
2825*67e74705SXin Li   const char ** extendedMethodTypes;
2826*67e74705SXin Li   struct objc_property_list *class_properties;
2827*67e74705SXin Li   };
2828*67e74705SXin Li */
2829*67e74705SXin Li llvm::Constant *
EmitProtocolExtension(const ObjCProtocolDecl * PD,ArrayRef<llvm::Constant * > OptInstanceMethods,ArrayRef<llvm::Constant * > OptClassMethods,ArrayRef<llvm::Constant * > MethodTypesExt)2830*67e74705SXin Li CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
2831*67e74705SXin Li                                  ArrayRef<llvm::Constant*> OptInstanceMethods,
2832*67e74705SXin Li                                  ArrayRef<llvm::Constant*> OptClassMethods,
2833*67e74705SXin Li                                  ArrayRef<llvm::Constant*> MethodTypesExt) {
2834*67e74705SXin Li   uint64_t Size =
2835*67e74705SXin Li     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2836*67e74705SXin Li   llvm::Constant *Values[] = {
2837*67e74705SXin Li       llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2838*67e74705SXin Li       EmitMethodDescList("OBJC_PROTOCOL_INSTANCE_METHODS_OPT_" + PD->getName(),
2839*67e74705SXin Li                          "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2840*67e74705SXin Li                          OptInstanceMethods),
2841*67e74705SXin Li       EmitMethodDescList("OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
2842*67e74705SXin Li                          "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2843*67e74705SXin Li                          OptClassMethods),
2844*67e74705SXin Li       EmitPropertyList("OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD,
2845*67e74705SXin Li                        ObjCTypes, false),
2846*67e74705SXin Li       EmitProtocolMethodTypes("OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
2847*67e74705SXin Li                               MethodTypesExt, ObjCTypes),
2848*67e74705SXin Li       EmitPropertyList("OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), nullptr,
2849*67e74705SXin Li                        PD, ObjCTypes, true)};
2850*67e74705SXin Li 
2851*67e74705SXin Li   // Return null if no extension bits are used.
2852*67e74705SXin Li   if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2853*67e74705SXin Li       Values[3]->isNullValue() && Values[4]->isNullValue() &&
2854*67e74705SXin Li       Values[5]->isNullValue())
2855*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2856*67e74705SXin Li 
2857*67e74705SXin Li   llvm::Constant *Init =
2858*67e74705SXin Li     llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2859*67e74705SXin Li 
2860*67e74705SXin Li   // No special section, but goes in llvm.used
2861*67e74705SXin Li   return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(), Init,
2862*67e74705SXin Li                            StringRef(), CGM.getPointerAlign(), true);
2863*67e74705SXin Li }
2864*67e74705SXin Li 
2865*67e74705SXin Li /*
2866*67e74705SXin Li   struct objc_protocol_list {
2867*67e74705SXin Li     struct objc_protocol_list *next;
2868*67e74705SXin Li     long count;
2869*67e74705SXin Li     Protocol *list[];
2870*67e74705SXin Li   };
2871*67e74705SXin Li */
2872*67e74705SXin Li llvm::Constant *
EmitProtocolList(Twine Name,ObjCProtocolDecl::protocol_iterator begin,ObjCProtocolDecl::protocol_iterator end)2873*67e74705SXin Li CGObjCMac::EmitProtocolList(Twine Name,
2874*67e74705SXin Li                             ObjCProtocolDecl::protocol_iterator begin,
2875*67e74705SXin Li                             ObjCProtocolDecl::protocol_iterator end) {
2876*67e74705SXin Li   SmallVector<llvm::Constant *, 16> ProtocolRefs;
2877*67e74705SXin Li 
2878*67e74705SXin Li   for (; begin != end; ++begin)
2879*67e74705SXin Li     ProtocolRefs.push_back(GetProtocolRef(*begin));
2880*67e74705SXin Li 
2881*67e74705SXin Li   // Just return null for empty protocol lists
2882*67e74705SXin Li   if (ProtocolRefs.empty())
2883*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2884*67e74705SXin Li 
2885*67e74705SXin Li   // This list is null terminated.
2886*67e74705SXin Li   ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2887*67e74705SXin Li 
2888*67e74705SXin Li   llvm::Constant *Values[3];
2889*67e74705SXin Li   // This field is only used by the runtime.
2890*67e74705SXin Li   Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2891*67e74705SXin Li   Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2892*67e74705SXin Li                                      ProtocolRefs.size() - 1);
2893*67e74705SXin Li   Values[2] =
2894*67e74705SXin Li     llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2895*67e74705SXin Li                                                   ProtocolRefs.size()),
2896*67e74705SXin Li                              ProtocolRefs);
2897*67e74705SXin Li 
2898*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2899*67e74705SXin Li   llvm::GlobalVariable *GV =
2900*67e74705SXin Li     CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2901*67e74705SXin Li                       CGM.getPointerAlign(), false);
2902*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2903*67e74705SXin Li }
2904*67e74705SXin Li 
2905*67e74705SXin Li void CGObjCCommonMac::
PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo *,16> & PropertySet,SmallVectorImpl<llvm::Constant * > & Properties,const Decl * Container,const ObjCProtocolDecl * Proto,const ObjCCommonTypesHelper & ObjCTypes,bool IsClassProperty)2906*67e74705SXin Li PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2907*67e74705SXin Li                        SmallVectorImpl<llvm::Constant *> &Properties,
2908*67e74705SXin Li                        const Decl *Container,
2909*67e74705SXin Li                        const ObjCProtocolDecl *Proto,
2910*67e74705SXin Li                        const ObjCCommonTypesHelper &ObjCTypes,
2911*67e74705SXin Li                        bool IsClassProperty) {
2912*67e74705SXin Li   for (const auto *P : Proto->protocols())
2913*67e74705SXin Li     PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes,
2914*67e74705SXin Li                            IsClassProperty);
2915*67e74705SXin Li 
2916*67e74705SXin Li   for (const auto *PD : Proto->properties()) {
2917*67e74705SXin Li     if (IsClassProperty != PD->isClassProperty())
2918*67e74705SXin Li       continue;
2919*67e74705SXin Li     if (!PropertySet.insert(PD->getIdentifier()).second)
2920*67e74705SXin Li       continue;
2921*67e74705SXin Li     llvm::Constant *Prop[] = {
2922*67e74705SXin Li       GetPropertyName(PD->getIdentifier()),
2923*67e74705SXin Li       GetPropertyTypeString(PD, Container)
2924*67e74705SXin Li     };
2925*67e74705SXin Li     Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2926*67e74705SXin Li   }
2927*67e74705SXin Li }
2928*67e74705SXin Li 
2929*67e74705SXin Li /*
2930*67e74705SXin Li   struct _objc_property {
2931*67e74705SXin Li     const char * const name;
2932*67e74705SXin Li     const char * const attributes;
2933*67e74705SXin Li   };
2934*67e74705SXin Li 
2935*67e74705SXin Li   struct _objc_property_list {
2936*67e74705SXin Li     uint32_t entsize; // sizeof (struct _objc_property)
2937*67e74705SXin Li     uint32_t prop_count;
2938*67e74705SXin Li     struct _objc_property[prop_count];
2939*67e74705SXin Li   };
2940*67e74705SXin Li */
EmitPropertyList(Twine Name,const Decl * Container,const ObjCContainerDecl * OCD,const ObjCCommonTypesHelper & ObjCTypes,bool IsClassProperty)2941*67e74705SXin Li llvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2942*67e74705SXin Li                                        const Decl *Container,
2943*67e74705SXin Li                                        const ObjCContainerDecl *OCD,
2944*67e74705SXin Li                                        const ObjCCommonTypesHelper &ObjCTypes,
2945*67e74705SXin Li                                        bool IsClassProperty) {
2946*67e74705SXin Li   if (IsClassProperty) {
2947*67e74705SXin Li     // Make this entry NULL for OS X with deployment target < 10.11, for iOS
2948*67e74705SXin Li     // with deployment target < 9.0.
2949*67e74705SXin Li     const llvm::Triple &Triple = CGM.getTarget().getTriple();
2950*67e74705SXin Li     if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
2951*67e74705SXin Li         (Triple.isiOS() && Triple.isOSVersionLT(9)))
2952*67e74705SXin Li       return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2953*67e74705SXin Li   }
2954*67e74705SXin Li 
2955*67e74705SXin Li   SmallVector<llvm::Constant *, 16> Properties;
2956*67e74705SXin Li   llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2957*67e74705SXin Li 
2958*67e74705SXin Li   auto AddProperty = [&](const ObjCPropertyDecl *PD) {
2959*67e74705SXin Li     llvm::Constant *Prop[] = {GetPropertyName(PD->getIdentifier()),
2960*67e74705SXin Li                               GetPropertyTypeString(PD, Container)};
2961*67e74705SXin Li     Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2962*67e74705SXin Li   };
2963*67e74705SXin Li   if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
2964*67e74705SXin Li     for (const ObjCCategoryDecl *ClassExt : OID->known_extensions())
2965*67e74705SXin Li       for (auto *PD : ClassExt->properties()) {
2966*67e74705SXin Li         if (IsClassProperty != PD->isClassProperty())
2967*67e74705SXin Li           continue;
2968*67e74705SXin Li         PropertySet.insert(PD->getIdentifier());
2969*67e74705SXin Li         AddProperty(PD);
2970*67e74705SXin Li       }
2971*67e74705SXin Li 
2972*67e74705SXin Li   for (const auto *PD : OCD->properties()) {
2973*67e74705SXin Li     if (IsClassProperty != PD->isClassProperty())
2974*67e74705SXin Li       continue;
2975*67e74705SXin Li     // Don't emit duplicate metadata for properties that were already in a
2976*67e74705SXin Li     // class extension.
2977*67e74705SXin Li     if (!PropertySet.insert(PD->getIdentifier()).second)
2978*67e74705SXin Li       continue;
2979*67e74705SXin Li     AddProperty(PD);
2980*67e74705SXin Li   }
2981*67e74705SXin Li 
2982*67e74705SXin Li   if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
2983*67e74705SXin Li     for (const auto *P : OID->all_referenced_protocols())
2984*67e74705SXin Li       PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes,
2985*67e74705SXin Li                              IsClassProperty);
2986*67e74705SXin Li   }
2987*67e74705SXin Li   else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
2988*67e74705SXin Li     for (const auto *P : CD->protocols())
2989*67e74705SXin Li       PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes,
2990*67e74705SXin Li                              IsClassProperty);
2991*67e74705SXin Li   }
2992*67e74705SXin Li 
2993*67e74705SXin Li   // Return null for empty list.
2994*67e74705SXin Li   if (Properties.empty())
2995*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2996*67e74705SXin Li 
2997*67e74705SXin Li   unsigned PropertySize =
2998*67e74705SXin Li     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
2999*67e74705SXin Li   llvm::Constant *Values[3];
3000*67e74705SXin Li   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
3001*67e74705SXin Li   Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
3002*67e74705SXin Li   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
3003*67e74705SXin Li                                              Properties.size());
3004*67e74705SXin Li   Values[2] = llvm::ConstantArray::get(AT, Properties);
3005*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3006*67e74705SXin Li 
3007*67e74705SXin Li   llvm::GlobalVariable *GV =
3008*67e74705SXin Li     CreateMetadataVar(Name, Init,
3009*67e74705SXin Li                       (ObjCABI == 2) ? "__DATA, __objc_const" :
3010*67e74705SXin Li                       "__OBJC,__property,regular,no_dead_strip",
3011*67e74705SXin Li                       CGM.getPointerAlign(),
3012*67e74705SXin Li                       true);
3013*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3014*67e74705SXin Li }
3015*67e74705SXin Li 
3016*67e74705SXin Li llvm::Constant *
EmitProtocolMethodTypes(Twine Name,ArrayRef<llvm::Constant * > MethodTypes,const ObjCCommonTypesHelper & ObjCTypes)3017*67e74705SXin Li CGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3018*67e74705SXin Li                                          ArrayRef<llvm::Constant*> MethodTypes,
3019*67e74705SXin Li                                          const ObjCCommonTypesHelper &ObjCTypes) {
3020*67e74705SXin Li   // Return null for empty list.
3021*67e74705SXin Li   if (MethodTypes.empty())
3022*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3023*67e74705SXin Li 
3024*67e74705SXin Li   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3025*67e74705SXin Li                                              MethodTypes.size());
3026*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3027*67e74705SXin Li 
3028*67e74705SXin Li   llvm::GlobalVariable *GV = CreateMetadataVar(
3029*67e74705SXin Li       Name, Init, (ObjCABI == 2) ? "__DATA, __objc_const" : StringRef(),
3030*67e74705SXin Li       CGM.getPointerAlign(), true);
3031*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3032*67e74705SXin Li }
3033*67e74705SXin Li 
3034*67e74705SXin Li /*
3035*67e74705SXin Li   struct objc_method_description_list {
3036*67e74705SXin Li   int count;
3037*67e74705SXin Li   struct objc_method_description list[];
3038*67e74705SXin Li   };
3039*67e74705SXin Li */
3040*67e74705SXin Li llvm::Constant *
GetMethodDescriptionConstant(const ObjCMethodDecl * MD)3041*67e74705SXin Li CGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
3042*67e74705SXin Li   llvm::Constant *Desc[] = {
3043*67e74705SXin Li     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
3044*67e74705SXin Li                                    ObjCTypes.SelectorPtrTy),
3045*67e74705SXin Li     GetMethodVarType(MD)
3046*67e74705SXin Li   };
3047*67e74705SXin Li   if (!Desc[1])
3048*67e74705SXin Li     return nullptr;
3049*67e74705SXin Li 
3050*67e74705SXin Li   return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
3051*67e74705SXin Li                                    Desc);
3052*67e74705SXin Li }
3053*67e74705SXin Li 
3054*67e74705SXin Li llvm::Constant *
EmitMethodDescList(Twine Name,StringRef Section,ArrayRef<llvm::Constant * > Methods)3055*67e74705SXin Li CGObjCMac::EmitMethodDescList(Twine Name, StringRef Section,
3056*67e74705SXin Li                               ArrayRef<llvm::Constant *> Methods) {
3057*67e74705SXin Li   // Return null for empty list.
3058*67e74705SXin Li   if (Methods.empty())
3059*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
3060*67e74705SXin Li 
3061*67e74705SXin Li   llvm::Constant *Values[2];
3062*67e74705SXin Li   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3063*67e74705SXin Li   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
3064*67e74705SXin Li                                              Methods.size());
3065*67e74705SXin Li   Values[1] = llvm::ConstantArray::get(AT, Methods);
3066*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3067*67e74705SXin Li 
3068*67e74705SXin Li   llvm::GlobalVariable *GV =
3069*67e74705SXin Li     CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);
3070*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV,
3071*67e74705SXin Li                                         ObjCTypes.MethodDescriptionListPtrTy);
3072*67e74705SXin Li }
3073*67e74705SXin Li 
3074*67e74705SXin Li /*
3075*67e74705SXin Li   struct _objc_category {
3076*67e74705SXin Li   char *category_name;
3077*67e74705SXin Li   char *class_name;
3078*67e74705SXin Li   struct _objc_method_list *instance_methods;
3079*67e74705SXin Li   struct _objc_method_list *class_methods;
3080*67e74705SXin Li   struct _objc_protocol_list *protocols;
3081*67e74705SXin Li   uint32_t size; // <rdar://4585769>
3082*67e74705SXin Li   struct _objc_property_list *instance_properties;
3083*67e74705SXin Li   struct _objc_property_list *class_properties;
3084*67e74705SXin Li   };
3085*67e74705SXin Li */
GenerateCategory(const ObjCCategoryImplDecl * OCD)3086*67e74705SXin Li void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
3087*67e74705SXin Li   unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3088*67e74705SXin Li 
3089*67e74705SXin Li   // FIXME: This is poor design, the OCD should have a pointer to the category
3090*67e74705SXin Li   // decl. Additionally, note that Category can be null for the @implementation
3091*67e74705SXin Li   // w/o an @interface case. Sema should just create one for us as it does for
3092*67e74705SXin Li   // @implementation so everyone else can live life under a clear blue sky.
3093*67e74705SXin Li   const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
3094*67e74705SXin Li   const ObjCCategoryDecl *Category =
3095*67e74705SXin Li     Interface->FindCategoryDeclaration(OCD->getIdentifier());
3096*67e74705SXin Li 
3097*67e74705SXin Li   SmallString<256> ExtName;
3098*67e74705SXin Li   llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
3099*67e74705SXin Li                                      << OCD->getName();
3100*67e74705SXin Li 
3101*67e74705SXin Li   SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
3102*67e74705SXin Li   for (const auto *I : OCD->instance_methods())
3103*67e74705SXin Li     // Instance methods should always be defined.
3104*67e74705SXin Li     InstanceMethods.push_back(GetMethodConstant(I));
3105*67e74705SXin Li 
3106*67e74705SXin Li   for (const auto *I : OCD->class_methods())
3107*67e74705SXin Li     // Class methods should always be defined.
3108*67e74705SXin Li     ClassMethods.push_back(GetMethodConstant(I));
3109*67e74705SXin Li 
3110*67e74705SXin Li   llvm::Constant *Values[8];
3111*67e74705SXin Li   Values[0] = GetClassName(OCD->getName());
3112*67e74705SXin Li   Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString());
3113*67e74705SXin Li   LazySymbols.insert(Interface->getIdentifier());
3114*67e74705SXin Li   Values[2] = EmitMethodList("OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
3115*67e74705SXin Li                              "__OBJC,__cat_inst_meth,regular,no_dead_strip",
3116*67e74705SXin Li                              InstanceMethods);
3117*67e74705SXin Li   Values[3] = EmitMethodList("OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
3118*67e74705SXin Li                              "__OBJC,__cat_cls_meth,regular,no_dead_strip",
3119*67e74705SXin Li                              ClassMethods);
3120*67e74705SXin Li   if (Category) {
3121*67e74705SXin Li     Values[4] =
3122*67e74705SXin Li         EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3123*67e74705SXin Li                          Category->protocol_begin(), Category->protocol_end());
3124*67e74705SXin Li   } else {
3125*67e74705SXin Li     Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3126*67e74705SXin Li   }
3127*67e74705SXin Li   Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3128*67e74705SXin Li 
3129*67e74705SXin Li   // If there is no category @interface then there can be no properties.
3130*67e74705SXin Li   if (Category) {
3131*67e74705SXin Li     Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
3132*67e74705SXin Li                                  OCD, Category, ObjCTypes, false);
3133*67e74705SXin Li     Values[7] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3134*67e74705SXin Li                                  OCD, Category, ObjCTypes, true);
3135*67e74705SXin Li   } else {
3136*67e74705SXin Li     Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3137*67e74705SXin Li     Values[7] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3138*67e74705SXin Li   }
3139*67e74705SXin Li 
3140*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
3141*67e74705SXin Li                                                    Values);
3142*67e74705SXin Li 
3143*67e74705SXin Li   llvm::GlobalVariable *GV =
3144*67e74705SXin Li       CreateMetadataVar("OBJC_CATEGORY_" + ExtName.str(), Init,
3145*67e74705SXin Li                         "__OBJC,__category,regular,no_dead_strip",
3146*67e74705SXin Li                         CGM.getPointerAlign(), true);
3147*67e74705SXin Li   DefinedCategories.push_back(GV);
3148*67e74705SXin Li   DefinedCategoryNames.insert(ExtName.str());
3149*67e74705SXin Li   // method definition entries must be clear for next implementation.
3150*67e74705SXin Li   MethodDefinitions.clear();
3151*67e74705SXin Li }
3152*67e74705SXin Li 
3153*67e74705SXin Li enum FragileClassFlags {
3154*67e74705SXin Li   /// Apparently: is not a meta-class.
3155*67e74705SXin Li   FragileABI_Class_Factory                 = 0x00001,
3156*67e74705SXin Li 
3157*67e74705SXin Li   /// Is a meta-class.
3158*67e74705SXin Li   FragileABI_Class_Meta                    = 0x00002,
3159*67e74705SXin Li 
3160*67e74705SXin Li   /// Has a non-trivial constructor or destructor.
3161*67e74705SXin Li   FragileABI_Class_HasCXXStructors         = 0x02000,
3162*67e74705SXin Li 
3163*67e74705SXin Li   /// Has hidden visibility.
3164*67e74705SXin Li   FragileABI_Class_Hidden                  = 0x20000,
3165*67e74705SXin Li 
3166*67e74705SXin Li   /// Class implementation was compiled under ARC.
3167*67e74705SXin Li   FragileABI_Class_CompiledByARC           = 0x04000000,
3168*67e74705SXin Li 
3169*67e74705SXin Li   /// Class implementation was compiled under MRC and has MRC weak ivars.
3170*67e74705SXin Li   /// Exclusive with CompiledByARC.
3171*67e74705SXin Li   FragileABI_Class_HasMRCWeakIvars         = 0x08000000,
3172*67e74705SXin Li };
3173*67e74705SXin Li 
3174*67e74705SXin Li enum NonFragileClassFlags {
3175*67e74705SXin Li   /// Is a meta-class.
3176*67e74705SXin Li   NonFragileABI_Class_Meta                 = 0x00001,
3177*67e74705SXin Li 
3178*67e74705SXin Li   /// Is a root class.
3179*67e74705SXin Li   NonFragileABI_Class_Root                 = 0x00002,
3180*67e74705SXin Li 
3181*67e74705SXin Li   /// Has a non-trivial constructor or destructor.
3182*67e74705SXin Li   NonFragileABI_Class_HasCXXStructors      = 0x00004,
3183*67e74705SXin Li 
3184*67e74705SXin Li   /// Has hidden visibility.
3185*67e74705SXin Li   NonFragileABI_Class_Hidden               = 0x00010,
3186*67e74705SXin Li 
3187*67e74705SXin Li   /// Has the exception attribute.
3188*67e74705SXin Li   NonFragileABI_Class_Exception            = 0x00020,
3189*67e74705SXin Li 
3190*67e74705SXin Li   /// (Obsolete) ARC-specific: this class has a .release_ivars method
3191*67e74705SXin Li   NonFragileABI_Class_HasIvarReleaser      = 0x00040,
3192*67e74705SXin Li 
3193*67e74705SXin Li   /// Class implementation was compiled under ARC.
3194*67e74705SXin Li   NonFragileABI_Class_CompiledByARC        = 0x00080,
3195*67e74705SXin Li 
3196*67e74705SXin Li   /// Class has non-trivial destructors, but zero-initialization is okay.
3197*67e74705SXin Li   NonFragileABI_Class_HasCXXDestructorOnly = 0x00100,
3198*67e74705SXin Li 
3199*67e74705SXin Li   /// Class implementation was compiled under MRC and has MRC weak ivars.
3200*67e74705SXin Li   /// Exclusive with CompiledByARC.
3201*67e74705SXin Li   NonFragileABI_Class_HasMRCWeakIvars      = 0x00200,
3202*67e74705SXin Li };
3203*67e74705SXin Li 
hasWeakMember(QualType type)3204*67e74705SXin Li static bool hasWeakMember(QualType type) {
3205*67e74705SXin Li   if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {
3206*67e74705SXin Li     return true;
3207*67e74705SXin Li   }
3208*67e74705SXin Li 
3209*67e74705SXin Li   if (auto recType = type->getAs<RecordType>()) {
3210*67e74705SXin Li     for (auto field : recType->getDecl()->fields()) {
3211*67e74705SXin Li       if (hasWeakMember(field->getType()))
3212*67e74705SXin Li         return true;
3213*67e74705SXin Li     }
3214*67e74705SXin Li   }
3215*67e74705SXin Li 
3216*67e74705SXin Li   return false;
3217*67e74705SXin Li }
3218*67e74705SXin Li 
3219*67e74705SXin Li /// For compatibility, we only want to set the "HasMRCWeakIvars" flag
3220*67e74705SXin Li /// (and actually fill in a layout string) if we really do have any
3221*67e74705SXin Li /// __weak ivars.
hasMRCWeakIvars(CodeGenModule & CGM,const ObjCImplementationDecl * ID)3222*67e74705SXin Li static bool hasMRCWeakIvars(CodeGenModule &CGM,
3223*67e74705SXin Li                             const ObjCImplementationDecl *ID) {
3224*67e74705SXin Li   if (!CGM.getLangOpts().ObjCWeak) return false;
3225*67e74705SXin Li   assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3226*67e74705SXin Li 
3227*67e74705SXin Li   for (const ObjCIvarDecl *ivar =
3228*67e74705SXin Li          ID->getClassInterface()->all_declared_ivar_begin();
3229*67e74705SXin Li        ivar; ivar = ivar->getNextIvar()) {
3230*67e74705SXin Li     if (hasWeakMember(ivar->getType()))
3231*67e74705SXin Li       return true;
3232*67e74705SXin Li   }
3233*67e74705SXin Li 
3234*67e74705SXin Li   return false;
3235*67e74705SXin Li }
3236*67e74705SXin Li 
3237*67e74705SXin Li /*
3238*67e74705SXin Li   struct _objc_class {
3239*67e74705SXin Li   Class isa;
3240*67e74705SXin Li   Class super_class;
3241*67e74705SXin Li   const char *name;
3242*67e74705SXin Li   long version;
3243*67e74705SXin Li   long info;
3244*67e74705SXin Li   long instance_size;
3245*67e74705SXin Li   struct _objc_ivar_list *ivars;
3246*67e74705SXin Li   struct _objc_method_list *methods;
3247*67e74705SXin Li   struct _objc_cache *cache;
3248*67e74705SXin Li   struct _objc_protocol_list *protocols;
3249*67e74705SXin Li   // Objective-C 1.0 extensions (<rdr://4585769>)
3250*67e74705SXin Li   const char *ivar_layout;
3251*67e74705SXin Li   struct _objc_class_ext *ext;
3252*67e74705SXin Li   };
3253*67e74705SXin Li 
3254*67e74705SXin Li   See EmitClassExtension();
3255*67e74705SXin Li */
GenerateClass(const ObjCImplementationDecl * ID)3256*67e74705SXin Li void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
3257*67e74705SXin Li   DefinedSymbols.insert(ID->getIdentifier());
3258*67e74705SXin Li 
3259*67e74705SXin Li   std::string ClassName = ID->getNameAsString();
3260*67e74705SXin Li   // FIXME: Gross
3261*67e74705SXin Li   ObjCInterfaceDecl *Interface =
3262*67e74705SXin Li     const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
3263*67e74705SXin Li   llvm::Constant *Protocols =
3264*67e74705SXin Li       EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),
3265*67e74705SXin Li                        Interface->all_referenced_protocol_begin(),
3266*67e74705SXin Li                        Interface->all_referenced_protocol_end());
3267*67e74705SXin Li   unsigned Flags = FragileABI_Class_Factory;
3268*67e74705SXin Li   if (ID->hasNonZeroConstructors() || ID->hasDestructors())
3269*67e74705SXin Li     Flags |= FragileABI_Class_HasCXXStructors;
3270*67e74705SXin Li 
3271*67e74705SXin Li   bool hasMRCWeak = false;
3272*67e74705SXin Li 
3273*67e74705SXin Li   if (CGM.getLangOpts().ObjCAutoRefCount)
3274*67e74705SXin Li     Flags |= FragileABI_Class_CompiledByARC;
3275*67e74705SXin Li   else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
3276*67e74705SXin Li     Flags |= FragileABI_Class_HasMRCWeakIvars;
3277*67e74705SXin Li 
3278*67e74705SXin Li   CharUnits Size =
3279*67e74705SXin Li     CGM.getContext().getASTObjCImplementationLayout(ID).getSize();
3280*67e74705SXin Li 
3281*67e74705SXin Li   // FIXME: Set CXX-structors flag.
3282*67e74705SXin Li   if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3283*67e74705SXin Li     Flags |= FragileABI_Class_Hidden;
3284*67e74705SXin Li 
3285*67e74705SXin Li   SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
3286*67e74705SXin Li   for (const auto *I : ID->instance_methods())
3287*67e74705SXin Li     // Instance methods should always be defined.
3288*67e74705SXin Li     InstanceMethods.push_back(GetMethodConstant(I));
3289*67e74705SXin Li 
3290*67e74705SXin Li   for (const auto *I : ID->class_methods())
3291*67e74705SXin Li     // Class methods should always be defined.
3292*67e74705SXin Li     ClassMethods.push_back(GetMethodConstant(I));
3293*67e74705SXin Li 
3294*67e74705SXin Li   for (const auto *PID : ID->property_impls()) {
3295*67e74705SXin Li     if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3296*67e74705SXin Li       ObjCPropertyDecl *PD = PID->getPropertyDecl();
3297*67e74705SXin Li 
3298*67e74705SXin Li       if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
3299*67e74705SXin Li         if (llvm::Constant *C = GetMethodConstant(MD))
3300*67e74705SXin Li           InstanceMethods.push_back(C);
3301*67e74705SXin Li       if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
3302*67e74705SXin Li         if (llvm::Constant *C = GetMethodConstant(MD))
3303*67e74705SXin Li           InstanceMethods.push_back(C);
3304*67e74705SXin Li     }
3305*67e74705SXin Li   }
3306*67e74705SXin Li 
3307*67e74705SXin Li   llvm::Constant *Values[12];
3308*67e74705SXin Li   Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
3309*67e74705SXin Li   if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
3310*67e74705SXin Li     // Record a reference to the super class.
3311*67e74705SXin Li     LazySymbols.insert(Super->getIdentifier());
3312*67e74705SXin Li 
3313*67e74705SXin Li     Values[ 1] =
3314*67e74705SXin Li       llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3315*67e74705SXin Li                                      ObjCTypes.ClassPtrTy);
3316*67e74705SXin Li   } else {
3317*67e74705SXin Li     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3318*67e74705SXin Li   }
3319*67e74705SXin Li   Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
3320*67e74705SXin Li   // Version is always 0.
3321*67e74705SXin Li   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3322*67e74705SXin Li   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3323*67e74705SXin Li   Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size.getQuantity());
3324*67e74705SXin Li   Values[ 6] = EmitIvarList(ID, false);
3325*67e74705SXin Li   Values[7] = EmitMethodList("OBJC_INSTANCE_METHODS_" + ID->getName(),
3326*67e74705SXin Li                              "__OBJC,__inst_meth,regular,no_dead_strip",
3327*67e74705SXin Li                              InstanceMethods);
3328*67e74705SXin Li   // cache is always NULL.
3329*67e74705SXin Li   Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3330*67e74705SXin Li   Values[ 9] = Protocols;
3331*67e74705SXin Li   Values[10] = BuildStrongIvarLayout(ID, CharUnits::Zero(), Size);
3332*67e74705SXin Li   Values[11] = EmitClassExtension(ID, Size, hasMRCWeak,
3333*67e74705SXin Li                                   false/*isClassProperty*/);
3334*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3335*67e74705SXin Li                                                    Values);
3336*67e74705SXin Li   std::string Name("OBJC_CLASS_");
3337*67e74705SXin Li   Name += ClassName;
3338*67e74705SXin Li   const char *Section = "__OBJC,__class,regular,no_dead_strip";
3339*67e74705SXin Li   // Check for a forward reference.
3340*67e74705SXin Li   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3341*67e74705SXin Li   if (GV) {
3342*67e74705SXin Li     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3343*67e74705SXin Li            "Forward metaclass reference has incorrect type.");
3344*67e74705SXin Li     GV->setInitializer(Init);
3345*67e74705SXin Li     GV->setSection(Section);
3346*67e74705SXin Li     GV->setAlignment(CGM.getPointerAlign().getQuantity());
3347*67e74705SXin Li     CGM.addCompilerUsedGlobal(GV);
3348*67e74705SXin Li   } else
3349*67e74705SXin Li     GV = CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);
3350*67e74705SXin Li   DefinedClasses.push_back(GV);
3351*67e74705SXin Li   ImplementedClasses.push_back(Interface);
3352*67e74705SXin Li   // method definition entries must be clear for next implementation.
3353*67e74705SXin Li   MethodDefinitions.clear();
3354*67e74705SXin Li }
3355*67e74705SXin Li 
EmitMetaClass(const ObjCImplementationDecl * ID,llvm::Constant * Protocols,ArrayRef<llvm::Constant * > Methods)3356*67e74705SXin Li llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
3357*67e74705SXin Li                                          llvm::Constant *Protocols,
3358*67e74705SXin Li                                          ArrayRef<llvm::Constant*> Methods) {
3359*67e74705SXin Li   unsigned Flags = FragileABI_Class_Meta;
3360*67e74705SXin Li   unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3361*67e74705SXin Li 
3362*67e74705SXin Li   if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3363*67e74705SXin Li     Flags |= FragileABI_Class_Hidden;
3364*67e74705SXin Li 
3365*67e74705SXin Li   llvm::Constant *Values[12];
3366*67e74705SXin Li   // The isa for the metaclass is the root of the hierarchy.
3367*67e74705SXin Li   const ObjCInterfaceDecl *Root = ID->getClassInterface();
3368*67e74705SXin Li   while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
3369*67e74705SXin Li     Root = Super;
3370*67e74705SXin Li   Values[ 0] =
3371*67e74705SXin Li     llvm::ConstantExpr::getBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
3372*67e74705SXin Li                                    ObjCTypes.ClassPtrTy);
3373*67e74705SXin Li   // The super class for the metaclass is emitted as the name of the
3374*67e74705SXin Li   // super class. The runtime fixes this up to point to the
3375*67e74705SXin Li   // *metaclass* for the super class.
3376*67e74705SXin Li   if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
3377*67e74705SXin Li     Values[ 1] =
3378*67e74705SXin Li       llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3379*67e74705SXin Li                                      ObjCTypes.ClassPtrTy);
3380*67e74705SXin Li   } else {
3381*67e74705SXin Li     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3382*67e74705SXin Li   }
3383*67e74705SXin Li   Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
3384*67e74705SXin Li   // Version is always 0.
3385*67e74705SXin Li   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3386*67e74705SXin Li   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3387*67e74705SXin Li   Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3388*67e74705SXin Li   Values[ 6] = EmitIvarList(ID, true);
3389*67e74705SXin Li   Values[7] =
3390*67e74705SXin Li       EmitMethodList("OBJC_CLASS_METHODS_" + ID->getNameAsString(),
3391*67e74705SXin Li                      "__OBJC,__cls_meth,regular,no_dead_strip", Methods);
3392*67e74705SXin Li   // cache is always NULL.
3393*67e74705SXin Li   Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3394*67e74705SXin Li   Values[ 9] = Protocols;
3395*67e74705SXin Li   // ivar_layout for metaclass is always NULL.
3396*67e74705SXin Li   Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3397*67e74705SXin Li   // The class extension is used to store class properties for metaclasses.
3398*67e74705SXin Li   Values[11] = EmitClassExtension(ID, CharUnits::Zero(), false/*hasMRCWeak*/,
3399*67e74705SXin Li                                   true/*isClassProperty*/);
3400*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3401*67e74705SXin Li                                                    Values);
3402*67e74705SXin Li 
3403*67e74705SXin Li   std::string Name("OBJC_METACLASS_");
3404*67e74705SXin Li   Name += ID->getName();
3405*67e74705SXin Li 
3406*67e74705SXin Li   // Check for a forward reference.
3407*67e74705SXin Li   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3408*67e74705SXin Li   if (GV) {
3409*67e74705SXin Li     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3410*67e74705SXin Li            "Forward metaclass reference has incorrect type.");
3411*67e74705SXin Li     GV->setInitializer(Init);
3412*67e74705SXin Li   } else {
3413*67e74705SXin Li     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3414*67e74705SXin Li                                   llvm::GlobalValue::PrivateLinkage,
3415*67e74705SXin Li                                   Init, Name);
3416*67e74705SXin Li   }
3417*67e74705SXin Li   GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
3418*67e74705SXin Li   GV->setAlignment(4);
3419*67e74705SXin Li   CGM.addCompilerUsedGlobal(GV);
3420*67e74705SXin Li 
3421*67e74705SXin Li   return GV;
3422*67e74705SXin Li }
3423*67e74705SXin Li 
EmitMetaClassRef(const ObjCInterfaceDecl * ID)3424*67e74705SXin Li llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
3425*67e74705SXin Li   std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
3426*67e74705SXin Li 
3427*67e74705SXin Li   // FIXME: Should we look these up somewhere other than the module. Its a bit
3428*67e74705SXin Li   // silly since we only generate these while processing an implementation, so
3429*67e74705SXin Li   // exactly one pointer would work if know when we entered/exitted an
3430*67e74705SXin Li   // implementation block.
3431*67e74705SXin Li 
3432*67e74705SXin Li   // Check for an existing forward reference.
3433*67e74705SXin Li   // Previously, metaclass with internal linkage may have been defined.
3434*67e74705SXin Li   // pass 'true' as 2nd argument so it is returned.
3435*67e74705SXin Li   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3436*67e74705SXin Li   if (!GV)
3437*67e74705SXin Li     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3438*67e74705SXin Li                                   llvm::GlobalValue::PrivateLinkage, nullptr,
3439*67e74705SXin Li                                   Name);
3440*67e74705SXin Li 
3441*67e74705SXin Li   assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3442*67e74705SXin Li          "Forward metaclass reference has incorrect type.");
3443*67e74705SXin Li   return GV;
3444*67e74705SXin Li }
3445*67e74705SXin Li 
EmitSuperClassRef(const ObjCInterfaceDecl * ID)3446*67e74705SXin Li llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
3447*67e74705SXin Li   std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
3448*67e74705SXin Li   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3449*67e74705SXin Li 
3450*67e74705SXin Li   if (!GV)
3451*67e74705SXin Li     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3452*67e74705SXin Li                                   llvm::GlobalValue::PrivateLinkage, nullptr,
3453*67e74705SXin Li                                   Name);
3454*67e74705SXin Li 
3455*67e74705SXin Li   assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3456*67e74705SXin Li          "Forward class metadata reference has incorrect type.");
3457*67e74705SXin Li   return GV;
3458*67e74705SXin Li }
3459*67e74705SXin Li 
3460*67e74705SXin Li /*
3461*67e74705SXin Li   Emit a "class extension", which in this specific context means extra
3462*67e74705SXin Li   data that doesn't fit in the normal fragile-ABI class structure, and
3463*67e74705SXin Li   has nothing to do with the language concept of a class extension.
3464*67e74705SXin Li 
3465*67e74705SXin Li   struct objc_class_ext {
3466*67e74705SXin Li   uint32_t size;
3467*67e74705SXin Li   const char *weak_ivar_layout;
3468*67e74705SXin Li   struct _objc_property_list *properties;
3469*67e74705SXin Li   };
3470*67e74705SXin Li */
3471*67e74705SXin Li llvm::Constant *
EmitClassExtension(const ObjCImplementationDecl * ID,CharUnits InstanceSize,bool hasMRCWeakIvars,bool isClassProperty)3472*67e74705SXin Li CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,
3473*67e74705SXin Li                               CharUnits InstanceSize, bool hasMRCWeakIvars,
3474*67e74705SXin Li                               bool isClassProperty) {
3475*67e74705SXin Li   uint64_t Size =
3476*67e74705SXin Li     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3477*67e74705SXin Li 
3478*67e74705SXin Li   llvm::Constant *Values[3];
3479*67e74705SXin Li   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3480*67e74705SXin Li   if (isClassProperty) {
3481*67e74705SXin Li     llvm::Type *PtrTy = CGM.Int8PtrTy;
3482*67e74705SXin Li     Values[1] = llvm::Constant::getNullValue(PtrTy);
3483*67e74705SXin Li   } else
3484*67e74705SXin Li     Values[1] = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,
3485*67e74705SXin Li                                     hasMRCWeakIvars);
3486*67e74705SXin Li   if (isClassProperty)
3487*67e74705SXin Li     Values[2] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ID->getName(),
3488*67e74705SXin Li                                  ID, ID->getClassInterface(), ObjCTypes, true);
3489*67e74705SXin Li   else
3490*67e74705SXin Li     Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
3491*67e74705SXin Li                                  ID, ID->getClassInterface(), ObjCTypes, false);
3492*67e74705SXin Li 
3493*67e74705SXin Li   // Return null if no extension bits are used.
3494*67e74705SXin Li   if ((!Values[1] || Values[1]->isNullValue()) && Values[2]->isNullValue())
3495*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3496*67e74705SXin Li 
3497*67e74705SXin Li   llvm::Constant *Init =
3498*67e74705SXin Li     llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
3499*67e74705SXin Li   return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), Init,
3500*67e74705SXin Li                            "__OBJC,__class_ext,regular,no_dead_strip",
3501*67e74705SXin Li                            CGM.getPointerAlign(), true);
3502*67e74705SXin Li }
3503*67e74705SXin Li 
3504*67e74705SXin Li /*
3505*67e74705SXin Li   struct objc_ivar {
3506*67e74705SXin Li     char *ivar_name;
3507*67e74705SXin Li     char *ivar_type;
3508*67e74705SXin Li     int ivar_offset;
3509*67e74705SXin Li   };
3510*67e74705SXin Li 
3511*67e74705SXin Li   struct objc_ivar_list {
3512*67e74705SXin Li     int ivar_count;
3513*67e74705SXin Li     struct objc_ivar list[count];
3514*67e74705SXin Li   };
3515*67e74705SXin Li */
EmitIvarList(const ObjCImplementationDecl * ID,bool ForClass)3516*67e74705SXin Li llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
3517*67e74705SXin Li                                         bool ForClass) {
3518*67e74705SXin Li   std::vector<llvm::Constant*> Ivars;
3519*67e74705SXin Li 
3520*67e74705SXin Li   // When emitting the root class GCC emits ivar entries for the
3521*67e74705SXin Li   // actual class structure. It is not clear if we need to follow this
3522*67e74705SXin Li   // behavior; for now lets try and get away with not doing it. If so,
3523*67e74705SXin Li   // the cleanest solution would be to make up an ObjCInterfaceDecl
3524*67e74705SXin Li   // for the class.
3525*67e74705SXin Li   if (ForClass)
3526*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3527*67e74705SXin Li 
3528*67e74705SXin Li   const ObjCInterfaceDecl *OID = ID->getClassInterface();
3529*67e74705SXin Li 
3530*67e74705SXin Li   for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
3531*67e74705SXin Li        IVD; IVD = IVD->getNextIvar()) {
3532*67e74705SXin Li     // Ignore unnamed bit-fields.
3533*67e74705SXin Li     if (!IVD->getDeclName())
3534*67e74705SXin Li       continue;
3535*67e74705SXin Li     llvm::Constant *Ivar[] = {
3536*67e74705SXin Li       GetMethodVarName(IVD->getIdentifier()),
3537*67e74705SXin Li       GetMethodVarType(IVD),
3538*67e74705SXin Li       llvm::ConstantInt::get(ObjCTypes.IntTy,
3539*67e74705SXin Li                              ComputeIvarBaseOffset(CGM, OID, IVD))
3540*67e74705SXin Li     };
3541*67e74705SXin Li     Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
3542*67e74705SXin Li   }
3543*67e74705SXin Li 
3544*67e74705SXin Li   // Return null for empty list.
3545*67e74705SXin Li   if (Ivars.empty())
3546*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3547*67e74705SXin Li 
3548*67e74705SXin Li   llvm::Constant *Values[2];
3549*67e74705SXin Li   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
3550*67e74705SXin Li   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
3551*67e74705SXin Li                                              Ivars.size());
3552*67e74705SXin Li   Values[1] = llvm::ConstantArray::get(AT, Ivars);
3553*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3554*67e74705SXin Li 
3555*67e74705SXin Li   llvm::GlobalVariable *GV;
3556*67e74705SXin Li   if (ForClass)
3557*67e74705SXin Li     GV =
3558*67e74705SXin Li         CreateMetadataVar("OBJC_CLASS_VARIABLES_" + ID->getName(), Init,
3559*67e74705SXin Li                           "__OBJC,__class_vars,regular,no_dead_strip",
3560*67e74705SXin Li                           CGM.getPointerAlign(), true);
3561*67e74705SXin Li   else
3562*67e74705SXin Li     GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), Init,
3563*67e74705SXin Li                            "__OBJC,__instance_vars,regular,no_dead_strip",
3564*67e74705SXin Li                            CGM.getPointerAlign(), true);
3565*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3566*67e74705SXin Li }
3567*67e74705SXin Li 
3568*67e74705SXin Li /*
3569*67e74705SXin Li   struct objc_method {
3570*67e74705SXin Li   SEL method_name;
3571*67e74705SXin Li   char *method_types;
3572*67e74705SXin Li   void *method;
3573*67e74705SXin Li   };
3574*67e74705SXin Li 
3575*67e74705SXin Li   struct objc_method_list {
3576*67e74705SXin Li   struct objc_method_list *obsolete;
3577*67e74705SXin Li   int count;
3578*67e74705SXin Li   struct objc_method methods_list[count];
3579*67e74705SXin Li   };
3580*67e74705SXin Li */
3581*67e74705SXin Li 
3582*67e74705SXin Li /// GetMethodConstant - Return a struct objc_method constant for the
3583*67e74705SXin Li /// given method if it has been defined. The result is null if the
3584*67e74705SXin Li /// method has not been defined. The return value has type MethodPtrTy.
GetMethodConstant(const ObjCMethodDecl * MD)3585*67e74705SXin Li llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
3586*67e74705SXin Li   llvm::Function *Fn = GetMethodDefinition(MD);
3587*67e74705SXin Li   if (!Fn)
3588*67e74705SXin Li     return nullptr;
3589*67e74705SXin Li 
3590*67e74705SXin Li   llvm::Constant *Method[] = {
3591*67e74705SXin Li     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
3592*67e74705SXin Li                                    ObjCTypes.SelectorPtrTy),
3593*67e74705SXin Li     GetMethodVarType(MD),
3594*67e74705SXin Li     llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3595*67e74705SXin Li   };
3596*67e74705SXin Li   return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
3597*67e74705SXin Li }
3598*67e74705SXin Li 
EmitMethodList(Twine Name,StringRef Section,ArrayRef<llvm::Constant * > Methods)3599*67e74705SXin Li llvm::Constant *CGObjCMac::EmitMethodList(Twine Name, StringRef Section,
3600*67e74705SXin Li                                           ArrayRef<llvm::Constant *> Methods) {
3601*67e74705SXin Li   // Return null for empty list.
3602*67e74705SXin Li   if (Methods.empty())
3603*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
3604*67e74705SXin Li 
3605*67e74705SXin Li   llvm::Constant *Values[3];
3606*67e74705SXin Li   Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3607*67e74705SXin Li   Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3608*67e74705SXin Li   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
3609*67e74705SXin Li                                              Methods.size());
3610*67e74705SXin Li   Values[2] = llvm::ConstantArray::get(AT, Methods);
3611*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3612*67e74705SXin Li 
3613*67e74705SXin Li   llvm::GlobalVariable *GV =
3614*67e74705SXin Li     CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);
3615*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3616*67e74705SXin Li }
3617*67e74705SXin Li 
GenerateMethod(const ObjCMethodDecl * OMD,const ObjCContainerDecl * CD)3618*67e74705SXin Li llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
3619*67e74705SXin Li                                                 const ObjCContainerDecl *CD) {
3620*67e74705SXin Li   SmallString<256> Name;
3621*67e74705SXin Li   GetNameForMethod(OMD, CD, Name);
3622*67e74705SXin Li 
3623*67e74705SXin Li   CodeGenTypes &Types = CGM.getTypes();
3624*67e74705SXin Li   llvm::FunctionType *MethodTy =
3625*67e74705SXin Li     Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3626*67e74705SXin Li   llvm::Function *Method =
3627*67e74705SXin Li     llvm::Function::Create(MethodTy,
3628*67e74705SXin Li                            llvm::GlobalValue::InternalLinkage,
3629*67e74705SXin Li                            Name.str(),
3630*67e74705SXin Li                            &CGM.getModule());
3631*67e74705SXin Li   MethodDefinitions.insert(std::make_pair(OMD, Method));
3632*67e74705SXin Li 
3633*67e74705SXin Li   return Method;
3634*67e74705SXin Li }
3635*67e74705SXin Li 
CreateMetadataVar(Twine Name,llvm::Constant * Init,StringRef Section,CharUnits Align,bool AddToUsed)3636*67e74705SXin Li llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
3637*67e74705SXin Li                                                          llvm::Constant *Init,
3638*67e74705SXin Li                                                          StringRef Section,
3639*67e74705SXin Li                                                          CharUnits Align,
3640*67e74705SXin Li                                                          bool AddToUsed) {
3641*67e74705SXin Li   llvm::Type *Ty = Init->getType();
3642*67e74705SXin Li   llvm::GlobalVariable *GV =
3643*67e74705SXin Li     new llvm::GlobalVariable(CGM.getModule(), Ty, false,
3644*67e74705SXin Li                              llvm::GlobalValue::PrivateLinkage, Init, Name);
3645*67e74705SXin Li   if (!Section.empty())
3646*67e74705SXin Li     GV->setSection(Section);
3647*67e74705SXin Li   GV->setAlignment(Align.getQuantity());
3648*67e74705SXin Li   if (AddToUsed)
3649*67e74705SXin Li     CGM.addCompilerUsedGlobal(GV);
3650*67e74705SXin Li   return GV;
3651*67e74705SXin Li }
3652*67e74705SXin Li 
ModuleInitFunction()3653*67e74705SXin Li llvm::Function *CGObjCMac::ModuleInitFunction() {
3654*67e74705SXin Li   // Abuse this interface function as a place to finalize.
3655*67e74705SXin Li   FinishModule();
3656*67e74705SXin Li   return nullptr;
3657*67e74705SXin Li }
3658*67e74705SXin Li 
GetPropertyGetFunction()3659*67e74705SXin Li llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3660*67e74705SXin Li   return ObjCTypes.getGetPropertyFn();
3661*67e74705SXin Li }
3662*67e74705SXin Li 
GetPropertySetFunction()3663*67e74705SXin Li llvm::Constant *CGObjCMac::GetPropertySetFunction() {
3664*67e74705SXin Li   return ObjCTypes.getSetPropertyFn();
3665*67e74705SXin Li }
3666*67e74705SXin Li 
GetOptimizedPropertySetFunction(bool atomic,bool copy)3667*67e74705SXin Li llvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
3668*67e74705SXin Li                                                            bool copy) {
3669*67e74705SXin Li   return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3670*67e74705SXin Li }
3671*67e74705SXin Li 
GetGetStructFunction()3672*67e74705SXin Li llvm::Constant *CGObjCMac::GetGetStructFunction() {
3673*67e74705SXin Li   return ObjCTypes.getCopyStructFn();
3674*67e74705SXin Li }
3675*67e74705SXin Li 
GetSetStructFunction()3676*67e74705SXin Li llvm::Constant *CGObjCMac::GetSetStructFunction() {
3677*67e74705SXin Li   return ObjCTypes.getCopyStructFn();
3678*67e74705SXin Li }
3679*67e74705SXin Li 
GetCppAtomicObjectGetFunction()3680*67e74705SXin Li llvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3681*67e74705SXin Li   return ObjCTypes.getCppAtomicObjectFunction();
3682*67e74705SXin Li }
3683*67e74705SXin Li 
GetCppAtomicObjectSetFunction()3684*67e74705SXin Li llvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3685*67e74705SXin Li   return ObjCTypes.getCppAtomicObjectFunction();
3686*67e74705SXin Li }
3687*67e74705SXin Li 
EnumerationMutationFunction()3688*67e74705SXin Li llvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3689*67e74705SXin Li   return ObjCTypes.getEnumerationMutationFn();
3690*67e74705SXin Li }
3691*67e74705SXin Li 
EmitTryStmt(CodeGenFunction & CGF,const ObjCAtTryStmt & S)3692*67e74705SXin Li void CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
3693*67e74705SXin Li   return EmitTryOrSynchronizedStmt(CGF, S);
3694*67e74705SXin Li }
3695*67e74705SXin Li 
EmitSynchronizedStmt(CodeGenFunction & CGF,const ObjCAtSynchronizedStmt & S)3696*67e74705SXin Li void CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
3697*67e74705SXin Li                                      const ObjCAtSynchronizedStmt &S) {
3698*67e74705SXin Li   return EmitTryOrSynchronizedStmt(CGF, S);
3699*67e74705SXin Li }
3700*67e74705SXin Li 
3701*67e74705SXin Li namespace {
3702*67e74705SXin Li   struct PerformFragileFinally final : EHScopeStack::Cleanup {
3703*67e74705SXin Li     const Stmt &S;
3704*67e74705SXin Li     Address SyncArgSlot;
3705*67e74705SXin Li     Address CallTryExitVar;
3706*67e74705SXin Li     Address ExceptionData;
3707*67e74705SXin Li     ObjCTypesHelper &ObjCTypes;
PerformFragileFinally__anon33e85b2f0511::PerformFragileFinally3708*67e74705SXin Li     PerformFragileFinally(const Stmt *S,
3709*67e74705SXin Li                           Address SyncArgSlot,
3710*67e74705SXin Li                           Address CallTryExitVar,
3711*67e74705SXin Li                           Address ExceptionData,
3712*67e74705SXin Li                           ObjCTypesHelper *ObjCTypes)
3713*67e74705SXin Li       : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
3714*67e74705SXin Li         ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3715*67e74705SXin Li 
Emit__anon33e85b2f0511::PerformFragileFinally3716*67e74705SXin Li     void Emit(CodeGenFunction &CGF, Flags flags) override {
3717*67e74705SXin Li       // Check whether we need to call objc_exception_try_exit.
3718*67e74705SXin Li       // In optimized code, this branch will always be folded.
3719*67e74705SXin Li       llvm::BasicBlock *FinallyCallExit =
3720*67e74705SXin Li         CGF.createBasicBlock("finally.call_exit");
3721*67e74705SXin Li       llvm::BasicBlock *FinallyNoCallExit =
3722*67e74705SXin Li         CGF.createBasicBlock("finally.no_call_exit");
3723*67e74705SXin Li       CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
3724*67e74705SXin Li                                FinallyCallExit, FinallyNoCallExit);
3725*67e74705SXin Li 
3726*67e74705SXin Li       CGF.EmitBlock(FinallyCallExit);
3727*67e74705SXin Li       CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
3728*67e74705SXin Li                                   ExceptionData.getPointer());
3729*67e74705SXin Li 
3730*67e74705SXin Li       CGF.EmitBlock(FinallyNoCallExit);
3731*67e74705SXin Li 
3732*67e74705SXin Li       if (isa<ObjCAtTryStmt>(S)) {
3733*67e74705SXin Li         if (const ObjCAtFinallyStmt* FinallyStmt =
3734*67e74705SXin Li               cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
3735*67e74705SXin Li           // Don't try to do the @finally if this is an EH cleanup.
3736*67e74705SXin Li           if (flags.isForEHCleanup()) return;
3737*67e74705SXin Li 
3738*67e74705SXin Li           // Save the current cleanup destination in case there's
3739*67e74705SXin Li           // control flow inside the finally statement.
3740*67e74705SXin Li           llvm::Value *CurCleanupDest =
3741*67e74705SXin Li             CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
3742*67e74705SXin Li 
3743*67e74705SXin Li           CGF.EmitStmt(FinallyStmt->getFinallyBody());
3744*67e74705SXin Li 
3745*67e74705SXin Li           if (CGF.HaveInsertPoint()) {
3746*67e74705SXin Li             CGF.Builder.CreateStore(CurCleanupDest,
3747*67e74705SXin Li                                     CGF.getNormalCleanupDestSlot());
3748*67e74705SXin Li           } else {
3749*67e74705SXin Li             // Currently, the end of the cleanup must always exist.
3750*67e74705SXin Li             CGF.EnsureInsertPoint();
3751*67e74705SXin Li           }
3752*67e74705SXin Li         }
3753*67e74705SXin Li       } else {
3754*67e74705SXin Li         // Emit objc_sync_exit(expr); as finally's sole statement for
3755*67e74705SXin Li         // @synchronized.
3756*67e74705SXin Li         llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
3757*67e74705SXin Li         CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
3758*67e74705SXin Li       }
3759*67e74705SXin Li     }
3760*67e74705SXin Li   };
3761*67e74705SXin Li 
3762*67e74705SXin Li   class FragileHazards {
3763*67e74705SXin Li     CodeGenFunction &CGF;
3764*67e74705SXin Li     SmallVector<llvm::Value*, 20> Locals;
3765*67e74705SXin Li     llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
3766*67e74705SXin Li 
3767*67e74705SXin Li     llvm::InlineAsm *ReadHazard;
3768*67e74705SXin Li     llvm::InlineAsm *WriteHazard;
3769*67e74705SXin Li 
3770*67e74705SXin Li     llvm::FunctionType *GetAsmFnType();
3771*67e74705SXin Li 
3772*67e74705SXin Li     void collectLocals();
3773*67e74705SXin Li     void emitReadHazard(CGBuilderTy &Builder);
3774*67e74705SXin Li 
3775*67e74705SXin Li   public:
3776*67e74705SXin Li     FragileHazards(CodeGenFunction &CGF);
3777*67e74705SXin Li 
3778*67e74705SXin Li     void emitWriteHazard();
3779*67e74705SXin Li     void emitHazardsInNewBlocks();
3780*67e74705SXin Li   };
3781*67e74705SXin Li } // end anonymous namespace
3782*67e74705SXin Li 
3783*67e74705SXin Li /// Create the fragile-ABI read and write hazards based on the current
3784*67e74705SXin Li /// state of the function, which is presumed to be immediately prior
3785*67e74705SXin Li /// to a @try block.  These hazards are used to maintain correct
3786*67e74705SXin Li /// semantics in the face of optimization and the fragile ABI's
3787*67e74705SXin Li /// cavalier use of setjmp/longjmp.
FragileHazards(CodeGenFunction & CGF)3788*67e74705SXin Li FragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
3789*67e74705SXin Li   collectLocals();
3790*67e74705SXin Li 
3791*67e74705SXin Li   if (Locals.empty()) return;
3792*67e74705SXin Li 
3793*67e74705SXin Li   // Collect all the blocks in the function.
3794*67e74705SXin Li   for (llvm::Function::iterator
3795*67e74705SXin Li          I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
3796*67e74705SXin Li     BlocksBeforeTry.insert(&*I);
3797*67e74705SXin Li 
3798*67e74705SXin Li   llvm::FunctionType *AsmFnTy = GetAsmFnType();
3799*67e74705SXin Li 
3800*67e74705SXin Li   // Create a read hazard for the allocas.  This inhibits dead-store
3801*67e74705SXin Li   // optimizations and forces the values to memory.  This hazard is
3802*67e74705SXin Li   // inserted before any 'throwing' calls in the protected scope to
3803*67e74705SXin Li   // reflect the possibility that the variables might be read from the
3804*67e74705SXin Li   // catch block if the call throws.
3805*67e74705SXin Li   {
3806*67e74705SXin Li     std::string Constraint;
3807*67e74705SXin Li     for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3808*67e74705SXin Li       if (I) Constraint += ',';
3809*67e74705SXin Li       Constraint += "*m";
3810*67e74705SXin Li     }
3811*67e74705SXin Li 
3812*67e74705SXin Li     ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3813*67e74705SXin Li   }
3814*67e74705SXin Li 
3815*67e74705SXin Li   // Create a write hazard for the allocas.  This inhibits folding
3816*67e74705SXin Li   // loads across the hazard.  This hazard is inserted at the
3817*67e74705SXin Li   // beginning of the catch path to reflect the possibility that the
3818*67e74705SXin Li   // variables might have been written within the protected scope.
3819*67e74705SXin Li   {
3820*67e74705SXin Li     std::string Constraint;
3821*67e74705SXin Li     for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3822*67e74705SXin Li       if (I) Constraint += ',';
3823*67e74705SXin Li       Constraint += "=*m";
3824*67e74705SXin Li     }
3825*67e74705SXin Li 
3826*67e74705SXin Li     WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3827*67e74705SXin Li   }
3828*67e74705SXin Li }
3829*67e74705SXin Li 
3830*67e74705SXin Li /// Emit a write hazard at the current location.
emitWriteHazard()3831*67e74705SXin Li void FragileHazards::emitWriteHazard() {
3832*67e74705SXin Li   if (Locals.empty()) return;
3833*67e74705SXin Li 
3834*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
3835*67e74705SXin Li }
3836*67e74705SXin Li 
emitReadHazard(CGBuilderTy & Builder)3837*67e74705SXin Li void FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
3838*67e74705SXin Li   assert(!Locals.empty());
3839*67e74705SXin Li   llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
3840*67e74705SXin Li   call->setDoesNotThrow();
3841*67e74705SXin Li   call->setCallingConv(CGF.getRuntimeCC());
3842*67e74705SXin Li }
3843*67e74705SXin Li 
3844*67e74705SXin Li /// Emit read hazards in all the protected blocks, i.e. all the blocks
3845*67e74705SXin Li /// which have been inserted since the beginning of the try.
emitHazardsInNewBlocks()3846*67e74705SXin Li void FragileHazards::emitHazardsInNewBlocks() {
3847*67e74705SXin Li   if (Locals.empty()) return;
3848*67e74705SXin Li 
3849*67e74705SXin Li   CGBuilderTy Builder(CGF, CGF.getLLVMContext());
3850*67e74705SXin Li 
3851*67e74705SXin Li   // Iterate through all blocks, skipping those prior to the try.
3852*67e74705SXin Li   for (llvm::Function::iterator
3853*67e74705SXin Li          FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
3854*67e74705SXin Li     llvm::BasicBlock &BB = *FI;
3855*67e74705SXin Li     if (BlocksBeforeTry.count(&BB)) continue;
3856*67e74705SXin Li 
3857*67e74705SXin Li     // Walk through all the calls in the block.
3858*67e74705SXin Li     for (llvm::BasicBlock::iterator
3859*67e74705SXin Li            BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3860*67e74705SXin Li       llvm::Instruction &I = *BI;
3861*67e74705SXin Li 
3862*67e74705SXin Li       // Ignore instructions that aren't non-intrinsic calls.
3863*67e74705SXin Li       // These are the only calls that can possibly call longjmp.
3864*67e74705SXin Li       if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
3865*67e74705SXin Li       if (isa<llvm::IntrinsicInst>(I))
3866*67e74705SXin Li         continue;
3867*67e74705SXin Li 
3868*67e74705SXin Li       // Ignore call sites marked nounwind.  This may be questionable,
3869*67e74705SXin Li       // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
3870*67e74705SXin Li       llvm::CallSite CS(&I);
3871*67e74705SXin Li       if (CS.doesNotThrow()) continue;
3872*67e74705SXin Li 
3873*67e74705SXin Li       // Insert a read hazard before the call.  This will ensure that
3874*67e74705SXin Li       // any writes to the locals are performed before making the
3875*67e74705SXin Li       // call.  If the call throws, then this is sufficient to
3876*67e74705SXin Li       // guarantee correctness as long as it doesn't also write to any
3877*67e74705SXin Li       // locals.
3878*67e74705SXin Li       Builder.SetInsertPoint(&BB, BI);
3879*67e74705SXin Li       emitReadHazard(Builder);
3880*67e74705SXin Li     }
3881*67e74705SXin Li   }
3882*67e74705SXin Li }
3883*67e74705SXin Li 
addIfPresent(llvm::DenseSet<llvm::Value * > & S,llvm::Value * V)3884*67e74705SXin Li static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
3885*67e74705SXin Li   if (V) S.insert(V);
3886*67e74705SXin Li }
3887*67e74705SXin Li 
addIfPresent(llvm::DenseSet<llvm::Value * > & S,Address V)3888*67e74705SXin Li static void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) {
3889*67e74705SXin Li   if (V.isValid()) S.insert(V.getPointer());
3890*67e74705SXin Li }
3891*67e74705SXin Li 
collectLocals()3892*67e74705SXin Li void FragileHazards::collectLocals() {
3893*67e74705SXin Li   // Compute a set of allocas to ignore.
3894*67e74705SXin Li   llvm::DenseSet<llvm::Value*> AllocasToIgnore;
3895*67e74705SXin Li   addIfPresent(AllocasToIgnore, CGF.ReturnValue);
3896*67e74705SXin Li   addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
3897*67e74705SXin Li 
3898*67e74705SXin Li   // Collect all the allocas currently in the function.  This is
3899*67e74705SXin Li   // probably way too aggressive.
3900*67e74705SXin Li   llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
3901*67e74705SXin Li   for (llvm::BasicBlock::iterator
3902*67e74705SXin Li          I = Entry.begin(), E = Entry.end(); I != E; ++I)
3903*67e74705SXin Li     if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3904*67e74705SXin Li       Locals.push_back(&*I);
3905*67e74705SXin Li }
3906*67e74705SXin Li 
GetAsmFnType()3907*67e74705SXin Li llvm::FunctionType *FragileHazards::GetAsmFnType() {
3908*67e74705SXin Li   SmallVector<llvm::Type *, 16> tys(Locals.size());
3909*67e74705SXin Li   for (unsigned i = 0, e = Locals.size(); i != e; ++i)
3910*67e74705SXin Li     tys[i] = Locals[i]->getType();
3911*67e74705SXin Li   return llvm::FunctionType::get(CGF.VoidTy, tys, false);
3912*67e74705SXin Li }
3913*67e74705SXin Li 
3914*67e74705SXin Li /*
3915*67e74705SXin Li 
3916*67e74705SXin Li   Objective-C setjmp-longjmp (sjlj) Exception Handling
3917*67e74705SXin Li   --
3918*67e74705SXin Li 
3919*67e74705SXin Li   A catch buffer is a setjmp buffer plus:
3920*67e74705SXin Li     - a pointer to the exception that was caught
3921*67e74705SXin Li     - a pointer to the previous exception data buffer
3922*67e74705SXin Li     - two pointers of reserved storage
3923*67e74705SXin Li   Therefore catch buffers form a stack, with a pointer to the top
3924*67e74705SXin Li   of the stack kept in thread-local storage.
3925*67e74705SXin Li 
3926*67e74705SXin Li   objc_exception_try_enter pushes a catch buffer onto the EH stack.
3927*67e74705SXin Li   objc_exception_try_exit pops the given catch buffer, which is
3928*67e74705SXin Li     required to be the top of the EH stack.
3929*67e74705SXin Li   objc_exception_throw pops the top of the EH stack, writes the
3930*67e74705SXin Li     thrown exception into the appropriate field, and longjmps
3931*67e74705SXin Li     to the setjmp buffer.  It crashes the process (with a printf
3932*67e74705SXin Li     and an abort()) if there are no catch buffers on the stack.
3933*67e74705SXin Li   objc_exception_extract just reads the exception pointer out of the
3934*67e74705SXin Li     catch buffer.
3935*67e74705SXin Li 
3936*67e74705SXin Li   There's no reason an implementation couldn't use a light-weight
3937*67e74705SXin Li   setjmp here --- something like __builtin_setjmp, but API-compatible
3938*67e74705SXin Li   with the heavyweight setjmp.  This will be more important if we ever
3939*67e74705SXin Li   want to implement correct ObjC/C++ exception interactions for the
3940*67e74705SXin Li   fragile ABI.
3941*67e74705SXin Li 
3942*67e74705SXin Li   Note that for this use of setjmp/longjmp to be correct, we may need
3943*67e74705SXin Li   to mark some local variables volatile: if a non-volatile local
3944*67e74705SXin Li   variable is modified between the setjmp and the longjmp, it has
3945*67e74705SXin Li   indeterminate value.  For the purposes of LLVM IR, it may be
3946*67e74705SXin Li   sufficient to make loads and stores within the @try (to variables
3947*67e74705SXin Li   declared outside the @try) volatile.  This is necessary for
3948*67e74705SXin Li   optimized correctness, but is not currently being done; this is
3949*67e74705SXin Li   being tracked as rdar://problem/8160285
3950*67e74705SXin Li 
3951*67e74705SXin Li   The basic framework for a @try-catch-finally is as follows:
3952*67e74705SXin Li   {
3953*67e74705SXin Li   objc_exception_data d;
3954*67e74705SXin Li   id _rethrow = null;
3955*67e74705SXin Li   bool _call_try_exit = true;
3956*67e74705SXin Li 
3957*67e74705SXin Li   objc_exception_try_enter(&d);
3958*67e74705SXin Li   if (!setjmp(d.jmp_buf)) {
3959*67e74705SXin Li   ... try body ...
3960*67e74705SXin Li   } else {
3961*67e74705SXin Li   // exception path
3962*67e74705SXin Li   id _caught = objc_exception_extract(&d);
3963*67e74705SXin Li 
3964*67e74705SXin Li   // enter new try scope for handlers
3965*67e74705SXin Li   if (!setjmp(d.jmp_buf)) {
3966*67e74705SXin Li   ... match exception and execute catch blocks ...
3967*67e74705SXin Li 
3968*67e74705SXin Li   // fell off end, rethrow.
3969*67e74705SXin Li   _rethrow = _caught;
3970*67e74705SXin Li   ... jump-through-finally to finally_rethrow ...
3971*67e74705SXin Li   } else {
3972*67e74705SXin Li   // exception in catch block
3973*67e74705SXin Li   _rethrow = objc_exception_extract(&d);
3974*67e74705SXin Li   _call_try_exit = false;
3975*67e74705SXin Li   ... jump-through-finally to finally_rethrow ...
3976*67e74705SXin Li   }
3977*67e74705SXin Li   }
3978*67e74705SXin Li   ... jump-through-finally to finally_end ...
3979*67e74705SXin Li 
3980*67e74705SXin Li   finally:
3981*67e74705SXin Li   if (_call_try_exit)
3982*67e74705SXin Li   objc_exception_try_exit(&d);
3983*67e74705SXin Li 
3984*67e74705SXin Li   ... finally block ....
3985*67e74705SXin Li   ... dispatch to finally destination ...
3986*67e74705SXin Li 
3987*67e74705SXin Li   finally_rethrow:
3988*67e74705SXin Li   objc_exception_throw(_rethrow);
3989*67e74705SXin Li 
3990*67e74705SXin Li   finally_end:
3991*67e74705SXin Li   }
3992*67e74705SXin Li 
3993*67e74705SXin Li   This framework differs slightly from the one gcc uses, in that gcc
3994*67e74705SXin Li   uses _rethrow to determine if objc_exception_try_exit should be called
3995*67e74705SXin Li   and if the object should be rethrown. This breaks in the face of
3996*67e74705SXin Li   throwing nil and introduces unnecessary branches.
3997*67e74705SXin Li 
3998*67e74705SXin Li   We specialize this framework for a few particular circumstances:
3999*67e74705SXin Li 
4000*67e74705SXin Li   - If there are no catch blocks, then we avoid emitting the second
4001*67e74705SXin Li   exception handling context.
4002*67e74705SXin Li 
4003*67e74705SXin Li   - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
4004*67e74705SXin Li   e)) we avoid emitting the code to rethrow an uncaught exception.
4005*67e74705SXin Li 
4006*67e74705SXin Li   - FIXME: If there is no @finally block we can do a few more
4007*67e74705SXin Li   simplifications.
4008*67e74705SXin Li 
4009*67e74705SXin Li   Rethrows and Jumps-Through-Finally
4010*67e74705SXin Li   --
4011*67e74705SXin Li 
4012*67e74705SXin Li   '@throw;' is supported by pushing the currently-caught exception
4013*67e74705SXin Li   onto ObjCEHStack while the @catch blocks are emitted.
4014*67e74705SXin Li 
4015*67e74705SXin Li   Branches through the @finally block are handled with an ordinary
4016*67e74705SXin Li   normal cleanup.  We do not register an EH cleanup; fragile-ABI ObjC
4017*67e74705SXin Li   exceptions are not compatible with C++ exceptions, and this is
4018*67e74705SXin Li   hardly the only place where this will go wrong.
4019*67e74705SXin Li 
4020*67e74705SXin Li   @synchronized(expr) { stmt; } is emitted as if it were:
4021*67e74705SXin Li     id synch_value = expr;
4022*67e74705SXin Li     objc_sync_enter(synch_value);
4023*67e74705SXin Li     @try { stmt; } @finally { objc_sync_exit(synch_value); }
4024*67e74705SXin Li */
4025*67e74705SXin Li 
EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction & CGF,const Stmt & S)4026*67e74705SXin Li void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
4027*67e74705SXin Li                                           const Stmt &S) {
4028*67e74705SXin Li   bool isTry = isa<ObjCAtTryStmt>(S);
4029*67e74705SXin Li 
4030*67e74705SXin Li   // A destination for the fall-through edges of the catch handlers to
4031*67e74705SXin Li   // jump to.
4032*67e74705SXin Li   CodeGenFunction::JumpDest FinallyEnd =
4033*67e74705SXin Li     CGF.getJumpDestInCurrentScope("finally.end");
4034*67e74705SXin Li 
4035*67e74705SXin Li   // A destination for the rethrow edge of the catch handlers to jump
4036*67e74705SXin Li   // to.
4037*67e74705SXin Li   CodeGenFunction::JumpDest FinallyRethrow =
4038*67e74705SXin Li     CGF.getJumpDestInCurrentScope("finally.rethrow");
4039*67e74705SXin Li 
4040*67e74705SXin Li   // For @synchronized, call objc_sync_enter(sync.expr). The
4041*67e74705SXin Li   // evaluation of the expression must occur before we enter the
4042*67e74705SXin Li   // @synchronized.  We can't avoid a temp here because we need the
4043*67e74705SXin Li   // value to be preserved.  If the backend ever does liveness
4044*67e74705SXin Li   // correctly after setjmp, this will be unnecessary.
4045*67e74705SXin Li   Address SyncArgSlot = Address::invalid();
4046*67e74705SXin Li   if (!isTry) {
4047*67e74705SXin Li     llvm::Value *SyncArg =
4048*67e74705SXin Li       CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4049*67e74705SXin Li     SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
4050*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
4051*67e74705SXin Li 
4052*67e74705SXin Li     SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(),
4053*67e74705SXin Li                                        CGF.getPointerAlign(), "sync.arg");
4054*67e74705SXin Li     CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
4055*67e74705SXin Li   }
4056*67e74705SXin Li 
4057*67e74705SXin Li   // Allocate memory for the setjmp buffer.  This needs to be kept
4058*67e74705SXin Li   // live throughout the try and catch blocks.
4059*67e74705SXin Li   Address ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
4060*67e74705SXin Li                                                CGF.getPointerAlign(),
4061*67e74705SXin Li                                                "exceptiondata.ptr");
4062*67e74705SXin Li 
4063*67e74705SXin Li   // Create the fragile hazards.  Note that this will not capture any
4064*67e74705SXin Li   // of the allocas required for exception processing, but will
4065*67e74705SXin Li   // capture the current basic block (which extends all the way to the
4066*67e74705SXin Li   // setjmp call) as "before the @try".
4067*67e74705SXin Li   FragileHazards Hazards(CGF);
4068*67e74705SXin Li 
4069*67e74705SXin Li   // Create a flag indicating whether the cleanup needs to call
4070*67e74705SXin Li   // objc_exception_try_exit.  This is true except when
4071*67e74705SXin Li   //   - no catches match and we're branching through the cleanup
4072*67e74705SXin Li   //     just to rethrow the exception, or
4073*67e74705SXin Li   //   - a catch matched and we're falling out of the catch handler.
4074*67e74705SXin Li   // The setjmp-safety rule here is that we should always store to this
4075*67e74705SXin Li   // variable in a place that dominates the branch through the cleanup
4076*67e74705SXin Li   // without passing through any setjmps.
4077*67e74705SXin Li   Address CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
4078*67e74705SXin Li                                                 CharUnits::One(),
4079*67e74705SXin Li                                                 "_call_try_exit");
4080*67e74705SXin Li 
4081*67e74705SXin Li   // A slot containing the exception to rethrow.  Only needed when we
4082*67e74705SXin Li   // have both a @catch and a @finally.
4083*67e74705SXin Li   Address PropagatingExnVar = Address::invalid();
4084*67e74705SXin Li 
4085*67e74705SXin Li   // Push a normal cleanup to leave the try scope.
4086*67e74705SXin Li   CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
4087*67e74705SXin Li                                                  SyncArgSlot,
4088*67e74705SXin Li                                                  CallTryExitVar,
4089*67e74705SXin Li                                                  ExceptionData,
4090*67e74705SXin Li                                                  &ObjCTypes);
4091*67e74705SXin Li 
4092*67e74705SXin Li   // Enter a try block:
4093*67e74705SXin Li   //  - Call objc_exception_try_enter to push ExceptionData on top of
4094*67e74705SXin Li   //    the EH stack.
4095*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
4096*67e74705SXin Li                               ExceptionData.getPointer());
4097*67e74705SXin Li 
4098*67e74705SXin Li   //  - Call setjmp on the exception data buffer.
4099*67e74705SXin Li   llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
4100*67e74705SXin Li   llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
4101*67e74705SXin Li   llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
4102*67e74705SXin Li       ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4103*67e74705SXin Li       "setjmp_buffer");
4104*67e74705SXin Li   llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
4105*67e74705SXin Li       ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
4106*67e74705SXin Li   SetJmpResult->setCanReturnTwice();
4107*67e74705SXin Li 
4108*67e74705SXin Li   // If setjmp returned 0, enter the protected block; otherwise,
4109*67e74705SXin Li   // branch to the handler.
4110*67e74705SXin Li   llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
4111*67e74705SXin Li   llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
4112*67e74705SXin Li   llvm::Value *DidCatch =
4113*67e74705SXin Li     CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
4114*67e74705SXin Li   CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4115*67e74705SXin Li 
4116*67e74705SXin Li   // Emit the protected block.
4117*67e74705SXin Li   CGF.EmitBlock(TryBlock);
4118*67e74705SXin Li   CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4119*67e74705SXin Li   CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4120*67e74705SXin Li                      : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4121*67e74705SXin Li 
4122*67e74705SXin Li   CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
4123*67e74705SXin Li 
4124*67e74705SXin Li   // Emit the exception handler block.
4125*67e74705SXin Li   CGF.EmitBlock(TryHandler);
4126*67e74705SXin Li 
4127*67e74705SXin Li   // Don't optimize loads of the in-scope locals across this point.
4128*67e74705SXin Li   Hazards.emitWriteHazard();
4129*67e74705SXin Li 
4130*67e74705SXin Li   // For a @synchronized (or a @try with no catches), just branch
4131*67e74705SXin Li   // through the cleanup to the rethrow block.
4132*67e74705SXin Li   if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4133*67e74705SXin Li     // Tell the cleanup not to re-pop the exit.
4134*67e74705SXin Li     CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4135*67e74705SXin Li     CGF.EmitBranchThroughCleanup(FinallyRethrow);
4136*67e74705SXin Li 
4137*67e74705SXin Li   // Otherwise, we have to match against the caught exceptions.
4138*67e74705SXin Li   } else {
4139*67e74705SXin Li     // Retrieve the exception object.  We may emit multiple blocks but
4140*67e74705SXin Li     // nothing can cross this so the value is already in SSA form.
4141*67e74705SXin Li     llvm::CallInst *Caught =
4142*67e74705SXin Li       CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4143*67e74705SXin Li                                   ExceptionData.getPointer(), "caught");
4144*67e74705SXin Li 
4145*67e74705SXin Li     // Push the exception to rethrow onto the EH value stack for the
4146*67e74705SXin Li     // benefit of any @throws in the handlers.
4147*67e74705SXin Li     CGF.ObjCEHValueStack.push_back(Caught);
4148*67e74705SXin Li 
4149*67e74705SXin Li     const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
4150*67e74705SXin Li 
4151*67e74705SXin Li     bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
4152*67e74705SXin Li 
4153*67e74705SXin Li     llvm::BasicBlock *CatchBlock = nullptr;
4154*67e74705SXin Li     llvm::BasicBlock *CatchHandler = nullptr;
4155*67e74705SXin Li     if (HasFinally) {
4156*67e74705SXin Li       // Save the currently-propagating exception before
4157*67e74705SXin Li       // objc_exception_try_enter clears the exception slot.
4158*67e74705SXin Li       PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
4159*67e74705SXin Li                                                CGF.getPointerAlign(),
4160*67e74705SXin Li                                                "propagating_exception");
4161*67e74705SXin Li       CGF.Builder.CreateStore(Caught, PropagatingExnVar);
4162*67e74705SXin Li 
4163*67e74705SXin Li       // Enter a new exception try block (in case a @catch block
4164*67e74705SXin Li       // throws an exception).
4165*67e74705SXin Li       CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
4166*67e74705SXin Li                                   ExceptionData.getPointer());
4167*67e74705SXin Li 
4168*67e74705SXin Li       llvm::CallInst *SetJmpResult =
4169*67e74705SXin Li         CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(),
4170*67e74705SXin Li                                     SetJmpBuffer, "setjmp.result");
4171*67e74705SXin Li       SetJmpResult->setCanReturnTwice();
4172*67e74705SXin Li 
4173*67e74705SXin Li       llvm::Value *Threw =
4174*67e74705SXin Li         CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
4175*67e74705SXin Li 
4176*67e74705SXin Li       CatchBlock = CGF.createBasicBlock("catch");
4177*67e74705SXin Li       CatchHandler = CGF.createBasicBlock("catch_for_catch");
4178*67e74705SXin Li       CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4179*67e74705SXin Li 
4180*67e74705SXin Li       CGF.EmitBlock(CatchBlock);
4181*67e74705SXin Li     }
4182*67e74705SXin Li 
4183*67e74705SXin Li     CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
4184*67e74705SXin Li 
4185*67e74705SXin Li     // Handle catch list. As a special case we check if everything is
4186*67e74705SXin Li     // matched and avoid generating code for falling off the end if
4187*67e74705SXin Li     // so.
4188*67e74705SXin Li     bool AllMatched = false;
4189*67e74705SXin Li     for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
4190*67e74705SXin Li       const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
4191*67e74705SXin Li 
4192*67e74705SXin Li       const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
4193*67e74705SXin Li       const ObjCObjectPointerType *OPT = nullptr;
4194*67e74705SXin Li 
4195*67e74705SXin Li       // catch(...) always matches.
4196*67e74705SXin Li       if (!CatchParam) {
4197*67e74705SXin Li         AllMatched = true;
4198*67e74705SXin Li       } else {
4199*67e74705SXin Li         OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
4200*67e74705SXin Li 
4201*67e74705SXin Li         // catch(id e) always matches under this ABI, since only
4202*67e74705SXin Li         // ObjC exceptions end up here in the first place.
4203*67e74705SXin Li         // FIXME: For the time being we also match id<X>; this should
4204*67e74705SXin Li         // be rejected by Sema instead.
4205*67e74705SXin Li         if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
4206*67e74705SXin Li           AllMatched = true;
4207*67e74705SXin Li       }
4208*67e74705SXin Li 
4209*67e74705SXin Li       // If this is a catch-all, we don't need to test anything.
4210*67e74705SXin Li       if (AllMatched) {
4211*67e74705SXin Li         CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4212*67e74705SXin Li 
4213*67e74705SXin Li         if (CatchParam) {
4214*67e74705SXin Li           CGF.EmitAutoVarDecl(*CatchParam);
4215*67e74705SXin Li           assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4216*67e74705SXin Li 
4217*67e74705SXin Li           // These types work out because ConvertType(id) == i8*.
4218*67e74705SXin Li           EmitInitOfCatchParam(CGF, Caught, CatchParam);
4219*67e74705SXin Li         }
4220*67e74705SXin Li 
4221*67e74705SXin Li         CGF.EmitStmt(CatchStmt->getCatchBody());
4222*67e74705SXin Li 
4223*67e74705SXin Li         // The scope of the catch variable ends right here.
4224*67e74705SXin Li         CatchVarCleanups.ForceCleanup();
4225*67e74705SXin Li 
4226*67e74705SXin Li         CGF.EmitBranchThroughCleanup(FinallyEnd);
4227*67e74705SXin Li         break;
4228*67e74705SXin Li       }
4229*67e74705SXin Li 
4230*67e74705SXin Li       assert(OPT && "Unexpected non-object pointer type in @catch");
4231*67e74705SXin Li       const ObjCObjectType *ObjTy = OPT->getObjectType();
4232*67e74705SXin Li 
4233*67e74705SXin Li       // FIXME: @catch (Class c) ?
4234*67e74705SXin Li       ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
4235*67e74705SXin Li       assert(IDecl && "Catch parameter must have Objective-C type!");
4236*67e74705SXin Li 
4237*67e74705SXin Li       // Check if the @catch block matches the exception object.
4238*67e74705SXin Li       llvm::Value *Class = EmitClassRef(CGF, IDecl);
4239*67e74705SXin Li 
4240*67e74705SXin Li       llvm::Value *matchArgs[] = { Class, Caught };
4241*67e74705SXin Li       llvm::CallInst *Match =
4242*67e74705SXin Li         CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionMatchFn(),
4243*67e74705SXin Li                                     matchArgs, "match");
4244*67e74705SXin Li 
4245*67e74705SXin Li       llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
4246*67e74705SXin Li       llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
4247*67e74705SXin Li 
4248*67e74705SXin Li       CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
4249*67e74705SXin Li                                MatchedBlock, NextCatchBlock);
4250*67e74705SXin Li 
4251*67e74705SXin Li       // Emit the @catch block.
4252*67e74705SXin Li       CGF.EmitBlock(MatchedBlock);
4253*67e74705SXin Li 
4254*67e74705SXin Li       // Collect any cleanups for the catch variable.  The scope lasts until
4255*67e74705SXin Li       // the end of the catch body.
4256*67e74705SXin Li       CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4257*67e74705SXin Li 
4258*67e74705SXin Li       CGF.EmitAutoVarDecl(*CatchParam);
4259*67e74705SXin Li       assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4260*67e74705SXin Li 
4261*67e74705SXin Li       // Initialize the catch variable.
4262*67e74705SXin Li       llvm::Value *Tmp =
4263*67e74705SXin Li         CGF.Builder.CreateBitCast(Caught,
4264*67e74705SXin Li                                   CGF.ConvertType(CatchParam->getType()));
4265*67e74705SXin Li       EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4266*67e74705SXin Li 
4267*67e74705SXin Li       CGF.EmitStmt(CatchStmt->getCatchBody());
4268*67e74705SXin Li 
4269*67e74705SXin Li       // We're done with the catch variable.
4270*67e74705SXin Li       CatchVarCleanups.ForceCleanup();
4271*67e74705SXin Li 
4272*67e74705SXin Li       CGF.EmitBranchThroughCleanup(FinallyEnd);
4273*67e74705SXin Li 
4274*67e74705SXin Li       CGF.EmitBlock(NextCatchBlock);
4275*67e74705SXin Li     }
4276*67e74705SXin Li 
4277*67e74705SXin Li     CGF.ObjCEHValueStack.pop_back();
4278*67e74705SXin Li 
4279*67e74705SXin Li     // If nothing wanted anything to do with the caught exception,
4280*67e74705SXin Li     // kill the extract call.
4281*67e74705SXin Li     if (Caught->use_empty())
4282*67e74705SXin Li       Caught->eraseFromParent();
4283*67e74705SXin Li 
4284*67e74705SXin Li     if (!AllMatched)
4285*67e74705SXin Li       CGF.EmitBranchThroughCleanup(FinallyRethrow);
4286*67e74705SXin Li 
4287*67e74705SXin Li     if (HasFinally) {
4288*67e74705SXin Li       // Emit the exception handler for the @catch blocks.
4289*67e74705SXin Li       CGF.EmitBlock(CatchHandler);
4290*67e74705SXin Li 
4291*67e74705SXin Li       // In theory we might now need a write hazard, but actually it's
4292*67e74705SXin Li       // unnecessary because there's no local-accessing code between
4293*67e74705SXin Li       // the try's write hazard and here.
4294*67e74705SXin Li       //Hazards.emitWriteHazard();
4295*67e74705SXin Li 
4296*67e74705SXin Li       // Extract the new exception and save it to the
4297*67e74705SXin Li       // propagating-exception slot.
4298*67e74705SXin Li       assert(PropagatingExnVar.isValid());
4299*67e74705SXin Li       llvm::CallInst *NewCaught =
4300*67e74705SXin Li         CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4301*67e74705SXin Li                                     ExceptionData.getPointer(), "caught");
4302*67e74705SXin Li       CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
4303*67e74705SXin Li 
4304*67e74705SXin Li       // Don't pop the catch handler; the throw already did.
4305*67e74705SXin Li       CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4306*67e74705SXin Li       CGF.EmitBranchThroughCleanup(FinallyRethrow);
4307*67e74705SXin Li     }
4308*67e74705SXin Li   }
4309*67e74705SXin Li 
4310*67e74705SXin Li   // Insert read hazards as required in the new blocks.
4311*67e74705SXin Li   Hazards.emitHazardsInNewBlocks();
4312*67e74705SXin Li 
4313*67e74705SXin Li   // Pop the cleanup.
4314*67e74705SXin Li   CGF.Builder.restoreIP(TryFallthroughIP);
4315*67e74705SXin Li   if (CGF.HaveInsertPoint())
4316*67e74705SXin Li     CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4317*67e74705SXin Li   CGF.PopCleanupBlock();
4318*67e74705SXin Li   CGF.EmitBlock(FinallyEnd.getBlock(), true);
4319*67e74705SXin Li 
4320*67e74705SXin Li   // Emit the rethrow block.
4321*67e74705SXin Li   CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
4322*67e74705SXin Li   CGF.EmitBlock(FinallyRethrow.getBlock(), true);
4323*67e74705SXin Li   if (CGF.HaveInsertPoint()) {
4324*67e74705SXin Li     // If we have a propagating-exception variable, check it.
4325*67e74705SXin Li     llvm::Value *PropagatingExn;
4326*67e74705SXin Li     if (PropagatingExnVar.isValid()) {
4327*67e74705SXin Li       PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
4328*67e74705SXin Li 
4329*67e74705SXin Li     // Otherwise, just look in the buffer for the exception to throw.
4330*67e74705SXin Li     } else {
4331*67e74705SXin Li       llvm::CallInst *Caught =
4332*67e74705SXin Li         CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4333*67e74705SXin Li                                     ExceptionData.getPointer());
4334*67e74705SXin Li       PropagatingExn = Caught;
4335*67e74705SXin Li     }
4336*67e74705SXin Li 
4337*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
4338*67e74705SXin Li                                 PropagatingExn);
4339*67e74705SXin Li     CGF.Builder.CreateUnreachable();
4340*67e74705SXin Li   }
4341*67e74705SXin Li 
4342*67e74705SXin Li   CGF.Builder.restoreIP(SavedIP);
4343*67e74705SXin Li }
4344*67e74705SXin Li 
EmitThrowStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtThrowStmt & S,bool ClearInsertionPoint)4345*67e74705SXin Li void CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
4346*67e74705SXin Li                               const ObjCAtThrowStmt &S,
4347*67e74705SXin Li                               bool ClearInsertionPoint) {
4348*67e74705SXin Li   llvm::Value *ExceptionAsObject;
4349*67e74705SXin Li 
4350*67e74705SXin Li   if (const Expr *ThrowExpr = S.getThrowExpr()) {
4351*67e74705SXin Li     llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
4352*67e74705SXin Li     ExceptionAsObject =
4353*67e74705SXin Li       CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4354*67e74705SXin Li   } else {
4355*67e74705SXin Li     assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
4356*67e74705SXin Li            "Unexpected rethrow outside @catch block.");
4357*67e74705SXin Li     ExceptionAsObject = CGF.ObjCEHValueStack.back();
4358*67e74705SXin Li   }
4359*67e74705SXin Li 
4360*67e74705SXin Li   CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4361*67e74705SXin Li     ->setDoesNotReturn();
4362*67e74705SXin Li   CGF.Builder.CreateUnreachable();
4363*67e74705SXin Li 
4364*67e74705SXin Li   // Clear the insertion point to indicate we are in unreachable code.
4365*67e74705SXin Li   if (ClearInsertionPoint)
4366*67e74705SXin Li     CGF.Builder.ClearInsertionPoint();
4367*67e74705SXin Li }
4368*67e74705SXin Li 
4369*67e74705SXin Li /// EmitObjCWeakRead - Code gen for loading value of a __weak
4370*67e74705SXin Li /// object: objc_read_weak (id *src)
4371*67e74705SXin Li ///
EmitObjCWeakRead(CodeGen::CodeGenFunction & CGF,Address AddrWeakObj)4372*67e74705SXin Li llvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
4373*67e74705SXin Li                                           Address AddrWeakObj) {
4374*67e74705SXin Li   llvm::Type* DestTy = AddrWeakObj.getElementType();
4375*67e74705SXin Li   AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
4376*67e74705SXin Li                                           ObjCTypes.PtrObjectPtrTy);
4377*67e74705SXin Li   llvm::Value *read_weak =
4378*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
4379*67e74705SXin Li                                 AddrWeakObj.getPointer(), "weakread");
4380*67e74705SXin Li   read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
4381*67e74705SXin Li   return read_weak;
4382*67e74705SXin Li }
4383*67e74705SXin Li 
4384*67e74705SXin Li /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4385*67e74705SXin Li /// objc_assign_weak (id src, id *dst)
4386*67e74705SXin Li ///
EmitObjCWeakAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst)4387*67e74705SXin Li void CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
4388*67e74705SXin Li                                    llvm::Value *src, Address dst) {
4389*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
4390*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
4391*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4392*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
4393*67e74705SXin Li     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4394*67e74705SXin Li       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4395*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4396*67e74705SXin Li   }
4397*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4398*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4399*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer() };
4400*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4401*67e74705SXin Li                               args, "weakassign");
4402*67e74705SXin Li }
4403*67e74705SXin Li 
4404*67e74705SXin Li /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4405*67e74705SXin Li /// objc_assign_global (id src, id *dst)
4406*67e74705SXin Li ///
EmitObjCGlobalAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst,bool threadlocal)4407*67e74705SXin Li void CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4408*67e74705SXin Li                                      llvm::Value *src, Address dst,
4409*67e74705SXin Li                                      bool threadlocal) {
4410*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
4411*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
4412*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4413*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
4414*67e74705SXin Li     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4415*67e74705SXin Li       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4416*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4417*67e74705SXin Li   }
4418*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4419*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4420*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer() };
4421*67e74705SXin Li   if (!threadlocal)
4422*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4423*67e74705SXin Li                                 args, "globalassign");
4424*67e74705SXin Li   else
4425*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4426*67e74705SXin Li                                 args, "threadlocalassign");
4427*67e74705SXin Li }
4428*67e74705SXin Li 
4429*67e74705SXin Li /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
4430*67e74705SXin Li /// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
4431*67e74705SXin Li ///
EmitObjCIvarAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst,llvm::Value * ivarOffset)4432*67e74705SXin Li void CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4433*67e74705SXin Li                                    llvm::Value *src, Address dst,
4434*67e74705SXin Li                                    llvm::Value *ivarOffset) {
4435*67e74705SXin Li   assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
4436*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
4437*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
4438*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4439*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
4440*67e74705SXin Li     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4441*67e74705SXin Li       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4442*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4443*67e74705SXin Li   }
4444*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4445*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4446*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
4447*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4448*67e74705SXin Li }
4449*67e74705SXin Li 
4450*67e74705SXin Li /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
4451*67e74705SXin Li /// objc_assign_strongCast (id src, id *dst)
4452*67e74705SXin Li ///
EmitObjCStrongCastAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst)4453*67e74705SXin Li void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4454*67e74705SXin Li                                          llvm::Value *src, Address dst) {
4455*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
4456*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
4457*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4458*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
4459*67e74705SXin Li     src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4460*67e74705SXin Li       : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4461*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4462*67e74705SXin Li   }
4463*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4464*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4465*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer() };
4466*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4467*67e74705SXin Li                               args, "strongassign");
4468*67e74705SXin Li }
4469*67e74705SXin Li 
EmitGCMemmoveCollectable(CodeGen::CodeGenFunction & CGF,Address DestPtr,Address SrcPtr,llvm::Value * size)4470*67e74705SXin Li void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4471*67e74705SXin Li                                          Address DestPtr,
4472*67e74705SXin Li                                          Address SrcPtr,
4473*67e74705SXin Li                                          llvm::Value *size) {
4474*67e74705SXin Li   SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4475*67e74705SXin Li   DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4476*67e74705SXin Li   llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size };
4477*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4478*67e74705SXin Li }
4479*67e74705SXin Li 
4480*67e74705SXin Li /// EmitObjCValueForIvar - Code Gen for ivar reference.
4481*67e74705SXin Li ///
EmitObjCValueForIvar(CodeGen::CodeGenFunction & CGF,QualType ObjectTy,llvm::Value * BaseValue,const ObjCIvarDecl * Ivar,unsigned CVRQualifiers)4482*67e74705SXin Li LValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4483*67e74705SXin Li                                        QualType ObjectTy,
4484*67e74705SXin Li                                        llvm::Value *BaseValue,
4485*67e74705SXin Li                                        const ObjCIvarDecl *Ivar,
4486*67e74705SXin Li                                        unsigned CVRQualifiers) {
4487*67e74705SXin Li   const ObjCInterfaceDecl *ID =
4488*67e74705SXin Li     ObjectTy->getAs<ObjCObjectType>()->getInterface();
4489*67e74705SXin Li   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4490*67e74705SXin Li                                   EmitIvarOffset(CGF, ID, Ivar));
4491*67e74705SXin Li }
4492*67e74705SXin Li 
EmitIvarOffset(CodeGen::CodeGenFunction & CGF,const ObjCInterfaceDecl * Interface,const ObjCIvarDecl * Ivar)4493*67e74705SXin Li llvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4494*67e74705SXin Li                                        const ObjCInterfaceDecl *Interface,
4495*67e74705SXin Li                                        const ObjCIvarDecl *Ivar) {
4496*67e74705SXin Li   uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4497*67e74705SXin Li   return llvm::ConstantInt::get(
4498*67e74705SXin Li     CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4499*67e74705SXin Li     Offset);
4500*67e74705SXin Li }
4501*67e74705SXin Li 
4502*67e74705SXin Li /* *** Private Interface *** */
4503*67e74705SXin Li 
4504*67e74705SXin Li /// EmitImageInfo - Emit the image info marker used to encode some module
4505*67e74705SXin Li /// level information.
4506*67e74705SXin Li ///
4507*67e74705SXin Li /// See: <rdr://4810609&4810587&4810587>
4508*67e74705SXin Li /// struct IMAGE_INFO {
4509*67e74705SXin Li ///   unsigned version;
4510*67e74705SXin Li ///   unsigned flags;
4511*67e74705SXin Li /// };
4512*67e74705SXin Li enum ImageInfoFlags {
4513*67e74705SXin Li   eImageInfo_FixAndContinue      = (1 << 0), // This flag is no longer set by clang.
4514*67e74705SXin Li   eImageInfo_GarbageCollected    = (1 << 1),
4515*67e74705SXin Li   eImageInfo_GCOnly              = (1 << 2),
4516*67e74705SXin Li   eImageInfo_OptimizedByDyld     = (1 << 3), // This flag is set by the dyld shared cache.
4517*67e74705SXin Li 
4518*67e74705SXin Li   // A flag indicating that the module has no instances of a @synthesize of a
4519*67e74705SXin Li   // superclass variable. <rdar://problem/6803242>
4520*67e74705SXin Li   eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
4521*67e74705SXin Li   eImageInfo_ImageIsSimulated    = (1 << 5),
4522*67e74705SXin Li   eImageInfo_ClassProperties     = (1 << 6)
4523*67e74705SXin Li };
4524*67e74705SXin Li 
EmitImageInfo()4525*67e74705SXin Li void CGObjCCommonMac::EmitImageInfo() {
4526*67e74705SXin Li   unsigned version = 0; // Version is unused?
4527*67e74705SXin Li   const char *Section = (ObjCABI == 1) ?
4528*67e74705SXin Li     "__OBJC, __image_info,regular" :
4529*67e74705SXin Li     "__DATA, __objc_imageinfo, regular, no_dead_strip";
4530*67e74705SXin Li 
4531*67e74705SXin Li   // Generate module-level named metadata to convey this information to the
4532*67e74705SXin Li   // linker and code-gen.
4533*67e74705SXin Li   llvm::Module &Mod = CGM.getModule();
4534*67e74705SXin Li 
4535*67e74705SXin Li   // Add the ObjC ABI version to the module flags.
4536*67e74705SXin Li   Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
4537*67e74705SXin Li   Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
4538*67e74705SXin Li                     version);
4539*67e74705SXin Li   Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
4540*67e74705SXin Li                     llvm::MDString::get(VMContext,Section));
4541*67e74705SXin Li 
4542*67e74705SXin Li   if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4543*67e74705SXin Li     // Non-GC overrides those files which specify GC.
4544*67e74705SXin Li     Mod.addModuleFlag(llvm::Module::Override,
4545*67e74705SXin Li                       "Objective-C Garbage Collection", (uint32_t)0);
4546*67e74705SXin Li   } else {
4547*67e74705SXin Li     // Add the ObjC garbage collection value.
4548*67e74705SXin Li     Mod.addModuleFlag(llvm::Module::Error,
4549*67e74705SXin Li                       "Objective-C Garbage Collection",
4550*67e74705SXin Li                       eImageInfo_GarbageCollected);
4551*67e74705SXin Li 
4552*67e74705SXin Li     if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4553*67e74705SXin Li       // Add the ObjC GC Only value.
4554*67e74705SXin Li       Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
4555*67e74705SXin Li                         eImageInfo_GCOnly);
4556*67e74705SXin Li 
4557*67e74705SXin Li       // Require that GC be specified and set to eImageInfo_GarbageCollected.
4558*67e74705SXin Li       llvm::Metadata *Ops[2] = {
4559*67e74705SXin Li           llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
4560*67e74705SXin Li           llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
4561*67e74705SXin Li               llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
4562*67e74705SXin Li       Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
4563*67e74705SXin Li                         llvm::MDNode::get(VMContext, Ops));
4564*67e74705SXin Li     }
4565*67e74705SXin Li   }
4566*67e74705SXin Li 
4567*67e74705SXin Li   // Indicate whether we're compiling this to run on a simulator.
4568*67e74705SXin Li   const llvm::Triple &Triple = CGM.getTarget().getTriple();
4569*67e74705SXin Li   if ((Triple.isiOS() || Triple.isWatchOS()) &&
4570*67e74705SXin Li       (Triple.getArch() == llvm::Triple::x86 ||
4571*67e74705SXin Li        Triple.getArch() == llvm::Triple::x86_64))
4572*67e74705SXin Li     Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
4573*67e74705SXin Li                       eImageInfo_ImageIsSimulated);
4574*67e74705SXin Li 
4575*67e74705SXin Li   // Indicate whether we are generating class properties.
4576*67e74705SXin Li   Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties",
4577*67e74705SXin Li                     eImageInfo_ClassProperties);
4578*67e74705SXin Li }
4579*67e74705SXin Li 
4580*67e74705SXin Li // struct objc_module {
4581*67e74705SXin Li //   unsigned long version;
4582*67e74705SXin Li //   unsigned long size;
4583*67e74705SXin Li //   const char *name;
4584*67e74705SXin Li //   Symtab symtab;
4585*67e74705SXin Li // };
4586*67e74705SXin Li 
4587*67e74705SXin Li // FIXME: Get from somewhere
4588*67e74705SXin Li static const int ModuleVersion = 7;
4589*67e74705SXin Li 
EmitModuleInfo()4590*67e74705SXin Li void CGObjCMac::EmitModuleInfo() {
4591*67e74705SXin Li   uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4592*67e74705SXin Li 
4593*67e74705SXin Li   llvm::Constant *Values[] = {
4594*67e74705SXin Li     llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4595*67e74705SXin Li     llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4596*67e74705SXin Li     // This used to be the filename, now it is unused. <rdr://4327263>
4597*67e74705SXin Li     GetClassName(StringRef("")),
4598*67e74705SXin Li     EmitModuleSymbols()
4599*67e74705SXin Li   };
4600*67e74705SXin Li   CreateMetadataVar("OBJC_MODULES",
4601*67e74705SXin Li                     llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
4602*67e74705SXin Li                     "__OBJC,__module_info,regular,no_dead_strip",
4603*67e74705SXin Li                     CGM.getPointerAlign(), true);
4604*67e74705SXin Li }
4605*67e74705SXin Li 
EmitModuleSymbols()4606*67e74705SXin Li llvm::Constant *CGObjCMac::EmitModuleSymbols() {
4607*67e74705SXin Li   unsigned NumClasses = DefinedClasses.size();
4608*67e74705SXin Li   unsigned NumCategories = DefinedCategories.size();
4609*67e74705SXin Li 
4610*67e74705SXin Li   // Return null if no symbols were defined.
4611*67e74705SXin Li   if (!NumClasses && !NumCategories)
4612*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4613*67e74705SXin Li 
4614*67e74705SXin Li   llvm::Constant *Values[5];
4615*67e74705SXin Li   Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
4616*67e74705SXin Li   Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
4617*67e74705SXin Li   Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4618*67e74705SXin Li   Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
4619*67e74705SXin Li 
4620*67e74705SXin Li   // The runtime expects exactly the list of defined classes followed
4621*67e74705SXin Li   // by the list of defined categories, in a single array.
4622*67e74705SXin Li   SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
4623*67e74705SXin Li   for (unsigned i=0; i<NumClasses; i++) {
4624*67e74705SXin Li     const ObjCInterfaceDecl *ID = ImplementedClasses[i];
4625*67e74705SXin Li     assert(ID);
4626*67e74705SXin Li     if (ObjCImplementationDecl *IMP = ID->getImplementation())
4627*67e74705SXin Li       // We are implementing a weak imported interface. Give it external linkage
4628*67e74705SXin Li       if (ID->isWeakImported() && !IMP->isWeakImported())
4629*67e74705SXin Li         DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
4630*67e74705SXin Li 
4631*67e74705SXin Li     Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
4632*67e74705SXin Li                                                 ObjCTypes.Int8PtrTy);
4633*67e74705SXin Li   }
4634*67e74705SXin Li   for (unsigned i=0; i<NumCategories; i++)
4635*67e74705SXin Li     Symbols[NumClasses + i] =
4636*67e74705SXin Li       llvm::ConstantExpr::getBitCast(DefinedCategories[i],
4637*67e74705SXin Li                                      ObjCTypes.Int8PtrTy);
4638*67e74705SXin Li 
4639*67e74705SXin Li   Values[4] =
4640*67e74705SXin Li     llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4641*67e74705SXin Li                                                   Symbols.size()),
4642*67e74705SXin Li                              Symbols);
4643*67e74705SXin Li 
4644*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
4645*67e74705SXin Li 
4646*67e74705SXin Li   llvm::GlobalVariable *GV = CreateMetadataVar(
4647*67e74705SXin Li       "OBJC_SYMBOLS", Init, "__OBJC,__symbols,regular,no_dead_strip",
4648*67e74705SXin Li       CGM.getPointerAlign(), true);
4649*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4650*67e74705SXin Li }
4651*67e74705SXin Li 
EmitClassRefFromId(CodeGenFunction & CGF,IdentifierInfo * II)4652*67e74705SXin Li llvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4653*67e74705SXin Li                                            IdentifierInfo *II) {
4654*67e74705SXin Li   LazySymbols.insert(II);
4655*67e74705SXin Li 
4656*67e74705SXin Li   llvm::GlobalVariable *&Entry = ClassReferences[II];
4657*67e74705SXin Li 
4658*67e74705SXin Li   if (!Entry) {
4659*67e74705SXin Li     llvm::Constant *Casted =
4660*67e74705SXin Li     llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
4661*67e74705SXin Li                                    ObjCTypes.ClassPtrTy);
4662*67e74705SXin Li     Entry = CreateMetadataVar(
4663*67e74705SXin Li         "OBJC_CLASS_REFERENCES_", Casted,
4664*67e74705SXin Li         "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
4665*67e74705SXin Li         CGM.getPointerAlign(), true);
4666*67e74705SXin Li   }
4667*67e74705SXin Li 
4668*67e74705SXin Li   return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign());
4669*67e74705SXin Li }
4670*67e74705SXin Li 
EmitClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)4671*67e74705SXin Li llvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4672*67e74705SXin Li                                      const ObjCInterfaceDecl *ID) {
4673*67e74705SXin Li   // If the class has the objc_runtime_visible attribute, we need to
4674*67e74705SXin Li   // use the Objective-C runtime to get the class.
4675*67e74705SXin Li   if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
4676*67e74705SXin Li     return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
4677*67e74705SXin Li 
4678*67e74705SXin Li   return EmitClassRefFromId(CGF, ID->getIdentifier());
4679*67e74705SXin Li }
4680*67e74705SXin Li 
EmitNSAutoreleasePoolClassRef(CodeGenFunction & CGF)4681*67e74705SXin Li llvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4682*67e74705SXin Li   IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
4683*67e74705SXin Li   return EmitClassRefFromId(CGF, II);
4684*67e74705SXin Li }
4685*67e74705SXin Li 
EmitSelector(CodeGenFunction & CGF,Selector Sel)4686*67e74705SXin Li llvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
4687*67e74705SXin Li   return CGF.Builder.CreateLoad(EmitSelectorAddr(CGF, Sel));
4688*67e74705SXin Li }
4689*67e74705SXin Li 
EmitSelectorAddr(CodeGenFunction & CGF,Selector Sel)4690*67e74705SXin Li Address CGObjCMac::EmitSelectorAddr(CodeGenFunction &CGF, Selector Sel) {
4691*67e74705SXin Li   CharUnits Align = CGF.getPointerAlign();
4692*67e74705SXin Li 
4693*67e74705SXin Li   llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4694*67e74705SXin Li   if (!Entry) {
4695*67e74705SXin Li     llvm::Constant *Casted =
4696*67e74705SXin Li       llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4697*67e74705SXin Li                                      ObjCTypes.SelectorPtrTy);
4698*67e74705SXin Li     Entry = CreateMetadataVar(
4699*67e74705SXin Li         "OBJC_SELECTOR_REFERENCES_", Casted,
4700*67e74705SXin Li         "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, true);
4701*67e74705SXin Li     Entry->setExternallyInitialized(true);
4702*67e74705SXin Li   }
4703*67e74705SXin Li 
4704*67e74705SXin Li   return Address(Entry, Align);
4705*67e74705SXin Li }
4706*67e74705SXin Li 
GetClassName(StringRef RuntimeName)4707*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
4708*67e74705SXin Li     llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
4709*67e74705SXin Li     if (!Entry)
4710*67e74705SXin Li       Entry = CreateMetadataVar(
4711*67e74705SXin Li           "OBJC_CLASS_NAME_",
4712*67e74705SXin Li           llvm::ConstantDataArray::getString(VMContext, RuntimeName),
4713*67e74705SXin Li           ((ObjCABI == 2) ? "__TEXT,__objc_classname,cstring_literals"
4714*67e74705SXin Li                           : "__TEXT,__cstring,cstring_literals"),
4715*67e74705SXin Li           CharUnits::One(), true);
4716*67e74705SXin Li     return getConstantGEP(VMContext, Entry, 0, 0);
4717*67e74705SXin Li }
4718*67e74705SXin Li 
GetMethodDefinition(const ObjCMethodDecl * MD)4719*67e74705SXin Li llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4720*67e74705SXin Li   llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4721*67e74705SXin Li       I = MethodDefinitions.find(MD);
4722*67e74705SXin Li   if (I != MethodDefinitions.end())
4723*67e74705SXin Li     return I->second;
4724*67e74705SXin Li 
4725*67e74705SXin Li   return nullptr;
4726*67e74705SXin Li }
4727*67e74705SXin Li 
4728*67e74705SXin Li /// GetIvarLayoutName - Returns a unique constant for the given
4729*67e74705SXin Li /// ivar layout bitmap.
GetIvarLayoutName(IdentifierInfo * Ident,const ObjCCommonTypesHelper & ObjCTypes)4730*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
4731*67e74705SXin Li                                        const ObjCCommonTypesHelper &ObjCTypes) {
4732*67e74705SXin Li   return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
4733*67e74705SXin Li }
4734*67e74705SXin Li 
visitRecord(const RecordType * RT,CharUnits offset)4735*67e74705SXin Li void IvarLayoutBuilder::visitRecord(const RecordType *RT,
4736*67e74705SXin Li                                     CharUnits offset) {
4737*67e74705SXin Li   const RecordDecl *RD = RT->getDecl();
4738*67e74705SXin Li 
4739*67e74705SXin Li   // If this is a union, remember that we had one, because it might mess
4740*67e74705SXin Li   // up the ordering of layout entries.
4741*67e74705SXin Li   if (RD->isUnion())
4742*67e74705SXin Li     IsDisordered = true;
4743*67e74705SXin Li 
4744*67e74705SXin Li   const ASTRecordLayout *recLayout = nullptr;
4745*67e74705SXin Li   visitAggregate(RD->field_begin(), RD->field_end(), offset,
4746*67e74705SXin Li                  [&](const FieldDecl *field) -> CharUnits {
4747*67e74705SXin Li     if (!recLayout)
4748*67e74705SXin Li       recLayout = &CGM.getContext().getASTRecordLayout(RD);
4749*67e74705SXin Li     auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
4750*67e74705SXin Li     return CGM.getContext().toCharUnitsFromBits(offsetInBits);
4751*67e74705SXin Li   });
4752*67e74705SXin Li }
4753*67e74705SXin Li 
4754*67e74705SXin Li template <class Iterator, class GetOffsetFn>
visitAggregate(Iterator begin,Iterator end,CharUnits aggregateOffset,const GetOffsetFn & getOffset)4755*67e74705SXin Li void IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
4756*67e74705SXin Li                                        CharUnits aggregateOffset,
4757*67e74705SXin Li                                        const GetOffsetFn &getOffset) {
4758*67e74705SXin Li   for (; begin != end; ++begin) {
4759*67e74705SXin Li     auto field = *begin;
4760*67e74705SXin Li 
4761*67e74705SXin Li     // Skip over bitfields.
4762*67e74705SXin Li     if (field->isBitField()) {
4763*67e74705SXin Li       continue;
4764*67e74705SXin Li     }
4765*67e74705SXin Li 
4766*67e74705SXin Li     // Compute the offset of the field within the aggregate.
4767*67e74705SXin Li     CharUnits fieldOffset = aggregateOffset + getOffset(field);
4768*67e74705SXin Li 
4769*67e74705SXin Li     visitField(field, fieldOffset);
4770*67e74705SXin Li   }
4771*67e74705SXin Li }
4772*67e74705SXin Li 
4773*67e74705SXin Li /// Collect layout information for the given fields into IvarsInfo.
visitField(const FieldDecl * field,CharUnits fieldOffset)4774*67e74705SXin Li void IvarLayoutBuilder::visitField(const FieldDecl *field,
4775*67e74705SXin Li                                    CharUnits fieldOffset) {
4776*67e74705SXin Li   QualType fieldType = field->getType();
4777*67e74705SXin Li 
4778*67e74705SXin Li   // Drill down into arrays.
4779*67e74705SXin Li   uint64_t numElts = 1;
4780*67e74705SXin Li   while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
4781*67e74705SXin Li     numElts *= arrayType->getSize().getZExtValue();
4782*67e74705SXin Li     fieldType = arrayType->getElementType();
4783*67e74705SXin Li   }
4784*67e74705SXin Li 
4785*67e74705SXin Li   assert(!fieldType->isArrayType() && "ivar of non-constant array type?");
4786*67e74705SXin Li 
4787*67e74705SXin Li   // If we ended up with a zero-sized array, we've done what we can do within
4788*67e74705SXin Li   // the limits of this layout encoding.
4789*67e74705SXin Li   if (numElts == 0) return;
4790*67e74705SXin Li 
4791*67e74705SXin Li   // Recurse if the base element type is a record type.
4792*67e74705SXin Li   if (auto recType = fieldType->getAs<RecordType>()) {
4793*67e74705SXin Li     size_t oldEnd = IvarsInfo.size();
4794*67e74705SXin Li 
4795*67e74705SXin Li     visitRecord(recType, fieldOffset);
4796*67e74705SXin Li 
4797*67e74705SXin Li     // If we have an array, replicate the first entry's layout information.
4798*67e74705SXin Li     auto numEltEntries = IvarsInfo.size() - oldEnd;
4799*67e74705SXin Li     if (numElts != 1 && numEltEntries != 0) {
4800*67e74705SXin Li       CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
4801*67e74705SXin Li       for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
4802*67e74705SXin Li         // Copy the last numEltEntries onto the end of the array, adjusting
4803*67e74705SXin Li         // each for the element size.
4804*67e74705SXin Li         for (size_t i = 0; i != numEltEntries; ++i) {
4805*67e74705SXin Li           auto firstEntry = IvarsInfo[oldEnd + i];
4806*67e74705SXin Li           IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
4807*67e74705SXin Li                                        firstEntry.SizeInWords));
4808*67e74705SXin Li         }
4809*67e74705SXin Li       }
4810*67e74705SXin Li     }
4811*67e74705SXin Li 
4812*67e74705SXin Li     return;
4813*67e74705SXin Li   }
4814*67e74705SXin Li 
4815*67e74705SXin Li   // Classify the element type.
4816*67e74705SXin Li   Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
4817*67e74705SXin Li 
4818*67e74705SXin Li   // If it matches what we're looking for, add an entry.
4819*67e74705SXin Li   if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4820*67e74705SXin Li       || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
4821*67e74705SXin Li     assert(CGM.getContext().getTypeSizeInChars(fieldType)
4822*67e74705SXin Li              == CGM.getPointerSize());
4823*67e74705SXin Li     IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
4824*67e74705SXin Li   }
4825*67e74705SXin Li }
4826*67e74705SXin Li 
4827*67e74705SXin Li /// buildBitmap - This routine does the horsework of taking the offsets of
4828*67e74705SXin Li /// strong/weak references and creating a bitmap.  The bitmap is also
4829*67e74705SXin Li /// returned in the given buffer, suitable for being passed to \c dump().
buildBitmap(CGObjCCommonMac & CGObjC,llvm::SmallVectorImpl<unsigned char> & buffer)4830*67e74705SXin Li llvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
4831*67e74705SXin Li                                 llvm::SmallVectorImpl<unsigned char> &buffer) {
4832*67e74705SXin Li   // The bitmap is a series of skip/scan instructions, aligned to word
4833*67e74705SXin Li   // boundaries.  The skip is performed first.
4834*67e74705SXin Li   const unsigned char MaxNibble = 0xF;
4835*67e74705SXin Li   const unsigned char SkipMask = 0xF0, SkipShift = 4;
4836*67e74705SXin Li   const unsigned char ScanMask = 0x0F, ScanShift = 0;
4837*67e74705SXin Li 
4838*67e74705SXin Li   assert(!IvarsInfo.empty() && "generating bitmap for no data");
4839*67e74705SXin Li 
4840*67e74705SXin Li   // Sort the ivar info on byte position in case we encounterred a
4841*67e74705SXin Li   // union nested in the ivar list.
4842*67e74705SXin Li   if (IsDisordered) {
4843*67e74705SXin Li     // This isn't a stable sort, but our algorithm should handle it fine.
4844*67e74705SXin Li     llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
4845*67e74705SXin Li   } else {
4846*67e74705SXin Li     assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end()));
4847*67e74705SXin Li   }
4848*67e74705SXin Li   assert(IvarsInfo.back().Offset < InstanceEnd);
4849*67e74705SXin Li 
4850*67e74705SXin Li   assert(buffer.empty());
4851*67e74705SXin Li 
4852*67e74705SXin Li   // Skip the next N words.
4853*67e74705SXin Li   auto skip = [&](unsigned numWords) {
4854*67e74705SXin Li     assert(numWords > 0);
4855*67e74705SXin Li 
4856*67e74705SXin Li     // Try to merge into the previous byte.  Since scans happen second, we
4857*67e74705SXin Li     // can't do this if it includes a scan.
4858*67e74705SXin Li     if (!buffer.empty() && !(buffer.back() & ScanMask)) {
4859*67e74705SXin Li       unsigned lastSkip = buffer.back() >> SkipShift;
4860*67e74705SXin Li       if (lastSkip < MaxNibble) {
4861*67e74705SXin Li         unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
4862*67e74705SXin Li         numWords -= claimed;
4863*67e74705SXin Li         lastSkip += claimed;
4864*67e74705SXin Li         buffer.back() = (lastSkip << SkipShift);
4865*67e74705SXin Li       }
4866*67e74705SXin Li     }
4867*67e74705SXin Li 
4868*67e74705SXin Li     while (numWords >= MaxNibble) {
4869*67e74705SXin Li       buffer.push_back(MaxNibble << SkipShift);
4870*67e74705SXin Li       numWords -= MaxNibble;
4871*67e74705SXin Li     }
4872*67e74705SXin Li     if (numWords) {
4873*67e74705SXin Li       buffer.push_back(numWords << SkipShift);
4874*67e74705SXin Li     }
4875*67e74705SXin Li   };
4876*67e74705SXin Li 
4877*67e74705SXin Li   // Scan the next N words.
4878*67e74705SXin Li   auto scan = [&](unsigned numWords) {
4879*67e74705SXin Li     assert(numWords > 0);
4880*67e74705SXin Li 
4881*67e74705SXin Li     // Try to merge into the previous byte.  Since scans happen second, we can
4882*67e74705SXin Li     // do this even if it includes a skip.
4883*67e74705SXin Li     if (!buffer.empty()) {
4884*67e74705SXin Li       unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
4885*67e74705SXin Li       if (lastScan < MaxNibble) {
4886*67e74705SXin Li         unsigned claimed = std::min(MaxNibble - lastScan, numWords);
4887*67e74705SXin Li         numWords -= claimed;
4888*67e74705SXin Li         lastScan += claimed;
4889*67e74705SXin Li         buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
4890*67e74705SXin Li       }
4891*67e74705SXin Li     }
4892*67e74705SXin Li 
4893*67e74705SXin Li     while (numWords >= MaxNibble) {
4894*67e74705SXin Li       buffer.push_back(MaxNibble << ScanShift);
4895*67e74705SXin Li       numWords -= MaxNibble;
4896*67e74705SXin Li     }
4897*67e74705SXin Li     if (numWords) {
4898*67e74705SXin Li       buffer.push_back(numWords << ScanShift);
4899*67e74705SXin Li     }
4900*67e74705SXin Li   };
4901*67e74705SXin Li 
4902*67e74705SXin Li   // One past the end of the last scan.
4903*67e74705SXin Li   unsigned endOfLastScanInWords = 0;
4904*67e74705SXin Li   const CharUnits WordSize = CGM.getPointerSize();
4905*67e74705SXin Li 
4906*67e74705SXin Li   // Consider all the scan requests.
4907*67e74705SXin Li   for (auto &request : IvarsInfo) {
4908*67e74705SXin Li     CharUnits beginOfScan = request.Offset - InstanceBegin;
4909*67e74705SXin Li 
4910*67e74705SXin Li     // Ignore scan requests that don't start at an even multiple of the
4911*67e74705SXin Li     // word size.  We can't encode them.
4912*67e74705SXin Li     if ((beginOfScan % WordSize) != 0) continue;
4913*67e74705SXin Li 
4914*67e74705SXin Li     // Ignore scan requests that start before the instance start.
4915*67e74705SXin Li     // This assumes that scans never span that boundary.  The boundary
4916*67e74705SXin Li     // isn't the true start of the ivars, because in the fragile-ARC case
4917*67e74705SXin Li     // it's rounded up to word alignment, but the test above should leave
4918*67e74705SXin Li     // us ignoring that possibility.
4919*67e74705SXin Li     if (beginOfScan.isNegative()) {
4920*67e74705SXin Li       assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
4921*67e74705SXin Li       continue;
4922*67e74705SXin Li     }
4923*67e74705SXin Li 
4924*67e74705SXin Li     unsigned beginOfScanInWords = beginOfScan / WordSize;
4925*67e74705SXin Li     unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
4926*67e74705SXin Li 
4927*67e74705SXin Li     // If the scan starts some number of words after the last one ended,
4928*67e74705SXin Li     // skip forward.
4929*67e74705SXin Li     if (beginOfScanInWords > endOfLastScanInWords) {
4930*67e74705SXin Li       skip(beginOfScanInWords - endOfLastScanInWords);
4931*67e74705SXin Li 
4932*67e74705SXin Li     // Otherwise, start scanning where the last left off.
4933*67e74705SXin Li     } else {
4934*67e74705SXin Li       beginOfScanInWords = endOfLastScanInWords;
4935*67e74705SXin Li 
4936*67e74705SXin Li       // If that leaves us with nothing to scan, ignore this request.
4937*67e74705SXin Li       if (beginOfScanInWords >= endOfScanInWords) continue;
4938*67e74705SXin Li     }
4939*67e74705SXin Li 
4940*67e74705SXin Li     // Scan to the end of the request.
4941*67e74705SXin Li     assert(beginOfScanInWords < endOfScanInWords);
4942*67e74705SXin Li     scan(endOfScanInWords - beginOfScanInWords);
4943*67e74705SXin Li     endOfLastScanInWords = endOfScanInWords;
4944*67e74705SXin Li   }
4945*67e74705SXin Li 
4946*67e74705SXin Li   if (buffer.empty())
4947*67e74705SXin Li     return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
4948*67e74705SXin Li 
4949*67e74705SXin Li   // For GC layouts, emit a skip to the end of the allocation so that we
4950*67e74705SXin Li   // have precise information about the entire thing.  This isn't useful
4951*67e74705SXin Li   // or necessary for the ARC-style layout strings.
4952*67e74705SXin Li   if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
4953*67e74705SXin Li     unsigned lastOffsetInWords =
4954*67e74705SXin Li       (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
4955*67e74705SXin Li     if (lastOffsetInWords > endOfLastScanInWords) {
4956*67e74705SXin Li       skip(lastOffsetInWords - endOfLastScanInWords);
4957*67e74705SXin Li     }
4958*67e74705SXin Li   }
4959*67e74705SXin Li 
4960*67e74705SXin Li   // Null terminate the string.
4961*67e74705SXin Li   buffer.push_back(0);
4962*67e74705SXin Li 
4963*67e74705SXin Li   bool isNonFragileABI = CGObjC.isNonFragileABI();
4964*67e74705SXin Li 
4965*67e74705SXin Li   llvm::GlobalVariable *Entry = CGObjC.CreateMetadataVar(
4966*67e74705SXin Li       "OBJC_CLASS_NAME_",
4967*67e74705SXin Li       llvm::ConstantDataArray::get(CGM.getLLVMContext(), buffer),
4968*67e74705SXin Li       (isNonFragileABI ? "__TEXT,__objc_classname,cstring_literals"
4969*67e74705SXin Li                        : "__TEXT,__cstring,cstring_literals"),
4970*67e74705SXin Li       CharUnits::One(), true);
4971*67e74705SXin Li   return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
4972*67e74705SXin Li }
4973*67e74705SXin Li 
4974*67e74705SXin Li /// BuildIvarLayout - Builds ivar layout bitmap for the class
4975*67e74705SXin Li /// implementation for the __strong or __weak case.
4976*67e74705SXin Li /// The layout map displays which words in ivar list must be skipped
4977*67e74705SXin Li /// and which must be scanned by GC (see below). String is built of bytes.
4978*67e74705SXin Li /// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
4979*67e74705SXin Li /// of words to skip and right nibble is count of words to scan. So, each
4980*67e74705SXin Li /// nibble represents up to 15 workds to skip or scan. Skipping the rest is
4981*67e74705SXin Li /// represented by a 0x00 byte which also ends the string.
4982*67e74705SXin Li /// 1. when ForStrongLayout is true, following ivars are scanned:
4983*67e74705SXin Li /// - id, Class
4984*67e74705SXin Li /// - object *
4985*67e74705SXin Li /// - __strong anything
4986*67e74705SXin Li ///
4987*67e74705SXin Li /// 2. When ForStrongLayout is false, following ivars are scanned:
4988*67e74705SXin Li /// - __weak anything
4989*67e74705SXin Li ///
4990*67e74705SXin Li llvm::Constant *
BuildIvarLayout(const ObjCImplementationDecl * OMD,CharUnits beginOffset,CharUnits endOffset,bool ForStrongLayout,bool HasMRCWeakIvars)4991*67e74705SXin Li CGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
4992*67e74705SXin Li                                  CharUnits beginOffset, CharUnits endOffset,
4993*67e74705SXin Li                                  bool ForStrongLayout, bool HasMRCWeakIvars) {
4994*67e74705SXin Li   // If this is MRC, and we're either building a strong layout or there
4995*67e74705SXin Li   // are no weak ivars, bail out early.
4996*67e74705SXin Li   llvm::Type *PtrTy = CGM.Int8PtrTy;
4997*67e74705SXin Li   if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4998*67e74705SXin Li       !CGM.getLangOpts().ObjCAutoRefCount &&
4999*67e74705SXin Li       (ForStrongLayout || !HasMRCWeakIvars))
5000*67e74705SXin Li     return llvm::Constant::getNullValue(PtrTy);
5001*67e74705SXin Li 
5002*67e74705SXin Li   const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5003*67e74705SXin Li   SmallVector<const ObjCIvarDecl*, 32> ivars;
5004*67e74705SXin Li 
5005*67e74705SXin Li   // GC layout strings include the complete object layout, possibly
5006*67e74705SXin Li   // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5007*67e74705SXin Li   // up.
5008*67e74705SXin Li   //
5009*67e74705SXin Li   // ARC layout strings only include the class's ivars.  In non-fragile
5010*67e74705SXin Li   // runtimes, that means starting at InstanceStart, rounded up to word
5011*67e74705SXin Li   // alignment.  In fragile runtimes, there's no InstanceStart, so it means
5012*67e74705SXin Li   // starting at the offset of the first ivar, rounded up to word alignment.
5013*67e74705SXin Li   //
5014*67e74705SXin Li   // MRC weak layout strings follow the ARC style.
5015*67e74705SXin Li   CharUnits baseOffset;
5016*67e74705SXin Li   if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5017*67e74705SXin Li     for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5018*67e74705SXin Li          IVD; IVD = IVD->getNextIvar())
5019*67e74705SXin Li       ivars.push_back(IVD);
5020*67e74705SXin Li 
5021*67e74705SXin Li     if (isNonFragileABI()) {
5022*67e74705SXin Li       baseOffset = beginOffset; // InstanceStart
5023*67e74705SXin Li     } else if (!ivars.empty()) {
5024*67e74705SXin Li       baseOffset =
5025*67e74705SXin Li         CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5026*67e74705SXin Li     } else {
5027*67e74705SXin Li       baseOffset = CharUnits::Zero();
5028*67e74705SXin Li     }
5029*67e74705SXin Li 
5030*67e74705SXin Li     baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5031*67e74705SXin Li   }
5032*67e74705SXin Li   else {
5033*67e74705SXin Li     CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5034*67e74705SXin Li 
5035*67e74705SXin Li     baseOffset = CharUnits::Zero();
5036*67e74705SXin Li   }
5037*67e74705SXin Li 
5038*67e74705SXin Li   if (ivars.empty())
5039*67e74705SXin Li     return llvm::Constant::getNullValue(PtrTy);
5040*67e74705SXin Li 
5041*67e74705SXin Li   IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5042*67e74705SXin Li 
5043*67e74705SXin Li   builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5044*67e74705SXin Li                          [&](const ObjCIvarDecl *ivar) -> CharUnits {
5045*67e74705SXin Li       return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5046*67e74705SXin Li   });
5047*67e74705SXin Li 
5048*67e74705SXin Li   if (!builder.hasBitmapData())
5049*67e74705SXin Li     return llvm::Constant::getNullValue(PtrTy);
5050*67e74705SXin Li 
5051*67e74705SXin Li   llvm::SmallVector<unsigned char, 4> buffer;
5052*67e74705SXin Li   llvm::Constant *C = builder.buildBitmap(*this, buffer);
5053*67e74705SXin Li 
5054*67e74705SXin Li    if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5055*67e74705SXin Li     printf("\n%s ivar layout for class '%s': ",
5056*67e74705SXin Li            ForStrongLayout ? "strong" : "weak",
5057*67e74705SXin Li            OMD->getClassInterface()->getName().str().c_str());
5058*67e74705SXin Li     builder.dump(buffer);
5059*67e74705SXin Li   }
5060*67e74705SXin Li   return C;
5061*67e74705SXin Li }
5062*67e74705SXin Li 
GetMethodVarName(Selector Sel)5063*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5064*67e74705SXin Li   llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5065*67e74705SXin Li 
5066*67e74705SXin Li   // FIXME: Avoid std::string in "Sel.getAsString()"
5067*67e74705SXin Li   if (!Entry)
5068*67e74705SXin Li     Entry = CreateMetadataVar(
5069*67e74705SXin Li         "OBJC_METH_VAR_NAME_",
5070*67e74705SXin Li         llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
5071*67e74705SXin Li         ((ObjCABI == 2) ? "__TEXT,__objc_methname,cstring_literals"
5072*67e74705SXin Li                         : "__TEXT,__cstring,cstring_literals"),
5073*67e74705SXin Li         CharUnits::One(), true);
5074*67e74705SXin Li 
5075*67e74705SXin Li   return getConstantGEP(VMContext, Entry, 0, 0);
5076*67e74705SXin Li }
5077*67e74705SXin Li 
5078*67e74705SXin Li // FIXME: Merge into a single cstring creation function.
GetMethodVarName(IdentifierInfo * ID)5079*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5080*67e74705SXin Li   return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5081*67e74705SXin Li }
5082*67e74705SXin Li 
GetMethodVarType(const FieldDecl * Field)5083*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5084*67e74705SXin Li   std::string TypeStr;
5085*67e74705SXin Li   CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5086*67e74705SXin Li 
5087*67e74705SXin Li   llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5088*67e74705SXin Li 
5089*67e74705SXin Li   if (!Entry)
5090*67e74705SXin Li     Entry = CreateMetadataVar(
5091*67e74705SXin Li         "OBJC_METH_VAR_TYPE_",
5092*67e74705SXin Li         llvm::ConstantDataArray::getString(VMContext, TypeStr),
5093*67e74705SXin Li         ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
5094*67e74705SXin Li                         : "__TEXT,__cstring,cstring_literals"),
5095*67e74705SXin Li         CharUnits::One(), true);
5096*67e74705SXin Li 
5097*67e74705SXin Li   return getConstantGEP(VMContext, Entry, 0, 0);
5098*67e74705SXin Li }
5099*67e74705SXin Li 
GetMethodVarType(const ObjCMethodDecl * D,bool Extended)5100*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5101*67e74705SXin Li                                                   bool Extended) {
5102*67e74705SXin Li   std::string TypeStr;
5103*67e74705SXin Li   if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
5104*67e74705SXin Li     return nullptr;
5105*67e74705SXin Li 
5106*67e74705SXin Li   llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5107*67e74705SXin Li 
5108*67e74705SXin Li   if (!Entry)
5109*67e74705SXin Li     Entry = CreateMetadataVar(
5110*67e74705SXin Li         "OBJC_METH_VAR_TYPE_",
5111*67e74705SXin Li         llvm::ConstantDataArray::getString(VMContext, TypeStr),
5112*67e74705SXin Li         ((ObjCABI == 2) ? "__TEXT,__objc_methtype,cstring_literals"
5113*67e74705SXin Li                         : "__TEXT,__cstring,cstring_literals"),
5114*67e74705SXin Li         CharUnits::One(), true);
5115*67e74705SXin Li 
5116*67e74705SXin Li   return getConstantGEP(VMContext, Entry, 0, 0);
5117*67e74705SXin Li }
5118*67e74705SXin Li 
5119*67e74705SXin Li // FIXME: Merge into a single cstring creation function.
GetPropertyName(IdentifierInfo * Ident)5120*67e74705SXin Li llvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5121*67e74705SXin Li   llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5122*67e74705SXin Li 
5123*67e74705SXin Li   if (!Entry)
5124*67e74705SXin Li     Entry = CreateMetadataVar(
5125*67e74705SXin Li         "OBJC_PROP_NAME_ATTR_",
5126*67e74705SXin Li         llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
5127*67e74705SXin Li         "__TEXT,__cstring,cstring_literals", CharUnits::One(), true);
5128*67e74705SXin Li 
5129*67e74705SXin Li   return getConstantGEP(VMContext, Entry, 0, 0);
5130*67e74705SXin Li }
5131*67e74705SXin Li 
5132*67e74705SXin Li // FIXME: Merge into a single cstring creation function.
5133*67e74705SXin Li // FIXME: This Decl should be more precise.
5134*67e74705SXin Li llvm::Constant *
GetPropertyTypeString(const ObjCPropertyDecl * PD,const Decl * Container)5135*67e74705SXin Li CGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5136*67e74705SXin Li                                        const Decl *Container) {
5137*67e74705SXin Li   std::string TypeStr;
5138*67e74705SXin Li   CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
5139*67e74705SXin Li   return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5140*67e74705SXin Li }
5141*67e74705SXin Li 
GetNameForMethod(const ObjCMethodDecl * D,const ObjCContainerDecl * CD,SmallVectorImpl<char> & Name)5142*67e74705SXin Li void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
5143*67e74705SXin Li                                        const ObjCContainerDecl *CD,
5144*67e74705SXin Li                                        SmallVectorImpl<char> &Name) {
5145*67e74705SXin Li   llvm::raw_svector_ostream OS(Name);
5146*67e74705SXin Li   assert (CD && "Missing container decl in GetNameForMethod");
5147*67e74705SXin Li   OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
5148*67e74705SXin Li      << '[' << CD->getName();
5149*67e74705SXin Li   if (const ObjCCategoryImplDecl *CID =
5150*67e74705SXin Li       dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
5151*67e74705SXin Li     OS << '(' << *CID << ')';
5152*67e74705SXin Li   OS << ' ' << D->getSelector().getAsString() << ']';
5153*67e74705SXin Li }
5154*67e74705SXin Li 
FinishModule()5155*67e74705SXin Li void CGObjCMac::FinishModule() {
5156*67e74705SXin Li   EmitModuleInfo();
5157*67e74705SXin Li 
5158*67e74705SXin Li   // Emit the dummy bodies for any protocols which were referenced but
5159*67e74705SXin Li   // never defined.
5160*67e74705SXin Li   for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
5161*67e74705SXin Li          I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
5162*67e74705SXin Li     if (I->second->hasInitializer())
5163*67e74705SXin Li       continue;
5164*67e74705SXin Li 
5165*67e74705SXin Li     llvm::Constant *Values[5];
5166*67e74705SXin Li     Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
5167*67e74705SXin Li     Values[1] = GetClassName(I->first->getName());
5168*67e74705SXin Li     Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
5169*67e74705SXin Li     Values[3] = Values[4] =
5170*67e74705SXin Li       llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
5171*67e74705SXin Li     I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
5172*67e74705SXin Li                                                         Values));
5173*67e74705SXin Li     CGM.addCompilerUsedGlobal(I->second);
5174*67e74705SXin Li   }
5175*67e74705SXin Li 
5176*67e74705SXin Li   // Add assembler directives to add lazy undefined symbol references
5177*67e74705SXin Li   // for classes which are referenced but not defined. This is
5178*67e74705SXin Li   // important for correct linker interaction.
5179*67e74705SXin Li   //
5180*67e74705SXin Li   // FIXME: It would be nice if we had an LLVM construct for this.
5181*67e74705SXin Li   if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
5182*67e74705SXin Li     SmallString<256> Asm;
5183*67e74705SXin Li     Asm += CGM.getModule().getModuleInlineAsm();
5184*67e74705SXin Li     if (!Asm.empty() && Asm.back() != '\n')
5185*67e74705SXin Li       Asm += '\n';
5186*67e74705SXin Li 
5187*67e74705SXin Li     llvm::raw_svector_ostream OS(Asm);
5188*67e74705SXin Li     for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
5189*67e74705SXin Li            e = DefinedSymbols.end(); I != e; ++I)
5190*67e74705SXin Li       OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
5191*67e74705SXin Li          << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
5192*67e74705SXin Li     for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
5193*67e74705SXin Li          e = LazySymbols.end(); I != e; ++I) {
5194*67e74705SXin Li       OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
5195*67e74705SXin Li     }
5196*67e74705SXin Li 
5197*67e74705SXin Li     for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
5198*67e74705SXin Li       OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
5199*67e74705SXin Li          << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
5200*67e74705SXin Li     }
5201*67e74705SXin Li 
5202*67e74705SXin Li     CGM.getModule().setModuleInlineAsm(OS.str());
5203*67e74705SXin Li   }
5204*67e74705SXin Li }
5205*67e74705SXin Li 
CGObjCNonFragileABIMac(CodeGen::CodeGenModule & cgm)5206*67e74705SXin Li CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5207*67e74705SXin Li     : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5208*67e74705SXin Li       ObjCEmptyVtableVar(nullptr) {
5209*67e74705SXin Li   ObjCABI = 2;
5210*67e74705SXin Li }
5211*67e74705SXin Li 
5212*67e74705SXin Li /* *** */
5213*67e74705SXin Li 
ObjCCommonTypesHelper(CodeGen::CodeGenModule & cgm)5214*67e74705SXin Li ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5215*67e74705SXin Li   : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5216*67e74705SXin Li {
5217*67e74705SXin Li   CodeGen::CodeGenTypes &Types = CGM.getTypes();
5218*67e74705SXin Li   ASTContext &Ctx = CGM.getContext();
5219*67e74705SXin Li 
5220*67e74705SXin Li   ShortTy = Types.ConvertType(Ctx.ShortTy);
5221*67e74705SXin Li   IntTy = Types.ConvertType(Ctx.IntTy);
5222*67e74705SXin Li   LongTy = Types.ConvertType(Ctx.LongTy);
5223*67e74705SXin Li   LongLongTy = Types.ConvertType(Ctx.LongLongTy);
5224*67e74705SXin Li   Int8PtrTy = CGM.Int8PtrTy;
5225*67e74705SXin Li   Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5226*67e74705SXin Li 
5227*67e74705SXin Li   // arm64 targets use "int" ivar offset variables. All others,
5228*67e74705SXin Li   // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5229*67e74705SXin Li   if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5230*67e74705SXin Li     IvarOffsetVarTy = IntTy;
5231*67e74705SXin Li   else
5232*67e74705SXin Li     IvarOffsetVarTy = LongTy;
5233*67e74705SXin Li 
5234*67e74705SXin Li   ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
5235*67e74705SXin Li   PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
5236*67e74705SXin Li   SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
5237*67e74705SXin Li 
5238*67e74705SXin Li   // I'm not sure I like this. The implicit coordination is a bit
5239*67e74705SXin Li   // gross. We should solve this in a reasonable fashion because this
5240*67e74705SXin Li   // is a pretty common task (match some runtime data structure with
5241*67e74705SXin Li   // an LLVM data structure).
5242*67e74705SXin Li 
5243*67e74705SXin Li   // FIXME: This is leaked.
5244*67e74705SXin Li   // FIXME: Merge with rewriter code?
5245*67e74705SXin Li 
5246*67e74705SXin Li   // struct _objc_super {
5247*67e74705SXin Li   //   id self;
5248*67e74705SXin Li   //   Class cls;
5249*67e74705SXin Li   // }
5250*67e74705SXin Li   RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5251*67e74705SXin Li                                       Ctx.getTranslationUnitDecl(),
5252*67e74705SXin Li                                       SourceLocation(), SourceLocation(),
5253*67e74705SXin Li                                       &Ctx.Idents.get("_objc_super"));
5254*67e74705SXin Li   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5255*67e74705SXin Li                                 nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5256*67e74705SXin Li                                 false, ICIS_NoInit));
5257*67e74705SXin Li   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5258*67e74705SXin Li                                 nullptr, Ctx.getObjCClassType(), nullptr,
5259*67e74705SXin Li                                 nullptr, false, ICIS_NoInit));
5260*67e74705SXin Li   RD->completeDefinition();
5261*67e74705SXin Li 
5262*67e74705SXin Li   SuperCTy = Ctx.getTagDeclType(RD);
5263*67e74705SXin Li   SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5264*67e74705SXin Li 
5265*67e74705SXin Li   SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5266*67e74705SXin Li   SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5267*67e74705SXin Li 
5268*67e74705SXin Li   // struct _prop_t {
5269*67e74705SXin Li   //   char *name;
5270*67e74705SXin Li   //   char *attributes;
5271*67e74705SXin Li   // }
5272*67e74705SXin Li   PropertyTy = llvm::StructType::create("struct._prop_t",
5273*67e74705SXin Li                                         Int8PtrTy, Int8PtrTy, nullptr);
5274*67e74705SXin Li 
5275*67e74705SXin Li   // struct _prop_list_t {
5276*67e74705SXin Li   //   uint32_t entsize;      // sizeof(struct _prop_t)
5277*67e74705SXin Li   //   uint32_t count_of_properties;
5278*67e74705SXin Li   //   struct _prop_t prop_list[count_of_properties];
5279*67e74705SXin Li   // }
5280*67e74705SXin Li   PropertyListTy =
5281*67e74705SXin Li     llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
5282*67e74705SXin Li                              llvm::ArrayType::get(PropertyTy, 0), nullptr);
5283*67e74705SXin Li   // struct _prop_list_t *
5284*67e74705SXin Li   PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5285*67e74705SXin Li 
5286*67e74705SXin Li   // struct _objc_method {
5287*67e74705SXin Li   //   SEL _cmd;
5288*67e74705SXin Li   //   char *method_type;
5289*67e74705SXin Li   //   char *_imp;
5290*67e74705SXin Li   // }
5291*67e74705SXin Li   MethodTy = llvm::StructType::create("struct._objc_method",
5292*67e74705SXin Li                                       SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5293*67e74705SXin Li                                       nullptr);
5294*67e74705SXin Li 
5295*67e74705SXin Li   // struct _objc_cache *
5296*67e74705SXin Li   CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
5297*67e74705SXin Li   CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5298*67e74705SXin Li }
5299*67e74705SXin Li 
ObjCTypesHelper(CodeGen::CodeGenModule & cgm)5300*67e74705SXin Li ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5301*67e74705SXin Li   : ObjCCommonTypesHelper(cgm) {
5302*67e74705SXin Li   // struct _objc_method_description {
5303*67e74705SXin Li   //   SEL name;
5304*67e74705SXin Li   //   char *types;
5305*67e74705SXin Li   // }
5306*67e74705SXin Li   MethodDescriptionTy =
5307*67e74705SXin Li     llvm::StructType::create("struct._objc_method_description",
5308*67e74705SXin Li                              SelectorPtrTy, Int8PtrTy, nullptr);
5309*67e74705SXin Li 
5310*67e74705SXin Li   // struct _objc_method_description_list {
5311*67e74705SXin Li   //   int count;
5312*67e74705SXin Li   //   struct _objc_method_description[1];
5313*67e74705SXin Li   // }
5314*67e74705SXin Li   MethodDescriptionListTy = llvm::StructType::create(
5315*67e74705SXin Li       "struct._objc_method_description_list", IntTy,
5316*67e74705SXin Li       llvm::ArrayType::get(MethodDescriptionTy, 0), nullptr);
5317*67e74705SXin Li 
5318*67e74705SXin Li   // struct _objc_method_description_list *
5319*67e74705SXin Li   MethodDescriptionListPtrTy =
5320*67e74705SXin Li     llvm::PointerType::getUnqual(MethodDescriptionListTy);
5321*67e74705SXin Li 
5322*67e74705SXin Li   // Protocol description structures
5323*67e74705SXin Li 
5324*67e74705SXin Li   // struct _objc_protocol_extension {
5325*67e74705SXin Li   //   uint32_t size;  // sizeof(struct _objc_protocol_extension)
5326*67e74705SXin Li   //   struct _objc_method_description_list *optional_instance_methods;
5327*67e74705SXin Li   //   struct _objc_method_description_list *optional_class_methods;
5328*67e74705SXin Li   //   struct _objc_property_list *instance_properties;
5329*67e74705SXin Li   //   const char ** extendedMethodTypes;
5330*67e74705SXin Li   //   struct _objc_property_list *class_properties;
5331*67e74705SXin Li   // }
5332*67e74705SXin Li   ProtocolExtensionTy =
5333*67e74705SXin Li     llvm::StructType::create("struct._objc_protocol_extension",
5334*67e74705SXin Li                              IntTy, MethodDescriptionListPtrTy,
5335*67e74705SXin Li                              MethodDescriptionListPtrTy, PropertyListPtrTy,
5336*67e74705SXin Li                              Int8PtrPtrTy, PropertyListPtrTy, nullptr);
5337*67e74705SXin Li 
5338*67e74705SXin Li   // struct _objc_protocol_extension *
5339*67e74705SXin Li   ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5340*67e74705SXin Li 
5341*67e74705SXin Li   // Handle recursive construction of Protocol and ProtocolList types
5342*67e74705SXin Li 
5343*67e74705SXin Li   ProtocolTy =
5344*67e74705SXin Li     llvm::StructType::create(VMContext, "struct._objc_protocol");
5345*67e74705SXin Li 
5346*67e74705SXin Li   ProtocolListTy =
5347*67e74705SXin Li     llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5348*67e74705SXin Li   ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
5349*67e74705SXin Li                           LongTy,
5350*67e74705SXin Li                           llvm::ArrayType::get(ProtocolTy, 0),
5351*67e74705SXin Li                           nullptr);
5352*67e74705SXin Li 
5353*67e74705SXin Li   // struct _objc_protocol {
5354*67e74705SXin Li   //   struct _objc_protocol_extension *isa;
5355*67e74705SXin Li   //   char *protocol_name;
5356*67e74705SXin Li   //   struct _objc_protocol **_objc_protocol_list;
5357*67e74705SXin Li   //   struct _objc_method_description_list *instance_methods;
5358*67e74705SXin Li   //   struct _objc_method_description_list *class_methods;
5359*67e74705SXin Li   // }
5360*67e74705SXin Li   ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5361*67e74705SXin Li                       llvm::PointerType::getUnqual(ProtocolListTy),
5362*67e74705SXin Li                       MethodDescriptionListPtrTy,
5363*67e74705SXin Li                       MethodDescriptionListPtrTy,
5364*67e74705SXin Li                       nullptr);
5365*67e74705SXin Li 
5366*67e74705SXin Li   // struct _objc_protocol_list *
5367*67e74705SXin Li   ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5368*67e74705SXin Li 
5369*67e74705SXin Li   ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5370*67e74705SXin Li 
5371*67e74705SXin Li   // Class description structures
5372*67e74705SXin Li 
5373*67e74705SXin Li   // struct _objc_ivar {
5374*67e74705SXin Li   //   char *ivar_name;
5375*67e74705SXin Li   //   char *ivar_type;
5376*67e74705SXin Li   //   int  ivar_offset;
5377*67e74705SXin Li   // }
5378*67e74705SXin Li   IvarTy = llvm::StructType::create("struct._objc_ivar",
5379*67e74705SXin Li                                     Int8PtrTy, Int8PtrTy, IntTy, nullptr);
5380*67e74705SXin Li 
5381*67e74705SXin Li   // struct _objc_ivar_list *
5382*67e74705SXin Li   IvarListTy =
5383*67e74705SXin Li     llvm::StructType::create(VMContext, "struct._objc_ivar_list");
5384*67e74705SXin Li   IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5385*67e74705SXin Li 
5386*67e74705SXin Li   // struct _objc_method_list *
5387*67e74705SXin Li   MethodListTy =
5388*67e74705SXin Li     llvm::StructType::create(VMContext, "struct._objc_method_list");
5389*67e74705SXin Li   MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5390*67e74705SXin Li 
5391*67e74705SXin Li   // struct _objc_class_extension *
5392*67e74705SXin Li   ClassExtensionTy =
5393*67e74705SXin Li     llvm::StructType::create("struct._objc_class_extension",
5394*67e74705SXin Li                              IntTy, Int8PtrTy, PropertyListPtrTy, nullptr);
5395*67e74705SXin Li   ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5396*67e74705SXin Li 
5397*67e74705SXin Li   ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
5398*67e74705SXin Li 
5399*67e74705SXin Li   // struct _objc_class {
5400*67e74705SXin Li   //   Class isa;
5401*67e74705SXin Li   //   Class super_class;
5402*67e74705SXin Li   //   char *name;
5403*67e74705SXin Li   //   long version;
5404*67e74705SXin Li   //   long info;
5405*67e74705SXin Li   //   long instance_size;
5406*67e74705SXin Li   //   struct _objc_ivar_list *ivars;
5407*67e74705SXin Li   //   struct _objc_method_list *methods;
5408*67e74705SXin Li   //   struct _objc_cache *cache;
5409*67e74705SXin Li   //   struct _objc_protocol_list *protocols;
5410*67e74705SXin Li   //   char *ivar_layout;
5411*67e74705SXin Li   //   struct _objc_class_ext *ext;
5412*67e74705SXin Li   // };
5413*67e74705SXin Li   ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5414*67e74705SXin Li                    llvm::PointerType::getUnqual(ClassTy),
5415*67e74705SXin Li                    Int8PtrTy,
5416*67e74705SXin Li                    LongTy,
5417*67e74705SXin Li                    LongTy,
5418*67e74705SXin Li                    LongTy,
5419*67e74705SXin Li                    IvarListPtrTy,
5420*67e74705SXin Li                    MethodListPtrTy,
5421*67e74705SXin Li                    CachePtrTy,
5422*67e74705SXin Li                    ProtocolListPtrTy,
5423*67e74705SXin Li                    Int8PtrTy,
5424*67e74705SXin Li                    ClassExtensionPtrTy,
5425*67e74705SXin Li                    nullptr);
5426*67e74705SXin Li 
5427*67e74705SXin Li   ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5428*67e74705SXin Li 
5429*67e74705SXin Li   // struct _objc_category {
5430*67e74705SXin Li   //   char *category_name;
5431*67e74705SXin Li   //   char *class_name;
5432*67e74705SXin Li   //   struct _objc_method_list *instance_method;
5433*67e74705SXin Li   //   struct _objc_method_list *class_method;
5434*67e74705SXin Li   //   struct _objc_protocol_list *protocols;
5435*67e74705SXin Li   //   uint32_t size;  // sizeof(struct _objc_category)
5436*67e74705SXin Li   //   struct _objc_property_list *instance_properties;// category's @property
5437*67e74705SXin Li   //   struct _objc_property_list *class_properties;
5438*67e74705SXin Li   // }
5439*67e74705SXin Li   CategoryTy =
5440*67e74705SXin Li     llvm::StructType::create("struct._objc_category",
5441*67e74705SXin Li                              Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5442*67e74705SXin Li                              MethodListPtrTy, ProtocolListPtrTy,
5443*67e74705SXin Li                              IntTy, PropertyListPtrTy, PropertyListPtrTy,
5444*67e74705SXin Li                              nullptr);
5445*67e74705SXin Li 
5446*67e74705SXin Li   // Global metadata structures
5447*67e74705SXin Li 
5448*67e74705SXin Li   // struct _objc_symtab {
5449*67e74705SXin Li   //   long sel_ref_cnt;
5450*67e74705SXin Li   //   SEL *refs;
5451*67e74705SXin Li   //   short cls_def_cnt;
5452*67e74705SXin Li   //   short cat_def_cnt;
5453*67e74705SXin Li   //   char *defs[cls_def_cnt + cat_def_cnt];
5454*67e74705SXin Li   // }
5455*67e74705SXin Li   SymtabTy =
5456*67e74705SXin Li     llvm::StructType::create("struct._objc_symtab",
5457*67e74705SXin Li                              LongTy, SelectorPtrTy, ShortTy, ShortTy,
5458*67e74705SXin Li                              llvm::ArrayType::get(Int8PtrTy, 0), nullptr);
5459*67e74705SXin Li   SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5460*67e74705SXin Li 
5461*67e74705SXin Li   // struct _objc_module {
5462*67e74705SXin Li   //   long version;
5463*67e74705SXin Li   //   long size;   // sizeof(struct _objc_module)
5464*67e74705SXin Li   //   char *name;
5465*67e74705SXin Li   //   struct _objc_symtab* symtab;
5466*67e74705SXin Li   //  }
5467*67e74705SXin Li   ModuleTy =
5468*67e74705SXin Li     llvm::StructType::create("struct._objc_module",
5469*67e74705SXin Li                              LongTy, LongTy, Int8PtrTy, SymtabPtrTy, nullptr);
5470*67e74705SXin Li 
5471*67e74705SXin Li 
5472*67e74705SXin Li   // FIXME: This is the size of the setjmp buffer and should be target
5473*67e74705SXin Li   // specific. 18 is what's used on 32-bit X86.
5474*67e74705SXin Li   uint64_t SetJmpBufferSize = 18;
5475*67e74705SXin Li 
5476*67e74705SXin Li   // Exceptions
5477*67e74705SXin Li   llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5478*67e74705SXin Li 
5479*67e74705SXin Li   ExceptionDataTy =
5480*67e74705SXin Li     llvm::StructType::create("struct._objc_exception_data",
5481*67e74705SXin Li                              llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5482*67e74705SXin Li                              StackPtrTy, nullptr);
5483*67e74705SXin Li }
5484*67e74705SXin Li 
ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule & cgm)5485*67e74705SXin Li ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5486*67e74705SXin Li   : ObjCCommonTypesHelper(cgm) {
5487*67e74705SXin Li   // struct _method_list_t {
5488*67e74705SXin Li   //   uint32_t entsize;  // sizeof(struct _objc_method)
5489*67e74705SXin Li   //   uint32_t method_count;
5490*67e74705SXin Li   //   struct _objc_method method_list[method_count];
5491*67e74705SXin Li   // }
5492*67e74705SXin Li   MethodListnfABITy =
5493*67e74705SXin Li     llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
5494*67e74705SXin Li                              llvm::ArrayType::get(MethodTy, 0), nullptr);
5495*67e74705SXin Li   // struct method_list_t *
5496*67e74705SXin Li   MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5497*67e74705SXin Li 
5498*67e74705SXin Li   // struct _protocol_t {
5499*67e74705SXin Li   //   id isa;  // NULL
5500*67e74705SXin Li   //   const char * const protocol_name;
5501*67e74705SXin Li   //   const struct _protocol_list_t * protocol_list; // super protocols
5502*67e74705SXin Li   //   const struct method_list_t * const instance_methods;
5503*67e74705SXin Li   //   const struct method_list_t * const class_methods;
5504*67e74705SXin Li   //   const struct method_list_t *optionalInstanceMethods;
5505*67e74705SXin Li   //   const struct method_list_t *optionalClassMethods;
5506*67e74705SXin Li   //   const struct _prop_list_t * properties;
5507*67e74705SXin Li   //   const uint32_t size;  // sizeof(struct _protocol_t)
5508*67e74705SXin Li   //   const uint32_t flags;  // = 0
5509*67e74705SXin Li   //   const char ** extendedMethodTypes;
5510*67e74705SXin Li   //   const char *demangledName;
5511*67e74705SXin Li   //   const struct _prop_list_t * class_properties;
5512*67e74705SXin Li   // }
5513*67e74705SXin Li 
5514*67e74705SXin Li   // Holder for struct _protocol_list_t *
5515*67e74705SXin Li   ProtocolListnfABITy =
5516*67e74705SXin Li     llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5517*67e74705SXin Li 
5518*67e74705SXin Li   ProtocolnfABITy =
5519*67e74705SXin Li     llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
5520*67e74705SXin Li                              llvm::PointerType::getUnqual(ProtocolListnfABITy),
5521*67e74705SXin Li                              MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5522*67e74705SXin Li                              MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5523*67e74705SXin Li                              PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5524*67e74705SXin Li                              Int8PtrTy, PropertyListPtrTy,
5525*67e74705SXin Li                              nullptr);
5526*67e74705SXin Li 
5527*67e74705SXin Li   // struct _protocol_t*
5528*67e74705SXin Li   ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5529*67e74705SXin Li 
5530*67e74705SXin Li   // struct _protocol_list_t {
5531*67e74705SXin Li   //   long protocol_count;   // Note, this is 32/64 bit
5532*67e74705SXin Li   //   struct _protocol_t *[protocol_count];
5533*67e74705SXin Li   // }
5534*67e74705SXin Li   ProtocolListnfABITy->setBody(LongTy,
5535*67e74705SXin Li                                llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5536*67e74705SXin Li                                nullptr);
5537*67e74705SXin Li 
5538*67e74705SXin Li   // struct _objc_protocol_list*
5539*67e74705SXin Li   ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5540*67e74705SXin Li 
5541*67e74705SXin Li   // struct _ivar_t {
5542*67e74705SXin Li   //   unsigned [long] int *offset;  // pointer to ivar offset location
5543*67e74705SXin Li   //   char *name;
5544*67e74705SXin Li   //   char *type;
5545*67e74705SXin Li   //   uint32_t alignment;
5546*67e74705SXin Li   //   uint32_t size;
5547*67e74705SXin Li   // }
5548*67e74705SXin Li   IvarnfABITy = llvm::StructType::create(
5549*67e74705SXin Li       "struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy),
5550*67e74705SXin Li       Int8PtrTy, Int8PtrTy, IntTy, IntTy, nullptr);
5551*67e74705SXin Li 
5552*67e74705SXin Li   // struct _ivar_list_t {
5553*67e74705SXin Li   //   uint32 entsize;  // sizeof(struct _ivar_t)
5554*67e74705SXin Li   //   uint32 count;
5555*67e74705SXin Li   //   struct _iver_t list[count];
5556*67e74705SXin Li   // }
5557*67e74705SXin Li   IvarListnfABITy =
5558*67e74705SXin Li     llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
5559*67e74705SXin Li                              llvm::ArrayType::get(IvarnfABITy, 0), nullptr);
5560*67e74705SXin Li 
5561*67e74705SXin Li   IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5562*67e74705SXin Li 
5563*67e74705SXin Li   // struct _class_ro_t {
5564*67e74705SXin Li   //   uint32_t const flags;
5565*67e74705SXin Li   //   uint32_t const instanceStart;
5566*67e74705SXin Li   //   uint32_t const instanceSize;
5567*67e74705SXin Li   //   uint32_t const reserved;  // only when building for 64bit targets
5568*67e74705SXin Li   //   const uint8_t * const ivarLayout;
5569*67e74705SXin Li   //   const char *const name;
5570*67e74705SXin Li   //   const struct _method_list_t * const baseMethods;
5571*67e74705SXin Li   //   const struct _objc_protocol_list *const baseProtocols;
5572*67e74705SXin Li   //   const struct _ivar_list_t *const ivars;
5573*67e74705SXin Li   //   const uint8_t * const weakIvarLayout;
5574*67e74705SXin Li   //   const struct _prop_list_t * const properties;
5575*67e74705SXin Li   // }
5576*67e74705SXin Li 
5577*67e74705SXin Li   // FIXME. Add 'reserved' field in 64bit abi mode!
5578*67e74705SXin Li   ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
5579*67e74705SXin Li                                             IntTy, IntTy, IntTy, Int8PtrTy,
5580*67e74705SXin Li                                             Int8PtrTy, MethodListnfABIPtrTy,
5581*67e74705SXin Li                                             ProtocolListnfABIPtrTy,
5582*67e74705SXin Li                                             IvarListnfABIPtrTy,
5583*67e74705SXin Li                                             Int8PtrTy, PropertyListPtrTy,
5584*67e74705SXin Li                                             nullptr);
5585*67e74705SXin Li 
5586*67e74705SXin Li   // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5587*67e74705SXin Li   llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5588*67e74705SXin Li   ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5589*67e74705SXin Li                  ->getPointerTo();
5590*67e74705SXin Li 
5591*67e74705SXin Li   // struct _class_t {
5592*67e74705SXin Li   //   struct _class_t *isa;
5593*67e74705SXin Li   //   struct _class_t * const superclass;
5594*67e74705SXin Li   //   void *cache;
5595*67e74705SXin Li   //   IMP *vtable;
5596*67e74705SXin Li   //   struct class_ro_t *ro;
5597*67e74705SXin Li   // }
5598*67e74705SXin Li 
5599*67e74705SXin Li   ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
5600*67e74705SXin Li   ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5601*67e74705SXin Li                         llvm::PointerType::getUnqual(ClassnfABITy),
5602*67e74705SXin Li                         CachePtrTy,
5603*67e74705SXin Li                         llvm::PointerType::getUnqual(ImpnfABITy),
5604*67e74705SXin Li                         llvm::PointerType::getUnqual(ClassRonfABITy),
5605*67e74705SXin Li                         nullptr);
5606*67e74705SXin Li 
5607*67e74705SXin Li   // LLVM for struct _class_t *
5608*67e74705SXin Li   ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5609*67e74705SXin Li 
5610*67e74705SXin Li   // struct _category_t {
5611*67e74705SXin Li   //   const char * const name;
5612*67e74705SXin Li   //   struct _class_t *const cls;
5613*67e74705SXin Li   //   const struct _method_list_t * const instance_methods;
5614*67e74705SXin Li   //   const struct _method_list_t * const class_methods;
5615*67e74705SXin Li   //   const struct _protocol_list_t * const protocols;
5616*67e74705SXin Li   //   const struct _prop_list_t * const properties;
5617*67e74705SXin Li   //   const struct _prop_list_t * const class_properties;
5618*67e74705SXin Li   //   const uint32_t size;
5619*67e74705SXin Li   // }
5620*67e74705SXin Li   CategorynfABITy = llvm::StructType::create("struct._category_t",
5621*67e74705SXin Li                                              Int8PtrTy, ClassnfABIPtrTy,
5622*67e74705SXin Li                                              MethodListnfABIPtrTy,
5623*67e74705SXin Li                                              MethodListnfABIPtrTy,
5624*67e74705SXin Li                                              ProtocolListnfABIPtrTy,
5625*67e74705SXin Li                                              PropertyListPtrTy,
5626*67e74705SXin Li                                              PropertyListPtrTy,
5627*67e74705SXin Li                                              IntTy,
5628*67e74705SXin Li                                              nullptr);
5629*67e74705SXin Li 
5630*67e74705SXin Li   // New types for nonfragile abi messaging.
5631*67e74705SXin Li   CodeGen::CodeGenTypes &Types = CGM.getTypes();
5632*67e74705SXin Li   ASTContext &Ctx = CGM.getContext();
5633*67e74705SXin Li 
5634*67e74705SXin Li   // MessageRefTy - LLVM for:
5635*67e74705SXin Li   // struct _message_ref_t {
5636*67e74705SXin Li   //   IMP messenger;
5637*67e74705SXin Li   //   SEL name;
5638*67e74705SXin Li   // };
5639*67e74705SXin Li 
5640*67e74705SXin Li   // First the clang type for struct _message_ref_t
5641*67e74705SXin Li   RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5642*67e74705SXin Li                                       Ctx.getTranslationUnitDecl(),
5643*67e74705SXin Li                                       SourceLocation(), SourceLocation(),
5644*67e74705SXin Li                                       &Ctx.Idents.get("_message_ref_t"));
5645*67e74705SXin Li   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5646*67e74705SXin Li                                 nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
5647*67e74705SXin Li                                 ICIS_NoInit));
5648*67e74705SXin Li   RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5649*67e74705SXin Li                                 nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
5650*67e74705SXin Li                                 false, ICIS_NoInit));
5651*67e74705SXin Li   RD->completeDefinition();
5652*67e74705SXin Li 
5653*67e74705SXin Li   MessageRefCTy = Ctx.getTagDeclType(RD);
5654*67e74705SXin Li   MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5655*67e74705SXin Li   MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5656*67e74705SXin Li 
5657*67e74705SXin Li   // MessageRefPtrTy - LLVM for struct _message_ref_t*
5658*67e74705SXin Li   MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5659*67e74705SXin Li 
5660*67e74705SXin Li   // SuperMessageRefTy - LLVM for:
5661*67e74705SXin Li   // struct _super_message_ref_t {
5662*67e74705SXin Li   //   SUPER_IMP messenger;
5663*67e74705SXin Li   //   SEL name;
5664*67e74705SXin Li   // };
5665*67e74705SXin Li   SuperMessageRefTy =
5666*67e74705SXin Li     llvm::StructType::create("struct._super_message_ref_t",
5667*67e74705SXin Li                              ImpnfABITy, SelectorPtrTy, nullptr);
5668*67e74705SXin Li 
5669*67e74705SXin Li   // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5670*67e74705SXin Li   SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5671*67e74705SXin Li 
5672*67e74705SXin Li 
5673*67e74705SXin Li   // struct objc_typeinfo {
5674*67e74705SXin Li   //   const void** vtable; // objc_ehtype_vtable + 2
5675*67e74705SXin Li   //   const char*  name;    // c++ typeinfo string
5676*67e74705SXin Li   //   Class        cls;
5677*67e74705SXin Li   // };
5678*67e74705SXin Li   EHTypeTy =
5679*67e74705SXin Li     llvm::StructType::create("struct._objc_typeinfo",
5680*67e74705SXin Li                              llvm::PointerType::getUnqual(Int8PtrTy),
5681*67e74705SXin Li                              Int8PtrTy, ClassnfABIPtrTy, nullptr);
5682*67e74705SXin Li   EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5683*67e74705SXin Li }
5684*67e74705SXin Li 
ModuleInitFunction()5685*67e74705SXin Li llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5686*67e74705SXin Li   FinishNonFragileABIModule();
5687*67e74705SXin Li 
5688*67e74705SXin Li   return nullptr;
5689*67e74705SXin Li }
5690*67e74705SXin Li 
AddModuleClassList(ArrayRef<llvm::GlobalValue * > Container,StringRef SymbolName,StringRef SectionName)5691*67e74705SXin Li void CGObjCNonFragileABIMac::AddModuleClassList(
5692*67e74705SXin Li     ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
5693*67e74705SXin Li     StringRef SectionName) {
5694*67e74705SXin Li   unsigned NumClasses = Container.size();
5695*67e74705SXin Li 
5696*67e74705SXin Li   if (!NumClasses)
5697*67e74705SXin Li     return;
5698*67e74705SXin Li 
5699*67e74705SXin Li   SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5700*67e74705SXin Li   for (unsigned i=0; i<NumClasses; i++)
5701*67e74705SXin Li     Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5702*67e74705SXin Li                                                 ObjCTypes.Int8PtrTy);
5703*67e74705SXin Li   llvm::Constant *Init =
5704*67e74705SXin Li     llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5705*67e74705SXin Li                                                   Symbols.size()),
5706*67e74705SXin Li                              Symbols);
5707*67e74705SXin Li 
5708*67e74705SXin Li   llvm::GlobalVariable *GV =
5709*67e74705SXin Li     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5710*67e74705SXin Li                              llvm::GlobalValue::PrivateLinkage,
5711*67e74705SXin Li                              Init,
5712*67e74705SXin Li                              SymbolName);
5713*67e74705SXin Li   GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5714*67e74705SXin Li   GV->setSection(SectionName);
5715*67e74705SXin Li   CGM.addCompilerUsedGlobal(GV);
5716*67e74705SXin Li }
5717*67e74705SXin Li 
FinishNonFragileABIModule()5718*67e74705SXin Li void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5719*67e74705SXin Li   // nonfragile abi has no module definition.
5720*67e74705SXin Li 
5721*67e74705SXin Li   // Build list of all implemented class addresses in array
5722*67e74705SXin Li   // L_OBJC_LABEL_CLASS_$.
5723*67e74705SXin Li 
5724*67e74705SXin Li   for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
5725*67e74705SXin Li     const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5726*67e74705SXin Li     assert(ID);
5727*67e74705SXin Li     if (ObjCImplementationDecl *IMP = ID->getImplementation())
5728*67e74705SXin Li       // We are implementing a weak imported interface. Give it external linkage
5729*67e74705SXin Li       if (ID->isWeakImported() && !IMP->isWeakImported()) {
5730*67e74705SXin Li         DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5731*67e74705SXin Li         DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5732*67e74705SXin Li       }
5733*67e74705SXin Li   }
5734*67e74705SXin Li 
5735*67e74705SXin Li   AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$",
5736*67e74705SXin Li                      "__DATA, __objc_classlist, regular, no_dead_strip");
5737*67e74705SXin Li 
5738*67e74705SXin Li   AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$",
5739*67e74705SXin Li                      "__DATA, __objc_nlclslist, regular, no_dead_strip");
5740*67e74705SXin Li 
5741*67e74705SXin Li   // Build list of all implemented category addresses in array
5742*67e74705SXin Li   // L_OBJC_LABEL_CATEGORY_$.
5743*67e74705SXin Li   AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$",
5744*67e74705SXin Li                      "__DATA, __objc_catlist, regular, no_dead_strip");
5745*67e74705SXin Li   AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$",
5746*67e74705SXin Li                      "__DATA, __objc_nlcatlist, regular, no_dead_strip");
5747*67e74705SXin Li 
5748*67e74705SXin Li   EmitImageInfo();
5749*67e74705SXin Li }
5750*67e74705SXin Li 
5751*67e74705SXin Li /// isVTableDispatchedSelector - Returns true if SEL is not in the list of
5752*67e74705SXin Li /// VTableDispatchMethods; false otherwise. What this means is that
5753*67e74705SXin Li /// except for the 19 selectors in the list, we generate 32bit-style
5754*67e74705SXin Li /// message dispatch call for all the rest.
isVTableDispatchedSelector(Selector Sel)5755*67e74705SXin Li bool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5756*67e74705SXin Li   // At various points we've experimented with using vtable-based
5757*67e74705SXin Li   // dispatch for all methods.
5758*67e74705SXin Li   switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5759*67e74705SXin Li   case CodeGenOptions::Legacy:
5760*67e74705SXin Li     return false;
5761*67e74705SXin Li   case CodeGenOptions::NonLegacy:
5762*67e74705SXin Li     return true;
5763*67e74705SXin Li   case CodeGenOptions::Mixed:
5764*67e74705SXin Li     break;
5765*67e74705SXin Li   }
5766*67e74705SXin Li 
5767*67e74705SXin Li   // If so, see whether this selector is in the white-list of things which must
5768*67e74705SXin Li   // use the new dispatch convention. We lazily build a dense set for this.
5769*67e74705SXin Li   if (VTableDispatchMethods.empty()) {
5770*67e74705SXin Li     VTableDispatchMethods.insert(GetNullarySelector("alloc"));
5771*67e74705SXin Li     VTableDispatchMethods.insert(GetNullarySelector("class"));
5772*67e74705SXin Li     VTableDispatchMethods.insert(GetNullarySelector("self"));
5773*67e74705SXin Li     VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
5774*67e74705SXin Li     VTableDispatchMethods.insert(GetNullarySelector("length"));
5775*67e74705SXin Li     VTableDispatchMethods.insert(GetNullarySelector("count"));
5776*67e74705SXin Li 
5777*67e74705SXin Li     // These are vtable-based if GC is disabled.
5778*67e74705SXin Li     // Optimistically use vtable dispatch for hybrid compiles.
5779*67e74705SXin Li     if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
5780*67e74705SXin Li       VTableDispatchMethods.insert(GetNullarySelector("retain"));
5781*67e74705SXin Li       VTableDispatchMethods.insert(GetNullarySelector("release"));
5782*67e74705SXin Li       VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
5783*67e74705SXin Li     }
5784*67e74705SXin Li 
5785*67e74705SXin Li     VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
5786*67e74705SXin Li     VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
5787*67e74705SXin Li     VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
5788*67e74705SXin Li     VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
5789*67e74705SXin Li     VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
5790*67e74705SXin Li     VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
5791*67e74705SXin Li     VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
5792*67e74705SXin Li 
5793*67e74705SXin Li     // These are vtable-based if GC is enabled.
5794*67e74705SXin Li     // Optimistically use vtable dispatch for hybrid compiles.
5795*67e74705SXin Li     if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5796*67e74705SXin Li       VTableDispatchMethods.insert(GetNullarySelector("hash"));
5797*67e74705SXin Li       VTableDispatchMethods.insert(GetUnarySelector("addObject"));
5798*67e74705SXin Li 
5799*67e74705SXin Li       // "countByEnumeratingWithState:objects:count"
5800*67e74705SXin Li       IdentifierInfo *KeyIdents[] = {
5801*67e74705SXin Li         &CGM.getContext().Idents.get("countByEnumeratingWithState"),
5802*67e74705SXin Li         &CGM.getContext().Idents.get("objects"),
5803*67e74705SXin Li         &CGM.getContext().Idents.get("count")
5804*67e74705SXin Li       };
5805*67e74705SXin Li       VTableDispatchMethods.insert(
5806*67e74705SXin Li         CGM.getContext().Selectors.getSelector(3, KeyIdents));
5807*67e74705SXin Li     }
5808*67e74705SXin Li   }
5809*67e74705SXin Li 
5810*67e74705SXin Li   return VTableDispatchMethods.count(Sel);
5811*67e74705SXin Li }
5812*67e74705SXin Li 
5813*67e74705SXin Li /// BuildClassRoTInitializer - generate meta-data for:
5814*67e74705SXin Li /// struct _class_ro_t {
5815*67e74705SXin Li ///   uint32_t const flags;
5816*67e74705SXin Li ///   uint32_t const instanceStart;
5817*67e74705SXin Li ///   uint32_t const instanceSize;
5818*67e74705SXin Li ///   uint32_t const reserved;  // only when building for 64bit targets
5819*67e74705SXin Li ///   const uint8_t * const ivarLayout;
5820*67e74705SXin Li ///   const char *const name;
5821*67e74705SXin Li ///   const struct _method_list_t * const baseMethods;
5822*67e74705SXin Li ///   const struct _protocol_list_t *const baseProtocols;
5823*67e74705SXin Li ///   const struct _ivar_list_t *const ivars;
5824*67e74705SXin Li ///   const uint8_t * const weakIvarLayout;
5825*67e74705SXin Li ///   const struct _prop_list_t * const properties;
5826*67e74705SXin Li /// }
5827*67e74705SXin Li ///
BuildClassRoTInitializer(unsigned flags,unsigned InstanceStart,unsigned InstanceSize,const ObjCImplementationDecl * ID)5828*67e74705SXin Li llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
5829*67e74705SXin Li   unsigned flags,
5830*67e74705SXin Li   unsigned InstanceStart,
5831*67e74705SXin Li   unsigned InstanceSize,
5832*67e74705SXin Li   const ObjCImplementationDecl *ID) {
5833*67e74705SXin Li   std::string ClassName = ID->getObjCRuntimeNameAsString();
5834*67e74705SXin Li   llvm::Constant *Values[10]; // 11 for 64bit targets!
5835*67e74705SXin Li 
5836*67e74705SXin Li   CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
5837*67e74705SXin Li   CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
5838*67e74705SXin Li 
5839*67e74705SXin Li   bool hasMRCWeak = false;
5840*67e74705SXin Li   if (CGM.getLangOpts().ObjCAutoRefCount)
5841*67e74705SXin Li     flags |= NonFragileABI_Class_CompiledByARC;
5842*67e74705SXin Li   else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
5843*67e74705SXin Li     flags |= NonFragileABI_Class_HasMRCWeakIvars;
5844*67e74705SXin Li 
5845*67e74705SXin Li   Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5846*67e74705SXin Li   Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5847*67e74705SXin Li   Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
5848*67e74705SXin Li   // FIXME. For 64bit targets add 0 here.
5849*67e74705SXin Li   Values[ 3] = (flags & NonFragileABI_Class_Meta)
5850*67e74705SXin Li     ? GetIvarLayoutName(nullptr, ObjCTypes)
5851*67e74705SXin Li     : BuildStrongIvarLayout(ID, beginInstance, endInstance);
5852*67e74705SXin Li   Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
5853*67e74705SXin Li   // const struct _method_list_t * const baseMethods;
5854*67e74705SXin Li   std::vector<llvm::Constant*> Methods;
5855*67e74705SXin Li   std::string MethodListName("\01l_OBJC_$_");
5856*67e74705SXin Li   if (flags & NonFragileABI_Class_Meta) {
5857*67e74705SXin Li     MethodListName += "CLASS_METHODS_";
5858*67e74705SXin Li     MethodListName += ID->getObjCRuntimeNameAsString();
5859*67e74705SXin Li     for (const auto *I : ID->class_methods())
5860*67e74705SXin Li       // Class methods should always be defined.
5861*67e74705SXin Li       Methods.push_back(GetMethodConstant(I));
5862*67e74705SXin Li   } else {
5863*67e74705SXin Li     MethodListName += "INSTANCE_METHODS_";
5864*67e74705SXin Li     MethodListName += ID->getObjCRuntimeNameAsString();
5865*67e74705SXin Li     for (const auto *I : ID->instance_methods())
5866*67e74705SXin Li       // Instance methods should always be defined.
5867*67e74705SXin Li       Methods.push_back(GetMethodConstant(I));
5868*67e74705SXin Li 
5869*67e74705SXin Li     for (const auto *PID : ID->property_impls()) {
5870*67e74705SXin Li       if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5871*67e74705SXin Li         ObjCPropertyDecl *PD = PID->getPropertyDecl();
5872*67e74705SXin Li 
5873*67e74705SXin Li         if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5874*67e74705SXin Li           if (llvm::Constant *C = GetMethodConstant(MD))
5875*67e74705SXin Li             Methods.push_back(C);
5876*67e74705SXin Li         if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5877*67e74705SXin Li           if (llvm::Constant *C = GetMethodConstant(MD))
5878*67e74705SXin Li             Methods.push_back(C);
5879*67e74705SXin Li       }
5880*67e74705SXin Li     }
5881*67e74705SXin Li   }
5882*67e74705SXin Li   Values[ 5] = EmitMethodList(MethodListName,
5883*67e74705SXin Li                               "__DATA, __objc_const", Methods);
5884*67e74705SXin Li 
5885*67e74705SXin Li   const ObjCInterfaceDecl *OID = ID->getClassInterface();
5886*67e74705SXin Li   assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
5887*67e74705SXin Li   Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
5888*67e74705SXin Li                                 + OID->getObjCRuntimeNameAsString(),
5889*67e74705SXin Li                                 OID->all_referenced_protocol_begin(),
5890*67e74705SXin Li                                 OID->all_referenced_protocol_end());
5891*67e74705SXin Li 
5892*67e74705SXin Li   if (flags & NonFragileABI_Class_Meta) {
5893*67e74705SXin Li     Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5894*67e74705SXin Li     Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes);
5895*67e74705SXin Li     Values[ 9] = EmitPropertyList(
5896*67e74705SXin Li         "\01l_OBJC_$_CLASS_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
5897*67e74705SXin Li         ID, ID->getClassInterface(), ObjCTypes, true);
5898*67e74705SXin Li   } else {
5899*67e74705SXin Li     Values[ 7] = EmitIvarList(ID);
5900*67e74705SXin Li     Values[ 8] = BuildWeakIvarLayout(ID, beginInstance, endInstance,
5901*67e74705SXin Li                                      hasMRCWeak);
5902*67e74705SXin Li     Values[ 9] = EmitPropertyList(
5903*67e74705SXin Li         "\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
5904*67e74705SXin Li         ID, ID->getClassInterface(), ObjCTypes, false);
5905*67e74705SXin Li   }
5906*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5907*67e74705SXin Li                                                    Values);
5908*67e74705SXin Li   llvm::GlobalVariable *CLASS_RO_GV =
5909*67e74705SXin Li     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5910*67e74705SXin Li                              llvm::GlobalValue::PrivateLinkage,
5911*67e74705SXin Li                              Init,
5912*67e74705SXin Li                              (flags & NonFragileABI_Class_Meta) ?
5913*67e74705SXin Li                              std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
5914*67e74705SXin Li                              std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
5915*67e74705SXin Li   CLASS_RO_GV->setAlignment(
5916*67e74705SXin Li     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5917*67e74705SXin Li   CLASS_RO_GV->setSection("__DATA, __objc_const");
5918*67e74705SXin Li   return CLASS_RO_GV;
5919*67e74705SXin Li 
5920*67e74705SXin Li }
5921*67e74705SXin Li 
5922*67e74705SXin Li /// BuildClassMetaData - This routine defines that to-level meta-data
5923*67e74705SXin Li /// for the given ClassName for:
5924*67e74705SXin Li /// struct _class_t {
5925*67e74705SXin Li ///   struct _class_t *isa;
5926*67e74705SXin Li ///   struct _class_t * const superclass;
5927*67e74705SXin Li ///   void *cache;
5928*67e74705SXin Li ///   IMP *vtable;
5929*67e74705SXin Li ///   struct class_ro_t *ro;
5930*67e74705SXin Li /// }
5931*67e74705SXin Li ///
BuildClassMetaData(const std::string & ClassName,llvm::Constant * IsAGV,llvm::Constant * SuperClassGV,llvm::Constant * ClassRoGV,bool HiddenVisibility,bool Weak)5932*67e74705SXin Li llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
5933*67e74705SXin Li     const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
5934*67e74705SXin Li     llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
5935*67e74705SXin Li   llvm::Constant *Values[] = {
5936*67e74705SXin Li     IsAGV,
5937*67e74705SXin Li     SuperClassGV,
5938*67e74705SXin Li     ObjCEmptyCacheVar,  // &ObjCEmptyCacheVar
5939*67e74705SXin Li     ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5940*67e74705SXin Li     ClassRoGV           // &CLASS_RO_GV
5941*67e74705SXin Li   };
5942*67e74705SXin Li   if (!Values[1])
5943*67e74705SXin Li     Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5944*67e74705SXin Li   if (!Values[3])
5945*67e74705SXin Li     Values[3] = llvm::Constant::getNullValue(
5946*67e74705SXin Li                   llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
5947*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5948*67e74705SXin Li                                                    Values);
5949*67e74705SXin Li   llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
5950*67e74705SXin Li   GV->setInitializer(Init);
5951*67e74705SXin Li   GV->setSection("__DATA, __objc_data");
5952*67e74705SXin Li   GV->setAlignment(
5953*67e74705SXin Li     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5954*67e74705SXin Li   if (HiddenVisibility)
5955*67e74705SXin Li     GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5956*67e74705SXin Li   return GV;
5957*67e74705SXin Li }
5958*67e74705SXin Li 
5959*67e74705SXin Li bool
ImplementationIsNonLazy(const ObjCImplDecl * OD) const5960*67e74705SXin Li CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5961*67e74705SXin Li   return OD->getClassMethod(GetNullarySelector("load")) != nullptr;
5962*67e74705SXin Li }
5963*67e74705SXin Li 
GetClassSizeInfo(const ObjCImplementationDecl * OID,uint32_t & InstanceStart,uint32_t & InstanceSize)5964*67e74705SXin Li void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5965*67e74705SXin Li                                               uint32_t &InstanceStart,
5966*67e74705SXin Li                                               uint32_t &InstanceSize) {
5967*67e74705SXin Li   const ASTRecordLayout &RL =
5968*67e74705SXin Li     CGM.getContext().getASTObjCImplementationLayout(OID);
5969*67e74705SXin Li 
5970*67e74705SXin Li   // InstanceSize is really instance end.
5971*67e74705SXin Li   InstanceSize = RL.getDataSize().getQuantity();
5972*67e74705SXin Li 
5973*67e74705SXin Li   // If there are no fields, the start is the same as the end.
5974*67e74705SXin Li   if (!RL.getFieldCount())
5975*67e74705SXin Li     InstanceStart = InstanceSize;
5976*67e74705SXin Li   else
5977*67e74705SXin Li     InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5978*67e74705SXin Li }
5979*67e74705SXin Li 
GenerateClass(const ObjCImplementationDecl * ID)5980*67e74705SXin Li void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5981*67e74705SXin Li   std::string ClassName = ID->getObjCRuntimeNameAsString();
5982*67e74705SXin Li   if (!ObjCEmptyCacheVar) {
5983*67e74705SXin Li     ObjCEmptyCacheVar = new llvm::GlobalVariable(
5984*67e74705SXin Li         CGM.getModule(), ObjCTypes.CacheTy, false,
5985*67e74705SXin Li         llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_cache");
5986*67e74705SXin Li 
5987*67e74705SXin Li     // Only OS X with deployment version <10.9 use the empty vtable symbol
5988*67e74705SXin Li     const llvm::Triple &Triple = CGM.getTarget().getTriple();
5989*67e74705SXin Li     if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
5990*67e74705SXin Li       ObjCEmptyVtableVar = new llvm::GlobalVariable(
5991*67e74705SXin Li           CGM.getModule(), ObjCTypes.ImpnfABITy, false,
5992*67e74705SXin Li           llvm::GlobalValue::ExternalLinkage, nullptr, "_objc_empty_vtable");
5993*67e74705SXin Li   }
5994*67e74705SXin Li   assert(ID->getClassInterface() &&
5995*67e74705SXin Li          "CGObjCNonFragileABIMac::GenerateClass - class is 0");
5996*67e74705SXin Li   // FIXME: Is this correct (that meta class size is never computed)?
5997*67e74705SXin Li   uint32_t InstanceStart =
5998*67e74705SXin Li     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5999*67e74705SXin Li   uint32_t InstanceSize = InstanceStart;
6000*67e74705SXin Li   uint32_t flags = NonFragileABI_Class_Meta;
6001*67e74705SXin Li   llvm::SmallString<64> ObjCMetaClassName(getMetaclassSymbolPrefix());
6002*67e74705SXin Li   llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix());
6003*67e74705SXin Li   llvm::SmallString<64> TClassName;
6004*67e74705SXin Li 
6005*67e74705SXin Li   llvm::GlobalVariable *SuperClassGV, *IsAGV;
6006*67e74705SXin Li 
6007*67e74705SXin Li   // Build the flags for the metaclass.
6008*67e74705SXin Li   bool classIsHidden =
6009*67e74705SXin Li     ID->getClassInterface()->getVisibility() == HiddenVisibility;
6010*67e74705SXin Li   if (classIsHidden)
6011*67e74705SXin Li     flags |= NonFragileABI_Class_Hidden;
6012*67e74705SXin Li 
6013*67e74705SXin Li   // FIXME: why is this flag set on the metaclass?
6014*67e74705SXin Li   // ObjC metaclasses have no fields and don't really get constructed.
6015*67e74705SXin Li   if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6016*67e74705SXin Li     flags |= NonFragileABI_Class_HasCXXStructors;
6017*67e74705SXin Li     if (!ID->hasNonZeroConstructors())
6018*67e74705SXin Li       flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6019*67e74705SXin Li   }
6020*67e74705SXin Li 
6021*67e74705SXin Li   if (!ID->getClassInterface()->getSuperClass()) {
6022*67e74705SXin Li     // class is root
6023*67e74705SXin Li     flags |= NonFragileABI_Class_Root;
6024*67e74705SXin Li     TClassName = ObjCClassName;
6025*67e74705SXin Li     TClassName += ClassName;
6026*67e74705SXin Li     SuperClassGV = GetClassGlobal(TClassName.str(),
6027*67e74705SXin Li                                   ID->getClassInterface()->isWeakImported());
6028*67e74705SXin Li     TClassName = ObjCMetaClassName;
6029*67e74705SXin Li     TClassName += ClassName;
6030*67e74705SXin Li     IsAGV = GetClassGlobal(TClassName.str(),
6031*67e74705SXin Li                            ID->getClassInterface()->isWeakImported());
6032*67e74705SXin Li   } else {
6033*67e74705SXin Li     // Has a root. Current class is not a root.
6034*67e74705SXin Li     const ObjCInterfaceDecl *Root = ID->getClassInterface();
6035*67e74705SXin Li     while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
6036*67e74705SXin Li       Root = Super;
6037*67e74705SXin Li     TClassName = ObjCMetaClassName ;
6038*67e74705SXin Li     TClassName += Root->getObjCRuntimeNameAsString();
6039*67e74705SXin Li     IsAGV = GetClassGlobal(TClassName.str(),
6040*67e74705SXin Li                            Root->isWeakImported());
6041*67e74705SXin Li 
6042*67e74705SXin Li     // work on super class metadata symbol.
6043*67e74705SXin Li     TClassName = ObjCMetaClassName;
6044*67e74705SXin Li     TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
6045*67e74705SXin Li     SuperClassGV = GetClassGlobal(
6046*67e74705SXin Li                                   TClassName.str(),
6047*67e74705SXin Li                                   ID->getClassInterface()->getSuperClass()->isWeakImported());
6048*67e74705SXin Li   }
6049*67e74705SXin Li   llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
6050*67e74705SXin Li                                                                InstanceStart,
6051*67e74705SXin Li                                                                InstanceSize,ID);
6052*67e74705SXin Li   TClassName = ObjCMetaClassName;
6053*67e74705SXin Li   TClassName += ClassName;
6054*67e74705SXin Li   llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
6055*67e74705SXin Li       TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
6056*67e74705SXin Li       ID->getClassInterface()->isWeakImported());
6057*67e74705SXin Li   DefinedMetaClasses.push_back(MetaTClass);
6058*67e74705SXin Li 
6059*67e74705SXin Li   // Metadata for the class
6060*67e74705SXin Li   flags = 0;
6061*67e74705SXin Li   if (classIsHidden)
6062*67e74705SXin Li     flags |= NonFragileABI_Class_Hidden;
6063*67e74705SXin Li 
6064*67e74705SXin Li   if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6065*67e74705SXin Li     flags |= NonFragileABI_Class_HasCXXStructors;
6066*67e74705SXin Li 
6067*67e74705SXin Li     // Set a flag to enable a runtime optimization when a class has
6068*67e74705SXin Li     // fields that require destruction but which don't require
6069*67e74705SXin Li     // anything except zero-initialization during construction.  This
6070*67e74705SXin Li     // is most notably true of __strong and __weak types, but you can
6071*67e74705SXin Li     // also imagine there being C++ types with non-trivial default
6072*67e74705SXin Li     // constructors that merely set all fields to null.
6073*67e74705SXin Li     if (!ID->hasNonZeroConstructors())
6074*67e74705SXin Li       flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6075*67e74705SXin Li   }
6076*67e74705SXin Li 
6077*67e74705SXin Li   if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
6078*67e74705SXin Li     flags |= NonFragileABI_Class_Exception;
6079*67e74705SXin Li 
6080*67e74705SXin Li   if (!ID->getClassInterface()->getSuperClass()) {
6081*67e74705SXin Li     flags |= NonFragileABI_Class_Root;
6082*67e74705SXin Li     SuperClassGV = nullptr;
6083*67e74705SXin Li   } else {
6084*67e74705SXin Li     // Has a root. Current class is not a root.
6085*67e74705SXin Li     TClassName = ObjCClassName;
6086*67e74705SXin Li     TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
6087*67e74705SXin Li     SuperClassGV = GetClassGlobal(
6088*67e74705SXin Li                                   TClassName.str(),
6089*67e74705SXin Li                                   ID->getClassInterface()->getSuperClass()->isWeakImported());
6090*67e74705SXin Li   }
6091*67e74705SXin Li   GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6092*67e74705SXin Li   CLASS_RO_GV = BuildClassRoTInitializer(flags,
6093*67e74705SXin Li                                          InstanceStart,
6094*67e74705SXin Li                                          InstanceSize,
6095*67e74705SXin Li                                          ID);
6096*67e74705SXin Li 
6097*67e74705SXin Li   TClassName = ObjCClassName;
6098*67e74705SXin Li   TClassName += ClassName;
6099*67e74705SXin Li   llvm::GlobalVariable *ClassMD =
6100*67e74705SXin Li     BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
6101*67e74705SXin Li                        classIsHidden,
6102*67e74705SXin Li                        ID->getClassInterface()->isWeakImported());
6103*67e74705SXin Li   DefinedClasses.push_back(ClassMD);
6104*67e74705SXin Li   ImplementedClasses.push_back(ID->getClassInterface());
6105*67e74705SXin Li 
6106*67e74705SXin Li   // Determine if this class is also "non-lazy".
6107*67e74705SXin Li   if (ImplementationIsNonLazy(ID))
6108*67e74705SXin Li     DefinedNonLazyClasses.push_back(ClassMD);
6109*67e74705SXin Li 
6110*67e74705SXin Li   // Force the definition of the EHType if necessary.
6111*67e74705SXin Li   if (flags & NonFragileABI_Class_Exception)
6112*67e74705SXin Li     GetInterfaceEHType(ID->getClassInterface(), true);
6113*67e74705SXin Li   // Make sure method definition entries are all clear for next implementation.
6114*67e74705SXin Li   MethodDefinitions.clear();
6115*67e74705SXin Li }
6116*67e74705SXin Li 
6117*67e74705SXin Li /// GenerateProtocolRef - This routine is called to generate code for
6118*67e74705SXin Li /// a protocol reference expression; as in:
6119*67e74705SXin Li /// @code
6120*67e74705SXin Li ///   @protocol(Proto1);
6121*67e74705SXin Li /// @endcode
6122*67e74705SXin Li /// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
6123*67e74705SXin Li /// which will hold address of the protocol meta-data.
6124*67e74705SXin Li ///
GenerateProtocolRef(CodeGenFunction & CGF,const ObjCProtocolDecl * PD)6125*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
6126*67e74705SXin Li                                                          const ObjCProtocolDecl *PD) {
6127*67e74705SXin Li 
6128*67e74705SXin Li   // This routine is called for @protocol only. So, we must build definition
6129*67e74705SXin Li   // of protocol's meta-data (not a reference to it!)
6130*67e74705SXin Li   //
6131*67e74705SXin Li   llvm::Constant *Init =
6132*67e74705SXin Li     llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6133*67e74705SXin Li                                    ObjCTypes.getExternalProtocolPtrTy());
6134*67e74705SXin Li 
6135*67e74705SXin Li   std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
6136*67e74705SXin Li   ProtocolName += PD->getObjCRuntimeNameAsString();
6137*67e74705SXin Li 
6138*67e74705SXin Li   CharUnits Align = CGF.getPointerAlign();
6139*67e74705SXin Li 
6140*67e74705SXin Li   llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
6141*67e74705SXin Li   if (PTGV)
6142*67e74705SXin Li     return CGF.Builder.CreateAlignedLoad(PTGV, Align);
6143*67e74705SXin Li   PTGV = new llvm::GlobalVariable(
6144*67e74705SXin Li     CGM.getModule(),
6145*67e74705SXin Li     Init->getType(), false,
6146*67e74705SXin Li     llvm::GlobalValue::WeakAnyLinkage,
6147*67e74705SXin Li     Init,
6148*67e74705SXin Li     ProtocolName);
6149*67e74705SXin Li   PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
6150*67e74705SXin Li   PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6151*67e74705SXin Li   PTGV->setAlignment(Align.getQuantity());
6152*67e74705SXin Li   CGM.addCompilerUsedGlobal(PTGV);
6153*67e74705SXin Li   return CGF.Builder.CreateAlignedLoad(PTGV, Align);
6154*67e74705SXin Li }
6155*67e74705SXin Li 
6156*67e74705SXin Li /// GenerateCategory - Build metadata for a category implementation.
6157*67e74705SXin Li /// struct _category_t {
6158*67e74705SXin Li ///   const char * const name;
6159*67e74705SXin Li ///   struct _class_t *const cls;
6160*67e74705SXin Li ///   const struct _method_list_t * const instance_methods;
6161*67e74705SXin Li ///   const struct _method_list_t * const class_methods;
6162*67e74705SXin Li ///   const struct _protocol_list_t * const protocols;
6163*67e74705SXin Li ///   const struct _prop_list_t * const properties;
6164*67e74705SXin Li ///   const struct _prop_list_t * const class_properties;
6165*67e74705SXin Li ///   const uint32_t size;
6166*67e74705SXin Li /// }
6167*67e74705SXin Li ///
GenerateCategory(const ObjCCategoryImplDecl * OCD)6168*67e74705SXin Li void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
6169*67e74705SXin Li   const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
6170*67e74705SXin Li   const char *Prefix = "\01l_OBJC_$_CATEGORY_";
6171*67e74705SXin Li 
6172*67e74705SXin Li   llvm::SmallString<64> ExtCatName(Prefix);
6173*67e74705SXin Li   ExtCatName += Interface->getObjCRuntimeNameAsString();
6174*67e74705SXin Li   ExtCatName += "_$_";
6175*67e74705SXin Li   ExtCatName += OCD->getNameAsString();
6176*67e74705SXin Li 
6177*67e74705SXin Li   llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
6178*67e74705SXin Li   ExtClassName += Interface->getObjCRuntimeNameAsString();
6179*67e74705SXin Li 
6180*67e74705SXin Li   llvm::Constant *Values[8];
6181*67e74705SXin Li   Values[0] = GetClassName(OCD->getIdentifier()->getName());
6182*67e74705SXin Li   // meta-class entry symbol
6183*67e74705SXin Li   llvm::GlobalVariable *ClassGV =
6184*67e74705SXin Li       GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
6185*67e74705SXin Li 
6186*67e74705SXin Li   Values[1] = ClassGV;
6187*67e74705SXin Li   std::vector<llvm::Constant*> Methods;
6188*67e74705SXin Li   llvm::SmallString<64> MethodListName(Prefix);
6189*67e74705SXin Li 
6190*67e74705SXin Li   MethodListName += "INSTANCE_METHODS_";
6191*67e74705SXin Li   MethodListName += Interface->getObjCRuntimeNameAsString();
6192*67e74705SXin Li   MethodListName += "_$_";
6193*67e74705SXin Li   MethodListName += OCD->getName();
6194*67e74705SXin Li 
6195*67e74705SXin Li   for (const auto *I : OCD->instance_methods())
6196*67e74705SXin Li     // Instance methods should always be defined.
6197*67e74705SXin Li     Methods.push_back(GetMethodConstant(I));
6198*67e74705SXin Li 
6199*67e74705SXin Li   Values[2] = EmitMethodList(MethodListName.str(),
6200*67e74705SXin Li                              "__DATA, __objc_const",
6201*67e74705SXin Li                              Methods);
6202*67e74705SXin Li 
6203*67e74705SXin Li   MethodListName = Prefix;
6204*67e74705SXin Li   MethodListName += "CLASS_METHODS_";
6205*67e74705SXin Li   MethodListName += Interface->getObjCRuntimeNameAsString();
6206*67e74705SXin Li   MethodListName += "_$_";
6207*67e74705SXin Li   MethodListName += OCD->getNameAsString();
6208*67e74705SXin Li 
6209*67e74705SXin Li   Methods.clear();
6210*67e74705SXin Li   for (const auto *I : OCD->class_methods())
6211*67e74705SXin Li     // Class methods should always be defined.
6212*67e74705SXin Li     Methods.push_back(GetMethodConstant(I));
6213*67e74705SXin Li 
6214*67e74705SXin Li   Values[3] = EmitMethodList(MethodListName.str(),
6215*67e74705SXin Li                              "__DATA, __objc_const",
6216*67e74705SXin Li                              Methods);
6217*67e74705SXin Li   const ObjCCategoryDecl *Category =
6218*67e74705SXin Li     Interface->FindCategoryDeclaration(OCD->getIdentifier());
6219*67e74705SXin Li   if (Category) {
6220*67e74705SXin Li     SmallString<256> ExtName;
6221*67e74705SXin Li     llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
6222*67e74705SXin Li                                        << OCD->getName();
6223*67e74705SXin Li     Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
6224*67e74705SXin Li                                    + Interface->getObjCRuntimeNameAsString() + "_$_"
6225*67e74705SXin Li                                    + Category->getName(),
6226*67e74705SXin Li                                    Category->protocol_begin(),
6227*67e74705SXin Li                                    Category->protocol_end());
6228*67e74705SXin Li     Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6229*67e74705SXin Li                                  OCD, Category, ObjCTypes, false);
6230*67e74705SXin Li     Values[6] = EmitPropertyList("\01l_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6231*67e74705SXin Li                                  OCD, Category, ObjCTypes, true);
6232*67e74705SXin Li   } else {
6233*67e74705SXin Li     Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6234*67e74705SXin Li     Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
6235*67e74705SXin Li     Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
6236*67e74705SXin Li   }
6237*67e74705SXin Li 
6238*67e74705SXin Li   unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6239*67e74705SXin Li   Values[7] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6240*67e74705SXin Li 
6241*67e74705SXin Li   llvm::Constant *Init =
6242*67e74705SXin Li     llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
6243*67e74705SXin Li                               Values);
6244*67e74705SXin Li   llvm::GlobalVariable *GCATV
6245*67e74705SXin Li     = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
6246*67e74705SXin Li                                false,
6247*67e74705SXin Li                                llvm::GlobalValue::PrivateLinkage,
6248*67e74705SXin Li                                Init,
6249*67e74705SXin Li                                ExtCatName.str());
6250*67e74705SXin Li   GCATV->setAlignment(
6251*67e74705SXin Li     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
6252*67e74705SXin Li   GCATV->setSection("__DATA, __objc_const");
6253*67e74705SXin Li   CGM.addCompilerUsedGlobal(GCATV);
6254*67e74705SXin Li   DefinedCategories.push_back(GCATV);
6255*67e74705SXin Li 
6256*67e74705SXin Li   // Determine if this category is also "non-lazy".
6257*67e74705SXin Li   if (ImplementationIsNonLazy(OCD))
6258*67e74705SXin Li     DefinedNonLazyCategories.push_back(GCATV);
6259*67e74705SXin Li   // method definition entries must be clear for next implementation.
6260*67e74705SXin Li   MethodDefinitions.clear();
6261*67e74705SXin Li }
6262*67e74705SXin Li 
6263*67e74705SXin Li /// GetMethodConstant - Return a struct objc_method constant for the
6264*67e74705SXin Li /// given method if it has been defined. The result is null if the
6265*67e74705SXin Li /// method has not been defined. The return value has type MethodPtrTy.
GetMethodConstant(const ObjCMethodDecl * MD)6266*67e74705SXin Li llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
6267*67e74705SXin Li   const ObjCMethodDecl *MD) {
6268*67e74705SXin Li   llvm::Function *Fn = GetMethodDefinition(MD);
6269*67e74705SXin Li   if (!Fn)
6270*67e74705SXin Li     return nullptr;
6271*67e74705SXin Li 
6272*67e74705SXin Li   llvm::Constant *Method[] = {
6273*67e74705SXin Li     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6274*67e74705SXin Li                                    ObjCTypes.SelectorPtrTy),
6275*67e74705SXin Li     GetMethodVarType(MD),
6276*67e74705SXin Li     llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
6277*67e74705SXin Li   };
6278*67e74705SXin Li   return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
6279*67e74705SXin Li }
6280*67e74705SXin Li 
6281*67e74705SXin Li /// EmitMethodList - Build meta-data for method declarations
6282*67e74705SXin Li /// struct _method_list_t {
6283*67e74705SXin Li ///   uint32_t entsize;  // sizeof(struct _objc_method)
6284*67e74705SXin Li ///   uint32_t method_count;
6285*67e74705SXin Li ///   struct _objc_method method_list[method_count];
6286*67e74705SXin Li /// }
6287*67e74705SXin Li ///
6288*67e74705SXin Li llvm::Constant *
EmitMethodList(Twine Name,StringRef Section,ArrayRef<llvm::Constant * > Methods)6289*67e74705SXin Li CGObjCNonFragileABIMac::EmitMethodList(Twine Name, StringRef Section,
6290*67e74705SXin Li                                        ArrayRef<llvm::Constant *> Methods) {
6291*67e74705SXin Li   // Return null for empty list.
6292*67e74705SXin Li   if (Methods.empty())
6293*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6294*67e74705SXin Li 
6295*67e74705SXin Li   llvm::Constant *Values[3];
6296*67e74705SXin Li   // sizeof(struct _objc_method)
6297*67e74705SXin Li   unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6298*67e74705SXin Li   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6299*67e74705SXin Li   // method_count
6300*67e74705SXin Li   Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
6301*67e74705SXin Li   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
6302*67e74705SXin Li                                              Methods.size());
6303*67e74705SXin Li   Values[2] = llvm::ConstantArray::get(AT, Methods);
6304*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6305*67e74705SXin Li 
6306*67e74705SXin Li   llvm::GlobalVariable *GV =
6307*67e74705SXin Li     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6308*67e74705SXin Li                              llvm::GlobalValue::PrivateLinkage, Init, Name);
6309*67e74705SXin Li   GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6310*67e74705SXin Li   GV->setSection(Section);
6311*67e74705SXin Li   CGM.addCompilerUsedGlobal(GV);
6312*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6313*67e74705SXin Li }
6314*67e74705SXin Li 
6315*67e74705SXin Li /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6316*67e74705SXin Li /// the given ivar.
6317*67e74705SXin Li llvm::GlobalVariable *
ObjCIvarOffsetVariable(const ObjCInterfaceDecl * ID,const ObjCIvarDecl * Ivar)6318*67e74705SXin Li CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6319*67e74705SXin Li                                                const ObjCIvarDecl *Ivar) {
6320*67e74705SXin Li 
6321*67e74705SXin Li   const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6322*67e74705SXin Li   llvm::SmallString<64> Name("OBJC_IVAR_$_");
6323*67e74705SXin Li   Name += Container->getObjCRuntimeNameAsString();
6324*67e74705SXin Li   Name += ".";
6325*67e74705SXin Li   Name += Ivar->getName();
6326*67e74705SXin Li   llvm::GlobalVariable *IvarOffsetGV =
6327*67e74705SXin Li     CGM.getModule().getGlobalVariable(Name);
6328*67e74705SXin Li   if (!IvarOffsetGV)
6329*67e74705SXin Li     IvarOffsetGV = new llvm::GlobalVariable(
6330*67e74705SXin Li       CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
6331*67e74705SXin Li       llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
6332*67e74705SXin Li   return IvarOffsetGV;
6333*67e74705SXin Li }
6334*67e74705SXin Li 
6335*67e74705SXin Li llvm::Constant *
EmitIvarOffsetVar(const ObjCInterfaceDecl * ID,const ObjCIvarDecl * Ivar,unsigned long int Offset)6336*67e74705SXin Li CGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6337*67e74705SXin Li                                           const ObjCIvarDecl *Ivar,
6338*67e74705SXin Li                                           unsigned long int Offset) {
6339*67e74705SXin Li   llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6340*67e74705SXin Li   IvarOffsetGV->setInitializer(
6341*67e74705SXin Li       llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6342*67e74705SXin Li   IvarOffsetGV->setAlignment(
6343*67e74705SXin Li       CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
6344*67e74705SXin Li 
6345*67e74705SXin Li   // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
6346*67e74705SXin Li   // well (i.e., in ObjCIvarOffsetVariable).
6347*67e74705SXin Li   if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6348*67e74705SXin Li       Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6349*67e74705SXin Li       ID->getVisibility() == HiddenVisibility)
6350*67e74705SXin Li     IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6351*67e74705SXin Li   else
6352*67e74705SXin Li     IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6353*67e74705SXin Li   IvarOffsetGV->setSection("__DATA, __objc_ivar");
6354*67e74705SXin Li   return IvarOffsetGV;
6355*67e74705SXin Li }
6356*67e74705SXin Li 
6357*67e74705SXin Li /// EmitIvarList - Emit the ivar list for the given
6358*67e74705SXin Li /// implementation. The return value has type
6359*67e74705SXin Li /// IvarListnfABIPtrTy.
6360*67e74705SXin Li ///  struct _ivar_t {
6361*67e74705SXin Li ///   unsigned [long] int *offset;  // pointer to ivar offset location
6362*67e74705SXin Li ///   char *name;
6363*67e74705SXin Li ///   char *type;
6364*67e74705SXin Li ///   uint32_t alignment;
6365*67e74705SXin Li ///   uint32_t size;
6366*67e74705SXin Li /// }
6367*67e74705SXin Li /// struct _ivar_list_t {
6368*67e74705SXin Li ///   uint32 entsize;  // sizeof(struct _ivar_t)
6369*67e74705SXin Li ///   uint32 count;
6370*67e74705SXin Li ///   struct _iver_t list[count];
6371*67e74705SXin Li /// }
6372*67e74705SXin Li ///
6373*67e74705SXin Li 
EmitIvarList(const ObjCImplementationDecl * ID)6374*67e74705SXin Li llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6375*67e74705SXin Li   const ObjCImplementationDecl *ID) {
6376*67e74705SXin Li 
6377*67e74705SXin Li   std::vector<llvm::Constant*> Ivars;
6378*67e74705SXin Li 
6379*67e74705SXin Li   const ObjCInterfaceDecl *OID = ID->getClassInterface();
6380*67e74705SXin Li   assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
6381*67e74705SXin Li 
6382*67e74705SXin Li   // FIXME. Consolidate this with similar code in GenerateClass.
6383*67e74705SXin Li 
6384*67e74705SXin Li   for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6385*67e74705SXin Li        IVD; IVD = IVD->getNextIvar()) {
6386*67e74705SXin Li     // Ignore unnamed bit-fields.
6387*67e74705SXin Li     if (!IVD->getDeclName())
6388*67e74705SXin Li       continue;
6389*67e74705SXin Li     llvm::Constant *Ivar[5];
6390*67e74705SXin Li     Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6391*67e74705SXin Li                                 ComputeIvarBaseOffset(CGM, ID, IVD));
6392*67e74705SXin Li     Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6393*67e74705SXin Li     Ivar[2] = GetMethodVarType(IVD);
6394*67e74705SXin Li     llvm::Type *FieldTy =
6395*67e74705SXin Li       CGM.getTypes().ConvertTypeForMem(IVD->getType());
6396*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6397*67e74705SXin Li     unsigned Align = CGM.getContext().getPreferredTypeAlign(
6398*67e74705SXin Li       IVD->getType().getTypePtr()) >> 3;
6399*67e74705SXin Li     Align = llvm::Log2_32(Align);
6400*67e74705SXin Li     Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
6401*67e74705SXin Li     // NOTE. Size of a bitfield does not match gcc's, because of the
6402*67e74705SXin Li     // way bitfields are treated special in each. But I am told that
6403*67e74705SXin Li     // 'size' for bitfield ivars is ignored by the runtime so it does
6404*67e74705SXin Li     // not matter.  If it matters, there is enough info to get the
6405*67e74705SXin Li     // bitfield right!
6406*67e74705SXin Li     Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6407*67e74705SXin Li     Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
6408*67e74705SXin Li   }
6409*67e74705SXin Li   // Return null for empty list.
6410*67e74705SXin Li   if (Ivars.empty())
6411*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6412*67e74705SXin Li 
6413*67e74705SXin Li   llvm::Constant *Values[3];
6414*67e74705SXin Li   unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
6415*67e74705SXin Li   Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6416*67e74705SXin Li   Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
6417*67e74705SXin Li   llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
6418*67e74705SXin Li                                              Ivars.size());
6419*67e74705SXin Li   Values[2] = llvm::ConstantArray::get(AT, Ivars);
6420*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6421*67e74705SXin Li   const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
6422*67e74705SXin Li   llvm::GlobalVariable *GV =
6423*67e74705SXin Li     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6424*67e74705SXin Li                              llvm::GlobalValue::PrivateLinkage,
6425*67e74705SXin Li                              Init,
6426*67e74705SXin Li                              Prefix + OID->getObjCRuntimeNameAsString());
6427*67e74705SXin Li   GV->setAlignment(
6428*67e74705SXin Li     CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6429*67e74705SXin Li   GV->setSection("__DATA, __objc_const");
6430*67e74705SXin Li 
6431*67e74705SXin Li   CGM.addCompilerUsedGlobal(GV);
6432*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6433*67e74705SXin Li }
6434*67e74705SXin Li 
GetOrEmitProtocolRef(const ObjCProtocolDecl * PD)6435*67e74705SXin Li llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6436*67e74705SXin Li   const ObjCProtocolDecl *PD) {
6437*67e74705SXin Li   llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6438*67e74705SXin Li 
6439*67e74705SXin Li   if (!Entry)
6440*67e74705SXin Li     // We use the initializer as a marker of whether this is a forward
6441*67e74705SXin Li     // reference or not. At module finalization we add the empty
6442*67e74705SXin Li     // contents for protocols which were referenced but never defined.
6443*67e74705SXin Li     Entry =
6444*67e74705SXin Li         new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6445*67e74705SXin Li                                  false, llvm::GlobalValue::ExternalLinkage,
6446*67e74705SXin Li                                  nullptr,
6447*67e74705SXin Li                                  "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
6448*67e74705SXin Li 
6449*67e74705SXin Li   return Entry;
6450*67e74705SXin Li }
6451*67e74705SXin Li 
6452*67e74705SXin Li /// GetOrEmitProtocol - Generate the protocol meta-data:
6453*67e74705SXin Li /// @code
6454*67e74705SXin Li /// struct _protocol_t {
6455*67e74705SXin Li ///   id isa;  // NULL
6456*67e74705SXin Li ///   const char * const protocol_name;
6457*67e74705SXin Li ///   const struct _protocol_list_t * protocol_list; // super protocols
6458*67e74705SXin Li ///   const struct method_list_t * const instance_methods;
6459*67e74705SXin Li ///   const struct method_list_t * const class_methods;
6460*67e74705SXin Li ///   const struct method_list_t *optionalInstanceMethods;
6461*67e74705SXin Li ///   const struct method_list_t *optionalClassMethods;
6462*67e74705SXin Li ///   const struct _prop_list_t * properties;
6463*67e74705SXin Li ///   const uint32_t size;  // sizeof(struct _protocol_t)
6464*67e74705SXin Li ///   const uint32_t flags;  // = 0
6465*67e74705SXin Li ///   const char ** extendedMethodTypes;
6466*67e74705SXin Li ///   const char *demangledName;
6467*67e74705SXin Li ///   const struct _prop_list_t * class_properties;
6468*67e74705SXin Li /// }
6469*67e74705SXin Li /// @endcode
6470*67e74705SXin Li ///
6471*67e74705SXin Li 
GetOrEmitProtocol(const ObjCProtocolDecl * PD)6472*67e74705SXin Li llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6473*67e74705SXin Li   const ObjCProtocolDecl *PD) {
6474*67e74705SXin Li   llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
6475*67e74705SXin Li 
6476*67e74705SXin Li   // Early exit if a defining object has already been generated.
6477*67e74705SXin Li   if (Entry && Entry->hasInitializer())
6478*67e74705SXin Li     return Entry;
6479*67e74705SXin Li 
6480*67e74705SXin Li   // Use the protocol definition, if there is one.
6481*67e74705SXin Li   if (const ObjCProtocolDecl *Def = PD->getDefinition())
6482*67e74705SXin Li     PD = Def;
6483*67e74705SXin Li 
6484*67e74705SXin Li   // Construct method lists.
6485*67e74705SXin Li   std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6486*67e74705SXin Li   std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
6487*67e74705SXin Li   std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
6488*67e74705SXin Li   for (const auto *MD : PD->instance_methods()) {
6489*67e74705SXin Li     llvm::Constant *C = GetMethodDescriptionConstant(MD);
6490*67e74705SXin Li     if (!C)
6491*67e74705SXin Li       return GetOrEmitProtocolRef(PD);
6492*67e74705SXin Li 
6493*67e74705SXin Li     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6494*67e74705SXin Li       OptInstanceMethods.push_back(C);
6495*67e74705SXin Li       OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6496*67e74705SXin Li     } else {
6497*67e74705SXin Li       InstanceMethods.push_back(C);
6498*67e74705SXin Li       MethodTypesExt.push_back(GetMethodVarType(MD, true));
6499*67e74705SXin Li     }
6500*67e74705SXin Li   }
6501*67e74705SXin Li 
6502*67e74705SXin Li   for (const auto *MD : PD->class_methods()) {
6503*67e74705SXin Li     llvm::Constant *C = GetMethodDescriptionConstant(MD);
6504*67e74705SXin Li     if (!C)
6505*67e74705SXin Li       return GetOrEmitProtocolRef(PD);
6506*67e74705SXin Li 
6507*67e74705SXin Li     if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6508*67e74705SXin Li       OptClassMethods.push_back(C);
6509*67e74705SXin Li       OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6510*67e74705SXin Li     } else {
6511*67e74705SXin Li       ClassMethods.push_back(C);
6512*67e74705SXin Li       MethodTypesExt.push_back(GetMethodVarType(MD, true));
6513*67e74705SXin Li     }
6514*67e74705SXin Li   }
6515*67e74705SXin Li 
6516*67e74705SXin Li   MethodTypesExt.insert(MethodTypesExt.end(),
6517*67e74705SXin Li                         OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6518*67e74705SXin Li 
6519*67e74705SXin Li   llvm::Constant *Values[13];
6520*67e74705SXin Li   // isa is NULL
6521*67e74705SXin Li   Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
6522*67e74705SXin Li   Values[1] = GetClassName(PD->getObjCRuntimeNameAsString());
6523*67e74705SXin Li   Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getObjCRuntimeNameAsString(),
6524*67e74705SXin Li                                PD->protocol_begin(),
6525*67e74705SXin Li                                PD->protocol_end());
6526*67e74705SXin Li 
6527*67e74705SXin Li   Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
6528*67e74705SXin Li                              + PD->getObjCRuntimeNameAsString(),
6529*67e74705SXin Li                              "__DATA, __objc_const",
6530*67e74705SXin Li                              InstanceMethods);
6531*67e74705SXin Li   Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
6532*67e74705SXin Li                              + PD->getObjCRuntimeNameAsString(),
6533*67e74705SXin Li                              "__DATA, __objc_const",
6534*67e74705SXin Li                              ClassMethods);
6535*67e74705SXin Li   Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
6536*67e74705SXin Li                              + PD->getObjCRuntimeNameAsString(),
6537*67e74705SXin Li                              "__DATA, __objc_const",
6538*67e74705SXin Li                              OptInstanceMethods);
6539*67e74705SXin Li   Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
6540*67e74705SXin Li                              + PD->getObjCRuntimeNameAsString(),
6541*67e74705SXin Li                              "__DATA, __objc_const",
6542*67e74705SXin Li                              OptClassMethods);
6543*67e74705SXin Li   Values[7] = EmitPropertyList(
6544*67e74705SXin Li       "\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6545*67e74705SXin Li       nullptr, PD, ObjCTypes, false);
6546*67e74705SXin Li   uint32_t Size =
6547*67e74705SXin Li     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6548*67e74705SXin Li   Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6549*67e74705SXin Li   Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
6550*67e74705SXin Li   Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6551*67e74705SXin Li                                        + PD->getObjCRuntimeNameAsString(),
6552*67e74705SXin Li                                        MethodTypesExt, ObjCTypes);
6553*67e74705SXin Li   // const char *demangledName;
6554*67e74705SXin Li   Values[11] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6555*67e74705SXin Li 
6556*67e74705SXin Li   Values[12] = EmitPropertyList(
6557*67e74705SXin Li       "\01l_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
6558*67e74705SXin Li       nullptr, PD, ObjCTypes, true);
6559*67e74705SXin Li 
6560*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
6561*67e74705SXin Li                                                    Values);
6562*67e74705SXin Li 
6563*67e74705SXin Li   if (Entry) {
6564*67e74705SXin Li     // Already created, fix the linkage and update the initializer.
6565*67e74705SXin Li     Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6566*67e74705SXin Li     Entry->setInitializer(Init);
6567*67e74705SXin Li   } else {
6568*67e74705SXin Li     Entry =
6569*67e74705SXin Li       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6570*67e74705SXin Li                                false, llvm::GlobalValue::WeakAnyLinkage, Init,
6571*67e74705SXin Li                                "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
6572*67e74705SXin Li     Entry->setAlignment(
6573*67e74705SXin Li       CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
6574*67e74705SXin Li 
6575*67e74705SXin Li     Protocols[PD->getIdentifier()] = Entry;
6576*67e74705SXin Li   }
6577*67e74705SXin Li   Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6578*67e74705SXin Li   CGM.addCompilerUsedGlobal(Entry);
6579*67e74705SXin Li 
6580*67e74705SXin Li   // Use this protocol meta-data to build protocol list table in section
6581*67e74705SXin Li   // __DATA, __objc_protolist
6582*67e74705SXin Li   llvm::GlobalVariable *PTGV =
6583*67e74705SXin Li     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6584*67e74705SXin Li                              false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6585*67e74705SXin Li                              "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
6586*67e74705SXin Li   PTGV->setAlignment(
6587*67e74705SXin Li     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6588*67e74705SXin Li   PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
6589*67e74705SXin Li   PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6590*67e74705SXin Li   CGM.addCompilerUsedGlobal(PTGV);
6591*67e74705SXin Li   return Entry;
6592*67e74705SXin Li }
6593*67e74705SXin Li 
6594*67e74705SXin Li /// EmitProtocolList - Generate protocol list meta-data:
6595*67e74705SXin Li /// @code
6596*67e74705SXin Li /// struct _protocol_list_t {
6597*67e74705SXin Li ///   long protocol_count;   // Note, this is 32/64 bit
6598*67e74705SXin Li ///   struct _protocol_t[protocol_count];
6599*67e74705SXin Li /// }
6600*67e74705SXin Li /// @endcode
6601*67e74705SXin Li ///
6602*67e74705SXin Li llvm::Constant *
EmitProtocolList(Twine Name,ObjCProtocolDecl::protocol_iterator begin,ObjCProtocolDecl::protocol_iterator end)6603*67e74705SXin Li CGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6604*67e74705SXin Li                                       ObjCProtocolDecl::protocol_iterator begin,
6605*67e74705SXin Li                                       ObjCProtocolDecl::protocol_iterator end) {
6606*67e74705SXin Li   SmallVector<llvm::Constant *, 16> ProtocolRefs;
6607*67e74705SXin Li 
6608*67e74705SXin Li   // Just return null for empty protocol lists
6609*67e74705SXin Li   if (begin == end)
6610*67e74705SXin Li     return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6611*67e74705SXin Li 
6612*67e74705SXin Li   // FIXME: We shouldn't need to do this lookup here, should we?
6613*67e74705SXin Li   SmallString<256> TmpName;
6614*67e74705SXin Li   Name.toVector(TmpName);
6615*67e74705SXin Li   llvm::GlobalVariable *GV =
6616*67e74705SXin Li     CGM.getModule().getGlobalVariable(TmpName.str(), true);
6617*67e74705SXin Li   if (GV)
6618*67e74705SXin Li     return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6619*67e74705SXin Li 
6620*67e74705SXin Li   for (; begin != end; ++begin)
6621*67e74705SXin Li     ProtocolRefs.push_back(GetProtocolRef(*begin));  // Implemented???
6622*67e74705SXin Li 
6623*67e74705SXin Li   // This list is null terminated.
6624*67e74705SXin Li   ProtocolRefs.push_back(llvm::Constant::getNullValue(
6625*67e74705SXin Li                            ObjCTypes.ProtocolnfABIPtrTy));
6626*67e74705SXin Li 
6627*67e74705SXin Li   llvm::Constant *Values[2];
6628*67e74705SXin Li   Values[0] =
6629*67e74705SXin Li     llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
6630*67e74705SXin Li   Values[1] =
6631*67e74705SXin Li     llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6632*67e74705SXin Li                                                   ProtocolRefs.size()),
6633*67e74705SXin Li                              ProtocolRefs);
6634*67e74705SXin Li 
6635*67e74705SXin Li   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6636*67e74705SXin Li   GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6637*67e74705SXin Li                                 llvm::GlobalValue::PrivateLinkage,
6638*67e74705SXin Li                                 Init, Name);
6639*67e74705SXin Li   GV->setSection("__DATA, __objc_const");
6640*67e74705SXin Li   GV->setAlignment(
6641*67e74705SXin Li     CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6642*67e74705SXin Li   CGM.addCompilerUsedGlobal(GV);
6643*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(GV,
6644*67e74705SXin Li                                         ObjCTypes.ProtocolListnfABIPtrTy);
6645*67e74705SXin Li }
6646*67e74705SXin Li 
6647*67e74705SXin Li /// GetMethodDescriptionConstant - This routine build following meta-data:
6648*67e74705SXin Li /// struct _objc_method {
6649*67e74705SXin Li ///   SEL _cmd;
6650*67e74705SXin Li ///   char *method_type;
6651*67e74705SXin Li ///   char *_imp;
6652*67e74705SXin Li /// }
6653*67e74705SXin Li 
6654*67e74705SXin Li llvm::Constant *
GetMethodDescriptionConstant(const ObjCMethodDecl * MD)6655*67e74705SXin Li CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
6656*67e74705SXin Li   llvm::Constant *Desc[3];
6657*67e74705SXin Li   Desc[0] =
6658*67e74705SXin Li     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6659*67e74705SXin Li                                    ObjCTypes.SelectorPtrTy);
6660*67e74705SXin Li   Desc[1] = GetMethodVarType(MD);
6661*67e74705SXin Li   if (!Desc[1])
6662*67e74705SXin Li     return nullptr;
6663*67e74705SXin Li 
6664*67e74705SXin Li   // Protocol methods have no implementation. So, this entry is always NULL.
6665*67e74705SXin Li   Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6666*67e74705SXin Li   return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
6667*67e74705SXin Li }
6668*67e74705SXin Li 
6669*67e74705SXin Li /// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
6670*67e74705SXin Li /// This code gen. amounts to generating code for:
6671*67e74705SXin Li /// @code
6672*67e74705SXin Li /// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
6673*67e74705SXin Li /// @encode
6674*67e74705SXin Li ///
EmitObjCValueForIvar(CodeGen::CodeGenFunction & CGF,QualType ObjectTy,llvm::Value * BaseValue,const ObjCIvarDecl * Ivar,unsigned CVRQualifiers)6675*67e74705SXin Li LValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6676*67e74705SXin Li                                                CodeGen::CodeGenFunction &CGF,
6677*67e74705SXin Li                                                QualType ObjectTy,
6678*67e74705SXin Li                                                llvm::Value *BaseValue,
6679*67e74705SXin Li                                                const ObjCIvarDecl *Ivar,
6680*67e74705SXin Li                                                unsigned CVRQualifiers) {
6681*67e74705SXin Li   ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
6682*67e74705SXin Li   llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6683*67e74705SXin Li   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6684*67e74705SXin Li                                   Offset);
6685*67e74705SXin Li }
6686*67e74705SXin Li 
EmitIvarOffset(CodeGen::CodeGenFunction & CGF,const ObjCInterfaceDecl * Interface,const ObjCIvarDecl * Ivar)6687*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6688*67e74705SXin Li   CodeGen::CodeGenFunction &CGF,
6689*67e74705SXin Li   const ObjCInterfaceDecl *Interface,
6690*67e74705SXin Li   const ObjCIvarDecl *Ivar) {
6691*67e74705SXin Li   llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
6692*67e74705SXin Li   IvarOffsetValue = CGF.Builder.CreateAlignedLoad(IvarOffsetValue,
6693*67e74705SXin Li                                                   CGF.getSizeAlign(), "ivar");
6694*67e74705SXin Li   if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
6695*67e74705SXin Li     cast<llvm::LoadInst>(IvarOffsetValue)
6696*67e74705SXin Li         ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6697*67e74705SXin Li                       llvm::MDNode::get(VMContext, None));
6698*67e74705SXin Li 
6699*67e74705SXin Li   // This could be 32bit int or 64bit integer depending on the architecture.
6700*67e74705SXin Li   // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
6701*67e74705SXin Li   //  as this is what caller always expectes.
6702*67e74705SXin Li   if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
6703*67e74705SXin Li     IvarOffsetValue = CGF.Builder.CreateIntCast(
6704*67e74705SXin Li         IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");
6705*67e74705SXin Li   return IvarOffsetValue;
6706*67e74705SXin Li }
6707*67e74705SXin Li 
appendSelectorForMessageRefTable(std::string & buffer,Selector selector)6708*67e74705SXin Li static void appendSelectorForMessageRefTable(std::string &buffer,
6709*67e74705SXin Li                                              Selector selector) {
6710*67e74705SXin Li   if (selector.isUnarySelector()) {
6711*67e74705SXin Li     buffer += selector.getNameForSlot(0);
6712*67e74705SXin Li     return;
6713*67e74705SXin Li   }
6714*67e74705SXin Li 
6715*67e74705SXin Li   for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
6716*67e74705SXin Li     buffer += selector.getNameForSlot(i);
6717*67e74705SXin Li     buffer += '_';
6718*67e74705SXin Li   }
6719*67e74705SXin Li }
6720*67e74705SXin Li 
6721*67e74705SXin Li /// Emit a "vtable" message send.  We emit a weak hidden-visibility
6722*67e74705SXin Li /// struct, initially containing the selector pointer and a pointer to
6723*67e74705SXin Li /// a "fixup" variant of the appropriate objc_msgSend.  To call, we
6724*67e74705SXin Li /// load and call the function pointer, passing the address of the
6725*67e74705SXin Li /// struct as the second parameter.  The runtime determines whether
6726*67e74705SXin Li /// the selector is currently emitted using vtable dispatch; if so, it
6727*67e74705SXin Li /// substitutes a stub function which simply tail-calls through the
6728*67e74705SXin Li /// appropriate vtable slot, and if not, it substitues a stub function
6729*67e74705SXin Li /// which tail-calls objc_msgSend.  Both stubs adjust the selector
6730*67e74705SXin Li /// argument to correctly point to the selector.
6731*67e74705SXin Li RValue
EmitVTableMessageSend(CodeGenFunction & CGF,ReturnValueSlot returnSlot,QualType resultType,Selector selector,llvm::Value * arg0,QualType arg0Type,bool isSuper,const CallArgList & formalArgs,const ObjCMethodDecl * method)6732*67e74705SXin Li CGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
6733*67e74705SXin Li                                               ReturnValueSlot returnSlot,
6734*67e74705SXin Li                                               QualType resultType,
6735*67e74705SXin Li                                               Selector selector,
6736*67e74705SXin Li                                               llvm::Value *arg0,
6737*67e74705SXin Li                                               QualType arg0Type,
6738*67e74705SXin Li                                               bool isSuper,
6739*67e74705SXin Li                                               const CallArgList &formalArgs,
6740*67e74705SXin Li                                               const ObjCMethodDecl *method) {
6741*67e74705SXin Li   // Compute the actual arguments.
6742*67e74705SXin Li   CallArgList args;
6743*67e74705SXin Li 
6744*67e74705SXin Li   // First argument: the receiver / super-call structure.
6745*67e74705SXin Li   if (!isSuper)
6746*67e74705SXin Li     arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
6747*67e74705SXin Li   args.add(RValue::get(arg0), arg0Type);
6748*67e74705SXin Li 
6749*67e74705SXin Li   // Second argument: a pointer to the message ref structure.  Leave
6750*67e74705SXin Li   // the actual argument value blank for now.
6751*67e74705SXin Li   args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
6752*67e74705SXin Li 
6753*67e74705SXin Li   args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6754*67e74705SXin Li 
6755*67e74705SXin Li   MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6756*67e74705SXin Li 
6757*67e74705SXin Li   NullReturnState nullReturn;
6758*67e74705SXin Li 
6759*67e74705SXin Li   // Find the function to call and the mangled name for the message
6760*67e74705SXin Li   // ref structure.  Using a different mangled name wouldn't actually
6761*67e74705SXin Li   // be a problem; it would just be a waste.
6762*67e74705SXin Li   //
6763*67e74705SXin Li   // The runtime currently never uses vtable dispatch for anything
6764*67e74705SXin Li   // except normal, non-super message-sends.
6765*67e74705SXin Li   // FIXME: don't use this for that.
6766*67e74705SXin Li   llvm::Constant *fn = nullptr;
6767*67e74705SXin Li   std::string messageRefName("\01l_");
6768*67e74705SXin Li   if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
6769*67e74705SXin Li     if (isSuper) {
6770*67e74705SXin Li       fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6771*67e74705SXin Li       messageRefName += "objc_msgSendSuper2_stret_fixup";
6772*67e74705SXin Li     } else {
6773*67e74705SXin Li       nullReturn.init(CGF, arg0);
6774*67e74705SXin Li       fn = ObjCTypes.getMessageSendStretFixupFn();
6775*67e74705SXin Li       messageRefName += "objc_msgSend_stret_fixup";
6776*67e74705SXin Li     }
6777*67e74705SXin Li   } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
6778*67e74705SXin Li     fn = ObjCTypes.getMessageSendFpretFixupFn();
6779*67e74705SXin Li     messageRefName += "objc_msgSend_fpret_fixup";
6780*67e74705SXin Li   } else {
6781*67e74705SXin Li     if (isSuper) {
6782*67e74705SXin Li       fn = ObjCTypes.getMessageSendSuper2FixupFn();
6783*67e74705SXin Li       messageRefName += "objc_msgSendSuper2_fixup";
6784*67e74705SXin Li     } else {
6785*67e74705SXin Li       fn = ObjCTypes.getMessageSendFixupFn();
6786*67e74705SXin Li       messageRefName += "objc_msgSend_fixup";
6787*67e74705SXin Li     }
6788*67e74705SXin Li   }
6789*67e74705SXin Li   assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
6790*67e74705SXin Li   messageRefName += '_';
6791*67e74705SXin Li 
6792*67e74705SXin Li   // Append the selector name, except use underscores anywhere we
6793*67e74705SXin Li   // would have used colons.
6794*67e74705SXin Li   appendSelectorForMessageRefTable(messageRefName, selector);
6795*67e74705SXin Li 
6796*67e74705SXin Li   llvm::GlobalVariable *messageRef
6797*67e74705SXin Li     = CGM.getModule().getGlobalVariable(messageRefName);
6798*67e74705SXin Li   if (!messageRef) {
6799*67e74705SXin Li     // Build the message ref structure.
6800*67e74705SXin Li     llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
6801*67e74705SXin Li     llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
6802*67e74705SXin Li     messageRef = new llvm::GlobalVariable(CGM.getModule(),
6803*67e74705SXin Li                                           init->getType(),
6804*67e74705SXin Li                                           /*constant*/ false,
6805*67e74705SXin Li                                           llvm::GlobalValue::WeakAnyLinkage,
6806*67e74705SXin Li                                           init,
6807*67e74705SXin Li                                           messageRefName);
6808*67e74705SXin Li     messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
6809*67e74705SXin Li     messageRef->setAlignment(16);
6810*67e74705SXin Li     messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
6811*67e74705SXin Li   }
6812*67e74705SXin Li 
6813*67e74705SXin Li   bool requiresnullCheck = false;
6814*67e74705SXin Li   if (CGM.getLangOpts().ObjCAutoRefCount && method)
6815*67e74705SXin Li     for (const auto *ParamDecl : method->parameters()) {
6816*67e74705SXin Li       if (ParamDecl->hasAttr<NSConsumedAttr>()) {
6817*67e74705SXin Li         if (!nullReturn.NullBB)
6818*67e74705SXin Li           nullReturn.init(CGF, arg0);
6819*67e74705SXin Li         requiresnullCheck = true;
6820*67e74705SXin Li         break;
6821*67e74705SXin Li       }
6822*67e74705SXin Li     }
6823*67e74705SXin Li 
6824*67e74705SXin Li   Address mref =
6825*67e74705SXin Li     Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
6826*67e74705SXin Li             CGF.getPointerAlign());
6827*67e74705SXin Li 
6828*67e74705SXin Li   // Update the message ref argument.
6829*67e74705SXin Li   args[1].RV = RValue::get(mref.getPointer());
6830*67e74705SXin Li 
6831*67e74705SXin Li   // Load the function to call from the message ref table.
6832*67e74705SXin Li   Address calleeAddr =
6833*67e74705SXin Li       CGF.Builder.CreateStructGEP(mref, 0, CharUnits::Zero());
6834*67e74705SXin Li   llvm::Value *callee = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");
6835*67e74705SXin Li 
6836*67e74705SXin Li   callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
6837*67e74705SXin Li 
6838*67e74705SXin Li   RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
6839*67e74705SXin Li   return nullReturn.complete(CGF, result, resultType, formalArgs,
6840*67e74705SXin Li                              requiresnullCheck ? method : nullptr);
6841*67e74705SXin Li }
6842*67e74705SXin Li 
6843*67e74705SXin Li /// Generate code for a message send expression in the nonfragile abi.
6844*67e74705SXin Li CodeGen::RValue
GenerateMessageSend(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,llvm::Value * Receiver,const CallArgList & CallArgs,const ObjCInterfaceDecl * Class,const ObjCMethodDecl * Method)6845*67e74705SXin Li CGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
6846*67e74705SXin Li                                             ReturnValueSlot Return,
6847*67e74705SXin Li                                             QualType ResultType,
6848*67e74705SXin Li                                             Selector Sel,
6849*67e74705SXin Li                                             llvm::Value *Receiver,
6850*67e74705SXin Li                                             const CallArgList &CallArgs,
6851*67e74705SXin Li                                             const ObjCInterfaceDecl *Class,
6852*67e74705SXin Li                                             const ObjCMethodDecl *Method) {
6853*67e74705SXin Li   return isVTableDispatchedSelector(Sel)
6854*67e74705SXin Li     ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6855*67e74705SXin Li                             Receiver, CGF.getContext().getObjCIdType(),
6856*67e74705SXin Li                             false, CallArgs, Method)
6857*67e74705SXin Li     : EmitMessageSend(CGF, Return, ResultType,
6858*67e74705SXin Li                       EmitSelector(CGF, Sel),
6859*67e74705SXin Li                       Receiver, CGF.getContext().getObjCIdType(),
6860*67e74705SXin Li                       false, CallArgs, Method, Class, ObjCTypes);
6861*67e74705SXin Li }
6862*67e74705SXin Li 
6863*67e74705SXin Li llvm::GlobalVariable *
GetClassGlobal(StringRef Name,bool Weak)6864*67e74705SXin Li CGObjCNonFragileABIMac::GetClassGlobal(StringRef Name, bool Weak) {
6865*67e74705SXin Li   llvm::GlobalValue::LinkageTypes L =
6866*67e74705SXin Li       Weak ? llvm::GlobalValue::ExternalWeakLinkage
6867*67e74705SXin Li            : llvm::GlobalValue::ExternalLinkage;
6868*67e74705SXin Li 
6869*67e74705SXin Li   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
6870*67e74705SXin Li 
6871*67e74705SXin Li   if (!GV)
6872*67e74705SXin Li     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
6873*67e74705SXin Li                                   false, L, nullptr, Name);
6874*67e74705SXin Li 
6875*67e74705SXin Li   assert(GV->getLinkage() == L);
6876*67e74705SXin Li   return GV;
6877*67e74705SXin Li }
6878*67e74705SXin Li 
EmitClassRefFromId(CodeGenFunction & CGF,IdentifierInfo * II,bool Weak,const ObjCInterfaceDecl * ID)6879*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
6880*67e74705SXin Li                                                         IdentifierInfo *II,
6881*67e74705SXin Li                                                         bool Weak,
6882*67e74705SXin Li                                                         const ObjCInterfaceDecl *ID) {
6883*67e74705SXin Li   CharUnits Align = CGF.getPointerAlign();
6884*67e74705SXin Li   llvm::GlobalVariable *&Entry = ClassReferences[II];
6885*67e74705SXin Li 
6886*67e74705SXin Li   if (!Entry) {
6887*67e74705SXin Li     StringRef Name = ID ? ID->getObjCRuntimeNameAsString() : II->getName();
6888*67e74705SXin Li     std::string ClassName = (getClassSymbolPrefix() + Name).str();
6889*67e74705SXin Li     llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
6890*67e74705SXin Li     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6891*67e74705SXin Li                                      false, llvm::GlobalValue::PrivateLinkage,
6892*67e74705SXin Li                                      ClassGV, "OBJC_CLASSLIST_REFERENCES_$_");
6893*67e74705SXin Li     Entry->setAlignment(Align.getQuantity());
6894*67e74705SXin Li     Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
6895*67e74705SXin Li     CGM.addCompilerUsedGlobal(Entry);
6896*67e74705SXin Li   }
6897*67e74705SXin Li   return CGF.Builder.CreateAlignedLoad(Entry, Align);
6898*67e74705SXin Li }
6899*67e74705SXin Li 
EmitClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)6900*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
6901*67e74705SXin Li                                                   const ObjCInterfaceDecl *ID) {
6902*67e74705SXin Li   // If the class has the objc_runtime_visible attribute, we need to
6903*67e74705SXin Li   // use the Objective-C runtime to get the class.
6904*67e74705SXin Li   if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
6905*67e74705SXin Li     return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
6906*67e74705SXin Li 
6907*67e74705SXin Li   return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID);
6908*67e74705SXin Li }
6909*67e74705SXin Li 
EmitNSAutoreleasePoolClassRef(CodeGenFunction & CGF)6910*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
6911*67e74705SXin Li                                                     CodeGenFunction &CGF) {
6912*67e74705SXin Li   IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
6913*67e74705SXin Li   return EmitClassRefFromId(CGF, II, false, nullptr);
6914*67e74705SXin Li }
6915*67e74705SXin Li 
6916*67e74705SXin Li llvm::Value *
EmitSuperClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)6917*67e74705SXin Li CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
6918*67e74705SXin Li                                           const ObjCInterfaceDecl *ID) {
6919*67e74705SXin Li   CharUnits Align = CGF.getPointerAlign();
6920*67e74705SXin Li   llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
6921*67e74705SXin Li 
6922*67e74705SXin Li   if (!Entry) {
6923*67e74705SXin Li     llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6924*67e74705SXin Li     ClassName += ID->getObjCRuntimeNameAsString();
6925*67e74705SXin Li     llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
6926*67e74705SXin Li                                                    ID->isWeakImported());
6927*67e74705SXin Li     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6928*67e74705SXin Li                                      false, llvm::GlobalValue::PrivateLinkage,
6929*67e74705SXin Li                                      ClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
6930*67e74705SXin Li     Entry->setAlignment(Align.getQuantity());
6931*67e74705SXin Li     Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6932*67e74705SXin Li     CGM.addCompilerUsedGlobal(Entry);
6933*67e74705SXin Li   }
6934*67e74705SXin Li   return CGF.Builder.CreateAlignedLoad(Entry, Align);
6935*67e74705SXin Li }
6936*67e74705SXin Li 
6937*67e74705SXin Li /// EmitMetaClassRef - Return a Value * of the address of _class_t
6938*67e74705SXin Li /// meta-data
6939*67e74705SXin Li ///
EmitMetaClassRef(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID,bool Weak)6940*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
6941*67e74705SXin Li                                                       const ObjCInterfaceDecl *ID,
6942*67e74705SXin Li                                                       bool Weak) {
6943*67e74705SXin Li   CharUnits Align = CGF.getPointerAlign();
6944*67e74705SXin Li   llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
6945*67e74705SXin Li   if (!Entry) {
6946*67e74705SXin Li     llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix());
6947*67e74705SXin Li     MetaClassName += ID->getObjCRuntimeNameAsString();
6948*67e74705SXin Li     llvm::GlobalVariable *MetaClassGV =
6949*67e74705SXin Li       GetClassGlobal(MetaClassName.str(), Weak);
6950*67e74705SXin Li 
6951*67e74705SXin Li     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6952*67e74705SXin Li                                      false, llvm::GlobalValue::PrivateLinkage,
6953*67e74705SXin Li                                      MetaClassGV, "OBJC_CLASSLIST_SUP_REFS_$_");
6954*67e74705SXin Li     Entry->setAlignment(Align.getQuantity());
6955*67e74705SXin Li 
6956*67e74705SXin Li     Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6957*67e74705SXin Li     CGM.addCompilerUsedGlobal(Entry);
6958*67e74705SXin Li   }
6959*67e74705SXin Li 
6960*67e74705SXin Li   return CGF.Builder.CreateAlignedLoad(Entry, Align);
6961*67e74705SXin Li }
6962*67e74705SXin Li 
6963*67e74705SXin Li /// GetClass - Return a reference to the class for the given interface
6964*67e74705SXin Li /// decl.
GetClass(CodeGenFunction & CGF,const ObjCInterfaceDecl * ID)6965*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
6966*67e74705SXin Li                                               const ObjCInterfaceDecl *ID) {
6967*67e74705SXin Li   if (ID->isWeakImported()) {
6968*67e74705SXin Li     llvm::SmallString<64> ClassName(getClassSymbolPrefix());
6969*67e74705SXin Li     ClassName += ID->getObjCRuntimeNameAsString();
6970*67e74705SXin Li     llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true);
6971*67e74705SXin Li     (void)ClassGV;
6972*67e74705SXin Li     assert(ClassGV->hasExternalWeakLinkage());
6973*67e74705SXin Li   }
6974*67e74705SXin Li 
6975*67e74705SXin Li   return EmitClassRef(CGF, ID);
6976*67e74705SXin Li }
6977*67e74705SXin Li 
6978*67e74705SXin Li /// Generates a message send where the super is the receiver.  This is
6979*67e74705SXin Li /// a message send to self with special delivery semantics indicating
6980*67e74705SXin Li /// which class's method should be called.
6981*67e74705SXin Li CodeGen::RValue
GenerateMessageSendSuper(CodeGen::CodeGenFunction & CGF,ReturnValueSlot Return,QualType ResultType,Selector Sel,const ObjCInterfaceDecl * Class,bool isCategoryImpl,llvm::Value * Receiver,bool IsClassMessage,const CodeGen::CallArgList & CallArgs,const ObjCMethodDecl * Method)6982*67e74705SXin Li CGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
6983*67e74705SXin Li                                                  ReturnValueSlot Return,
6984*67e74705SXin Li                                                  QualType ResultType,
6985*67e74705SXin Li                                                  Selector Sel,
6986*67e74705SXin Li                                                  const ObjCInterfaceDecl *Class,
6987*67e74705SXin Li                                                  bool isCategoryImpl,
6988*67e74705SXin Li                                                  llvm::Value *Receiver,
6989*67e74705SXin Li                                                  bool IsClassMessage,
6990*67e74705SXin Li                                                  const CodeGen::CallArgList &CallArgs,
6991*67e74705SXin Li                                                  const ObjCMethodDecl *Method) {
6992*67e74705SXin Li   // ...
6993*67e74705SXin Li   // Create and init a super structure; this is a (receiver, class)
6994*67e74705SXin Li   // pair we will pass to objc_msgSendSuper.
6995*67e74705SXin Li   Address ObjCSuper =
6996*67e74705SXin Li     CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(),
6997*67e74705SXin Li                          "objc_super");
6998*67e74705SXin Li 
6999*67e74705SXin Li   llvm::Value *ReceiverAsObject =
7000*67e74705SXin Li     CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
7001*67e74705SXin Li   CGF.Builder.CreateStore(
7002*67e74705SXin Li       ReceiverAsObject,
7003*67e74705SXin Li       CGF.Builder.CreateStructGEP(ObjCSuper, 0, CharUnits::Zero()));
7004*67e74705SXin Li 
7005*67e74705SXin Li   // If this is a class message the metaclass is passed as the target.
7006*67e74705SXin Li   llvm::Value *Target;
7007*67e74705SXin Li   if (IsClassMessage)
7008*67e74705SXin Li       Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
7009*67e74705SXin Li   else
7010*67e74705SXin Li     Target = EmitSuperClassRef(CGF, Class);
7011*67e74705SXin Li 
7012*67e74705SXin Li   // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
7013*67e74705SXin Li   // ObjCTypes types.
7014*67e74705SXin Li   llvm::Type *ClassTy =
7015*67e74705SXin Li     CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
7016*67e74705SXin Li   Target = CGF.Builder.CreateBitCast(Target, ClassTy);
7017*67e74705SXin Li   CGF.Builder.CreateStore(
7018*67e74705SXin Li       Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1, CGF.getPointerSize()));
7019*67e74705SXin Li 
7020*67e74705SXin Li   return (isVTableDispatchedSelector(Sel))
7021*67e74705SXin Li     ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7022*67e74705SXin Li                             ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7023*67e74705SXin Li                             true, CallArgs, Method)
7024*67e74705SXin Li     : EmitMessageSend(CGF, Return, ResultType,
7025*67e74705SXin Li                       EmitSelector(CGF, Sel),
7026*67e74705SXin Li                       ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7027*67e74705SXin Li                       true, CallArgs, Method, Class, ObjCTypes);
7028*67e74705SXin Li }
7029*67e74705SXin Li 
EmitSelector(CodeGenFunction & CGF,Selector Sel)7030*67e74705SXin Li llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
7031*67e74705SXin Li                                                   Selector Sel) {
7032*67e74705SXin Li   Address Addr = EmitSelectorAddr(CGF, Sel);
7033*67e74705SXin Li 
7034*67e74705SXin Li   llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr);
7035*67e74705SXin Li   LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
7036*67e74705SXin Li                   llvm::MDNode::get(VMContext, None));
7037*67e74705SXin Li   return LI;
7038*67e74705SXin Li }
7039*67e74705SXin Li 
EmitSelectorAddr(CodeGenFunction & CGF,Selector Sel)7040*67e74705SXin Li Address CGObjCNonFragileABIMac::EmitSelectorAddr(CodeGenFunction &CGF,
7041*67e74705SXin Li                                                  Selector Sel) {
7042*67e74705SXin Li   llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7043*67e74705SXin Li 
7044*67e74705SXin Li   CharUnits Align = CGF.getPointerAlign();
7045*67e74705SXin Li   if (!Entry) {
7046*67e74705SXin Li     llvm::Constant *Casted =
7047*67e74705SXin Li       llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7048*67e74705SXin Li                                      ObjCTypes.SelectorPtrTy);
7049*67e74705SXin Li     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy,
7050*67e74705SXin Li                                      false, llvm::GlobalValue::PrivateLinkage,
7051*67e74705SXin Li                                      Casted, "OBJC_SELECTOR_REFERENCES_");
7052*67e74705SXin Li     Entry->setExternallyInitialized(true);
7053*67e74705SXin Li     Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
7054*67e74705SXin Li     Entry->setAlignment(Align.getQuantity());
7055*67e74705SXin Li     CGM.addCompilerUsedGlobal(Entry);
7056*67e74705SXin Li   }
7057*67e74705SXin Li 
7058*67e74705SXin Li   return Address(Entry, Align);
7059*67e74705SXin Li }
7060*67e74705SXin Li 
7061*67e74705SXin Li /// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
7062*67e74705SXin Li /// objc_assign_ivar (id src, id *dst, ptrdiff_t)
7063*67e74705SXin Li ///
EmitObjCIvarAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst,llvm::Value * ivarOffset)7064*67e74705SXin Li void CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
7065*67e74705SXin Li                                                 llvm::Value *src,
7066*67e74705SXin Li                                                 Address dst,
7067*67e74705SXin Li                                                 llvm::Value *ivarOffset) {
7068*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
7069*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
7070*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7071*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
7072*67e74705SXin Li     src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7073*67e74705SXin Li            : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7074*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7075*67e74705SXin Li   }
7076*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7077*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7078*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
7079*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7080*67e74705SXin Li }
7081*67e74705SXin Li 
7082*67e74705SXin Li /// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
7083*67e74705SXin Li /// objc_assign_strongCast (id src, id *dst)
7084*67e74705SXin Li ///
EmitObjCStrongCastAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst)7085*67e74705SXin Li void CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7086*67e74705SXin Li   CodeGen::CodeGenFunction &CGF,
7087*67e74705SXin Li   llvm::Value *src, Address dst) {
7088*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
7089*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
7090*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7091*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
7092*67e74705SXin Li     src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7093*67e74705SXin Li            : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7094*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7095*67e74705SXin Li   }
7096*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7097*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7098*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer() };
7099*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7100*67e74705SXin Li                               args, "weakassign");
7101*67e74705SXin Li }
7102*67e74705SXin Li 
EmitGCMemmoveCollectable(CodeGen::CodeGenFunction & CGF,Address DestPtr,Address SrcPtr,llvm::Value * Size)7103*67e74705SXin Li void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7104*67e74705SXin Li   CodeGen::CodeGenFunction &CGF,
7105*67e74705SXin Li   Address DestPtr,
7106*67e74705SXin Li   Address SrcPtr,
7107*67e74705SXin Li   llvm::Value *Size) {
7108*67e74705SXin Li   SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
7109*67e74705SXin Li   DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
7110*67e74705SXin Li   llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size };
7111*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7112*67e74705SXin Li }
7113*67e74705SXin Li 
7114*67e74705SXin Li /// EmitObjCWeakRead - Code gen for loading value of a __weak
7115*67e74705SXin Li /// object: objc_read_weak (id *src)
7116*67e74705SXin Li ///
EmitObjCWeakRead(CodeGen::CodeGenFunction & CGF,Address AddrWeakObj)7117*67e74705SXin Li llvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7118*67e74705SXin Li   CodeGen::CodeGenFunction &CGF,
7119*67e74705SXin Li   Address AddrWeakObj) {
7120*67e74705SXin Li   llvm::Type *DestTy = AddrWeakObj.getElementType();
7121*67e74705SXin Li   AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7122*67e74705SXin Li   llvm::Value *read_weak =
7123*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7124*67e74705SXin Li                                 AddrWeakObj.getPointer(), "weakread");
7125*67e74705SXin Li   read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7126*67e74705SXin Li   return read_weak;
7127*67e74705SXin Li }
7128*67e74705SXin Li 
7129*67e74705SXin Li /// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
7130*67e74705SXin Li /// objc_assign_weak (id src, id *dst)
7131*67e74705SXin Li ///
EmitObjCWeakAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst)7132*67e74705SXin Li void CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7133*67e74705SXin Li                                                 llvm::Value *src, Address dst) {
7134*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
7135*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
7136*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7137*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
7138*67e74705SXin Li     src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7139*67e74705SXin Li            : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7140*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7141*67e74705SXin Li   }
7142*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7143*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7144*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer() };
7145*67e74705SXin Li   CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7146*67e74705SXin Li                               args, "weakassign");
7147*67e74705SXin Li }
7148*67e74705SXin Li 
7149*67e74705SXin Li /// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
7150*67e74705SXin Li /// objc_assign_global (id src, id *dst)
7151*67e74705SXin Li ///
EmitObjCGlobalAssign(CodeGen::CodeGenFunction & CGF,llvm::Value * src,Address dst,bool threadlocal)7152*67e74705SXin Li void CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7153*67e74705SXin Li                                           llvm::Value *src, Address dst,
7154*67e74705SXin Li                                           bool threadlocal) {
7155*67e74705SXin Li   llvm::Type * SrcTy = src->getType();
7156*67e74705SXin Li   if (!isa<llvm::PointerType>(SrcTy)) {
7157*67e74705SXin Li     unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7158*67e74705SXin Li     assert(Size <= 8 && "does not support size > 8");
7159*67e74705SXin Li     src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7160*67e74705SXin Li            : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7161*67e74705SXin Li     src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7162*67e74705SXin Li   }
7163*67e74705SXin Li   src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7164*67e74705SXin Li   dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7165*67e74705SXin Li   llvm::Value *args[] = { src, dst.getPointer() };
7166*67e74705SXin Li   if (!threadlocal)
7167*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7168*67e74705SXin Li                                 args, "globalassign");
7169*67e74705SXin Li   else
7170*67e74705SXin Li     CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7171*67e74705SXin Li                                 args, "threadlocalassign");
7172*67e74705SXin Li }
7173*67e74705SXin Li 
7174*67e74705SXin Li void
EmitSynchronizedStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtSynchronizedStmt & S)7175*67e74705SXin Li CGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7176*67e74705SXin Li                                              const ObjCAtSynchronizedStmt &S) {
7177*67e74705SXin Li   EmitAtSynchronizedStmt(CGF, S,
7178*67e74705SXin Li       cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
7179*67e74705SXin Li       cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
7180*67e74705SXin Li }
7181*67e74705SXin Li 
7182*67e74705SXin Li llvm::Constant *
GetEHType(QualType T)7183*67e74705SXin Li CGObjCNonFragileABIMac::GetEHType(QualType T) {
7184*67e74705SXin Li   // There's a particular fixed type info for 'id'.
7185*67e74705SXin Li   if (T->isObjCIdType() ||
7186*67e74705SXin Li       T->isObjCQualifiedIdType()) {
7187*67e74705SXin Li     llvm::Constant *IDEHType =
7188*67e74705SXin Li       CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
7189*67e74705SXin Li     if (!IDEHType)
7190*67e74705SXin Li       IDEHType =
7191*67e74705SXin Li         new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7192*67e74705SXin Li                                  false,
7193*67e74705SXin Li                                  llvm::GlobalValue::ExternalLinkage,
7194*67e74705SXin Li                                  nullptr, "OBJC_EHTYPE_id");
7195*67e74705SXin Li     return IDEHType;
7196*67e74705SXin Li   }
7197*67e74705SXin Li 
7198*67e74705SXin Li   // All other types should be Objective-C interface pointer types.
7199*67e74705SXin Li   const ObjCObjectPointerType *PT =
7200*67e74705SXin Li     T->getAs<ObjCObjectPointerType>();
7201*67e74705SXin Li   assert(PT && "Invalid @catch type.");
7202*67e74705SXin Li   const ObjCInterfaceType *IT = PT->getInterfaceType();
7203*67e74705SXin Li   assert(IT && "Invalid @catch type.");
7204*67e74705SXin Li   return GetInterfaceEHType(IT->getDecl(), false);
7205*67e74705SXin Li }
7206*67e74705SXin Li 
EmitTryStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtTryStmt & S)7207*67e74705SXin Li void CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7208*67e74705SXin Li                                          const ObjCAtTryStmt &S) {
7209*67e74705SXin Li   EmitTryCatchStmt(CGF, S,
7210*67e74705SXin Li       cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
7211*67e74705SXin Li       cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
7212*67e74705SXin Li       cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
7213*67e74705SXin Li }
7214*67e74705SXin Li 
7215*67e74705SXin Li /// EmitThrowStmt - Generate code for a throw statement.
EmitThrowStmt(CodeGen::CodeGenFunction & CGF,const ObjCAtThrowStmt & S,bool ClearInsertionPoint)7216*67e74705SXin Li void CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7217*67e74705SXin Li                                            const ObjCAtThrowStmt &S,
7218*67e74705SXin Li                                            bool ClearInsertionPoint) {
7219*67e74705SXin Li   if (const Expr *ThrowExpr = S.getThrowExpr()) {
7220*67e74705SXin Li     llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7221*67e74705SXin Li     Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7222*67e74705SXin Li     CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7223*67e74705SXin Li       .setDoesNotReturn();
7224*67e74705SXin Li   } else {
7225*67e74705SXin Li     CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7226*67e74705SXin Li       .setDoesNotReturn();
7227*67e74705SXin Li   }
7228*67e74705SXin Li 
7229*67e74705SXin Li   CGF.Builder.CreateUnreachable();
7230*67e74705SXin Li   if (ClearInsertionPoint)
7231*67e74705SXin Li     CGF.Builder.ClearInsertionPoint();
7232*67e74705SXin Li }
7233*67e74705SXin Li 
7234*67e74705SXin Li llvm::Constant *
GetInterfaceEHType(const ObjCInterfaceDecl * ID,bool ForDefinition)7235*67e74705SXin Li CGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7236*67e74705SXin Li                                            bool ForDefinition) {
7237*67e74705SXin Li   llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7238*67e74705SXin Li 
7239*67e74705SXin Li   // If we don't need a definition, return the entry if found or check
7240*67e74705SXin Li   // if we use an external reference.
7241*67e74705SXin Li   if (!ForDefinition) {
7242*67e74705SXin Li     if (Entry)
7243*67e74705SXin Li       return Entry;
7244*67e74705SXin Li 
7245*67e74705SXin Li     // If this type (or a super class) has the __objc_exception__
7246*67e74705SXin Li     // attribute, emit an external reference.
7247*67e74705SXin Li     if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7248*67e74705SXin Li       return Entry =
7249*67e74705SXin Li           new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7250*67e74705SXin Li                                    llvm::GlobalValue::ExternalLinkage,
7251*67e74705SXin Li                                    nullptr,
7252*67e74705SXin Li                                    ("OBJC_EHTYPE_$_" +
7253*67e74705SXin Li                                     ID->getObjCRuntimeNameAsString()));
7254*67e74705SXin Li   }
7255*67e74705SXin Li 
7256*67e74705SXin Li   // Otherwise we need to either make a new entry or fill in the
7257*67e74705SXin Li   // initializer.
7258*67e74705SXin Li   assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
7259*67e74705SXin Li   llvm::SmallString<64> ClassName(getClassSymbolPrefix());
7260*67e74705SXin Li   ClassName += ID->getObjCRuntimeNameAsString();
7261*67e74705SXin Li   std::string VTableName = "objc_ehtype_vtable";
7262*67e74705SXin Li   llvm::GlobalVariable *VTableGV =
7263*67e74705SXin Li     CGM.getModule().getGlobalVariable(VTableName);
7264*67e74705SXin Li   if (!VTableGV)
7265*67e74705SXin Li     VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
7266*67e74705SXin Li                                         false,
7267*67e74705SXin Li                                         llvm::GlobalValue::ExternalLinkage,
7268*67e74705SXin Li                                         nullptr, VTableName);
7269*67e74705SXin Li 
7270*67e74705SXin Li   llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7271*67e74705SXin Li 
7272*67e74705SXin Li   llvm::Constant *Values[] = {
7273*67e74705SXin Li       llvm::ConstantExpr::getGetElementPtr(VTableGV->getValueType(), VTableGV,
7274*67e74705SXin Li                                            VTableIdx),
7275*67e74705SXin Li       GetClassName(ID->getObjCRuntimeNameAsString()),
7276*67e74705SXin Li       GetClassGlobal(ClassName.str())};
7277*67e74705SXin Li   llvm::Constant *Init =
7278*67e74705SXin Li     llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
7279*67e74705SXin Li 
7280*67e74705SXin Li   llvm::GlobalValue::LinkageTypes L = ForDefinition
7281*67e74705SXin Li                                           ? llvm::GlobalValue::ExternalLinkage
7282*67e74705SXin Li                                           : llvm::GlobalValue::WeakAnyLinkage;
7283*67e74705SXin Li   if (Entry) {
7284*67e74705SXin Li     Entry->setInitializer(Init);
7285*67e74705SXin Li   } else {
7286*67e74705SXin Li     llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_");
7287*67e74705SXin Li     EHTYPEName += ID->getObjCRuntimeNameAsString();
7288*67e74705SXin Li     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7289*67e74705SXin Li                                      L,
7290*67e74705SXin Li                                      Init,
7291*67e74705SXin Li                                      EHTYPEName.str());
7292*67e74705SXin Li   }
7293*67e74705SXin Li   assert(Entry->getLinkage() == L);
7294*67e74705SXin Li 
7295*67e74705SXin Li   if (ID->getVisibility() == HiddenVisibility)
7296*67e74705SXin Li     Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7297*67e74705SXin Li   Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
7298*67e74705SXin Li       ObjCTypes.EHTypeTy));
7299*67e74705SXin Li 
7300*67e74705SXin Li   if (ForDefinition)
7301*67e74705SXin Li     Entry->setSection("__DATA,__objc_const");
7302*67e74705SXin Li 
7303*67e74705SXin Li   return Entry;
7304*67e74705SXin Li }
7305*67e74705SXin Li 
7306*67e74705SXin Li /* *** */
7307*67e74705SXin Li 
7308*67e74705SXin Li CodeGen::CGObjCRuntime *
CreateMacObjCRuntime(CodeGen::CodeGenModule & CGM)7309*67e74705SXin Li CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7310*67e74705SXin Li   switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7311*67e74705SXin Li   case ObjCRuntime::FragileMacOSX:
7312*67e74705SXin Li   return new CGObjCMac(CGM);
7313*67e74705SXin Li 
7314*67e74705SXin Li   case ObjCRuntime::MacOSX:
7315*67e74705SXin Li   case ObjCRuntime::iOS:
7316*67e74705SXin Li   case ObjCRuntime::WatchOS:
7317*67e74705SXin Li     return new CGObjCNonFragileABIMac(CGM);
7318*67e74705SXin Li 
7319*67e74705SXin Li   case ObjCRuntime::GNUstep:
7320*67e74705SXin Li   case ObjCRuntime::GCC:
7321*67e74705SXin Li   case ObjCRuntime::ObjFW:
7322*67e74705SXin Li     llvm_unreachable("these runtimes are not Mac runtimes");
7323*67e74705SXin Li   }
7324*67e74705SXin Li   llvm_unreachable("bad runtime");
7325*67e74705SXin Li }
7326