1193326Sed//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2193326Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193326Sed//
7193326Sed//===----------------------------------------------------------------------===//
8193326Sed//
9221345Sdim// This provides Objective-C code generation targeting the Apple runtime.
10193326Sed//
11193326Sed//===----------------------------------------------------------------------===//
12193326Sed
13249423Sdim#include "CGBlocks.h"
14249423Sdim#include "CGCleanup.h"
15314564Sdim#include "CGObjCRuntime.h"
16206084Srdivacky#include "CGRecordLayout.h"
17249423Sdim#include "CodeGenFunction.h"
18193326Sed#include "CodeGenModule.h"
19193326Sed#include "clang/AST/ASTContext.h"
20360784Sdim#include "clang/AST/Attr.h"
21193326Sed#include "clang/AST/Decl.h"
22193326Sed#include "clang/AST/DeclObjC.h"
23193326Sed#include "clang/AST/RecordLayout.h"
24193326Sed#include "clang/AST/StmtObjC.h"
25344779Sdim#include "clang/Basic/CodeGenOptions.h"
26193326Sed#include "clang/Basic/LangOptions.h"
27261991Sdim#include "clang/CodeGen/CGFunctionInfo.h"
28360784Sdim#include "clang/CodeGen/ConstantInitBuilder.h"
29314564Sdim#include "llvm/ADT/CachedHashString.h"
30193326Sed#include "llvm/ADT/DenseSet.h"
31198092Srdivacky#include "llvm/ADT/SetVector.h"
32249423Sdim#include "llvm/ADT/SmallPtrSet.h"
33198092Srdivacky#include "llvm/ADT/SmallString.h"
34249423Sdim#include "llvm/IR/DataLayout.h"
35249423Sdim#include "llvm/IR/InlineAsm.h"
36249423Sdim#include "llvm/IR/IntrinsicInst.h"
37249423Sdim#include "llvm/IR/LLVMContext.h"
38249423Sdim#include "llvm/IR/Module.h"
39344779Sdim#include "llvm/Support/ScopedPrinter.h"
40198092Srdivacky#include "llvm/Support/raw_ostream.h"
41198092Srdivacky#include <cstdio>
42193326Sed
43193326Sedusing namespace clang;
44193326Sedusing namespace CodeGen;
45193326Sed
46193326Sednamespace {
47193326Sed
48198092Srdivacky// FIXME: We should find a nicer way to make the labels for metadata, string
49198092Srdivacky// concatenation is lame.
50193326Sed
51193326Sedclass ObjCCommonTypesHelper {
52198092Srdivackyprotected:
53198092Srdivacky  llvm::LLVMContext &VMContext;
54198092Srdivacky
55193326Sedprivate:
56223017Sdim  // The types of these functions don't really matter because we
57223017Sdim  // should always bitcast before calling them.
58223017Sdim
59223017Sdim  /// id objc_msgSend (id, SEL, ...)
60341825Sdim  ///
61223017Sdim  /// The default messenger, used for sends whose ABI is unchanged from
62223017Sdim  /// the all-integer/pointer case.
63353358Sdim  llvm::FunctionCallee getMessageSendFn() const {
64224145Sdim    // Add the non-lazy-bind attribute, since objc_msgSend is likely to
65224145Sdim    // be called a lot.
66224145Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
67321369Sdim    return CGM.CreateRuntimeFunction(
68321369Sdim        llvm::FunctionType::get(ObjectPtrTy, params, true), "objc_msgSend",
69321369Sdim        llvm::AttributeList::get(CGM.getLLVMContext(),
70321369Sdim                                 llvm::AttributeList::FunctionIndex,
71321369Sdim                                 llvm::Attribute::NonLazyBind));
72193326Sed  }
73198092Srdivacky
74223017Sdim  /// void objc_msgSend_stret (id, SEL, ...)
75223017Sdim  ///
76223017Sdim  /// The messenger used when the return value is an aggregate returned
77223017Sdim  /// by indirect reference in the first argument, and therefore the
78223017Sdim  /// self and selector parameters are shifted over by one.
79353358Sdim  llvm::FunctionCallee getMessageSendStretFn() const {
80224145Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81223017Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
82223017Sdim                                                             params, true),
83223017Sdim                                     "objc_msgSend_stret");
84193326Sed  }
85198092Srdivacky
86223017Sdim  /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
87223017Sdim  ///
88223017Sdim  /// The messenger used when the return value is returned on the x87
89223017Sdim  /// floating-point stack; without a special entrypoint, the nil case
90223017Sdim  /// would be unbalanced.
91353358Sdim  llvm::FunctionCallee getMessageSendFpretFn() const {
92224145Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
93234353Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
94234353Sdim                                                             params, true),
95223017Sdim                                     "objc_msgSend_fpret");
96193326Sed  }
97198092Srdivacky
98234353Sdim  /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
99234353Sdim  ///
100234353Sdim  /// The messenger used when the return value is returned in two values on the
101234353Sdim  /// x87 floating point stack; without a special entrypoint, the nil case
102234353Sdim  /// would be unbalanced. Only used on 64-bit X86.
103353358Sdim  llvm::FunctionCallee getMessageSendFp2retFn() const {
104234353Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
105234353Sdim    llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
106321369Sdim    llvm::Type *resultType =
107321369Sdim        llvm::StructType::get(longDoubleType, longDoubleType);
108234353Sdim
109234353Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
110234353Sdim                                                             params, true),
111234353Sdim                                     "objc_msgSend_fp2ret");
112234353Sdim  }
113234353Sdim
114223017Sdim  /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
115223017Sdim  ///
116223017Sdim  /// The messenger used for super calls, which have different dispatch
117223017Sdim  /// semantics.  The class passed is the superclass of the current
118223017Sdim  /// class.
119353358Sdim  llvm::FunctionCallee getMessageSendSuperFn() const {
120224145Sdim    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
121193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
122223017Sdim                                                             params, true),
123223017Sdim                                     "objc_msgSendSuper");
124193326Sed  }
125198092Srdivacky
126223017Sdim  /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
127223017Sdim  ///
128223017Sdim  /// A slightly different messenger used for super calls.  The class
129223017Sdim  /// passed is the current class.
130353358Sdim  llvm::FunctionCallee getMessageSendSuperFn2() const {
131224145Sdim    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
132193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
133223017Sdim                                                             params, true),
134223017Sdim                                     "objc_msgSendSuper2");
135193326Sed  }
136198092Srdivacky
137223017Sdim  /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
138223017Sdim  ///                              SEL op, ...)
139223017Sdim  ///
140223017Sdim  /// The messenger used for super calls which return an aggregate indirectly.
141353358Sdim  llvm::FunctionCallee getMessageSendSuperStretFn() const {
142224145Sdim    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
143198092Srdivacky    return CGM.CreateRuntimeFunction(
144223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, true),
145198092Srdivacky      "objc_msgSendSuper_stret");
146193326Sed  }
147198092Srdivacky
148223017Sdim  /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
149223017Sdim  ///                               SEL op, ...)
150223017Sdim  ///
151223017Sdim  /// objc_msgSendSuper_stret with the super2 semantics.
152353358Sdim  llvm::FunctionCallee getMessageSendSuperStretFn2() const {
153224145Sdim    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
154198092Srdivacky    return CGM.CreateRuntimeFunction(
155223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, true),
156198092Srdivacky      "objc_msgSendSuper2_stret");
157193326Sed  }
158198092Srdivacky
159353358Sdim  llvm::FunctionCallee getMessageSendSuperFpretFn() const {
160193326Sed    // There is no objc_msgSendSuper_fpret? How can that work?
161193326Sed    return getMessageSendSuperFn();
162193326Sed  }
163198092Srdivacky
164353358Sdim  llvm::FunctionCallee getMessageSendSuperFpretFn2() const {
165193326Sed    // There is no objc_msgSendSuper_fpret? How can that work?
166193326Sed    return getMessageSendSuperFn2();
167193326Sed  }
168198092Srdivacky
169193326Sedprotected:
170193326Sed  CodeGen::CodeGenModule &CGM;
171198092Srdivacky
172193326Sedpublic:
173314564Sdim  llvm::IntegerType *ShortTy, *IntTy, *LongTy;
174314564Sdim  llvm::PointerType *Int8PtrTy, *Int8PtrPtrTy;
175276479Sdim  llvm::Type *IvarOffsetVarTy;
176198092Srdivacky
177193326Sed  /// ObjectPtrTy - LLVM type for object handles (typeof(id))
178314564Sdim  llvm::PointerType *ObjectPtrTy;
179198092Srdivacky
180193326Sed  /// PtrObjectPtrTy - LLVM type for id *
181314564Sdim  llvm::PointerType *PtrObjectPtrTy;
182198092Srdivacky
183193326Sed  /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
184314564Sdim  llvm::PointerType *SelectorPtrTy;
185341825Sdim
186234353Sdimprivate:
187193326Sed  /// ProtocolPtrTy - LLVM type for external protocol handles
188193326Sed  /// (typeof(Protocol))
189224145Sdim  llvm::Type *ExternalProtocolPtrTy;
190341825Sdim
191234353Sdimpublic:
192234353Sdim  llvm::Type *getExternalProtocolPtrTy() {
193234353Sdim    if (!ExternalProtocolPtrTy) {
194234353Sdim      // FIXME: It would be nice to unify this with the opaque type, so that the
195234353Sdim      // IR comes out a bit cleaner.
196234353Sdim      CodeGen::CodeGenTypes &Types = CGM.getTypes();
197234353Sdim      ASTContext &Ctx = CGM.getContext();
198234353Sdim      llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
199234353Sdim      ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
200234353Sdim    }
201341825Sdim
202234353Sdim    return ExternalProtocolPtrTy;
203234353Sdim  }
204341825Sdim
205193326Sed  // SuperCTy - clang type for struct objc_super.
206193326Sed  QualType SuperCTy;
207193326Sed  // SuperPtrCTy - clang type for struct objc_super *.
208193326Sed  QualType SuperPtrCTy;
209198092Srdivacky
210193326Sed  /// SuperTy - LLVM type for struct objc_super.
211224145Sdim  llvm::StructType *SuperTy;
212193326Sed  /// SuperPtrTy - LLVM type for struct objc_super *.
213314564Sdim  llvm::PointerType *SuperPtrTy;
214198092Srdivacky
215193326Sed  /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
216193326Sed  /// in GCC parlance).
217224145Sdim  llvm::StructType *PropertyTy;
218198092Srdivacky
219193326Sed  /// PropertyListTy - LLVM type for struct objc_property_list
220193326Sed  /// (_prop_list_t in GCC parlance).
221224145Sdim  llvm::StructType *PropertyListTy;
222193326Sed  /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
223314564Sdim  llvm::PointerType *PropertyListPtrTy;
224198092Srdivacky
225193326Sed  // MethodTy - LLVM type for struct objc_method.
226224145Sdim  llvm::StructType *MethodTy;
227198092Srdivacky
228193326Sed  /// CacheTy - LLVM type for struct objc_cache.
229224145Sdim  llvm::Type *CacheTy;
230193326Sed  /// CachePtrTy - LLVM type for struct objc_cache *.
231314564Sdim  llvm::PointerType *CachePtrTy;
232341825Sdim
233353358Sdim  llvm::FunctionCallee getGetPropertyFn() {
234193326Sed    CodeGen::CodeGenTypes &Types = CGM.getTypes();
235193326Sed    ASTContext &Ctx = CGM.getContext();
236193326Sed    // id objc_getProperty (id, SEL, ptrdiff_t, bool)
237204643Srdivacky    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
238204643Srdivacky    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
239309124Sdim    CanQualType Params[] = {
240309124Sdim        IdType, SelType,
241309124Sdim        Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(), Ctx.BoolTy};
242226633Sdim    llvm::FunctionType *FTy =
243309124Sdim        Types.GetFunctionType(
244309124Sdim          Types.arrangeBuiltinFunctionDeclaration(IdType, Params));
245193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
246193326Sed  }
247198092Srdivacky
248353358Sdim  llvm::FunctionCallee getSetPropertyFn() {
249193326Sed    CodeGen::CodeGenTypes &Types = CGM.getTypes();
250193326Sed    ASTContext &Ctx = CGM.getContext();
251193326Sed    // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
252204643Srdivacky    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
253204643Srdivacky    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
254309124Sdim    CanQualType Params[] = {
255309124Sdim        IdType,
256309124Sdim        SelType,
257309124Sdim        Ctx.getPointerDiffType()->getCanonicalTypeUnqualified(),
258309124Sdim        IdType,
259309124Sdim        Ctx.BoolTy,
260309124Sdim        Ctx.BoolTy};
261226633Sdim    llvm::FunctionType *FTy =
262309124Sdim        Types.GetFunctionType(
263309124Sdim          Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
264193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
265193326Sed  }
266198092Srdivacky
267353358Sdim  llvm::FunctionCallee getOptimizedSetPropertyFn(bool atomic, bool copy) {
268234353Sdim    CodeGen::CodeGenTypes &Types = CGM.getTypes();
269234353Sdim    ASTContext &Ctx = CGM.getContext();
270341825Sdim    // void objc_setProperty_atomic(id self, SEL _cmd,
271234353Sdim    //                              id newValue, ptrdiff_t offset);
272341825Sdim    // void objc_setProperty_nonatomic(id self, SEL _cmd,
273234353Sdim    //                                 id newValue, ptrdiff_t offset);
274341825Sdim    // void objc_setProperty_atomic_copy(id self, SEL _cmd,
275234353Sdim    //                                   id newValue, ptrdiff_t offset);
276341825Sdim    // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
277234353Sdim    //                                      id newValue, ptrdiff_t offset);
278341825Sdim
279234353Sdim    SmallVector<CanQualType,4> Params;
280234353Sdim    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
281234353Sdim    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
282234353Sdim    Params.push_back(IdType);
283234353Sdim    Params.push_back(SelType);
284234353Sdim    Params.push_back(IdType);
285234353Sdim    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
286234353Sdim    llvm::FunctionType *FTy =
287309124Sdim        Types.GetFunctionType(
288309124Sdim          Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
289234353Sdim    const char *name;
290234353Sdim    if (atomic && copy)
291234353Sdim      name = "objc_setProperty_atomic_copy";
292234353Sdim    else if (atomic && !copy)
293234353Sdim      name = "objc_setProperty_atomic";
294234353Sdim    else if (!atomic && copy)
295234353Sdim      name = "objc_setProperty_nonatomic_copy";
296234353Sdim    else
297234353Sdim      name = "objc_setProperty_nonatomic";
298341825Sdim
299234353Sdim    return CGM.CreateRuntimeFunction(FTy, name);
300234353Sdim  }
301341825Sdim
302353358Sdim  llvm::FunctionCallee getCopyStructFn() {
303207619Srdivacky    CodeGen::CodeGenTypes &Types = CGM.getTypes();
304207619Srdivacky    ASTContext &Ctx = CGM.getContext();
305207619Srdivacky    // void objc_copyStruct (void *, const void *, size_t, bool, bool)
306226633Sdim    SmallVector<CanQualType,5> Params;
307207619Srdivacky    Params.push_back(Ctx.VoidPtrTy);
308207619Srdivacky    Params.push_back(Ctx.VoidPtrTy);
309321369Sdim    Params.push_back(Ctx.getSizeType());
310207619Srdivacky    Params.push_back(Ctx.BoolTy);
311207619Srdivacky    Params.push_back(Ctx.BoolTy);
312226633Sdim    llvm::FunctionType *FTy =
313309124Sdim        Types.GetFunctionType(
314309124Sdim          Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
315207619Srdivacky    return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
316207619Srdivacky  }
317341825Sdim
318234353Sdim  /// This routine declares and returns address of:
319234353Sdim  /// void objc_copyCppObjectAtomic(
320341825Sdim  ///         void *dest, const void *src,
321234353Sdim  ///         void (*copyHelper) (void *dest, const void *source));
322353358Sdim  llvm::FunctionCallee getCppAtomicObjectFunction() {
323234353Sdim    CodeGen::CodeGenTypes &Types = CGM.getTypes();
324234353Sdim    ASTContext &Ctx = CGM.getContext();
325234353Sdim    /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
326234353Sdim    SmallVector<CanQualType,3> Params;
327234353Sdim    Params.push_back(Ctx.VoidPtrTy);
328234353Sdim    Params.push_back(Ctx.VoidPtrTy);
329234353Sdim    Params.push_back(Ctx.VoidPtrTy);
330234353Sdim    llvm::FunctionType *FTy =
331309124Sdim        Types.GetFunctionType(
332309124Sdim          Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
333234353Sdim    return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
334234353Sdim  }
335341825Sdim
336353358Sdim  llvm::FunctionCallee getEnumerationMutationFn() {
337198092Srdivacky    CodeGen::CodeGenTypes &Types = CGM.getTypes();
338198092Srdivacky    ASTContext &Ctx = CGM.getContext();
339193326Sed    // void objc_enumerationMutation (id)
340226633Sdim    SmallVector<CanQualType,1> Params;
341204643Srdivacky    Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
342226633Sdim    llvm::FunctionType *FTy =
343309124Sdim        Types.GetFunctionType(
344309124Sdim          Types.arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Params));
345193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
346193326Sed  }
347198092Srdivacky
348353358Sdim  llvm::FunctionCallee getLookUpClassFn() {
349309124Sdim    CodeGen::CodeGenTypes &Types = CGM.getTypes();
350309124Sdim    ASTContext &Ctx = CGM.getContext();
351309124Sdim    // Class objc_lookUpClass (const char *)
352309124Sdim    SmallVector<CanQualType,1> Params;
353309124Sdim    Params.push_back(
354309124Sdim      Ctx.getCanonicalType(Ctx.getPointerType(Ctx.CharTy.withConst())));
355309124Sdim    llvm::FunctionType *FTy =
356309124Sdim        Types.GetFunctionType(Types.arrangeBuiltinFunctionDeclaration(
357309124Sdim                                Ctx.getCanonicalType(Ctx.getObjCClassType()),
358309124Sdim                                Params));
359309124Sdim    return CGM.CreateRuntimeFunction(FTy, "objc_lookUpClass");
360309124Sdim  }
361309124Sdim
362193326Sed  /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
363353358Sdim  llvm::FunctionCallee getGcReadWeakFn() {
364193326Sed    // id objc_read_weak (id *)
365224145Sdim    llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
366198092Srdivacky    llvm::FunctionType *FTy =
367223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
368193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
369198092Srdivacky  }
370198092Srdivacky
371193326Sed  /// GcAssignWeakFn -- LLVM objc_assign_weak function.
372353358Sdim  llvm::FunctionCallee getGcAssignWeakFn() {
373193326Sed    // id objc_assign_weak (id, id *)
374224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
375193326Sed    llvm::FunctionType *FTy =
376223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
377193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
378193326Sed  }
379198092Srdivacky
380193326Sed  /// GcAssignGlobalFn -- LLVM objc_assign_global function.
381353358Sdim  llvm::FunctionCallee getGcAssignGlobalFn() {
382193326Sed    // id objc_assign_global(id, id *)
383224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
384198092Srdivacky    llvm::FunctionType *FTy =
385223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
386193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
387193326Sed  }
388198092Srdivacky
389212904Sdim  /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
390353358Sdim  llvm::FunctionCallee getGcAssignThreadLocalFn() {
391212904Sdim    // id objc_assign_threadlocal(id src, id * dest)
392224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
393212904Sdim    llvm::FunctionType *FTy =
394223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
395212904Sdim    return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
396212904Sdim  }
397341825Sdim
398193326Sed  /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
399353358Sdim  llvm::FunctionCallee getGcAssignIvarFn() {
400198092Srdivacky    // id objc_assign_ivar(id, id *, ptrdiff_t)
401224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
402224145Sdim                           CGM.PtrDiffTy };
403198092Srdivacky    llvm::FunctionType *FTy =
404223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
405193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
406193326Sed  }
407198092Srdivacky
408198092Srdivacky  /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
409353358Sdim  llvm::FunctionCallee GcMemmoveCollectableFn() {
410198092Srdivacky    // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
411224145Sdim    llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
412223017Sdim    llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
413198092Srdivacky    return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
414198092Srdivacky  }
415198092Srdivacky
416193326Sed  /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
417353358Sdim  llvm::FunctionCallee getGcAssignStrongCastFn() {
418212904Sdim    // id objc_assign_strongCast(id, id *)
419224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
420198092Srdivacky    llvm::FunctionType *FTy =
421223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
422193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
423193326Sed  }
424193326Sed
425193326Sed  /// ExceptionThrowFn - LLVM objc_exception_throw function.
426353358Sdim  llvm::FunctionCallee getExceptionThrowFn() {
427193326Sed    // void objc_exception_throw(id)
428224145Sdim    llvm::Type *args[] = { ObjectPtrTy };
429193326Sed    llvm::FunctionType *FTy =
430223017Sdim      llvm::FunctionType::get(CGM.VoidTy, args, false);
431193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
432193326Sed  }
433198092Srdivacky
434210299Sed  /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
435353358Sdim  llvm::FunctionCallee getExceptionRethrowFn() {
436210299Sed    // void objc_exception_rethrow(void)
437223017Sdim    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
438210299Sed    return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
439210299Sed  }
440341825Sdim
441193326Sed  /// SyncEnterFn - LLVM object_sync_enter function.
442353358Sdim  llvm::FunctionCallee getSyncEnterFn() {
443243830Sdim    // int objc_sync_enter (id)
444224145Sdim    llvm::Type *args[] = { ObjectPtrTy };
445193326Sed    llvm::FunctionType *FTy =
446243830Sdim      llvm::FunctionType::get(CGM.IntTy, args, false);
447193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
448193326Sed  }
449198092Srdivacky
450193326Sed  /// SyncExitFn - LLVM object_sync_exit function.
451353358Sdim  llvm::FunctionCallee getSyncExitFn() {
452243830Sdim    // int objc_sync_exit (id)
453224145Sdim    llvm::Type *args[] = { ObjectPtrTy };
454193326Sed    llvm::FunctionType *FTy =
455243830Sdim      llvm::FunctionType::get(CGM.IntTy, args, false);
456193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
457193326Sed  }
458198092Srdivacky
459353358Sdim  llvm::FunctionCallee getSendFn(bool IsSuper) const {
460193326Sed    return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
461193326Sed  }
462198092Srdivacky
463353358Sdim  llvm::FunctionCallee getSendFn2(bool IsSuper) const {
464193326Sed    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
465193326Sed  }
466198092Srdivacky
467353358Sdim  llvm::FunctionCallee getSendStretFn(bool IsSuper) const {
468193326Sed    return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
469193326Sed  }
470198092Srdivacky
471353358Sdim  llvm::FunctionCallee getSendStretFn2(bool IsSuper) const {
472193326Sed    return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
473193326Sed  }
474198092Srdivacky
475353358Sdim  llvm::FunctionCallee getSendFpretFn(bool IsSuper) const {
476193326Sed    return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
477193326Sed  }
478198092Srdivacky
479353358Sdim  llvm::FunctionCallee getSendFpretFn2(bool IsSuper) const {
480193326Sed    return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
481193326Sed  }
482198092Srdivacky
483353358Sdim  llvm::FunctionCallee getSendFp2retFn(bool IsSuper) const {
484234353Sdim    return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
485234353Sdim  }
486234353Sdim
487353358Sdim  llvm::FunctionCallee getSendFp2RetFn2(bool IsSuper) const {
488234353Sdim    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
489234353Sdim  }
490234353Sdim
491193326Sed  ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
492193326Sed};
493193326Sed
494193326Sed/// ObjCTypesHelper - Helper class that encapsulates lazy
495193326Sed/// construction of varies types used during ObjC generation.
496193326Sedclass ObjCTypesHelper : public ObjCCommonTypesHelper {
497193326Sedpublic:
498193326Sed  /// SymtabTy - LLVM type for struct objc_symtab.
499224145Sdim  llvm::StructType *SymtabTy;
500193326Sed  /// SymtabPtrTy - LLVM type for struct objc_symtab *.
501314564Sdim  llvm::PointerType *SymtabPtrTy;
502193326Sed  /// ModuleTy - LLVM type for struct objc_module.
503224145Sdim  llvm::StructType *ModuleTy;
504193326Sed
505193326Sed  /// ProtocolTy - LLVM type for struct objc_protocol.
506224145Sdim  llvm::StructType *ProtocolTy;
507193326Sed  /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
508314564Sdim  llvm::PointerType *ProtocolPtrTy;
509193326Sed  /// ProtocolExtensionTy - LLVM type for struct
510193326Sed  /// objc_protocol_extension.
511224145Sdim  llvm::StructType *ProtocolExtensionTy;
512193326Sed  /// ProtocolExtensionTy - LLVM type for struct
513193326Sed  /// objc_protocol_extension *.
514314564Sdim  llvm::PointerType *ProtocolExtensionPtrTy;
515193326Sed  /// MethodDescriptionTy - LLVM type for struct
516193326Sed  /// objc_method_description.
517224145Sdim  llvm::StructType *MethodDescriptionTy;
518193326Sed  /// MethodDescriptionListTy - LLVM type for struct
519193326Sed  /// objc_method_description_list.
520224145Sdim  llvm::StructType *MethodDescriptionListTy;
521193326Sed  /// MethodDescriptionListPtrTy - LLVM type for struct
522193326Sed  /// objc_method_description_list *.
523314564Sdim  llvm::PointerType *MethodDescriptionListPtrTy;
524193326Sed  /// ProtocolListTy - LLVM type for struct objc_property_list.
525224145Sdim  llvm::StructType *ProtocolListTy;
526193326Sed  /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
527314564Sdim  llvm::PointerType *ProtocolListPtrTy;
528193326Sed  /// CategoryTy - LLVM type for struct objc_category.
529224145Sdim  llvm::StructType *CategoryTy;
530193326Sed  /// ClassTy - LLVM type for struct objc_class.
531224145Sdim  llvm::StructType *ClassTy;
532193326Sed  /// ClassPtrTy - LLVM type for struct objc_class *.
533314564Sdim  llvm::PointerType *ClassPtrTy;
534193326Sed  /// ClassExtensionTy - LLVM type for struct objc_class_ext.
535224145Sdim  llvm::StructType *ClassExtensionTy;
536193326Sed  /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
537314564Sdim  llvm::PointerType *ClassExtensionPtrTy;
538193326Sed  // IvarTy - LLVM type for struct objc_ivar.
539224145Sdim  llvm::StructType *IvarTy;
540193326Sed  /// IvarListTy - LLVM type for struct objc_ivar_list.
541314564Sdim  llvm::StructType *IvarListTy;
542193326Sed  /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
543314564Sdim  llvm::PointerType *IvarListPtrTy;
544193326Sed  /// MethodListTy - LLVM type for struct objc_method_list.
545314564Sdim  llvm::StructType *MethodListTy;
546193326Sed  /// MethodListPtrTy - LLVM type for struct objc_method_list *.
547314564Sdim  llvm::PointerType *MethodListPtrTy;
548198092Srdivacky
549193326Sed  /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
550314564Sdim  llvm::StructType *ExceptionDataTy;
551341825Sdim
552193326Sed  /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
553353358Sdim  llvm::FunctionCallee getExceptionTryEnterFn() {
554224145Sdim    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
555198092Srdivacky    return CGM.CreateRuntimeFunction(
556223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, false),
557198092Srdivacky      "objc_exception_try_enter");
558193326Sed  }
559193326Sed
560193326Sed  /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
561353358Sdim  llvm::FunctionCallee getExceptionTryExitFn() {
562224145Sdim    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
563198092Srdivacky    return CGM.CreateRuntimeFunction(
564223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, false),
565198092Srdivacky      "objc_exception_try_exit");
566193326Sed  }
567193326Sed
568193326Sed  /// ExceptionExtractFn - LLVM objc_exception_extract function.
569353358Sdim  llvm::FunctionCallee getExceptionExtractFn() {
570224145Sdim    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
571193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
572223017Sdim                                                             params, false),
573193326Sed                                     "objc_exception_extract");
574193326Sed  }
575198092Srdivacky
576193326Sed  /// ExceptionMatchFn - LLVM objc_exception_match function.
577353358Sdim  llvm::FunctionCallee getExceptionMatchFn() {
578224145Sdim    llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
579198092Srdivacky    return CGM.CreateRuntimeFunction(
580223017Sdim      llvm::FunctionType::get(CGM.Int32Ty, params, false),
581198092Srdivacky      "objc_exception_match");
582193326Sed  }
583198092Srdivacky
584193326Sed  /// SetJmpFn - LLVM _setjmp function.
585353358Sdim  llvm::FunctionCallee getSetJmpFn() {
586223017Sdim    // This is specifically the prototype for x86.
587224145Sdim    llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
588321369Sdim    return CGM.CreateRuntimeFunction(
589321369Sdim        llvm::FunctionType::get(CGM.Int32Ty, params, false), "_setjmp",
590321369Sdim        llvm::AttributeList::get(CGM.getLLVMContext(),
591321369Sdim                                 llvm::AttributeList::FunctionIndex,
592321369Sdim                                 llvm::Attribute::NonLazyBind));
593193326Sed  }
594198092Srdivacky
595193326Sedpublic:
596193326Sed  ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
597193326Sed};
598193326Sed
599193326Sed/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
600193326Sed/// modern abi
601193326Sedclass ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
602193326Sedpublic:
603193326Sed  // MethodListnfABITy - LLVM for struct _method_list_t
604224145Sdim  llvm::StructType *MethodListnfABITy;
605198092Srdivacky
606193326Sed  // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
607314564Sdim  llvm::PointerType *MethodListnfABIPtrTy;
608198092Srdivacky
609193326Sed  // ProtocolnfABITy = LLVM for struct _protocol_t
610224145Sdim  llvm::StructType *ProtocolnfABITy;
611198092Srdivacky
612193326Sed  // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
613314564Sdim  llvm::PointerType *ProtocolnfABIPtrTy;
614193326Sed
615193326Sed  // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
616224145Sdim  llvm::StructType *ProtocolListnfABITy;
617198092Srdivacky
618193326Sed  // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
619314564Sdim  llvm::PointerType *ProtocolListnfABIPtrTy;
620198092Srdivacky
621193326Sed  // ClassnfABITy - LLVM for struct _class_t
622224145Sdim  llvm::StructType *ClassnfABITy;
623198092Srdivacky
624193326Sed  // ClassnfABIPtrTy - LLVM for struct _class_t*
625314564Sdim  llvm::PointerType *ClassnfABIPtrTy;
626198092Srdivacky
627193326Sed  // IvarnfABITy - LLVM for struct _ivar_t
628224145Sdim  llvm::StructType *IvarnfABITy;
629198092Srdivacky
630193326Sed  // IvarListnfABITy - LLVM for struct _ivar_list_t
631224145Sdim  llvm::StructType *IvarListnfABITy;
632198092Srdivacky
633193326Sed  // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
634314564Sdim  llvm::PointerType *IvarListnfABIPtrTy;
635198092Srdivacky
636193326Sed  // ClassRonfABITy - LLVM for struct _class_ro_t
637224145Sdim  llvm::StructType *ClassRonfABITy;
638198092Srdivacky
639193326Sed  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
640314564Sdim  llvm::PointerType *ImpnfABITy;
641198092Srdivacky
642193326Sed  // CategorynfABITy - LLVM for struct _category_t
643224145Sdim  llvm::StructType *CategorynfABITy;
644198092Srdivacky
645193326Sed  // New types for nonfragile abi messaging.
646198092Srdivacky
647193326Sed  // MessageRefTy - LLVM for:
648193326Sed  // struct _message_ref_t {
649193326Sed  //   IMP messenger;
650193326Sed  //   SEL name;
651193326Sed  // };
652224145Sdim  llvm::StructType *MessageRefTy;
653193326Sed  // MessageRefCTy - clang type for struct _message_ref_t
654193326Sed  QualType MessageRefCTy;
655198092Srdivacky
656193326Sed  // MessageRefPtrTy - LLVM for struct _message_ref_t*
657224145Sdim  llvm::Type *MessageRefPtrTy;
658193326Sed  // MessageRefCPtrTy - clang type for struct _message_ref_t*
659193326Sed  QualType MessageRefCPtrTy;
660198092Srdivacky
661193326Sed  // SuperMessageRefTy - LLVM for:
662193326Sed  // struct _super_message_ref_t {
663193326Sed  //   SUPER_IMP messenger;
664193326Sed  //   SEL name;
665193326Sed  // };
666224145Sdim  llvm::StructType *SuperMessageRefTy;
667198092Srdivacky
668193326Sed  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
669314564Sdim  llvm::PointerType *SuperMessageRefPtrTy;
670193326Sed
671353358Sdim  llvm::FunctionCallee getMessageSendFixupFn() {
672193326Sed    // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
673224145Sdim    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
674193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
675223017Sdim                                                             params, true),
676193326Sed                                     "objc_msgSend_fixup");
677193326Sed  }
678198092Srdivacky
679353358Sdim  llvm::FunctionCallee getMessageSendFpretFixupFn() {
680193326Sed    // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
681224145Sdim    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
682193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
683223017Sdim                                                             params, true),
684193326Sed                                     "objc_msgSend_fpret_fixup");
685193326Sed  }
686198092Srdivacky
687353358Sdim  llvm::FunctionCallee getMessageSendStretFixupFn() {
688193326Sed    // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
689224145Sdim    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
690193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
691223017Sdim                                                             params, true),
692193326Sed                                     "objc_msgSend_stret_fixup");
693193326Sed  }
694198092Srdivacky
695353358Sdim  llvm::FunctionCallee getMessageSendSuper2FixupFn() {
696198092Srdivacky    // id objc_msgSendSuper2_fixup (struct objc_super *,
697193326Sed    //                              struct _super_message_ref_t*, ...)
698224145Sdim    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
699193326Sed    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
700223017Sdim                                                              params, true),
701193326Sed                                      "objc_msgSendSuper2_fixup");
702193326Sed  }
703198092Srdivacky
704353358Sdim  llvm::FunctionCallee getMessageSendSuper2StretFixupFn() {
705198092Srdivacky    // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
706193326Sed    //                                   struct _super_message_ref_t*, ...)
707224145Sdim    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
708193326Sed    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
709223017Sdim                                                              params, true),
710193326Sed                                      "objc_msgSendSuper2_stret_fixup");
711193326Sed  }
712198092Srdivacky
713353358Sdim  llvm::FunctionCallee getObjCEndCatchFn() {
714223017Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
715193326Sed                                     "objc_end_catch");
716193326Sed  }
717198092Srdivacky
718353358Sdim  llvm::FunctionCallee getObjCBeginCatchFn() {
719224145Sdim    llvm::Type *params[] = { Int8PtrTy };
720193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
721223017Sdim                                                             params, false),
722193326Sed                                     "objc_begin_catch");
723193326Sed  }
724193326Sed
725353358Sdim  /// Class objc_loadClassref (void *)
726353358Sdim  ///
727353358Sdim  /// Loads from a classref. For Objective-C stub classes, this invokes the
728353358Sdim  /// initialization callback stored inside the stub. For all other classes
729353358Sdim  /// this simply dereferences the pointer.
730353358Sdim  llvm::FunctionCallee getLoadClassrefFn() const {
731353358Sdim    // Add the non-lazy-bind attribute, since objc_loadClassref is likely to
732353358Sdim    // be called a lot.
733353358Sdim    //
734353358Sdim    // Also it is safe to make it readnone, since we never load or store the
735353358Sdim    // classref except by calling this function.
736353358Sdim    llvm::Type *params[] = { Int8PtrPtrTy };
737353358Sdim    llvm::FunctionCallee F = CGM.CreateRuntimeFunction(
738353358Sdim        llvm::FunctionType::get(ClassnfABIPtrTy, params, false),
739353358Sdim        "objc_loadClassref",
740353358Sdim        llvm::AttributeList::get(CGM.getLLVMContext(),
741353358Sdim                                 llvm::AttributeList::FunctionIndex,
742353358Sdim                                 {llvm::Attribute::NonLazyBind,
743353358Sdim                                  llvm::Attribute::ReadNone,
744353358Sdim                                  llvm::Attribute::NoUnwind}));
745353358Sdim    if (!CGM.getTriple().isOSBinFormatCOFF())
746353358Sdim      cast<llvm::Function>(F.getCallee())->setLinkage(
747353358Sdim        llvm::Function::ExternalWeakLinkage);
748353358Sdim
749353358Sdim    return F;
750353358Sdim  }
751353358Sdim
752224145Sdim  llvm::StructType *EHTypeTy;
753224145Sdim  llvm::Type *EHTypePtrTy;
754341825Sdim
755193326Sed  ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
756193326Sed};
757198092Srdivacky
758314564Sdimenum class ObjCLabelType {
759314564Sdim  ClassName,
760314564Sdim  MethodVarName,
761314564Sdim  MethodVarType,
762314564Sdim  PropertyName,
763314564Sdim};
764314564Sdim
765193326Sedclass CGObjCCommonMac : public CodeGen::CGObjCRuntime {
766193326Sedpublic:
767193326Sed  class SKIP_SCAN {
768193326Sed  public:
769193326Sed    unsigned skip;
770193326Sed    unsigned scan;
771198092Srdivacky    SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
772193326Sed      : skip(_skip), scan(_scan) {}
773193326Sed  };
774198092Srdivacky
775243830Sdim  /// opcode for captured block variables layout 'instructions'.
776243830Sdim  /// In the following descriptions, 'I' is the value of the immediate field.
777243830Sdim  /// (field following the opcode).
778243830Sdim  ///
779243830Sdim  enum BLOCK_LAYOUT_OPCODE {
780243830Sdim    /// An operator which affects how the following layout should be
781243830Sdim    /// interpreted.
782243830Sdim    ///   I == 0: Halt interpretation and treat everything else as
783243830Sdim    ///           a non-pointer.  Note that this instruction is equal
784243830Sdim    ///           to '\0'.
785243830Sdim    ///   I != 0: Currently unused.
786243830Sdim    BLOCK_LAYOUT_OPERATOR            = 0,
787341825Sdim
788243830Sdim    /// The next I+1 bytes do not contain a value of object pointer type.
789243830Sdim    /// Note that this can leave the stream unaligned, meaning that
790243830Sdim    /// subsequent word-size instructions do not begin at a multiple of
791243830Sdim    /// the pointer size.
792243830Sdim    BLOCK_LAYOUT_NON_OBJECT_BYTES    = 1,
793341825Sdim
794243830Sdim    /// The next I+1 words do not contain a value of object pointer type.
795243830Sdim    /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
796243830Sdim    /// when the required skip quantity is a multiple of the pointer size.
797243830Sdim    BLOCK_LAYOUT_NON_OBJECT_WORDS    = 2,
798341825Sdim
799243830Sdim    /// The next I+1 words are __strong pointers to Objective-C
800243830Sdim    /// objects or blocks.
801243830Sdim    BLOCK_LAYOUT_STRONG              = 3,
802341825Sdim
803243830Sdim    /// The next I+1 words are pointers to __block variables.
804243830Sdim    BLOCK_LAYOUT_BYREF               = 4,
805341825Sdim
806243830Sdim    /// The next I+1 words are __weak pointers to Objective-C
807243830Sdim    /// objects or blocks.
808243830Sdim    BLOCK_LAYOUT_WEAK                = 5,
809341825Sdim
810243830Sdim    /// The next I+1 words are __unsafe_unretained pointers to
811243830Sdim    /// Objective-C objects or blocks.
812243830Sdim    BLOCK_LAYOUT_UNRETAINED          = 6
813341825Sdim
814243830Sdim    /// The next I+1 words are block or object pointers with some
815243830Sdim    /// as-yet-unspecified ownership semantics.  If we add more
816243830Sdim    /// flavors of ownership semantics, values will be taken from
817243830Sdim    /// this range.
818243830Sdim    ///
819243830Sdim    /// This is included so that older tools can at least continue
820243830Sdim    /// processing the layout past such things.
821243830Sdim    //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
822341825Sdim
823243830Sdim    /// All other opcodes are reserved.  Halt interpretation and
824243830Sdim    /// treat everything else as opaque.
825243830Sdim  };
826341825Sdim
827243830Sdim  class RUN_SKIP {
828243830Sdim  public:
829243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode;
830243830Sdim    CharUnits block_var_bytepos;
831243830Sdim    CharUnits block_var_size;
832243830Sdim    RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
833243830Sdim             CharUnits BytePos = CharUnits::Zero(),
834243830Sdim             CharUnits Size = CharUnits::Zero())
835243830Sdim    : opcode(Opcode), block_var_bytepos(BytePos),  block_var_size(Size) {}
836341825Sdim
837243830Sdim    // Allow sorting based on byte pos.
838243830Sdim    bool operator<(const RUN_SKIP &b) const {
839243830Sdim      return block_var_bytepos < b.block_var_bytepos;
840243830Sdim    }
841243830Sdim  };
842341825Sdim
843193326Sedprotected:
844198092Srdivacky  llvm::LLVMContext &VMContext;
845193326Sed  // FIXME! May not be needing this after all.
846193326Sed  unsigned ObjCABI;
847198092Srdivacky
848243830Sdim  // arc/mrr layout of captured block literal variables.
849243830Sdim  SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
850198092Srdivacky
851193326Sed  /// LazySymbols - Symbols to generate a lazy reference for. See
852193326Sed  /// DefinedSymbols and FinishModule().
853198092Srdivacky  llvm::SetVector<IdentifierInfo*> LazySymbols;
854198092Srdivacky
855193326Sed  /// DefinedSymbols - External symbols which are defined by this
856193326Sed  /// module. The symbols in this list and LazySymbols are used to add
857193326Sed  /// special linker symbols which ensure that Objective-C modules are
858193326Sed  /// linked properly.
859198092Srdivacky  llvm::SetVector<IdentifierInfo*> DefinedSymbols;
860198092Srdivacky
861193326Sed  /// ClassNames - uniqued class names.
862276479Sdim  llvm::StringMap<llvm::GlobalVariable*> ClassNames;
863198092Srdivacky
864193326Sed  /// MethodVarNames - uniqued method variable names.
865193326Sed  llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
866198092Srdivacky
867210299Sed  /// DefinedCategoryNames - list of category names in form Class_Category.
868314564Sdim  llvm::SmallSetVector<llvm::CachedHashString, 16> DefinedCategoryNames;
869210299Sed
870193326Sed  /// MethodVarTypes - uniqued method type signatures. We have to use
871193326Sed  /// a StringMap here because have no other unique reference.
872193326Sed  llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
873198092Srdivacky
874193326Sed  /// MethodDefinitions - map of methods which have been defined in
875193326Sed  /// this translation unit.
876193326Sed  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
877198092Srdivacky
878360784Sdim  /// DirectMethodDefinitions - map of direct methods which have been defined in
879360784Sdim  /// this translation unit.
880360784Sdim  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> DirectMethodDefinitions;
881360784Sdim
882193326Sed  /// PropertyNames - uniqued method variable names.
883193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
884198092Srdivacky
885193326Sed  /// ClassReferences - uniqued class references.
886193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
887198092Srdivacky
888193326Sed  /// SelectorReferences - uniqued selector references.
889193326Sed  llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
890198092Srdivacky
891193326Sed  /// Protocols - Protocols for which an objc_protocol structure has
892193326Sed  /// been emitted. Forward declarations are handled by creating an
893193326Sed  /// empty structure whose initializer is filled in when/if defined.
894193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
895198092Srdivacky
896193326Sed  /// DefinedProtocols - Protocols which have actually been
897193326Sed  /// defined. We should not need this, see FIXME in GenerateProtocol.
898193326Sed  llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
899198092Srdivacky
900193326Sed  /// DefinedClasses - List of defined classes.
901249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
902341825Sdim
903276479Sdim  /// ImplementedClasses - List of @implemented classes.
904276479Sdim  SmallVector<const ObjCInterfaceDecl*, 16> ImplementedClasses;
905193326Sed
906193326Sed  /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
907249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
908198092Srdivacky
909193326Sed  /// DefinedCategories - List of defined categories.
910249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
911198092Srdivacky
912353358Sdim  /// DefinedStubCategories - List of defined categories on class stubs.
913353358Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedStubCategories;
914353358Sdim
915193326Sed  /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
916249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
917193326Sed
918314564Sdim  /// Cached reference to the class for constant strings. This value has type
919314564Sdim  /// int * but is actually an Obj-C class pointer.
920321369Sdim  llvm::WeakTrackingVH ConstantStringClassRef;
921314564Sdim
922341825Sdim  /// The LLVM type corresponding to NSConstantString.
923314564Sdim  llvm::StructType *NSConstantStringType = nullptr;
924314564Sdim
925314564Sdim  llvm::StringMap<llvm::GlobalVariable *> NSConstantStringMap;
926314564Sdim
927193326Sed  /// GetNameForMethod - Return a name for the given method.
928193326Sed  /// \param[out] NameOut - The return value.
929193326Sed  void GetNameForMethod(const ObjCMethodDecl *OMD,
930193326Sed                        const ObjCContainerDecl *CD,
931360784Sdim                        SmallVectorImpl<char> &NameOut,
932360784Sdim                        bool ignoreCategoryNamespace = false);
933198092Srdivacky
934193326Sed  /// GetMethodVarName - Return a unique constant for the given
935193326Sed  /// selector's name. The return value has type char *.
936193326Sed  llvm::Constant *GetMethodVarName(Selector Sel);
937193326Sed  llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
938198092Srdivacky
939193326Sed  /// GetMethodVarType - Return a unique constant for the given
940234353Sdim  /// method's type encoding string. The return value has type char *.
941198092Srdivacky
942193326Sed  // FIXME: This is a horrible name.
943234353Sdim  llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
944234353Sdim                                   bool Extended = false);
945193326Sed  llvm::Constant *GetMethodVarType(const FieldDecl *D);
946198092Srdivacky
947193326Sed  /// GetPropertyName - Return a unique constant for the given
948193326Sed  /// name. The return value has type char *.
949193326Sed  llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
950198092Srdivacky
951193326Sed  // FIXME: This can be dropped once string functions are unified.
952193326Sed  llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
953193326Sed                                        const Decl *Container);
954198092Srdivacky
955193326Sed  /// GetClassName - Return a unique constant for the given selector's
956276479Sdim  /// runtime name (which may change via use of objc_runtime_name attribute on
957276479Sdim  /// class or protocol definition. The return value has type char *.
958276479Sdim  llvm::Constant *GetClassName(StringRef RuntimeName);
959198092Srdivacky
960212904Sdim  llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
961212904Sdim
962193326Sed  /// BuildIvarLayout - Builds ivar layout bitmap for the class
963193326Sed  /// implementation for the __strong or __weak case.
964193326Sed  ///
965296417Sdim  /// \param hasMRCWeakIvars - Whether we are compiling in MRC and there
966296417Sdim  ///   are any weak ivars defined directly in the class.  Meaningless unless
967296417Sdim  ///   building a weak layout.  Does not guarantee that the layout will
968296417Sdim  ///   actually have any entries, because the ivar might be under-aligned.
969193326Sed  llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
970296417Sdim                                  CharUnits beginOffset,
971296417Sdim                                  CharUnits endOffset,
972296417Sdim                                  bool forStrongLayout,
973296417Sdim                                  bool hasMRCWeakIvars);
974198092Srdivacky
975296417Sdim  llvm::Constant *BuildStrongIvarLayout(const ObjCImplementationDecl *OI,
976296417Sdim                                        CharUnits beginOffset,
977296417Sdim                                        CharUnits endOffset) {
978296417Sdim    return BuildIvarLayout(OI, beginOffset, endOffset, true, false);
979296417Sdim  }
980296417Sdim
981296417Sdim  llvm::Constant *BuildWeakIvarLayout(const ObjCImplementationDecl *OI,
982296417Sdim                                      CharUnits beginOffset,
983296417Sdim                                      CharUnits endOffset,
984296417Sdim                                      bool hasMRCWeakIvars) {
985296417Sdim    return BuildIvarLayout(OI, beginOffset, endOffset, false, hasMRCWeakIvars);
986296417Sdim  }
987341825Sdim
988249423Sdim  Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout);
989341825Sdim
990243830Sdim  void UpdateRunSkipBlockVars(bool IsByref,
991243830Sdim                              Qualifiers::ObjCLifetime LifeTime,
992243830Sdim                              CharUnits FieldOffset,
993243830Sdim                              CharUnits FieldSize);
994341825Sdim
995243830Sdim  void BuildRCBlockVarRecordLayout(const RecordType *RT,
996249423Sdim                                   CharUnits BytePos, bool &HasUnion,
997249423Sdim                                   bool ByrefLayout=false);
998341825Sdim
999243830Sdim  void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
1000243830Sdim                           const RecordDecl *RD,
1001243830Sdim                           ArrayRef<const FieldDecl*> RecFields,
1002249423Sdim                           CharUnits BytePos, bool &HasUnion,
1003249423Sdim                           bool ByrefLayout);
1004341825Sdim
1005243830Sdim  uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
1006341825Sdim
1007249423Sdim  llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);
1008341825Sdim
1009193326Sed  /// GetIvarLayoutName - Returns a unique constant for the given
1010193326Sed  /// ivar layout bitmap.
1011193326Sed  llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
1012193326Sed                                    const ObjCCommonTypesHelper &ObjCTypes);
1013198092Srdivacky
1014193326Sed  /// EmitPropertyList - Emit the given property list. The return
1015193326Sed  /// value has type PropertyListPtrTy.
1016226633Sdim  llvm::Constant *EmitPropertyList(Twine Name,
1017198092Srdivacky                                   const Decl *Container,
1018193326Sed                                   const ObjCContainerDecl *OCD,
1019309124Sdim                                   const ObjCCommonTypesHelper &ObjCTypes,
1020309124Sdim                                   bool IsClassProperty);
1021198092Srdivacky
1022341825Sdim  /// EmitProtocolMethodTypes - Generate the array of extended method type
1023234353Sdim  /// strings. The return value has type Int8PtrPtrTy.
1024341825Sdim  llvm::Constant *EmitProtocolMethodTypes(Twine Name,
1025234353Sdim                                          ArrayRef<llvm::Constant*> MethodTypes,
1026234353Sdim                                       const ObjCCommonTypesHelper &ObjCTypes);
1027234353Sdim
1028193326Sed  /// GetProtocolRef - Return a reference to the internal protocol
1029193326Sed  /// description, creating an empty one if it has not been
1030193326Sed  /// defined. The return value has type ProtocolPtrTy.
1031193326Sed  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
1032193326Sed
1033309124Sdim  /// Return a reference to the given Class using runtime calls rather than
1034309124Sdim  /// by a symbol reference.
1035309124Sdim  llvm::Value *EmitClassRefViaRuntime(CodeGenFunction &CGF,
1036309124Sdim                                      const ObjCInterfaceDecl *ID,
1037309124Sdim                                      ObjCCommonTypesHelper &ObjCTypes);
1038309124Sdim
1039321369Sdim  std::string GetSectionName(StringRef Section, StringRef MachOAttributes);
1040321369Sdim
1041296417Sdimpublic:
1042193326Sed  /// CreateMetadataVar - Create a global variable with internal
1043193326Sed  /// linkage for use by the Objective-C runtime.
1044193326Sed  ///
1045193326Sed  /// This is a convenience wrapper which not only creates the
1046193326Sed  /// variable, but also sets the section and alignment and adds the
1047198092Srdivacky  /// global to the "llvm.used" list.
1048193326Sed  ///
1049193326Sed  /// \param Name - The variable name.
1050193326Sed  /// \param Init - The variable initializer; this is also used to
1051314564Sdim  ///   define the type of the variable.
1052276479Sdim  /// \param Section - The section the variable should go into, or empty.
1053193326Sed  /// \param Align - The alignment for the variable, or 0.
1054193326Sed  /// \param AddToUsed - Whether the variable should be added to
1055314564Sdim  ///   "llvm.used".
1056314564Sdim  llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1057314564Sdim                                          ConstantStructBuilder &Init,
1058296417Sdim                                          StringRef Section, CharUnits Align,
1059193326Sed                                          bool AddToUsed);
1060314564Sdim  llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1061314564Sdim                                          llvm::Constant *Init,
1062314564Sdim                                          StringRef Section, CharUnits Align,
1063314564Sdim                                          bool AddToUsed);
1064193326Sed
1065314564Sdim  llvm::GlobalVariable *CreateCStringLiteral(StringRef Name,
1066314564Sdim                                             ObjCLabelType LabelType,
1067314564Sdim                                             bool ForceNonFragileABI = false,
1068314564Sdim                                             bool NullTerminate = true);
1069314564Sdim
1070296417Sdimprotected:
1071223017Sdim  CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1072223017Sdim                                  ReturnValueSlot Return,
1073223017Sdim                                  QualType ResultType,
1074360784Sdim                                  Selector Sel,
1075223017Sdim                                  llvm::Value *Arg0,
1076223017Sdim                                  QualType Arg0Ty,
1077223017Sdim                                  bool IsSuper,
1078223017Sdim                                  const CallArgList &CallArgs,
1079223017Sdim                                  const ObjCMethodDecl *OMD,
1080296417Sdim                                  const ObjCInterfaceDecl *ClassReceiver,
1081223017Sdim                                  const ObjCCommonTypesHelper &ObjCTypes);
1082193326Sed
1083207619Srdivacky  /// EmitImageInfo - Emit the image info marker used to encode some module
1084207619Srdivacky  /// level information.
1085207619Srdivacky  void EmitImageInfo();
1086207619Srdivacky
1087198092Srdivackypublic:
1088198092Srdivacky  CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
1089234353Sdim    CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
1090195099Sed
1091296417Sdim  bool isNonFragileABI() const {
1092296417Sdim    return ObjCABI == 2;
1093296417Sdim  }
1094198092Srdivacky
1095296417Sdim  ConstantAddress GenerateConstantString(const StringLiteral *SL) override;
1096314564Sdim  ConstantAddress GenerateConstantNSString(const StringLiteral *SL);
1097296417Sdim
1098276479Sdim  llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
1099276479Sdim                                 const ObjCContainerDecl *CD=nullptr) override;
1100198092Srdivacky
1101360784Sdim  llvm::Function *GenerateDirectMethod(const ObjCMethodDecl *OMD,
1102360784Sdim                                       const ObjCContainerDecl *CD);
1103360784Sdim
1104360784Sdim  void GenerateDirectMethodPrologue(CodeGenFunction &CGF, llvm::Function *Fn,
1105360784Sdim                                    const ObjCMethodDecl *OMD,
1106360784Sdim                                    const ObjCContainerDecl *CD) override;
1107360784Sdim
1108276479Sdim  void GenerateProtocol(const ObjCProtocolDecl *PD) override;
1109276479Sdim
1110193326Sed  /// GetOrEmitProtocol - Get the protocol object for the given
1111193326Sed  /// declaration, emitting it if necessary. The return value has type
1112193326Sed  /// ProtocolPtrTy.
1113193326Sed  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
1114198092Srdivacky
1115193326Sed  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1116193326Sed  /// object for the given declaration, emitting it if needed. These
1117193326Sed  /// forward references will be filled in with empty bodies if no
1118193326Sed  /// definition is seen. The return value has type ProtocolPtrTy.
1119193326Sed  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
1120314564Sdim
1121314564Sdim  virtual llvm::Constant *getNSConstantStringClassRef() = 0;
1122314564Sdim
1123276479Sdim  llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1124276479Sdim                                     const CGBlockInfo &blockInfo) override;
1125276479Sdim  llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1126276479Sdim                                     const CGBlockInfo &blockInfo) override;
1127344779Sdim  std::string getRCBlockLayoutStr(CodeGen::CodeGenModule &CGM,
1128344779Sdim                                  const CGBlockInfo &blockInfo) override;
1129276479Sdim
1130276479Sdim  llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1131276479Sdim                                   QualType T) override;
1132344779Sdim
1133344779Sdimprivate:
1134344779Sdim  void fillRunSkipBlockVars(CodeGenModule &CGM, const CGBlockInfo &blockInfo);
1135193326Sed};
1136198092Srdivacky
1137314564Sdimnamespace {
1138314564Sdim
1139314564Sdimenum class MethodListType {
1140314564Sdim  CategoryInstanceMethods,
1141314564Sdim  CategoryClassMethods,
1142314564Sdim  InstanceMethods,
1143314564Sdim  ClassMethods,
1144314564Sdim  ProtocolInstanceMethods,
1145314564Sdim  ProtocolClassMethods,
1146314564Sdim  OptionalProtocolInstanceMethods,
1147314564Sdim  OptionalProtocolClassMethods,
1148314564Sdim};
1149314564Sdim
1150314564Sdim/// A convenience class for splitting the methods of a protocol into
1151314564Sdim/// the four interesting groups.
1152314564Sdimclass ProtocolMethodLists {
1153314564Sdimpublic:
1154314564Sdim  enum Kind {
1155314564Sdim    RequiredInstanceMethods,
1156314564Sdim    RequiredClassMethods,
1157314564Sdim    OptionalInstanceMethods,
1158314564Sdim    OptionalClassMethods
1159314564Sdim  };
1160314564Sdim  enum {
1161314564Sdim    NumProtocolMethodLists = 4
1162314564Sdim  };
1163314564Sdim
1164314564Sdim  static MethodListType getMethodListKind(Kind kind) {
1165314564Sdim    switch (kind) {
1166314564Sdim    case RequiredInstanceMethods:
1167314564Sdim      return MethodListType::ProtocolInstanceMethods;
1168314564Sdim    case RequiredClassMethods:
1169314564Sdim      return MethodListType::ProtocolClassMethods;
1170314564Sdim    case OptionalInstanceMethods:
1171314564Sdim      return MethodListType::OptionalProtocolInstanceMethods;
1172314564Sdim    case OptionalClassMethods:
1173314564Sdim      return MethodListType::OptionalProtocolClassMethods;
1174314564Sdim    }
1175314564Sdim    llvm_unreachable("bad kind");
1176314564Sdim  }
1177314564Sdim
1178314564Sdim  SmallVector<const ObjCMethodDecl *, 4> Methods[NumProtocolMethodLists];
1179314564Sdim
1180314564Sdim  static ProtocolMethodLists get(const ObjCProtocolDecl *PD) {
1181314564Sdim    ProtocolMethodLists result;
1182314564Sdim
1183314564Sdim    for (auto MD : PD->methods()) {
1184314564Sdim      size_t index = (2 * size_t(MD->isOptional()))
1185314564Sdim                   + (size_t(MD->isClassMethod()));
1186314564Sdim      result.Methods[index].push_back(MD);
1187314564Sdim    }
1188314564Sdim
1189314564Sdim    return result;
1190314564Sdim  }
1191314564Sdim
1192314564Sdim  template <class Self>
1193314564Sdim  SmallVector<llvm::Constant*, 8> emitExtendedTypesArray(Self *self) const {
1194314564Sdim    // In both ABIs, the method types list is parallel with the
1195314564Sdim    // concatenation of the methods arrays in the following order:
1196314564Sdim    //   instance methods
1197314564Sdim    //   class methods
1198314564Sdim    //   optional instance methods
1199314564Sdim    //   optional class methods
1200314564Sdim    SmallVector<llvm::Constant*, 8> result;
1201314564Sdim
1202314564Sdim    // Methods is already in the correct order for both ABIs.
1203314564Sdim    for (auto &list : Methods) {
1204314564Sdim      for (auto MD : list) {
1205314564Sdim        result.push_back(self->GetMethodVarType(MD, true));
1206314564Sdim      }
1207314564Sdim    }
1208314564Sdim
1209314564Sdim    return result;
1210314564Sdim  }
1211314564Sdim
1212314564Sdim  template <class Self>
1213314564Sdim  llvm::Constant *emitMethodList(Self *self, const ObjCProtocolDecl *PD,
1214314564Sdim                                 Kind kind) const {
1215314564Sdim    return self->emitMethodList(PD->getObjCRuntimeNameAsString(),
1216314564Sdim                                getMethodListKind(kind), Methods[kind]);
1217314564Sdim  }
1218314564Sdim};
1219314564Sdim
1220314564Sdim} // end anonymous namespace
1221314564Sdim
1222193326Sedclass CGObjCMac : public CGObjCCommonMac {
1223193326Sedprivate:
1224314564Sdim  friend ProtocolMethodLists;
1225314564Sdim
1226193326Sed  ObjCTypesHelper ObjCTypes;
1227193326Sed
1228193326Sed  /// EmitModuleInfo - Another marker encoding module level
1229198092Srdivacky  /// information.
1230193326Sed  void EmitModuleInfo();
1231193326Sed
1232193326Sed  /// EmitModuleSymols - Emit module symbols, the list of defined
1233193326Sed  /// classes and categories. The result has type SymtabPtrTy.
1234193326Sed  llvm::Constant *EmitModuleSymbols();
1235193326Sed
1236193326Sed  /// FinishModule - Write out global data structures at the end of
1237193326Sed  /// processing a translation unit.
1238193326Sed  void FinishModule();
1239193326Sed
1240193326Sed  /// EmitClassExtension - Generate the class extension structure used
1241193326Sed  /// to store the weak ivar layout and properties. The return value
1242193326Sed  /// has type ClassExtensionPtrTy.
1243296417Sdim  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID,
1244296417Sdim                                     CharUnits instanceSize,
1245309124Sdim                                     bool hasMRCWeakIvars,
1246314564Sdim                                     bool isMetaclass);
1247193326Sed
1248193326Sed  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1249193326Sed  /// for the given class.
1250249423Sdim  llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1251193326Sed                            const ObjCInterfaceDecl *ID);
1252341825Sdim
1253249423Sdim  llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1254224145Sdim                                  IdentifierInfo *II);
1255276479Sdim
1256276479Sdim  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1257276479Sdim
1258199482Srdivacky  /// EmitSuperClassRef - Emits reference to class's main metadata class.
1259199482Srdivacky  llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
1260193326Sed
1261193326Sed  /// EmitIvarList - Emit the ivar list for the given
1262193326Sed  /// implementation. If ForClass is true the list of class ivars
1263193326Sed  /// (i.e. metaclass ivars) is emitted, otherwise the list of
1264193326Sed  /// interface ivars will be emitted. The return value has type
1265193326Sed  /// IvarListPtrTy.
1266193326Sed  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1267193326Sed                               bool ForClass);
1268198092Srdivacky
1269193326Sed  /// EmitMetaClass - Emit a forward reference to the class structure
1270193326Sed  /// for the metaclass of the given interface. The return value has
1271193326Sed  /// type ClassPtrTy.
1272193326Sed  llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1273193326Sed
1274193326Sed  /// EmitMetaClass - Emit a class structure for the metaclass of the
1275193326Sed  /// given implementation. The return value has type ClassPtrTy.
1276193326Sed  llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1277193326Sed                                llvm::Constant *Protocols,
1278314564Sdim                                ArrayRef<const ObjCMethodDecl *> Methods);
1279198092Srdivacky
1280314564Sdim  void emitMethodConstant(ConstantArrayBuilder &builder,
1281314564Sdim                          const ObjCMethodDecl *MD);
1282198092Srdivacky
1283314564Sdim  void emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
1284314564Sdim                                     const ObjCMethodDecl *MD);
1285193326Sed
1286193326Sed  /// EmitMethodList - Emit the method list for the given
1287193326Sed  /// implementation. The return value has type MethodListPtrTy.
1288314564Sdim  llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1289314564Sdim                                 ArrayRef<const ObjCMethodDecl *> Methods);
1290193326Sed
1291193326Sed  /// GetOrEmitProtocol - Get the protocol object for the given
1292193326Sed  /// declaration, emitting it if necessary. The return value has type
1293193326Sed  /// ProtocolPtrTy.
1294276479Sdim  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1295193326Sed
1296193326Sed  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1297193326Sed  /// object for the given declaration, emitting it if needed. These
1298193326Sed  /// forward references will be filled in with empty bodies if no
1299193326Sed  /// definition is seen. The return value has type ProtocolPtrTy.
1300276479Sdim  llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1301193326Sed
1302193326Sed  /// EmitProtocolExtension - Generate the protocol extension
1303193326Sed  /// structure used to store optional instance and class methods, and
1304193326Sed  /// protocol properties. The return value has type
1305193326Sed  /// ProtocolExtensionPtrTy.
1306193326Sed  llvm::Constant *
1307193326Sed  EmitProtocolExtension(const ObjCProtocolDecl *PD,
1308314564Sdim                        const ProtocolMethodLists &methodLists);
1309193326Sed
1310193326Sed  /// EmitProtocolList - Generate the list of referenced
1311193326Sed  /// protocols. The return value has type ProtocolListPtrTy.
1312226633Sdim  llvm::Constant *EmitProtocolList(Twine Name,
1313193326Sed                                   ObjCProtocolDecl::protocol_iterator begin,
1314193326Sed                                   ObjCProtocolDecl::protocol_iterator end);
1315193326Sed
1316193326Sed  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1317193326Sed  /// for the given selector.
1318296417Sdim  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1319360784Sdim  Address EmitSelectorAddr(Selector Sel);
1320198092Srdivacky
1321198092Srdivackypublic:
1322193326Sed  CGObjCMac(CodeGen::CodeGenModule &cgm);
1323193326Sed
1324314564Sdim  llvm::Constant *getNSConstantStringClassRef() override;
1325314564Sdim
1326276479Sdim  llvm::Function *ModuleInitFunction() override;
1327198092Srdivacky
1328276479Sdim  CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1329276479Sdim                                      ReturnValueSlot Return,
1330276479Sdim                                      QualType ResultType,
1331276479Sdim                                      Selector Sel, llvm::Value *Receiver,
1332276479Sdim                                      const CallArgList &CallArgs,
1333276479Sdim                                      const ObjCInterfaceDecl *Class,
1334276479Sdim                                      const ObjCMethodDecl *Method) override;
1335193326Sed
1336276479Sdim  CodeGen::RValue
1337193326Sed  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1338276479Sdim                           ReturnValueSlot Return, QualType ResultType,
1339276479Sdim                           Selector Sel, const ObjCInterfaceDecl *Class,
1340276479Sdim                           bool isCategoryImpl, llvm::Value *Receiver,
1341276479Sdim                           bool IsClassMessage, const CallArgList &CallArgs,
1342276479Sdim                           const ObjCMethodDecl *Method) override;
1343198092Srdivacky
1344276479Sdim  llvm::Value *GetClass(CodeGenFunction &CGF,
1345276479Sdim                        const ObjCInterfaceDecl *ID) override;
1346193326Sed
1347296417Sdim  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override;
1348296417Sdim  Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override;
1349193326Sed
1350193326Sed  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1351193326Sed  /// untyped one.
1352276479Sdim  llvm::Value *GetSelector(CodeGenFunction &CGF,
1353276479Sdim                           const ObjCMethodDecl *Method) override;
1354193326Sed
1355276479Sdim  llvm::Constant *GetEHType(QualType T) override;
1356212904Sdim
1357276479Sdim  void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1358193326Sed
1359276479Sdim  void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1360193326Sed
1361276479Sdim  void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1362234353Sdim
1363276479Sdim  llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1364276479Sdim                                   const ObjCProtocolDecl *PD) override;
1365198092Srdivacky
1366353358Sdim  llvm::FunctionCallee GetPropertyGetFunction() override;
1367353358Sdim  llvm::FunctionCallee GetPropertySetFunction() override;
1368353358Sdim  llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
1369353358Sdim                                                       bool copy) override;
1370353358Sdim  llvm::FunctionCallee GetGetStructFunction() override;
1371353358Sdim  llvm::FunctionCallee GetSetStructFunction() override;
1372353358Sdim  llvm::FunctionCallee GetCppAtomicObjectGetFunction() override;
1373353358Sdim  llvm::FunctionCallee GetCppAtomicObjectSetFunction() override;
1374353358Sdim  llvm::FunctionCallee EnumerationMutationFunction() override;
1375198092Srdivacky
1376276479Sdim  void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1377276479Sdim                   const ObjCAtTryStmt &S) override;
1378276479Sdim  void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1379276479Sdim                            const ObjCAtSynchronizedStmt &S) override;
1380210299Sed  void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1381276479Sdim  void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1382276479Sdim                     bool ClearInsertionPoint=true) override;
1383276479Sdim  llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1384296417Sdim                                 Address AddrWeakObj) override;
1385276479Sdim  void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1386296417Sdim                          llvm::Value *src, Address dst) override;
1387276479Sdim  void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1388296417Sdim                            llvm::Value *src, Address dest,
1389276479Sdim                            bool threadlocal = false) override;
1390276479Sdim  void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1391296417Sdim                          llvm::Value *src, Address dest,
1392276479Sdim                          llvm::Value *ivarOffset) override;
1393276479Sdim  void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1394296417Sdim                                llvm::Value *src, Address dest) override;
1395276479Sdim  void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1396296417Sdim                                Address dest, Address src,
1397276479Sdim                                llvm::Value *size) override;
1398198092Srdivacky
1399276479Sdim  LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1400276479Sdim                              llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1401276479Sdim                              unsigned CVRQualifiers) override;
1402276479Sdim  llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1403276479Sdim                              const ObjCInterfaceDecl *Interface,
1404276479Sdim                              const ObjCIvarDecl *Ivar) override;
1405193326Sed};
1406198092Srdivacky
1407193326Sedclass CGObjCNonFragileABIMac : public CGObjCCommonMac {
1408193326Sedprivate:
1409314564Sdim  friend ProtocolMethodLists;
1410193326Sed  ObjCNonFragileABITypesHelper ObjCTypes;
1411193326Sed  llvm::GlobalVariable* ObjCEmptyCacheVar;
1412314564Sdim  llvm::Constant* ObjCEmptyVtableVar;
1413198092Srdivacky
1414193326Sed  /// SuperClassReferences - uniqued super class references.
1415193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1416198092Srdivacky
1417193326Sed  /// MetaClassReferences - uniqued meta class references.
1418193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1419193326Sed
1420193326Sed  /// EHTypeReferences - uniqued class ehtype references.
1421193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1422198092Srdivacky
1423223017Sdim  /// VTableDispatchMethods - List of methods for which we generate
1424223017Sdim  /// vtable-based message dispatch.
1425223017Sdim  llvm::DenseSet<Selector> VTableDispatchMethods;
1426198092Srdivacky
1427199482Srdivacky  /// DefinedMetaClasses - List of defined meta-classes.
1428199482Srdivacky  std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1429341825Sdim
1430223017Sdim  /// isVTableDispatchedSelector - Returns true if SEL is a
1431223017Sdim  /// vtable-based selector.
1432223017Sdim  bool isVTableDispatchedSelector(Selector Sel);
1433198092Srdivacky
1434193326Sed  /// FinishNonFragileABIModule - Write out global data structures at the end of
1435193326Sed  /// processing a translation unit.
1436193326Sed  void FinishNonFragileABIModule();
1437193326Sed
1438193326Sed  /// AddModuleClassList - Add the given list of class pointers to the
1439193326Sed  /// module with the provided symbol and section names.
1440309124Sdim  void AddModuleClassList(ArrayRef<llvm::GlobalValue *> Container,
1441309124Sdim                          StringRef SymbolName, StringRef SectionName);
1442193326Sed
1443198092Srdivacky  llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1444198092Srdivacky                                              unsigned InstanceStart,
1445198092Srdivacky                                              unsigned InstanceSize,
1446198092Srdivacky                                              const ObjCImplementationDecl *ID);
1447314564Sdim  llvm::GlobalVariable *BuildClassObject(const ObjCInterfaceDecl *CI,
1448314564Sdim                                         bool isMetaclass,
1449314564Sdim                                         llvm::Constant *IsAGV,
1450314564Sdim                                         llvm::Constant *SuperClassGV,
1451314564Sdim                                         llvm::Constant *ClassRoGV,
1452314564Sdim                                         bool HiddenVisibility);
1453198092Srdivacky
1454314564Sdim  void emitMethodConstant(ConstantArrayBuilder &builder,
1455314564Sdim                            const ObjCMethodDecl *MD,
1456314564Sdim                            bool forProtocol);
1457198092Srdivacky
1458314564Sdim  /// Emit the method list for the given implementation. The return value
1459314564Sdim  /// has type MethodListnfABITy.
1460314564Sdim  llvm::Constant *emitMethodList(Twine Name, MethodListType MLT,
1461314564Sdim                                 ArrayRef<const ObjCMethodDecl *> Methods);
1462198092Srdivacky
1463193326Sed  /// EmitIvarList - Emit the ivar list for the given
1464193326Sed  /// implementation. If ForClass is true the list of class ivars
1465193326Sed  /// (i.e. metaclass ivars) is emitted, otherwise the list of
1466193326Sed  /// interface ivars will be emitted. The return value has type
1467193326Sed  /// IvarListnfABIPtrTy.
1468193326Sed  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1469198092Srdivacky
1470193326Sed  llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1471193326Sed                                    const ObjCIvarDecl *Ivar,
1472193326Sed                                    unsigned long int offset);
1473198092Srdivacky
1474193326Sed  /// GetOrEmitProtocol - Get the protocol object for the given
1475193326Sed  /// declaration, emitting it if necessary. The return value has type
1476193326Sed  /// ProtocolPtrTy.
1477276479Sdim  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
1478198092Srdivacky
1479193326Sed  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1480193326Sed  /// object for the given declaration, emitting it if needed. These
1481193326Sed  /// forward references will be filled in with empty bodies if no
1482193326Sed  /// definition is seen. The return value has type ProtocolPtrTy.
1483276479Sdim  llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
1484198092Srdivacky
1485193326Sed  /// EmitProtocolList - Generate the list of referenced
1486193326Sed  /// protocols. The return value has type ProtocolListPtrTy.
1487226633Sdim  llvm::Constant *EmitProtocolList(Twine Name,
1488193326Sed                                   ObjCProtocolDecl::protocol_iterator begin,
1489193326Sed                                   ObjCProtocolDecl::protocol_iterator end);
1490198092Srdivacky
1491223017Sdim  CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1492223017Sdim                                        ReturnValueSlot Return,
1493223017Sdim                                        QualType ResultType,
1494223017Sdim                                        Selector Sel,
1495223017Sdim                                        llvm::Value *Receiver,
1496223017Sdim                                        QualType Arg0Ty,
1497223017Sdim                                        bool IsSuper,
1498223017Sdim                                        const CallArgList &CallArgs,
1499223017Sdim                                        const ObjCMethodDecl *Method);
1500341825Sdim
1501193326Sed  /// GetClassGlobal - Return the global variable for the Objective-C
1502193326Sed  /// class of the given name.
1503314564Sdim  llvm::Constant *GetClassGlobal(StringRef Name,
1504314564Sdim                                 ForDefinition_t IsForDefinition,
1505314564Sdim                                 bool Weak = false, bool DLLImport = false);
1506314564Sdim  llvm::Constant *GetClassGlobal(const ObjCInterfaceDecl *ID,
1507314564Sdim                                 bool isMetaclass,
1508314564Sdim                                 ForDefinition_t isForDefinition);
1509276479Sdim
1510353358Sdim  llvm::Constant *GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID);
1511353358Sdim
1512353358Sdim  llvm::Value *EmitLoadOfClassRef(CodeGenFunction &CGF,
1513353358Sdim                                  const ObjCInterfaceDecl *ID,
1514353358Sdim                                  llvm::GlobalVariable *Entry);
1515353358Sdim
1516193326Sed  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1517193326Sed  /// for the given class reference.
1518249423Sdim  llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1519193326Sed                            const ObjCInterfaceDecl *ID);
1520341825Sdim
1521249423Sdim  llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1522314564Sdim                                  IdentifierInfo *II,
1523276479Sdim                                  const ObjCInterfaceDecl *ID);
1524198092Srdivacky
1525276479Sdim  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
1526276479Sdim
1527193326Sed  /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1528193326Sed  /// for the given super class reference.
1529249423Sdim  llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1530198092Srdivacky                                 const ObjCInterfaceDecl *ID);
1531198092Srdivacky
1532193326Sed  /// EmitMetaClassRef - Return a Value * of the address of _class_t
1533193326Sed  /// meta-data
1534249423Sdim  llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1535276479Sdim                                const ObjCInterfaceDecl *ID, bool Weak);
1536193326Sed
1537193326Sed  /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1538193326Sed  /// the given ivar.
1539193326Sed  ///
1540193326Sed  llvm::GlobalVariable * ObjCIvarOffsetVariable(
1541198092Srdivacky    const ObjCInterfaceDecl *ID,
1542198092Srdivacky    const ObjCIvarDecl *Ivar);
1543198092Srdivacky
1544193326Sed  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1545193326Sed  /// for the given selector.
1546296417Sdim  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel);
1547360784Sdim  Address EmitSelectorAddr(Selector Sel);
1548193326Sed
1549193326Sed  /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1550193326Sed  /// interface. The return value has type EHTypePtrTy.
1551212904Sdim  llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1552314564Sdim                                     ForDefinition_t IsForDefinition);
1553193326Sed
1554309124Sdim  StringRef getMetaclassSymbolPrefix() const { return "OBJC_METACLASS_$_"; }
1555198092Srdivacky
1556309124Sdim  StringRef getClassSymbolPrefix() const { return "OBJC_CLASS_$_"; }
1557193326Sed
1558193326Sed  void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1559193326Sed                        uint32_t &InstanceStart,
1560193326Sed                        uint32_t &InstanceSize);
1561198092Srdivacky
1562193326Sed  // Shamelessly stolen from Analysis/CFRefCount.cpp
1563193326Sed  Selector GetNullarySelector(const char* name) const {
1564193326Sed    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1565193326Sed    return CGM.getContext().Selectors.getSelector(0, &II);
1566193326Sed  }
1567198092Srdivacky
1568193326Sed  Selector GetUnarySelector(const char* name) const {
1569193326Sed    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1570193326Sed    return CGM.getContext().Selectors.getSelector(1, &II);
1571193326Sed  }
1572193326Sed
1573193326Sed  /// ImplementationIsNonLazy - Check whether the given category or
1574193326Sed  /// class implementation is "non-lazy".
1575193326Sed  bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1576193326Sed
1577249423Sdim  bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
1578249423Sdim                                   const ObjCIvarDecl *IV) {
1579276479Sdim    // Annotate the load as an invariant load iff inside an instance method
1580276479Sdim    // and ivar belongs to instance method's class and one of its super class.
1581276479Sdim    // This check is needed because the ivar offset is a lazily
1582249423Sdim    // initialised value that may depend on objc_msgSend to perform a fixup on
1583249423Sdim    // the first message dispatch.
1584249423Sdim    //
1585249423Sdim    // An additional opportunity to mark the load as invariant arises when the
1586249423Sdim    // base of the ivar access is a parameter to an Objective C method.
1587249423Sdim    // However, because the parameters are not available in the current
1588249423Sdim    // interface, we cannot perform this check.
1589360784Sdim    //
1590360784Sdim    // Note that for direct methods, because objc_msgSend is skipped,
1591360784Sdim    // and that the method may be inlined, this optimization actually
1592360784Sdim    // can't be performed.
1593276479Sdim    if (const ObjCMethodDecl *MD =
1594276479Sdim          dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
1595360784Sdim      if (MD->isInstanceMethod() && !MD->isDirectMethod())
1596276479Sdim        if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
1597276479Sdim          return IV->getContainingInterface()->isSuperClassOf(ID);
1598249423Sdim    return false;
1599249423Sdim  }
1600249423Sdim
1601353358Sdim  bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
1602353358Sdim    // NSObject is a fixed size. If we can see the @implementation of a class
1603353358Sdim    // which inherits from NSObject then we know that all it's offsets also must
1604353358Sdim    // be fixed. FIXME: Can we do this if see a chain of super classes with
1605353358Sdim    // implementations leading to NSObject?
1606353358Sdim    return ID->getImplementation() && ID->getSuperClass() &&
1607353358Sdim           ID->getSuperClass()->getName() == "NSObject";
1608353358Sdim  }
1609353358Sdim
1610193326Sedpublic:
1611193326Sed  CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1612314564Sdim
1613314564Sdim  llvm::Constant *getNSConstantStringClassRef() override;
1614314564Sdim
1615276479Sdim  llvm::Function *ModuleInitFunction() override;
1616198092Srdivacky
1617276479Sdim  CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1618276479Sdim                                      ReturnValueSlot Return,
1619276479Sdim                                      QualType ResultType, Selector Sel,
1620276479Sdim                                      llvm::Value *Receiver,
1621276479Sdim                                      const CallArgList &CallArgs,
1622276479Sdim                                      const ObjCInterfaceDecl *Class,
1623276479Sdim                                      const ObjCMethodDecl *Method) override;
1624198092Srdivacky
1625276479Sdim  CodeGen::RValue
1626193326Sed  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1627276479Sdim                           ReturnValueSlot Return, QualType ResultType,
1628276479Sdim                           Selector Sel, const ObjCInterfaceDecl *Class,
1629276479Sdim                           bool isCategoryImpl, llvm::Value *Receiver,
1630276479Sdim                           bool IsClassMessage, const CallArgList &CallArgs,
1631276479Sdim                           const ObjCMethodDecl *Method) override;
1632198092Srdivacky
1633276479Sdim  llvm::Value *GetClass(CodeGenFunction &CGF,
1634276479Sdim                        const ObjCInterfaceDecl *ID) override;
1635198092Srdivacky
1636296417Sdim  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel) override
1637296417Sdim    { return EmitSelector(CGF, Sel); }
1638296417Sdim  Address GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) override
1639360784Sdim    { return EmitSelectorAddr(Sel); }
1640193326Sed
1641193326Sed  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1642193326Sed  /// untyped one.
1643276479Sdim  llvm::Value *GetSelector(CodeGenFunction &CGF,
1644276479Sdim                           const ObjCMethodDecl *Method) override
1645249423Sdim    { return EmitSelector(CGF, Method->getSelector()); }
1646198092Srdivacky
1647276479Sdim  void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
1648198092Srdivacky
1649276479Sdim  void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
1650234353Sdim
1651276479Sdim  void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
1652234353Sdim
1653276479Sdim  llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1654276479Sdim                                   const ObjCProtocolDecl *PD) override;
1655198092Srdivacky
1656276479Sdim  llvm::Constant *GetEHType(QualType T) override;
1657212904Sdim
1658353358Sdim  llvm::FunctionCallee GetPropertyGetFunction() override {
1659193326Sed    return ObjCTypes.getGetPropertyFn();
1660193326Sed  }
1661353358Sdim  llvm::FunctionCallee GetPropertySetFunction() override {
1662198092Srdivacky    return ObjCTypes.getSetPropertyFn();
1663193326Sed  }
1664276479Sdim
1665353358Sdim  llvm::FunctionCallee GetOptimizedPropertySetFunction(bool atomic,
1666353358Sdim                                                       bool copy) override {
1667234353Sdim    return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1668234353Sdim  }
1669276479Sdim
1670353358Sdim  llvm::FunctionCallee GetSetStructFunction() override {
1671207619Srdivacky    return ObjCTypes.getCopyStructFn();
1672207619Srdivacky  }
1673309124Sdim
1674353358Sdim  llvm::FunctionCallee GetGetStructFunction() override {
1675218893Sdim    return ObjCTypes.getCopyStructFn();
1676218893Sdim  }
1677309124Sdim
1678353358Sdim  llvm::FunctionCallee GetCppAtomicObjectSetFunction() override {
1679234353Sdim    return ObjCTypes.getCppAtomicObjectFunction();
1680234353Sdim  }
1681309124Sdim
1682353358Sdim  llvm::FunctionCallee GetCppAtomicObjectGetFunction() override {
1683249423Sdim    return ObjCTypes.getCppAtomicObjectFunction();
1684249423Sdim  }
1685276479Sdim
1686353358Sdim  llvm::FunctionCallee EnumerationMutationFunction() override {
1687193326Sed    return ObjCTypes.getEnumerationMutationFn();
1688193326Sed  }
1689198092Srdivacky
1690276479Sdim  void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1691276479Sdim                   const ObjCAtTryStmt &S) override;
1692276479Sdim  void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1693276479Sdim                            const ObjCAtSynchronizedStmt &S) override;
1694276479Sdim  void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
1695276479Sdim                     bool ClearInsertionPoint=true) override;
1696276479Sdim  llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1697296417Sdim                                 Address AddrWeakObj) override;
1698276479Sdim  void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1699296417Sdim                          llvm::Value *src, Address edst) override;
1700276479Sdim  void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1701296417Sdim                            llvm::Value *src, Address dest,
1702276479Sdim                            bool threadlocal = false) override;
1703276479Sdim  void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1704296417Sdim                          llvm::Value *src, Address dest,
1705276479Sdim                          llvm::Value *ivarOffset) override;
1706276479Sdim  void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1707296417Sdim                                llvm::Value *src, Address dest) override;
1708276479Sdim  void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1709296417Sdim                                Address dest, Address src,
1710276479Sdim                                llvm::Value *size) override;
1711276479Sdim  LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
1712276479Sdim                              llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
1713276479Sdim                              unsigned CVRQualifiers) override;
1714276479Sdim  llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1715276479Sdim                              const ObjCInterfaceDecl *Interface,
1716276479Sdim                              const ObjCIvarDecl *Ivar) override;
1717193326Sed};
1718198092Srdivacky
1719223017Sdim/// A helper class for performing the null-initialization of a return
1720223017Sdim/// value.
1721223017Sdimstruct NullReturnState {
1722223017Sdim  llvm::BasicBlock *NullBB;
1723276479Sdim  NullReturnState() : NullBB(nullptr) {}
1724223017Sdim
1725249423Sdim  /// Perform a null-check of the given receiver.
1726223017Sdim  void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1727249423Sdim    // Make blocks for the null-receiver and call edges.
1728249423Sdim    NullBB = CGF.createBasicBlock("msgSend.null-receiver");
1729249423Sdim    llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1730223017Sdim
1731223017Sdim    // Check for a null receiver and, if there is one, jump to the
1732249423Sdim    // null-receiver block.  There's no point in trying to avoid it:
1733249423Sdim    // we're always going to put *something* there, because otherwise
1734249423Sdim    // we shouldn't have done this null-check in the first place.
1735223017Sdim    llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1736223017Sdim    CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1737223017Sdim
1738223017Sdim    // Otherwise, start performing the call.
1739223017Sdim    CGF.EmitBlock(callBB);
1740223017Sdim  }
1741223017Sdim
1742249423Sdim  /// Complete the null-return operation.  It is valid to call this
1743249423Sdim  /// regardless of whether 'init' has been called.
1744321369Sdim  RValue complete(CodeGenFunction &CGF,
1745321369Sdim                  ReturnValueSlot returnSlot,
1746321369Sdim                  RValue result,
1747321369Sdim                  QualType resultType,
1748234353Sdim                  const CallArgList &CallArgs,
1749234353Sdim                  const ObjCMethodDecl *Method) {
1750249423Sdim    // If we never had to do a null-check, just use the raw result.
1751223017Sdim    if (!NullBB) return result;
1752249423Sdim
1753249423Sdim    // The continuation block.  This will be left null if we don't have an
1754249423Sdim    // IP, which can happen if the method we're calling is marked noreturn.
1755276479Sdim    llvm::BasicBlock *contBB = nullptr;
1756276479Sdim
1757249423Sdim    // Finish the call path.
1758249423Sdim    llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
1759249423Sdim    if (callBB) {
1760249423Sdim      contBB = CGF.createBasicBlock("msgSend.cont");
1761249423Sdim      CGF.Builder.CreateBr(contBB);
1762234353Sdim    }
1763223017Sdim
1764249423Sdim    // Okay, start emitting the null-receiver block.
1765223017Sdim    CGF.EmitBlock(NullBB);
1766341825Sdim
1767249423Sdim    // Release any consumed arguments we've got.
1768234353Sdim    if (Method) {
1769234353Sdim      CallArgList::const_iterator I = CallArgs.begin();
1770234353Sdim      for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1771234353Sdim           e = Method->param_end(); i != e; ++i, ++I) {
1772234353Sdim        const ParmVarDecl *ParamDecl = (*i);
1773234353Sdim        if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1774341825Sdim          RValue RV = I->getRValue(CGF);
1775341825Sdim          assert(RV.isScalar() &&
1776234353Sdim                 "NullReturnState::complete - arg not on object");
1777249423Sdim          CGF.EmitARCRelease(RV.getScalarVal(), ARCImpreciseLifetime);
1778234353Sdim        }
1779234353Sdim      }
1780234353Sdim    }
1781249423Sdim
1782249423Sdim    // The phi code below assumes that we haven't needed any control flow yet.
1783249423Sdim    assert(CGF.Builder.GetInsertBlock() == NullBB);
1784249423Sdim
1785249423Sdim    // If we've got a void return, just jump to the continuation block.
1786249423Sdim    if (result.isScalar() && resultType->isVoidType()) {
1787249423Sdim      // No jumps required if the message-send was noreturn.
1788249423Sdim      if (contBB) CGF.EmitBlock(contBB);
1789249423Sdim      return result;
1790249423Sdim    }
1791249423Sdim
1792249423Sdim    // If we've got a scalar return, build a phi.
1793234353Sdim    if (result.isScalar()) {
1794249423Sdim      // Derive the null-initialization value.
1795249423Sdim      llvm::Constant *null = CGF.CGM.EmitNullConstant(resultType);
1796249423Sdim
1797249423Sdim      // If no join is necessary, just flow out.
1798249423Sdim      if (!contBB) return RValue::get(null);
1799249423Sdim
1800249423Sdim      // Otherwise, build a phi.
1801234353Sdim      CGF.EmitBlock(contBB);
1802249423Sdim      llvm::PHINode *phi = CGF.Builder.CreatePHI(null->getType(), 2);
1803249423Sdim      phi->addIncoming(result.getScalarVal(), callBB);
1804249423Sdim      phi->addIncoming(null, NullBB);
1805249423Sdim      return RValue::get(phi);
1806234353Sdim    }
1807249423Sdim
1808249423Sdim    // If we've got an aggregate return, null the buffer out.
1809249423Sdim    // FIXME: maybe we should be doing things differently for all the
1810249423Sdim    // cases where the ABI has us returning (1) non-agg values in
1811249423Sdim    // memory or (2) agg values in registers.
1812249423Sdim    if (result.isAggregate()) {
1813234353Sdim      assert(result.isAggregate() && "null init of non-aggregate result?");
1814321369Sdim      if (!returnSlot.isUnused())
1815321369Sdim        CGF.EmitNullInitialization(result.getAggregateAddress(), resultType);
1816249423Sdim      if (contBB) CGF.EmitBlock(contBB);
1817234353Sdim      return result;
1818234353Sdim    }
1819223017Sdim
1820249423Sdim    // Complex types.
1821223017Sdim    CGF.EmitBlock(contBB);
1822249423Sdim    CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();
1823249423Sdim
1824249423Sdim    // Find the scalar type and its zero value.
1825249423Sdim    llvm::Type *scalarTy = callResult.first->getType();
1826249423Sdim    llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1827249423Sdim
1828249423Sdim    // Build phis for both coordinates.
1829249423Sdim    llvm::PHINode *real = CGF.Builder.CreatePHI(scalarTy, 2);
1830249423Sdim    real->addIncoming(callResult.first, callBB);
1831249423Sdim    real->addIncoming(scalarZero, NullBB);
1832249423Sdim    llvm::PHINode *imag = CGF.Builder.CreatePHI(scalarTy, 2);
1833249423Sdim    imag->addIncoming(callResult.second, callBB);
1834249423Sdim    imag->addIncoming(scalarZero, NullBB);
1835249423Sdim    return RValue::getComplex(real, imag);
1836223017Sdim  }
1837223017Sdim};
1838223017Sdim
1839193326Sed} // end anonymous namespace
1840193326Sed
1841193326Sed/* *** Helper Functions *** */
1842193326Sed
1843193326Sed/// getConstantGEP() - Help routine to construct simple GEPs.
1844198092Srdivackystatic llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1845288943Sdim                                      llvm::GlobalVariable *C, unsigned idx0,
1846193326Sed                                      unsigned idx1) {
1847193326Sed  llvm::Value *Idxs[] = {
1848198092Srdivacky    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1849198092Srdivacky    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1850193326Sed  };
1851288943Sdim  return llvm::ConstantExpr::getGetElementPtr(C->getValueType(), C, Idxs);
1852193326Sed}
1853193326Sed
1854193326Sed/// hasObjCExceptionAttribute - Return true if this class or any super
1855193326Sed/// class has the __objc_exception__ attribute.
1856198092Srdivackystatic bool hasObjCExceptionAttribute(ASTContext &Context,
1857194613Sed                                      const ObjCInterfaceDecl *OID) {
1858195341Sed  if (OID->hasAttr<ObjCExceptionAttr>())
1859193326Sed    return true;
1860193326Sed  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1861194613Sed    return hasObjCExceptionAttribute(Context, Super);
1862193326Sed  return false;
1863193326Sed}
1864193326Sed
1865353358Sdimstatic llvm::GlobalValue::LinkageTypes
1866353358SdimgetLinkageTypeForObjCMetadata(CodeGenModule &CGM, StringRef Section) {
1867353358Sdim  if (CGM.getTriple().isOSBinFormatMachO() &&
1868353358Sdim      (Section.empty() || Section.startswith("__DATA")))
1869353358Sdim    return llvm::GlobalValue::InternalLinkage;
1870353358Sdim  return llvm::GlobalValue::PrivateLinkage;
1871353358Sdim}
1872353358Sdim
1873353358Sdim/// A helper function to create an internal or private global variable.
1874353358Sdimstatic llvm::GlobalVariable *
1875353358SdimfinishAndCreateGlobal(ConstantInitBuilder::StructBuilder &Builder,
1876353358Sdim                     const llvm::Twine &Name, CodeGenModule &CGM) {
1877353358Sdim  std::string SectionName;
1878353358Sdim  if (CGM.getTriple().isOSBinFormatMachO())
1879353358Sdim    SectionName = "__DATA, __objc_const";
1880353358Sdim  auto *GV = Builder.finishAndCreateGlobal(
1881353358Sdim      Name, CGM.getPointerAlign(), /*constant*/ false,
1882353358Sdim      getLinkageTypeForObjCMetadata(CGM, SectionName));
1883353358Sdim  GV->setSection(SectionName);
1884353358Sdim  return GV;
1885353358Sdim}
1886353358Sdim
1887193326Sed/* *** CGObjCMac Public Interface *** */
1888198092Srdivacky
1889193326SedCGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1890198092Srdivacky                                                    ObjCTypes(cgm) {
1891193326Sed  ObjCABI = 1;
1892198092Srdivacky  EmitImageInfo();
1893193326Sed}
1894193326Sed
1895193326Sed/// GetClass - Return a reference to the class for the given interface
1896193326Sed/// decl.
1897249423Sdimllvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
1898193326Sed                                 const ObjCInterfaceDecl *ID) {
1899249423Sdim  return EmitClassRef(CGF, ID);
1900193326Sed}
1901193326Sed
1902193326Sed/// GetSelector - Return the pointer to the unique'd string for this selector.
1903296417Sdimllvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel) {
1904296417Sdim  return EmitSelector(CGF, Sel);
1905193326Sed}
1906296417SdimAddress CGObjCMac::GetAddrOfSelector(CodeGenFunction &CGF, Selector Sel) {
1907360784Sdim  return EmitSelectorAddr(Sel);
1908296417Sdim}
1909249423Sdimllvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
1910198092Srdivacky                                    *Method) {
1911249423Sdim  return EmitSelector(CGF, Method->getSelector());
1912193326Sed}
1913193326Sed
1914212904Sdimllvm::Constant *CGObjCMac::GetEHType(QualType T) {
1915224145Sdim  if (T->isObjCIdType() ||
1916224145Sdim      T->isObjCQualifiedIdType()) {
1917224145Sdim    return CGM.GetAddrOfRTTIDescriptor(
1918226633Sdim              CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1919224145Sdim  }
1920224145Sdim  if (T->isObjCClassType() ||
1921224145Sdim      T->isObjCQualifiedClassType()) {
1922224145Sdim    return CGM.GetAddrOfRTTIDescriptor(
1923226633Sdim             CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1924224145Sdim  }
1925224145Sdim  if (T->isObjCObjectPointerType())
1926224145Sdim    return CGM.GetAddrOfRTTIDescriptor(T,  /*ForEH=*/true);
1927341825Sdim
1928212904Sdim  llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1929212904Sdim}
1930212904Sdim
1931193326Sed/// Generate a constant CFString object.
1932198092Srdivacky/*
1933198092Srdivacky  struct __builtin_CFString {
1934198092Srdivacky  const int *isa; // point to __CFConstantStringClassReference
1935198092Srdivacky  int flags;
1936198092Srdivacky  const char *str;
1937198092Srdivacky  long length;
1938198092Srdivacky  };
1939193326Sed*/
1940193326Sed
1941207619Srdivacky/// or Generate a constant NSString object.
1942207619Srdivacky/*
1943207619Srdivacky   struct __builtin_NSString {
1944207619Srdivacky     const int *isa; // point to __NSConstantStringClassReference
1945207619Srdivacky     const char *str;
1946207619Srdivacky     unsigned int length;
1947207619Srdivacky   };
1948207619Srdivacky*/
1949207619Srdivacky
1950314564SdimConstantAddress
1951314564SdimCGObjCCommonMac::GenerateConstantString(const StringLiteral *SL) {
1952314564Sdim  return (!CGM.getLangOpts().NoConstantCFStrings
1953314564Sdim            ? CGM.GetAddrOfConstantCFString(SL)
1954314564Sdim            : GenerateConstantNSString(SL));
1955193326Sed}
1956193326Sed
1957314564Sdimstatic llvm::StringMapEntry<llvm::GlobalVariable *> &
1958314564SdimGetConstantStringEntry(llvm::StringMap<llvm::GlobalVariable *> &Map,
1959314564Sdim                       const StringLiteral *Literal, unsigned &StringLength) {
1960314564Sdim  StringRef String = Literal->getString();
1961314564Sdim  StringLength = String.size();
1962314564Sdim  return *Map.insert(std::make_pair(String, nullptr)).first;
1963314564Sdim}
1964314564Sdim
1965314564Sdimllvm::Constant *CGObjCMac::getNSConstantStringClassRef() {
1966314564Sdim  if (llvm::Value *V = ConstantStringClassRef)
1967314564Sdim    return cast<llvm::Constant>(V);
1968314564Sdim
1969314564Sdim  auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1970314564Sdim  std::string str =
1971314564Sdim    StringClass.empty() ? "_NSConstantStringClassReference"
1972314564Sdim                        : "_" + StringClass + "ClassReference";
1973314564Sdim
1974314564Sdim  llvm::Type *PTy = llvm::ArrayType::get(CGM.IntTy, 0);
1975314564Sdim  auto GV = CGM.CreateRuntimeVariable(PTy, str);
1976314564Sdim  auto V = llvm::ConstantExpr::getBitCast(GV, CGM.IntTy->getPointerTo());
1977314564Sdim  ConstantStringClassRef = V;
1978314564Sdim  return V;
1979314564Sdim}
1980314564Sdim
1981314564Sdimllvm::Constant *CGObjCNonFragileABIMac::getNSConstantStringClassRef() {
1982314564Sdim  if (llvm::Value *V = ConstantStringClassRef)
1983314564Sdim    return cast<llvm::Constant>(V);
1984314564Sdim
1985314564Sdim  auto &StringClass = CGM.getLangOpts().ObjCConstantStringClass;
1986341825Sdim  std::string str =
1987341825Sdim    StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
1988314564Sdim                        : "OBJC_CLASS_$_" + StringClass;
1989353358Sdim  llvm::Constant *GV = GetClassGlobal(str, NotForDefinition);
1990314564Sdim
1991314564Sdim  // Make sure the result is of the correct type.
1992314564Sdim  auto V = llvm::ConstantExpr::getBitCast(GV, CGM.IntTy->getPointerTo());
1993314564Sdim
1994314564Sdim  ConstantStringClassRef = V;
1995314564Sdim  return V;
1996314564Sdim}
1997314564Sdim
1998314564SdimConstantAddress
1999314564SdimCGObjCCommonMac::GenerateConstantNSString(const StringLiteral *Literal) {
2000314564Sdim  unsigned StringLength = 0;
2001314564Sdim  llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
2002314564Sdim    GetConstantStringEntry(NSConstantStringMap, Literal, StringLength);
2003314564Sdim
2004314564Sdim  if (auto *C = Entry.second)
2005314564Sdim    return ConstantAddress(C, CharUnits::fromQuantity(C->getAlignment()));
2006314564Sdim
2007314564Sdim  // If we don't already have it, get _NSConstantStringClassReference.
2008314564Sdim  llvm::Constant *Class = getNSConstantStringClassRef();
2009314564Sdim
2010314564Sdim  // If we don't already have it, construct the type for a constant NSString.
2011314564Sdim  if (!NSConstantStringType) {
2012314564Sdim    NSConstantStringType =
2013314564Sdim      llvm::StructType::create({
2014314564Sdim        CGM.Int32Ty->getPointerTo(),
2015314564Sdim        CGM.Int8PtrTy,
2016314564Sdim        CGM.IntTy
2017314564Sdim      }, "struct.__builtin_NSString");
2018314564Sdim  }
2019314564Sdim
2020314564Sdim  ConstantInitBuilder Builder(CGM);
2021314564Sdim  auto Fields = Builder.beginStruct(NSConstantStringType);
2022314564Sdim
2023314564Sdim  // Class pointer.
2024314564Sdim  Fields.add(Class);
2025314564Sdim
2026314564Sdim  // String pointer.
2027314564Sdim  llvm::Constant *C =
2028314564Sdim    llvm::ConstantDataArray::getString(VMContext, Entry.first());
2029314564Sdim
2030314564Sdim  llvm::GlobalValue::LinkageTypes Linkage = llvm::GlobalValue::PrivateLinkage;
2031314564Sdim  bool isConstant = !CGM.getLangOpts().WritableStrings;
2032314564Sdim
2033314564Sdim  auto *GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), isConstant,
2034314564Sdim                                      Linkage, C, ".str");
2035314564Sdim  GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2036314564Sdim  // Don't enforce the target's minimum global alignment, since the only use
2037314564Sdim  // of the string is via this class initializer.
2038360784Sdim  GV->setAlignment(llvm::Align::None());
2039314564Sdim  Fields.addBitCast(GV, CGM.Int8PtrTy);
2040314564Sdim
2041314564Sdim  // String length.
2042314564Sdim  Fields.addInt(CGM.IntTy, StringLength);
2043314564Sdim
2044314564Sdim  // The struct.
2045314564Sdim  CharUnits Alignment = CGM.getPointerAlign();
2046314564Sdim  GV = Fields.finishAndCreateGlobal("_unnamed_nsstring_", Alignment,
2047314564Sdim                                    /*constant*/ true,
2048314564Sdim                                    llvm::GlobalVariable::PrivateLinkage);
2049314564Sdim  const char *NSStringSection = "__OBJC,__cstring_object,regular,no_dead_strip";
2050314564Sdim  const char *NSStringNonFragileABISection =
2051314564Sdim      "__DATA,__objc_stringobj,regular,no_dead_strip";
2052314564Sdim  // FIXME. Fix section.
2053314564Sdim  GV->setSection(CGM.getLangOpts().ObjCRuntime.isNonFragile()
2054314564Sdim                     ? NSStringNonFragileABISection
2055314564Sdim                     : NSStringSection);
2056314564Sdim  Entry.second = GV;
2057314564Sdim
2058314564Sdim  return ConstantAddress(GV, Alignment);
2059314564Sdim}
2060314564Sdim
2061234353Sdimenum {
2062234353Sdim  kCFTaggedObjectID_Integer = (1 << 1) + 1
2063234353Sdim};
2064234353Sdim
2065193326Sed/// Generates a message send where the super is the receiver.  This is
2066193326Sed/// a message send to self with special delivery semantics indicating
2067193326Sed/// which class's method should be called.
2068193326SedCodeGen::RValue
2069193326SedCGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
2070208600Srdivacky                                    ReturnValueSlot Return,
2071193326Sed                                    QualType ResultType,
2072193326Sed                                    Selector Sel,
2073193326Sed                                    const ObjCInterfaceDecl *Class,
2074193326Sed                                    bool isCategoryImpl,
2075193326Sed                                    llvm::Value *Receiver,
2076193326Sed                                    bool IsClassMessage,
2077198092Srdivacky                                    const CodeGen::CallArgList &CallArgs,
2078198092Srdivacky                                    const ObjCMethodDecl *Method) {
2079193326Sed  // Create and init a super structure; this is a (receiver, class)
2080193326Sed  // pair we will pass to objc_msgSendSuper.
2081296417Sdim  Address ObjCSuper =
2082296417Sdim    CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(),
2083296417Sdim                         "objc_super");
2084198092Srdivacky  llvm::Value *ReceiverAsObject =
2085193326Sed    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
2086353358Sdim  CGF.Builder.CreateStore(ReceiverAsObject,
2087353358Sdim                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
2088193326Sed
2089193326Sed  // If this is a class message the metaclass is passed as the target.
2090193326Sed  llvm::Value *Target;
2091193326Sed  if (IsClassMessage) {
2092193326Sed    if (isCategoryImpl) {
2093193326Sed      // Message sent to 'super' in a class method defined in a category
2094193326Sed      // implementation requires an odd treatment.
2095193326Sed      // If we are in a class method, we must retrieve the
2096193326Sed      // _metaclass_ for the current class, pointed at by
2097193326Sed      // the class's "isa" pointer.  The following assumes that
2098193326Sed      // isa" is the first ivar in a class (which it must be).
2099249423Sdim      Target = EmitClassRef(CGF, Class->getSuperClass());
2100288943Sdim      Target = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, Target, 0);
2101296417Sdim      Target = CGF.Builder.CreateAlignedLoad(Target, CGF.getPointerAlign());
2102198092Srdivacky    } else {
2103288943Sdim      llvm::Constant *MetaClassPtr = EmitMetaClassRef(Class);
2104288943Sdim      llvm::Value *SuperPtr =
2105288943Sdim          CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, MetaClassPtr, 1);
2106296417Sdim      llvm::Value *Super =
2107296417Sdim        CGF.Builder.CreateAlignedLoad(SuperPtr, CGF.getPointerAlign());
2108193326Sed      Target = Super;
2109198092Srdivacky    }
2110288943Sdim  } else if (isCategoryImpl)
2111249423Sdim    Target = EmitClassRef(CGF, Class->getSuperClass());
2112199482Srdivacky  else {
2113199482Srdivacky    llvm::Value *ClassPtr = EmitSuperClassRef(Class);
2114288943Sdim    ClassPtr = CGF.Builder.CreateStructGEP(ObjCTypes.ClassTy, ClassPtr, 1);
2115296417Sdim    Target = CGF.Builder.CreateAlignedLoad(ClassPtr, CGF.getPointerAlign());
2116193326Sed  }
2117193326Sed  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
2118193326Sed  // ObjCTypes types.
2119226633Sdim  llvm::Type *ClassTy =
2120193326Sed    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
2121193326Sed  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
2122353358Sdim  CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
2123360784Sdim  return EmitMessageSend(CGF, Return, ResultType, Sel, ObjCSuper.getPointer(),
2124360784Sdim                         ObjCTypes.SuperPtrCTy, true, CallArgs, Method, Class,
2125360784Sdim                         ObjCTypes);
2126193326Sed}
2127198092Srdivacky
2128198092Srdivacky/// Generate code for a message send expression.
2129193326SedCodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
2130208600Srdivacky                                               ReturnValueSlot Return,
2131193326Sed                                               QualType ResultType,
2132193326Sed                                               Selector Sel,
2133193326Sed                                               llvm::Value *Receiver,
2134193326Sed                                               const CallArgList &CallArgs,
2135207619Srdivacky                                               const ObjCInterfaceDecl *Class,
2136193326Sed                                               const ObjCMethodDecl *Method) {
2137360784Sdim  return EmitMessageSend(CGF, Return, ResultType, Sel, Receiver,
2138360784Sdim                         CGF.getContext().getObjCIdType(), false, CallArgs,
2139360784Sdim                         Method, Class, ObjCTypes);
2140193326Sed}
2141193326Sed
2142296417Sdimstatic bool isWeakLinkedClass(const ObjCInterfaceDecl *ID) {
2143296417Sdim  do {
2144296417Sdim    if (ID->isWeakImported())
2145296417Sdim      return true;
2146296417Sdim  } while ((ID = ID->getSuperClass()));
2147296417Sdim
2148296417Sdim  return false;
2149296417Sdim}
2150296417Sdim
2151198092SrdivackyCodeGen::RValue
2152223017SdimCGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
2153223017Sdim                                 ReturnValueSlot Return,
2154223017Sdim                                 QualType ResultType,
2155360784Sdim                                 Selector Sel,
2156223017Sdim                                 llvm::Value *Arg0,
2157223017Sdim                                 QualType Arg0Ty,
2158223017Sdim                                 bool IsSuper,
2159223017Sdim                                 const CallArgList &CallArgs,
2160223017Sdim                                 const ObjCMethodDecl *Method,
2161296417Sdim                                 const ObjCInterfaceDecl *ClassReceiver,
2162223017Sdim                                 const ObjCCommonTypesHelper &ObjCTypes) {
2163360784Sdim  CodeGenTypes &Types = CGM.getTypes();
2164360784Sdim  auto selTy = CGF.getContext().getObjCSelType();
2165360784Sdim  llvm::Value *SelValue;
2166360784Sdim
2167360784Sdim  if (Method && Method->isDirectMethod()) {
2168360784Sdim    // Direct methods will synthesize the proper `_cmd` internally,
2169360784Sdim    // so just don't bother with setting the `_cmd` argument.
2170360784Sdim    assert(!IsSuper);
2171360784Sdim    SelValue = llvm::UndefValue::get(Types.ConvertType(selTy));
2172360784Sdim  } else {
2173360784Sdim    SelValue = GetSelector(CGF, Sel);
2174360784Sdim  }
2175360784Sdim
2176193326Sed  CallArgList ActualArgs;
2177193326Sed  if (!IsSuper)
2178226633Sdim    Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
2179221345Sdim  ActualArgs.add(RValue::get(Arg0), Arg0Ty);
2180360784Sdim  ActualArgs.add(RValue::get(SelValue), selTy);
2181224145Sdim  ActualArgs.addFrom(CallArgs);
2182198092Srdivacky
2183234353Sdim  // If we're calling a method, use the formal signature.
2184234353Sdim  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
2185198092Srdivacky
2186210299Sed  if (Method)
2187276479Sdim    assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
2188276479Sdim               CGM.getContext().getCanonicalType(ResultType) &&
2189210299Sed           "Result type mismatch!");
2190210299Sed
2191296417Sdim  bool ReceiverCanBeNull = true;
2192296417Sdim
2193296417Sdim  // Super dispatch assumes that self is non-null; even the messenger
2194296417Sdim  // doesn't have a null check internally.
2195296417Sdim  if (IsSuper) {
2196296417Sdim    ReceiverCanBeNull = false;
2197296417Sdim
2198296417Sdim  // If this is a direct dispatch of a class method, check whether the class,
2199296417Sdim  // or anything in its hierarchy, was weak-linked.
2200296417Sdim  } else if (ClassReceiver && Method && Method->isClassMethod()) {
2201296417Sdim    ReceiverCanBeNull = isWeakLinkedClass(ClassReceiver);
2202296417Sdim
2203296417Sdim  // If we're emitting a method, and self is const (meaning just ARC, for now),
2204296417Sdim  // and the receiver is a load of self, then self is a valid object.
2205296417Sdim  } else if (auto CurMethod =
2206296417Sdim               dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl)) {
2207296417Sdim    auto Self = CurMethod->getSelfDecl();
2208296417Sdim    if (Self->getType().isConstQualified()) {
2209296417Sdim      if (auto LI = dyn_cast<llvm::LoadInst>(Arg0->stripPointerCasts())) {
2210296417Sdim        llvm::Value *SelfAddr = CGF.GetAddrOfLocalVar(Self).getPointer();
2211296417Sdim        if (SelfAddr == LI->getPointerOperand()) {
2212296417Sdim          ReceiverCanBeNull = false;
2213296417Sdim        }
2214296417Sdim      }
2215296417Sdim    }
2216296417Sdim  }
2217296417Sdim
2218321369Sdim  bool RequiresNullCheck = false;
2219223017Sdim
2220353358Sdim  llvm::FunctionCallee Fn = nullptr;
2221360784Sdim  if (Method && Method->isDirectMethod()) {
2222360784Sdim    Fn = GenerateDirectMethod(Method, Method->getClassInterface());
2223360784Sdim  } else if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
2224321369Sdim    if (ReceiverCanBeNull) RequiresNullCheck = true;
2225193326Sed    Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
2226198092Srdivacky      : ObjCTypes.getSendStretFn(IsSuper);
2227210299Sed  } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
2228210299Sed    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
2229210299Sed      : ObjCTypes.getSendFpretFn(IsSuper);
2230234353Sdim  } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
2231234353Sdim    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
2232234353Sdim      : ObjCTypes.getSendFp2retFn(IsSuper);
2233193326Sed  } else {
2234276479Sdim    // arm64 uses objc_msgSend for stret methods and yet null receiver check
2235276479Sdim    // must be made for it.
2236296417Sdim    if (ReceiverCanBeNull && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
2237321369Sdim      RequiresNullCheck = true;
2238193326Sed    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
2239198092Srdivacky      : ObjCTypes.getSendFn(IsSuper);
2240193326Sed  }
2241296417Sdim
2242353358Sdim  // Cast function to proper signature
2243353358Sdim  llvm::Constant *BitcastFn = cast<llvm::Constant>(
2244353358Sdim      CGF.Builder.CreateBitCast(Fn.getCallee(), MSI.MessengerType));
2245353358Sdim
2246321369Sdim  // We don't need to emit a null check to zero out an indirect result if the
2247321369Sdim  // result is ignored.
2248321369Sdim  if (Return.isUnused())
2249321369Sdim    RequiresNullCheck = false;
2250321369Sdim
2251296417Sdim  // Emit a null-check if there's a consumed argument other than the receiver.
2252321369Sdim  if (!RequiresNullCheck && CGM.getLangOpts().ObjCAutoRefCount && Method) {
2253309124Sdim    for (const auto *ParamDecl : Method->parameters()) {
2254234353Sdim      if (ParamDecl->hasAttr<NSConsumedAttr>()) {
2255296417Sdim        RequiresNullCheck = true;
2256234353Sdim        break;
2257234353Sdim      }
2258234353Sdim    }
2259296417Sdim  }
2260321369Sdim
2261321369Sdim  NullReturnState nullReturn;
2262321369Sdim  if (RequiresNullCheck) {
2263321369Sdim    nullReturn.init(CGF, Arg0);
2264321369Sdim  }
2265341825Sdim
2266353358Sdim  llvm::CallBase *CallSite;
2267353358Sdim  CGCallee Callee = CGCallee::forDirect(BitcastFn);
2268314564Sdim  RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs,
2269314564Sdim                               &CallSite);
2270296417Sdim
2271296417Sdim  // Mark the call as noreturn if the method is marked noreturn and the
2272296417Sdim  // receiver cannot be null.
2273296417Sdim  if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) {
2274353358Sdim    CallSite->setDoesNotReturn();
2275296417Sdim  }
2276296417Sdim
2277321369Sdim  return nullReturn.complete(CGF, Return, rvalue, ResultType, CallArgs,
2278296417Sdim                             RequiresNullCheck ? Method : nullptr);
2279193326Sed}
2280193326Sed
2281296417Sdimstatic Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT,
2282296417Sdim                                           bool pointee = false) {
2283296417Sdim  // Note that GC qualification applies recursively to C pointer types
2284296417Sdim  // that aren't otherwise decorated.  This is weird, but it's probably
2285296417Sdim  // an intentional workaround to the unreliable placement of GC qualifiers.
2286212904Sdim  if (FQT.isObjCGCStrong())
2287212904Sdim    return Qualifiers::Strong;
2288296417Sdim
2289296417Sdim  if (FQT.isObjCGCWeak())
2290212904Sdim    return Qualifiers::Weak;
2291296417Sdim
2292296417Sdim  if (auto ownership = FQT.getObjCLifetime()) {
2293296417Sdim    // Ownership does not apply recursively to C pointer types.
2294296417Sdim    if (pointee) return Qualifiers::GCNone;
2295296417Sdim    switch (ownership) {
2296296417Sdim    case Qualifiers::OCL_Weak: return Qualifiers::Weak;
2297296417Sdim    case Qualifiers::OCL_Strong: return Qualifiers::Strong;
2298296417Sdim    case Qualifiers::OCL_ExplicitNone: return Qualifiers::GCNone;
2299296417Sdim    case Qualifiers::OCL_Autoreleasing: llvm_unreachable("autoreleasing ivar?");
2300296417Sdim    case Qualifiers::OCL_None: llvm_unreachable("known nonzero");
2301296417Sdim    }
2302296417Sdim    llvm_unreachable("bad objc ownership");
2303296417Sdim  }
2304341825Sdim
2305296417Sdim  // Treat unqualified retainable pointers as strong.
2306212904Sdim  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2307212904Sdim    return Qualifiers::Strong;
2308341825Sdim
2309296417Sdim  // Walk into C pointer types, but only in GC.
2310296417Sdim  if (Ctx.getLangOpts().getGC() != LangOptions::NonGC) {
2311296417Sdim    if (const PointerType *PT = FQT->getAs<PointerType>())
2312296417Sdim      return GetGCAttrTypeForType(Ctx, PT->getPointeeType(), /*pointee*/ true);
2313296417Sdim  }
2314341825Sdim
2315212904Sdim  return Qualifiers::GCNone;
2316212904Sdim}
2317212904Sdim
2318296417Sdimnamespace {
2319296417Sdim  struct IvarInfo {
2320296417Sdim    CharUnits Offset;
2321296417Sdim    uint64_t SizeInWords;
2322296417Sdim    IvarInfo(CharUnits offset, uint64_t sizeInWords)
2323296417Sdim      : Offset(offset), SizeInWords(sizeInWords) {}
2324296417Sdim
2325296417Sdim    // Allow sorting based on byte pos.
2326296417Sdim    bool operator<(const IvarInfo &other) const {
2327296417Sdim      return Offset < other.Offset;
2328296417Sdim    }
2329296417Sdim  };
2330296417Sdim
2331296417Sdim  /// A helper class for building GC layout strings.
2332296417Sdim  class IvarLayoutBuilder {
2333296417Sdim    CodeGenModule &CGM;
2334296417Sdim
2335296417Sdim    /// The start of the layout.  Offsets will be relative to this value,
2336296417Sdim    /// and entries less than this value will be silently discarded.
2337296417Sdim    CharUnits InstanceBegin;
2338296417Sdim
2339296417Sdim    /// The end of the layout.  Offsets will never exceed this value.
2340296417Sdim    CharUnits InstanceEnd;
2341296417Sdim
2342296417Sdim    /// Whether we're generating the strong layout or the weak layout.
2343296417Sdim    bool ForStrongLayout;
2344296417Sdim
2345296417Sdim    /// Whether the offsets in IvarsInfo might be out-of-order.
2346296417Sdim    bool IsDisordered = false;
2347296417Sdim
2348296417Sdim    llvm::SmallVector<IvarInfo, 8> IvarsInfo;
2349309124Sdim
2350296417Sdim  public:
2351296417Sdim    IvarLayoutBuilder(CodeGenModule &CGM, CharUnits instanceBegin,
2352296417Sdim                      CharUnits instanceEnd, bool forStrongLayout)
2353296417Sdim      : CGM(CGM), InstanceBegin(instanceBegin), InstanceEnd(instanceEnd),
2354296417Sdim        ForStrongLayout(forStrongLayout) {
2355296417Sdim    }
2356296417Sdim
2357296417Sdim    void visitRecord(const RecordType *RT, CharUnits offset);
2358296417Sdim
2359296417Sdim    template <class Iterator, class GetOffsetFn>
2360341825Sdim    void visitAggregate(Iterator begin, Iterator end,
2361296417Sdim                        CharUnits aggrOffset,
2362296417Sdim                        const GetOffsetFn &getOffset);
2363296417Sdim
2364296417Sdim    void visitField(const FieldDecl *field, CharUnits offset);
2365296417Sdim
2366296417Sdim    /// Add the layout of a block implementation.
2367296417Sdim    void visitBlock(const CGBlockInfo &blockInfo);
2368296417Sdim
2369296417Sdim    /// Is there any information for an interesting bitmap?
2370296417Sdim    bool hasBitmapData() const { return !IvarsInfo.empty(); }
2371296417Sdim
2372296417Sdim    llvm::Constant *buildBitmap(CGObjCCommonMac &CGObjC,
2373296417Sdim                                llvm::SmallVectorImpl<unsigned char> &buffer);
2374296417Sdim
2375296417Sdim    static void dump(ArrayRef<unsigned char> buffer) {
2376296417Sdim      const unsigned char *s = buffer.data();
2377296417Sdim      for (unsigned i = 0, e = buffer.size(); i < e; i++)
2378296417Sdim        if (!(s[i] & 0xf0))
2379296417Sdim          printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2380296417Sdim        else
2381296417Sdim          printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
2382296417Sdim      printf("\n");
2383296417Sdim    }
2384296417Sdim  };
2385309124Sdim} // end anonymous namespace
2386296417Sdim
2387218893Sdimllvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
2388218893Sdim                                                const CGBlockInfo &blockInfo) {
2389341825Sdim
2390234353Sdim  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2391296417Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
2392218893Sdim    return nullPtr;
2393218893Sdim
2394296417Sdim  IvarLayoutBuilder builder(CGM, CharUnits::Zero(), blockInfo.BlockSize,
2395296417Sdim                            /*for strong layout*/ true);
2396296417Sdim
2397296417Sdim  builder.visitBlock(blockInfo);
2398296417Sdim
2399296417Sdim  if (!builder.hasBitmapData())
2400296417Sdim    return nullPtr;
2401296417Sdim
2402296417Sdim  llvm::SmallVector<unsigned char, 32> buffer;
2403296417Sdim  llvm::Constant *C = builder.buildBitmap(*this, buffer);
2404296417Sdim  if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
2405296417Sdim    printf("\n block variable layout for block: ");
2406296417Sdim    builder.dump(buffer);
2407296417Sdim  }
2408341825Sdim
2409296417Sdim  return C;
2410296417Sdim}
2411296417Sdim
2412296417Sdimvoid IvarLayoutBuilder::visitBlock(const CGBlockInfo &blockInfo) {
2413218893Sdim  // __isa is the first field in block descriptor and must assume by runtime's
2414218893Sdim  // convention that it is GC'able.
2415296417Sdim  IvarsInfo.push_back(IvarInfo(CharUnits::Zero(), 1));
2416218893Sdim
2417218893Sdim  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2418218893Sdim
2419218893Sdim  // Ignore the optional 'this' capture: C++ objects are not assumed
2420218893Sdim  // to be GC'ed.
2421218893Sdim
2422296417Sdim  CharUnits lastFieldOffset;
2423296417Sdim
2424218893Sdim  // Walk the captured variables.
2425276479Sdim  for (const auto &CI : blockDecl->captures()) {
2426276479Sdim    const VarDecl *variable = CI.getVariable();
2427218893Sdim    QualType type = variable->getType();
2428218893Sdim
2429218893Sdim    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2430218893Sdim
2431218893Sdim    // Ignore constant captures.
2432218893Sdim    if (capture.isConstant()) continue;
2433218893Sdim
2434296417Sdim    CharUnits fieldOffset = capture.getOffset();
2435218893Sdim
2436296417Sdim    // Block fields are not necessarily ordered; if we detect that we're
2437296417Sdim    // adding them out-of-order, make sure we sort later.
2438296417Sdim    if (fieldOffset < lastFieldOffset)
2439296417Sdim      IsDisordered = true;
2440296417Sdim    lastFieldOffset = fieldOffset;
2441296417Sdim
2442218893Sdim    // __block variables are passed by their descriptor address.
2443276479Sdim    if (CI.isByRef()) {
2444296417Sdim      IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
2445212904Sdim      continue;
2446212904Sdim    }
2447218893Sdim
2448218893Sdim    assert(!type->isArrayType() && "array variable should not be caught");
2449218893Sdim    if (const RecordType *record = type->getAs<RecordType>()) {
2450296417Sdim      visitRecord(record, fieldOffset);
2451218893Sdim      continue;
2452218893Sdim    }
2453341825Sdim
2454218893Sdim    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
2455218893Sdim
2456296417Sdim    if (GCAttr == Qualifiers::Strong) {
2457296417Sdim      assert(CGM.getContext().getTypeSize(type)
2458296417Sdim                == CGM.getTarget().getPointerWidth(0));
2459296417Sdim      IvarsInfo.push_back(IvarInfo(fieldOffset, /*size in words*/ 1));
2460296417Sdim    }
2461212904Sdim  }
2462212904Sdim}
2463212904Sdim
2464243830Sdim/// getBlockCaptureLifetime - This routine returns life time of the captured
2465243830Sdim/// block variable for the purpose of block layout meta-data generation. FQT is
2466243830Sdim/// the type of the variable captured in the block.
2467249423SdimQualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
2468249423Sdim                                                                  bool ByrefLayout) {
2469296417Sdim  // If it has an ownership qualifier, we're done.
2470296417Sdim  if (auto lifetime = FQT.getObjCLifetime())
2471296417Sdim    return lifetime;
2472296417Sdim
2473296417Sdim  // If it doesn't, and this is ARC, it has no ownership.
2474243830Sdim  if (CGM.getLangOpts().ObjCAutoRefCount)
2475296417Sdim    return Qualifiers::OCL_None;
2476341825Sdim
2477296417Sdim  // In MRC, retainable pointers are owned by non-__block variables.
2478243830Sdim  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2479249423Sdim    return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2480341825Sdim
2481243830Sdim  return Qualifiers::OCL_None;
2482243830Sdim}
2483243830Sdim
2484243830Sdimvoid CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
2485243830Sdim                                             Qualifiers::ObjCLifetime LifeTime,
2486243830Sdim                                             CharUnits FieldOffset,
2487243830Sdim                                             CharUnits FieldSize) {
2488243830Sdim  // __block variables are passed by their descriptor address.
2489243830Sdim  if (IsByref)
2490243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2491243830Sdim                                        FieldSize));
2492243830Sdim  else if (LifeTime == Qualifiers::OCL_Strong)
2493243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2494243830Sdim                                        FieldSize));
2495243830Sdim  else if (LifeTime == Qualifiers::OCL_Weak)
2496243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2497243830Sdim                                        FieldSize));
2498243830Sdim  else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2499243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2500243830Sdim                                        FieldSize));
2501243830Sdim  else
2502243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2503243830Sdim                                        FieldOffset,
2504243830Sdim                                        FieldSize));
2505243830Sdim}
2506243830Sdim
2507243830Sdimvoid CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
2508243830Sdim                                          const RecordDecl *RD,
2509243830Sdim                                          ArrayRef<const FieldDecl*> RecFields,
2510249423Sdim                                          CharUnits BytePos, bool &HasUnion,
2511249423Sdim                                          bool ByrefLayout) {
2512243830Sdim  bool IsUnion = (RD && RD->isUnion());
2513243830Sdim  CharUnits MaxUnionSize = CharUnits::Zero();
2514276479Sdim  const FieldDecl *MaxField = nullptr;
2515276479Sdim  const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
2516243830Sdim  CharUnits MaxFieldOffset = CharUnits::Zero();
2517243830Sdim  CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2518341825Sdim
2519243830Sdim  if (RecFields.empty())
2520243830Sdim    return;
2521251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2522341825Sdim
2523243830Sdim  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2524243830Sdim    const FieldDecl *Field = RecFields[i];
2525243830Sdim    // Note that 'i' here is actually the field index inside RD of Field,
2526243830Sdim    // although this dependency is hidden.
2527243830Sdim    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2528243830Sdim    CharUnits FieldOffset =
2529243830Sdim      CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
2530341825Sdim
2531243830Sdim    // Skip over unnamed or bitfields
2532243830Sdim    if (!Field->getIdentifier() || Field->isBitField()) {
2533243830Sdim      LastFieldBitfieldOrUnnamed = Field;
2534243830Sdim      LastBitfieldOrUnnamedOffset = FieldOffset;
2535243830Sdim      continue;
2536243830Sdim    }
2537276479Sdim
2538276479Sdim    LastFieldBitfieldOrUnnamed = nullptr;
2539243830Sdim    QualType FQT = Field->getType();
2540243830Sdim    if (FQT->isRecordType() || FQT->isUnionType()) {
2541243830Sdim      if (FQT->isUnionType())
2542243830Sdim        HasUnion = true;
2543341825Sdim
2544243830Sdim      BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(),
2545243830Sdim                                  BytePos + FieldOffset, HasUnion);
2546243830Sdim      continue;
2547243830Sdim    }
2548341825Sdim
2549243830Sdim    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2550360784Sdim      auto *CArray = cast<ConstantArrayType>(Array);
2551243830Sdim      uint64_t ElCount = CArray->getSize().getZExtValue();
2552243830Sdim      assert(CArray && "only array with known element size is supported");
2553243830Sdim      FQT = CArray->getElementType();
2554243830Sdim      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2555360784Sdim        auto *CArray = cast<ConstantArrayType>(Array);
2556243830Sdim        ElCount *= CArray->getSize().getZExtValue();
2557243830Sdim        FQT = CArray->getElementType();
2558243830Sdim      }
2559243830Sdim      if (FQT->isRecordType() && ElCount) {
2560243830Sdim        int OldIndex = RunSkipBlockVars.size() - 1;
2561243830Sdim        const RecordType *RT = FQT->getAs<RecordType>();
2562243830Sdim        BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2563243830Sdim                                    HasUnion);
2564341825Sdim
2565243830Sdim        // Replicate layout information for each array element. Note that
2566243830Sdim        // one element is already done.
2567243830Sdim        uint64_t ElIx = 1;
2568243830Sdim        for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2569243830Sdim          CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
2570243830Sdim          for (int i = OldIndex+1; i <= FirstIndex; ++i)
2571243830Sdim            RunSkipBlockVars.push_back(
2572243830Sdim              RUN_SKIP(RunSkipBlockVars[i].opcode,
2573243830Sdim              RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2574243830Sdim              RunSkipBlockVars[i].block_var_size));
2575243830Sdim        }
2576243830Sdim        continue;
2577243830Sdim      }
2578243830Sdim    }
2579243830Sdim    CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
2580243830Sdim    if (IsUnion) {
2581243830Sdim      CharUnits UnionIvarSize = FieldSize;
2582243830Sdim      if (UnionIvarSize > MaxUnionSize) {
2583243830Sdim        MaxUnionSize = UnionIvarSize;
2584243830Sdim        MaxField = Field;
2585243830Sdim        MaxFieldOffset = FieldOffset;
2586243830Sdim      }
2587243830Sdim    } else {
2588243830Sdim      UpdateRunSkipBlockVars(false,
2589249423Sdim                             getBlockCaptureLifetime(FQT, ByrefLayout),
2590243830Sdim                             BytePos + FieldOffset,
2591243830Sdim                             FieldSize);
2592243830Sdim    }
2593243830Sdim  }
2594341825Sdim
2595243830Sdim  if (LastFieldBitfieldOrUnnamed) {
2596243830Sdim    if (LastFieldBitfieldOrUnnamed->isBitField()) {
2597243830Sdim      // Last field was a bitfield. Must update the info.
2598243830Sdim      uint64_t BitFieldSize
2599243830Sdim        = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
2600243830Sdim      unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2601243830Sdim                        ((BitFieldSize % ByteSizeInBits) != 0);
2602243830Sdim      CharUnits Size = CharUnits::fromQuantity(UnsSize);
2603243830Sdim      Size += LastBitfieldOrUnnamedOffset;
2604243830Sdim      UpdateRunSkipBlockVars(false,
2605249423Sdim                             getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2606249423Sdim                                                     ByrefLayout),
2607243830Sdim                             BytePos + LastBitfieldOrUnnamedOffset,
2608243830Sdim                             Size);
2609243830Sdim    } else {
2610243830Sdim      assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
2611243830Sdim      // Last field was unnamed. Must update skip info.
2612243830Sdim      CharUnits FieldSize
2613243830Sdim        = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
2614243830Sdim      UpdateRunSkipBlockVars(false,
2615249423Sdim                             getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2616249423Sdim                                                     ByrefLayout),
2617243830Sdim                             BytePos + LastBitfieldOrUnnamedOffset,
2618243830Sdim                             FieldSize);
2619243830Sdim    }
2620243830Sdim  }
2621341825Sdim
2622243830Sdim  if (MaxField)
2623243830Sdim    UpdateRunSkipBlockVars(false,
2624249423Sdim                           getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),
2625243830Sdim                           BytePos + MaxFieldOffset,
2626243830Sdim                           MaxUnionSize);
2627243830Sdim}
2628243830Sdim
2629243830Sdimvoid CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
2630243830Sdim                                                  CharUnits BytePos,
2631249423Sdim                                                  bool &HasUnion,
2632249423Sdim                                                  bool ByrefLayout) {
2633243830Sdim  const RecordDecl *RD = RT->getDecl();
2634276479Sdim  SmallVector<const FieldDecl*, 16> Fields(RD->fields());
2635243830Sdim  llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
2636243830Sdim  const llvm::StructLayout *RecLayout =
2637243830Sdim    CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2638341825Sdim
2639249423Sdim  BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2640243830Sdim}
2641243830Sdim
2642243830Sdim/// InlineLayoutInstruction - This routine produce an inline instruction for the
2643243830Sdim/// block variable layout if it can. If not, it returns 0. Rules are as follow:
2644243830Sdim/// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit world,
2645243830Sdim/// an inline layout of value 0x0000000000000xyz is interpreted as follows:
2646243830Sdim/// x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by
2647243830Sdim/// y captured object of BLOCK_LAYOUT_BYREF. Followed by
2648243830Sdim/// z captured object of BLOCK_LAYOUT_WEAK. If any of the above is missing, zero
2649243830Sdim/// replaces it. For example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no
2650243830Sdim/// BLOCK_LAYOUT_BYREF and no BLOCK_LAYOUT_WEAK objects are captured.
2651243830Sdimuint64_t CGObjCCommonMac::InlineLayoutInstruction(
2652243830Sdim                                    SmallVectorImpl<unsigned char> &Layout) {
2653243830Sdim  uint64_t Result = 0;
2654243830Sdim  if (Layout.size() <= 3) {
2655243830Sdim    unsigned size = Layout.size();
2656243830Sdim    unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2657243830Sdim    unsigned char inst;
2658243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode ;
2659243830Sdim    switch (size) {
2660243830Sdim      case 3:
2661243830Sdim        inst = Layout[0];
2662243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2663243830Sdim        if (opcode == BLOCK_LAYOUT_STRONG)
2664243830Sdim          strong_word_count = (inst & 0xF)+1;
2665243830Sdim        else
2666243830Sdim          return 0;
2667243830Sdim        inst = Layout[1];
2668243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2669243830Sdim        if (opcode == BLOCK_LAYOUT_BYREF)
2670243830Sdim          byref_word_count = (inst & 0xF)+1;
2671243830Sdim        else
2672243830Sdim          return 0;
2673243830Sdim        inst = Layout[2];
2674243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2675243830Sdim        if (opcode == BLOCK_LAYOUT_WEAK)
2676243830Sdim          weak_word_count = (inst & 0xF)+1;
2677243830Sdim        else
2678243830Sdim          return 0;
2679243830Sdim        break;
2680341825Sdim
2681243830Sdim      case 2:
2682243830Sdim        inst = Layout[0];
2683243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2684243830Sdim        if (opcode == BLOCK_LAYOUT_STRONG) {
2685243830Sdim          strong_word_count = (inst & 0xF)+1;
2686243830Sdim          inst = Layout[1];
2687243830Sdim          opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2688243830Sdim          if (opcode == BLOCK_LAYOUT_BYREF)
2689243830Sdim            byref_word_count = (inst & 0xF)+1;
2690243830Sdim          else if (opcode == BLOCK_LAYOUT_WEAK)
2691243830Sdim            weak_word_count = (inst & 0xF)+1;
2692243830Sdim          else
2693243830Sdim            return 0;
2694243830Sdim        }
2695243830Sdim        else if (opcode == BLOCK_LAYOUT_BYREF) {
2696243830Sdim          byref_word_count = (inst & 0xF)+1;
2697243830Sdim          inst = Layout[1];
2698243830Sdim          opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2699243830Sdim          if (opcode == BLOCK_LAYOUT_WEAK)
2700243830Sdim            weak_word_count = (inst & 0xF)+1;
2701243830Sdim          else
2702243830Sdim            return 0;
2703243830Sdim        }
2704243830Sdim        else
2705243830Sdim          return 0;
2706243830Sdim        break;
2707341825Sdim
2708243830Sdim      case 1:
2709243830Sdim        inst = Layout[0];
2710243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2711243830Sdim        if (opcode == BLOCK_LAYOUT_STRONG)
2712243830Sdim          strong_word_count = (inst & 0xF)+1;
2713243830Sdim        else if (opcode == BLOCK_LAYOUT_BYREF)
2714243830Sdim          byref_word_count = (inst & 0xF)+1;
2715243830Sdim        else if (opcode == BLOCK_LAYOUT_WEAK)
2716243830Sdim          weak_word_count = (inst & 0xF)+1;
2717243830Sdim        else
2718243830Sdim          return 0;
2719243830Sdim        break;
2720341825Sdim
2721243830Sdim      default:
2722243830Sdim        return 0;
2723243830Sdim    }
2724341825Sdim
2725243830Sdim    // Cannot inline when any of the word counts is 15. Because this is one less
2726243830Sdim    // than the actual work count (so 15 means 16 actual word counts),
2727243830Sdim    // and we can only display 0 thru 15 word counts.
2728243830Sdim    if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2729243830Sdim      return 0;
2730341825Sdim
2731243830Sdim    unsigned count =
2732243830Sdim      (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2733341825Sdim
2734243830Sdim    if (size == count) {
2735243830Sdim      if (strong_word_count)
2736243830Sdim        Result = strong_word_count;
2737243830Sdim      Result <<= 4;
2738243830Sdim      if (byref_word_count)
2739243830Sdim        Result += byref_word_count;
2740243830Sdim      Result <<= 4;
2741243830Sdim      if (weak_word_count)
2742243830Sdim        Result += weak_word_count;
2743243830Sdim    }
2744243830Sdim  }
2745243830Sdim  return Result;
2746243830Sdim}
2747243830Sdim
2748249423Sdimllvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
2749243830Sdim  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2750249423Sdim  if (RunSkipBlockVars.empty())
2751249423Sdim    return nullPtr;
2752251662Sdim  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2753251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2754243830Sdim  unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2755341825Sdim
2756243830Sdim  // Sort on byte position; captures might not be allocated in order,
2757243830Sdim  // and unions can do funny things.
2758243830Sdim  llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2759243830Sdim  SmallVector<unsigned char, 16> Layout;
2760341825Sdim
2761243830Sdim  unsigned size = RunSkipBlockVars.size();
2762243830Sdim  for (unsigned i = 0; i < size; i++) {
2763243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2764243830Sdim    CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2765243830Sdim    CharUnits end_byte_pos = start_byte_pos;
2766243830Sdim    unsigned j = i+1;
2767243830Sdim    while (j < size) {
2768243830Sdim      if (opcode == RunSkipBlockVars[j].opcode) {
2769243830Sdim        end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2770243830Sdim        i++;
2771243830Sdim      }
2772243830Sdim      else
2773243830Sdim        break;
2774243830Sdim    }
2775243830Sdim    CharUnits size_in_bytes =
2776249423Sdim    end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2777243830Sdim    if (j < size) {
2778243830Sdim      CharUnits gap =
2779249423Sdim      RunSkipBlockVars[j].block_var_bytepos -
2780249423Sdim      RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2781243830Sdim      size_in_bytes += gap;
2782243830Sdim    }
2783243830Sdim    CharUnits residue_in_bytes = CharUnits::Zero();
2784243830Sdim    if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2785243830Sdim      residue_in_bytes = size_in_bytes % WordSizeInBytes;
2786243830Sdim      size_in_bytes -= residue_in_bytes;
2787243830Sdim      opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2788243830Sdim    }
2789341825Sdim
2790243830Sdim    unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
2791243830Sdim    while (size_in_words >= 16) {
2792243830Sdim      // Note that value in imm. is one less that the actual
2793243830Sdim      // value. So, 0xf means 16 words follow!
2794243830Sdim      unsigned char inst = (opcode << 4) | 0xf;
2795243830Sdim      Layout.push_back(inst);
2796243830Sdim      size_in_words -= 16;
2797243830Sdim    }
2798243830Sdim    if (size_in_words > 0) {
2799243830Sdim      // Note that value in imm. is one less that the actual
2800243830Sdim      // value. So, we subtract 1 away!
2801243830Sdim      unsigned char inst = (opcode << 4) | (size_in_words-1);
2802243830Sdim      Layout.push_back(inst);
2803243830Sdim    }
2804243830Sdim    if (residue_in_bytes > CharUnits::Zero()) {
2805243830Sdim      unsigned char inst =
2806249423Sdim      (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.getQuantity()-1);
2807243830Sdim      Layout.push_back(inst);
2808243830Sdim    }
2809243830Sdim  }
2810341825Sdim
2811296417Sdim  while (!Layout.empty()) {
2812296417Sdim    unsigned char inst = Layout.back();
2813243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2814243830Sdim    if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2815243830Sdim      Layout.pop_back();
2816243830Sdim    else
2817243830Sdim      break;
2818243830Sdim  }
2819341825Sdim
2820243830Sdim  uint64_t Result = InlineLayoutInstruction(Layout);
2821243830Sdim  if (Result != 0) {
2822243830Sdim    // Block variable layout instruction has been inlined.
2823243830Sdim    if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2824249423Sdim      if (ComputeByrefLayout)
2825296417Sdim        printf("\n Inline BYREF variable layout: ");
2826249423Sdim      else
2827296417Sdim        printf("\n Inline block variable layout: ");
2828296417Sdim      printf("0x0%" PRIx64 "", Result);
2829296417Sdim      if (auto numStrong = (Result & 0xF00) >> 8)
2830296417Sdim        printf(", BL_STRONG:%d", (int) numStrong);
2831296417Sdim      if (auto numByref = (Result & 0x0F0) >> 4)
2832296417Sdim        printf(", BL_BYREF:%d", (int) numByref);
2833296417Sdim      if (auto numWeak = (Result & 0x00F) >> 0)
2834296417Sdim        printf(", BL_WEAK:%d", (int) numWeak);
2835296417Sdim      printf(", BL_OPERATOR:0\n");
2836243830Sdim    }
2837296417Sdim    return llvm::ConstantInt::get(CGM.IntPtrTy, Result);
2838243830Sdim  }
2839341825Sdim
2840243830Sdim  unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2841243830Sdim  Layout.push_back(inst);
2842243830Sdim  std::string BitMap;
2843243830Sdim  for (unsigned i = 0, e = Layout.size(); i != e; i++)
2844243830Sdim    BitMap += Layout[i];
2845341825Sdim
2846243830Sdim  if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2847249423Sdim    if (ComputeByrefLayout)
2848296417Sdim      printf("\n Byref variable layout: ");
2849249423Sdim    else
2850296417Sdim      printf("\n Block variable layout: ");
2851243830Sdim    for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
2852243830Sdim      unsigned char inst = BitMap[i];
2853243830Sdim      enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2854243830Sdim      unsigned delta = 1;
2855243830Sdim      switch (opcode) {
2856243830Sdim        case BLOCK_LAYOUT_OPERATOR:
2857243830Sdim          printf("BL_OPERATOR:");
2858243830Sdim          delta = 0;
2859243830Sdim          break;
2860243830Sdim        case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2861243830Sdim          printf("BL_NON_OBJECT_BYTES:");
2862243830Sdim          break;
2863243830Sdim        case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2864243830Sdim          printf("BL_NON_OBJECT_WORD:");
2865243830Sdim          break;
2866243830Sdim        case BLOCK_LAYOUT_STRONG:
2867243830Sdim          printf("BL_STRONG:");
2868243830Sdim          break;
2869243830Sdim        case BLOCK_LAYOUT_BYREF:
2870243830Sdim          printf("BL_BYREF:");
2871243830Sdim          break;
2872243830Sdim        case BLOCK_LAYOUT_WEAK:
2873243830Sdim          printf("BL_WEAK:");
2874243830Sdim          break;
2875243830Sdim        case BLOCK_LAYOUT_UNRETAINED:
2876243830Sdim          printf("BL_UNRETAINED:");
2877243830Sdim          break;
2878249423Sdim      }
2879243830Sdim      // Actual value of word count is one more that what is in the imm.
2880243830Sdim      // field of the instruction
2881249423Sdim      printf("%d", (inst & 0xf) + delta);
2882243830Sdim      if (i < e-1)
2883243830Sdim        printf(", ");
2884243830Sdim      else
2885243830Sdim        printf("\n");
2886243830Sdim    }
2887243830Sdim  }
2888280031Sdim
2889314564Sdim  auto *Entry = CreateCStringLiteral(BitMap, ObjCLabelType::ClassName,
2890314564Sdim                                     /*ForceNonFragileABI=*/true,
2891314564Sdim                                     /*NullTerminate=*/false);
2892243830Sdim  return getConstantGEP(VMContext, Entry, 0, 0);
2893243830Sdim}
2894243830Sdim
2895344779Sdimstatic std::string getBlockLayoutInfoString(
2896344779Sdim    const SmallVectorImpl<CGObjCCommonMac::RUN_SKIP> &RunSkipBlockVars,
2897344779Sdim    bool HasCopyDisposeHelpers) {
2898344779Sdim  std::string Str;
2899344779Sdim  for (const CGObjCCommonMac::RUN_SKIP &R : RunSkipBlockVars) {
2900344779Sdim    if (R.opcode == CGObjCCommonMac::BLOCK_LAYOUT_UNRETAINED) {
2901344779Sdim      // Copy/dispose helpers don't have any information about
2902344779Sdim      // __unsafe_unretained captures, so unconditionally concatenate a string.
2903344779Sdim      Str += "u";
2904344779Sdim    } else if (HasCopyDisposeHelpers) {
2905344779Sdim      // Information about __strong, __weak, or byref captures has already been
2906344779Sdim      // encoded into the names of the copy/dispose helpers. We have to add a
2907344779Sdim      // string here only when the copy/dispose helpers aren't generated (which
2908344779Sdim      // happens when the block is non-escaping).
2909344779Sdim      continue;
2910344779Sdim    } else {
2911344779Sdim      switch (R.opcode) {
2912344779Sdim      case CGObjCCommonMac::BLOCK_LAYOUT_STRONG:
2913344779Sdim        Str += "s";
2914344779Sdim        break;
2915344779Sdim      case CGObjCCommonMac::BLOCK_LAYOUT_BYREF:
2916344779Sdim        Str += "r";
2917344779Sdim        break;
2918344779Sdim      case CGObjCCommonMac::BLOCK_LAYOUT_WEAK:
2919344779Sdim        Str += "w";
2920344779Sdim        break;
2921344779Sdim      default:
2922344779Sdim        continue;
2923344779Sdim      }
2924344779Sdim    }
2925344779Sdim    Str += llvm::to_string(R.block_var_bytepos.getQuantity());
2926344779Sdim    Str += "l" + llvm::to_string(R.block_var_size.getQuantity());
2927344779Sdim  }
2928344779Sdim  return Str;
2929344779Sdim}
2930344779Sdim
2931344779Sdimvoid CGObjCCommonMac::fillRunSkipBlockVars(CodeGenModule &CGM,
2932344779Sdim                                           const CGBlockInfo &blockInfo) {
2933249423Sdim  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2934341825Sdim
2935249423Sdim  RunSkipBlockVars.clear();
2936249423Sdim  bool hasUnion = false;
2937341825Sdim
2938251662Sdim  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2939251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2940249423Sdim  unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2941341825Sdim
2942249423Sdim  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2943341825Sdim
2944249423Sdim  // Calculate the basic layout of the block structure.
2945249423Sdim  const llvm::StructLayout *layout =
2946249423Sdim  CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
2947341825Sdim
2948249423Sdim  // Ignore the optional 'this' capture: C++ objects are not assumed
2949249423Sdim  // to be GC'ed.
2950249423Sdim  if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
2951249423Sdim    UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,
2952249423Sdim                           blockInfo.BlockHeaderForcedGapOffset,
2953249423Sdim                           blockInfo.BlockHeaderForcedGapSize);
2954249423Sdim  // Walk the captured variables.
2955276479Sdim  for (const auto &CI : blockDecl->captures()) {
2956276479Sdim    const VarDecl *variable = CI.getVariable();
2957249423Sdim    QualType type = variable->getType();
2958341825Sdim
2959249423Sdim    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2960341825Sdim
2961249423Sdim    // Ignore constant captures.
2962249423Sdim    if (capture.isConstant()) continue;
2963341825Sdim
2964249423Sdim    CharUnits fieldOffset =
2965249423Sdim       CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
2966341825Sdim
2967249423Sdim    assert(!type->isArrayType() && "array variable should not be caught");
2968276479Sdim    if (!CI.isByRef())
2969249423Sdim      if (const RecordType *record = type->getAs<RecordType>()) {
2970249423Sdim        BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2971249423Sdim        continue;
2972249423Sdim      }
2973249423Sdim    CharUnits fieldSize;
2974276479Sdim    if (CI.isByRef())
2975249423Sdim      fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2976249423Sdim    else
2977249423Sdim      fieldSize = CGM.getContext().getTypeSizeInChars(type);
2978276479Sdim    UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
2979249423Sdim                           fieldOffset, fieldSize);
2980249423Sdim  }
2981344779Sdim}
2982344779Sdim
2983344779Sdimllvm::Constant *
2984344779SdimCGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
2985344779Sdim                                    const CGBlockInfo &blockInfo) {
2986344779Sdim  fillRunSkipBlockVars(CGM, blockInfo);
2987249423Sdim  return getBitmapBlockLayout(false);
2988249423Sdim}
2989249423Sdim
2990344779Sdimstd::string CGObjCCommonMac::getRCBlockLayoutStr(CodeGenModule &CGM,
2991344779Sdim                                                 const CGBlockInfo &blockInfo) {
2992344779Sdim  fillRunSkipBlockVars(CGM, blockInfo);
2993344779Sdim  return getBlockLayoutInfoString(RunSkipBlockVars,
2994344779Sdim                                  blockInfo.needsCopyDisposeHelpers());
2995344779Sdim}
2996344779Sdim
2997249423Sdimllvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
2998249423Sdim                                                  QualType T) {
2999249423Sdim  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3000249423Sdim  assert(!T->isArrayType() && "__block array variable should not be caught");
3001249423Sdim  CharUnits fieldOffset;
3002249423Sdim  RunSkipBlockVars.clear();
3003249423Sdim  bool hasUnion = false;
3004249423Sdim  if (const RecordType *record = T->getAs<RecordType>()) {
3005249423Sdim    BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion, true /*ByrefLayout */);
3006249423Sdim    llvm::Constant *Result = getBitmapBlockLayout(true);
3007296417Sdim    if (isa<llvm::ConstantInt>(Result))
3008296417Sdim      Result = llvm::ConstantExpr::getIntToPtr(Result, CGM.Int8PtrTy);
3009249423Sdim    return Result;
3010249423Sdim  }
3011249423Sdim  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
3012249423Sdim  return nullPtr;
3013249423Sdim}
3014249423Sdim
3015249423Sdimllvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
3016193326Sed                                            const ObjCProtocolDecl *PD) {
3017193326Sed  // FIXME: I don't understand why gcc generates this, or where it is
3018193326Sed  // resolved. Investigate. Its also wasteful to look this up over and over.
3019193326Sed  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
3020193326Sed
3021193326Sed  return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
3022234353Sdim                                        ObjCTypes.getExternalProtocolPtrTy());
3023193326Sed}
3024193326Sed
3025193326Sedvoid CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
3026193326Sed  // FIXME: We shouldn't need this, the protocol decl should contain enough
3027193326Sed  // information to tell us whether this was a declaration or a definition.
3028193326Sed  DefinedProtocols.insert(PD->getIdentifier());
3029193326Sed
3030193326Sed  // If we have generated a forward reference to this protocol, emit
3031193326Sed  // it now. Otherwise do nothing, the protocol objects are lazily
3032193326Sed  // emitted.
3033198092Srdivacky  if (Protocols.count(PD->getIdentifier()))
3034193326Sed    GetOrEmitProtocol(PD);
3035193326Sed}
3036193326Sed
3037193326Sedllvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
3038193326Sed  if (DefinedProtocols.count(PD->getIdentifier()))
3039193326Sed    return GetOrEmitProtocol(PD);
3040341825Sdim
3041193326Sed  return GetOrEmitProtocolRef(PD);
3042193326Sed}
3043193326Sed
3044309124Sdimllvm::Value *CGObjCCommonMac::EmitClassRefViaRuntime(
3045309124Sdim               CodeGenFunction &CGF,
3046309124Sdim               const ObjCInterfaceDecl *ID,
3047309124Sdim               ObjCCommonTypesHelper &ObjCTypes) {
3048353358Sdim  llvm::FunctionCallee lookUpClassFn = ObjCTypes.getLookUpClassFn();
3049309124Sdim
3050309124Sdim  llvm::Value *className =
3051309124Sdim      CGF.CGM.GetAddrOfConstantCString(ID->getObjCRuntimeNameAsString())
3052309124Sdim        .getPointer();
3053309124Sdim  ASTContext &ctx = CGF.CGM.getContext();
3054309124Sdim  className =
3055309124Sdim      CGF.Builder.CreateBitCast(className,
3056309124Sdim                                CGF.ConvertType(
3057309124Sdim                                  ctx.getPointerType(ctx.CharTy.withConst())));
3058309124Sdim  llvm::CallInst *call = CGF.Builder.CreateCall(lookUpClassFn, className);
3059309124Sdim  call->setDoesNotThrow();
3060309124Sdim  return call;
3061309124Sdim}
3062309124Sdim
3063193326Sed/*
3064276479Sdim// Objective-C 1.0 extensions
3065198092Srdivackystruct _objc_protocol {
3066198092Srdivackystruct _objc_protocol_extension *isa;
3067198092Srdivackychar *protocol_name;
3068198092Srdivackystruct _objc_protocol_list *protocol_list;
3069198092Srdivackystruct _objc__method_prototype_list *instance_methods;
3070198092Srdivackystruct _objc__method_prototype_list *class_methods
3071198092Srdivacky};
3072193326Sed
3073198092SrdivackySee EmitProtocolExtension().
3074193326Sed*/
3075193326Sedllvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
3076234353Sdim  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
3077193326Sed
3078193326Sed  // Early exit if a defining object has already been generated.
3079193326Sed  if (Entry && Entry->hasInitializer())
3080193326Sed    return Entry;
3081193326Sed
3082234353Sdim  // Use the protocol definition, if there is one.
3083234353Sdim  if (const ObjCProtocolDecl *Def = PD->getDefinition())
3084234353Sdim    PD = Def;
3085234353Sdim
3086193326Sed  // FIXME: I don't understand why gcc generates this, or where it is
3087193326Sed  // resolved. Investigate. Its also wasteful to look this up over and over.
3088193326Sed  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
3089193326Sed
3090193326Sed  // Construct method lists.
3091314564Sdim  auto methodLists = ProtocolMethodLists::get(PD);
3092193326Sed
3093314564Sdim  ConstantInitBuilder builder(CGM);
3094314564Sdim  auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
3095314564Sdim  values.add(EmitProtocolExtension(PD, methodLists));
3096314564Sdim  values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
3097314564Sdim  values.add(EmitProtocolList("OBJC_PROTOCOL_REFS_" + PD->getName(),
3098314564Sdim                              PD->protocol_begin(), PD->protocol_end()));
3099314564Sdim  values.add(methodLists.emitMethodList(this, PD,
3100314564Sdim                              ProtocolMethodLists::RequiredInstanceMethods));
3101314564Sdim  values.add(methodLists.emitMethodList(this, PD,
3102314564Sdim                              ProtocolMethodLists::RequiredClassMethods));
3103223017Sdim
3104193326Sed  if (Entry) {
3105276479Sdim    // Already created, update the initializer.
3106276479Sdim    assert(Entry->hasPrivateLinkage());
3107314564Sdim    values.finishAndSetAsInitializer(Entry);
3108193326Sed  } else {
3109314564Sdim    Entry = values.finishAndCreateGlobal("OBJC_PROTOCOL_" + PD->getName(),
3110314564Sdim                                         CGM.getPointerAlign(),
3111314564Sdim                                         /*constant*/ false,
3112314564Sdim                                         llvm::GlobalValue::PrivateLinkage);
3113193326Sed    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3114234353Sdim
3115234353Sdim    Protocols[PD->getIdentifier()] = Entry;
3116193326Sed  }
3117276479Sdim  CGM.addCompilerUsedGlobal(Entry);
3118193326Sed
3119193326Sed  return Entry;
3120193326Sed}
3121193326Sed
3122193326Sedllvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
3123193326Sed  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
3124193326Sed
3125193326Sed  if (!Entry) {
3126193326Sed    // We use the initializer as a marker of whether this is a forward
3127193326Sed    // reference or not. At module finalization we add the empty
3128193326Sed    // contents for protocols which were referenced but never defined.
3129280031Sdim    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy,
3130280031Sdim                                     false, llvm::GlobalValue::PrivateLinkage,
3131280031Sdim                                     nullptr, "OBJC_PROTOCOL_" + PD->getName());
3132193326Sed    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
3133193326Sed    // FIXME: Is this necessary? Why only for protocol?
3134360784Sdim    Entry->setAlignment(llvm::Align(4));
3135193326Sed  }
3136198092Srdivacky
3137193326Sed  return Entry;
3138193326Sed}
3139193326Sed
3140193326Sed/*
3141193326Sed  struct _objc_protocol_extension {
3142198092Srdivacky  uint32_t size;
3143198092Srdivacky  struct objc_method_description_list *optional_instance_methods;
3144198092Srdivacky  struct objc_method_description_list *optional_class_methods;
3145198092Srdivacky  struct objc_property_list *instance_properties;
3146234353Sdim  const char ** extendedMethodTypes;
3147309124Sdim  struct objc_property_list *class_properties;
3148193326Sed  };
3149193326Sed*/
3150193326Sedllvm::Constant *
3151193326SedCGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
3152314564Sdim                                 const ProtocolMethodLists &methodLists) {
3153314564Sdim  auto optInstanceMethods =
3154314564Sdim    methodLists.emitMethodList(this, PD,
3155314564Sdim                               ProtocolMethodLists::OptionalInstanceMethods);
3156314564Sdim  auto optClassMethods =
3157314564Sdim    methodLists.emitMethodList(this, PD,
3158314564Sdim                               ProtocolMethodLists::OptionalClassMethods);
3159193326Sed
3160314564Sdim  auto extendedMethodTypes =
3161314564Sdim    EmitProtocolMethodTypes("OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
3162314564Sdim                            methodLists.emitExtendedTypesArray(this),
3163314564Sdim                            ObjCTypes);
3164314564Sdim
3165314564Sdim  auto instanceProperties =
3166314564Sdim    EmitPropertyList("OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr, PD,
3167314564Sdim                     ObjCTypes, false);
3168314564Sdim  auto classProperties =
3169314564Sdim    EmitPropertyList("OBJC_$_CLASS_PROP_PROTO_LIST_" + PD->getName(), nullptr,
3170314564Sdim                     PD, ObjCTypes, true);
3171314564Sdim
3172193326Sed  // Return null if no extension bits are used.
3173314564Sdim  if (optInstanceMethods->isNullValue() &&
3174314564Sdim      optClassMethods->isNullValue() &&
3175314564Sdim      extendedMethodTypes->isNullValue() &&
3176314564Sdim      instanceProperties->isNullValue() &&
3177314564Sdim      classProperties->isNullValue()) {
3178193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
3179314564Sdim  }
3180193326Sed
3181314564Sdim  uint64_t size =
3182314564Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
3183193326Sed
3184314564Sdim  ConstantInitBuilder builder(CGM);
3185314564Sdim  auto values = builder.beginStruct(ObjCTypes.ProtocolExtensionTy);
3186314564Sdim  values.addInt(ObjCTypes.IntTy, size);
3187314564Sdim  values.add(optInstanceMethods);
3188314564Sdim  values.add(optClassMethods);
3189314564Sdim  values.add(instanceProperties);
3190314564Sdim  values.add(extendedMethodTypes);
3191314564Sdim  values.add(classProperties);
3192314564Sdim
3193193326Sed  // No special section, but goes in llvm.used
3194353358Sdim  return CreateMetadataVar("_OBJC_PROTOCOLEXT_" + PD->getName(), values,
3195296417Sdim                           StringRef(), CGM.getPointerAlign(), true);
3196193326Sed}
3197193326Sed
3198193326Sed/*
3199193326Sed  struct objc_protocol_list {
3200234353Sdim    struct objc_protocol_list *next;
3201234353Sdim    long count;
3202234353Sdim    Protocol *list[];
3203193326Sed  };
3204193326Sed*/
3205193326Sedllvm::Constant *
3206314564SdimCGObjCMac::EmitProtocolList(Twine name,
3207193326Sed                            ObjCProtocolDecl::protocol_iterator begin,
3208193326Sed                            ObjCProtocolDecl::protocol_iterator end) {
3209193326Sed  // Just return null for empty protocol lists
3210314564Sdim  if (begin == end)
3211193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
3212193326Sed
3213314564Sdim  ConstantInitBuilder builder(CGM);
3214314564Sdim  auto values = builder.beginStruct();
3215193326Sed
3216193326Sed  // This field is only used by the runtime.
3217314564Sdim  values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3218198092Srdivacky
3219314564Sdim  // Reserve a slot for the count.
3220314564Sdim  auto countSlot = values.addPlaceholder();
3221314564Sdim
3222314564Sdim  auto refsArray = values.beginArray(ObjCTypes.ProtocolPtrTy);
3223314564Sdim  for (; begin != end; ++begin) {
3224314564Sdim    refsArray.add(GetProtocolRef(*begin));
3225314564Sdim  }
3226314564Sdim  auto count = refsArray.size();
3227314564Sdim
3228314564Sdim  // This list is null terminated.
3229314564Sdim  refsArray.addNullPointer(ObjCTypes.ProtocolPtrTy);
3230314564Sdim
3231314564Sdim  refsArray.finishAndAddTo(values);
3232314564Sdim  values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
3233314564Sdim
3234314564Sdim  StringRef section;
3235314564Sdim  if (CGM.getTriple().isOSBinFormatMachO())
3236314564Sdim    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3237314564Sdim
3238198092Srdivacky  llvm::GlobalVariable *GV =
3239314564Sdim      CreateMetadataVar(name, values, section, CGM.getPointerAlign(), false);
3240193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
3241193326Sed}
3242193326Sed
3243341825Sdimstatic void
3244234353SdimPushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
3245314564Sdim                       SmallVectorImpl<const ObjCPropertyDecl *> &Properties,
3246276479Sdim                       const ObjCProtocolDecl *Proto,
3247309124Sdim                       bool IsClassProperty) {
3248276479Sdim  for (const auto *PD : Proto->properties()) {
3249309124Sdim    if (IsClassProperty != PD->isClassProperty())
3250309124Sdim      continue;
3251280031Sdim    if (!PropertySet.insert(PD->getIdentifier()).second)
3252200583Srdivacky      continue;
3253314564Sdim    Properties.push_back(PD);
3254200583Srdivacky  }
3255360784Sdim
3256360784Sdim  for (const auto *P : Proto->protocols())
3257360784Sdim    PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3258200583Srdivacky}
3259200583Srdivacky
3260193326Sed/*
3261193326Sed  struct _objc_property {
3262234353Sdim    const char * const name;
3263234353Sdim    const char * const attributes;
3264193326Sed  };
3265193326Sed
3266193326Sed  struct _objc_property_list {
3267234353Sdim    uint32_t entsize; // sizeof (struct _objc_property)
3268234353Sdim    uint32_t prop_count;
3269234353Sdim    struct _objc_property[prop_count];
3270193326Sed  };
3271193326Sed*/
3272226633Sdimllvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
3273198092Srdivacky                                       const Decl *Container,
3274198092Srdivacky                                       const ObjCContainerDecl *OCD,
3275309124Sdim                                       const ObjCCommonTypesHelper &ObjCTypes,
3276309124Sdim                                       bool IsClassProperty) {
3277309124Sdim  if (IsClassProperty) {
3278309124Sdim    // Make this entry NULL for OS X with deployment target < 10.11, for iOS
3279309124Sdim    // with deployment target < 9.0.
3280309124Sdim    const llvm::Triple &Triple = CGM.getTarget().getTriple();
3281309124Sdim    if ((Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 11)) ||
3282309124Sdim        (Triple.isiOS() && Triple.isOSVersionLT(9)))
3283309124Sdim      return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3284309124Sdim  }
3285309124Sdim
3286314564Sdim  SmallVector<const ObjCPropertyDecl *, 16> Properties;
3287200583Srdivacky  llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
3288296417Sdim
3289296417Sdim  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
3290296417Sdim    for (const ObjCCategoryDecl *ClassExt : OID->known_extensions())
3291296417Sdim      for (auto *PD : ClassExt->properties()) {
3292309124Sdim        if (IsClassProperty != PD->isClassProperty())
3293309124Sdim          continue;
3294296417Sdim        PropertySet.insert(PD->getIdentifier());
3295314564Sdim        Properties.push_back(PD);
3296296417Sdim      }
3297309124Sdim
3298276479Sdim  for (const auto *PD : OCD->properties()) {
3299309124Sdim    if (IsClassProperty != PD->isClassProperty())
3300309124Sdim      continue;
3301296417Sdim    // Don't emit duplicate metadata for properties that were already in a
3302296417Sdim    // class extension.
3303296417Sdim    if (!PropertySet.insert(PD->getIdentifier()).second)
3304296417Sdim      continue;
3305314564Sdim    Properties.push_back(PD);
3306193326Sed  }
3307296417Sdim
3308210299Sed  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
3309276479Sdim    for (const auto *P : OID->all_referenced_protocols())
3310314564Sdim      PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3311210299Sed  }
3312210299Sed  else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
3313276479Sdim    for (const auto *P : CD->protocols())
3314314564Sdim      PushProtocolProperties(PropertySet, Properties, P, IsClassProperty);
3315210299Sed  }
3316193326Sed
3317193326Sed  // Return null for empty list.
3318193326Sed  if (Properties.empty())
3319193326Sed    return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
3320193326Sed
3321314564Sdim  unsigned propertySize =
3322243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
3323193326Sed
3324314564Sdim  ConstantInitBuilder builder(CGM);
3325314564Sdim  auto values = builder.beginStruct();
3326314564Sdim  values.addInt(ObjCTypes.IntTy, propertySize);
3327314564Sdim  values.addInt(ObjCTypes.IntTy, Properties.size());
3328314564Sdim  auto propertiesArray = values.beginArray(ObjCTypes.PropertyTy);
3329314564Sdim  for (auto PD : Properties) {
3330360784Sdim    if (PD->isDirectProperty())
3331360784Sdim      continue;
3332314564Sdim    auto property = propertiesArray.beginStruct(ObjCTypes.PropertyTy);
3333314564Sdim    property.add(GetPropertyName(PD->getIdentifier()));
3334314564Sdim    property.add(GetPropertyTypeString(PD, Container));
3335314564Sdim    property.finishAndAddTo(propertiesArray);
3336314564Sdim  }
3337314564Sdim  propertiesArray.finishAndAddTo(values);
3338314564Sdim
3339314564Sdim  StringRef Section;
3340314564Sdim  if (CGM.getTriple().isOSBinFormatMachO())
3341314564Sdim    Section = (ObjCABI == 2) ? "__DATA, __objc_const"
3342314564Sdim                             : "__OBJC,__property,regular,no_dead_strip";
3343314564Sdim
3344198092Srdivacky  llvm::GlobalVariable *GV =
3345314564Sdim      CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);
3346193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
3347193326Sed}
3348193326Sed
3349234353Sdimllvm::Constant *
3350234353SdimCGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
3351234353Sdim                                         ArrayRef<llvm::Constant*> MethodTypes,
3352234353Sdim                                         const ObjCCommonTypesHelper &ObjCTypes) {
3353234353Sdim  // Return null for empty list.
3354234353Sdim  if (MethodTypes.empty())
3355234353Sdim    return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
3356234353Sdim
3357234353Sdim  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
3358234353Sdim                                             MethodTypes.size());
3359234353Sdim  llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
3360234353Sdim
3361314564Sdim  StringRef Section;
3362314564Sdim  if (CGM.getTriple().isOSBinFormatMachO() && ObjCABI == 2)
3363314564Sdim    Section = "__DATA, __objc_const";
3364234353Sdim
3365296417Sdim  llvm::GlobalVariable *GV =
3366314564Sdim      CreateMetadataVar(Name, Init, Section, CGM.getPointerAlign(), true);
3367314564Sdim  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
3368193326Sed}
3369193326Sed
3370193326Sed/*
3371193326Sed  struct _objc_category {
3372198092Srdivacky  char *category_name;
3373198092Srdivacky  char *class_name;
3374198092Srdivacky  struct _objc_method_list *instance_methods;
3375198092Srdivacky  struct _objc_method_list *class_methods;
3376198092Srdivacky  struct _objc_protocol_list *protocols;
3377198092Srdivacky  uint32_t size; // <rdar://4585769>
3378198092Srdivacky  struct _objc_property_list *instance_properties;
3379309124Sdim  struct _objc_property_list *class_properties;
3380193326Sed  };
3381198092Srdivacky*/
3382193326Sedvoid CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
3383243830Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
3384193326Sed
3385193326Sed  // FIXME: This is poor design, the OCD should have a pointer to the category
3386193326Sed  // decl. Additionally, note that Category can be null for the @implementation
3387193326Sed  // w/o an @interface case. Sema should just create one for us as it does for
3388193326Sed  // @implementation so everyone else can live life under a clear blue sky.
3389193326Sed  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
3390198092Srdivacky  const ObjCCategoryDecl *Category =
3391193326Sed    Interface->FindCategoryDeclaration(OCD->getIdentifier());
3392193326Sed
3393234353Sdim  SmallString<256> ExtName;
3394198398Srdivacky  llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
3395198398Srdivacky                                     << OCD->getName();
3396198398Srdivacky
3397314564Sdim  ConstantInitBuilder Builder(CGM);
3398314564Sdim  auto Values = Builder.beginStruct(ObjCTypes.CategoryTy);
3399276479Sdim
3400314564Sdim  enum {
3401314564Sdim    InstanceMethods,
3402314564Sdim    ClassMethods,
3403314564Sdim    NumMethodLists
3404314564Sdim  };
3405314564Sdim  SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3406314564Sdim  for (const auto *MD : OCD->methods()) {
3407360784Sdim    if (!MD->isDirectMethod())
3408360784Sdim      Methods[unsigned(MD->isClassMethod())].push_back(MD);
3409314564Sdim  }
3410193326Sed
3411314564Sdim  Values.add(GetClassName(OCD->getName()));
3412314564Sdim  Values.add(GetClassName(Interface->getObjCRuntimeNameAsString()));
3413193326Sed  LazySymbols.insert(Interface->getIdentifier());
3414314564Sdim
3415314564Sdim  Values.add(emitMethodList(ExtName, MethodListType::CategoryInstanceMethods,
3416314564Sdim                            Methods[InstanceMethods]));
3417314564Sdim  Values.add(emitMethodList(ExtName, MethodListType::CategoryClassMethods,
3418314564Sdim                            Methods[ClassMethods]));
3419193326Sed  if (Category) {
3420314564Sdim    Values.add(
3421280031Sdim        EmitProtocolList("OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
3422314564Sdim                         Category->protocol_begin(), Category->protocol_end()));
3423193326Sed  } else {
3424314564Sdim    Values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
3425193326Sed  }
3426314564Sdim  Values.addInt(ObjCTypes.IntTy, Size);
3427193326Sed
3428193326Sed  // If there is no category @interface then there can be no properties.
3429193326Sed  if (Category) {
3430353358Sdim    Values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(),
3431314564Sdim                                OCD, Category, ObjCTypes, false));
3432353358Sdim    Values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
3433314564Sdim                                OCD, Category, ObjCTypes, true));
3434193326Sed  } else {
3435314564Sdim    Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3436314564Sdim    Values.addNullPointer(ObjCTypes.PropertyListPtrTy);
3437193326Sed  }
3438198092Srdivacky
3439198092Srdivacky  llvm::GlobalVariable *GV =
3440314564Sdim      CreateMetadataVar("OBJC_CATEGORY_" + ExtName.str(), Values,
3441296417Sdim                        "__OBJC,__category,regular,no_dead_strip",
3442296417Sdim                        CGM.getPointerAlign(), true);
3443193326Sed  DefinedCategories.push_back(GV);
3444314564Sdim  DefinedCategoryNames.insert(llvm::CachedHashString(ExtName));
3445221345Sdim  // method definition entries must be clear for next implementation.
3446221345Sdim  MethodDefinitions.clear();
3447193326Sed}
3448193326Sed
3449243830Sdimenum FragileClassFlags {
3450296417Sdim  /// Apparently: is not a meta-class.
3451243830Sdim  FragileABI_Class_Factory                 = 0x00001,
3452296417Sdim
3453296417Sdim  /// Is a meta-class.
3454243830Sdim  FragileABI_Class_Meta                    = 0x00002,
3455296417Sdim
3456296417Sdim  /// Has a non-trivial constructor or destructor.
3457243830Sdim  FragileABI_Class_HasCXXStructors         = 0x02000,
3458296417Sdim
3459296417Sdim  /// Has hidden visibility.
3460296417Sdim  FragileABI_Class_Hidden                  = 0x20000,
3461296417Sdim
3462296417Sdim  /// Class implementation was compiled under ARC.
3463296417Sdim  FragileABI_Class_CompiledByARC           = 0x04000000,
3464296417Sdim
3465296417Sdim  /// Class implementation was compiled under MRC and has MRC weak ivars.
3466296417Sdim  /// Exclusive with CompiledByARC.
3467296417Sdim  FragileABI_Class_HasMRCWeakIvars         = 0x08000000,
3468193326Sed};
3469193326Sed
3470243830Sdimenum NonFragileClassFlags {
3471243830Sdim  /// Is a meta-class.
3472243830Sdim  NonFragileABI_Class_Meta                 = 0x00001,
3473243830Sdim
3474243830Sdim  /// Is a root class.
3475243830Sdim  NonFragileABI_Class_Root                 = 0x00002,
3476243830Sdim
3477296417Sdim  /// Has a non-trivial constructor or destructor.
3478243830Sdim  NonFragileABI_Class_HasCXXStructors      = 0x00004,
3479243830Sdim
3480243830Sdim  /// Has hidden visibility.
3481243830Sdim  NonFragileABI_Class_Hidden               = 0x00010,
3482243830Sdim
3483243830Sdim  /// Has the exception attribute.
3484243830Sdim  NonFragileABI_Class_Exception            = 0x00020,
3485243830Sdim
3486243830Sdim  /// (Obsolete) ARC-specific: this class has a .release_ivars method
3487243830Sdim  NonFragileABI_Class_HasIvarReleaser      = 0x00040,
3488243830Sdim
3489243830Sdim  /// Class implementation was compiled under ARC.
3490243830Sdim  NonFragileABI_Class_CompiledByARC        = 0x00080,
3491243830Sdim
3492243830Sdim  /// Class has non-trivial destructors, but zero-initialization is okay.
3493296417Sdim  NonFragileABI_Class_HasCXXDestructorOnly = 0x00100,
3494296417Sdim
3495296417Sdim  /// Class implementation was compiled under MRC and has MRC weak ivars.
3496296417Sdim  /// Exclusive with CompiledByARC.
3497296417Sdim  NonFragileABI_Class_HasMRCWeakIvars      = 0x00200,
3498243830Sdim};
3499243830Sdim
3500296417Sdimstatic bool hasWeakMember(QualType type) {
3501296417Sdim  if (type.getObjCLifetime() == Qualifiers::OCL_Weak) {
3502296417Sdim    return true;
3503296417Sdim  }
3504296417Sdim
3505296417Sdim  if (auto recType = type->getAs<RecordType>()) {
3506296417Sdim    for (auto field : recType->getDecl()->fields()) {
3507296417Sdim      if (hasWeakMember(field->getType()))
3508296417Sdim        return true;
3509296417Sdim    }
3510296417Sdim  }
3511296417Sdim
3512296417Sdim  return false;
3513296417Sdim}
3514296417Sdim
3515296417Sdim/// For compatibility, we only want to set the "HasMRCWeakIvars" flag
3516296417Sdim/// (and actually fill in a layout string) if we really do have any
3517296417Sdim/// __weak ivars.
3518296417Sdimstatic bool hasMRCWeakIvars(CodeGenModule &CGM,
3519296417Sdim                            const ObjCImplementationDecl *ID) {
3520296417Sdim  if (!CGM.getLangOpts().ObjCWeak) return false;
3521296417Sdim  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
3522296417Sdim
3523296417Sdim  for (const ObjCIvarDecl *ivar =
3524296417Sdim         ID->getClassInterface()->all_declared_ivar_begin();
3525296417Sdim       ivar; ivar = ivar->getNextIvar()) {
3526296417Sdim    if (hasWeakMember(ivar->getType()))
3527296417Sdim      return true;
3528296417Sdim  }
3529296417Sdim
3530296417Sdim  return false;
3531296417Sdim}
3532296417Sdim
3533193326Sed/*
3534193326Sed  struct _objc_class {
3535198092Srdivacky  Class isa;
3536198092Srdivacky  Class super_class;
3537198092Srdivacky  const char *name;
3538198092Srdivacky  long version;
3539198092Srdivacky  long info;
3540198092Srdivacky  long instance_size;
3541198092Srdivacky  struct _objc_ivar_list *ivars;
3542198092Srdivacky  struct _objc_method_list *methods;
3543198092Srdivacky  struct _objc_cache *cache;
3544198092Srdivacky  struct _objc_protocol_list *protocols;
3545198092Srdivacky  // Objective-C 1.0 extensions (<rdr://4585769>)
3546198092Srdivacky  const char *ivar_layout;
3547198092Srdivacky  struct _objc_class_ext *ext;
3548193326Sed  };
3549193326Sed
3550193326Sed  See EmitClassExtension();
3551198092Srdivacky*/
3552193326Sedvoid CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
3553341825Sdim  IdentifierInfo *RuntimeName =
3554341825Sdim      &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
3555341825Sdim  DefinedSymbols.insert(RuntimeName);
3556193326Sed
3557193326Sed  std::string ClassName = ID->getNameAsString();
3558193326Sed  // FIXME: Gross
3559198092Srdivacky  ObjCInterfaceDecl *Interface =
3560193326Sed    const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
3561198092Srdivacky  llvm::Constant *Protocols =
3562280031Sdim      EmitProtocolList("OBJC_CLASS_PROTOCOLS_" + ID->getName(),
3563280031Sdim                       Interface->all_referenced_protocol_begin(),
3564280031Sdim                       Interface->all_referenced_protocol_end());
3565243830Sdim  unsigned Flags = FragileABI_Class_Factory;
3566243830Sdim  if (ID->hasNonZeroConstructors() || ID->hasDestructors())
3567243830Sdim    Flags |= FragileABI_Class_HasCXXStructors;
3568193326Sed
3569296417Sdim  bool hasMRCWeak = false;
3570296417Sdim
3571296417Sdim  if (CGM.getLangOpts().ObjCAutoRefCount)
3572296417Sdim    Flags |= FragileABI_Class_CompiledByARC;
3573296417Sdim  else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
3574296417Sdim    Flags |= FragileABI_Class_HasMRCWeakIvars;
3575296417Sdim
3576296417Sdim  CharUnits Size =
3577296417Sdim    CGM.getContext().getASTObjCImplementationLayout(ID).getSize();
3578296417Sdim
3579193326Sed  // FIXME: Set CXX-structors flag.
3580218893Sdim  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3581243830Sdim    Flags |= FragileABI_Class_Hidden;
3582193326Sed
3583314564Sdim  enum {
3584314564Sdim    InstanceMethods,
3585314564Sdim    ClassMethods,
3586314564Sdim    NumMethodLists
3587314564Sdim  };
3588314564Sdim  SmallVector<const ObjCMethodDecl *, 16> Methods[NumMethodLists];
3589314564Sdim  for (const auto *MD : ID->methods()) {
3590360784Sdim    if (!MD->isDirectMethod())
3591360784Sdim      Methods[unsigned(MD->isClassMethod())].push_back(MD);
3592314564Sdim  }
3593276479Sdim
3594276479Sdim  for (const auto *PID : ID->property_impls()) {
3595193326Sed    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3596360784Sdim      if (PID->getPropertyDecl()->isDirectProperty())
3597360784Sdim        continue;
3598360784Sdim      if (ObjCMethodDecl *MD = PID->getGetterMethodDecl())
3599314564Sdim        if (GetMethodDefinition(MD))
3600314564Sdim          Methods[InstanceMethods].push_back(MD);
3601360784Sdim      if (ObjCMethodDecl *MD = PID->getSetterMethodDecl())
3602314564Sdim        if (GetMethodDefinition(MD))
3603314564Sdim          Methods[InstanceMethods].push_back(MD);
3604193326Sed    }
3605193326Sed  }
3606193326Sed
3607314564Sdim  ConstantInitBuilder builder(CGM);
3608314564Sdim  auto values = builder.beginStruct(ObjCTypes.ClassTy);
3609314564Sdim  values.add(EmitMetaClass(ID, Protocols, Methods[ClassMethods]));
3610193326Sed  if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
3611193326Sed    // Record a reference to the super class.
3612193326Sed    LazySymbols.insert(Super->getIdentifier());
3613193326Sed
3614314564Sdim    values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3615314564Sdim                      ObjCTypes.ClassPtrTy);
3616193326Sed  } else {
3617314564Sdim    values.addNullPointer(ObjCTypes.ClassPtrTy);
3618193326Sed  }
3619314564Sdim  values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
3620193326Sed  // Version is always 0.
3621314564Sdim  values.addInt(ObjCTypes.LongTy, 0);
3622314564Sdim  values.addInt(ObjCTypes.LongTy, Flags);
3623314564Sdim  values.addInt(ObjCTypes.LongTy, Size.getQuantity());
3624314564Sdim  values.add(EmitIvarList(ID, false));
3625314564Sdim  values.add(emitMethodList(ID->getName(), MethodListType::InstanceMethods,
3626314564Sdim                            Methods[InstanceMethods]));
3627193326Sed  // cache is always NULL.
3628314564Sdim  values.addNullPointer(ObjCTypes.CachePtrTy);
3629314564Sdim  values.add(Protocols);
3630314564Sdim  values.add(BuildStrongIvarLayout(ID, CharUnits::Zero(), Size));
3631314564Sdim  values.add(EmitClassExtension(ID, Size, hasMRCWeak,
3632314564Sdim                                /*isMetaclass*/ false));
3633314564Sdim
3634280031Sdim  std::string Name("OBJC_CLASS_");
3635199482Srdivacky  Name += ClassName;
3636199482Srdivacky  const char *Section = "__OBJC,__class,regular,no_dead_strip";
3637199482Srdivacky  // Check for a forward reference.
3638276479Sdim  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3639199482Srdivacky  if (GV) {
3640199482Srdivacky    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3641199482Srdivacky           "Forward metaclass reference has incorrect type.");
3642314564Sdim    values.finishAndSetAsInitializer(GV);
3643199482Srdivacky    GV->setSection(Section);
3644360784Sdim    GV->setAlignment(CGM.getPointerAlign().getAsAlign());
3645276479Sdim    CGM.addCompilerUsedGlobal(GV);
3646276479Sdim  } else
3647314564Sdim    GV = CreateMetadataVar(Name, values, Section, CGM.getPointerAlign(), true);
3648193326Sed  DefinedClasses.push_back(GV);
3649276479Sdim  ImplementedClasses.push_back(Interface);
3650221345Sdim  // method definition entries must be clear for next implementation.
3651221345Sdim  MethodDefinitions.clear();
3652193326Sed}
3653193326Sed
3654193326Sedllvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
3655193326Sed                                         llvm::Constant *Protocols,
3656314564Sdim                                ArrayRef<const ObjCMethodDecl*> Methods) {
3657243830Sdim  unsigned Flags = FragileABI_Class_Meta;
3658243830Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3659193326Sed
3660218893Sdim  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3661243830Sdim    Flags |= FragileABI_Class_Hidden;
3662198092Srdivacky
3663314564Sdim  ConstantInitBuilder builder(CGM);
3664314564Sdim  auto values = builder.beginStruct(ObjCTypes.ClassTy);
3665193326Sed  // The isa for the metaclass is the root of the hierarchy.
3666193326Sed  const ObjCInterfaceDecl *Root = ID->getClassInterface();
3667193326Sed  while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
3668193326Sed    Root = Super;
3669314564Sdim  values.addBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
3670314564Sdim                    ObjCTypes.ClassPtrTy);
3671193326Sed  // The super class for the metaclass is emitted as the name of the
3672193326Sed  // super class. The runtime fixes this up to point to the
3673193326Sed  // *metaclass* for the super class.
3674193326Sed  if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
3675314564Sdim    values.addBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
3676314564Sdim                      ObjCTypes.ClassPtrTy);
3677193326Sed  } else {
3678314564Sdim    values.addNullPointer(ObjCTypes.ClassPtrTy);
3679193326Sed  }
3680314564Sdim  values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
3681193326Sed  // Version is always 0.
3682314564Sdim  values.addInt(ObjCTypes.LongTy, 0);
3683314564Sdim  values.addInt(ObjCTypes.LongTy, Flags);
3684314564Sdim  values.addInt(ObjCTypes.LongTy, Size);
3685314564Sdim  values.add(EmitIvarList(ID, true));
3686314564Sdim  values.add(emitMethodList(ID->getName(), MethodListType::ClassMethods,
3687314564Sdim                            Methods));
3688193326Sed  // cache is always NULL.
3689314564Sdim  values.addNullPointer(ObjCTypes.CachePtrTy);
3690314564Sdim  values.add(Protocols);
3691193326Sed  // ivar_layout for metaclass is always NULL.
3692314564Sdim  values.addNullPointer(ObjCTypes.Int8PtrTy);
3693309124Sdim  // The class extension is used to store class properties for metaclasses.
3694314564Sdim  values.add(EmitClassExtension(ID, CharUnits::Zero(), false/*hasMRCWeak*/,
3695314564Sdim                                /*isMetaclass*/true));
3696193326Sed
3697280031Sdim  std::string Name("OBJC_METACLASS_");
3698239462Sdim  Name += ID->getName();
3699193326Sed
3700193326Sed  // Check for a forward reference.
3701276479Sdim  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3702193326Sed  if (GV) {
3703193326Sed    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3704193326Sed           "Forward metaclass reference has incorrect type.");
3705314564Sdim    values.finishAndSetAsInitializer(GV);
3706193326Sed  } else {
3707314564Sdim    GV = values.finishAndCreateGlobal(Name, CGM.getPointerAlign(),
3708314564Sdim                                      /*constant*/ false,
3709314564Sdim                                      llvm::GlobalValue::PrivateLinkage);
3710193326Sed  }
3711193326Sed  GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
3712276479Sdim  CGM.addCompilerUsedGlobal(GV);
3713193326Sed
3714193326Sed  return GV;
3715193326Sed}
3716193326Sed
3717198092Srdivackyllvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
3718280031Sdim  std::string Name = "OBJC_METACLASS_" + ID->getNameAsString();
3719193326Sed
3720193326Sed  // FIXME: Should we look these up somewhere other than the module. Its a bit
3721193326Sed  // silly since we only generate these while processing an implementation, so
3722193326Sed  // exactly one pointer would work if know when we entered/exitted an
3723193326Sed  // implementation block.
3724193326Sed
3725193326Sed  // Check for an existing forward reference.
3726193326Sed  // Previously, metaclass with internal linkage may have been defined.
3727193326Sed  // pass 'true' as 2nd argument so it is returned.
3728276479Sdim  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3729276479Sdim  if (!GV)
3730276479Sdim    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3731276479Sdim                                  llvm::GlobalValue::PrivateLinkage, nullptr,
3732276479Sdim                                  Name);
3733276479Sdim
3734276479Sdim  assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3735276479Sdim         "Forward metaclass reference has incorrect type.");
3736276479Sdim  return GV;
3737193326Sed}
3738193326Sed
3739199482Srdivackyllvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
3740280031Sdim  std::string Name = "OBJC_CLASS_" + ID->getNameAsString();
3741276479Sdim  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
3742276479Sdim
3743276479Sdim  if (!GV)
3744276479Sdim    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3745276479Sdim                                  llvm::GlobalValue::PrivateLinkage, nullptr,
3746276479Sdim                                  Name);
3747276479Sdim
3748276479Sdim  assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3749276479Sdim         "Forward class metadata reference has incorrect type.");
3750276479Sdim  return GV;
3751199482Srdivacky}
3752199482Srdivacky
3753193326Sed/*
3754296417Sdim  Emit a "class extension", which in this specific context means extra
3755296417Sdim  data that doesn't fit in the normal fragile-ABI class structure, and
3756296417Sdim  has nothing to do with the language concept of a class extension.
3757296417Sdim
3758193326Sed  struct objc_class_ext {
3759198092Srdivacky  uint32_t size;
3760198092Srdivacky  const char *weak_ivar_layout;
3761198092Srdivacky  struct _objc_property_list *properties;
3762193326Sed  };
3763193326Sed*/
3764193326Sedllvm::Constant *
3765296417SdimCGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID,
3766309124Sdim                              CharUnits InstanceSize, bool hasMRCWeakIvars,
3767314564Sdim                              bool isMetaclass) {
3768314564Sdim  // Weak ivar layout.
3769314564Sdim  llvm::Constant *layout;
3770314564Sdim  if (isMetaclass) {
3771314564Sdim    layout = llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
3772314564Sdim  } else {
3773314564Sdim    layout = BuildWeakIvarLayout(ID, CharUnits::Zero(), InstanceSize,
3774314564Sdim                                 hasMRCWeakIvars);
3775314564Sdim  }
3776193326Sed
3777314564Sdim  // Properties.
3778314564Sdim  llvm::Constant *propertyList =
3779353358Sdim    EmitPropertyList((isMetaclass ? Twine("_OBJC_$_CLASS_PROP_LIST_")
3780353358Sdim                                  : Twine("_OBJC_$_PROP_LIST_"))
3781314564Sdim                        + ID->getName(),
3782314564Sdim                     ID, ID->getClassInterface(), ObjCTypes, isMetaclass);
3783193326Sed
3784193326Sed  // Return null if no extension bits are used.
3785314564Sdim  if (layout->isNullValue() && propertyList->isNullValue()) {
3786193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3787314564Sdim  }
3788193326Sed
3789314564Sdim  uint64_t size =
3790314564Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3791314564Sdim
3792314564Sdim  ConstantInitBuilder builder(CGM);
3793314564Sdim  auto values = builder.beginStruct(ObjCTypes.ClassExtensionTy);
3794314564Sdim  values.addInt(ObjCTypes.IntTy, size);
3795314564Sdim  values.add(layout);
3796314564Sdim  values.add(propertyList);
3797314564Sdim
3798314564Sdim  return CreateMetadataVar("OBJC_CLASSEXT_" + ID->getName(), values,
3799296417Sdim                           "__OBJC,__class_ext,regular,no_dead_strip",
3800296417Sdim                           CGM.getPointerAlign(), true);
3801193326Sed}
3802193326Sed
3803193326Sed/*
3804193326Sed  struct objc_ivar {
3805234353Sdim    char *ivar_name;
3806234353Sdim    char *ivar_type;
3807234353Sdim    int ivar_offset;
3808193326Sed  };
3809193326Sed
3810193326Sed  struct objc_ivar_list {
3811234353Sdim    int ivar_count;
3812234353Sdim    struct objc_ivar list[count];
3813193326Sed  };
3814198092Srdivacky*/
3815193326Sedllvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
3816193326Sed                                        bool ForClass) {
3817193326Sed  // When emitting the root class GCC emits ivar entries for the
3818193326Sed  // actual class structure. It is not clear if we need to follow this
3819193326Sed  // behavior; for now lets try and get away with not doing it. If so,
3820193326Sed  // the cleanest solution would be to make up an ObjCInterfaceDecl
3821193326Sed  // for the class.
3822193326Sed  if (ForClass)
3823193326Sed    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3824198092Srdivacky
3825226633Sdim  const ObjCInterfaceDecl *OID = ID->getClassInterface();
3826198092Srdivacky
3827314564Sdim  ConstantInitBuilder builder(CGM);
3828314564Sdim  auto ivarList = builder.beginStruct();
3829314564Sdim  auto countSlot = ivarList.addPlaceholder();
3830314564Sdim  auto ivars = ivarList.beginArray(ObjCTypes.IvarTy);
3831314564Sdim
3832341825Sdim  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
3833224145Sdim       IVD; IVD = IVD->getNextIvar()) {
3834193576Sed    // Ignore unnamed bit-fields.
3835193576Sed    if (!IVD->getDeclName())
3836198092Srdivacky      continue;
3837314564Sdim
3838314564Sdim    auto ivar = ivars.beginStruct(ObjCTypes.IvarTy);
3839314564Sdim    ivar.add(GetMethodVarName(IVD->getIdentifier()));
3840314564Sdim    ivar.add(GetMethodVarType(IVD));
3841314564Sdim    ivar.addInt(ObjCTypes.IntTy, ComputeIvarBaseOffset(CGM, OID, IVD));
3842314564Sdim    ivar.finishAndAddTo(ivars);
3843193326Sed  }
3844193326Sed
3845193326Sed  // Return null for empty list.
3846314564Sdim  auto count = ivars.size();
3847314564Sdim  if (count == 0) {
3848314564Sdim    ivars.abandon();
3849314564Sdim    ivarList.abandon();
3850193326Sed    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3851314564Sdim  }
3852193326Sed
3853314564Sdim  ivars.finishAndAddTo(ivarList);
3854314564Sdim  ivarList.fillPlaceholderWithInt(countSlot, ObjCTypes.IntTy, count);
3855193326Sed
3856193326Sed  llvm::GlobalVariable *GV;
3857193326Sed  if (ForClass)
3858280031Sdim    GV =
3859314564Sdim        CreateMetadataVar("OBJC_CLASS_VARIABLES_" + ID->getName(), ivarList,
3860296417Sdim                          "__OBJC,__class_vars,regular,no_dead_strip",
3861296417Sdim                          CGM.getPointerAlign(), true);
3862193326Sed  else
3863314564Sdim    GV = CreateMetadataVar("OBJC_INSTANCE_VARIABLES_" + ID->getName(), ivarList,
3864296417Sdim                           "__OBJC,__instance_vars,regular,no_dead_strip",
3865296417Sdim                           CGM.getPointerAlign(), true);
3866193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3867193326Sed}
3868193326Sed
3869314564Sdim/// Build a struct objc_method_description constant for the given method.
3870314564Sdim///
3871314564Sdim/// struct objc_method_description {
3872314564Sdim///   SEL method_name;
3873314564Sdim///   char *method_types;
3874314564Sdim/// };
3875314564Sdimvoid CGObjCMac::emitMethodDescriptionConstant(ConstantArrayBuilder &builder,
3876314564Sdim                                              const ObjCMethodDecl *MD) {
3877314564Sdim  auto description = builder.beginStruct(ObjCTypes.MethodDescriptionTy);
3878314564Sdim  description.addBitCast(GetMethodVarName(MD->getSelector()),
3879314564Sdim                         ObjCTypes.SelectorPtrTy);
3880314564Sdim  description.add(GetMethodVarType(MD));
3881314564Sdim  description.finishAndAddTo(builder);
3882314564Sdim}
3883198092Srdivacky
3884314564Sdim/// Build a struct objc_method constant for the given method.
3885314564Sdim///
3886314564Sdim/// struct objc_method {
3887314564Sdim///   SEL method_name;
3888314564Sdim///   char *method_types;
3889314564Sdim///   void *method;
3890314564Sdim/// };
3891314564Sdimvoid CGObjCMac::emitMethodConstant(ConstantArrayBuilder &builder,
3892314564Sdim                                   const ObjCMethodDecl *MD) {
3893314564Sdim  llvm::Function *fn = GetMethodDefinition(MD);
3894314564Sdim  assert(fn && "no definition registered for method");
3895193326Sed
3896314564Sdim  auto method = builder.beginStruct(ObjCTypes.MethodTy);
3897314564Sdim  method.addBitCast(GetMethodVarName(MD->getSelector()),
3898314564Sdim                    ObjCTypes.SelectorPtrTy);
3899314564Sdim  method.add(GetMethodVarType(MD));
3900314564Sdim  method.addBitCast(fn, ObjCTypes.Int8PtrTy);
3901314564Sdim  method.finishAndAddTo(builder);
3902193326Sed}
3903193326Sed
3904314564Sdim/// Build a struct objc_method_list or struct objc_method_description_list,
3905314564Sdim/// as appropriate.
3906314564Sdim///
3907314564Sdim/// struct objc_method_list {
3908314564Sdim///   struct objc_method_list *obsolete;
3909314564Sdim///   int count;
3910314564Sdim///   struct objc_method methods_list[count];
3911314564Sdim/// };
3912314564Sdim///
3913314564Sdim/// struct objc_method_description_list {
3914314564Sdim///   int count;
3915314564Sdim///   struct objc_method_description list[count];
3916314564Sdim/// };
3917314564Sdimllvm::Constant *CGObjCMac::emitMethodList(Twine name, MethodListType MLT,
3918314564Sdim                                 ArrayRef<const ObjCMethodDecl *> methods) {
3919314564Sdim  StringRef prefix;
3920314564Sdim  StringRef section;
3921314564Sdim  bool forProtocol = false;
3922314564Sdim  switch (MLT) {
3923314564Sdim  case MethodListType::CategoryInstanceMethods:
3924314564Sdim    prefix = "OBJC_CATEGORY_INSTANCE_METHODS_";
3925314564Sdim    section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
3926314564Sdim    forProtocol = false;
3927314564Sdim    break;
3928314564Sdim  case MethodListType::CategoryClassMethods:
3929314564Sdim    prefix = "OBJC_CATEGORY_CLASS_METHODS_";
3930314564Sdim    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3931314564Sdim    forProtocol = false;
3932314564Sdim    break;
3933314564Sdim  case MethodListType::InstanceMethods:
3934314564Sdim    prefix = "OBJC_INSTANCE_METHODS_";
3935314564Sdim    section = "__OBJC,__inst_meth,regular,no_dead_strip";
3936314564Sdim    forProtocol = false;
3937314564Sdim    break;
3938314564Sdim  case MethodListType::ClassMethods:
3939314564Sdim    prefix = "OBJC_CLASS_METHODS_";
3940314564Sdim    section = "__OBJC,__cls_meth,regular,no_dead_strip";
3941314564Sdim    forProtocol = false;
3942314564Sdim    break;
3943314564Sdim  case MethodListType::ProtocolInstanceMethods:
3944314564Sdim    prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_";
3945314564Sdim    section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
3946314564Sdim    forProtocol = true;
3947314564Sdim    break;
3948314564Sdim  case MethodListType::ProtocolClassMethods:
3949314564Sdim    prefix = "OBJC_PROTOCOL_CLASS_METHODS_";
3950314564Sdim    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3951314564Sdim    forProtocol = true;
3952314564Sdim    break;
3953314564Sdim  case MethodListType::OptionalProtocolInstanceMethods:
3954314564Sdim    prefix = "OBJC_PROTOCOL_INSTANCE_METHODS_OPT_";
3955314564Sdim    section = "__OBJC,__cat_inst_meth,regular,no_dead_strip";
3956314564Sdim    forProtocol = true;
3957314564Sdim    break;
3958314564Sdim  case MethodListType::OptionalProtocolClassMethods:
3959314564Sdim    prefix = "OBJC_PROTOCOL_CLASS_METHODS_OPT_";
3960314564Sdim    section = "__OBJC,__cat_cls_meth,regular,no_dead_strip";
3961314564Sdim    forProtocol = true;
3962314564Sdim    break;
3963314564Sdim  }
3964314564Sdim
3965193326Sed  // Return null for empty list.
3966314564Sdim  if (methods.empty())
3967314564Sdim    return llvm::Constant::getNullValue(forProtocol
3968314564Sdim                                        ? ObjCTypes.MethodDescriptionListPtrTy
3969314564Sdim                                        : ObjCTypes.MethodListPtrTy);
3970193326Sed
3971314564Sdim  // For protocols, this is an objc_method_description_list, which has
3972314564Sdim  // a slightly different structure.
3973314564Sdim  if (forProtocol) {
3974314564Sdim    ConstantInitBuilder builder(CGM);
3975314564Sdim    auto values = builder.beginStruct();
3976314564Sdim    values.addInt(ObjCTypes.IntTy, methods.size());
3977314564Sdim    auto methodArray = values.beginArray(ObjCTypes.MethodDescriptionTy);
3978314564Sdim    for (auto MD : methods) {
3979314564Sdim      emitMethodDescriptionConstant(methodArray, MD);
3980314564Sdim    }
3981314564Sdim    methodArray.finishAndAddTo(values);
3982193326Sed
3983314564Sdim    llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
3984314564Sdim                                                 CGM.getPointerAlign(), true);
3985314564Sdim    return llvm::ConstantExpr::getBitCast(GV,
3986314564Sdim                                          ObjCTypes.MethodDescriptionListPtrTy);
3987314564Sdim  }
3988314564Sdim
3989314564Sdim  // Otherwise, it's an objc_method_list.
3990314564Sdim  ConstantInitBuilder builder(CGM);
3991314564Sdim  auto values = builder.beginStruct();
3992314564Sdim  values.addNullPointer(ObjCTypes.Int8PtrTy);
3993314564Sdim  values.addInt(ObjCTypes.IntTy, methods.size());
3994314564Sdim  auto methodArray = values.beginArray(ObjCTypes.MethodTy);
3995314564Sdim  for (auto MD : methods) {
3996360784Sdim    if (!MD->isDirectMethod())
3997360784Sdim      emitMethodConstant(methodArray, MD);
3998314564Sdim  }
3999314564Sdim  methodArray.finishAndAddTo(values);
4000314564Sdim
4001314564Sdim  llvm::GlobalVariable *GV = CreateMetadataVar(prefix + name, values, section,
4002314564Sdim                                               CGM.getPointerAlign(), true);
4003224145Sdim  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
4004193326Sed}
4005193326Sed
4006193326Sedllvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
4007198092Srdivacky                                                const ObjCContainerDecl *CD) {
4008360784Sdim  llvm::Function *Method;
4009360784Sdim
4010360784Sdim  if (OMD->isDirectMethod()) {
4011360784Sdim    Method = GenerateDirectMethod(OMD, CD);
4012360784Sdim  } else {
4013360784Sdim    SmallString<256> Name;
4014360784Sdim    GetNameForMethod(OMD, CD, Name);
4015360784Sdim
4016360784Sdim    CodeGenTypes &Types = CGM.getTypes();
4017360784Sdim    llvm::FunctionType *MethodTy =
4018360784Sdim        Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4019360784Sdim    Method =
4020360784Sdim        llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage,
4021360784Sdim                               Name.str(), &CGM.getModule());
4022360784Sdim  }
4023360784Sdim
4024360784Sdim  MethodDefinitions.insert(std::make_pair(OMD, Method));
4025360784Sdim
4026360784Sdim  return Method;
4027360784Sdim}
4028360784Sdim
4029360784Sdimllvm::Function *
4030360784SdimCGObjCCommonMac::GenerateDirectMethod(const ObjCMethodDecl *OMD,
4031360784Sdim                                      const ObjCContainerDecl *CD) {
4032360784Sdim  auto I = DirectMethodDefinitions.find(OMD->getCanonicalDecl());
4033360784Sdim  if (I != DirectMethodDefinitions.end())
4034360784Sdim    return I->second;
4035360784Sdim
4036234353Sdim  SmallString<256> Name;
4037360784Sdim  GetNameForMethod(OMD, CD, Name, /*ignoreCategoryNamespace*/true);
4038193326Sed
4039193326Sed  CodeGenTypes &Types = CGM.getTypes();
4040226633Sdim  llvm::FunctionType *MethodTy =
4041234353Sdim    Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
4042198092Srdivacky  llvm::Function *Method =
4043360784Sdim      llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage,
4044360784Sdim                             Name.str(), &CGM.getModule());
4045360784Sdim  DirectMethodDefinitions.insert(std::make_pair(OMD->getCanonicalDecl(), Method));
4046193326Sed
4047193326Sed  return Method;
4048193326Sed}
4049193326Sed
4050360784Sdimvoid CGObjCCommonMac::GenerateDirectMethodPrologue(
4051360784Sdim    CodeGenFunction &CGF, llvm::Function *Fn, const ObjCMethodDecl *OMD,
4052360784Sdim    const ObjCContainerDecl *CD) {
4053360784Sdim  auto &Builder = CGF.Builder;
4054360784Sdim  bool ReceiverCanBeNull = true;
4055360784Sdim  auto selfAddr = CGF.GetAddrOfLocalVar(OMD->getSelfDecl());
4056360784Sdim  auto selfValue = Builder.CreateLoad(selfAddr);
4057360784Sdim
4058360784Sdim  // Generate:
4059360784Sdim  //
4060360784Sdim  // /* for class methods only to force class lazy initialization */
4061360784Sdim  // self = [self self];
4062360784Sdim  //
4063360784Sdim  // /* unless the receiver is never NULL */
4064360784Sdim  // if (self == nil) {
4065360784Sdim  //     return (ReturnType){ };
4066360784Sdim  // }
4067360784Sdim  //
4068360784Sdim  // _cmd = @selector(...)
4069360784Sdim  // ...
4070360784Sdim
4071360784Sdim  if (OMD->isClassMethod()) {
4072360784Sdim    const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(CD);
4073360784Sdim    assert(OID &&
4074360784Sdim           "GenerateDirectMethod() should be called with the Class Interface");
4075360784Sdim    Selector SelfSel = GetNullarySelector("self", CGM.getContext());
4076360784Sdim    auto ResultType = CGF.getContext().getObjCIdType();
4077360784Sdim    RValue result;
4078360784Sdim    CallArgList Args;
4079360784Sdim
4080360784Sdim    // TODO: If this method is inlined, the caller might know that `self` is
4081360784Sdim    // already initialized; for example, it might be an ordinary Objective-C
4082360784Sdim    // method which always receives an initialized `self`, or it might have just
4083360784Sdim    // forced initialization on its own.
4084360784Sdim    //
4085360784Sdim    // We should find a way to eliminate this unnecessary initialization in such
4086360784Sdim    // cases in LLVM.
4087360784Sdim    result = GeneratePossiblySpecializedMessageSend(
4088360784Sdim        CGF, ReturnValueSlot(), ResultType, SelfSel, selfValue, Args, OID,
4089360784Sdim        nullptr, true);
4090360784Sdim    Builder.CreateStore(result.getScalarVal(), selfAddr);
4091360784Sdim
4092360784Sdim    // Nullable `Class` expressions cannot be messaged with a direct method
4093360784Sdim    // so the only reason why the receive can be null would be because
4094360784Sdim    // of weak linking.
4095360784Sdim    ReceiverCanBeNull = isWeakLinkedClass(OID);
4096360784Sdim  }
4097360784Sdim
4098360784Sdim  if (ReceiverCanBeNull) {
4099360784Sdim    llvm::BasicBlock *SelfIsNilBlock =
4100360784Sdim        CGF.createBasicBlock("objc_direct_method.self_is_nil");
4101360784Sdim    llvm::BasicBlock *ContBlock =
4102360784Sdim        CGF.createBasicBlock("objc_direct_method.cont");
4103360784Sdim
4104360784Sdim    // if (self == nil) {
4105360784Sdim    auto selfTy = cast<llvm::PointerType>(selfValue->getType());
4106360784Sdim    auto Zero = llvm::ConstantPointerNull::get(selfTy);
4107360784Sdim
4108360784Sdim    llvm::MDBuilder MDHelper(CGM.getLLVMContext());
4109360784Sdim    Builder.CreateCondBr(Builder.CreateICmpEQ(selfValue, Zero), SelfIsNilBlock,
4110360784Sdim                         ContBlock, MDHelper.createBranchWeights(1, 1 << 20));
4111360784Sdim
4112360784Sdim    CGF.EmitBlock(SelfIsNilBlock);
4113360784Sdim
4114360784Sdim    //   return (ReturnType){ };
4115360784Sdim    auto retTy = OMD->getReturnType();
4116360784Sdim    Builder.SetInsertPoint(SelfIsNilBlock);
4117360784Sdim    if (!retTy->isVoidType()) {
4118360784Sdim      CGF.EmitNullInitialization(CGF.ReturnValue, retTy);
4119360784Sdim    }
4120360784Sdim    CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
4121360784Sdim    // }
4122360784Sdim
4123360784Sdim    // rest of the body
4124360784Sdim    CGF.EmitBlock(ContBlock);
4125360784Sdim    Builder.SetInsertPoint(ContBlock);
4126360784Sdim  }
4127360784Sdim
4128360784Sdim  // only synthesize _cmd if it's referenced
4129360784Sdim  if (OMD->getCmdDecl()->isUsed()) {
4130360784Sdim    Builder.CreateStore(GetSelector(CGF, OMD),
4131360784Sdim                        CGF.GetAddrOfLocalVar(OMD->getCmdDecl()));
4132360784Sdim  }
4133360784Sdim}
4134360784Sdim
4135276479Sdimllvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4136314564Sdim                                               ConstantStructBuilder &Init,
4137314564Sdim                                                         StringRef Section,
4138314564Sdim                                                         CharUnits Align,
4139314564Sdim                                                         bool AddToUsed) {
4140353358Sdim  llvm::GlobalValue::LinkageTypes LT =
4141353358Sdim      getLinkageTypeForObjCMetadata(CGM, Section);
4142314564Sdim  llvm::GlobalVariable *GV =
4143353358Sdim      Init.finishAndCreateGlobal(Name, Align, /*constant*/ false, LT);
4144314564Sdim  if (!Section.empty())
4145314564Sdim    GV->setSection(Section);
4146314564Sdim  if (AddToUsed)
4147314564Sdim    CGM.addCompilerUsedGlobal(GV);
4148314564Sdim  return GV;
4149314564Sdim}
4150314564Sdim
4151314564Sdimllvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
4152276479Sdim                                                         llvm::Constant *Init,
4153276479Sdim                                                         StringRef Section,
4154296417Sdim                                                         CharUnits Align,
4155276479Sdim                                                         bool AddToUsed) {
4156226633Sdim  llvm::Type *Ty = Init->getType();
4157353358Sdim  llvm::GlobalValue::LinkageTypes LT =
4158353358Sdim      getLinkageTypeForObjCMetadata(CGM, Section);
4159198092Srdivacky  llvm::GlobalVariable *GV =
4160353358Sdim      new llvm::GlobalVariable(CGM.getModule(), Ty, false, LT, Init, Name);
4161276479Sdim  if (!Section.empty())
4162193326Sed    GV->setSection(Section);
4163360784Sdim  GV->setAlignment(Align.getAsAlign());
4164193326Sed  if (AddToUsed)
4165276479Sdim    CGM.addCompilerUsedGlobal(GV);
4166193326Sed  return GV;
4167193326Sed}
4168193326Sed
4169314564Sdimllvm::GlobalVariable *
4170314564SdimCGObjCCommonMac::CreateCStringLiteral(StringRef Name, ObjCLabelType Type,
4171314564Sdim                                      bool ForceNonFragileABI,
4172314564Sdim                                      bool NullTerminate) {
4173314564Sdim  StringRef Label;
4174314564Sdim  switch (Type) {
4175314564Sdim  case ObjCLabelType::ClassName:     Label = "OBJC_CLASS_NAME_"; break;
4176314564Sdim  case ObjCLabelType::MethodVarName: Label = "OBJC_METH_VAR_NAME_"; break;
4177314564Sdim  case ObjCLabelType::MethodVarType: Label = "OBJC_METH_VAR_TYPE_"; break;
4178314564Sdim  case ObjCLabelType::PropertyName:  Label = "OBJC_PROP_NAME_ATTR_"; break;
4179314564Sdim  }
4180314564Sdim
4181314564Sdim  bool NonFragile = ForceNonFragileABI || isNonFragileABI();
4182314564Sdim
4183314564Sdim  StringRef Section;
4184314564Sdim  switch (Type) {
4185314564Sdim  case ObjCLabelType::ClassName:
4186314564Sdim    Section = NonFragile ? "__TEXT,__objc_classname,cstring_literals"
4187314564Sdim                         : "__TEXT,__cstring,cstring_literals";
4188314564Sdim    break;
4189314564Sdim  case ObjCLabelType::MethodVarName:
4190314564Sdim    Section = NonFragile ? "__TEXT,__objc_methname,cstring_literals"
4191314564Sdim                         : "__TEXT,__cstring,cstring_literals";
4192314564Sdim    break;
4193314564Sdim  case ObjCLabelType::MethodVarType:
4194314564Sdim    Section = NonFragile ? "__TEXT,__objc_methtype,cstring_literals"
4195314564Sdim                         : "__TEXT,__cstring,cstring_literals";
4196314564Sdim    break;
4197314564Sdim  case ObjCLabelType::PropertyName:
4198314564Sdim    Section = "__TEXT,__cstring,cstring_literals";
4199314564Sdim    break;
4200314564Sdim  }
4201314564Sdim
4202314564Sdim  llvm::Constant *Value =
4203314564Sdim      llvm::ConstantDataArray::getString(VMContext, Name, NullTerminate);
4204314564Sdim  llvm::GlobalVariable *GV =
4205314564Sdim      new llvm::GlobalVariable(CGM.getModule(), Value->getType(),
4206314564Sdim                               /*isConstant=*/true,
4207314564Sdim                               llvm::GlobalValue::PrivateLinkage, Value, Label);
4208314564Sdim  if (CGM.getTriple().isOSBinFormatMachO())
4209314564Sdim    GV->setSection(Section);
4210314564Sdim  GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4211360784Sdim  GV->setAlignment(CharUnits::One().getAsAlign());
4212314564Sdim  CGM.addCompilerUsedGlobal(GV);
4213314564Sdim
4214314564Sdim  return GV;
4215314564Sdim}
4216314564Sdim
4217198092Srdivackyllvm::Function *CGObjCMac::ModuleInitFunction() {
4218193326Sed  // Abuse this interface function as a place to finalize.
4219193326Sed  FinishModule();
4220276479Sdim  return nullptr;
4221193326Sed}
4222193326Sed
4223353358Sdimllvm::FunctionCallee CGObjCMac::GetPropertyGetFunction() {
4224193326Sed  return ObjCTypes.getGetPropertyFn();
4225193326Sed}
4226193326Sed
4227353358Sdimllvm::FunctionCallee CGObjCMac::GetPropertySetFunction() {
4228193326Sed  return ObjCTypes.getSetPropertyFn();
4229193326Sed}
4230193326Sed
4231353358Sdimllvm::FunctionCallee CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
4232353358Sdim                                                                bool copy) {
4233234353Sdim  return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
4234234353Sdim}
4235234353Sdim
4236353358Sdimllvm::FunctionCallee CGObjCMac::GetGetStructFunction() {
4237207619Srdivacky  return ObjCTypes.getCopyStructFn();
4238207619Srdivacky}
4239309124Sdim
4240353358Sdimllvm::FunctionCallee CGObjCMac::GetSetStructFunction() {
4241218893Sdim  return ObjCTypes.getCopyStructFn();
4242218893Sdim}
4243207619Srdivacky
4244353358Sdimllvm::FunctionCallee CGObjCMac::GetCppAtomicObjectGetFunction() {
4245234353Sdim  return ObjCTypes.getCppAtomicObjectFunction();
4246234353Sdim}
4247309124Sdim
4248353358Sdimllvm::FunctionCallee CGObjCMac::GetCppAtomicObjectSetFunction() {
4249249423Sdim  return ObjCTypes.getCppAtomicObjectFunction();
4250249423Sdim}
4251234353Sdim
4252353358Sdimllvm::FunctionCallee CGObjCMac::EnumerationMutationFunction() {
4253193326Sed  return ObjCTypes.getEnumerationMutationFn();
4254193326Sed}
4255193326Sed
4256210299Sedvoid CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
4257210299Sed  return EmitTryOrSynchronizedStmt(CGF, S);
4258210299Sed}
4259210299Sed
4260210299Sedvoid CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
4261210299Sed                                     const ObjCAtSynchronizedStmt &S) {
4262210299Sed  return EmitTryOrSynchronizedStmt(CGF, S);
4263210299Sed}
4264210299Sed
4265212904Sdimnamespace {
4266296417Sdim  struct PerformFragileFinally final : EHScopeStack::Cleanup {
4267212904Sdim    const Stmt &S;
4268296417Sdim    Address SyncArgSlot;
4269296417Sdim    Address CallTryExitVar;
4270296417Sdim    Address ExceptionData;
4271212904Sdim    ObjCTypesHelper &ObjCTypes;
4272212904Sdim    PerformFragileFinally(const Stmt *S,
4273296417Sdim                          Address SyncArgSlot,
4274296417Sdim                          Address CallTryExitVar,
4275296417Sdim                          Address ExceptionData,
4276212904Sdim                          ObjCTypesHelper *ObjCTypes)
4277212904Sdim      : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
4278212904Sdim        ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
4279212904Sdim
4280276479Sdim    void Emit(CodeGenFunction &CGF, Flags flags) override {
4281212904Sdim      // Check whether we need to call objc_exception_try_exit.
4282212904Sdim      // In optimized code, this branch will always be folded.
4283212904Sdim      llvm::BasicBlock *FinallyCallExit =
4284212904Sdim        CGF.createBasicBlock("finally.call_exit");
4285212904Sdim      llvm::BasicBlock *FinallyNoCallExit =
4286212904Sdim        CGF.createBasicBlock("finally.no_call_exit");
4287212904Sdim      CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
4288212904Sdim                               FinallyCallExit, FinallyNoCallExit);
4289212904Sdim
4290212904Sdim      CGF.EmitBlock(FinallyCallExit);
4291249423Sdim      CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
4292296417Sdim                                  ExceptionData.getPointer());
4293212904Sdim
4294212904Sdim      CGF.EmitBlock(FinallyNoCallExit);
4295212904Sdim
4296212904Sdim      if (isa<ObjCAtTryStmt>(S)) {
4297212904Sdim        if (const ObjCAtFinallyStmt* FinallyStmt =
4298212904Sdim              cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
4299249423Sdim          // Don't try to do the @finally if this is an EH cleanup.
4300249423Sdim          if (flags.isForEHCleanup()) return;
4301249423Sdim
4302212904Sdim          // Save the current cleanup destination in case there's
4303212904Sdim          // control flow inside the finally statement.
4304212904Sdim          llvm::Value *CurCleanupDest =
4305212904Sdim            CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
4306212904Sdim
4307212904Sdim          CGF.EmitStmt(FinallyStmt->getFinallyBody());
4308212904Sdim
4309212904Sdim          if (CGF.HaveInsertPoint()) {
4310212904Sdim            CGF.Builder.CreateStore(CurCleanupDest,
4311212904Sdim                                    CGF.getNormalCleanupDestSlot());
4312212904Sdim          } else {
4313212904Sdim            // Currently, the end of the cleanup must always exist.
4314212904Sdim            CGF.EnsureInsertPoint();
4315212904Sdim          }
4316212904Sdim        }
4317212904Sdim      } else {
4318212904Sdim        // Emit objc_sync_exit(expr); as finally's sole statement for
4319212904Sdim        // @synchronized.
4320212904Sdim        llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
4321249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
4322212904Sdim      }
4323212904Sdim    }
4324212904Sdim  };
4325212904Sdim
4326212904Sdim  class FragileHazards {
4327212904Sdim    CodeGenFunction &CGF;
4328226633Sdim    SmallVector<llvm::Value*, 20> Locals;
4329212904Sdim    llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
4330212904Sdim
4331212904Sdim    llvm::InlineAsm *ReadHazard;
4332212904Sdim    llvm::InlineAsm *WriteHazard;
4333212904Sdim
4334212904Sdim    llvm::FunctionType *GetAsmFnType();
4335212904Sdim
4336212904Sdim    void collectLocals();
4337212904Sdim    void emitReadHazard(CGBuilderTy &Builder);
4338212904Sdim
4339212904Sdim  public:
4340212904Sdim    FragileHazards(CodeGenFunction &CGF);
4341212904Sdim
4342212904Sdim    void emitWriteHazard();
4343212904Sdim    void emitHazardsInNewBlocks();
4344212904Sdim  };
4345309124Sdim} // end anonymous namespace
4346212904Sdim
4347212904Sdim/// Create the fragile-ABI read and write hazards based on the current
4348212904Sdim/// state of the function, which is presumed to be immediately prior
4349212904Sdim/// to a @try block.  These hazards are used to maintain correct
4350212904Sdim/// semantics in the face of optimization and the fragile ABI's
4351212904Sdim/// cavalier use of setjmp/longjmp.
4352212904SdimFragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
4353212904Sdim  collectLocals();
4354212904Sdim
4355212904Sdim  if (Locals.empty()) return;
4356212904Sdim
4357212904Sdim  // Collect all the blocks in the function.
4358212904Sdim  for (llvm::Function::iterator
4359212904Sdim         I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
4360212904Sdim    BlocksBeforeTry.insert(&*I);
4361212904Sdim
4362212904Sdim  llvm::FunctionType *AsmFnTy = GetAsmFnType();
4363212904Sdim
4364212904Sdim  // Create a read hazard for the allocas.  This inhibits dead-store
4365212904Sdim  // optimizations and forces the values to memory.  This hazard is
4366212904Sdim  // inserted before any 'throwing' calls in the protected scope to
4367212904Sdim  // reflect the possibility that the variables might be read from the
4368212904Sdim  // catch block if the call throws.
4369212904Sdim  {
4370212904Sdim    std::string Constraint;
4371212904Sdim    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
4372212904Sdim      if (I) Constraint += ',';
4373212904Sdim      Constraint += "*m";
4374212904Sdim    }
4375212904Sdim
4376212904Sdim    ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
4377212904Sdim  }
4378212904Sdim
4379212904Sdim  // Create a write hazard for the allocas.  This inhibits folding
4380212904Sdim  // loads across the hazard.  This hazard is inserted at the
4381212904Sdim  // beginning of the catch path to reflect the possibility that the
4382212904Sdim  // variables might have been written within the protected scope.
4383212904Sdim  {
4384212904Sdim    std::string Constraint;
4385212904Sdim    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
4386212904Sdim      if (I) Constraint += ',';
4387212904Sdim      Constraint += "=*m";
4388212904Sdim    }
4389212904Sdim
4390212904Sdim    WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
4391212904Sdim  }
4392212904Sdim}
4393212904Sdim
4394212904Sdim/// Emit a write hazard at the current location.
4395212904Sdimvoid FragileHazards::emitWriteHazard() {
4396212904Sdim  if (Locals.empty()) return;
4397212904Sdim
4398249423Sdim  CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
4399212904Sdim}
4400212904Sdim
4401212904Sdimvoid FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
4402212904Sdim  assert(!Locals.empty());
4403249423Sdim  llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
4404249423Sdim  call->setDoesNotThrow();
4405249423Sdim  call->setCallingConv(CGF.getRuntimeCC());
4406212904Sdim}
4407212904Sdim
4408212904Sdim/// Emit read hazards in all the protected blocks, i.e. all the blocks
4409212904Sdim/// which have been inserted since the beginning of the try.
4410212904Sdimvoid FragileHazards::emitHazardsInNewBlocks() {
4411212904Sdim  if (Locals.empty()) return;
4412212904Sdim
4413296417Sdim  CGBuilderTy Builder(CGF, CGF.getLLVMContext());
4414212904Sdim
4415212904Sdim  // Iterate through all blocks, skipping those prior to the try.
4416212904Sdim  for (llvm::Function::iterator
4417212904Sdim         FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
4418212904Sdim    llvm::BasicBlock &BB = *FI;
4419212904Sdim    if (BlocksBeforeTry.count(&BB)) continue;
4420212904Sdim
4421212904Sdim    // Walk through all the calls in the block.
4422212904Sdim    for (llvm::BasicBlock::iterator
4423212904Sdim           BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
4424212904Sdim      llvm::Instruction &I = *BI;
4425212904Sdim
4426212904Sdim      // Ignore instructions that aren't non-intrinsic calls.
4427212904Sdim      // These are the only calls that can possibly call longjmp.
4428353358Sdim      if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I))
4429353358Sdim        continue;
4430212904Sdim      if (isa<llvm::IntrinsicInst>(I))
4431212904Sdim        continue;
4432212904Sdim
4433212904Sdim      // Ignore call sites marked nounwind.  This may be questionable,
4434212904Sdim      // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
4435353358Sdim      if (cast<llvm::CallBase>(I).doesNotThrow())
4436353358Sdim        continue;
4437212904Sdim
4438212904Sdim      // Insert a read hazard before the call.  This will ensure that
4439212904Sdim      // any writes to the locals are performed before making the
4440212904Sdim      // call.  If the call throws, then this is sufficient to
4441212904Sdim      // guarantee correctness as long as it doesn't also write to any
4442212904Sdim      // locals.
4443212904Sdim      Builder.SetInsertPoint(&BB, BI);
4444212904Sdim      emitReadHazard(Builder);
4445212904Sdim    }
4446212904Sdim  }
4447212904Sdim}
4448212904Sdim
4449296417Sdimstatic void addIfPresent(llvm::DenseSet<llvm::Value*> &S, Address V) {
4450296417Sdim  if (V.isValid()) S.insert(V.getPointer());
4451296417Sdim}
4452296417Sdim
4453212904Sdimvoid FragileHazards::collectLocals() {
4454212904Sdim  // Compute a set of allocas to ignore.
4455212904Sdim  llvm::DenseSet<llvm::Value*> AllocasToIgnore;
4456212904Sdim  addIfPresent(AllocasToIgnore, CGF.ReturnValue);
4457212904Sdim  addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
4458212904Sdim
4459212904Sdim  // Collect all the allocas currently in the function.  This is
4460212904Sdim  // probably way too aggressive.
4461212904Sdim  llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
4462212904Sdim  for (llvm::BasicBlock::iterator
4463212904Sdim         I = Entry.begin(), E = Entry.end(); I != E; ++I)
4464212904Sdim    if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
4465212904Sdim      Locals.push_back(&*I);
4466212904Sdim}
4467212904Sdim
4468212904Sdimllvm::FunctionType *FragileHazards::GetAsmFnType() {
4469226633Sdim  SmallVector<llvm::Type *, 16> tys(Locals.size());
4470223017Sdim  for (unsigned i = 0, e = Locals.size(); i != e; ++i)
4471223017Sdim    tys[i] = Locals[i]->getType();
4472223017Sdim  return llvm::FunctionType::get(CGF.VoidTy, tys, false);
4473212904Sdim}
4474212904Sdim
4475198092Srdivacky/*
4476193326Sed
4477198092Srdivacky  Objective-C setjmp-longjmp (sjlj) Exception Handling
4478198092Srdivacky  --
4479193326Sed
4480210299Sed  A catch buffer is a setjmp buffer plus:
4481210299Sed    - a pointer to the exception that was caught
4482210299Sed    - a pointer to the previous exception data buffer
4483210299Sed    - two pointers of reserved storage
4484210299Sed  Therefore catch buffers form a stack, with a pointer to the top
4485210299Sed  of the stack kept in thread-local storage.
4486210299Sed
4487210299Sed  objc_exception_try_enter pushes a catch buffer onto the EH stack.
4488210299Sed  objc_exception_try_exit pops the given catch buffer, which is
4489210299Sed    required to be the top of the EH stack.
4490210299Sed  objc_exception_throw pops the top of the EH stack, writes the
4491210299Sed    thrown exception into the appropriate field, and longjmps
4492210299Sed    to the setjmp buffer.  It crashes the process (with a printf
4493210299Sed    and an abort()) if there are no catch buffers on the stack.
4494210299Sed  objc_exception_extract just reads the exception pointer out of the
4495210299Sed    catch buffer.
4496210299Sed
4497210299Sed  There's no reason an implementation couldn't use a light-weight
4498210299Sed  setjmp here --- something like __builtin_setjmp, but API-compatible
4499210299Sed  with the heavyweight setjmp.  This will be more important if we ever
4500210299Sed  want to implement correct ObjC/C++ exception interactions for the
4501210299Sed  fragile ABI.
4502210299Sed
4503210299Sed  Note that for this use of setjmp/longjmp to be correct, we may need
4504210299Sed  to mark some local variables volatile: if a non-volatile local
4505210299Sed  variable is modified between the setjmp and the longjmp, it has
4506210299Sed  indeterminate value.  For the purposes of LLVM IR, it may be
4507210299Sed  sufficient to make loads and stores within the @try (to variables
4508210299Sed  declared outside the @try) volatile.  This is necessary for
4509210299Sed  optimized correctness, but is not currently being done; this is
4510210299Sed  being tracked as rdar://problem/8160285
4511210299Sed
4512198092Srdivacky  The basic framework for a @try-catch-finally is as follows:
4513198092Srdivacky  {
4514193326Sed  objc_exception_data d;
4515193326Sed  id _rethrow = null;
4516193326Sed  bool _call_try_exit = true;
4517198092Srdivacky
4518193326Sed  objc_exception_try_enter(&d);
4519193326Sed  if (!setjmp(d.jmp_buf)) {
4520198092Srdivacky  ... try body ...
4521193326Sed  } else {
4522198092Srdivacky  // exception path
4523198092Srdivacky  id _caught = objc_exception_extract(&d);
4524198092Srdivacky
4525198092Srdivacky  // enter new try scope for handlers
4526198092Srdivacky  if (!setjmp(d.jmp_buf)) {
4527198092Srdivacky  ... match exception and execute catch blocks ...
4528198092Srdivacky
4529198092Srdivacky  // fell off end, rethrow.
4530198092Srdivacky  _rethrow = _caught;
4531198092Srdivacky  ... jump-through-finally to finally_rethrow ...
4532198092Srdivacky  } else {
4533198092Srdivacky  // exception in catch block
4534198092Srdivacky  _rethrow = objc_exception_extract(&d);
4535198092Srdivacky  _call_try_exit = false;
4536198092Srdivacky  ... jump-through-finally to finally_rethrow ...
4537193326Sed  }
4538198092Srdivacky  }
4539193326Sed  ... jump-through-finally to finally_end ...
4540193326Sed
4541198092Srdivacky  finally:
4542193326Sed  if (_call_try_exit)
4543198092Srdivacky  objc_exception_try_exit(&d);
4544193326Sed
4545193326Sed  ... finally block ....
4546193326Sed  ... dispatch to finally destination ...
4547193326Sed
4548198092Srdivacky  finally_rethrow:
4549193326Sed  objc_exception_throw(_rethrow);
4550193326Sed
4551198092Srdivacky  finally_end:
4552198092Srdivacky  }
4553193326Sed
4554198092Srdivacky  This framework differs slightly from the one gcc uses, in that gcc
4555198092Srdivacky  uses _rethrow to determine if objc_exception_try_exit should be called
4556198092Srdivacky  and if the object should be rethrown. This breaks in the face of
4557198092Srdivacky  throwing nil and introduces unnecessary branches.
4558193326Sed
4559198092Srdivacky  We specialize this framework for a few particular circumstances:
4560193326Sed
4561198092Srdivacky  - If there are no catch blocks, then we avoid emitting the second
4562198092Srdivacky  exception handling context.
4563193326Sed
4564198092Srdivacky  - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
4565198092Srdivacky  e)) we avoid emitting the code to rethrow an uncaught exception.
4566193326Sed
4567198092Srdivacky  - FIXME: If there is no @finally block we can do a few more
4568198092Srdivacky  simplifications.
4569193326Sed
4570198092Srdivacky  Rethrows and Jumps-Through-Finally
4571198092Srdivacky  --
4572193326Sed
4573210299Sed  '@throw;' is supported by pushing the currently-caught exception
4574210299Sed  onto ObjCEHStack while the @catch blocks are emitted.
4575193326Sed
4576210299Sed  Branches through the @finally block are handled with an ordinary
4577210299Sed  normal cleanup.  We do not register an EH cleanup; fragile-ABI ObjC
4578210299Sed  exceptions are not compatible with C++ exceptions, and this is
4579210299Sed  hardly the only place where this will go wrong.
4580193326Sed
4581210299Sed  @synchronized(expr) { stmt; } is emitted as if it were:
4582210299Sed    id synch_value = expr;
4583210299Sed    objc_sync_enter(synch_value);
4584210299Sed    @try { stmt; } @finally { objc_sync_exit(synch_value); }
4585193326Sed*/
4586193326Sed
4587193326Sedvoid CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
4588193326Sed                                          const Stmt &S) {
4589193326Sed  bool isTry = isa<ObjCAtTryStmt>(S);
4590198092Srdivacky
4591210299Sed  // A destination for the fall-through edges of the catch handlers to
4592210299Sed  // jump to.
4593210299Sed  CodeGenFunction::JumpDest FinallyEnd =
4594210299Sed    CGF.getJumpDestInCurrentScope("finally.end");
4595210299Sed
4596210299Sed  // A destination for the rethrow edge of the catch handlers to jump
4597210299Sed  // to.
4598210299Sed  CodeGenFunction::JumpDest FinallyRethrow =
4599210299Sed    CGF.getJumpDestInCurrentScope("finally.rethrow");
4600210299Sed
4601193326Sed  // For @synchronized, call objc_sync_enter(sync.expr). The
4602193326Sed  // evaluation of the expression must occur before we enter the
4603212904Sdim  // @synchronized.  We can't avoid a temp here because we need the
4604212904Sdim  // value to be preserved.  If the backend ever does liveness
4605212904Sdim  // correctly after setjmp, this will be unnecessary.
4606296417Sdim  Address SyncArgSlot = Address::invalid();
4607193326Sed  if (!isTry) {
4608212904Sdim    llvm::Value *SyncArg =
4609193326Sed      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
4610193326Sed    SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
4611249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
4612212904Sdim
4613296417Sdim    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(),
4614296417Sdim                                       CGF.getPointerAlign(), "sync.arg");
4615212904Sdim    CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
4616193326Sed  }
4617193326Sed
4618212904Sdim  // Allocate memory for the setjmp buffer.  This needs to be kept
4619212904Sdim  // live throughout the try and catch blocks.
4620296417Sdim  Address ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
4621296417Sdim                                               CGF.getPointerAlign(),
4622296417Sdim                                               "exceptiondata.ptr");
4623210299Sed
4624212904Sdim  // Create the fragile hazards.  Note that this will not capture any
4625212904Sdim  // of the allocas required for exception processing, but will
4626212904Sdim  // capture the current basic block (which extends all the way to the
4627212904Sdim  // setjmp call) as "before the @try".
4628212904Sdim  FragileHazards Hazards(CGF);
4629212904Sdim
4630210299Sed  // Create a flag indicating whether the cleanup needs to call
4631210299Sed  // objc_exception_try_exit.  This is true except when
4632210299Sed  //   - no catches match and we're branching through the cleanup
4633210299Sed  //     just to rethrow the exception, or
4634210299Sed  //   - a catch matched and we're falling out of the catch handler.
4635212904Sdim  // The setjmp-safety rule here is that we should always store to this
4636212904Sdim  // variable in a place that dominates the branch through the cleanup
4637212904Sdim  // without passing through any setjmps.
4638296417Sdim  Address CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
4639296417Sdim                                                CharUnits::One(),
4640296417Sdim                                                "_call_try_exit");
4641198092Srdivacky
4642218893Sdim  // A slot containing the exception to rethrow.  Only needed when we
4643218893Sdim  // have both a @catch and a @finally.
4644296417Sdim  Address PropagatingExnVar = Address::invalid();
4645218893Sdim
4646210299Sed  // Push a normal cleanup to leave the try scope.
4647249423Sdim  CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
4648212904Sdim                                                 SyncArgSlot,
4649212904Sdim                                                 CallTryExitVar,
4650212904Sdim                                                 ExceptionData,
4651212904Sdim                                                 &ObjCTypes);
4652193326Sed
4653210299Sed  // Enter a try block:
4654210299Sed  //  - Call objc_exception_try_enter to push ExceptionData on top of
4655210299Sed  //    the EH stack.
4656288943Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
4657296417Sdim                              ExceptionData.getPointer());
4658210299Sed
4659210299Sed  //  - Call setjmp on the exception data buffer.
4660210299Sed  llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
4661210299Sed  llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
4662288943Sdim  llvm::Value *SetJmpBuffer = CGF.Builder.CreateGEP(
4663296417Sdim      ObjCTypes.ExceptionDataTy, ExceptionData.getPointer(), GEPIndexes,
4664296417Sdim      "setjmp_buffer");
4665288943Sdim  llvm::CallInst *SetJmpResult = CGF.EmitNounwindRuntimeCall(
4666288943Sdim      ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
4667234353Sdim  SetJmpResult->setCanReturnTwice();
4668210299Sed
4669210299Sed  // If setjmp returned 0, enter the protected block; otherwise,
4670210299Sed  // branch to the handler.
4671193326Sed  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
4672193326Sed  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
4673210299Sed  llvm::Value *DidCatch =
4674212904Sdim    CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
4675212904Sdim  CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
4676193326Sed
4677210299Sed  // Emit the protected block.
4678193326Sed  CGF.EmitBlock(TryBlock);
4679212904Sdim  CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4680198092Srdivacky  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
4681210299Sed                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
4682198092Srdivacky
4683212904Sdim  CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
4684212904Sdim
4685210299Sed  // Emit the exception handler block.
4686193326Sed  CGF.EmitBlock(TryHandler);
4687193326Sed
4688212904Sdim  // Don't optimize loads of the in-scope locals across this point.
4689212904Sdim  Hazards.emitWriteHazard();
4690210299Sed
4691210299Sed  // For a @synchronized (or a @try with no catches), just branch
4692210299Sed  // through the cleanup to the rethrow block.
4693210299Sed  if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
4694210299Sed    // Tell the cleanup not to re-pop the exit.
4695212904Sdim    CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4696193326Sed    CGF.EmitBranchThroughCleanup(FinallyRethrow);
4697210299Sed
4698210299Sed  // Otherwise, we have to match against the caught exceptions.
4699210299Sed  } else {
4700212904Sdim    // Retrieve the exception object.  We may emit multiple blocks but
4701212904Sdim    // nothing can cross this so the value is already in SSA form.
4702212904Sdim    llvm::CallInst *Caught =
4703249423Sdim      CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4704296417Sdim                                  ExceptionData.getPointer(), "caught");
4705212904Sdim
4706210299Sed    // Push the exception to rethrow onto the EH value stack for the
4707210299Sed    // benefit of any @throws in the handlers.
4708210299Sed    CGF.ObjCEHValueStack.push_back(Caught);
4709210299Sed
4710207619Srdivacky    const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
4711198092Srdivacky
4712276479Sdim    bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
4713193326Sed
4714276479Sdim    llvm::BasicBlock *CatchBlock = nullptr;
4715276479Sdim    llvm::BasicBlock *CatchHandler = nullptr;
4716212904Sdim    if (HasFinally) {
4717218893Sdim      // Save the currently-propagating exception before
4718218893Sdim      // objc_exception_try_enter clears the exception slot.
4719218893Sdim      PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
4720296417Sdim                                               CGF.getPointerAlign(),
4721218893Sdim                                               "propagating_exception");
4722218893Sdim      CGF.Builder.CreateStore(Caught, PropagatingExnVar);
4723218893Sdim
4724212904Sdim      // Enter a new exception try block (in case a @catch block
4725212904Sdim      // throws an exception).
4726249423Sdim      CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
4727296417Sdim                                  ExceptionData.getPointer());
4728210299Sed
4729212904Sdim      llvm::CallInst *SetJmpResult =
4730249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(),
4731249423Sdim                                    SetJmpBuffer, "setjmp.result");
4732234353Sdim      SetJmpResult->setCanReturnTwice();
4733198092Srdivacky
4734212904Sdim      llvm::Value *Threw =
4735212904Sdim        CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
4736198092Srdivacky
4737212904Sdim      CatchBlock = CGF.createBasicBlock("catch");
4738212904Sdim      CatchHandler = CGF.createBasicBlock("catch_for_catch");
4739212904Sdim      CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
4740212904Sdim
4741212904Sdim      CGF.EmitBlock(CatchBlock);
4742212904Sdim    }
4743212904Sdim
4744212904Sdim    CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
4745212904Sdim
4746193326Sed    // Handle catch list. As a special case we check if everything is
4747193326Sed    // matched and avoid generating code for falling off the end if
4748193326Sed    // so.
4749193326Sed    bool AllMatched = false;
4750207619Srdivacky    for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
4751207619Srdivacky      const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
4752193326Sed
4753207619Srdivacky      const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
4754276479Sdim      const ObjCObjectPointerType *OPT = nullptr;
4755193326Sed
4756193326Sed      // catch(...) always matches.
4757193326Sed      if (!CatchParam) {
4758193326Sed        AllMatched = true;
4759193326Sed      } else {
4760198092Srdivacky        OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
4761198092Srdivacky
4762210299Sed        // catch(id e) always matches under this ABI, since only
4763210299Sed        // ObjC exceptions end up here in the first place.
4764193326Sed        // FIXME: For the time being we also match id<X>; this should
4765193326Sed        // be rejected by Sema instead.
4766198092Srdivacky        if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
4767193326Sed          AllMatched = true;
4768193326Sed      }
4769198092Srdivacky
4770210299Sed      // If this is a catch-all, we don't need to test anything.
4771198092Srdivacky      if (AllMatched) {
4772210299Sed        CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4773210299Sed
4774193326Sed        if (CatchParam) {
4775218893Sdim          CGF.EmitAutoVarDecl(*CatchParam);
4776193326Sed          assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4777210299Sed
4778210299Sed          // These types work out because ConvertType(id) == i8*.
4779296417Sdim          EmitInitOfCatchParam(CGF, Caught, CatchParam);
4780193326Sed        }
4781198092Srdivacky
4782193326Sed        CGF.EmitStmt(CatchStmt->getCatchBody());
4783210299Sed
4784210299Sed        // The scope of the catch variable ends right here.
4785210299Sed        CatchVarCleanups.ForceCleanup();
4786210299Sed
4787193326Sed        CGF.EmitBranchThroughCleanup(FinallyEnd);
4788193326Sed        break;
4789193326Sed      }
4790198092Srdivacky
4791198092Srdivacky      assert(OPT && "Unexpected non-object pointer type in @catch");
4792208600Srdivacky      const ObjCObjectType *ObjTy = OPT->getObjectType();
4793210299Sed
4794210299Sed      // FIXME: @catch (Class c) ?
4795208600Srdivacky      ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
4796208600Srdivacky      assert(IDecl && "Catch parameter must have Objective-C type!");
4797193326Sed
4798193326Sed      // Check if the @catch block matches the exception object.
4799249423Sdim      llvm::Value *Class = EmitClassRef(CGF, IDecl);
4800198092Srdivacky
4801249423Sdim      llvm::Value *matchArgs[] = { Class, Caught };
4802210299Sed      llvm::CallInst *Match =
4803249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionMatchFn(),
4804249423Sdim                                    matchArgs, "match");
4805198092Srdivacky
4806210299Sed      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
4807210299Sed      llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
4808198092Srdivacky
4809198092Srdivacky      CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
4810193326Sed                               MatchedBlock, NextCatchBlock);
4811198092Srdivacky
4812193326Sed      // Emit the @catch block.
4813193326Sed      CGF.EmitBlock(MatchedBlock);
4814210299Sed
4815210299Sed      // Collect any cleanups for the catch variable.  The scope lasts until
4816210299Sed      // the end of the catch body.
4817212904Sdim      CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4818210299Sed
4819218893Sdim      CGF.EmitAutoVarDecl(*CatchParam);
4820193326Sed      assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4821193326Sed
4822210299Sed      // Initialize the catch variable.
4823198092Srdivacky      llvm::Value *Tmp =
4824198092Srdivacky        CGF.Builder.CreateBitCast(Caught,
4825226633Sdim                                  CGF.ConvertType(CatchParam->getType()));
4826296417Sdim      EmitInitOfCatchParam(CGF, Tmp, CatchParam);
4827198092Srdivacky
4828193326Sed      CGF.EmitStmt(CatchStmt->getCatchBody());
4829210299Sed
4830210299Sed      // We're done with the catch variable.
4831210299Sed      CatchVarCleanups.ForceCleanup();
4832210299Sed
4833193326Sed      CGF.EmitBranchThroughCleanup(FinallyEnd);
4834198092Srdivacky
4835193326Sed      CGF.EmitBlock(NextCatchBlock);
4836193326Sed    }
4837193326Sed
4838210299Sed    CGF.ObjCEHValueStack.pop_back();
4839210299Sed
4840212904Sdim    // If nothing wanted anything to do with the caught exception,
4841212904Sdim    // kill the extract call.
4842212904Sdim    if (Caught->use_empty())
4843212904Sdim      Caught->eraseFromParent();
4844212904Sdim
4845212904Sdim    if (!AllMatched)
4846193326Sed      CGF.EmitBranchThroughCleanup(FinallyRethrow);
4847198092Srdivacky
4848212904Sdim    if (HasFinally) {
4849212904Sdim      // Emit the exception handler for the @catch blocks.
4850212904Sdim      CGF.EmitBlock(CatchHandler);
4851210299Sed
4852212904Sdim      // In theory we might now need a write hazard, but actually it's
4853212904Sdim      // unnecessary because there's no local-accessing code between
4854212904Sdim      // the try's write hazard and here.
4855212904Sdim      //Hazards.emitWriteHazard();
4856210299Sed
4857218893Sdim      // Extract the new exception and save it to the
4858218893Sdim      // propagating-exception slot.
4859296417Sdim      assert(PropagatingExnVar.isValid());
4860218893Sdim      llvm::CallInst *NewCaught =
4861249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4862296417Sdim                                    ExceptionData.getPointer(), "caught");
4863218893Sdim      CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
4864218893Sdim
4865212904Sdim      // Don't pop the catch handler; the throw already did.
4866212904Sdim      CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4867212904Sdim      CGF.EmitBranchThroughCleanup(FinallyRethrow);
4868212904Sdim    }
4869193326Sed  }
4870198092Srdivacky
4871212904Sdim  // Insert read hazards as required in the new blocks.
4872212904Sdim  Hazards.emitHazardsInNewBlocks();
4873212904Sdim
4874210299Sed  // Pop the cleanup.
4875212904Sdim  CGF.Builder.restoreIP(TryFallthroughIP);
4876212904Sdim  if (CGF.HaveInsertPoint())
4877212904Sdim    CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4878210299Sed  CGF.PopCleanupBlock();
4879212904Sdim  CGF.EmitBlock(FinallyEnd.getBlock(), true);
4880193326Sed
4881210299Sed  // Emit the rethrow block.
4882212904Sdim  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
4883212904Sdim  CGF.EmitBlock(FinallyRethrow.getBlock(), true);
4884210299Sed  if (CGF.HaveInsertPoint()) {
4885218893Sdim    // If we have a propagating-exception variable, check it.
4886218893Sdim    llvm::Value *PropagatingExn;
4887296417Sdim    if (PropagatingExnVar.isValid()) {
4888218893Sdim      PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
4889212904Sdim
4890218893Sdim    // Otherwise, just look in the buffer for the exception to throw.
4891218893Sdim    } else {
4892218893Sdim      llvm::CallInst *Caught =
4893249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4894296417Sdim                                    ExceptionData.getPointer());
4895218893Sdim      PropagatingExn = Caught;
4896218893Sdim    }
4897218893Sdim
4898249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
4899249423Sdim                                PropagatingExn);
4900210299Sed    CGF.Builder.CreateUnreachable();
4901193326Sed  }
4902193326Sed
4903212904Sdim  CGF.Builder.restoreIP(SavedIP);
4904193326Sed}
4905193326Sed
4906193326Sedvoid CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
4907249423Sdim                              const ObjCAtThrowStmt &S,
4908249423Sdim                              bool ClearInsertionPoint) {
4909193326Sed  llvm::Value *ExceptionAsObject;
4910198092Srdivacky
4911193326Sed  if (const Expr *ThrowExpr = S.getThrowExpr()) {
4912226633Sdim    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
4913198092Srdivacky    ExceptionAsObject =
4914226633Sdim      CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4915193326Sed  } else {
4916198092Srdivacky    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
4917193326Sed           "Unexpected rethrow outside @catch block.");
4918193326Sed    ExceptionAsObject = CGF.ObjCEHValueStack.back();
4919193326Sed  }
4920198092Srdivacky
4921249423Sdim  CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4922210299Sed    ->setDoesNotReturn();
4923193326Sed  CGF.Builder.CreateUnreachable();
4924193326Sed
4925193326Sed  // Clear the insertion point to indicate we are in unreachable code.
4926249423Sdim  if (ClearInsertionPoint)
4927249423Sdim    CGF.Builder.ClearInsertionPoint();
4928193326Sed}
4929193326Sed
4930193326Sed/// EmitObjCWeakRead - Code gen for loading value of a __weak
4931193326Sed/// object: objc_read_weak (id *src)
4932193326Sed///
4933193326Sedllvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
4934296417Sdim                                          Address AddrWeakObj) {
4935296417Sdim  llvm::Type* DestTy = AddrWeakObj.getElementType();
4936198092Srdivacky  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
4937198092Srdivacky                                          ObjCTypes.PtrObjectPtrTy);
4938249423Sdim  llvm::Value *read_weak =
4939249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
4940296417Sdim                                AddrWeakObj.getPointer(), "weakread");
4941193326Sed  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
4942193326Sed  return read_weak;
4943193326Sed}
4944193326Sed
4945193326Sed/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4946193326Sed/// objc_assign_weak (id src, id *dst)
4947193326Sed///
4948193326Sedvoid CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
4949296417Sdim                                   llvm::Value *src, Address dst) {
4950226633Sdim  llvm::Type * SrcTy = src->getType();
4951193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
4952243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4953193326Sed    assert(Size <= 8 && "does not support size > 8");
4954314564Sdim    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4955314564Sdim                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4956193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4957193326Sed  }
4958193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4959193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4960296417Sdim  llvm::Value *args[] = { src, dst.getPointer() };
4961249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4962249423Sdim                              args, "weakassign");
4963193326Sed}
4964193326Sed
4965193326Sed/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4966193326Sed/// objc_assign_global (id src, id *dst)
4967193326Sed///
4968193326Sedvoid CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4969296417Sdim                                     llvm::Value *src, Address dst,
4970212904Sdim                                     bool threadlocal) {
4971226633Sdim  llvm::Type * SrcTy = src->getType();
4972193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
4973243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4974193326Sed    assert(Size <= 8 && "does not support size > 8");
4975314564Sdim    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
4976314564Sdim                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
4977193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4978193326Sed  }
4979193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4980193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4981296417Sdim  llvm::Value *args[] = { src, dst.getPointer() };
4982212904Sdim  if (!threadlocal)
4983249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4984249423Sdim                                args, "globalassign");
4985212904Sdim  else
4986249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4987249423Sdim                                args, "threadlocalassign");
4988193326Sed}
4989193326Sed
4990193326Sed/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
4991198092Srdivacky/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
4992193326Sed///
4993193326Sedvoid CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4994296417Sdim                                   llvm::Value *src, Address dst,
4995198092Srdivacky                                   llvm::Value *ivarOffset) {
4996198092Srdivacky  assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
4997226633Sdim  llvm::Type * SrcTy = src->getType();
4998193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
4999243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5000193326Sed    assert(Size <= 8 && "does not support size > 8");
5001314564Sdim    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5002314564Sdim                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5003193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5004193326Sed  }
5005193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5006193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5007296417Sdim  llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
5008249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
5009193326Sed}
5010193326Sed
5011193326Sed/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
5012193326Sed/// objc_assign_strongCast (id src, id *dst)
5013193326Sed///
5014193326Sedvoid CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
5015296417Sdim                                         llvm::Value *src, Address dst) {
5016226633Sdim  llvm::Type * SrcTy = src->getType();
5017193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
5018243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
5019193326Sed    assert(Size <= 8 && "does not support size > 8");
5020314564Sdim    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, CGM.Int32Ty)
5021314564Sdim                      : CGF.Builder.CreateBitCast(src, CGM.Int64Ty);
5022193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
5023193326Sed  }
5024193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
5025193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
5026296417Sdim  llvm::Value *args[] = { src, dst.getPointer() };
5027249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
5028296417Sdim                              args, "strongassign");
5029193326Sed}
5030193326Sed
5031198092Srdivackyvoid CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
5032296417Sdim                                         Address DestPtr,
5033296417Sdim                                         Address SrcPtr,
5034210299Sed                                         llvm::Value *size) {
5035198092Srdivacky  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
5036198092Srdivacky  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
5037296417Sdim  llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), size };
5038249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
5039198092Srdivacky}
5040198092Srdivacky
5041193326Sed/// EmitObjCValueForIvar - Code Gen for ivar reference.
5042193326Sed///
5043193326SedLValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
5044193326Sed                                       QualType ObjectTy,
5045193326Sed                                       llvm::Value *BaseValue,
5046193326Sed                                       const ObjCIvarDecl *Ivar,
5047193326Sed                                       unsigned CVRQualifiers) {
5048208600Srdivacky  const ObjCInterfaceDecl *ID =
5049360784Sdim    ObjectTy->castAs<ObjCObjectType>()->getInterface();
5050193326Sed  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
5051193326Sed                                  EmitIvarOffset(CGF, ID, Ivar));
5052193326Sed}
5053193326Sed
5054193326Sedllvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
5055193326Sed                                       const ObjCInterfaceDecl *Interface,
5056193326Sed                                       const ObjCIvarDecl *Ivar) {
5057193326Sed  uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
5058193326Sed  return llvm::ConstantInt::get(
5059198092Srdivacky    CGM.getTypes().ConvertType(CGM.getContext().LongTy),
5060198092Srdivacky    Offset);
5061193326Sed}
5062193326Sed
5063193326Sed/* *** Private Interface *** */
5064193326Sed
5065321369Sdimstd::string CGObjCCommonMac::GetSectionName(StringRef Section,
5066321369Sdim                                            StringRef MachOAttributes) {
5067321369Sdim  switch (CGM.getTriple().getObjectFormat()) {
5068353358Sdim  case llvm::Triple::UnknownObjectFormat:
5069321369Sdim    llvm_unreachable("unexpected object file format");
5070321369Sdim  case llvm::Triple::MachO: {
5071321369Sdim    if (MachOAttributes.empty())
5072321369Sdim      return ("__DATA," + Section).str();
5073321369Sdim    return ("__DATA," + Section + "," + MachOAttributes).str();
5074321369Sdim  }
5075321369Sdim  case llvm::Triple::ELF:
5076321369Sdim    assert(Section.substr(0, 2) == "__" &&
5077321369Sdim           "expected the name to begin with __");
5078321369Sdim    return Section.substr(2).str();
5079321369Sdim  case llvm::Triple::COFF:
5080321369Sdim    assert(Section.substr(0, 2) == "__" &&
5081321369Sdim           "expected the name to begin with __");
5082321369Sdim    return ("." + Section.substr(2) + "$B").str();
5083353358Sdim  case llvm::Triple::Wasm:
5084353358Sdim  case llvm::Triple::XCOFF:
5085353358Sdim    llvm::report_fatal_error(
5086353358Sdim        "Objective-C support is unimplemented for object file format.");
5087321369Sdim  }
5088353358Sdim
5089353358Sdim  llvm_unreachable("Unhandled llvm::Triple::ObjectFormatType enum");
5090321369Sdim}
5091321369Sdim
5092193326Sed/// EmitImageInfo - Emit the image info marker used to encode some module
5093193326Sed/// level information.
5094193326Sed///
5095193326Sed/// See: <rdr://4810609&4810587&4810587>
5096193326Sed/// struct IMAGE_INFO {
5097193326Sed///   unsigned version;
5098193326Sed///   unsigned flags;
5099193326Sed/// };
5100193326Sedenum ImageInfoFlags {
5101276479Sdim  eImageInfo_FixAndContinue      = (1 << 0), // This flag is no longer set by clang.
5102198092Srdivacky  eImageInfo_GarbageCollected    = (1 << 1),
5103198092Srdivacky  eImageInfo_GCOnly              = (1 << 2),
5104276479Sdim  eImageInfo_OptimizedByDyld     = (1 << 3), // This flag is set by the dyld shared cache.
5105193326Sed
5106207619Srdivacky  // A flag indicating that the module has no instances of a @synthesize of a
5107207619Srdivacky  // superclass variable. <rdar://problem/6803242>
5108276479Sdim  eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
5109309124Sdim  eImageInfo_ImageIsSimulated    = (1 << 5),
5110309124Sdim  eImageInfo_ClassProperties     = (1 << 6)
5111193326Sed};
5112193326Sed
5113207619Srdivackyvoid CGObjCCommonMac::EmitImageInfo() {
5114193326Sed  unsigned version = 0; // Version is unused?
5115321369Sdim  std::string Section =
5116321369Sdim      (ObjCABI == 1)
5117321369Sdim          ? "__OBJC,__image_info,regular"
5118321369Sdim          : GetSectionName("__objc_imageinfo", "regular,no_dead_strip");
5119193326Sed
5120234353Sdim  // Generate module-level named metadata to convey this information to the
5121234353Sdim  // linker and code-gen.
5122234353Sdim  llvm::Module &Mod = CGM.getModule();
5123198092Srdivacky
5124234353Sdim  // Add the ObjC ABI version to the module flags.
5125234353Sdim  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
5126234353Sdim  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
5127234353Sdim                    version);
5128234353Sdim  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
5129321369Sdim                    llvm::MDString::get(VMContext, Section));
5130193326Sed
5131234353Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5132234353Sdim    // Non-GC overrides those files which specify GC.
5133234353Sdim    Mod.addModuleFlag(llvm::Module::Override,
5134234353Sdim                      "Objective-C Garbage Collection", (uint32_t)0);
5135234353Sdim  } else {
5136234353Sdim    // Add the ObjC garbage collection value.
5137234353Sdim    Mod.addModuleFlag(llvm::Module::Error,
5138234353Sdim                      "Objective-C Garbage Collection",
5139234353Sdim                      eImageInfo_GarbageCollected);
5140193326Sed
5141234353Sdim    if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
5142234353Sdim      // Add the ObjC GC Only value.
5143234353Sdim      Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
5144234353Sdim                        eImageInfo_GCOnly);
5145234353Sdim
5146234353Sdim      // Require that GC be specified and set to eImageInfo_GarbageCollected.
5147280031Sdim      llvm::Metadata *Ops[2] = {
5148280031Sdim          llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
5149280031Sdim          llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
5150280031Sdim              llvm::Type::getInt32Ty(VMContext), eImageInfo_GarbageCollected))};
5151234353Sdim      Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
5152234353Sdim                        llvm::MDNode::get(VMContext, Ops));
5153234353Sdim    }
5154234353Sdim  }
5155239462Sdim
5156239462Sdim  // Indicate whether we're compiling this to run on a simulator.
5157327952Sdim  if (CGM.getTarget().getTriple().isSimulatorEnvironment())
5158239462Sdim    Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
5159239462Sdim                      eImageInfo_ImageIsSimulated);
5160309124Sdim
5161309124Sdim  // Indicate whether we are generating class properties.
5162309124Sdim  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Class Properties",
5163309124Sdim                    eImageInfo_ClassProperties);
5164193326Sed}
5165193326Sed
5166193326Sed// struct objc_module {
5167193326Sed//   unsigned long version;
5168193326Sed//   unsigned long size;
5169193326Sed//   const char *name;
5170193326Sed//   Symtab symtab;
5171193326Sed// };
5172193326Sed
5173193326Sed// FIXME: Get from somewhere
5174193326Sedstatic const int ModuleVersion = 7;
5175193326Sed
5176193326Sedvoid CGObjCMac::EmitModuleInfo() {
5177243830Sdim  uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
5178198092Srdivacky
5179314564Sdim  ConstantInitBuilder builder(CGM);
5180314564Sdim  auto values = builder.beginStruct(ObjCTypes.ModuleTy);
5181314564Sdim  values.addInt(ObjCTypes.LongTy, ModuleVersion);
5182314564Sdim  values.addInt(ObjCTypes.LongTy, Size);
5183314564Sdim  // This used to be the filename, now it is unused. <rdr://4327263>
5184314564Sdim  values.add(GetClassName(StringRef("")));
5185314564Sdim  values.add(EmitModuleSymbols());
5186314564Sdim  CreateMetadataVar("OBJC_MODULES", values,
5187296417Sdim                    "__OBJC,__module_info,regular,no_dead_strip",
5188296417Sdim                    CGM.getPointerAlign(), true);
5189193326Sed}
5190193326Sed
5191193326Sedllvm::Constant *CGObjCMac::EmitModuleSymbols() {
5192193326Sed  unsigned NumClasses = DefinedClasses.size();
5193193326Sed  unsigned NumCategories = DefinedCategories.size();
5194193326Sed
5195193326Sed  // Return null if no symbols were defined.
5196193326Sed  if (!NumClasses && !NumCategories)
5197193326Sed    return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
5198193326Sed
5199314564Sdim  ConstantInitBuilder builder(CGM);
5200314564Sdim  auto values = builder.beginStruct();
5201314564Sdim  values.addInt(ObjCTypes.LongTy, 0);
5202314564Sdim  values.addNullPointer(ObjCTypes.SelectorPtrTy);
5203314564Sdim  values.addInt(ObjCTypes.ShortTy, NumClasses);
5204314564Sdim  values.addInt(ObjCTypes.ShortTy, NumCategories);
5205193326Sed
5206193326Sed  // The runtime expects exactly the list of defined classes followed
5207193326Sed  // by the list of defined categories, in a single array.
5208314564Sdim  auto array = values.beginArray(ObjCTypes.Int8PtrTy);
5209276479Sdim  for (unsigned i=0; i<NumClasses; i++) {
5210276479Sdim    const ObjCInterfaceDecl *ID = ImplementedClasses[i];
5211276479Sdim    assert(ID);
5212276479Sdim    if (ObjCImplementationDecl *IMP = ID->getImplementation())
5213276479Sdim      // We are implementing a weak imported interface. Give it external linkage
5214276479Sdim      if (ID->isWeakImported() && !IMP->isWeakImported())
5215276479Sdim        DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
5216314564Sdim
5217314564Sdim    array.addBitCast(DefinedClasses[i], ObjCTypes.Int8PtrTy);
5218276479Sdim  }
5219193326Sed  for (unsigned i=0; i<NumCategories; i++)
5220314564Sdim    array.addBitCast(DefinedCategories[i], ObjCTypes.Int8PtrTy);
5221193326Sed
5222314564Sdim  array.finishAndAddTo(values);
5223193326Sed
5224280031Sdim  llvm::GlobalVariable *GV = CreateMetadataVar(
5225314564Sdim      "OBJC_SYMBOLS", values, "__OBJC,__symbols,regular,no_dead_strip",
5226296417Sdim      CGM.getPointerAlign(), true);
5227193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
5228193326Sed}
5229193326Sed
5230249423Sdimllvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
5231249423Sdim                                           IdentifierInfo *II) {
5232224145Sdim  LazySymbols.insert(II);
5233341825Sdim
5234224145Sdim  llvm::GlobalVariable *&Entry = ClassReferences[II];
5235341825Sdim
5236193326Sed  if (!Entry) {
5237198092Srdivacky    llvm::Constant *Casted =
5238276479Sdim    llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
5239224145Sdim                                   ObjCTypes.ClassPtrTy);
5240280031Sdim    Entry = CreateMetadataVar(
5241280031Sdim        "OBJC_CLASS_REFERENCES_", Casted,
5242296417Sdim        "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
5243296417Sdim        CGM.getPointerAlign(), true);
5244193326Sed  }
5245341825Sdim
5246296417Sdim  return CGF.Builder.CreateAlignedLoad(Entry, CGF.getPointerAlign());
5247193326Sed}
5248193326Sed
5249249423Sdimllvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
5250224145Sdim                                     const ObjCInterfaceDecl *ID) {
5251309124Sdim  // If the class has the objc_runtime_visible attribute, we need to
5252309124Sdim  // use the Objective-C runtime to get the class.
5253309124Sdim  if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
5254309124Sdim    return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
5255309124Sdim
5256341825Sdim  IdentifierInfo *RuntimeName =
5257341825Sdim      &CGM.getContext().Idents.get(ID->getObjCRuntimeNameAsString());
5258341825Sdim  return EmitClassRefFromId(CGF, RuntimeName);
5259224145Sdim}
5260224145Sdim
5261249423Sdimllvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
5262224145Sdim  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
5263249423Sdim  return EmitClassRefFromId(CGF, II);
5264224145Sdim}
5265224145Sdim
5266296417Sdimllvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel) {
5267360784Sdim  return CGF.Builder.CreateLoad(EmitSelectorAddr(Sel));
5268296417Sdim}
5269296417Sdim
5270360784SdimAddress CGObjCMac::EmitSelectorAddr(Selector Sel) {
5271360784Sdim  CharUnits Align = CGM.getPointerAlign();
5272296417Sdim
5273193326Sed  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
5274193326Sed  if (!Entry) {
5275198092Srdivacky    llvm::Constant *Casted =
5276193326Sed      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
5277193326Sed                                     ObjCTypes.SelectorPtrTy);
5278280031Sdim    Entry = CreateMetadataVar(
5279280031Sdim        "OBJC_SELECTOR_REFERENCES_", Casted,
5280296417Sdim        "__OBJC,__message_refs,literal_pointers,no_dead_strip", Align, true);
5281249423Sdim    Entry->setExternallyInitialized(true);
5282193326Sed  }
5283193326Sed
5284296417Sdim  return Address(Entry, Align);
5285193326Sed}
5286193326Sed
5287276479Sdimllvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
5288276479Sdim    llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
5289276479Sdim    if (!Entry)
5290314564Sdim      Entry = CreateCStringLiteral(RuntimeName, ObjCLabelType::ClassName);
5291276479Sdim    return getConstantGEP(VMContext, Entry, 0, 0);
5292193326Sed}
5293193326Sed
5294212904Sdimllvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
5295212904Sdim  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
5296212904Sdim      I = MethodDefinitions.find(MD);
5297212904Sdim  if (I != MethodDefinitions.end())
5298212904Sdim    return I->second;
5299212904Sdim
5300276479Sdim  return nullptr;
5301212904Sdim}
5302212904Sdim
5303193326Sed/// GetIvarLayoutName - Returns a unique constant for the given
5304193326Sed/// ivar layout bitmap.
5305193326Sedllvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
5306198092Srdivacky                                       const ObjCCommonTypesHelper &ObjCTypes) {
5307193326Sed  return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
5308193326Sed}
5309193326Sed
5310296417Sdimvoid IvarLayoutBuilder::visitRecord(const RecordType *RT,
5311296417Sdim                                    CharUnits offset) {
5312193326Sed  const RecordDecl *RD = RT->getDecl();
5313198092Srdivacky
5314296417Sdim  // If this is a union, remember that we had one, because it might mess
5315296417Sdim  // up the ordering of layout entries.
5316296417Sdim  if (RD->isUnion())
5317296417Sdim    IsDisordered = true;
5318296417Sdim
5319296417Sdim  const ASTRecordLayout *recLayout = nullptr;
5320296417Sdim  visitAggregate(RD->field_begin(), RD->field_end(), offset,
5321296417Sdim                 [&](const FieldDecl *field) -> CharUnits {
5322296417Sdim    if (!recLayout)
5323296417Sdim      recLayout = &CGM.getContext().getASTRecordLayout(RD);
5324296417Sdim    auto offsetInBits = recLayout->getFieldOffset(field->getFieldIndex());
5325296417Sdim    return CGM.getContext().toCharUnitsFromBits(offsetInBits);
5326296417Sdim  });
5327193326Sed}
5328193326Sed
5329296417Sdimtemplate <class Iterator, class GetOffsetFn>
5330341825Sdimvoid IvarLayoutBuilder::visitAggregate(Iterator begin, Iterator end,
5331296417Sdim                                       CharUnits aggregateOffset,
5332296417Sdim                                       const GetOffsetFn &getOffset) {
5333296417Sdim  for (; begin != end; ++begin) {
5334296417Sdim    auto field = *begin;
5335198092Srdivacky
5336296417Sdim    // Skip over bitfields.
5337296417Sdim    if (field->isBitField()) {
5338193326Sed      continue;
5339193326Sed    }
5340193326Sed
5341296417Sdim    // Compute the offset of the field within the aggregate.
5342296417Sdim    CharUnits fieldOffset = aggregateOffset + getOffset(field);
5343193326Sed
5344296417Sdim    visitField(field, fieldOffset);
5345296417Sdim  }
5346296417Sdim}
5347198092Srdivacky
5348296417Sdim/// Collect layout information for the given fields into IvarsInfo.
5349296417Sdimvoid IvarLayoutBuilder::visitField(const FieldDecl *field,
5350296417Sdim                                   CharUnits fieldOffset) {
5351296417Sdim  QualType fieldType = field->getType();
5352198092Srdivacky
5353296417Sdim  // Drill down into arrays.
5354296417Sdim  uint64_t numElts = 1;
5355327952Sdim  if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
5356327952Sdim    numElts = 0;
5357327952Sdim    fieldType = arrayType->getElementType();
5358327952Sdim  }
5359327952Sdim  // Unlike incomplete arrays, constant arrays can be nested.
5360296417Sdim  while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
5361296417Sdim    numElts *= arrayType->getSize().getZExtValue();
5362296417Sdim    fieldType = arrayType->getElementType();
5363296417Sdim  }
5364198092Srdivacky
5365296417Sdim  assert(!fieldType->isArrayType() && "ivar of non-constant array type?");
5366296417Sdim
5367296417Sdim  // If we ended up with a zero-sized array, we've done what we can do within
5368296417Sdim  // the limits of this layout encoding.
5369296417Sdim  if (numElts == 0) return;
5370296417Sdim
5371296417Sdim  // Recurse if the base element type is a record type.
5372296417Sdim  if (auto recType = fieldType->getAs<RecordType>()) {
5373296417Sdim    size_t oldEnd = IvarsInfo.size();
5374296417Sdim
5375296417Sdim    visitRecord(recType, fieldOffset);
5376296417Sdim
5377296417Sdim    // If we have an array, replicate the first entry's layout information.
5378296417Sdim    auto numEltEntries = IvarsInfo.size() - oldEnd;
5379296417Sdim    if (numElts != 1 && numEltEntries != 0) {
5380296417Sdim      CharUnits eltSize = CGM.getContext().getTypeSizeInChars(recType);
5381296417Sdim      for (uint64_t eltIndex = 1; eltIndex != numElts; ++eltIndex) {
5382296417Sdim        // Copy the last numEltEntries onto the end of the array, adjusting
5383296417Sdim        // each for the element size.
5384296417Sdim        for (size_t i = 0; i != numEltEntries; ++i) {
5385296417Sdim          auto firstEntry = IvarsInfo[oldEnd + i];
5386296417Sdim          IvarsInfo.push_back(IvarInfo(firstEntry.Offset + eltIndex * eltSize,
5387296417Sdim                                       firstEntry.SizeInWords));
5388193326Sed        }
5389193326Sed      }
5390193326Sed    }
5391193326Sed
5392296417Sdim    return;
5393193326Sed  }
5394193326Sed
5395296417Sdim  // Classify the element type.
5396296417Sdim  Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), fieldType);
5397296417Sdim
5398296417Sdim  // If it matches what we're looking for, add an entry.
5399296417Sdim  if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
5400296417Sdim      || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
5401296417Sdim    assert(CGM.getContext().getTypeSizeInChars(fieldType)
5402296417Sdim             == CGM.getPointerSize());
5403296417Sdim    IvarsInfo.push_back(IvarInfo(fieldOffset, numElts));
5404193326Sed  }
5405193326Sed}
5406193326Sed
5407296417Sdim/// buildBitmap - This routine does the horsework of taking the offsets of
5408296417Sdim/// strong/weak references and creating a bitmap.  The bitmap is also
5409296417Sdim/// returned in the given buffer, suitable for being passed to \c dump().
5410296417Sdimllvm::Constant *IvarLayoutBuilder::buildBitmap(CGObjCCommonMac &CGObjC,
5411296417Sdim                                llvm::SmallVectorImpl<unsigned char> &buffer) {
5412296417Sdim  // The bitmap is a series of skip/scan instructions, aligned to word
5413296417Sdim  // boundaries.  The skip is performed first.
5414296417Sdim  const unsigned char MaxNibble = 0xF;
5415296417Sdim  const unsigned char SkipMask = 0xF0, SkipShift = 4;
5416296417Sdim  const unsigned char ScanMask = 0x0F, ScanShift = 0;
5417296417Sdim
5418296417Sdim  assert(!IvarsInfo.empty() && "generating bitmap for no data");
5419296417Sdim
5420296417Sdim  // Sort the ivar info on byte position in case we encounterred a
5421296417Sdim  // union nested in the ivar list.
5422296417Sdim  if (IsDisordered) {
5423296417Sdim    // This isn't a stable sort, but our algorithm should handle it fine.
5424296417Sdim    llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
5425193326Sed  } else {
5426296417Sdim    assert(std::is_sorted(IvarsInfo.begin(), IvarsInfo.end()));
5427193326Sed  }
5428296417Sdim  assert(IvarsInfo.back().Offset < InstanceEnd);
5429296417Sdim
5430296417Sdim  assert(buffer.empty());
5431296417Sdim
5432296417Sdim  // Skip the next N words.
5433296417Sdim  auto skip = [&](unsigned numWords) {
5434296417Sdim    assert(numWords > 0);
5435296417Sdim
5436296417Sdim    // Try to merge into the previous byte.  Since scans happen second, we
5437296417Sdim    // can't do this if it includes a scan.
5438296417Sdim    if (!buffer.empty() && !(buffer.back() & ScanMask)) {
5439296417Sdim      unsigned lastSkip = buffer.back() >> SkipShift;
5440296417Sdim      if (lastSkip < MaxNibble) {
5441296417Sdim        unsigned claimed = std::min(MaxNibble - lastSkip, numWords);
5442296417Sdim        numWords -= claimed;
5443296417Sdim        lastSkip += claimed;
5444296417Sdim        buffer.back() = (lastSkip << SkipShift);
5445296417Sdim      }
5446193326Sed    }
5447296417Sdim
5448296417Sdim    while (numWords >= MaxNibble) {
5449296417Sdim      buffer.push_back(MaxNibble << SkipShift);
5450296417Sdim      numWords -= MaxNibble;
5451193326Sed    }
5452296417Sdim    if (numWords) {
5453296417Sdim      buffer.push_back(numWords << SkipShift);
5454193326Sed    }
5455296417Sdim  };
5456296417Sdim
5457296417Sdim  // Scan the next N words.
5458296417Sdim  auto scan = [&](unsigned numWords) {
5459296417Sdim    assert(numWords > 0);
5460296417Sdim
5461296417Sdim    // Try to merge into the previous byte.  Since scans happen second, we can
5462296417Sdim    // do this even if it includes a skip.
5463296417Sdim    if (!buffer.empty()) {
5464296417Sdim      unsigned lastScan = (buffer.back() & ScanMask) >> ScanShift;
5465296417Sdim      if (lastScan < MaxNibble) {
5466296417Sdim        unsigned claimed = std::min(MaxNibble - lastScan, numWords);
5467296417Sdim        numWords -= claimed;
5468296417Sdim        lastScan += claimed;
5469296417Sdim        buffer.back() = (buffer.back() & SkipMask) | (lastScan << ScanShift);
5470193326Sed      }
5471193326Sed    }
5472296417Sdim
5473296417Sdim    while (numWords >= MaxNibble) {
5474296417Sdim      buffer.push_back(MaxNibble << ScanShift);
5475296417Sdim      numWords -= MaxNibble;
5476193326Sed    }
5477296417Sdim    if (numWords) {
5478296417Sdim      buffer.push_back(numWords << ScanShift);
5479296417Sdim    }
5480296417Sdim  };
5481296417Sdim
5482296417Sdim  // One past the end of the last scan.
5483296417Sdim  unsigned endOfLastScanInWords = 0;
5484296417Sdim  const CharUnits WordSize = CGM.getPointerSize();
5485296417Sdim
5486296417Sdim  // Consider all the scan requests.
5487296417Sdim  for (auto &request : IvarsInfo) {
5488296417Sdim    CharUnits beginOfScan = request.Offset - InstanceBegin;
5489296417Sdim
5490296417Sdim    // Ignore scan requests that don't start at an even multiple of the
5491296417Sdim    // word size.  We can't encode them.
5492296417Sdim    if ((beginOfScan % WordSize) != 0) continue;
5493296417Sdim
5494296417Sdim    // Ignore scan requests that start before the instance start.
5495296417Sdim    // This assumes that scans never span that boundary.  The boundary
5496296417Sdim    // isn't the true start of the ivars, because in the fragile-ARC case
5497296417Sdim    // it's rounded up to word alignment, but the test above should leave
5498296417Sdim    // us ignoring that possibility.
5499296417Sdim    if (beginOfScan.isNegative()) {
5500296417Sdim      assert(request.Offset + request.SizeInWords * WordSize <= InstanceBegin);
5501296417Sdim      continue;
5502296417Sdim    }
5503296417Sdim
5504296417Sdim    unsigned beginOfScanInWords = beginOfScan / WordSize;
5505296417Sdim    unsigned endOfScanInWords = beginOfScanInWords + request.SizeInWords;
5506296417Sdim
5507296417Sdim    // If the scan starts some number of words after the last one ended,
5508296417Sdim    // skip forward.
5509296417Sdim    if (beginOfScanInWords > endOfLastScanInWords) {
5510296417Sdim      skip(beginOfScanInWords - endOfLastScanInWords);
5511296417Sdim
5512296417Sdim    // Otherwise, start scanning where the last left off.
5513296417Sdim    } else {
5514296417Sdim      beginOfScanInWords = endOfLastScanInWords;
5515296417Sdim
5516296417Sdim      // If that leaves us with nothing to scan, ignore this request.
5517296417Sdim      if (beginOfScanInWords >= endOfScanInWords) continue;
5518296417Sdim    }
5519296417Sdim
5520296417Sdim    // Scan to the end of the request.
5521296417Sdim    assert(beginOfScanInWords < endOfScanInWords);
5522296417Sdim    scan(endOfScanInWords - beginOfScanInWords);
5523296417Sdim    endOfLastScanInWords = endOfScanInWords;
5524193326Sed  }
5525280031Sdim
5526296417Sdim  if (buffer.empty())
5527296417Sdim    return llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
5528296417Sdim
5529296417Sdim  // For GC layouts, emit a skip to the end of the allocation so that we
5530296417Sdim  // have precise information about the entire thing.  This isn't useful
5531296417Sdim  // or necessary for the ARC-style layout strings.
5532296417Sdim  if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5533296417Sdim    unsigned lastOffsetInWords =
5534296417Sdim      (InstanceEnd - InstanceBegin + WordSize - CharUnits::One()) / WordSize;
5535296417Sdim    if (lastOffsetInWords > endOfLastScanInWords) {
5536296417Sdim      skip(lastOffsetInWords - endOfLastScanInWords);
5537296417Sdim    }
5538296417Sdim  }
5539296417Sdim
5540296417Sdim  // Null terminate the string.
5541296417Sdim  buffer.push_back(0);
5542296417Sdim
5543314564Sdim  auto *Entry = CGObjC.CreateCStringLiteral(
5544314564Sdim      reinterpret_cast<char *>(buffer.data()), ObjCLabelType::ClassName);
5545296417Sdim  return getConstantGEP(CGM.getLLVMContext(), Entry, 0, 0);
5546212904Sdim}
5547198092Srdivacky
5548212904Sdim/// BuildIvarLayout - Builds ivar layout bitmap for the class
5549212904Sdim/// implementation for the __strong or __weak case.
5550212904Sdim/// The layout map displays which words in ivar list must be skipped
5551212904Sdim/// and which must be scanned by GC (see below). String is built of bytes.
5552212904Sdim/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
5553212904Sdim/// of words to skip and right nibble is count of words to scan. So, each
5554212904Sdim/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
5555212904Sdim/// represented by a 0x00 byte which also ends the string.
5556212904Sdim/// 1. when ForStrongLayout is true, following ivars are scanned:
5557212904Sdim/// - id, Class
5558212904Sdim/// - object *
5559212904Sdim/// - __strong anything
5560212904Sdim///
5561212904Sdim/// 2. When ForStrongLayout is false, following ivars are scanned:
5562212904Sdim/// - __weak anything
5563212904Sdim///
5564296417Sdimllvm::Constant *
5565296417SdimCGObjCCommonMac::BuildIvarLayout(const ObjCImplementationDecl *OMD,
5566296417Sdim                                 CharUnits beginOffset, CharUnits endOffset,
5567296417Sdim                                 bool ForStrongLayout, bool HasMRCWeakIvars) {
5568296417Sdim  // If this is MRC, and we're either building a strong layout or there
5569296417Sdim  // are no weak ivars, bail out early.
5570234353Sdim  llvm::Type *PtrTy = CGM.Int8PtrTy;
5571234353Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
5572296417Sdim      !CGM.getLangOpts().ObjCAutoRefCount &&
5573296417Sdim      (ForStrongLayout || !HasMRCWeakIvars))
5574212904Sdim    return llvm::Constant::getNullValue(PtrTy);
5575212904Sdim
5576226633Sdim  const ObjCInterfaceDecl *OI = OMD->getClassInterface();
5577296417Sdim  SmallVector<const ObjCIvarDecl*, 32> ivars;
5578296417Sdim
5579296417Sdim  // GC layout strings include the complete object layout, possibly
5580296417Sdim  // inaccurately in the non-fragile ABI; the runtime knows how to fix this
5581296417Sdim  // up.
5582296417Sdim  //
5583296417Sdim  // ARC layout strings only include the class's ivars.  In non-fragile
5584296417Sdim  // runtimes, that means starting at InstanceStart, rounded up to word
5585296417Sdim  // alignment.  In fragile runtimes, there's no InstanceStart, so it means
5586296417Sdim  // starting at the offset of the first ivar, rounded up to word alignment.
5587296417Sdim  //
5588296417Sdim  // MRC weak layout strings follow the ARC style.
5589296417Sdim  CharUnits baseOffset;
5590296417Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
5591341825Sdim    for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
5592224145Sdim         IVD; IVD = IVD->getNextIvar())
5593296417Sdim      ivars.push_back(IVD);
5594296417Sdim
5595296417Sdim    if (isNonFragileABI()) {
5596296417Sdim      baseOffset = beginOffset; // InstanceStart
5597296417Sdim    } else if (!ivars.empty()) {
5598296417Sdim      baseOffset =
5599296417Sdim        CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivars[0]));
5600296417Sdim    } else {
5601296417Sdim      baseOffset = CharUnits::Zero();
5602296417Sdim    }
5603296417Sdim
5604309124Sdim    baseOffset = baseOffset.alignTo(CGM.getPointerAlign());
5605224145Sdim  }
5606224145Sdim  else {
5607296417Sdim    CGM.getContext().DeepCollectObjCIvars(OI, true, ivars);
5608212904Sdim
5609296417Sdim    baseOffset = CharUnits::Zero();
5610224145Sdim  }
5611224145Sdim
5612296417Sdim  if (ivars.empty())
5613212904Sdim    return llvm::Constant::getNullValue(PtrTy);
5614212904Sdim
5615296417Sdim  IvarLayoutBuilder builder(CGM, baseOffset, endOffset, ForStrongLayout);
5616212904Sdim
5617296417Sdim  builder.visitAggregate(ivars.begin(), ivars.end(), CharUnits::Zero(),
5618296417Sdim                         [&](const ObjCIvarDecl *ivar) -> CharUnits {
5619296417Sdim      return CharUnits::fromQuantity(ComputeIvarBaseOffset(CGM, OMD, ivar));
5620296417Sdim  });
5621296417Sdim
5622296417Sdim  if (!builder.hasBitmapData())
5623212904Sdim    return llvm::Constant::getNullValue(PtrTy);
5624296417Sdim
5625296417Sdim  llvm::SmallVector<unsigned char, 4> buffer;
5626296417Sdim  llvm::Constant *C = builder.buildBitmap(*this, buffer);
5627341825Sdim
5628296417Sdim   if (CGM.getLangOpts().ObjCGCBitmapPrint && !buffer.empty()) {
5629198092Srdivacky    printf("\n%s ivar layout for class '%s': ",
5630193326Sed           ForStrongLayout ? "strong" : "weak",
5631276479Sdim           OMD->getClassInterface()->getName().str().c_str());
5632296417Sdim    builder.dump(buffer);
5633193326Sed  }
5634212904Sdim  return C;
5635193326Sed}
5636193326Sed
5637193326Sedllvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
5638193326Sed  llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
5639234353Sdim  // FIXME: Avoid std::string in "Sel.getAsString()"
5640193326Sed  if (!Entry)
5641314564Sdim    Entry = CreateCStringLiteral(Sel.getAsString(), ObjCLabelType::MethodVarName);
5642198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
5643193326Sed}
5644193326Sed
5645193326Sed// FIXME: Merge into a single cstring creation function.
5646193326Sedllvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
5647193326Sed  return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
5648193326Sed}
5649193326Sed
5650193326Sedllvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
5651193326Sed  std::string TypeStr;
5652193326Sed  CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
5653193326Sed
5654193326Sed  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5655193326Sed  if (!Entry)
5656314564Sdim    Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5657198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
5658193326Sed}
5659193326Sed
5660234353Sdimllvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
5661234353Sdim                                                  bool Extended) {
5662314564Sdim  std::string TypeStr =
5663314564Sdim    CGM.getContext().getObjCEncodingForMethodDecl(D, Extended);
5664193326Sed
5665193326Sed  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
5666193326Sed  if (!Entry)
5667314564Sdim    Entry = CreateCStringLiteral(TypeStr, ObjCLabelType::MethodVarType);
5668198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
5669193326Sed}
5670193326Sed
5671193326Sed// FIXME: Merge into a single cstring creation function.
5672193326Sedllvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
5673193326Sed  llvm::GlobalVariable *&Entry = PropertyNames[Ident];
5674193326Sed  if (!Entry)
5675314564Sdim    Entry = CreateCStringLiteral(Ident->getName(), ObjCLabelType::PropertyName);
5676198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
5677193326Sed}
5678193326Sed
5679193326Sed// FIXME: Merge into a single cstring creation function.
5680193326Sed// FIXME: This Decl should be more precise.
5681193326Sedllvm::Constant *
5682198092SrdivackyCGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
5683198092Srdivacky                                       const Decl *Container) {
5684314564Sdim  std::string TypeStr =
5685314564Sdim    CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container);
5686193326Sed  return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
5687193326Sed}
5688193326Sed
5689198092Srdivackyvoid CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
5690193326Sed                                       const ObjCContainerDecl *CD,
5691360784Sdim                                       SmallVectorImpl<char> &Name,
5692360784Sdim                                       bool ignoreCategoryNamespace) {
5693198398Srdivacky  llvm::raw_svector_ostream OS(Name);
5694193326Sed  assert (CD && "Missing container decl in GetNameForMethod");
5695198398Srdivacky  OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
5696198398Srdivacky     << '[' << CD->getName();
5697360784Sdim  if (!ignoreCategoryNamespace)
5698360784Sdim    if (const ObjCCategoryImplDecl *CID =
5699360784Sdim        dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
5700360784Sdim      OS << '(' << *CID << ')';
5701198398Srdivacky  OS << ' ' << D->getSelector().getAsString() << ']';
5702193326Sed}
5703193326Sed
5704193326Sedvoid CGObjCMac::FinishModule() {
5705193326Sed  EmitModuleInfo();
5706193326Sed
5707193326Sed  // Emit the dummy bodies for any protocols which were referenced but
5708193326Sed  // never defined.
5709314564Sdim  for (auto &entry : Protocols) {
5710314564Sdim    llvm::GlobalVariable *global = entry.second;
5711314564Sdim    if (global->hasInitializer())
5712193326Sed      continue;
5713193326Sed
5714314564Sdim    ConstantInitBuilder builder(CGM);
5715314564Sdim    auto values = builder.beginStruct(ObjCTypes.ProtocolTy);
5716314564Sdim    values.addNullPointer(ObjCTypes.ProtocolExtensionPtrTy);
5717314564Sdim    values.add(GetClassName(entry.first->getName()));
5718314564Sdim    values.addNullPointer(ObjCTypes.ProtocolListPtrTy);
5719314564Sdim    values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5720314564Sdim    values.addNullPointer(ObjCTypes.MethodDescriptionListPtrTy);
5721314564Sdim    values.finishAndSetAsInitializer(global);
5722314564Sdim    CGM.addCompilerUsedGlobal(global);
5723193326Sed  }
5724193326Sed
5725193326Sed  // Add assembler directives to add lazy undefined symbol references
5726193326Sed  // for classes which are referenced but not defined. This is
5727193326Sed  // important for correct linker interaction.
5728198092Srdivacky  //
5729198092Srdivacky  // FIXME: It would be nice if we had an LLVM construct for this.
5730314564Sdim  if ((!LazySymbols.empty() || !DefinedSymbols.empty()) &&
5731314564Sdim      CGM.getTriple().isOSBinFormatMachO()) {
5732234353Sdim    SmallString<256> Asm;
5733198092Srdivacky    Asm += CGM.getModule().getModuleInlineAsm();
5734198092Srdivacky    if (!Asm.empty() && Asm.back() != '\n')
5735198092Srdivacky      Asm += '\n';
5736193326Sed
5737198092Srdivacky    llvm::raw_svector_ostream OS(Asm);
5738314564Sdim    for (const auto *Sym : DefinedSymbols)
5739314564Sdim      OS << "\t.objc_class_name_" << Sym->getName() << "=0\n"
5740314564Sdim         << "\t.globl .objc_class_name_" << Sym->getName() << "\n";
5741314564Sdim    for (const auto *Sym : LazySymbols)
5742314564Sdim      OS << "\t.lazy_reference .objc_class_name_" << Sym->getName() << "\n";
5743314564Sdim    for (const auto &Category : DefinedCategoryNames)
5744314564Sdim      OS << "\t.objc_category_name_" << Category << "=0\n"
5745314564Sdim         << "\t.globl .objc_category_name_" << Category << "\n";
5746210299Sed
5747198092Srdivacky    CGM.getModule().setModuleInlineAsm(OS.str());
5748193326Sed  }
5749193326Sed}
5750193326Sed
5751198092SrdivackyCGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5752309124Sdim    : CGObjCCommonMac(cgm), ObjCTypes(cgm), ObjCEmptyCacheVar(nullptr),
5753309124Sdim      ObjCEmptyVtableVar(nullptr) {
5754193326Sed  ObjCABI = 2;
5755193326Sed}
5756193326Sed
5757193326Sed/* *** */
5758193326Sed
5759193326SedObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5760276479Sdim  : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
5761234353Sdim{
5762193326Sed  CodeGen::CodeGenTypes &Types = CGM.getTypes();
5763193326Sed  ASTContext &Ctx = CGM.getContext();
5764198092Srdivacky
5765314564Sdim  ShortTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.ShortTy));
5766314564Sdim  IntTy = CGM.IntTy;
5767314564Sdim  LongTy = cast<llvm::IntegerType>(Types.ConvertType(Ctx.LongTy));
5768234353Sdim  Int8PtrTy = CGM.Int8PtrTy;
5769234353Sdim  Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5770198092Srdivacky
5771276479Sdim  // arm64 targets use "int" ivar offset variables. All others,
5772276479Sdim  // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
5773280031Sdim  if (CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5774276479Sdim    IvarOffsetVarTy = IntTy;
5775276479Sdim  else
5776276479Sdim    IvarOffsetVarTy = LongTy;
5777276479Sdim
5778314564Sdim  ObjectPtrTy =
5779314564Sdim    cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCIdType()));
5780314564Sdim  PtrObjectPtrTy =
5781314564Sdim    llvm::PointerType::getUnqual(ObjectPtrTy);
5782314564Sdim  SelectorPtrTy =
5783314564Sdim    cast<llvm::PointerType>(Types.ConvertType(Ctx.getObjCSelType()));
5784198092Srdivacky
5785193326Sed  // I'm not sure I like this. The implicit coordination is a bit
5786193326Sed  // gross. We should solve this in a reasonable fashion because this
5787193326Sed  // is a pretty common task (match some runtime data structure with
5788193326Sed  // an LLVM data structure).
5789198092Srdivacky
5790193326Sed  // FIXME: This is leaked.
5791193326Sed  // FIXME: Merge with rewriter code?
5792198092Srdivacky
5793193326Sed  // struct _objc_super {
5794193326Sed  //   id self;
5795193326Sed  //   Class cls;
5796193326Sed  // }
5797208600Srdivacky  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5798207619Srdivacky                                      Ctx.getTranslationUnitDecl(),
5799221345Sdim                                      SourceLocation(), SourceLocation(),
5800198092Srdivacky                                      &Ctx.Idents.get("_objc_super"));
5801276479Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5802276479Sdim                                nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
5803276479Sdim                                false, ICIS_NoInit));
5804276479Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
5805276479Sdim                                nullptr, Ctx.getObjCClassType(), nullptr,
5806276479Sdim                                nullptr, false, ICIS_NoInit));
5807203955Srdivacky  RD->completeDefinition();
5808198092Srdivacky
5809193326Sed  SuperCTy = Ctx.getTagDeclType(RD);
5810193326Sed  SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5811198092Srdivacky
5812193326Sed  SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5813198092Srdivacky  SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5814198092Srdivacky
5815193326Sed  // struct _prop_t {
5816193326Sed  //   char *name;
5817198092Srdivacky  //   char *attributes;
5818193326Sed  // }
5819321369Sdim  PropertyTy = llvm::StructType::create("struct._prop_t", Int8PtrTy, Int8PtrTy);
5820198092Srdivacky
5821193326Sed  // struct _prop_list_t {
5822193326Sed  //   uint32_t entsize;      // sizeof(struct _prop_t)
5823193326Sed  //   uint32_t count_of_properties;
5824193326Sed  //   struct _prop_t prop_list[count_of_properties];
5825193326Sed  // }
5826321369Sdim  PropertyListTy = llvm::StructType::create(
5827321369Sdim      "struct._prop_list_t", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
5828193326Sed  // struct _prop_list_t *
5829193326Sed  PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5830198092Srdivacky
5831193326Sed  // struct _objc_method {
5832193326Sed  //   SEL _cmd;
5833193326Sed  //   char *method_type;
5834193326Sed  //   char *_imp;
5835193326Sed  // }
5836321369Sdim  MethodTy = llvm::StructType::create("struct._objc_method", SelectorPtrTy,
5837321369Sdim                                      Int8PtrTy, Int8PtrTy);
5838198092Srdivacky
5839193326Sed  // struct _objc_cache *
5840226633Sdim  CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
5841193326Sed  CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5842193326Sed}
5843193326Sed
5844198092SrdivackyObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5845198092Srdivacky  : ObjCCommonTypesHelper(cgm) {
5846193326Sed  // struct _objc_method_description {
5847193326Sed  //   SEL name;
5848193326Sed  //   char *types;
5849193326Sed  // }
5850321369Sdim  MethodDescriptionTy = llvm::StructType::create(
5851321369Sdim      "struct._objc_method_description", SelectorPtrTy, Int8PtrTy);
5852193326Sed
5853193326Sed  // struct _objc_method_description_list {
5854193326Sed  //   int count;
5855193326Sed  //   struct _objc_method_description[1];
5856193326Sed  // }
5857321369Sdim  MethodDescriptionListTy =
5858321369Sdim      llvm::StructType::create("struct._objc_method_description_list", IntTy,
5859321369Sdim                               llvm::ArrayType::get(MethodDescriptionTy, 0));
5860198092Srdivacky
5861193326Sed  // struct _objc_method_description_list *
5862198092Srdivacky  MethodDescriptionListPtrTy =
5863193326Sed    llvm::PointerType::getUnqual(MethodDescriptionListTy);
5864193326Sed
5865193326Sed  // Protocol description structures
5866193326Sed
5867193326Sed  // struct _objc_protocol_extension {
5868193326Sed  //   uint32_t size;  // sizeof(struct _objc_protocol_extension)
5869193326Sed  //   struct _objc_method_description_list *optional_instance_methods;
5870193326Sed  //   struct _objc_method_description_list *optional_class_methods;
5871193326Sed  //   struct _objc_property_list *instance_properties;
5872234353Sdim  //   const char ** extendedMethodTypes;
5873309124Sdim  //   struct _objc_property_list *class_properties;
5874193326Sed  // }
5875321369Sdim  ProtocolExtensionTy = llvm::StructType::create(
5876321369Sdim      "struct._objc_protocol_extension", IntTy, MethodDescriptionListPtrTy,
5877321369Sdim      MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
5878321369Sdim      PropertyListPtrTy);
5879198092Srdivacky
5880193326Sed  // struct _objc_protocol_extension *
5881193326Sed  ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5882193326Sed
5883193326Sed  // Handle recursive construction of Protocol and ProtocolList types
5884193326Sed
5885224145Sdim  ProtocolTy =
5886226633Sdim    llvm::StructType::create(VMContext, "struct._objc_protocol");
5887193326Sed
5888224145Sdim  ProtocolListTy =
5889226633Sdim    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5890321369Sdim  ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy,
5891321369Sdim                          llvm::ArrayType::get(ProtocolTy, 0));
5892193326Sed
5893193326Sed  // struct _objc_protocol {
5894193326Sed  //   struct _objc_protocol_extension *isa;
5895193326Sed  //   char *protocol_name;
5896193326Sed  //   struct _objc_protocol **_objc_protocol_list;
5897193326Sed  //   struct _objc_method_description_list *instance_methods;
5898193326Sed  //   struct _objc_method_description_list *class_methods;
5899193326Sed  // }
5900224145Sdim  ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5901224145Sdim                      llvm::PointerType::getUnqual(ProtocolListTy),
5902321369Sdim                      MethodDescriptionListPtrTy, MethodDescriptionListPtrTy);
5903193326Sed
5904193326Sed  // struct _objc_protocol_list *
5905193326Sed  ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5906193326Sed
5907193326Sed  ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5908193326Sed
5909193326Sed  // Class description structures
5910193326Sed
5911193326Sed  // struct _objc_ivar {
5912193326Sed  //   char *ivar_name;
5913193326Sed  //   char *ivar_type;
5914193326Sed  //   int  ivar_offset;
5915193326Sed  // }
5916321369Sdim  IvarTy = llvm::StructType::create("struct._objc_ivar", Int8PtrTy, Int8PtrTy,
5917321369Sdim                                    IntTy);
5918193326Sed
5919193326Sed  // struct _objc_ivar_list *
5920224145Sdim  IvarListTy =
5921226633Sdim    llvm::StructType::create(VMContext, "struct._objc_ivar_list");
5922193326Sed  IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5923193326Sed
5924193326Sed  // struct _objc_method_list *
5925224145Sdim  MethodListTy =
5926226633Sdim    llvm::StructType::create(VMContext, "struct._objc_method_list");
5927193326Sed  MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5928193326Sed
5929193326Sed  // struct _objc_class_extension *
5930321369Sdim  ClassExtensionTy = llvm::StructType::create(
5931321369Sdim      "struct._objc_class_extension", IntTy, Int8PtrTy, PropertyListPtrTy);
5932193326Sed  ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5933193326Sed
5934226633Sdim  ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
5935193326Sed
5936193326Sed  // struct _objc_class {
5937193326Sed  //   Class isa;
5938193326Sed  //   Class super_class;
5939193326Sed  //   char *name;
5940193326Sed  //   long version;
5941193326Sed  //   long info;
5942193326Sed  //   long instance_size;
5943193326Sed  //   struct _objc_ivar_list *ivars;
5944193326Sed  //   struct _objc_method_list *methods;
5945193326Sed  //   struct _objc_cache *cache;
5946193326Sed  //   struct _objc_protocol_list *protocols;
5947193326Sed  //   char *ivar_layout;
5948193326Sed  //   struct _objc_class_ext *ext;
5949193326Sed  // };
5950224145Sdim  ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5951321369Sdim                   llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy,
5952321369Sdim                   LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy,
5953321369Sdim                   ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy);
5954198092Srdivacky
5955193326Sed  ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5956193326Sed
5957193326Sed  // struct _objc_category {
5958193326Sed  //   char *category_name;
5959193326Sed  //   char *class_name;
5960193326Sed  //   struct _objc_method_list *instance_method;
5961193326Sed  //   struct _objc_method_list *class_method;
5962309124Sdim  //   struct _objc_protocol_list *protocols;
5963193326Sed  //   uint32_t size;  // sizeof(struct _objc_category)
5964193326Sed  //   struct _objc_property_list *instance_properties;// category's @property
5965309124Sdim  //   struct _objc_property_list *class_properties;
5966193326Sed  // }
5967321369Sdim  CategoryTy = llvm::StructType::create(
5968321369Sdim      "struct._objc_category", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5969321369Sdim      MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
5970321369Sdim      PropertyListPtrTy);
5971193326Sed
5972193326Sed  // Global metadata structures
5973193326Sed
5974193326Sed  // struct _objc_symtab {
5975193326Sed  //   long sel_ref_cnt;
5976193326Sed  //   SEL *refs;
5977193326Sed  //   short cls_def_cnt;
5978193326Sed  //   short cat_def_cnt;
5979193326Sed  //   char *defs[cls_def_cnt + cat_def_cnt];
5980193326Sed  // }
5981321369Sdim  SymtabTy = llvm::StructType::create("struct._objc_symtab", LongTy,
5982321369Sdim                                      SelectorPtrTy, ShortTy, ShortTy,
5983321369Sdim                                      llvm::ArrayType::get(Int8PtrTy, 0));
5984193326Sed  SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5985193326Sed
5986193326Sed  // struct _objc_module {
5987193326Sed  //   long version;
5988193326Sed  //   long size;   // sizeof(struct _objc_module)
5989193326Sed  //   char *name;
5990193326Sed  //   struct _objc_symtab* symtab;
5991193326Sed  //  }
5992321369Sdim  ModuleTy = llvm::StructType::create("struct._objc_module", LongTy, LongTy,
5993321369Sdim                                      Int8PtrTy, SymtabPtrTy);
5994193326Sed
5995193326Sed  // FIXME: This is the size of the setjmp buffer and should be target
5996193326Sed  // specific. 18 is what's used on 32-bit X86.
5997193326Sed  uint64_t SetJmpBufferSize = 18;
5998198092Srdivacky
5999193326Sed  // Exceptions
6000234353Sdim  llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
6001198092Srdivacky
6002321369Sdim  ExceptionDataTy = llvm::StructType::create(
6003321369Sdim      "struct._objc_exception_data",
6004321369Sdim      llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
6005193326Sed}
6006193326Sed
6007198092SrdivackyObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
6008198092Srdivacky  : ObjCCommonTypesHelper(cgm) {
6009193326Sed  // struct _method_list_t {
6010193326Sed  //   uint32_t entsize;  // sizeof(struct _objc_method)
6011193326Sed  //   uint32_t method_count;
6012193326Sed  //   struct _objc_method method_list[method_count];
6013193326Sed  // }
6014224145Sdim  MethodListnfABITy =
6015321369Sdim      llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
6016321369Sdim                               llvm::ArrayType::get(MethodTy, 0));
6017193326Sed  // struct method_list_t *
6018193326Sed  MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
6019198092Srdivacky
6020193326Sed  // struct _protocol_t {
6021193326Sed  //   id isa;  // NULL
6022193326Sed  //   const char * const protocol_name;
6023193326Sed  //   const struct _protocol_list_t * protocol_list; // super protocols
6024193326Sed  //   const struct method_list_t * const instance_methods;
6025193326Sed  //   const struct method_list_t * const class_methods;
6026193326Sed  //   const struct method_list_t *optionalInstanceMethods;
6027193326Sed  //   const struct method_list_t *optionalClassMethods;
6028193326Sed  //   const struct _prop_list_t * properties;
6029193326Sed  //   const uint32_t size;  // sizeof(struct _protocol_t)
6030193326Sed  //   const uint32_t flags;  // = 0
6031234353Sdim  //   const char ** extendedMethodTypes;
6032288943Sdim  //   const char *demangledName;
6033309124Sdim  //   const struct _prop_list_t * class_properties;
6034193326Sed  // }
6035198092Srdivacky
6036193326Sed  // Holder for struct _protocol_list_t *
6037224145Sdim  ProtocolListnfABITy =
6038226633Sdim    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
6039198092Srdivacky
6040321369Sdim  ProtocolnfABITy = llvm::StructType::create(
6041321369Sdim      "struct._protocol_t", ObjectPtrTy, Int8PtrTy,
6042321369Sdim      llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy,
6043321369Sdim      MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
6044321369Sdim      PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
6045321369Sdim      PropertyListPtrTy);
6046193326Sed
6047193326Sed  // struct _protocol_t*
6048193326Sed  ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
6049198092Srdivacky
6050193326Sed  // struct _protocol_list_t {
6051193326Sed  //   long protocol_count;   // Note, this is 32/64 bit
6052193326Sed  //   struct _protocol_t *[protocol_count];
6053193326Sed  // }
6054224145Sdim  ProtocolListnfABITy->setBody(LongTy,
6055321369Sdim                               llvm::ArrayType::get(ProtocolnfABIPtrTy, 0));
6056198092Srdivacky
6057193326Sed  // struct _objc_protocol_list*
6058193326Sed  ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
6059198092Srdivacky
6060193326Sed  // struct _ivar_t {
6061276479Sdim  //   unsigned [long] int *offset;  // pointer to ivar offset location
6062193326Sed  //   char *name;
6063193326Sed  //   char *type;
6064193326Sed  //   uint32_t alignment;
6065193326Sed  //   uint32_t size;
6066193326Sed  // }
6067276479Sdim  IvarnfABITy = llvm::StructType::create(
6068276479Sdim      "struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy),
6069321369Sdim      Int8PtrTy, Int8PtrTy, IntTy, IntTy);
6070198092Srdivacky
6071193326Sed  // struct _ivar_list_t {
6072193326Sed  //   uint32 entsize;  // sizeof(struct _ivar_t)
6073193326Sed  //   uint32 count;
6074193326Sed  //   struct _iver_t list[count];
6075193326Sed  // }
6076224145Sdim  IvarListnfABITy =
6077321369Sdim      llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
6078321369Sdim                               llvm::ArrayType::get(IvarnfABITy, 0));
6079198092Srdivacky
6080193326Sed  IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
6081198092Srdivacky
6082193326Sed  // struct _class_ro_t {
6083193326Sed  //   uint32_t const flags;
6084193326Sed  //   uint32_t const instanceStart;
6085193326Sed  //   uint32_t const instanceSize;
6086193326Sed  //   uint32_t const reserved;  // only when building for 64bit targets
6087193326Sed  //   const uint8_t * const ivarLayout;
6088193326Sed  //   const char *const name;
6089193326Sed  //   const struct _method_list_t * const baseMethods;
6090193326Sed  //   const struct _objc_protocol_list *const baseProtocols;
6091193326Sed  //   const struct _ivar_list_t *const ivars;
6092193326Sed  //   const uint8_t * const weakIvarLayout;
6093193326Sed  //   const struct _prop_list_t * const properties;
6094193326Sed  // }
6095198092Srdivacky
6096193326Sed  // FIXME. Add 'reserved' field in 64bit abi mode!
6097321369Sdim  ClassRonfABITy = llvm::StructType::create(
6098321369Sdim      "struct._class_ro_t", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
6099321369Sdim      MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
6100321369Sdim      Int8PtrTy, PropertyListPtrTy);
6101198092Srdivacky
6102193326Sed  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
6103224145Sdim  llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
6104223017Sdim  ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
6105223017Sdim                 ->getPointerTo();
6106198092Srdivacky
6107193326Sed  // struct _class_t {
6108193326Sed  //   struct _class_t *isa;
6109193326Sed  //   struct _class_t * const superclass;
6110193326Sed  //   void *cache;
6111193326Sed  //   IMP *vtable;
6112193326Sed  //   struct class_ro_t *ro;
6113193326Sed  // }
6114198092Srdivacky
6115226633Sdim  ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
6116224145Sdim  ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
6117321369Sdim                        llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy,
6118224145Sdim                        llvm::PointerType::getUnqual(ImpnfABITy),
6119321369Sdim                        llvm::PointerType::getUnqual(ClassRonfABITy));
6120193326Sed
6121193326Sed  // LLVM for struct _class_t *
6122193326Sed  ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
6123198092Srdivacky
6124193326Sed  // struct _category_t {
6125193326Sed  //   const char * const name;
6126193326Sed  //   struct _class_t *const cls;
6127193326Sed  //   const struct _method_list_t * const instance_methods;
6128193326Sed  //   const struct _method_list_t * const class_methods;
6129193326Sed  //   const struct _protocol_list_t * const protocols;
6130193326Sed  //   const struct _prop_list_t * const properties;
6131309124Sdim  //   const struct _prop_list_t * const class_properties;
6132309124Sdim  //   const uint32_t size;
6133193326Sed  // }
6134321369Sdim  CategorynfABITy = llvm::StructType::create(
6135321369Sdim      "struct._category_t", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
6136321369Sdim      MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
6137321369Sdim      PropertyListPtrTy, IntTy);
6138198092Srdivacky
6139193326Sed  // New types for nonfragile abi messaging.
6140193326Sed  CodeGen::CodeGenTypes &Types = CGM.getTypes();
6141193326Sed  ASTContext &Ctx = CGM.getContext();
6142198092Srdivacky
6143193326Sed  // MessageRefTy - LLVM for:
6144193326Sed  // struct _message_ref_t {
6145193326Sed  //   IMP messenger;
6146193326Sed  //   SEL name;
6147193326Sed  // };
6148198092Srdivacky
6149193326Sed  // First the clang type for struct _message_ref_t
6150208600Srdivacky  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
6151207619Srdivacky                                      Ctx.getTranslationUnitDecl(),
6152221345Sdim                                      SourceLocation(), SourceLocation(),
6153193326Sed                                      &Ctx.Idents.get("_message_ref_t"));
6154276479Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6155276479Sdim                                nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
6156239462Sdim                                ICIS_NoInit));
6157276479Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
6158276479Sdim                                nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
6159276479Sdim                                false, ICIS_NoInit));
6160203955Srdivacky  RD->completeDefinition();
6161198092Srdivacky
6162193326Sed  MessageRefCTy = Ctx.getTagDeclType(RD);
6163193326Sed  MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
6164193326Sed  MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
6165198092Srdivacky
6166193326Sed  // MessageRefPtrTy - LLVM for struct _message_ref_t*
6167193326Sed  MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
6168198092Srdivacky
6169193326Sed  // SuperMessageRefTy - LLVM for:
6170193326Sed  // struct _super_message_ref_t {
6171193326Sed  //   SUPER_IMP messenger;
6172193326Sed  //   SEL name;
6173193326Sed  // };
6174321369Sdim  SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t",
6175321369Sdim                                               ImpnfABITy, SelectorPtrTy);
6176198092Srdivacky
6177193326Sed  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
6178198092Srdivacky  SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
6179193326Sed
6180341825Sdim
6181193326Sed  // struct objc_typeinfo {
6182193326Sed  //   const void** vtable; // objc_ehtype_vtable + 2
6183193326Sed  //   const char*  name;    // c++ typeinfo string
6184193326Sed  //   Class        cls;
6185193326Sed  // };
6186321369Sdim  EHTypeTy = llvm::StructType::create("struct._objc_typeinfo",
6187321369Sdim                                      llvm::PointerType::getUnqual(Int8PtrTy),
6188321369Sdim                                      Int8PtrTy, ClassnfABIPtrTy);
6189193326Sed  EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
6190193326Sed}
6191193326Sed
6192198092Srdivackyllvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
6193193326Sed  FinishNonFragileABIModule();
6194198092Srdivacky
6195276479Sdim  return nullptr;
6196193326Sed}
6197193326Sed
6198309124Sdimvoid CGObjCNonFragileABIMac::AddModuleClassList(
6199309124Sdim    ArrayRef<llvm::GlobalValue *> Container, StringRef SymbolName,
6200309124Sdim    StringRef SectionName) {
6201193326Sed  unsigned NumClasses = Container.size();
6202198092Srdivacky
6203193326Sed  if (!NumClasses)
6204193326Sed    return;
6205198092Srdivacky
6206234353Sdim  SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
6207193326Sed  for (unsigned i=0; i<NumClasses; i++)
6208193326Sed    Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
6209193326Sed                                                ObjCTypes.Int8PtrTy);
6210234353Sdim  llvm::Constant *Init =
6211193326Sed    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
6212234353Sdim                                                  Symbols.size()),
6213193326Sed                             Symbols);
6214198092Srdivacky
6215353358Sdim  // Section name is obtained by calling GetSectionName, which returns
6216353358Sdim  // sections in the __DATA segment on MachO.
6217353358Sdim  assert((!CGM.getTriple().isOSBinFormatMachO() ||
6218353358Sdim          SectionName.startswith("__DATA")) &&
6219353358Sdim         "SectionName expected to start with __DATA on MachO");
6220353358Sdim  llvm::GlobalValue::LinkageTypes LT =
6221353358Sdim      getLinkageTypeForObjCMetadata(CGM, SectionName);
6222193326Sed  llvm::GlobalVariable *GV =
6223353358Sdim    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false, LT, Init,
6224198092Srdivacky                             SymbolName);
6225360784Sdim  GV->setAlignment(
6226360784Sdim      llvm::Align(CGM.getDataLayout().getABITypeAlignment(Init->getType())));
6227193326Sed  GV->setSection(SectionName);
6228276479Sdim  CGM.addCompilerUsedGlobal(GV);
6229193326Sed}
6230198092Srdivacky
6231193326Sedvoid CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
6232193326Sed  // nonfragile abi has no module definition.
6233198092Srdivacky
6234193326Sed  // Build list of all implemented class addresses in array
6235193326Sed  // L_OBJC_LABEL_CLASS_$.
6236276479Sdim
6237276479Sdim  for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
6238276479Sdim    const ObjCInterfaceDecl *ID = ImplementedClasses[i];
6239276479Sdim    assert(ID);
6240276479Sdim    if (ObjCImplementationDecl *IMP = ID->getImplementation())
6241276479Sdim      // We are implementing a weak imported interface. Give it external linkage
6242276479Sdim      if (ID->isWeakImported() && !IMP->isWeakImported()) {
6243276479Sdim        DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6244276479Sdim        DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
6245276479Sdim      }
6246276479Sdim  }
6247280031Sdim
6248280031Sdim  AddModuleClassList(DefinedClasses, "OBJC_LABEL_CLASS_$",
6249321369Sdim                     GetSectionName("__objc_classlist",
6250321369Sdim                                    "regular,no_dead_strip"));
6251276479Sdim
6252280031Sdim  AddModuleClassList(DefinedNonLazyClasses, "OBJC_LABEL_NONLAZY_CLASS_$",
6253321369Sdim                     GetSectionName("__objc_nlclslist",
6254321369Sdim                                    "regular,no_dead_strip"));
6255198092Srdivacky
6256193326Sed  // Build list of all implemented category addresses in array
6257193326Sed  // L_OBJC_LABEL_CATEGORY_$.
6258280031Sdim  AddModuleClassList(DefinedCategories, "OBJC_LABEL_CATEGORY_$",
6259321369Sdim                     GetSectionName("__objc_catlist",
6260321369Sdim                                    "regular,no_dead_strip"));
6261353358Sdim  AddModuleClassList(DefinedStubCategories, "OBJC_LABEL_STUB_CATEGORY_$",
6262353358Sdim                     GetSectionName("__objc_catlist2",
6263353358Sdim                                    "regular,no_dead_strip"));
6264280031Sdim  AddModuleClassList(DefinedNonLazyCategories, "OBJC_LABEL_NONLAZY_CATEGORY_$",
6265321369Sdim                     GetSectionName("__objc_nlcatlist",
6266321369Sdim                                    "regular,no_dead_strip"));
6267198092Srdivacky
6268207619Srdivacky  EmitImageInfo();
6269193326Sed}
6270193326Sed
6271223017Sdim/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
6272223017Sdim/// VTableDispatchMethods; false otherwise. What this means is that
6273198092Srdivacky/// except for the 19 selectors in the list, we generate 32bit-style
6274193326Sed/// message dispatch call for all the rest.
6275223017Sdimbool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
6276223017Sdim  // At various points we've experimented with using vtable-based
6277223017Sdim  // dispatch for all methods.
6278207619Srdivacky  switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
6279207619Srdivacky  case CodeGenOptions::Legacy:
6280223017Sdim    return false;
6281223017Sdim  case CodeGenOptions::NonLegacy:
6282203955Srdivacky    return true;
6283207619Srdivacky  case CodeGenOptions::Mixed:
6284207619Srdivacky    break;
6285207619Srdivacky  }
6286203955Srdivacky
6287207619Srdivacky  // If so, see whether this selector is in the white-list of things which must
6288207619Srdivacky  // use the new dispatch convention. We lazily build a dense set for this.
6289223017Sdim  if (VTableDispatchMethods.empty()) {
6290223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("alloc"));
6291223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("class"));
6292223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("self"));
6293223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
6294223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("length"));
6295223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("count"));
6296198092Srdivacky
6297223017Sdim    // These are vtable-based if GC is disabled.
6298223017Sdim    // Optimistically use vtable dispatch for hybrid compiles.
6299234353Sdim    if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
6300223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("retain"));
6301223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("release"));
6302223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
6303223017Sdim    }
6304223017Sdim
6305223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
6306223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
6307223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
6308223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
6309223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
6310223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
6311223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
6312223017Sdim
6313223017Sdim    // These are vtable-based if GC is enabled.
6314223017Sdim    // Optimistically use vtable dispatch for hybrid compiles.
6315234353Sdim    if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
6316223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("hash"));
6317223017Sdim      VTableDispatchMethods.insert(GetUnarySelector("addObject"));
6318341825Sdim
6319223017Sdim      // "countByEnumeratingWithState:objects:count"
6320223017Sdim      IdentifierInfo *KeyIdents[] = {
6321223017Sdim        &CGM.getContext().Idents.get("countByEnumeratingWithState"),
6322223017Sdim        &CGM.getContext().Idents.get("objects"),
6323223017Sdim        &CGM.getContext().Idents.get("count")
6324223017Sdim      };
6325223017Sdim      VTableDispatchMethods.insert(
6326223017Sdim        CGM.getContext().Selectors.getSelector(3, KeyIdents));
6327223017Sdim    }
6328193326Sed  }
6329207619Srdivacky
6330223017Sdim  return VTableDispatchMethods.count(Sel);
6331193326Sed}
6332193326Sed
6333193326Sed/// BuildClassRoTInitializer - generate meta-data for:
6334193326Sed/// struct _class_ro_t {
6335193326Sed///   uint32_t const flags;
6336193326Sed///   uint32_t const instanceStart;
6337193326Sed///   uint32_t const instanceSize;
6338193326Sed///   uint32_t const reserved;  // only when building for 64bit targets
6339193326Sed///   const uint8_t * const ivarLayout;
6340193326Sed///   const char *const name;
6341193326Sed///   const struct _method_list_t * const baseMethods;
6342193326Sed///   const struct _protocol_list_t *const baseProtocols;
6343193326Sed///   const struct _ivar_list_t *const ivars;
6344193326Sed///   const uint8_t * const weakIvarLayout;
6345193326Sed///   const struct _prop_list_t * const properties;
6346193326Sed/// }
6347193326Sed///
6348193326Sedllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
6349198092Srdivacky  unsigned flags,
6350198092Srdivacky  unsigned InstanceStart,
6351198092Srdivacky  unsigned InstanceSize,
6352198092Srdivacky  const ObjCImplementationDecl *ID) {
6353276479Sdim  std::string ClassName = ID->getObjCRuntimeNameAsString();
6354224145Sdim
6355296417Sdim  CharUnits beginInstance = CharUnits::fromQuantity(InstanceStart);
6356296417Sdim  CharUnits endInstance = CharUnits::fromQuantity(InstanceSize);
6357296417Sdim
6358296417Sdim  bool hasMRCWeak = false;
6359234353Sdim  if (CGM.getLangOpts().ObjCAutoRefCount)
6360243830Sdim    flags |= NonFragileABI_Class_CompiledByARC;
6361296417Sdim  else if ((hasMRCWeak = hasMRCWeakIvars(CGM, ID)))
6362296417Sdim    flags |= NonFragileABI_Class_HasMRCWeakIvars;
6363224145Sdim
6364314564Sdim  ConstantInitBuilder builder(CGM);
6365314564Sdim  auto values = builder.beginStruct(ObjCTypes.ClassRonfABITy);
6366314564Sdim
6367314564Sdim  values.addInt(ObjCTypes.IntTy, flags);
6368314564Sdim  values.addInt(ObjCTypes.IntTy, InstanceStart);
6369314564Sdim  values.addInt(ObjCTypes.IntTy, InstanceSize);
6370314564Sdim  values.add((flags & NonFragileABI_Class_Meta)
6371314564Sdim                ? GetIvarLayoutName(nullptr, ObjCTypes)
6372314564Sdim                : BuildStrongIvarLayout(ID, beginInstance, endInstance));
6373314564Sdim  values.add(GetClassName(ID->getObjCRuntimeNameAsString()));
6374314564Sdim
6375193326Sed  // const struct _method_list_t * const baseMethods;
6376314564Sdim  SmallVector<const ObjCMethodDecl*, 16> methods;
6377243830Sdim  if (flags & NonFragileABI_Class_Meta) {
6378314564Sdim    for (const auto *MD : ID->class_methods())
6379360784Sdim      if (!MD->isDirectMethod())
6380360784Sdim        methods.push_back(MD);
6381193326Sed  } else {
6382314564Sdim    for (const auto *MD : ID->instance_methods())
6383360784Sdim      if (!MD->isDirectMethod())
6384360784Sdim        methods.push_back(MD);
6385193326Sed  }
6386198092Srdivacky
6387314564Sdim  values.add(emitMethodList(ID->getObjCRuntimeNameAsString(),
6388314564Sdim                            (flags & NonFragileABI_Class_Meta)
6389314564Sdim                               ? MethodListType::ClassMethods
6390314564Sdim                               : MethodListType::InstanceMethods,
6391314564Sdim                            methods));
6392314564Sdim
6393193326Sed  const ObjCInterfaceDecl *OID = ID->getClassInterface();
6394193326Sed  assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
6395353358Sdim  values.add(EmitProtocolList("_OBJC_CLASS_PROTOCOLS_$_"
6396276479Sdim                                + OID->getObjCRuntimeNameAsString(),
6397314564Sdim                              OID->all_referenced_protocol_begin(),
6398314564Sdim                              OID->all_referenced_protocol_end()));
6399198092Srdivacky
6400243830Sdim  if (flags & NonFragileABI_Class_Meta) {
6401314564Sdim    values.addNullPointer(ObjCTypes.IvarListnfABIPtrTy);
6402314564Sdim    values.add(GetIvarLayoutName(nullptr, ObjCTypes));
6403314564Sdim    values.add(EmitPropertyList(
6404353358Sdim        "_OBJC_$_CLASS_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
6405314564Sdim        ID, ID->getClassInterface(), ObjCTypes, true));
6406243830Sdim  } else {
6407314564Sdim    values.add(EmitIvarList(ID));
6408314564Sdim    values.add(BuildWeakIvarLayout(ID, beginInstance, endInstance, hasMRCWeak));
6409314564Sdim    values.add(EmitPropertyList(
6410353358Sdim        "_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
6411314564Sdim        ID, ID->getClassInterface(), ObjCTypes, false));
6412243830Sdim  }
6413314564Sdim
6414314564Sdim  llvm::SmallString<64> roLabel;
6415314564Sdim  llvm::raw_svector_ostream(roLabel)
6416353358Sdim      << ((flags & NonFragileABI_Class_Meta) ? "_OBJC_METACLASS_RO_$_"
6417353358Sdim                                             : "_OBJC_CLASS_RO_$_")
6418314564Sdim      << ClassName;
6419314564Sdim
6420353358Sdim  return finishAndCreateGlobal(values, roLabel, CGM);
6421193326Sed}
6422193326Sed
6423314564Sdim/// Build the metaclass object for a class.
6424314564Sdim///
6425193326Sed/// struct _class_t {
6426193326Sed///   struct _class_t *isa;
6427193326Sed///   struct _class_t * const superclass;
6428193326Sed///   void *cache;
6429193326Sed///   IMP *vtable;
6430193326Sed///   struct class_ro_t *ro;
6431193326Sed/// }
6432193326Sed///
6433314564Sdimllvm::GlobalVariable *
6434314564SdimCGObjCNonFragileABIMac::BuildClassObject(const ObjCInterfaceDecl *CI,
6435314564Sdim                                         bool isMetaclass,
6436314564Sdim                                         llvm::Constant *IsAGV,
6437314564Sdim                                         llvm::Constant *SuperClassGV,
6438314564Sdim                                         llvm::Constant *ClassRoGV,
6439314564Sdim                                         bool HiddenVisibility) {
6440314564Sdim  ConstantInitBuilder builder(CGM);
6441314564Sdim  auto values = builder.beginStruct(ObjCTypes.ClassnfABITy);
6442314564Sdim  values.add(IsAGV);
6443314564Sdim  if (SuperClassGV) {
6444314564Sdim    values.add(SuperClassGV);
6445314564Sdim  } else {
6446314564Sdim    values.addNullPointer(ObjCTypes.ClassnfABIPtrTy);
6447314564Sdim  }
6448314564Sdim  values.add(ObjCEmptyCacheVar);
6449314564Sdim  values.add(ObjCEmptyVtableVar);
6450314564Sdim  values.add(ClassRoGV);
6451314564Sdim
6452314564Sdim  llvm::GlobalVariable *GV =
6453314564Sdim    cast<llvm::GlobalVariable>(GetClassGlobal(CI, isMetaclass, ForDefinition));
6454314564Sdim  values.finishAndSetAsInitializer(GV);
6455314564Sdim
6456314564Sdim  if (CGM.getTriple().isOSBinFormatMachO())
6457314564Sdim    GV->setSection("__DATA, __objc_data");
6458360784Sdim  GV->setAlignment(llvm::Align(
6459360784Sdim      CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy)));
6460309124Sdim  if (!CGM.getTriple().isOSBinFormatCOFF())
6461309124Sdim    if (HiddenVisibility)
6462309124Sdim      GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6463193326Sed  return GV;
6464193326Sed}
6465193326Sed
6466353358Sdimbool CGObjCNonFragileABIMac::ImplementationIsNonLazy(
6467353358Sdim    const ObjCImplDecl *OD) const {
6468353358Sdim  return OD->getClassMethod(GetNullarySelector("load")) != nullptr ||
6469353358Sdim         OD->getClassInterface()->hasAttr<ObjCNonLazyClassAttr>() ||
6470353358Sdim         OD->hasAttr<ObjCNonLazyClassAttr>();
6471193326Sed}
6472193326Sed
6473193326Sedvoid CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
6474193326Sed                                              uint32_t &InstanceStart,
6475193326Sed                                              uint32_t &InstanceSize) {
6476198092Srdivacky  const ASTRecordLayout &RL =
6477193326Sed    CGM.getContext().getASTObjCImplementationLayout(OID);
6478198092Srdivacky
6479193326Sed  // InstanceSize is really instance end.
6480218893Sdim  InstanceSize = RL.getDataSize().getQuantity();
6481193326Sed
6482193326Sed  // If there are no fields, the start is the same as the end.
6483193326Sed  if (!RL.getFieldCount())
6484193326Sed    InstanceStart = InstanceSize;
6485193326Sed  else
6486221345Sdim    InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
6487193326Sed}
6488193326Sed
6489309124Sdimstatic llvm::GlobalValue::DLLStorageClassTypes getStorage(CodeGenModule &CGM,
6490309124Sdim                                                          StringRef Name) {
6491309124Sdim  IdentifierInfo &II = CGM.getContext().Idents.get(Name);
6492309124Sdim  TranslationUnitDecl *TUDecl = CGM.getContext().getTranslationUnitDecl();
6493309124Sdim  DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl);
6494309124Sdim
6495309124Sdim  const VarDecl *VD = nullptr;
6496309124Sdim  for (const auto &Result : DC->lookup(&II))
6497309124Sdim    if ((VD = dyn_cast<VarDecl>(Result)))
6498309124Sdim      break;
6499309124Sdim
6500309124Sdim  if (!VD)
6501309124Sdim    return llvm::GlobalValue::DLLImportStorageClass;
6502309124Sdim  if (VD->hasAttr<DLLExportAttr>())
6503309124Sdim    return llvm::GlobalValue::DLLExportStorageClass;
6504309124Sdim  if (VD->hasAttr<DLLImportAttr>())
6505309124Sdim    return llvm::GlobalValue::DLLImportStorageClass;
6506309124Sdim  return llvm::GlobalValue::DefaultStorageClass;
6507309124Sdim}
6508309124Sdim
6509193326Sedvoid CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
6510193326Sed  if (!ObjCEmptyCacheVar) {
6511309124Sdim    ObjCEmptyCacheVar =
6512309124Sdim        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CacheTy, false,
6513309124Sdim                                 llvm::GlobalValue::ExternalLinkage, nullptr,
6514309124Sdim                                 "_objc_empty_cache");
6515309124Sdim    if (CGM.getTriple().isOSBinFormatCOFF())
6516309124Sdim      ObjCEmptyCacheVar->setDLLStorageClass(getStorage(CGM, "_objc_empty_cache"));
6517276479Sdim
6518309124Sdim    // Only OS X with deployment version <10.9 use the empty vtable symbol
6519261991Sdim    const llvm::Triple &Triple = CGM.getTarget().getTriple();
6520309124Sdim    if (Triple.isMacOSX() && Triple.isMacOSXVersionLT(10, 9))
6521309124Sdim      ObjCEmptyVtableVar =
6522309124Sdim          new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ImpnfABITy, false,
6523309124Sdim                                   llvm::GlobalValue::ExternalLinkage, nullptr,
6524309124Sdim                                   "_objc_empty_vtable");
6525314564Sdim    else
6526314564Sdim      ObjCEmptyVtableVar =
6527314564Sdim        llvm::ConstantPointerNull::get(ObjCTypes.ImpnfABITy->getPointerTo());
6528193326Sed  }
6529309124Sdim
6530193326Sed  // FIXME: Is this correct (that meta class size is never computed)?
6531198092Srdivacky  uint32_t InstanceStart =
6532243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
6533193326Sed  uint32_t InstanceSize = InstanceStart;
6534243830Sdim  uint32_t flags = NonFragileABI_Class_Meta;
6535198092Srdivacky
6536314564Sdim  llvm::Constant *SuperClassGV, *IsAGV;
6537198092Srdivacky
6538309124Sdim  const auto *CI = ID->getClassInterface();
6539309124Sdim  assert(CI && "CGObjCNonFragileABIMac::GenerateClass - class is 0");
6540309124Sdim
6541243830Sdim  // Build the flags for the metaclass.
6542309124Sdim  bool classIsHidden = (CGM.getTriple().isOSBinFormatCOFF())
6543309124Sdim                           ? !CI->hasAttr<DLLExportAttr>()
6544309124Sdim                           : CI->getVisibility() == HiddenVisibility;
6545193326Sed  if (classIsHidden)
6546243830Sdim    flags |= NonFragileABI_Class_Hidden;
6547243830Sdim
6548243830Sdim  // FIXME: why is this flag set on the metaclass?
6549243830Sdim  // ObjC metaclasses have no fields and don't really get constructed.
6550243830Sdim  if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6551243830Sdim    flags |= NonFragileABI_Class_HasCXXStructors;
6552243830Sdim    if (!ID->hasNonZeroConstructors())
6553309124Sdim      flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6554243830Sdim  }
6555243830Sdim
6556309124Sdim  if (!CI->getSuperClass()) {
6557193326Sed    // class is root
6558243830Sdim    flags |= NonFragileABI_Class_Root;
6559309124Sdim
6560314564Sdim    SuperClassGV = GetClassGlobal(CI, /*metaclass*/ false, NotForDefinition);
6561314564Sdim    IsAGV = GetClassGlobal(CI, /*metaclass*/ true, NotForDefinition);
6562193326Sed  } else {
6563193326Sed    // Has a root. Current class is not a root.
6564193326Sed    const ObjCInterfaceDecl *Root = ID->getClassInterface();
6565193326Sed    while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
6566193326Sed      Root = Super;
6567309124Sdim
6568309124Sdim    const auto *Super = CI->getSuperClass();
6569314564Sdim    IsAGV = GetClassGlobal(Root, /*metaclass*/ true, NotForDefinition);
6570314564Sdim    SuperClassGV = GetClassGlobal(Super, /*metaclass*/ true, NotForDefinition);
6571193326Sed  }
6572309124Sdim
6573309124Sdim  llvm::GlobalVariable *CLASS_RO_GV =
6574309124Sdim      BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6575309124Sdim
6576309124Sdim  llvm::GlobalVariable *MetaTClass =
6577314564Sdim    BuildClassObject(CI, /*metaclass*/ true,
6578314564Sdim                     IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden);
6579341825Sdim  CGM.setGVProperties(MetaTClass, CI);
6580199482Srdivacky  DefinedMetaClasses.push_back(MetaTClass);
6581193326Sed
6582193326Sed  // Metadata for the class
6583243830Sdim  flags = 0;
6584193326Sed  if (classIsHidden)
6585243830Sdim    flags |= NonFragileABI_Class_Hidden;
6586193326Sed
6587243830Sdim  if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
6588243830Sdim    flags |= NonFragileABI_Class_HasCXXStructors;
6589243830Sdim
6590243830Sdim    // Set a flag to enable a runtime optimization when a class has
6591243830Sdim    // fields that require destruction but which don't require
6592243830Sdim    // anything except zero-initialization during construction.  This
6593243830Sdim    // is most notably true of __strong and __weak types, but you can
6594243830Sdim    // also imagine there being C++ types with non-trivial default
6595243830Sdim    // constructors that merely set all fields to null.
6596243830Sdim    if (!ID->hasNonZeroConstructors())
6597243830Sdim      flags |= NonFragileABI_Class_HasCXXDestructorOnly;
6598243830Sdim  }
6599243830Sdim
6600309124Sdim  if (hasObjCExceptionAttribute(CGM.getContext(), CI))
6601243830Sdim    flags |= NonFragileABI_Class_Exception;
6602193326Sed
6603309124Sdim  if (!CI->getSuperClass()) {
6604243830Sdim    flags |= NonFragileABI_Class_Root;
6605276479Sdim    SuperClassGV = nullptr;
6606193326Sed  } else {
6607193326Sed    // Has a root. Current class is not a root.
6608309124Sdim    const auto *Super = CI->getSuperClass();
6609314564Sdim    SuperClassGV = GetClassGlobal(Super, /*metaclass*/ false, NotForDefinition);
6610193326Sed  }
6611309124Sdim
6612193326Sed  GetClassSizeInfo(ID, InstanceStart, InstanceSize);
6613309124Sdim  CLASS_RO_GV =
6614309124Sdim      BuildClassRoTInitializer(flags, InstanceStart, InstanceSize, ID);
6615198092Srdivacky
6616198092Srdivacky  llvm::GlobalVariable *ClassMD =
6617314564Sdim    BuildClassObject(CI, /*metaclass*/ false,
6618314564Sdim                     MetaTClass, SuperClassGV, CLASS_RO_GV, classIsHidden);
6619341825Sdim  CGM.setGVProperties(ClassMD, CI);
6620193326Sed  DefinedClasses.push_back(ClassMD);
6621309124Sdim  ImplementedClasses.push_back(CI);
6622193326Sed
6623193326Sed  // Determine if this class is also "non-lazy".
6624193326Sed  if (ImplementationIsNonLazy(ID))
6625193326Sed    DefinedNonLazyClasses.push_back(ClassMD);
6626193326Sed
6627193326Sed  // Force the definition of the EHType if necessary.
6628243830Sdim  if (flags & NonFragileABI_Class_Exception)
6629314564Sdim    (void) GetInterfaceEHType(CI, ForDefinition);
6630221345Sdim  // Make sure method definition entries are all clear for next implementation.
6631221345Sdim  MethodDefinitions.clear();
6632193326Sed}
6633193326Sed
6634193326Sed/// GenerateProtocolRef - This routine is called to generate code for
6635193326Sed/// a protocol reference expression; as in:
6636193326Sed/// @code
6637193326Sed///   @protocol(Proto1);
6638193326Sed/// @endcode
6639193326Sed/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
6640193326Sed/// which will hold address of the protocol meta-data.
6641193326Sed///
6642249423Sdimllvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
6643198092Srdivacky                                                         const ObjCProtocolDecl *PD) {
6644198092Srdivacky
6645193326Sed  // This routine is called for @protocol only. So, we must build definition
6646193326Sed  // of protocol's meta-data (not a reference to it!)
6647193326Sed  //
6648198092Srdivacky  llvm::Constant *Init =
6649198092Srdivacky    llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
6650234353Sdim                                   ObjCTypes.getExternalProtocolPtrTy());
6651198092Srdivacky
6652353358Sdim  std::string ProtocolName("_OBJC_PROTOCOL_REFERENCE_$_");
6653276479Sdim  ProtocolName += PD->getObjCRuntimeNameAsString();
6654198092Srdivacky
6655296417Sdim  CharUnits Align = CGF.getPointerAlign();
6656296417Sdim
6657193326Sed  llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
6658193326Sed  if (PTGV)
6659296417Sdim    return CGF.Builder.CreateAlignedLoad(PTGV, Align);
6660321369Sdim  PTGV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6661321369Sdim                                  llvm::GlobalValue::WeakAnyLinkage, Init,
6662321369Sdim                                  ProtocolName);
6663321369Sdim  PTGV->setSection(GetSectionName("__objc_protorefs",
6664321369Sdim                                  "coalesced,no_dead_strip"));
6665193326Sed  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6666360784Sdim  PTGV->setAlignment(Align.getAsAlign());
6667321369Sdim  if (!CGM.getTriple().isOSBinFormatMachO())
6668321369Sdim    PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolName));
6669341825Sdim  CGM.addUsedGlobal(PTGV);
6670296417Sdim  return CGF.Builder.CreateAlignedLoad(PTGV, Align);
6671193326Sed}
6672193326Sed
6673193326Sed/// GenerateCategory - Build metadata for a category implementation.
6674193326Sed/// struct _category_t {
6675193326Sed///   const char * const name;
6676193326Sed///   struct _class_t *const cls;
6677193326Sed///   const struct _method_list_t * const instance_methods;
6678193326Sed///   const struct _method_list_t * const class_methods;
6679193326Sed///   const struct _protocol_list_t * const protocols;
6680193326Sed///   const struct _prop_list_t * const properties;
6681309124Sdim///   const struct _prop_list_t * const class_properties;
6682309124Sdim///   const uint32_t size;
6683193326Sed/// }
6684193326Sed///
6685193326Sedvoid CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
6686193326Sed  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
6687353358Sdim  const char *Prefix = "_OBJC_$_CATEGORY_";
6688341825Sdim
6689276479Sdim  llvm::SmallString<64> ExtCatName(Prefix);
6690276479Sdim  ExtCatName += Interface->getObjCRuntimeNameAsString();
6691276479Sdim  ExtCatName += "_$_";
6692276479Sdim  ExtCatName += OCD->getNameAsString();
6693341825Sdim
6694314564Sdim  ConstantInitBuilder builder(CGM);
6695314564Sdim  auto values = builder.beginStruct(ObjCTypes.CategorynfABITy);
6696314564Sdim  values.add(GetClassName(OCD->getIdentifier()->getName()));
6697193326Sed  // meta-class entry symbol
6698314564Sdim  values.add(GetClassGlobal(Interface, /*metaclass*/ false, NotForDefinition));
6699314564Sdim  std::string listName =
6700314564Sdim      (Interface->getObjCRuntimeNameAsString() + "_$_" + OCD->getName()).str();
6701276479Sdim
6702314564Sdim  SmallVector<const ObjCMethodDecl *, 16> instanceMethods;
6703314564Sdim  SmallVector<const ObjCMethodDecl *, 8> classMethods;
6704314564Sdim  for (const auto *MD : OCD->methods()) {
6705360784Sdim    if (MD->isDirectMethod())
6706360784Sdim      continue;
6707314564Sdim    if (MD->isInstanceMethod()) {
6708314564Sdim      instanceMethods.push_back(MD);
6709314564Sdim    } else {
6710314564Sdim      classMethods.push_back(MD);
6711314564Sdim    }
6712314564Sdim  }
6713198092Srdivacky
6714314564Sdim  values.add(emitMethodList(listName, MethodListType::CategoryInstanceMethods,
6715314564Sdim                            instanceMethods));
6716314564Sdim  values.add(emitMethodList(listName, MethodListType::CategoryClassMethods,
6717314564Sdim                            classMethods));
6718198092Srdivacky
6719198092Srdivacky  const ObjCCategoryDecl *Category =
6720193326Sed    Interface->FindCategoryDeclaration(OCD->getIdentifier());
6721193326Sed  if (Category) {
6722234353Sdim    SmallString<256> ExtName;
6723276479Sdim    llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
6724198398Srdivacky                                       << OCD->getName();
6725353358Sdim    values.add(EmitProtocolList("_OBJC_CATEGORY_PROTOCOLS_$_"
6726276479Sdim                                   + Interface->getObjCRuntimeNameAsString() + "_$_"
6727276479Sdim                                   + Category->getName(),
6728314564Sdim                                Category->protocol_begin(),
6729314564Sdim                                Category->protocol_end()));
6730353358Sdim    values.add(EmitPropertyList("_OBJC_$_PROP_LIST_" + ExtName.str(),
6731314564Sdim                                OCD, Category, ObjCTypes, false));
6732353358Sdim    values.add(EmitPropertyList("_OBJC_$_CLASS_PROP_LIST_" + ExtName.str(),
6733314564Sdim                                OCD, Category, ObjCTypes, true));
6734198092Srdivacky  } else {
6735314564Sdim    values.addNullPointer(ObjCTypes.ProtocolListnfABIPtrTy);
6736314564Sdim    values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6737314564Sdim    values.addNullPointer(ObjCTypes.PropertyListPtrTy);
6738193326Sed  }
6739198092Srdivacky
6740309124Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategorynfABITy);
6741314564Sdim  values.addInt(ObjCTypes.IntTy, Size);
6742309124Sdim
6743314564Sdim  llvm::GlobalVariable *GCATV =
6744353358Sdim      finishAndCreateGlobal(values, ExtCatName.str(), CGM);
6745276479Sdim  CGM.addCompilerUsedGlobal(GCATV);
6746353358Sdim  if (Interface->hasAttr<ObjCClassStubAttr>())
6747353358Sdim    DefinedStubCategories.push_back(GCATV);
6748353358Sdim  else
6749353358Sdim    DefinedCategories.push_back(GCATV);
6750193326Sed
6751193326Sed  // Determine if this category is also "non-lazy".
6752193326Sed  if (ImplementationIsNonLazy(OCD))
6753193326Sed    DefinedNonLazyCategories.push_back(GCATV);
6754221345Sdim  // method definition entries must be clear for next implementation.
6755221345Sdim  MethodDefinitions.clear();
6756193326Sed}
6757193326Sed
6758314564Sdim/// emitMethodConstant - Return a struct objc_method constant.  If
6759314564Sdim/// forProtocol is true, the implementation will be null; otherwise,
6760314564Sdim/// the method must have a definition registered with the runtime.
6761314564Sdim///
6762314564Sdim/// struct _objc_method {
6763314564Sdim///   SEL _cmd;
6764314564Sdim///   char *method_type;
6765314564Sdim///   char *_imp;
6766314564Sdim/// }
6767314564Sdimvoid CGObjCNonFragileABIMac::emitMethodConstant(ConstantArrayBuilder &builder,
6768314564Sdim                                                const ObjCMethodDecl *MD,
6769314564Sdim                                                bool forProtocol) {
6770314564Sdim  auto method = builder.beginStruct(ObjCTypes.MethodTy);
6771314564Sdim  method.addBitCast(GetMethodVarName(MD->getSelector()),
6772314564Sdim                    ObjCTypes.SelectorPtrTy);
6773314564Sdim  method.add(GetMethodVarType(MD));
6774198092Srdivacky
6775314564Sdim  if (forProtocol) {
6776314564Sdim    // Protocol methods have no implementation. So, this entry is always NULL.
6777314564Sdim    method.addNullPointer(ObjCTypes.Int8PtrTy);
6778314564Sdim  } else {
6779314564Sdim    llvm::Function *fn = GetMethodDefinition(MD);
6780314564Sdim    assert(fn && "no definition for method?");
6781314564Sdim    method.addBitCast(fn, ObjCTypes.Int8PtrTy);
6782314564Sdim  }
6783314564Sdim
6784314564Sdim  method.finishAndAddTo(builder);
6785193326Sed}
6786193326Sed
6787314564Sdim/// Build meta-data for method declarations.
6788314564Sdim///
6789193326Sed/// struct _method_list_t {
6790193326Sed///   uint32_t entsize;  // sizeof(struct _objc_method)
6791193326Sed///   uint32_t method_count;
6792193326Sed///   struct _objc_method method_list[method_count];
6793193326Sed/// }
6794193326Sed///
6795234353Sdimllvm::Constant *
6796314564SdimCGObjCNonFragileABIMac::emitMethodList(Twine name, MethodListType kind,
6797314564Sdim                              ArrayRef<const ObjCMethodDecl *> methods) {
6798193326Sed  // Return null for empty list.
6799314564Sdim  if (methods.empty())
6800193326Sed    return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6801198092Srdivacky
6802314564Sdim  StringRef prefix;
6803314564Sdim  bool forProtocol;
6804314564Sdim  switch (kind) {
6805314564Sdim  case MethodListType::CategoryInstanceMethods:
6806353358Sdim    prefix = "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
6807314564Sdim    forProtocol = false;
6808314564Sdim    break;
6809314564Sdim  case MethodListType::CategoryClassMethods:
6810353358Sdim    prefix = "_OBJC_$_CATEGORY_CLASS_METHODS_";
6811314564Sdim    forProtocol = false;
6812314564Sdim    break;
6813314564Sdim  case MethodListType::InstanceMethods:
6814353358Sdim    prefix = "_OBJC_$_INSTANCE_METHODS_";
6815314564Sdim    forProtocol = false;
6816314564Sdim    break;
6817314564Sdim  case MethodListType::ClassMethods:
6818353358Sdim    prefix = "_OBJC_$_CLASS_METHODS_";
6819314564Sdim    forProtocol = false;
6820314564Sdim    break;
6821314564Sdim
6822314564Sdim  case MethodListType::ProtocolInstanceMethods:
6823353358Sdim    prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_";
6824314564Sdim    forProtocol = true;
6825314564Sdim    break;
6826314564Sdim  case MethodListType::ProtocolClassMethods:
6827353358Sdim    prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_";
6828314564Sdim    forProtocol = true;
6829314564Sdim    break;
6830314564Sdim  case MethodListType::OptionalProtocolInstanceMethods:
6831353358Sdim    prefix = "_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_";
6832314564Sdim    forProtocol = true;
6833314564Sdim    break;
6834314564Sdim  case MethodListType::OptionalProtocolClassMethods:
6835353358Sdim    prefix = "_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_";
6836314564Sdim    forProtocol = true;
6837314564Sdim    break;
6838314564Sdim  }
6839314564Sdim
6840314564Sdim  ConstantInitBuilder builder(CGM);
6841314564Sdim  auto values = builder.beginStruct();
6842314564Sdim
6843193326Sed  // sizeof(struct _objc_method)
6844243830Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6845314564Sdim  values.addInt(ObjCTypes.IntTy, Size);
6846193326Sed  // method_count
6847314564Sdim  values.addInt(ObjCTypes.IntTy, methods.size());
6848314564Sdim  auto methodArray = values.beginArray(ObjCTypes.MethodTy);
6849360784Sdim  for (auto MD : methods)
6850314564Sdim    emitMethodConstant(methodArray, MD, forProtocol);
6851314564Sdim  methodArray.finishAndAddTo(values);
6852198092Srdivacky
6853353358Sdim  llvm::GlobalVariable *GV = finishAndCreateGlobal(values, prefix + name, CGM);
6854276479Sdim  CGM.addCompilerUsedGlobal(GV);
6855224145Sdim  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6856193326Sed}
6857193326Sed
6858193326Sed/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6859193326Sed/// the given ivar.
6860206125Srdivackyllvm::GlobalVariable *
6861206125SrdivackyCGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6862206125Srdivacky                                               const ObjCIvarDecl *Ivar) {
6863206125Srdivacky  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6864276479Sdim  llvm::SmallString<64> Name("OBJC_IVAR_$_");
6865276479Sdim  Name += Container->getObjCRuntimeNameAsString();
6866276479Sdim  Name += ".";
6867276479Sdim  Name += Ivar->getName();
6868309124Sdim  llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(Name);
6869309124Sdim  if (!IvarOffsetGV) {
6870309124Sdim    IvarOffsetGV =
6871309124Sdim        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.IvarOffsetVarTy,
6872309124Sdim                                 false, llvm::GlobalValue::ExternalLinkage,
6873309124Sdim                                 nullptr, Name.str());
6874309124Sdim    if (CGM.getTriple().isOSBinFormatCOFF()) {
6875309124Sdim      bool IsPrivateOrPackage =
6876309124Sdim          Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6877309124Sdim          Ivar->getAccessControl() == ObjCIvarDecl::Package;
6878309124Sdim
6879327952Sdim      const ObjCInterfaceDecl *ContainingID = Ivar->getContainingInterface();
6880327952Sdim
6881327952Sdim      if (ContainingID->hasAttr<DLLImportAttr>())
6882327952Sdim        IvarOffsetGV
6883327952Sdim            ->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
6884327952Sdim      else if (ContainingID->hasAttr<DLLExportAttr>() && !IsPrivateOrPackage)
6885327952Sdim        IvarOffsetGV
6886327952Sdim            ->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
6887309124Sdim    }
6888309124Sdim  }
6889193326Sed  return IvarOffsetGV;
6890193326Sed}
6891193326Sed
6892206125Srdivackyllvm::Constant *
6893206125SrdivackyCGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6894206125Srdivacky                                          const ObjCIvarDecl *Ivar,
6895206125Srdivacky                                          unsigned long int Offset) {
6896193326Sed  llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6897276479Sdim  IvarOffsetGV->setInitializer(
6898276479Sdim      llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
6899360784Sdim  IvarOffsetGV->setAlignment(llvm::Align(
6900360784Sdim      CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy)));
6901193326Sed
6902309124Sdim  if (!CGM.getTriple().isOSBinFormatCOFF()) {
6903309124Sdim    // FIXME: This matches gcc, but shouldn't the visibility be set on the use
6904309124Sdim    // as well (i.e., in ObjCIvarOffsetVariable).
6905309124Sdim    if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6906309124Sdim        Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6907309124Sdim        ID->getVisibility() == HiddenVisibility)
6908309124Sdim      IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6909309124Sdim    else
6910309124Sdim      IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6911309124Sdim  }
6912309124Sdim
6913353358Sdim  // If ID's layout is known, then make the global constant. This serves as a
6914353358Sdim  // useful assertion: we'll never use this variable to calculate ivar offsets,
6915353358Sdim  // so if the runtime tries to patch it then we should crash.
6916353358Sdim  if (isClassLayoutKnownStatically(ID))
6917353358Sdim    IvarOffsetGV->setConstant(true);
6918353358Sdim
6919314564Sdim  if (CGM.getTriple().isOSBinFormatMachO())
6920314564Sdim    IvarOffsetGV->setSection("__DATA, __objc_ivar");
6921193326Sed  return IvarOffsetGV;
6922193326Sed}
6923193326Sed
6924193326Sed/// EmitIvarList - Emit the ivar list for the given
6925193326Sed/// implementation. The return value has type
6926193326Sed/// IvarListnfABIPtrTy.
6927193326Sed///  struct _ivar_t {
6928276479Sdim///   unsigned [long] int *offset;  // pointer to ivar offset location
6929193326Sed///   char *name;
6930193326Sed///   char *type;
6931193326Sed///   uint32_t alignment;
6932193326Sed///   uint32_t size;
6933193326Sed/// }
6934193326Sed/// struct _ivar_list_t {
6935193326Sed///   uint32 entsize;  // sizeof(struct _ivar_t)
6936193326Sed///   uint32 count;
6937193326Sed///   struct _iver_t list[count];
6938193326Sed/// }
6939193326Sed///
6940193326Sed
6941193326Sedllvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6942198092Srdivacky  const ObjCImplementationDecl *ID) {
6943198092Srdivacky
6944314564Sdim  ConstantInitBuilder builder(CGM);
6945314564Sdim  auto ivarList = builder.beginStruct();
6946314564Sdim  ivarList.addInt(ObjCTypes.IntTy,
6947314564Sdim                  CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy));
6948314564Sdim  auto ivarCountSlot = ivarList.addPlaceholder();
6949314564Sdim  auto ivars = ivarList.beginArray(ObjCTypes.IvarnfABITy);
6950198092Srdivacky
6951226633Sdim  const ObjCInterfaceDecl *OID = ID->getClassInterface();
6952193326Sed  assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
6953198092Srdivacky
6954193326Sed  // FIXME. Consolidate this with similar code in GenerateClass.
6955198092Srdivacky
6956341825Sdim  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6957224145Sdim       IVD; IVD = IVD->getNextIvar()) {
6958193576Sed    // Ignore unnamed bit-fields.
6959193576Sed    if (!IVD->getDeclName())
6960193576Sed      continue;
6961314564Sdim
6962314564Sdim    auto ivar = ivars.beginStruct(ObjCTypes.IvarnfABITy);
6963314564Sdim    ivar.add(EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6964314564Sdim                               ComputeIvarBaseOffset(CGM, ID, IVD)));
6965314564Sdim    ivar.add(GetMethodVarName(IVD->getIdentifier()));
6966314564Sdim    ivar.add(GetMethodVarType(IVD));
6967226633Sdim    llvm::Type *FieldTy =
6968193326Sed      CGM.getTypes().ConvertTypeForMem(IVD->getType());
6969243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6970193326Sed    unsigned Align = CGM.getContext().getPreferredTypeAlign(
6971198092Srdivacky      IVD->getType().getTypePtr()) >> 3;
6972193326Sed    Align = llvm::Log2_32(Align);
6973314564Sdim    ivar.addInt(ObjCTypes.IntTy, Align);
6974193326Sed    // NOTE. Size of a bitfield does not match gcc's, because of the
6975193326Sed    // way bitfields are treated special in each. But I am told that
6976193326Sed    // 'size' for bitfield ivars is ignored by the runtime so it does
6977193326Sed    // not matter.  If it matters, there is enough info to get the
6978193326Sed    // bitfield right!
6979314564Sdim    ivar.addInt(ObjCTypes.IntTy, Size);
6980314564Sdim    ivar.finishAndAddTo(ivars);
6981193326Sed  }
6982193326Sed  // Return null for empty list.
6983314564Sdim  if (ivars.empty()) {
6984314564Sdim    ivars.abandon();
6985314564Sdim    ivarList.abandon();
6986193326Sed    return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6987314564Sdim  }
6988224145Sdim
6989314564Sdim  auto ivarCount = ivars.size();
6990314564Sdim  ivars.finishAndAddTo(ivarList);
6991314564Sdim  ivarList.fillPlaceholderWithInt(ivarCountSlot, ObjCTypes.IntTy, ivarCount);
6992314564Sdim
6993353358Sdim  const char *Prefix = "_OBJC_$_INSTANCE_VARIABLES_";
6994353358Sdim  llvm::GlobalVariable *GV = finishAndCreateGlobal(
6995353358Sdim      ivarList, Prefix + OID->getObjCRuntimeNameAsString(), CGM);
6996276479Sdim  CGM.addCompilerUsedGlobal(GV);
6997198092Srdivacky  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6998193326Sed}
6999193326Sed
7000193326Sedllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
7001198092Srdivacky  const ObjCProtocolDecl *PD) {
7002193326Sed  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
7003198092Srdivacky
7004314564Sdim  if (!Entry) {
7005193326Sed    // We use the initializer as a marker of whether this is a forward
7006193326Sed    // reference or not. At module finalization we add the empty
7007193326Sed    // contents for protocols which were referenced but never defined.
7008314564Sdim    llvm::SmallString<64> Protocol;
7009353358Sdim    llvm::raw_svector_ostream(Protocol) << "_OBJC_PROTOCOL_$_"
7010314564Sdim                                        << PD->getObjCRuntimeNameAsString();
7011198092Srdivacky
7012314564Sdim    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
7013314564Sdim                                     false, llvm::GlobalValue::ExternalLinkage,
7014314564Sdim                                     nullptr, Protocol);
7015314564Sdim    if (!CGM.getTriple().isOSBinFormatMachO())
7016314564Sdim      Entry->setComdat(CGM.getModule().getOrInsertComdat(Protocol));
7017314564Sdim  }
7018314564Sdim
7019193326Sed  return Entry;
7020193326Sed}
7021193326Sed
7022193326Sed/// GetOrEmitProtocol - Generate the protocol meta-data:
7023193326Sed/// @code
7024193326Sed/// struct _protocol_t {
7025193326Sed///   id isa;  // NULL
7026193326Sed///   const char * const protocol_name;
7027193326Sed///   const struct _protocol_list_t * protocol_list; // super protocols
7028193326Sed///   const struct method_list_t * const instance_methods;
7029193326Sed///   const struct method_list_t * const class_methods;
7030193326Sed///   const struct method_list_t *optionalInstanceMethods;
7031193326Sed///   const struct method_list_t *optionalClassMethods;
7032193326Sed///   const struct _prop_list_t * properties;
7033193326Sed///   const uint32_t size;  // sizeof(struct _protocol_t)
7034193326Sed///   const uint32_t flags;  // = 0
7035234353Sdim///   const char ** extendedMethodTypes;
7036288943Sdim///   const char *demangledName;
7037309124Sdim///   const struct _prop_list_t * class_properties;
7038193326Sed/// }
7039193326Sed/// @endcode
7040193326Sed///
7041193326Sed
7042193326Sedllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
7043198092Srdivacky  const ObjCProtocolDecl *PD) {
7044234353Sdim  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
7045198092Srdivacky
7046193326Sed  // Early exit if a defining object has already been generated.
7047193326Sed  if (Entry && Entry->hasInitializer())
7048193326Sed    return Entry;
7049193326Sed
7050234353Sdim  // Use the protocol definition, if there is one.
7051344779Sdim  assert(PD->hasDefinition() &&
7052344779Sdim         "emitting protocol metadata without definition");
7053344779Sdim  PD = PD->getDefinition();
7054341825Sdim
7055314564Sdim  auto methodLists = ProtocolMethodLists::get(PD);
7056198092Srdivacky
7057314564Sdim  ConstantInitBuilder builder(CGM);
7058314564Sdim  auto values = builder.beginStruct(ObjCTypes.ProtocolnfABITy);
7059223017Sdim
7060193326Sed  // isa is NULL
7061314564Sdim  values.addNullPointer(ObjCTypes.ObjectPtrTy);
7062314564Sdim  values.add(GetClassName(PD->getObjCRuntimeNameAsString()));
7063353358Sdim  values.add(EmitProtocolList("_OBJC_$_PROTOCOL_REFS_"
7064314564Sdim                                + PD->getObjCRuntimeNameAsString(),
7065198398Srdivacky                               PD->protocol_begin(),
7066314564Sdim                               PD->protocol_end()));
7067314564Sdim  values.add(methodLists.emitMethodList(this, PD,
7068314564Sdim                                 ProtocolMethodLists::RequiredInstanceMethods));
7069314564Sdim  values.add(methodLists.emitMethodList(this, PD,
7070314564Sdim                                 ProtocolMethodLists::RequiredClassMethods));
7071314564Sdim  values.add(methodLists.emitMethodList(this, PD,
7072314564Sdim                                 ProtocolMethodLists::OptionalInstanceMethods));
7073314564Sdim  values.add(methodLists.emitMethodList(this, PD,
7074314564Sdim                                 ProtocolMethodLists::OptionalClassMethods));
7075314564Sdim  values.add(EmitPropertyList(
7076353358Sdim               "_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
7077314564Sdim               nullptr, PD, ObjCTypes, false));
7078198092Srdivacky  uint32_t Size =
7079243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
7080314564Sdim  values.addInt(ObjCTypes.IntTy, Size);
7081314564Sdim  values.addInt(ObjCTypes.IntTy, 0);
7082353358Sdim  values.add(EmitProtocolMethodTypes("_OBJC_$_PROTOCOL_METHOD_TYPES_"
7083276479Sdim                                       + PD->getObjCRuntimeNameAsString(),
7084314564Sdim                                     methodLists.emitExtendedTypesArray(this),
7085314564Sdim                                     ObjCTypes));
7086314564Sdim
7087288943Sdim  // const char *demangledName;
7088314564Sdim  values.addNullPointer(ObjCTypes.Int8PtrTy);
7089309124Sdim
7090314564Sdim  values.add(EmitPropertyList(
7091353358Sdim      "_OBJC_$_CLASS_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
7092314564Sdim      nullptr, PD, ObjCTypes, true));
7093341825Sdim
7094193326Sed  if (Entry) {
7095280031Sdim    // Already created, fix the linkage and update the initializer.
7096280031Sdim    Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
7097314564Sdim    values.finishAndSetAsInitializer(Entry);
7098193326Sed  } else {
7099314564Sdim    llvm::SmallString<64> symbolName;
7100314564Sdim    llvm::raw_svector_ostream(symbolName)
7101353358Sdim      << "_OBJC_PROTOCOL_$_" << PD->getObjCRuntimeNameAsString();
7102234353Sdim
7103314564Sdim    Entry = values.finishAndCreateGlobal(symbolName, CGM.getPointerAlign(),
7104314564Sdim                                         /*constant*/ false,
7105314564Sdim                                         llvm::GlobalValue::WeakAnyLinkage);
7106314564Sdim    if (!CGM.getTriple().isOSBinFormatMachO())
7107314564Sdim      Entry->setComdat(CGM.getModule().getOrInsertComdat(symbolName));
7108314564Sdim
7109234353Sdim    Protocols[PD->getIdentifier()] = Entry;
7110193326Sed  }
7111193326Sed  Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7112341825Sdim  CGM.addUsedGlobal(Entry);
7113198092Srdivacky
7114193326Sed  // Use this protocol meta-data to build protocol list table in section
7115193326Sed  // __DATA, __objc_protolist
7116314564Sdim  llvm::SmallString<64> ProtocolRef;
7117353358Sdim  llvm::raw_svector_ostream(ProtocolRef) << "_OBJC_LABEL_PROTOCOL_$_"
7118314564Sdim                                         << PD->getObjCRuntimeNameAsString();
7119314564Sdim
7120198398Srdivacky  llvm::GlobalVariable *PTGV =
7121198398Srdivacky    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
7122198398Srdivacky                             false, llvm::GlobalValue::WeakAnyLinkage, Entry,
7123314564Sdim                             ProtocolRef);
7124314564Sdim  if (!CGM.getTriple().isOSBinFormatMachO())
7125314564Sdim    PTGV->setComdat(CGM.getModule().getOrInsertComdat(ProtocolRef));
7126360784Sdim  PTGV->setAlignment(llvm::Align(
7127360784Sdim      CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)));
7128321369Sdim  PTGV->setSection(GetSectionName("__objc_protolist",
7129321369Sdim                                  "coalesced,no_dead_strip"));
7130193326Sed  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
7131341825Sdim  CGM.addUsedGlobal(PTGV);
7132193326Sed  return Entry;
7133193326Sed}
7134193326Sed
7135193326Sed/// EmitProtocolList - Generate protocol list meta-data:
7136193326Sed/// @code
7137193326Sed/// struct _protocol_list_t {
7138193326Sed///   long protocol_count;   // Note, this is 32/64 bit
7139193326Sed///   struct _protocol_t[protocol_count];
7140193326Sed/// }
7141193326Sed/// @endcode
7142193326Sed///
7143193326Sedllvm::Constant *
7144226633SdimCGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
7145198398Srdivacky                                      ObjCProtocolDecl::protocol_iterator begin,
7146198398Srdivacky                                      ObjCProtocolDecl::protocol_iterator end) {
7147249423Sdim  SmallVector<llvm::Constant *, 16> ProtocolRefs;
7148198092Srdivacky
7149193326Sed  // Just return null for empty protocol lists
7150198092Srdivacky  if (begin == end)
7151193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
7152198092Srdivacky
7153193326Sed  // FIXME: We shouldn't need to do this lookup here, should we?
7154234353Sdim  SmallString<256> TmpName;
7155198398Srdivacky  Name.toVector(TmpName);
7156198398Srdivacky  llvm::GlobalVariable *GV =
7157198398Srdivacky    CGM.getModule().getGlobalVariable(TmpName.str(), true);
7158193326Sed  if (GV)
7159198398Srdivacky    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
7160198092Srdivacky
7161314564Sdim  ConstantInitBuilder builder(CGM);
7162314564Sdim  auto values = builder.beginStruct();
7163314564Sdim  auto countSlot = values.addPlaceholder();
7164314564Sdim
7165314564Sdim  // A null-terminated array of protocols.
7166314564Sdim  auto array = values.beginArray(ObjCTypes.ProtocolnfABIPtrTy);
7167193326Sed  for (; begin != end; ++begin)
7168314564Sdim    array.add(GetProtocolRef(*begin));  // Implemented???
7169314564Sdim  auto count = array.size();
7170314564Sdim  array.addNullPointer(ObjCTypes.ProtocolnfABIPtrTy);
7171193326Sed
7172314564Sdim  array.finishAndAddTo(values);
7173314564Sdim  values.fillPlaceholderWithInt(countSlot, ObjCTypes.LongTy, count);
7174198092Srdivacky
7175353358Sdim  GV = finishAndCreateGlobal(values, Name, CGM);
7176276479Sdim  CGM.addCompilerUsedGlobal(GV);
7177198092Srdivacky  return llvm::ConstantExpr::getBitCast(GV,
7178193326Sed                                        ObjCTypes.ProtocolListnfABIPtrTy);
7179193326Sed}
7180193326Sed
7181193326Sed/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
7182193326Sed/// This code gen. amounts to generating code for:
7183193326Sed/// @code
7184193326Sed/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
7185193326Sed/// @encode
7186198092Srdivacky///
7187193326SedLValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
7188208600Srdivacky                                               CodeGen::CodeGenFunction &CGF,
7189208600Srdivacky                                               QualType ObjectTy,
7190208600Srdivacky                                               llvm::Value *BaseValue,
7191208600Srdivacky                                               const ObjCIvarDecl *Ivar,
7192208600Srdivacky                                               unsigned CVRQualifiers) {
7193360784Sdim  ObjCInterfaceDecl *ID = ObjectTy->castAs<ObjCObjectType>()->getInterface();
7194234353Sdim  llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
7195193326Sed  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
7196234353Sdim                                  Offset);
7197193326Sed}
7198193326Sed
7199353358Sdimllvm::Value *
7200353358SdimCGObjCNonFragileABIMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
7201353358Sdim                                       const ObjCInterfaceDecl *Interface,
7202353358Sdim                                       const ObjCIvarDecl *Ivar) {
7203353358Sdim  llvm::Value *IvarOffsetValue;
7204353358Sdim  if (isClassLayoutKnownStatically(Interface)) {
7205353358Sdim    IvarOffsetValue = llvm::ConstantInt::get(
7206353358Sdim        ObjCTypes.IvarOffsetVarTy,
7207353358Sdim        ComputeIvarBaseOffset(CGM, Interface->getImplementation(), Ivar));
7208353358Sdim  } else {
7209353358Sdim    llvm::GlobalVariable *GV = ObjCIvarOffsetVariable(Interface, Ivar);
7210353358Sdim    IvarOffsetValue =
7211353358Sdim        CGF.Builder.CreateAlignedLoad(GV, CGF.getSizeAlign(), "ivar");
7212353358Sdim    if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
7213353358Sdim      cast<llvm::LoadInst>(IvarOffsetValue)
7214353358Sdim          ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
7215353358Sdim                        llvm::MDNode::get(VMContext, None));
7216353358Sdim  }
7217276479Sdim
7218276479Sdim  // This could be 32bit int or 64bit integer depending on the architecture.
7219276479Sdim  // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
7220341825Sdim  //  as this is what caller always expects.
7221276479Sdim  if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
7222276479Sdim    IvarOffsetValue = CGF.Builder.CreateIntCast(
7223276479Sdim        IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");
7224276479Sdim  return IvarOffsetValue;
7225193326Sed}
7226193326Sed
7227223017Sdimstatic void appendSelectorForMessageRefTable(std::string &buffer,
7228223017Sdim                                             Selector selector) {
7229223017Sdim  if (selector.isUnarySelector()) {
7230223017Sdim    buffer += selector.getNameForSlot(0);
7231223017Sdim    return;
7232223017Sdim  }
7233198092Srdivacky
7234223017Sdim  for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
7235223017Sdim    buffer += selector.getNameForSlot(i);
7236223017Sdim    buffer += '_';
7237223017Sdim  }
7238223017Sdim}
7239223017Sdim
7240309124Sdim/// Emit a "vtable" message send.  We emit a weak hidden-visibility
7241223017Sdim/// struct, initially containing the selector pointer and a pointer to
7242223017Sdim/// a "fixup" variant of the appropriate objc_msgSend.  To call, we
7243223017Sdim/// load and call the function pointer, passing the address of the
7244223017Sdim/// struct as the second parameter.  The runtime determines whether
7245223017Sdim/// the selector is currently emitted using vtable dispatch; if so, it
7246223017Sdim/// substitutes a stub function which simply tail-calls through the
7247223017Sdim/// appropriate vtable slot, and if not, it substitues a stub function
7248223017Sdim/// which tail-calls objc_msgSend.  Both stubs adjust the selector
7249223017Sdim/// argument to correctly point to the selector.
7250223017SdimRValue
7251223017SdimCGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
7252223017Sdim                                              ReturnValueSlot returnSlot,
7253223017Sdim                                              QualType resultType,
7254223017Sdim                                              Selector selector,
7255223017Sdim                                              llvm::Value *arg0,
7256223017Sdim                                              QualType arg0Type,
7257223017Sdim                                              bool isSuper,
7258223017Sdim                                              const CallArgList &formalArgs,
7259223017Sdim                                              const ObjCMethodDecl *method) {
7260223017Sdim  // Compute the actual arguments.
7261223017Sdim  CallArgList args;
7262223017Sdim
7263223017Sdim  // First argument: the receiver / super-call structure.
7264223017Sdim  if (!isSuper)
7265223017Sdim    arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
7266223017Sdim  args.add(RValue::get(arg0), arg0Type);
7267223017Sdim
7268223017Sdim  // Second argument: a pointer to the message ref structure.  Leave
7269223017Sdim  // the actual argument value blank for now.
7270276479Sdim  args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
7271223017Sdim
7272223017Sdim  args.insert(args.end(), formalArgs.begin(), formalArgs.end());
7273223017Sdim
7274234353Sdim  MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
7275223017Sdim
7276223017Sdim  NullReturnState nullReturn;
7277223017Sdim
7278223017Sdim  // Find the function to call and the mangled name for the message
7279223017Sdim  // ref structure.  Using a different mangled name wouldn't actually
7280223017Sdim  // be a problem; it would just be a waste.
7281223017Sdim  //
7282223017Sdim  // The runtime currently never uses vtable dispatch for anything
7283223017Sdim  // except normal, non-super message-sends.
7284223017Sdim  // FIXME: don't use this for that.
7285353358Sdim  llvm::FunctionCallee fn = nullptr;
7286353358Sdim  std::string messageRefName("_");
7287276479Sdim  if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
7288223017Sdim    if (isSuper) {
7289223017Sdim      fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
7290223017Sdim      messageRefName += "objc_msgSendSuper2_stret_fixup";
7291212904Sdim    } else {
7292223017Sdim      nullReturn.init(CGF, arg0);
7293223017Sdim      fn = ObjCTypes.getMessageSendStretFixupFn();
7294223017Sdim      messageRefName += "objc_msgSend_stret_fixup";
7295212904Sdim    }
7296223017Sdim  } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
7297223017Sdim    fn = ObjCTypes.getMessageSendFpretFixupFn();
7298223017Sdim    messageRefName += "objc_msgSend_fpret_fixup";
7299198092Srdivacky  } else {
7300223017Sdim    if (isSuper) {
7301223017Sdim      fn = ObjCTypes.getMessageSendSuper2FixupFn();
7302223017Sdim      messageRefName += "objc_msgSendSuper2_fixup";
7303212904Sdim    } else {
7304223017Sdim      fn = ObjCTypes.getMessageSendFixupFn();
7305223017Sdim      messageRefName += "objc_msgSend_fixup";
7306212904Sdim    }
7307193326Sed  }
7308223017Sdim  assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
7309223017Sdim  messageRefName += '_';
7310223017Sdim
7311223017Sdim  // Append the selector name, except use underscores anywhere we
7312223017Sdim  // would have used colons.
7313223017Sdim  appendSelectorForMessageRefTable(messageRefName, selector);
7314223017Sdim
7315223017Sdim  llvm::GlobalVariable *messageRef
7316223017Sdim    = CGM.getModule().getGlobalVariable(messageRefName);
7317223017Sdim  if (!messageRef) {
7318223017Sdim    // Build the message ref structure.
7319314564Sdim    ConstantInitBuilder builder(CGM);
7320314564Sdim    auto values = builder.beginStruct();
7321353358Sdim    values.add(cast<llvm::Constant>(fn.getCallee()));
7322314564Sdim    values.add(GetMethodVarName(selector));
7323314564Sdim    messageRef = values.finishAndCreateGlobal(messageRefName,
7324314564Sdim                                              CharUnits::fromQuantity(16),
7325314564Sdim                                              /*constant*/ false,
7326314564Sdim                                        llvm::GlobalValue::WeakAnyLinkage);
7327223017Sdim    messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
7328321369Sdim    messageRef->setSection(GetSectionName("__objc_msgrefs", "coalesced"));
7329193326Sed  }
7330341825Sdim
7331234353Sdim  bool requiresnullCheck = false;
7332234353Sdim  if (CGM.getLangOpts().ObjCAutoRefCount && method)
7333309124Sdim    for (const auto *ParamDecl : method->parameters()) {
7334234353Sdim      if (ParamDecl->hasAttr<NSConsumedAttr>()) {
7335234353Sdim        if (!nullReturn.NullBB)
7336234353Sdim          nullReturn.init(CGF, arg0);
7337234353Sdim        requiresnullCheck = true;
7338234353Sdim        break;
7339234353Sdim      }
7340234353Sdim    }
7341341825Sdim
7342296417Sdim  Address mref =
7343296417Sdim    Address(CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy),
7344296417Sdim            CGF.getPointerAlign());
7345198092Srdivacky
7346223017Sdim  // Update the message ref argument.
7347341825Sdim  args[1].setRValue(RValue::get(mref.getPointer()));
7348223017Sdim
7349223017Sdim  // Load the function to call from the message ref table.
7350353358Sdim  Address calleeAddr = CGF.Builder.CreateStructGEP(mref, 0);
7351314564Sdim  llvm::Value *calleePtr = CGF.Builder.CreateLoad(calleeAddr, "msgSend_fn");
7352223017Sdim
7353314564Sdim  calleePtr = CGF.Builder.CreateBitCast(calleePtr, MSI.MessengerType);
7354314564Sdim  CGCallee callee(CGCalleeInfo(), calleePtr);
7355223017Sdim
7356234353Sdim  RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
7357321369Sdim  return nullReturn.complete(CGF, returnSlot, result, resultType, formalArgs,
7358276479Sdim                             requiresnullCheck ? method : nullptr);
7359193326Sed}
7360193326Sed
7361193326Sed/// Generate code for a message send expression in the nonfragile abi.
7362198092SrdivackyCodeGen::RValue
7363198092SrdivackyCGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
7364208600Srdivacky                                            ReturnValueSlot Return,
7365198092Srdivacky                                            QualType ResultType,
7366198092Srdivacky                                            Selector Sel,
7367198092Srdivacky                                            llvm::Value *Receiver,
7368198092Srdivacky                                            const CallArgList &CallArgs,
7369207619Srdivacky                                            const ObjCInterfaceDecl *Class,
7370198092Srdivacky                                            const ObjCMethodDecl *Method) {
7371223017Sdim  return isVTableDispatchedSelector(Sel)
7372223017Sdim    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7373198092Srdivacky                            Receiver, CGF.getContext().getObjCIdType(),
7374223017Sdim                            false, CallArgs, Method)
7375360784Sdim    : EmitMessageSend(CGF, Return, ResultType, Sel,
7376198092Srdivacky                      Receiver, CGF.getContext().getObjCIdType(),
7377296417Sdim                      false, CallArgs, Method, Class, ObjCTypes);
7378193326Sed}
7379193326Sed
7380314564Sdimllvm::Constant *
7381314564SdimCGObjCNonFragileABIMac::GetClassGlobal(const ObjCInterfaceDecl *ID,
7382314564Sdim                                       bool metaclass,
7383314564Sdim                                       ForDefinition_t isForDefinition) {
7384314564Sdim  auto prefix =
7385314564Sdim    (metaclass ? getMetaclassSymbolPrefix() : getClassSymbolPrefix());
7386314564Sdim  return GetClassGlobal((prefix + ID->getObjCRuntimeNameAsString()).str(),
7387314564Sdim                        isForDefinition,
7388314564Sdim                        ID->isWeakImported(),
7389314564Sdim                        !isForDefinition
7390314564Sdim                          && CGM.getTriple().isOSBinFormatCOFF()
7391314564Sdim                          && ID->hasAttr<DLLImportAttr>());
7392314564Sdim}
7393314564Sdim
7394314564Sdimllvm::Constant *
7395314564SdimCGObjCNonFragileABIMac::GetClassGlobal(StringRef Name,
7396314564Sdim                                       ForDefinition_t IsForDefinition,
7397314564Sdim                                       bool Weak, bool DLLImport) {
7398276479Sdim  llvm::GlobalValue::LinkageTypes L =
7399276479Sdim      Weak ? llvm::GlobalValue::ExternalWeakLinkage
7400276479Sdim           : llvm::GlobalValue::ExternalLinkage;
7401276479Sdim
7402193326Sed  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
7403344779Sdim  if (!GV || GV->getType() != ObjCTypes.ClassnfABITy->getPointerTo()) {
7404344779Sdim    auto *NewGV = new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, L,
7405344779Sdim                                           nullptr, Name);
7406193326Sed
7407314564Sdim    if (DLLImport)
7408344779Sdim      NewGV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
7409344779Sdim
7410344779Sdim    if (GV) {
7411344779Sdim      GV->replaceAllUsesWith(
7412344779Sdim          llvm::ConstantExpr::getBitCast(NewGV, GV->getType()));
7413344779Sdim      GV->eraseFromParent();
7414344779Sdim    }
7415344779Sdim    GV = NewGV;
7416344779Sdim    CGM.getModule().getGlobalList().push_back(GV);
7417314564Sdim  }
7418314564Sdim
7419276479Sdim  assert(GV->getLinkage() == L);
7420193326Sed  return GV;
7421193326Sed}
7422193326Sed
7423353358Sdimllvm::Constant *
7424353358SdimCGObjCNonFragileABIMac::GetClassGlobalForClassRef(const ObjCInterfaceDecl *ID) {
7425353358Sdim  llvm::Constant *ClassGV = GetClassGlobal(ID, /*metaclass*/ false,
7426353358Sdim                                           NotForDefinition);
7427353358Sdim
7428353358Sdim  if (!ID->hasAttr<ObjCClassStubAttr>())
7429353358Sdim    return ClassGV;
7430353358Sdim
7431353358Sdim  ClassGV = llvm::ConstantExpr::getPointerCast(ClassGV, ObjCTypes.Int8PtrTy);
7432353358Sdim
7433353358Sdim  // Stub classes are pointer-aligned. Classrefs pointing at stub classes
7434353358Sdim  // must set the least significant bit set to 1.
7435353358Sdim  auto *Idx = llvm::ConstantInt::get(CGM.Int32Ty, 1);
7436353358Sdim  return llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, ClassGV, Idx);
7437353358Sdim}
7438353358Sdim
7439314564Sdimllvm::Value *
7440353358SdimCGObjCNonFragileABIMac::EmitLoadOfClassRef(CodeGenFunction &CGF,
7441353358Sdim                                           const ObjCInterfaceDecl *ID,
7442353358Sdim                                           llvm::GlobalVariable *Entry) {
7443353358Sdim  if (ID && ID->hasAttr<ObjCClassStubAttr>()) {
7444353358Sdim    // Classrefs pointing at Objective-C stub classes must be loaded by calling
7445353358Sdim    // a special runtime function.
7446353358Sdim    return CGF.EmitRuntimeCall(
7447353358Sdim      ObjCTypes.getLoadClassrefFn(), Entry, "load_classref_result");
7448353358Sdim  }
7449353358Sdim
7450353358Sdim  CharUnits Align = CGF.getPointerAlign();
7451353358Sdim  return CGF.Builder.CreateAlignedLoad(Entry, Align);
7452353358Sdim}
7453353358Sdim
7454353358Sdimllvm::Value *
7455314564SdimCGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
7456314564Sdim                                           IdentifierInfo *II,
7457314564Sdim                                           const ObjCInterfaceDecl *ID) {
7458224145Sdim  llvm::GlobalVariable *&Entry = ClassReferences[II];
7459341825Sdim
7460193326Sed  if (!Entry) {
7461314564Sdim    llvm::Constant *ClassGV;
7462314564Sdim    if (ID) {
7463353358Sdim      ClassGV = GetClassGlobalForClassRef(ID);
7464314564Sdim    } else {
7465314564Sdim      ClassGV = GetClassGlobal((getClassSymbolPrefix() + II->getName()).str(),
7466314564Sdim                               NotForDefinition);
7467353358Sdim      assert(ClassGV->getType() == ObjCTypes.ClassnfABIPtrTy &&
7468353358Sdim             "classref was emitted with the wrong type?");
7469314564Sdim    }
7470314564Sdim
7471353358Sdim    std::string SectionName =
7472353358Sdim        GetSectionName("__objc_classrefs", "regular,no_dead_strip");
7473353358Sdim    Entry = new llvm::GlobalVariable(
7474353358Sdim        CGM.getModule(), ClassGV->getType(), false,
7475353358Sdim        getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
7476353358Sdim        "OBJC_CLASSLIST_REFERENCES_$_");
7477360784Sdim    Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7478353358Sdim    if (!ID || !ID->hasAttr<ObjCClassStubAttr>())
7479353358Sdim      Entry->setSection(SectionName);
7480353358Sdim
7481276479Sdim    CGM.addCompilerUsedGlobal(Entry);
7482193326Sed  }
7483353358Sdim
7484353358Sdim  return EmitLoadOfClassRef(CGF, ID, Entry);
7485193326Sed}
7486193326Sed
7487249423Sdimllvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
7488224145Sdim                                                  const ObjCInterfaceDecl *ID) {
7489309124Sdim  // If the class has the objc_runtime_visible attribute, we need to
7490309124Sdim  // use the Objective-C runtime to get the class.
7491309124Sdim  if (ID->hasAttr<ObjCRuntimeVisibleAttr>())
7492309124Sdim    return EmitClassRefViaRuntime(CGF, ID, ObjCTypes);
7493309124Sdim
7494314564Sdim  return EmitClassRefFromId(CGF, ID->getIdentifier(), ID);
7495224145Sdim}
7496224145Sdim
7497224145Sdimllvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
7498249423Sdim                                                    CodeGenFunction &CGF) {
7499224145Sdim  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
7500314564Sdim  return EmitClassRefFromId(CGF, II, nullptr);
7501224145Sdim}
7502224145Sdim
7503193326Sedllvm::Value *
7504249423SdimCGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
7505193326Sed                                          const ObjCInterfaceDecl *ID) {
7506193326Sed  llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
7507198092Srdivacky
7508193326Sed  if (!Entry) {
7509353358Sdim    llvm::Constant *ClassGV = GetClassGlobalForClassRef(ID);
7510353358Sdim    std::string SectionName =
7511353358Sdim        GetSectionName("__objc_superrefs", "regular,no_dead_strip");
7512353358Sdim    Entry = new llvm::GlobalVariable(
7513353358Sdim        CGM.getModule(), ClassGV->getType(), false,
7514353358Sdim        getLinkageTypeForObjCMetadata(CGM, SectionName), ClassGV,
7515353358Sdim        "OBJC_CLASSLIST_SUP_REFS_$_");
7516360784Sdim    Entry->setAlignment(CGF.getPointerAlign().getAsAlign());
7517353358Sdim    Entry->setSection(SectionName);
7518276479Sdim    CGM.addCompilerUsedGlobal(Entry);
7519193326Sed  }
7520353358Sdim
7521353358Sdim  return EmitLoadOfClassRef(CGF, ID, Entry);
7522193326Sed}
7523193326Sed
7524193326Sed/// EmitMetaClassRef - Return a Value * of the address of _class_t
7525193326Sed/// meta-data
7526193326Sed///
7527249423Sdimllvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
7528276479Sdim                                                      const ObjCInterfaceDecl *ID,
7529276479Sdim                                                      bool Weak) {
7530296417Sdim  CharUnits Align = CGF.getPointerAlign();
7531193326Sed  llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
7532276479Sdim  if (!Entry) {
7533314564Sdim    auto MetaClassGV = GetClassGlobal(ID, /*metaclass*/ true, NotForDefinition);
7534353358Sdim    std::string SectionName =
7535353358Sdim        GetSectionName("__objc_superrefs", "regular,no_dead_strip");
7536353358Sdim    Entry = new llvm::GlobalVariable(
7537353358Sdim        CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
7538353358Sdim        getLinkageTypeForObjCMetadata(CGM, SectionName), MetaClassGV,
7539353358Sdim        "OBJC_CLASSLIST_SUP_REFS_$_");
7540360784Sdim    Entry->setAlignment(Align.getAsAlign());
7541353358Sdim    Entry->setSection(SectionName);
7542276479Sdim    CGM.addCompilerUsedGlobal(Entry);
7543276479Sdim  }
7544198092Srdivacky
7545296417Sdim  return CGF.Builder.CreateAlignedLoad(Entry, Align);
7546193326Sed}
7547193326Sed
7548193326Sed/// GetClass - Return a reference to the class for the given interface
7549193326Sed/// decl.
7550249423Sdimllvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
7551193326Sed                                              const ObjCInterfaceDecl *ID) {
7552221345Sdim  if (ID->isWeakImported()) {
7553314564Sdim    auto ClassGV = GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition);
7554276479Sdim    (void)ClassGV;
7555314564Sdim    assert(!isa<llvm::GlobalVariable>(ClassGV) ||
7556314564Sdim           cast<llvm::GlobalVariable>(ClassGV)->hasExternalWeakLinkage());
7557199482Srdivacky  }
7558341825Sdim
7559249423Sdim  return EmitClassRef(CGF, ID);
7560193326Sed}
7561193326Sed
7562193326Sed/// Generates a message send where the super is the receiver.  This is
7563193326Sed/// a message send to self with special delivery semantics indicating
7564193326Sed/// which class's method should be called.
7565193326SedCodeGen::RValue
7566193326SedCGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
7567208600Srdivacky                                                 ReturnValueSlot Return,
7568198092Srdivacky                                                 QualType ResultType,
7569198092Srdivacky                                                 Selector Sel,
7570198092Srdivacky                                                 const ObjCInterfaceDecl *Class,
7571198092Srdivacky                                                 bool isCategoryImpl,
7572198092Srdivacky                                                 llvm::Value *Receiver,
7573198092Srdivacky                                                 bool IsClassMessage,
7574198092Srdivacky                                                 const CodeGen::CallArgList &CallArgs,
7575198092Srdivacky                                                 const ObjCMethodDecl *Method) {
7576193326Sed  // ...
7577193326Sed  // Create and init a super structure; this is a (receiver, class)
7578193326Sed  // pair we will pass to objc_msgSendSuper.
7579296417Sdim  Address ObjCSuper =
7580296417Sdim    CGF.CreateTempAlloca(ObjCTypes.SuperTy, CGF.getPointerAlign(),
7581296417Sdim                         "objc_super");
7582198092Srdivacky
7583193326Sed  llvm::Value *ReceiverAsObject =
7584193326Sed    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
7585353358Sdim  CGF.Builder.CreateStore(ReceiverAsObject,
7586353358Sdim                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
7587198092Srdivacky
7588193326Sed  // If this is a class message the metaclass is passed as the target.
7589193326Sed  llvm::Value *Target;
7590243830Sdim  if (IsClassMessage)
7591280031Sdim      Target = EmitMetaClassRef(CGF, Class, Class->isWeakImported());
7592243830Sdim  else
7593249423Sdim    Target = EmitSuperClassRef(CGF, Class);
7594198092Srdivacky
7595193326Sed  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
7596193326Sed  // ObjCTypes types.
7597226633Sdim  llvm::Type *ClassTy =
7598193326Sed    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
7599193326Sed  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
7600353358Sdim  CGF.Builder.CreateStore(Target, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
7601198092Srdivacky
7602223017Sdim  return (isVTableDispatchedSelector(Sel))
7603223017Sdim    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
7604296417Sdim                            ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7605223017Sdim                            true, CallArgs, Method)
7606360784Sdim    : EmitMessageSend(CGF, Return, ResultType, Sel,
7607296417Sdim                      ObjCSuper.getPointer(), ObjCTypes.SuperPtrCTy,
7608296417Sdim                      true, CallArgs, Method, Class, ObjCTypes);
7609193326Sed}
7610193326Sed
7611249423Sdimllvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
7612296417Sdim                                                  Selector Sel) {
7613360784Sdim  Address Addr = EmitSelectorAddr(Sel);
7614296417Sdim
7615296417Sdim  llvm::LoadInst* LI = CGF.Builder.CreateLoad(Addr);
7616341825Sdim  LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
7617296417Sdim                  llvm::MDNode::get(VMContext, None));
7618296417Sdim  return LI;
7619296417Sdim}
7620296417Sdim
7621360784SdimAddress CGObjCNonFragileABIMac::EmitSelectorAddr(Selector Sel) {
7622193326Sed  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
7623360784Sdim  CharUnits Align = CGM.getPointerAlign();
7624193326Sed  if (!Entry) {
7625198092Srdivacky    llvm::Constant *Casted =
7626198092Srdivacky      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
7627198092Srdivacky                                     ObjCTypes.SelectorPtrTy);
7628353358Sdim    std::string SectionName =
7629353358Sdim        GetSectionName("__objc_selrefs", "literal_pointers,no_dead_strip");
7630353358Sdim    Entry = new llvm::GlobalVariable(
7631353358Sdim        CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
7632353358Sdim        getLinkageTypeForObjCMetadata(CGM, SectionName), Casted,
7633353358Sdim        "OBJC_SELECTOR_REFERENCES_");
7634249423Sdim    Entry->setExternallyInitialized(true);
7635353358Sdim    Entry->setSection(SectionName);
7636360784Sdim    Entry->setAlignment(Align.getAsAlign());
7637276479Sdim    CGM.addCompilerUsedGlobal(Entry);
7638193326Sed  }
7639198092Srdivacky
7640296417Sdim  return Address(Entry, Align);
7641193326Sed}
7642296417Sdim
7643193326Sed/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
7644198092Srdivacky/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
7645193326Sed///
7646193326Sedvoid CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
7647198092Srdivacky                                                llvm::Value *src,
7648296417Sdim                                                Address dst,
7649198092Srdivacky                                                llvm::Value *ivarOffset) {
7650226633Sdim  llvm::Type * SrcTy = src->getType();
7651193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
7652243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7653193326Sed    assert(Size <= 8 && "does not support size > 8");
7654193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7655193326Sed           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7656193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7657193326Sed  }
7658193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7659193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7660296417Sdim  llvm::Value *args[] = { src, dst.getPointer(), ivarOffset };
7661249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
7662193326Sed}
7663193326Sed
7664193326Sed/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
7665193326Sed/// objc_assign_strongCast (id src, id *dst)
7666193326Sed///
7667193326Sedvoid CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
7668198092Srdivacky  CodeGen::CodeGenFunction &CGF,
7669296417Sdim  llvm::Value *src, Address dst) {
7670226633Sdim  llvm::Type * SrcTy = src->getType();
7671193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
7672243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7673193326Sed    assert(Size <= 8 && "does not support size > 8");
7674193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7675198092Srdivacky           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7676193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7677193326Sed  }
7678193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7679193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7680296417Sdim  llvm::Value *args[] = { src, dst.getPointer() };
7681249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
7682249423Sdim                              args, "weakassign");
7683193326Sed}
7684193326Sed
7685198092Srdivackyvoid CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
7686198092Srdivacky  CodeGen::CodeGenFunction &CGF,
7687296417Sdim  Address DestPtr,
7688296417Sdim  Address SrcPtr,
7689210299Sed  llvm::Value *Size) {
7690198092Srdivacky  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
7691198092Srdivacky  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
7692296417Sdim  llvm::Value *args[] = { DestPtr.getPointer(), SrcPtr.getPointer(), Size };
7693249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
7694198092Srdivacky}
7695198092Srdivacky
7696193326Sed/// EmitObjCWeakRead - Code gen for loading value of a __weak
7697193326Sed/// object: objc_read_weak (id *src)
7698193326Sed///
7699193326Sedllvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
7700198092Srdivacky  CodeGen::CodeGenFunction &CGF,
7701296417Sdim  Address AddrWeakObj) {
7702296417Sdim  llvm::Type *DestTy = AddrWeakObj.getElementType();
7703198092Srdivacky  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
7704249423Sdim  llvm::Value *read_weak =
7705249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
7706296417Sdim                                AddrWeakObj.getPointer(), "weakread");
7707193326Sed  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
7708193326Sed  return read_weak;
7709193326Sed}
7710193326Sed
7711193326Sed/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
7712193326Sed/// objc_assign_weak (id src, id *dst)
7713193326Sed///
7714193326Sedvoid CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
7715296417Sdim                                                llvm::Value *src, Address dst) {
7716226633Sdim  llvm::Type * SrcTy = src->getType();
7717193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
7718243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7719193326Sed    assert(Size <= 8 && "does not support size > 8");
7720193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7721193326Sed           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7722193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7723193326Sed  }
7724193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7725193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7726296417Sdim  llvm::Value *args[] = { src, dst.getPointer() };
7727249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
7728249423Sdim                              args, "weakassign");
7729193326Sed}
7730193326Sed
7731193326Sed/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
7732193326Sed/// objc_assign_global (id src, id *dst)
7733193326Sed///
7734193326Sedvoid CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
7735296417Sdim                                          llvm::Value *src, Address dst,
7736212904Sdim                                          bool threadlocal) {
7737226633Sdim  llvm::Type * SrcTy = src->getType();
7738193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
7739243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
7740193326Sed    assert(Size <= 8 && "does not support size > 8");
7741193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
7742193326Sed           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
7743193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
7744193326Sed  }
7745193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
7746193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
7747296417Sdim  llvm::Value *args[] = { src, dst.getPointer() };
7748212904Sdim  if (!threadlocal)
7749249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
7750249423Sdim                                args, "globalassign");
7751212904Sdim  else
7752249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
7753249423Sdim                                args, "threadlocalassign");
7754193326Sed}
7755193326Sed
7756198092Srdivackyvoid
7757210299SedCGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
7758210299Sed                                             const ObjCAtSynchronizedStmt &S) {
7759353358Sdim  EmitAtSynchronizedStmt(CGF, S, ObjCTypes.getSyncEnterFn(),
7760353358Sdim                         ObjCTypes.getSyncExitFn());
7761210299Sed}
7762193326Sed
7763212904Sdimllvm::Constant *
7764212904SdimCGObjCNonFragileABIMac::GetEHType(QualType T) {
7765212904Sdim  // There's a particular fixed type info for 'id'.
7766309124Sdim  if (T->isObjCIdType() || T->isObjCQualifiedIdType()) {
7767309124Sdim    auto *IDEHType = CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
7768309124Sdim    if (!IDEHType) {
7769212904Sdim      IDEHType =
7770309124Sdim          new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7771309124Sdim                                   llvm::GlobalValue::ExternalLinkage, nullptr,
7772309124Sdim                                   "OBJC_EHTYPE_id");
7773309124Sdim      if (CGM.getTriple().isOSBinFormatCOFF())
7774309124Sdim        IDEHType->setDLLStorageClass(getStorage(CGM, "OBJC_EHTYPE_id"));
7775309124Sdim    }
7776212904Sdim    return IDEHType;
7777212904Sdim  }
7778212904Sdim
7779212904Sdim  // All other types should be Objective-C interface pointer types.
7780309124Sdim  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
7781212904Sdim  assert(PT && "Invalid @catch type.");
7782309124Sdim
7783212904Sdim  const ObjCInterfaceType *IT = PT->getInterfaceType();
7784212904Sdim  assert(IT && "Invalid @catch type.");
7785309124Sdim
7786314564Sdim  return GetInterfaceEHType(IT->getDecl(), NotForDefinition);
7787309124Sdim}
7788212904Sdim
7789210299Sedvoid CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
7790210299Sed                                         const ObjCAtTryStmt &S) {
7791353358Sdim  EmitTryCatchStmt(CGF, S, ObjCTypes.getObjCBeginCatchFn(),
7792353358Sdim                   ObjCTypes.getObjCEndCatchFn(),
7793353358Sdim                   ObjCTypes.getExceptionRethrowFn());
7794193326Sed}
7795193326Sed
7796193326Sed/// EmitThrowStmt - Generate code for a throw statement.
7797193326Sedvoid CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
7798249423Sdim                                           const ObjCAtThrowStmt &S,
7799249423Sdim                                           bool ClearInsertionPoint) {
7800193326Sed  if (const Expr *ThrowExpr = S.getThrowExpr()) {
7801226633Sdim    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
7802226633Sdim    Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7803353358Sdim    llvm::CallBase *Call =
7804353358Sdim        CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception);
7805353358Sdim    Call->setDoesNotReturn();
7806193326Sed  } else {
7807353358Sdim    llvm::CallBase *Call =
7808353358Sdim        CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn());
7809353358Sdim    Call->setDoesNotReturn();
7810193326Sed  }
7811193326Sed
7812218893Sdim  CGF.Builder.CreateUnreachable();
7813249423Sdim  if (ClearInsertionPoint)
7814249423Sdim    CGF.Builder.ClearInsertionPoint();
7815193326Sed}
7816193326Sed
7817212904Sdimllvm::Constant *
7818198092SrdivackyCGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7819314564Sdim                                           ForDefinition_t IsForDefinition) {
7820193326Sed  llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7821309124Sdim  StringRef ClassName = ID->getObjCRuntimeNameAsString();
7822193326Sed
7823193326Sed  // If we don't need a definition, return the entry if found or check
7824193326Sed  // if we use an external reference.
7825314564Sdim  if (!IsForDefinition) {
7826193326Sed    if (Entry)
7827193326Sed      return Entry;
7828193326Sed
7829193326Sed    // If this type (or a super class) has the __objc_exception__
7830193326Sed    // attribute, emit an external reference.
7831309124Sdim    if (hasObjCExceptionAttribute(CGM.getContext(), ID)) {
7832309124Sdim      std::string EHTypeName = ("OBJC_EHTYPE_$_" + ClassName).str();
7833309124Sdim      Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
7834309124Sdim                                       false, llvm::GlobalValue::ExternalLinkage,
7835309124Sdim                                       nullptr, EHTypeName);
7836341825Sdim      CGM.setGVProperties(Entry, ID);
7837309124Sdim      return Entry;
7838309124Sdim    }
7839193326Sed  }
7840198092Srdivacky
7841309124Sdim  // Otherwise we need to either make a new entry or fill in the initializer.
7842193326Sed  assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
7843309124Sdim
7844193326Sed  std::string VTableName = "objc_ehtype_vtable";
7845309124Sdim  auto *VTableGV = CGM.getModule().getGlobalVariable(VTableName);
7846309124Sdim  if (!VTableGV) {
7847309124Sdim    VTableGV =
7848309124Sdim        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy, false,
7849309124Sdim                                 llvm::GlobalValue::ExternalLinkage, nullptr,
7850309124Sdim                                 VTableName);
7851309124Sdim    if (CGM.getTriple().isOSBinFormatCOFF())
7852309124Sdim      VTableGV->setDLLStorageClass(getStorage(CGM, VTableName));
7853309124Sdim  }
7854193326Sed
7855234353Sdim  llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7856314564Sdim  ConstantInitBuilder builder(CGM);
7857314564Sdim  auto values = builder.beginStruct(ObjCTypes.EHTypeTy);
7858327952Sdim  values.add(
7859327952Sdim    llvm::ConstantExpr::getInBoundsGetElementPtr(VTableGV->getValueType(),
7860327952Sdim                                                 VTableGV, VTableIdx));
7861314564Sdim  values.add(GetClassName(ClassName));
7862314564Sdim  values.add(GetClassGlobal(ID, /*metaclass*/ false, NotForDefinition));
7863193326Sed
7864314564Sdim  llvm::GlobalValue::LinkageTypes L = IsForDefinition
7865276479Sdim                                          ? llvm::GlobalValue::ExternalLinkage
7866276479Sdim                                          : llvm::GlobalValue::WeakAnyLinkage;
7867193326Sed  if (Entry) {
7868314564Sdim    values.finishAndSetAsInitializer(Entry);
7869360784Sdim    Entry->setAlignment(CGM.getPointerAlign().getAsAlign());
7870193326Sed  } else {
7871314564Sdim    Entry = values.finishAndCreateGlobal("OBJC_EHTYPE_$_" + ClassName,
7872314564Sdim                                         CGM.getPointerAlign(),
7873314564Sdim                                         /*constant*/ false,
7874314564Sdim                                         L);
7875341825Sdim    if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7876341825Sdim      CGM.setGVProperties(Entry, ID);
7877193326Sed  }
7878276479Sdim  assert(Entry->getLinkage() == L);
7879193326Sed
7880309124Sdim  if (!CGM.getTriple().isOSBinFormatCOFF())
7881309124Sdim    if (ID->getVisibility() == HiddenVisibility)
7882309124Sdim      Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7883193326Sed
7884314564Sdim  if (IsForDefinition)
7885314564Sdim    if (CGM.getTriple().isOSBinFormatMachO())
7886314564Sdim      Entry->setSection("__DATA,__objc_const");
7887309124Sdim
7888193326Sed  return Entry;
7889193326Sed}
7890198092Srdivacky
7891193326Sed/* *** */
7892193326Sed
7893193326SedCodeGen::CGObjCRuntime *
7894193326SedCodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7895239462Sdim  switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7896239462Sdim  case ObjCRuntime::FragileMacOSX:
7897239462Sdim  return new CGObjCMac(CGM);
7898239462Sdim
7899239462Sdim  case ObjCRuntime::MacOSX:
7900239462Sdim  case ObjCRuntime::iOS:
7901296417Sdim  case ObjCRuntime::WatchOS:
7902221345Sdim    return new CGObjCNonFragileABIMac(CGM);
7903239462Sdim
7904239462Sdim  case ObjCRuntime::GNUstep:
7905239462Sdim  case ObjCRuntime::GCC:
7906239462Sdim  case ObjCRuntime::ObjFW:
7907239462Sdim    llvm_unreachable("these runtimes are not Mac runtimes");
7908239462Sdim  }
7909239462Sdim  llvm_unreachable("bad runtime");
7910193326Sed}
7911