1193326Sed//===------- CGObjCMac.cpp - Interface to Apple Objective-C Runtime -------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10221345Sdim// This provides Objective-C code generation targeting the Apple runtime.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "CGObjCRuntime.h"
15249423Sdim#include "CGBlocks.h"
16249423Sdim#include "CGCleanup.h"
17206084Srdivacky#include "CGRecordLayout.h"
18249423Sdim#include "CodeGenFunction.h"
19193326Sed#include "CodeGenModule.h"
20193326Sed#include "clang/AST/ASTContext.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"
25193326Sed#include "clang/Basic/LangOptions.h"
26263508Sdim#include "clang/CodeGen/CGFunctionInfo.h"
27210299Sed#include "clang/Frontend/CodeGenOptions.h"
28193326Sed#include "llvm/ADT/DenseSet.h"
29198092Srdivacky#include "llvm/ADT/SetVector.h"
30249423Sdim#include "llvm/ADT/SmallPtrSet.h"
31198092Srdivacky#include "llvm/ADT/SmallString.h"
32249423Sdim#include "llvm/IR/DataLayout.h"
33249423Sdim#include "llvm/IR/InlineAsm.h"
34249423Sdim#include "llvm/IR/IntrinsicInst.h"
35249423Sdim#include "llvm/IR/LLVMContext.h"
36249423Sdim#include "llvm/IR/Module.h"
37210299Sed#include "llvm/Support/CallSite.h"
38198092Srdivacky#include "llvm/Support/raw_ostream.h"
39198092Srdivacky#include <cstdio>
40193326Sed
41193326Sedusing namespace clang;
42193326Sedusing namespace CodeGen;
43193326Sed
44193326Sednamespace {
45193326Sed
46198092Srdivacky// FIXME: We should find a nicer way to make the labels for metadata, string
47198092Srdivacky// concatenation is lame.
48193326Sed
49193326Sedclass ObjCCommonTypesHelper {
50198092Srdivackyprotected:
51198092Srdivacky  llvm::LLVMContext &VMContext;
52198092Srdivacky
53193326Sedprivate:
54223017Sdim  // The types of these functions don't really matter because we
55223017Sdim  // should always bitcast before calling them.
56223017Sdim
57223017Sdim  /// id objc_msgSend (id, SEL, ...)
58223017Sdim  ///
59223017Sdim  /// The default messenger, used for sends whose ABI is unchanged from
60223017Sdim  /// the all-integer/pointer case.
61193326Sed  llvm::Constant *getMessageSendFn() const {
62224145Sdim    // Add the non-lazy-bind attribute, since objc_msgSend is likely to
63224145Sdim    // be called a lot.
64224145Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
65249423Sdim    return
66249423Sdim      CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
67249423Sdim                                                        params, true),
68249423Sdim                                "objc_msgSend",
69249423Sdim                                llvm::AttributeSet::get(CGM.getLLVMContext(),
70249423Sdim                                              llvm::AttributeSet::FunctionIndex,
71249423Sdim                                                 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.
79193326Sed  llvm::Constant *getMessageSendStretFn() const {
80224145Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
81223017Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy,
82223017Sdim                                                             params, true),
83223017Sdim                                     "objc_msgSend_stret");
84198092Srdivacky
85193326Sed  }
86198092Srdivacky
87223017Sdim  /// [double | long double] objc_msgSend_fpret(id self, SEL op, ...)
88223017Sdim  ///
89223017Sdim  /// The messenger used when the return value is returned on the x87
90223017Sdim  /// floating-point stack; without a special entrypoint, the nil case
91223017Sdim  /// would be unbalanced.
92193326Sed  llvm::Constant *getMessageSendFpretFn() const {
93224145Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
94234353Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.DoubleTy,
95234353Sdim                                                             params, true),
96223017Sdim                                     "objc_msgSend_fpret");
97198092Srdivacky
98193326Sed  }
99198092Srdivacky
100234353Sdim  /// _Complex long double objc_msgSend_fp2ret(id self, SEL op, ...)
101234353Sdim  ///
102234353Sdim  /// The messenger used when the return value is returned in two values on the
103234353Sdim  /// x87 floating point stack; without a special entrypoint, the nil case
104234353Sdim  /// would be unbalanced. Only used on 64-bit X86.
105234353Sdim  llvm::Constant *getMessageSendFp2retFn() const {
106234353Sdim    llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
107234353Sdim    llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
108234353Sdim    llvm::Type *resultType =
109234353Sdim      llvm::StructType::get(longDoubleType, longDoubleType, NULL);
110234353Sdim
111234353Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
112234353Sdim                                                             params, true),
113234353Sdim                                     "objc_msgSend_fp2ret");
114234353Sdim  }
115234353Sdim
116223017Sdim  /// id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
117223017Sdim  ///
118223017Sdim  /// The messenger used for super calls, which have different dispatch
119223017Sdim  /// semantics.  The class passed is the superclass of the current
120223017Sdim  /// class.
121193326Sed  llvm::Constant *getMessageSendSuperFn() const {
122224145Sdim    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
123193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
124223017Sdim                                                             params, true),
125223017Sdim                                     "objc_msgSendSuper");
126193326Sed  }
127198092Srdivacky
128223017Sdim  /// id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
129223017Sdim  ///
130223017Sdim  /// A slightly different messenger used for super calls.  The class
131223017Sdim  /// passed is the current class.
132193326Sed  llvm::Constant *getMessageSendSuperFn2() const {
133224145Sdim    llvm::Type *params[] = { SuperPtrTy, SelectorPtrTy };
134193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
135223017Sdim                                                             params, true),
136223017Sdim                                     "objc_msgSendSuper2");
137193326Sed  }
138198092Srdivacky
139223017Sdim  /// void objc_msgSendSuper_stret(void *stretAddr, struct objc_super *super,
140223017Sdim  ///                              SEL op, ...)
141223017Sdim  ///
142223017Sdim  /// The messenger used for super calls which return an aggregate indirectly.
143193326Sed  llvm::Constant *getMessageSendSuperStretFn() const {
144224145Sdim    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
145198092Srdivacky    return CGM.CreateRuntimeFunction(
146223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, true),
147198092Srdivacky      "objc_msgSendSuper_stret");
148193326Sed  }
149198092Srdivacky
150223017Sdim  /// void objc_msgSendSuper2_stret(void * stretAddr, struct objc_super *super,
151223017Sdim  ///                               SEL op, ...)
152223017Sdim  ///
153223017Sdim  /// objc_msgSendSuper_stret with the super2 semantics.
154193326Sed  llvm::Constant *getMessageSendSuperStretFn2() const {
155224145Sdim    llvm::Type *params[] = { Int8PtrTy, SuperPtrTy, SelectorPtrTy };
156198092Srdivacky    return CGM.CreateRuntimeFunction(
157223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, true),
158198092Srdivacky      "objc_msgSendSuper2_stret");
159193326Sed  }
160198092Srdivacky
161193326Sed  llvm::Constant *getMessageSendSuperFpretFn() const {
162193326Sed    // There is no objc_msgSendSuper_fpret? How can that work?
163193326Sed    return getMessageSendSuperFn();
164193326Sed  }
165198092Srdivacky
166193326Sed  llvm::Constant *getMessageSendSuperFpretFn2() const {
167193326Sed    // There is no objc_msgSendSuper_fpret? How can that work?
168193326Sed    return getMessageSendSuperFn2();
169193326Sed  }
170198092Srdivacky
171193326Sedprotected:
172193326Sed  CodeGen::CodeGenModule &CGM;
173198092Srdivacky
174193326Sedpublic:
175224145Sdim  llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
176234353Sdim  llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
177198092Srdivacky
178193326Sed  /// ObjectPtrTy - LLVM type for object handles (typeof(id))
179224145Sdim  llvm::Type *ObjectPtrTy;
180198092Srdivacky
181193326Sed  /// PtrObjectPtrTy - LLVM type for id *
182224145Sdim  llvm::Type *PtrObjectPtrTy;
183198092Srdivacky
184193326Sed  /// SelectorPtrTy - LLVM type for selector handles (typeof(SEL))
185224145Sdim  llvm::Type *SelectorPtrTy;
186234353Sdim
187234353Sdimprivate:
188193326Sed  /// ProtocolPtrTy - LLVM type for external protocol handles
189193326Sed  /// (typeof(Protocol))
190224145Sdim  llvm::Type *ExternalProtocolPtrTy;
191234353Sdim
192234353Sdimpublic:
193234353Sdim  llvm::Type *getExternalProtocolPtrTy() {
194234353Sdim    if (!ExternalProtocolPtrTy) {
195234353Sdim      // FIXME: It would be nice to unify this with the opaque type, so that the
196234353Sdim      // IR comes out a bit cleaner.
197234353Sdim      CodeGen::CodeGenTypes &Types = CGM.getTypes();
198234353Sdim      ASTContext &Ctx = CGM.getContext();
199234353Sdim      llvm::Type *T = Types.ConvertType(Ctx.getObjCProtoType());
200234353Sdim      ExternalProtocolPtrTy = llvm::PointerType::getUnqual(T);
201234353Sdim    }
202234353Sdim
203234353Sdim    return ExternalProtocolPtrTy;
204234353Sdim  }
205234353Sdim
206193326Sed  // SuperCTy - clang type for struct objc_super.
207193326Sed  QualType SuperCTy;
208193326Sed  // SuperPtrCTy - clang type for struct objc_super *.
209193326Sed  QualType SuperPtrCTy;
210198092Srdivacky
211193326Sed  /// SuperTy - LLVM type for struct objc_super.
212224145Sdim  llvm::StructType *SuperTy;
213193326Sed  /// SuperPtrTy - LLVM type for struct objc_super *.
214224145Sdim  llvm::Type *SuperPtrTy;
215198092Srdivacky
216193326Sed  /// PropertyTy - LLVM type for struct objc_property (struct _prop_t
217193326Sed  /// in GCC parlance).
218224145Sdim  llvm::StructType *PropertyTy;
219198092Srdivacky
220193326Sed  /// PropertyListTy - LLVM type for struct objc_property_list
221193326Sed  /// (_prop_list_t in GCC parlance).
222224145Sdim  llvm::StructType *PropertyListTy;
223193326Sed  /// PropertyListPtrTy - LLVM type for struct objc_property_list*.
224224145Sdim  llvm::Type *PropertyListPtrTy;
225198092Srdivacky
226193326Sed  // MethodTy - LLVM type for struct objc_method.
227224145Sdim  llvm::StructType *MethodTy;
228198092Srdivacky
229193326Sed  /// CacheTy - LLVM type for struct objc_cache.
230224145Sdim  llvm::Type *CacheTy;
231193326Sed  /// CachePtrTy - LLVM type for struct objc_cache *.
232224145Sdim  llvm::Type *CachePtrTy;
233224145Sdim
234193326Sed  llvm::Constant *getGetPropertyFn() {
235193326Sed    CodeGen::CodeGenTypes &Types = CGM.getTypes();
236193326Sed    ASTContext &Ctx = CGM.getContext();
237193326Sed    // id objc_getProperty (id, SEL, ptrdiff_t, bool)
238226633Sdim    SmallVector<CanQualType,4> Params;
239204643Srdivacky    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
240204643Srdivacky    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
241193326Sed    Params.push_back(IdType);
242193326Sed    Params.push_back(SelType);
243221345Sdim    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
244193326Sed    Params.push_back(Ctx.BoolTy);
245226633Sdim    llvm::FunctionType *FTy =
246239462Sdim      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, Params,
247239462Sdim                                                    FunctionType::ExtInfo(),
248239462Sdim                                                          RequiredArgs::All));
249193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
250193326Sed  }
251198092Srdivacky
252193326Sed  llvm::Constant *getSetPropertyFn() {
253193326Sed    CodeGen::CodeGenTypes &Types = CGM.getTypes();
254193326Sed    ASTContext &Ctx = CGM.getContext();
255193326Sed    // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool)
256226633Sdim    SmallVector<CanQualType,6> Params;
257204643Srdivacky    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
258204643Srdivacky    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
259193326Sed    Params.push_back(IdType);
260193326Sed    Params.push_back(SelType);
261221345Sdim    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
262193326Sed    Params.push_back(IdType);
263193326Sed    Params.push_back(Ctx.BoolTy);
264193326Sed    Params.push_back(Ctx.BoolTy);
265226633Sdim    llvm::FunctionType *FTy =
266239462Sdim      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
267239462Sdim                                                     FunctionType::ExtInfo(),
268239462Sdim                                                          RequiredArgs::All));
269193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
270193326Sed  }
271198092Srdivacky
272234353Sdim  llvm::Constant *getOptimizedSetPropertyFn(bool atomic, bool copy) {
273234353Sdim    CodeGen::CodeGenTypes &Types = CGM.getTypes();
274234353Sdim    ASTContext &Ctx = CGM.getContext();
275234353Sdim    // void objc_setProperty_atomic(id self, SEL _cmd,
276234353Sdim    //                              id newValue, ptrdiff_t offset);
277234353Sdim    // void objc_setProperty_nonatomic(id self, SEL _cmd,
278234353Sdim    //                                 id newValue, ptrdiff_t offset);
279234353Sdim    // void objc_setProperty_atomic_copy(id self, SEL _cmd,
280234353Sdim    //                                   id newValue, ptrdiff_t offset);
281234353Sdim    // void objc_setProperty_nonatomic_copy(id self, SEL _cmd,
282234353Sdim    //                                      id newValue, ptrdiff_t offset);
283234353Sdim
284234353Sdim    SmallVector<CanQualType,4> Params;
285234353Sdim    CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType());
286234353Sdim    CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType());
287234353Sdim    Params.push_back(IdType);
288234353Sdim    Params.push_back(SelType);
289234353Sdim    Params.push_back(IdType);
290234353Sdim    Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
291234353Sdim    llvm::FunctionType *FTy =
292239462Sdim    Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
293239462Sdim                                                        FunctionType::ExtInfo(),
294239462Sdim                                                        RequiredArgs::All));
295234353Sdim    const char *name;
296234353Sdim    if (atomic && copy)
297234353Sdim      name = "objc_setProperty_atomic_copy";
298234353Sdim    else if (atomic && !copy)
299234353Sdim      name = "objc_setProperty_atomic";
300234353Sdim    else if (!atomic && copy)
301234353Sdim      name = "objc_setProperty_nonatomic_copy";
302234353Sdim    else
303234353Sdim      name = "objc_setProperty_nonatomic";
304234353Sdim
305234353Sdim    return CGM.CreateRuntimeFunction(FTy, name);
306234353Sdim  }
307207619Srdivacky
308207619Srdivacky  llvm::Constant *getCopyStructFn() {
309207619Srdivacky    CodeGen::CodeGenTypes &Types = CGM.getTypes();
310207619Srdivacky    ASTContext &Ctx = CGM.getContext();
311207619Srdivacky    // void objc_copyStruct (void *, const void *, size_t, bool, bool)
312226633Sdim    SmallVector<CanQualType,5> Params;
313207619Srdivacky    Params.push_back(Ctx.VoidPtrTy);
314207619Srdivacky    Params.push_back(Ctx.VoidPtrTy);
315207619Srdivacky    Params.push_back(Ctx.LongTy);
316207619Srdivacky    Params.push_back(Ctx.BoolTy);
317207619Srdivacky    Params.push_back(Ctx.BoolTy);
318226633Sdim    llvm::FunctionType *FTy =
319239462Sdim      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
320239462Sdim                                                     FunctionType::ExtInfo(),
321239462Sdim                                                          RequiredArgs::All));
322207619Srdivacky    return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
323207619Srdivacky  }
324207619Srdivacky
325234353Sdim  /// This routine declares and returns address of:
326234353Sdim  /// void objc_copyCppObjectAtomic(
327234353Sdim  ///         void *dest, const void *src,
328234353Sdim  ///         void (*copyHelper) (void *dest, const void *source));
329234353Sdim  llvm::Constant *getCppAtomicObjectFunction() {
330234353Sdim    CodeGen::CodeGenTypes &Types = CGM.getTypes();
331234353Sdim    ASTContext &Ctx = CGM.getContext();
332234353Sdim    /// void objc_copyCppObjectAtomic(void *dest, const void *src, void *helper);
333234353Sdim    SmallVector<CanQualType,3> Params;
334234353Sdim    Params.push_back(Ctx.VoidPtrTy);
335234353Sdim    Params.push_back(Ctx.VoidPtrTy);
336234353Sdim    Params.push_back(Ctx.VoidPtrTy);
337234353Sdim    llvm::FunctionType *FTy =
338239462Sdim      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
339239462Sdim                                                     FunctionType::ExtInfo(),
340239462Sdim                                                          RequiredArgs::All));
341234353Sdim    return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
342234353Sdim  }
343234353Sdim
344193326Sed  llvm::Constant *getEnumerationMutationFn() {
345198092Srdivacky    CodeGen::CodeGenTypes &Types = CGM.getTypes();
346198092Srdivacky    ASTContext &Ctx = CGM.getContext();
347193326Sed    // void objc_enumerationMutation (id)
348226633Sdim    SmallVector<CanQualType,1> Params;
349204643Srdivacky    Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
350226633Sdim    llvm::FunctionType *FTy =
351239462Sdim      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
352234353Sdim                                                      FunctionType::ExtInfo(),
353234353Sdim                                                      RequiredArgs::All));
354193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
355193326Sed  }
356198092Srdivacky
357193326Sed  /// GcReadWeakFn -- LLVM objc_read_weak (id *src) function.
358193326Sed  llvm::Constant *getGcReadWeakFn() {
359193326Sed    // id objc_read_weak (id *)
360224145Sdim    llvm::Type *args[] = { ObjectPtrTy->getPointerTo() };
361198092Srdivacky    llvm::FunctionType *FTy =
362223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
363193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_read_weak");
364198092Srdivacky  }
365198092Srdivacky
366193326Sed  /// GcAssignWeakFn -- LLVM objc_assign_weak function.
367193326Sed  llvm::Constant *getGcAssignWeakFn() {
368193326Sed    // id objc_assign_weak (id, id *)
369224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
370193326Sed    llvm::FunctionType *FTy =
371223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
372193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_weak");
373193326Sed  }
374198092Srdivacky
375193326Sed  /// GcAssignGlobalFn -- LLVM objc_assign_global function.
376193326Sed  llvm::Constant *getGcAssignGlobalFn() {
377193326Sed    // id objc_assign_global(id, id *)
378224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
379198092Srdivacky    llvm::FunctionType *FTy =
380223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
381193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_global");
382193326Sed  }
383198092Srdivacky
384212904Sdim  /// GcAssignThreadLocalFn -- LLVM objc_assign_threadlocal function.
385212904Sdim  llvm::Constant *getGcAssignThreadLocalFn() {
386212904Sdim    // id objc_assign_threadlocal(id src, id * dest)
387224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
388212904Sdim    llvm::FunctionType *FTy =
389223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
390212904Sdim    return CGM.CreateRuntimeFunction(FTy, "objc_assign_threadlocal");
391212904Sdim  }
392212904Sdim
393193326Sed  /// GcAssignIvarFn -- LLVM objc_assign_ivar function.
394193326Sed  llvm::Constant *getGcAssignIvarFn() {
395198092Srdivacky    // id objc_assign_ivar(id, id *, ptrdiff_t)
396224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo(),
397224145Sdim                           CGM.PtrDiffTy };
398198092Srdivacky    llvm::FunctionType *FTy =
399223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
400193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_ivar");
401193326Sed  }
402198092Srdivacky
403198092Srdivacky  /// GcMemmoveCollectableFn -- LLVM objc_memmove_collectable function.
404198092Srdivacky  llvm::Constant *GcMemmoveCollectableFn() {
405198092Srdivacky    // void *objc_memmove_collectable(void *dst, const void *src, size_t size)
406224145Sdim    llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, LongTy };
407223017Sdim    llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, args, false);
408198092Srdivacky    return CGM.CreateRuntimeFunction(FTy, "objc_memmove_collectable");
409198092Srdivacky  }
410198092Srdivacky
411193326Sed  /// GcAssignStrongCastFn -- LLVM objc_assign_strongCast function.
412193326Sed  llvm::Constant *getGcAssignStrongCastFn() {
413212904Sdim    // id objc_assign_strongCast(id, id *)
414224145Sdim    llvm::Type *args[] = { ObjectPtrTy, ObjectPtrTy->getPointerTo() };
415198092Srdivacky    llvm::FunctionType *FTy =
416223017Sdim      llvm::FunctionType::get(ObjectPtrTy, args, false);
417193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_assign_strongCast");
418193326Sed  }
419193326Sed
420193326Sed  /// ExceptionThrowFn - LLVM objc_exception_throw function.
421193326Sed  llvm::Constant *getExceptionThrowFn() {
422193326Sed    // void objc_exception_throw(id)
423224145Sdim    llvm::Type *args[] = { ObjectPtrTy };
424193326Sed    llvm::FunctionType *FTy =
425223017Sdim      llvm::FunctionType::get(CGM.VoidTy, args, false);
426193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_exception_throw");
427193326Sed  }
428198092Srdivacky
429210299Sed  /// ExceptionRethrowFn - LLVM objc_exception_rethrow function.
430210299Sed  llvm::Constant *getExceptionRethrowFn() {
431210299Sed    // void objc_exception_rethrow(void)
432223017Sdim    llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
433210299Sed    return CGM.CreateRuntimeFunction(FTy, "objc_exception_rethrow");
434210299Sed  }
435210299Sed
436193326Sed  /// SyncEnterFn - LLVM object_sync_enter function.
437193326Sed  llvm::Constant *getSyncEnterFn() {
438243830Sdim    // int objc_sync_enter (id)
439224145Sdim    llvm::Type *args[] = { ObjectPtrTy };
440193326Sed    llvm::FunctionType *FTy =
441243830Sdim      llvm::FunctionType::get(CGM.IntTy, args, false);
442193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_sync_enter");
443193326Sed  }
444198092Srdivacky
445193326Sed  /// SyncExitFn - LLVM object_sync_exit function.
446193326Sed  llvm::Constant *getSyncExitFn() {
447243830Sdim    // int objc_sync_exit (id)
448224145Sdim    llvm::Type *args[] = { ObjectPtrTy };
449193326Sed    llvm::FunctionType *FTy =
450243830Sdim      llvm::FunctionType::get(CGM.IntTy, args, false);
451193326Sed    return CGM.CreateRuntimeFunction(FTy, "objc_sync_exit");
452193326Sed  }
453198092Srdivacky
454193326Sed  llvm::Constant *getSendFn(bool IsSuper) const {
455193326Sed    return IsSuper ? getMessageSendSuperFn() : getMessageSendFn();
456193326Sed  }
457198092Srdivacky
458193326Sed  llvm::Constant *getSendFn2(bool IsSuper) const {
459193326Sed    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFn();
460193326Sed  }
461198092Srdivacky
462193326Sed  llvm::Constant *getSendStretFn(bool IsSuper) const {
463193326Sed    return IsSuper ? getMessageSendSuperStretFn() : getMessageSendStretFn();
464193326Sed  }
465198092Srdivacky
466193326Sed  llvm::Constant *getSendStretFn2(bool IsSuper) const {
467193326Sed    return IsSuper ? getMessageSendSuperStretFn2() : getMessageSendStretFn();
468193326Sed  }
469198092Srdivacky
470193326Sed  llvm::Constant *getSendFpretFn(bool IsSuper) const {
471193326Sed    return IsSuper ? getMessageSendSuperFpretFn() : getMessageSendFpretFn();
472193326Sed  }
473198092Srdivacky
474193326Sed  llvm::Constant *getSendFpretFn2(bool IsSuper) const {
475193326Sed    return IsSuper ? getMessageSendSuperFpretFn2() : getMessageSendFpretFn();
476193326Sed  }
477198092Srdivacky
478234353Sdim  llvm::Constant *getSendFp2retFn(bool IsSuper) const {
479234353Sdim    return IsSuper ? getMessageSendSuperFn() : getMessageSendFp2retFn();
480234353Sdim  }
481234353Sdim
482234353Sdim  llvm::Constant *getSendFp2RetFn2(bool IsSuper) const {
483234353Sdim    return IsSuper ? getMessageSendSuperFn2() : getMessageSendFp2retFn();
484234353Sdim  }
485234353Sdim
486193326Sed  ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm);
487193326Sed  ~ObjCCommonTypesHelper(){}
488193326Sed};
489193326Sed
490193326Sed/// ObjCTypesHelper - Helper class that encapsulates lazy
491193326Sed/// construction of varies types used during ObjC generation.
492193326Sedclass ObjCTypesHelper : public ObjCCommonTypesHelper {
493193326Sedpublic:
494193326Sed  /// SymtabTy - LLVM type for struct objc_symtab.
495224145Sdim  llvm::StructType *SymtabTy;
496193326Sed  /// SymtabPtrTy - LLVM type for struct objc_symtab *.
497224145Sdim  llvm::Type *SymtabPtrTy;
498193326Sed  /// ModuleTy - LLVM type for struct objc_module.
499224145Sdim  llvm::StructType *ModuleTy;
500193326Sed
501193326Sed  /// ProtocolTy - LLVM type for struct objc_protocol.
502224145Sdim  llvm::StructType *ProtocolTy;
503193326Sed  /// ProtocolPtrTy - LLVM type for struct objc_protocol *.
504224145Sdim  llvm::Type *ProtocolPtrTy;
505193326Sed  /// ProtocolExtensionTy - LLVM type for struct
506193326Sed  /// objc_protocol_extension.
507224145Sdim  llvm::StructType *ProtocolExtensionTy;
508193326Sed  /// ProtocolExtensionTy - LLVM type for struct
509193326Sed  /// objc_protocol_extension *.
510224145Sdim  llvm::Type *ProtocolExtensionPtrTy;
511193326Sed  /// MethodDescriptionTy - LLVM type for struct
512193326Sed  /// objc_method_description.
513224145Sdim  llvm::StructType *MethodDescriptionTy;
514193326Sed  /// MethodDescriptionListTy - LLVM type for struct
515193326Sed  /// objc_method_description_list.
516224145Sdim  llvm::StructType *MethodDescriptionListTy;
517193326Sed  /// MethodDescriptionListPtrTy - LLVM type for struct
518193326Sed  /// objc_method_description_list *.
519224145Sdim  llvm::Type *MethodDescriptionListPtrTy;
520193326Sed  /// ProtocolListTy - LLVM type for struct objc_property_list.
521224145Sdim  llvm::StructType *ProtocolListTy;
522193326Sed  /// ProtocolListPtrTy - LLVM type for struct objc_property_list*.
523224145Sdim  llvm::Type *ProtocolListPtrTy;
524193326Sed  /// CategoryTy - LLVM type for struct objc_category.
525224145Sdim  llvm::StructType *CategoryTy;
526193326Sed  /// ClassTy - LLVM type for struct objc_class.
527224145Sdim  llvm::StructType *ClassTy;
528193326Sed  /// ClassPtrTy - LLVM type for struct objc_class *.
529224145Sdim  llvm::Type *ClassPtrTy;
530193326Sed  /// ClassExtensionTy - LLVM type for struct objc_class_ext.
531224145Sdim  llvm::StructType *ClassExtensionTy;
532193326Sed  /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *.
533224145Sdim  llvm::Type *ClassExtensionPtrTy;
534193326Sed  // IvarTy - LLVM type for struct objc_ivar.
535224145Sdim  llvm::StructType *IvarTy;
536193326Sed  /// IvarListTy - LLVM type for struct objc_ivar_list.
537224145Sdim  llvm::Type *IvarListTy;
538193326Sed  /// IvarListPtrTy - LLVM type for struct objc_ivar_list *.
539224145Sdim  llvm::Type *IvarListPtrTy;
540193326Sed  /// MethodListTy - LLVM type for struct objc_method_list.
541224145Sdim  llvm::Type *MethodListTy;
542193326Sed  /// MethodListPtrTy - LLVM type for struct objc_method_list *.
543224145Sdim  llvm::Type *MethodListPtrTy;
544198092Srdivacky
545193326Sed  /// ExceptionDataTy - LLVM type for struct _objc_exception_data.
546224145Sdim  llvm::Type *ExceptionDataTy;
547224145Sdim
548193326Sed  /// ExceptionTryEnterFn - LLVM objc_exception_try_enter function.
549193326Sed  llvm::Constant *getExceptionTryEnterFn() {
550224145Sdim    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
551198092Srdivacky    return CGM.CreateRuntimeFunction(
552223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, false),
553198092Srdivacky      "objc_exception_try_enter");
554193326Sed  }
555193326Sed
556193326Sed  /// ExceptionTryExitFn - LLVM objc_exception_try_exit function.
557193326Sed  llvm::Constant *getExceptionTryExitFn() {
558224145Sdim    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
559198092Srdivacky    return CGM.CreateRuntimeFunction(
560223017Sdim      llvm::FunctionType::get(CGM.VoidTy, params, false),
561198092Srdivacky      "objc_exception_try_exit");
562193326Sed  }
563193326Sed
564193326Sed  /// ExceptionExtractFn - LLVM objc_exception_extract function.
565193326Sed  llvm::Constant *getExceptionExtractFn() {
566224145Sdim    llvm::Type *params[] = { ExceptionDataTy->getPointerTo() };
567193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
568223017Sdim                                                             params, false),
569193326Sed                                     "objc_exception_extract");
570193326Sed  }
571198092Srdivacky
572193326Sed  /// ExceptionMatchFn - LLVM objc_exception_match function.
573193326Sed  llvm::Constant *getExceptionMatchFn() {
574224145Sdim    llvm::Type *params[] = { ClassPtrTy, ObjectPtrTy };
575198092Srdivacky    return CGM.CreateRuntimeFunction(
576223017Sdim      llvm::FunctionType::get(CGM.Int32Ty, params, false),
577198092Srdivacky      "objc_exception_match");
578198092Srdivacky
579193326Sed  }
580198092Srdivacky
581193326Sed  /// SetJmpFn - LLVM _setjmp function.
582193326Sed  llvm::Constant *getSetJmpFn() {
583223017Sdim    // This is specifically the prototype for x86.
584224145Sdim    llvm::Type *params[] = { CGM.Int32Ty->getPointerTo() };
585249423Sdim    return
586249423Sdim      CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty,
587249423Sdim                                                        params, false),
588249423Sdim                                "_setjmp",
589249423Sdim                                llvm::AttributeSet::get(CGM.getLLVMContext(),
590249423Sdim                                              llvm::AttributeSet::FunctionIndex,
591249423Sdim                                                 llvm::Attribute::NonLazyBind));
592193326Sed  }
593198092Srdivacky
594193326Sedpublic:
595193326Sed  ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
596193326Sed  ~ObjCTypesHelper() {}
597193326Sed};
598193326Sed
599193326Sed/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's
600193326Sed/// modern abi
601193326Sedclass ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper {
602193326Sedpublic:
603198092Srdivacky
604193326Sed  // MethodListnfABITy - LLVM for struct _method_list_t
605224145Sdim  llvm::StructType *MethodListnfABITy;
606198092Srdivacky
607193326Sed  // MethodListnfABIPtrTy - LLVM for struct _method_list_t*
608224145Sdim  llvm::Type *MethodListnfABIPtrTy;
609198092Srdivacky
610193326Sed  // ProtocolnfABITy = LLVM for struct _protocol_t
611224145Sdim  llvm::StructType *ProtocolnfABITy;
612198092Srdivacky
613193326Sed  // ProtocolnfABIPtrTy = LLVM for struct _protocol_t*
614224145Sdim  llvm::Type *ProtocolnfABIPtrTy;
615193326Sed
616193326Sed  // ProtocolListnfABITy - LLVM for struct _objc_protocol_list
617224145Sdim  llvm::StructType *ProtocolListnfABITy;
618198092Srdivacky
619193326Sed  // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list*
620224145Sdim  llvm::Type *ProtocolListnfABIPtrTy;
621198092Srdivacky
622193326Sed  // ClassnfABITy - LLVM for struct _class_t
623224145Sdim  llvm::StructType *ClassnfABITy;
624198092Srdivacky
625193326Sed  // ClassnfABIPtrTy - LLVM for struct _class_t*
626224145Sdim  llvm::Type *ClassnfABIPtrTy;
627198092Srdivacky
628193326Sed  // IvarnfABITy - LLVM for struct _ivar_t
629224145Sdim  llvm::StructType *IvarnfABITy;
630198092Srdivacky
631193326Sed  // IvarListnfABITy - LLVM for struct _ivar_list_t
632224145Sdim  llvm::StructType *IvarListnfABITy;
633198092Srdivacky
634193326Sed  // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t*
635224145Sdim  llvm::Type *IvarListnfABIPtrTy;
636198092Srdivacky
637193326Sed  // ClassRonfABITy - LLVM for struct _class_ro_t
638224145Sdim  llvm::StructType *ClassRonfABITy;
639198092Srdivacky
640193326Sed  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
641224145Sdim  llvm::Type *ImpnfABITy;
642198092Srdivacky
643193326Sed  // CategorynfABITy - LLVM for struct _category_t
644224145Sdim  llvm::StructType *CategorynfABITy;
645198092Srdivacky
646193326Sed  // New types for nonfragile abi messaging.
647198092Srdivacky
648193326Sed  // MessageRefTy - LLVM for:
649193326Sed  // struct _message_ref_t {
650193326Sed  //   IMP messenger;
651193326Sed  //   SEL name;
652193326Sed  // };
653224145Sdim  llvm::StructType *MessageRefTy;
654193326Sed  // MessageRefCTy - clang type for struct _message_ref_t
655193326Sed  QualType MessageRefCTy;
656198092Srdivacky
657193326Sed  // MessageRefPtrTy - LLVM for struct _message_ref_t*
658224145Sdim  llvm::Type *MessageRefPtrTy;
659193326Sed  // MessageRefCPtrTy - clang type for struct _message_ref_t*
660193326Sed  QualType MessageRefCPtrTy;
661198092Srdivacky
662193326Sed  // MessengerTy - Type of the messenger (shown as IMP above)
663224145Sdim  llvm::FunctionType *MessengerTy;
664198092Srdivacky
665193326Sed  // SuperMessageRefTy - LLVM for:
666193326Sed  // struct _super_message_ref_t {
667193326Sed  //   SUPER_IMP messenger;
668193326Sed  //   SEL name;
669193326Sed  // };
670224145Sdim  llvm::StructType *SuperMessageRefTy;
671198092Srdivacky
672193326Sed  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
673224145Sdim  llvm::Type *SuperMessageRefPtrTy;
674193326Sed
675193326Sed  llvm::Constant *getMessageSendFixupFn() {
676193326Sed    // id objc_msgSend_fixup(id, struct message_ref_t*, ...)
677224145Sdim    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
678193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
679223017Sdim                                                             params, true),
680193326Sed                                     "objc_msgSend_fixup");
681193326Sed  }
682198092Srdivacky
683193326Sed  llvm::Constant *getMessageSendFpretFixupFn() {
684193326Sed    // id objc_msgSend_fpret_fixup(id, struct message_ref_t*, ...)
685224145Sdim    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
686193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
687223017Sdim                                                             params, true),
688193326Sed                                     "objc_msgSend_fpret_fixup");
689193326Sed  }
690198092Srdivacky
691193326Sed  llvm::Constant *getMessageSendStretFixupFn() {
692193326Sed    // id objc_msgSend_stret_fixup(id, struct message_ref_t*, ...)
693224145Sdim    llvm::Type *params[] = { ObjectPtrTy, MessageRefPtrTy };
694193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
695223017Sdim                                                             params, true),
696193326Sed                                     "objc_msgSend_stret_fixup");
697193326Sed  }
698198092Srdivacky
699193326Sed  llvm::Constant *getMessageSendSuper2FixupFn() {
700198092Srdivacky    // id objc_msgSendSuper2_fixup (struct objc_super *,
701193326Sed    //                              struct _super_message_ref_t*, ...)
702224145Sdim    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
703193326Sed    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
704223017Sdim                                                              params, true),
705193326Sed                                      "objc_msgSendSuper2_fixup");
706193326Sed  }
707198092Srdivacky
708193326Sed  llvm::Constant *getMessageSendSuper2StretFixupFn() {
709198092Srdivacky    // id objc_msgSendSuper2_stret_fixup(struct objc_super *,
710193326Sed    //                                   struct _super_message_ref_t*, ...)
711224145Sdim    llvm::Type *params[] = { SuperPtrTy, SuperMessageRefPtrTy };
712193326Sed    return  CGM.CreateRuntimeFunction(llvm::FunctionType::get(ObjectPtrTy,
713223017Sdim                                                              params, true),
714193326Sed                                      "objc_msgSendSuper2_stret_fixup");
715193326Sed  }
716198092Srdivacky
717193326Sed  llvm::Constant *getObjCEndCatchFn() {
718223017Sdim    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.VoidTy, false),
719193326Sed                                     "objc_end_catch");
720198092Srdivacky
721193326Sed  }
722198092Srdivacky
723193326Sed  llvm::Constant *getObjCBeginCatchFn() {
724224145Sdim    llvm::Type *params[] = { Int8PtrTy };
725193326Sed    return CGM.CreateRuntimeFunction(llvm::FunctionType::get(Int8PtrTy,
726223017Sdim                                                             params, false),
727193326Sed                                     "objc_begin_catch");
728193326Sed  }
729193326Sed
730224145Sdim  llvm::StructType *EHTypeTy;
731224145Sdim  llvm::Type *EHTypePtrTy;
732224145Sdim
733193326Sed  ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm);
734193326Sed  ~ObjCNonFragileABITypesHelper(){}
735193326Sed};
736198092Srdivacky
737193326Sedclass CGObjCCommonMac : public CodeGen::CGObjCRuntime {
738193326Sedpublic:
739193326Sed  // FIXME - accessibility
740193326Sed  class GC_IVAR {
741193326Sed  public:
742193326Sed    unsigned ivar_bytepos;
743193326Sed    unsigned ivar_size;
744193326Sed    GC_IVAR(unsigned bytepos = 0, unsigned size = 0)
745198092Srdivacky      : ivar_bytepos(bytepos), ivar_size(size) {}
746193326Sed
747193326Sed    // Allow sorting based on byte pos.
748193326Sed    bool operator<(const GC_IVAR &b) const {
749193326Sed      return ivar_bytepos < b.ivar_bytepos;
750193326Sed    }
751193326Sed  };
752198092Srdivacky
753193326Sed  class SKIP_SCAN {
754193326Sed  public:
755193326Sed    unsigned skip;
756193326Sed    unsigned scan;
757198092Srdivacky    SKIP_SCAN(unsigned _skip = 0, unsigned _scan = 0)
758193326Sed      : skip(_skip), scan(_scan) {}
759193326Sed  };
760198092Srdivacky
761243830Sdim  /// opcode for captured block variables layout 'instructions'.
762243830Sdim  /// In the following descriptions, 'I' is the value of the immediate field.
763243830Sdim  /// (field following the opcode).
764243830Sdim  ///
765243830Sdim  enum BLOCK_LAYOUT_OPCODE {
766243830Sdim    /// An operator which affects how the following layout should be
767243830Sdim    /// interpreted.
768243830Sdim    ///   I == 0: Halt interpretation and treat everything else as
769243830Sdim    ///           a non-pointer.  Note that this instruction is equal
770243830Sdim    ///           to '\0'.
771243830Sdim    ///   I != 0: Currently unused.
772243830Sdim    BLOCK_LAYOUT_OPERATOR            = 0,
773243830Sdim
774243830Sdim    /// The next I+1 bytes do not contain a value of object pointer type.
775243830Sdim    /// Note that this can leave the stream unaligned, meaning that
776243830Sdim    /// subsequent word-size instructions do not begin at a multiple of
777243830Sdim    /// the pointer size.
778243830Sdim    BLOCK_LAYOUT_NON_OBJECT_BYTES    = 1,
779243830Sdim
780243830Sdim    /// The next I+1 words do not contain a value of object pointer type.
781243830Sdim    /// This is simply an optimized version of BLOCK_LAYOUT_BYTES for
782243830Sdim    /// when the required skip quantity is a multiple of the pointer size.
783243830Sdim    BLOCK_LAYOUT_NON_OBJECT_WORDS    = 2,
784243830Sdim
785243830Sdim    /// The next I+1 words are __strong pointers to Objective-C
786243830Sdim    /// objects or blocks.
787243830Sdim    BLOCK_LAYOUT_STRONG              = 3,
788243830Sdim
789243830Sdim    /// The next I+1 words are pointers to __block variables.
790243830Sdim    BLOCK_LAYOUT_BYREF               = 4,
791243830Sdim
792243830Sdim    /// The next I+1 words are __weak pointers to Objective-C
793243830Sdim    /// objects or blocks.
794243830Sdim    BLOCK_LAYOUT_WEAK                = 5,
795243830Sdim
796243830Sdim    /// The next I+1 words are __unsafe_unretained pointers to
797243830Sdim    /// Objective-C objects or blocks.
798243830Sdim    BLOCK_LAYOUT_UNRETAINED          = 6
799243830Sdim
800243830Sdim    /// The next I+1 words are block or object pointers with some
801243830Sdim    /// as-yet-unspecified ownership semantics.  If we add more
802243830Sdim    /// flavors of ownership semantics, values will be taken from
803243830Sdim    /// this range.
804243830Sdim    ///
805243830Sdim    /// This is included so that older tools can at least continue
806243830Sdim    /// processing the layout past such things.
807243830Sdim    //BLOCK_LAYOUT_OWNERSHIP_UNKNOWN = 7..10,
808243830Sdim
809243830Sdim    /// All other opcodes are reserved.  Halt interpretation and
810243830Sdim    /// treat everything else as opaque.
811243830Sdim  };
812243830Sdim
813243830Sdim  class RUN_SKIP {
814243830Sdim  public:
815243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode;
816243830Sdim    CharUnits block_var_bytepos;
817243830Sdim    CharUnits block_var_size;
818243830Sdim    RUN_SKIP(enum BLOCK_LAYOUT_OPCODE Opcode = BLOCK_LAYOUT_OPERATOR,
819243830Sdim             CharUnits BytePos = CharUnits::Zero(),
820243830Sdim             CharUnits Size = CharUnits::Zero())
821243830Sdim    : opcode(Opcode), block_var_bytepos(BytePos),  block_var_size(Size) {}
822243830Sdim
823243830Sdim    // Allow sorting based on byte pos.
824243830Sdim    bool operator<(const RUN_SKIP &b) const {
825243830Sdim      return block_var_bytepos < b.block_var_bytepos;
826243830Sdim    }
827243830Sdim  };
828243830Sdim
829193326Sedprotected:
830198092Srdivacky  llvm::LLVMContext &VMContext;
831193326Sed  // FIXME! May not be needing this after all.
832193326Sed  unsigned ObjCABI;
833198092Srdivacky
834193326Sed  // gc ivar layout bitmap calculation helper caches.
835226633Sdim  SmallVector<GC_IVAR, 16> SkipIvars;
836226633Sdim  SmallVector<GC_IVAR, 16> IvarsInfo;
837243830Sdim
838243830Sdim  // arc/mrr layout of captured block literal variables.
839243830Sdim  SmallVector<RUN_SKIP, 16> RunSkipBlockVars;
840198092Srdivacky
841193326Sed  /// LazySymbols - Symbols to generate a lazy reference for. See
842193326Sed  /// DefinedSymbols and FinishModule().
843198092Srdivacky  llvm::SetVector<IdentifierInfo*> LazySymbols;
844198092Srdivacky
845193326Sed  /// DefinedSymbols - External symbols which are defined by this
846193326Sed  /// module. The symbols in this list and LazySymbols are used to add
847193326Sed  /// special linker symbols which ensure that Objective-C modules are
848193326Sed  /// linked properly.
849198092Srdivacky  llvm::SetVector<IdentifierInfo*> DefinedSymbols;
850198092Srdivacky
851193326Sed  /// ClassNames - uniqued class names.
852193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
853198092Srdivacky
854193326Sed  /// MethodVarNames - uniqued method variable names.
855193326Sed  llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
856198092Srdivacky
857210299Sed  /// DefinedCategoryNames - list of category names in form Class_Category.
858210299Sed  llvm::SetVector<std::string> DefinedCategoryNames;
859210299Sed
860193326Sed  /// MethodVarTypes - uniqued method type signatures. We have to use
861193326Sed  /// a StringMap here because have no other unique reference.
862193326Sed  llvm::StringMap<llvm::GlobalVariable*> MethodVarTypes;
863198092Srdivacky
864193326Sed  /// MethodDefinitions - map of methods which have been defined in
865193326Sed  /// this translation unit.
866193326Sed  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*> MethodDefinitions;
867198092Srdivacky
868193326Sed  /// PropertyNames - uniqued method variable names.
869193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> PropertyNames;
870198092Srdivacky
871193326Sed  /// ClassReferences - uniqued class references.
872193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassReferences;
873198092Srdivacky
874193326Sed  /// SelectorReferences - uniqued selector references.
875193326Sed  llvm::DenseMap<Selector, llvm::GlobalVariable*> SelectorReferences;
876198092Srdivacky
877193326Sed  /// Protocols - Protocols for which an objc_protocol structure has
878193326Sed  /// been emitted. Forward declarations are handled by creating an
879193326Sed  /// empty structure whose initializer is filled in when/if defined.
880193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> Protocols;
881198092Srdivacky
882193326Sed  /// DefinedProtocols - Protocols which have actually been
883193326Sed  /// defined. We should not need this, see FIXME in GenerateProtocol.
884193326Sed  llvm::DenseSet<IdentifierInfo*> DefinedProtocols;
885198092Srdivacky
886193326Sed  /// DefinedClasses - List of defined classes.
887249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
888193326Sed
889193326Sed  /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
890249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
891198092Srdivacky
892193326Sed  /// DefinedCategories - List of defined categories.
893249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedCategories;
894198092Srdivacky
895193326Sed  /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
896249423Sdim  SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyCategories;
897193326Sed
898193326Sed  /// GetNameForMethod - Return a name for the given method.
899193326Sed  /// \param[out] NameOut - The return value.
900193326Sed  void GetNameForMethod(const ObjCMethodDecl *OMD,
901193326Sed                        const ObjCContainerDecl *CD,
902226633Sdim                        SmallVectorImpl<char> &NameOut);
903198092Srdivacky
904193326Sed  /// GetMethodVarName - Return a unique constant for the given
905193326Sed  /// selector's name. The return value has type char *.
906193326Sed  llvm::Constant *GetMethodVarName(Selector Sel);
907193326Sed  llvm::Constant *GetMethodVarName(IdentifierInfo *Ident);
908198092Srdivacky
909193326Sed  /// GetMethodVarType - Return a unique constant for the given
910234353Sdim  /// method's type encoding string. The return value has type char *.
911198092Srdivacky
912193326Sed  // FIXME: This is a horrible name.
913234353Sdim  llvm::Constant *GetMethodVarType(const ObjCMethodDecl *D,
914234353Sdim                                   bool Extended = false);
915193326Sed  llvm::Constant *GetMethodVarType(const FieldDecl *D);
916198092Srdivacky
917193326Sed  /// GetPropertyName - Return a unique constant for the given
918193326Sed  /// name. The return value has type char *.
919193326Sed  llvm::Constant *GetPropertyName(IdentifierInfo *Ident);
920198092Srdivacky
921193326Sed  // FIXME: This can be dropped once string functions are unified.
922193326Sed  llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD,
923193326Sed                                        const Decl *Container);
924198092Srdivacky
925193326Sed  /// GetClassName - Return a unique constant for the given selector's
926193326Sed  /// name. The return value has type char *.
927193326Sed  llvm::Constant *GetClassName(IdentifierInfo *Ident);
928198092Srdivacky
929212904Sdim  llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
930212904Sdim
931193326Sed  /// BuildIvarLayout - Builds ivar layout bitmap for the class
932193326Sed  /// implementation for the __strong or __weak case.
933193326Sed  ///
934193326Sed  llvm::Constant *BuildIvarLayout(const ObjCImplementationDecl *OI,
935193326Sed                                  bool ForStrongLayout);
936212904Sdim
937212904Sdim  llvm::Constant *BuildIvarLayoutBitmap(std::string &BitMap);
938198092Srdivacky
939193326Sed  void BuildAggrIvarRecordLayout(const RecordType *RT,
940198092Srdivacky                                 unsigned int BytePos, bool ForStrongLayout,
941198092Srdivacky                                 bool &HasUnion);
942193326Sed  void BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
943193326Sed                           const llvm::StructLayout *Layout,
944193326Sed                           const RecordDecl *RD,
945234353Sdim                           ArrayRef<const FieldDecl*> RecFields,
946193326Sed                           unsigned int BytePos, bool ForStrongLayout,
947193326Sed                           bool &HasUnion);
948243830Sdim
949249423Sdim  Qualifiers::ObjCLifetime getBlockCaptureLifetime(QualType QT, bool ByrefLayout);
950243830Sdim
951243830Sdim  void UpdateRunSkipBlockVars(bool IsByref,
952243830Sdim                              Qualifiers::ObjCLifetime LifeTime,
953243830Sdim                              CharUnits FieldOffset,
954243830Sdim                              CharUnits FieldSize);
955243830Sdim
956243830Sdim  void BuildRCBlockVarRecordLayout(const RecordType *RT,
957249423Sdim                                   CharUnits BytePos, bool &HasUnion,
958249423Sdim                                   bool ByrefLayout=false);
959243830Sdim
960243830Sdim  void BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
961243830Sdim                           const RecordDecl *RD,
962243830Sdim                           ArrayRef<const FieldDecl*> RecFields,
963249423Sdim                           CharUnits BytePos, bool &HasUnion,
964249423Sdim                           bool ByrefLayout);
965243830Sdim
966243830Sdim  uint64_t InlineLayoutInstruction(SmallVectorImpl<unsigned char> &Layout);
967243830Sdim
968249423Sdim  llvm::Constant *getBitmapBlockLayout(bool ComputeByrefLayout);
969249423Sdim
970193326Sed
971193326Sed  /// GetIvarLayoutName - Returns a unique constant for the given
972193326Sed  /// ivar layout bitmap.
973193326Sed  llvm::Constant *GetIvarLayoutName(IdentifierInfo *Ident,
974193326Sed                                    const ObjCCommonTypesHelper &ObjCTypes);
975198092Srdivacky
976193326Sed  /// EmitPropertyList - Emit the given property list. The return
977193326Sed  /// value has type PropertyListPtrTy.
978226633Sdim  llvm::Constant *EmitPropertyList(Twine Name,
979198092Srdivacky                                   const Decl *Container,
980193326Sed                                   const ObjCContainerDecl *OCD,
981193326Sed                                   const ObjCCommonTypesHelper &ObjCTypes);
982198092Srdivacky
983234353Sdim  /// EmitProtocolMethodTypes - Generate the array of extended method type
984234353Sdim  /// strings. The return value has type Int8PtrPtrTy.
985234353Sdim  llvm::Constant *EmitProtocolMethodTypes(Twine Name,
986234353Sdim                                          ArrayRef<llvm::Constant*> MethodTypes,
987234353Sdim                                       const ObjCCommonTypesHelper &ObjCTypes);
988234353Sdim
989200583Srdivacky  /// PushProtocolProperties - Push protocol's property on the input stack.
990234353Sdim  void PushProtocolProperties(
991234353Sdim    llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
992249423Sdim    SmallVectorImpl<llvm::Constant*> &Properties,
993234353Sdim    const Decl *Container,
994234353Sdim    const ObjCProtocolDecl *PROTO,
995234353Sdim    const ObjCCommonTypesHelper &ObjCTypes);
996200583Srdivacky
997193326Sed  /// GetProtocolRef - Return a reference to the internal protocol
998193326Sed  /// description, creating an empty one if it has not been
999193326Sed  /// defined. The return value has type ProtocolPtrTy.
1000193326Sed  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
1001193326Sed
1002193326Sed  /// CreateMetadataVar - Create a global variable with internal
1003193326Sed  /// linkage for use by the Objective-C runtime.
1004193326Sed  ///
1005193326Sed  /// This is a convenience wrapper which not only creates the
1006193326Sed  /// variable, but also sets the section and alignment and adds the
1007198092Srdivacky  /// global to the "llvm.used" list.
1008193326Sed  ///
1009193326Sed  /// \param Name - The variable name.
1010193326Sed  /// \param Init - The variable initializer; this is also used to
1011193326Sed  /// define the type of the variable.
1012193326Sed  /// \param Section - The section the variable should go into, or 0.
1013193326Sed  /// \param Align - The alignment for the variable, or 0.
1014193326Sed  /// \param AddToUsed - Whether the variable should be added to
1015193326Sed  /// "llvm.used".
1016226633Sdim  llvm::GlobalVariable *CreateMetadataVar(Twine Name,
1017193326Sed                                          llvm::Constant *Init,
1018193326Sed                                          const char *Section,
1019193326Sed                                          unsigned Align,
1020193326Sed                                          bool AddToUsed);
1021193326Sed
1022223017Sdim  CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1023223017Sdim                                  ReturnValueSlot Return,
1024223017Sdim                                  QualType ResultType,
1025223017Sdim                                  llvm::Value *Sel,
1026223017Sdim                                  llvm::Value *Arg0,
1027223017Sdim                                  QualType Arg0Ty,
1028223017Sdim                                  bool IsSuper,
1029223017Sdim                                  const CallArgList &CallArgs,
1030223017Sdim                                  const ObjCMethodDecl *OMD,
1031223017Sdim                                  const ObjCCommonTypesHelper &ObjCTypes);
1032193326Sed
1033207619Srdivacky  /// EmitImageInfo - Emit the image info marker used to encode some module
1034207619Srdivacky  /// level information.
1035207619Srdivacky  void EmitImageInfo();
1036207619Srdivacky
1037198092Srdivackypublic:
1038198092Srdivacky  CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
1039234353Sdim    CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
1040195099Sed
1041202879Srdivacky  virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
1042234353Sdim
1043193326Sed  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
1044193326Sed                                         const ObjCContainerDecl *CD=0);
1045198092Srdivacky
1046193326Sed  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
1047198092Srdivacky
1048193326Sed  /// GetOrEmitProtocol - Get the protocol object for the given
1049193326Sed  /// declaration, emitting it if necessary. The return value has type
1050193326Sed  /// ProtocolPtrTy.
1051193326Sed  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
1052198092Srdivacky
1053193326Sed  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1054193326Sed  /// object for the given declaration, emitting it if needed. These
1055193326Sed  /// forward references will be filled in with empty bodies if no
1056193326Sed  /// definition is seen. The return value has type ProtocolPtrTy.
1057193326Sed  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
1058218893Sdim  virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
1059218893Sdim                                             const CGBlockInfo &blockInfo);
1060243830Sdim  virtual llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
1061243830Sdim                                             const CGBlockInfo &blockInfo);
1062212904Sdim
1063249423Sdim  virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
1064249423Sdim                                           QualType T);
1065193326Sed};
1066198092Srdivacky
1067193326Sedclass CGObjCMac : public CGObjCCommonMac {
1068193326Sedprivate:
1069193326Sed  ObjCTypesHelper ObjCTypes;
1070193326Sed
1071193326Sed  /// EmitModuleInfo - Another marker encoding module level
1072198092Srdivacky  /// information.
1073193326Sed  void EmitModuleInfo();
1074193326Sed
1075193326Sed  /// EmitModuleSymols - Emit module symbols, the list of defined
1076193326Sed  /// classes and categories. The result has type SymtabPtrTy.
1077193326Sed  llvm::Constant *EmitModuleSymbols();
1078193326Sed
1079193326Sed  /// FinishModule - Write out global data structures at the end of
1080193326Sed  /// processing a translation unit.
1081193326Sed  void FinishModule();
1082193326Sed
1083193326Sed  /// EmitClassExtension - Generate the class extension structure used
1084193326Sed  /// to store the weak ivar layout and properties. The return value
1085193326Sed  /// has type ClassExtensionPtrTy.
1086193326Sed  llvm::Constant *EmitClassExtension(const ObjCImplementationDecl *ID);
1087193326Sed
1088193326Sed  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1089193326Sed  /// for the given class.
1090249423Sdim  llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1091193326Sed                            const ObjCInterfaceDecl *ID);
1092199482Srdivacky
1093249423Sdim  llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1094224145Sdim                                  IdentifierInfo *II);
1095224145Sdim
1096249423Sdim  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
1097224145Sdim
1098199482Srdivacky  /// EmitSuperClassRef - Emits reference to class's main metadata class.
1099199482Srdivacky  llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
1100193326Sed
1101193326Sed  /// EmitIvarList - Emit the ivar list for the given
1102193326Sed  /// implementation. If ForClass is true the list of class ivars
1103193326Sed  /// (i.e. metaclass ivars) is emitted, otherwise the list of
1104193326Sed  /// interface ivars will be emitted. The return value has type
1105193326Sed  /// IvarListPtrTy.
1106193326Sed  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID,
1107193326Sed                               bool ForClass);
1108198092Srdivacky
1109193326Sed  /// EmitMetaClass - Emit a forward reference to the class structure
1110193326Sed  /// for the metaclass of the given interface. The return value has
1111193326Sed  /// type ClassPtrTy.
1112193326Sed  llvm::Constant *EmitMetaClassRef(const ObjCInterfaceDecl *ID);
1113193326Sed
1114193326Sed  /// EmitMetaClass - Emit a class structure for the metaclass of the
1115193326Sed  /// given implementation. The return value has type ClassPtrTy.
1116193326Sed  llvm::Constant *EmitMetaClass(const ObjCImplementationDecl *ID,
1117193326Sed                                llvm::Constant *Protocols,
1118234353Sdim                                ArrayRef<llvm::Constant*> Methods);
1119198092Srdivacky
1120193326Sed  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1121198092Srdivacky
1122193326Sed  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1123193326Sed
1124193326Sed  /// EmitMethodList - Emit the method list for the given
1125193326Sed  /// implementation. The return value has type MethodListPtrTy.
1126226633Sdim  llvm::Constant *EmitMethodList(Twine Name,
1127193326Sed                                 const char *Section,
1128234353Sdim                                 ArrayRef<llvm::Constant*> Methods);
1129193326Sed
1130193326Sed  /// EmitMethodDescList - Emit a method description list for a list of
1131198092Srdivacky  /// method declarations.
1132193326Sed  ///  - TypeName: The name for the type containing the methods.
1133193326Sed  ///  - IsProtocol: True iff these methods are for a protocol.
1134193326Sed  ///  - ClassMethds: True iff these are class methods.
1135193326Sed  ///  - Required: When true, only "required" methods are
1136193326Sed  ///    listed. Similarly, when false only "optional" methods are
1137193326Sed  ///    listed. For classes this should always be true.
1138193326Sed  ///  - begin, end: The method list to output.
1139193326Sed  ///
1140193326Sed  /// The return value has type MethodDescriptionListPtrTy.
1141226633Sdim  llvm::Constant *EmitMethodDescList(Twine Name,
1142193326Sed                                     const char *Section,
1143234353Sdim                                     ArrayRef<llvm::Constant*> Methods);
1144193326Sed
1145193326Sed  /// GetOrEmitProtocol - Get the protocol object for the given
1146193326Sed  /// declaration, emitting it if necessary. The return value has type
1147193326Sed  /// ProtocolPtrTy.
1148193326Sed  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1149193326Sed
1150193326Sed  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1151193326Sed  /// object for the given declaration, emitting it if needed. These
1152193326Sed  /// forward references will be filled in with empty bodies if no
1153193326Sed  /// definition is seen. The return value has type ProtocolPtrTy.
1154193326Sed  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1155193326Sed
1156193326Sed  /// EmitProtocolExtension - Generate the protocol extension
1157193326Sed  /// structure used to store optional instance and class methods, and
1158193326Sed  /// protocol properties. The return value has type
1159193326Sed  /// ProtocolExtensionPtrTy.
1160193326Sed  llvm::Constant *
1161193326Sed  EmitProtocolExtension(const ObjCProtocolDecl *PD,
1162234353Sdim                        ArrayRef<llvm::Constant*> OptInstanceMethods,
1163234353Sdim                        ArrayRef<llvm::Constant*> OptClassMethods,
1164234353Sdim                        ArrayRef<llvm::Constant*> MethodTypesExt);
1165193326Sed
1166193326Sed  /// EmitProtocolList - Generate the list of referenced
1167193326Sed  /// protocols. The return value has type ProtocolListPtrTy.
1168226633Sdim  llvm::Constant *EmitProtocolList(Twine Name,
1169193326Sed                                   ObjCProtocolDecl::protocol_iterator begin,
1170193326Sed                                   ObjCProtocolDecl::protocol_iterator end);
1171193326Sed
1172193326Sed  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1173193326Sed  /// for the given selector.
1174249423Sdim  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
1175210299Sed                            bool lval=false);
1176198092Srdivacky
1177198092Srdivackypublic:
1178193326Sed  CGObjCMac(CodeGen::CodeGenModule &cgm);
1179193326Sed
1180193326Sed  virtual llvm::Function *ModuleInitFunction();
1181198092Srdivacky
1182193326Sed  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1183208600Srdivacky                                              ReturnValueSlot Return,
1184193326Sed                                              QualType ResultType,
1185193326Sed                                              Selector Sel,
1186193326Sed                                              llvm::Value *Receiver,
1187193326Sed                                              const CallArgList &CallArgs,
1188207619Srdivacky                                              const ObjCInterfaceDecl *Class,
1189193326Sed                                              const ObjCMethodDecl *Method);
1190193326Sed
1191198092Srdivacky  virtual CodeGen::RValue
1192193326Sed  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1193208600Srdivacky                           ReturnValueSlot Return,
1194193326Sed                           QualType ResultType,
1195193326Sed                           Selector Sel,
1196193326Sed                           const ObjCInterfaceDecl *Class,
1197193326Sed                           bool isCategoryImpl,
1198193326Sed                           llvm::Value *Receiver,
1199193326Sed                           bool IsClassMessage,
1200198092Srdivacky                           const CallArgList &CallArgs,
1201198092Srdivacky                           const ObjCMethodDecl *Method);
1202198092Srdivacky
1203249423Sdim  virtual llvm::Value *GetClass(CodeGenFunction &CGF,
1204193326Sed                                const ObjCInterfaceDecl *ID);
1205193326Sed
1206249423Sdim  virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
1207210299Sed                                   bool lval = false);
1208193326Sed
1209193326Sed  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1210193326Sed  /// untyped one.
1211249423Sdim  virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
1212193326Sed                                   const ObjCMethodDecl *Method);
1213193326Sed
1214212904Sdim  virtual llvm::Constant *GetEHType(QualType T);
1215212904Sdim
1216193326Sed  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1217193326Sed
1218193326Sed  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1219193326Sed
1220234353Sdim  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
1221234353Sdim
1222249423Sdim  virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1223193326Sed                                           const ObjCProtocolDecl *PD);
1224198092Srdivacky
1225193326Sed  virtual llvm::Constant *GetPropertyGetFunction();
1226193326Sed  virtual llvm::Constant *GetPropertySetFunction();
1227234353Sdim  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1228234353Sdim                                                          bool copy);
1229218893Sdim  virtual llvm::Constant *GetGetStructFunction();
1230218893Sdim  virtual llvm::Constant *GetSetStructFunction();
1231249423Sdim  virtual llvm::Constant *GetCppAtomicObjectGetFunction();
1232249423Sdim  virtual llvm::Constant *GetCppAtomicObjectSetFunction();
1233193326Sed  virtual llvm::Constant *EnumerationMutationFunction();
1234198092Srdivacky
1235210299Sed  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1236210299Sed                           const ObjCAtTryStmt &S);
1237210299Sed  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1238210299Sed                                    const ObjCAtSynchronizedStmt &S);
1239210299Sed  void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
1240193326Sed  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1241249423Sdim                             const ObjCAtThrowStmt &S,
1242249423Sdim                             bool ClearInsertionPoint=true);
1243193326Sed  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1244198092Srdivacky                                         llvm::Value *AddrWeakObj);
1245193326Sed  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1246198092Srdivacky                                  llvm::Value *src, llvm::Value *dst);
1247193326Sed  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1248212904Sdim                                    llvm::Value *src, llvm::Value *dest,
1249212904Sdim                                    bool threadlocal = false);
1250193326Sed  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1251198092Srdivacky                                  llvm::Value *src, llvm::Value *dest,
1252198092Srdivacky                                  llvm::Value *ivarOffset);
1253193326Sed  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1254193326Sed                                        llvm::Value *src, llvm::Value *dest);
1255198092Srdivacky  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1256198092Srdivacky                                        llvm::Value *dest, llvm::Value *src,
1257210299Sed                                        llvm::Value *size);
1258198092Srdivacky
1259193326Sed  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1260193326Sed                                      QualType ObjectTy,
1261193326Sed                                      llvm::Value *BaseValue,
1262193326Sed                                      const ObjCIvarDecl *Ivar,
1263193326Sed                                      unsigned CVRQualifiers);
1264193326Sed  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1265193326Sed                                      const ObjCInterfaceDecl *Interface,
1266193326Sed                                      const ObjCIvarDecl *Ivar);
1267223017Sdim
1268223017Sdim  /// GetClassGlobal - Return the global variable for the Objective-C
1269223017Sdim  /// class of the given name.
1270223017Sdim  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
1271226633Sdim    llvm_unreachable("CGObjCMac::GetClassGlobal");
1272223017Sdim  }
1273193326Sed};
1274198092Srdivacky
1275193326Sedclass CGObjCNonFragileABIMac : public CGObjCCommonMac {
1276193326Sedprivate:
1277193326Sed  ObjCNonFragileABITypesHelper ObjCTypes;
1278193326Sed  llvm::GlobalVariable* ObjCEmptyCacheVar;
1279193326Sed  llvm::GlobalVariable* ObjCEmptyVtableVar;
1280198092Srdivacky
1281193326Sed  /// SuperClassReferences - uniqued super class references.
1282193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> SuperClassReferences;
1283198092Srdivacky
1284193326Sed  /// MetaClassReferences - uniqued meta class references.
1285193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> MetaClassReferences;
1286193326Sed
1287193326Sed  /// EHTypeReferences - uniqued class ehtype references.
1288193326Sed  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> EHTypeReferences;
1289198092Srdivacky
1290223017Sdim  /// VTableDispatchMethods - List of methods for which we generate
1291223017Sdim  /// vtable-based message dispatch.
1292223017Sdim  llvm::DenseSet<Selector> VTableDispatchMethods;
1293198092Srdivacky
1294199482Srdivacky  /// DefinedMetaClasses - List of defined meta-classes.
1295199482Srdivacky  std::vector<llvm::GlobalValue*> DefinedMetaClasses;
1296199482Srdivacky
1297223017Sdim  /// isVTableDispatchedSelector - Returns true if SEL is a
1298223017Sdim  /// vtable-based selector.
1299223017Sdim  bool isVTableDispatchedSelector(Selector Sel);
1300198092Srdivacky
1301193326Sed  /// FinishNonFragileABIModule - Write out global data structures at the end of
1302193326Sed  /// processing a translation unit.
1303193326Sed  void FinishNonFragileABIModule();
1304193326Sed
1305193326Sed  /// AddModuleClassList - Add the given list of class pointers to the
1306193326Sed  /// module with the provided symbol and section names.
1307234353Sdim  void AddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
1308193326Sed                          const char *SymbolName,
1309193326Sed                          const char *SectionName);
1310193326Sed
1311198092Srdivacky  llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags,
1312198092Srdivacky                                              unsigned InstanceStart,
1313198092Srdivacky                                              unsigned InstanceSize,
1314198092Srdivacky                                              const ObjCImplementationDecl *ID);
1315193326Sed  llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
1316198092Srdivacky                                            llvm::Constant *IsAGV,
1317193326Sed                                            llvm::Constant *SuperClassGV,
1318193326Sed                                            llvm::Constant *ClassRoGV,
1319193326Sed                                            bool HiddenVisibility);
1320198092Srdivacky
1321193326Sed  llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
1322198092Srdivacky
1323193326Sed  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
1324198092Srdivacky
1325193326Sed  /// EmitMethodList - Emit the method list for the given
1326193326Sed  /// implementation. The return value has type MethodListnfABITy.
1327226633Sdim  llvm::Constant *EmitMethodList(Twine Name,
1328193326Sed                                 const char *Section,
1329234353Sdim                                 ArrayRef<llvm::Constant*> Methods);
1330193326Sed  /// EmitIvarList - Emit the ivar list for the given
1331193326Sed  /// implementation. If ForClass is true the list of class ivars
1332193326Sed  /// (i.e. metaclass ivars) is emitted, otherwise the list of
1333193326Sed  /// interface ivars will be emitted. The return value has type
1334193326Sed  /// IvarListnfABIPtrTy.
1335193326Sed  llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID);
1336198092Srdivacky
1337193326Sed  llvm::Constant *EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
1338193326Sed                                    const ObjCIvarDecl *Ivar,
1339193326Sed                                    unsigned long int offset);
1340198092Srdivacky
1341193326Sed  /// GetOrEmitProtocol - Get the protocol object for the given
1342193326Sed  /// declaration, emitting it if necessary. The return value has type
1343193326Sed  /// ProtocolPtrTy.
1344193326Sed  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
1345198092Srdivacky
1346193326Sed  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
1347193326Sed  /// object for the given declaration, emitting it if needed. These
1348193326Sed  /// forward references will be filled in with empty bodies if no
1349193326Sed  /// definition is seen. The return value has type ProtocolPtrTy.
1350193326Sed  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
1351198092Srdivacky
1352193326Sed  /// EmitProtocolList - Generate the list of referenced
1353193326Sed  /// protocols. The return value has type ProtocolListPtrTy.
1354226633Sdim  llvm::Constant *EmitProtocolList(Twine Name,
1355193326Sed                                   ObjCProtocolDecl::protocol_iterator begin,
1356193326Sed                                   ObjCProtocolDecl::protocol_iterator end);
1357198092Srdivacky
1358223017Sdim  CodeGen::RValue EmitVTableMessageSend(CodeGen::CodeGenFunction &CGF,
1359223017Sdim                                        ReturnValueSlot Return,
1360223017Sdim                                        QualType ResultType,
1361223017Sdim                                        Selector Sel,
1362223017Sdim                                        llvm::Value *Receiver,
1363223017Sdim                                        QualType Arg0Ty,
1364223017Sdim                                        bool IsSuper,
1365223017Sdim                                        const CallArgList &CallArgs,
1366223017Sdim                                        const ObjCMethodDecl *Method);
1367223017Sdim
1368193326Sed  /// GetClassGlobal - Return the global variable for the Objective-C
1369193326Sed  /// class of the given name.
1370193326Sed  llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
1371223017Sdim
1372193326Sed  /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1373193326Sed  /// for the given class reference.
1374249423Sdim  llvm::Value *EmitClassRef(CodeGenFunction &CGF,
1375193326Sed                            const ObjCInterfaceDecl *ID);
1376224145Sdim
1377249423Sdim  llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
1378224145Sdim                                  IdentifierInfo *II);
1379224145Sdim
1380249423Sdim  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
1381198092Srdivacky
1382193326Sed  /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
1383193326Sed  /// for the given super class reference.
1384249423Sdim  llvm::Value *EmitSuperClassRef(CodeGenFunction &CGF,
1385198092Srdivacky                                 const ObjCInterfaceDecl *ID);
1386198092Srdivacky
1387193326Sed  /// EmitMetaClassRef - Return a Value * of the address of _class_t
1388193326Sed  /// meta-data
1389249423Sdim  llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
1390193326Sed                                const ObjCInterfaceDecl *ID);
1391193326Sed
1392193326Sed  /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
1393193326Sed  /// the given ivar.
1394193326Sed  ///
1395193326Sed  llvm::GlobalVariable * ObjCIvarOffsetVariable(
1396198092Srdivacky    const ObjCInterfaceDecl *ID,
1397198092Srdivacky    const ObjCIvarDecl *Ivar);
1398198092Srdivacky
1399193326Sed  /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy,
1400193326Sed  /// for the given selector.
1401249423Sdim  llvm::Value *EmitSelector(CodeGenFunction &CGF, Selector Sel,
1402210299Sed                            bool lval=false);
1403193326Sed
1404193326Sed  /// GetInterfaceEHType - Get the cached ehtype for the given Objective-C
1405193326Sed  /// interface. The return value has type EHTypePtrTy.
1406212904Sdim  llvm::Constant *GetInterfaceEHType(const ObjCInterfaceDecl *ID,
1407193326Sed                                  bool ForDefinition);
1408193326Sed
1409198092Srdivacky  const char *getMetaclassSymbolPrefix() const {
1410193326Sed    return "OBJC_METACLASS_$_";
1411193326Sed  }
1412198092Srdivacky
1413193326Sed  const char *getClassSymbolPrefix() const {
1414193326Sed    return "OBJC_CLASS_$_";
1415193326Sed  }
1416193326Sed
1417193326Sed  void GetClassSizeInfo(const ObjCImplementationDecl *OID,
1418193326Sed                        uint32_t &InstanceStart,
1419193326Sed                        uint32_t &InstanceSize);
1420198092Srdivacky
1421193326Sed  // Shamelessly stolen from Analysis/CFRefCount.cpp
1422193326Sed  Selector GetNullarySelector(const char* name) const {
1423193326Sed    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1424193326Sed    return CGM.getContext().Selectors.getSelector(0, &II);
1425193326Sed  }
1426198092Srdivacky
1427193326Sed  Selector GetUnarySelector(const char* name) const {
1428193326Sed    IdentifierInfo* II = &CGM.getContext().Idents.get(name);
1429193326Sed    return CGM.getContext().Selectors.getSelector(1, &II);
1430193326Sed  }
1431193326Sed
1432193326Sed  /// ImplementationIsNonLazy - Check whether the given category or
1433193326Sed  /// class implementation is "non-lazy".
1434193326Sed  bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
1435193326Sed
1436249423Sdim  bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
1437249423Sdim                                   const ObjCInterfaceDecl *ID,
1438249423Sdim                                   const ObjCIvarDecl *IV) {
1439249423Sdim    // Annotate the load as an invariant load iff the object type is the type,
1440249423Sdim    // or a derived type, of the class containing the ivar within an ObjC
1441249423Sdim    // method.  This check is needed because the ivar offset is a lazily
1442249423Sdim    // initialised value that may depend on objc_msgSend to perform a fixup on
1443249423Sdim    // the first message dispatch.
1444249423Sdim    //
1445249423Sdim    // An additional opportunity to mark the load as invariant arises when the
1446249423Sdim    // base of the ivar access is a parameter to an Objective C method.
1447249423Sdim    // However, because the parameters are not available in the current
1448249423Sdim    // interface, we cannot perform this check.
1449249423Sdim    if (CGF.CurFuncDecl && isa<ObjCMethodDecl>(CGF.CurFuncDecl))
1450249423Sdim      if (IV->getContainingInterface()->isSuperClassOf(ID))
1451249423Sdim        return true;
1452249423Sdim    return false;
1453249423Sdim  }
1454249423Sdim
1455193326Sedpublic:
1456193326Sed  CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
1457193326Sed  // FIXME. All stubs for now!
1458193326Sed  virtual llvm::Function *ModuleInitFunction();
1459198092Srdivacky
1460193326Sed  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1461208600Srdivacky                                              ReturnValueSlot Return,
1462193326Sed                                              QualType ResultType,
1463193326Sed                                              Selector Sel,
1464193326Sed                                              llvm::Value *Receiver,
1465193326Sed                                              const CallArgList &CallArgs,
1466207619Srdivacky                                              const ObjCInterfaceDecl *Class,
1467193326Sed                                              const ObjCMethodDecl *Method);
1468198092Srdivacky
1469198092Srdivacky  virtual CodeGen::RValue
1470193326Sed  GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1471208600Srdivacky                           ReturnValueSlot Return,
1472193326Sed                           QualType ResultType,
1473193326Sed                           Selector Sel,
1474193326Sed                           const ObjCInterfaceDecl *Class,
1475193326Sed                           bool isCategoryImpl,
1476193326Sed                           llvm::Value *Receiver,
1477193326Sed                           bool IsClassMessage,
1478198092Srdivacky                           const CallArgList &CallArgs,
1479198092Srdivacky                           const ObjCMethodDecl *Method);
1480198092Srdivacky
1481249423Sdim  virtual llvm::Value *GetClass(CodeGenFunction &CGF,
1482193326Sed                                const ObjCInterfaceDecl *ID);
1483198092Srdivacky
1484249423Sdim  virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
1485210299Sed                                   bool lvalue = false)
1486249423Sdim    { return EmitSelector(CGF, Sel, lvalue); }
1487193326Sed
1488193326Sed  /// The NeXT/Apple runtimes do not support typed selectors; just emit an
1489193326Sed  /// untyped one.
1490249423Sdim  virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
1491193326Sed                                   const ObjCMethodDecl *Method)
1492249423Sdim    { return EmitSelector(CGF, Method->getSelector()); }
1493198092Srdivacky
1494193326Sed  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
1495198092Srdivacky
1496193326Sed  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
1497234353Sdim
1498234353Sdim  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
1499234353Sdim
1500249423Sdim  virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
1501193326Sed                                           const ObjCProtocolDecl *PD);
1502198092Srdivacky
1503212904Sdim  virtual llvm::Constant *GetEHType(QualType T);
1504212904Sdim
1505198092Srdivacky  virtual llvm::Constant *GetPropertyGetFunction() {
1506193326Sed    return ObjCTypes.getGetPropertyFn();
1507193326Sed  }
1508198092Srdivacky  virtual llvm::Constant *GetPropertySetFunction() {
1509198092Srdivacky    return ObjCTypes.getSetPropertyFn();
1510193326Sed  }
1511207619Srdivacky
1512234353Sdim  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
1513234353Sdim                                                          bool copy) {
1514234353Sdim    return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
1515234353Sdim  }
1516234353Sdim
1517218893Sdim  virtual llvm::Constant *GetSetStructFunction() {
1518207619Srdivacky    return ObjCTypes.getCopyStructFn();
1519207619Srdivacky  }
1520218893Sdim  virtual llvm::Constant *GetGetStructFunction() {
1521218893Sdim    return ObjCTypes.getCopyStructFn();
1522218893Sdim  }
1523249423Sdim  virtual llvm::Constant *GetCppAtomicObjectSetFunction() {
1524234353Sdim    return ObjCTypes.getCppAtomicObjectFunction();
1525234353Sdim  }
1526249423Sdim  virtual llvm::Constant *GetCppAtomicObjectGetFunction() {
1527249423Sdim    return ObjCTypes.getCppAtomicObjectFunction();
1528249423Sdim  }
1529207619Srdivacky
1530193326Sed  virtual llvm::Constant *EnumerationMutationFunction() {
1531193326Sed    return ObjCTypes.getEnumerationMutationFn();
1532193326Sed  }
1533198092Srdivacky
1534210299Sed  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
1535210299Sed                           const ObjCAtTryStmt &S);
1536210299Sed  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
1537210299Sed                                    const ObjCAtSynchronizedStmt &S);
1538193326Sed  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
1539249423Sdim                             const ObjCAtThrowStmt &S,
1540249423Sdim                             bool ClearInsertionPoint=true);
1541193326Sed  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
1542193326Sed                                         llvm::Value *AddrWeakObj);
1543193326Sed  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
1544193326Sed                                  llvm::Value *src, llvm::Value *dst);
1545193326Sed  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
1546212904Sdim                                    llvm::Value *src, llvm::Value *dest,
1547212904Sdim                                    bool threadlocal = false);
1548193326Sed  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
1549198092Srdivacky                                  llvm::Value *src, llvm::Value *dest,
1550198092Srdivacky                                  llvm::Value *ivarOffset);
1551193326Sed  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
1552193326Sed                                        llvm::Value *src, llvm::Value *dest);
1553198092Srdivacky  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
1554198092Srdivacky                                        llvm::Value *dest, llvm::Value *src,
1555210299Sed                                        llvm::Value *size);
1556193326Sed  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
1557193326Sed                                      QualType ObjectTy,
1558193326Sed                                      llvm::Value *BaseValue,
1559193326Sed                                      const ObjCIvarDecl *Ivar,
1560193326Sed                                      unsigned CVRQualifiers);
1561193326Sed  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
1562193326Sed                                      const ObjCInterfaceDecl *Interface,
1563193326Sed                                      const ObjCIvarDecl *Ivar);
1564193326Sed};
1565198092Srdivacky
1566223017Sdim/// A helper class for performing the null-initialization of a return
1567223017Sdim/// value.
1568223017Sdimstruct NullReturnState {
1569223017Sdim  llvm::BasicBlock *NullBB;
1570249423Sdim  NullReturnState() : NullBB(0) {}
1571223017Sdim
1572249423Sdim  /// Perform a null-check of the given receiver.
1573223017Sdim  void init(CodeGenFunction &CGF, llvm::Value *receiver) {
1574249423Sdim    // Make blocks for the null-receiver and call edges.
1575249423Sdim    NullBB = CGF.createBasicBlock("msgSend.null-receiver");
1576249423Sdim    llvm::BasicBlock *callBB = CGF.createBasicBlock("msgSend.call");
1577223017Sdim
1578223017Sdim    // Check for a null receiver and, if there is one, jump to the
1579249423Sdim    // null-receiver block.  There's no point in trying to avoid it:
1580249423Sdim    // we're always going to put *something* there, because otherwise
1581249423Sdim    // we shouldn't have done this null-check in the first place.
1582223017Sdim    llvm::Value *isNull = CGF.Builder.CreateIsNull(receiver);
1583223017Sdim    CGF.Builder.CreateCondBr(isNull, NullBB, callBB);
1584223017Sdim
1585223017Sdim    // Otherwise, start performing the call.
1586223017Sdim    CGF.EmitBlock(callBB);
1587223017Sdim  }
1588223017Sdim
1589249423Sdim  /// Complete the null-return operation.  It is valid to call this
1590249423Sdim  /// regardless of whether 'init' has been called.
1591234353Sdim  RValue complete(CodeGenFunction &CGF, RValue result, QualType resultType,
1592234353Sdim                  const CallArgList &CallArgs,
1593234353Sdim                  const ObjCMethodDecl *Method) {
1594249423Sdim    // If we never had to do a null-check, just use the raw result.
1595223017Sdim    if (!NullBB) return result;
1596249423Sdim
1597249423Sdim    // The continuation block.  This will be left null if we don't have an
1598249423Sdim    // IP, which can happen if the method we're calling is marked noreturn.
1599249423Sdim    llvm::BasicBlock *contBB = 0;
1600234353Sdim
1601249423Sdim    // Finish the call path.
1602249423Sdim    llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
1603249423Sdim    if (callBB) {
1604249423Sdim      contBB = CGF.createBasicBlock("msgSend.cont");
1605249423Sdim      CGF.Builder.CreateBr(contBB);
1606234353Sdim    }
1607223017Sdim
1608249423Sdim    // Okay, start emitting the null-receiver block.
1609223017Sdim    CGF.EmitBlock(NullBB);
1610234353Sdim
1611249423Sdim    // Release any consumed arguments we've got.
1612234353Sdim    if (Method) {
1613234353Sdim      CallArgList::const_iterator I = CallArgs.begin();
1614234353Sdim      for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1615234353Sdim           e = Method->param_end(); i != e; ++i, ++I) {
1616234353Sdim        const ParmVarDecl *ParamDecl = (*i);
1617234353Sdim        if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1618234353Sdim          RValue RV = I->RV;
1619234353Sdim          assert(RV.isScalar() &&
1620234353Sdim                 "NullReturnState::complete - arg not on object");
1621249423Sdim          CGF.EmitARCRelease(RV.getScalarVal(), ARCImpreciseLifetime);
1622234353Sdim        }
1623234353Sdim      }
1624234353Sdim    }
1625249423Sdim
1626249423Sdim    // The phi code below assumes that we haven't needed any control flow yet.
1627249423Sdim    assert(CGF.Builder.GetInsertBlock() == NullBB);
1628249423Sdim
1629249423Sdim    // If we've got a void return, just jump to the continuation block.
1630249423Sdim    if (result.isScalar() && resultType->isVoidType()) {
1631249423Sdim      // No jumps required if the message-send was noreturn.
1632249423Sdim      if (contBB) CGF.EmitBlock(contBB);
1633249423Sdim      return result;
1634249423Sdim    }
1635249423Sdim
1636249423Sdim    // If we've got a scalar return, build a phi.
1637234353Sdim    if (result.isScalar()) {
1638249423Sdim      // Derive the null-initialization value.
1639249423Sdim      llvm::Constant *null = CGF.CGM.EmitNullConstant(resultType);
1640249423Sdim
1641249423Sdim      // If no join is necessary, just flow out.
1642249423Sdim      if (!contBB) return RValue::get(null);
1643249423Sdim
1644249423Sdim      // Otherwise, build a phi.
1645234353Sdim      CGF.EmitBlock(contBB);
1646249423Sdim      llvm::PHINode *phi = CGF.Builder.CreatePHI(null->getType(), 2);
1647249423Sdim      phi->addIncoming(result.getScalarVal(), callBB);
1648249423Sdim      phi->addIncoming(null, NullBB);
1649249423Sdim      return RValue::get(phi);
1650234353Sdim    }
1651249423Sdim
1652249423Sdim    // If we've got an aggregate return, null the buffer out.
1653249423Sdim    // FIXME: maybe we should be doing things differently for all the
1654249423Sdim    // cases where the ABI has us returning (1) non-agg values in
1655249423Sdim    // memory or (2) agg values in registers.
1656249423Sdim    if (result.isAggregate()) {
1657234353Sdim      assert(result.isAggregate() && "null init of non-aggregate result?");
1658234353Sdim      CGF.EmitNullInitialization(result.getAggregateAddr(), resultType);
1659249423Sdim      if (contBB) CGF.EmitBlock(contBB);
1660234353Sdim      return result;
1661234353Sdim    }
1662223017Sdim
1663249423Sdim    // Complex types.
1664223017Sdim    CGF.EmitBlock(contBB);
1665249423Sdim    CodeGenFunction::ComplexPairTy callResult = result.getComplexVal();
1666249423Sdim
1667249423Sdim    // Find the scalar type and its zero value.
1668249423Sdim    llvm::Type *scalarTy = callResult.first->getType();
1669249423Sdim    llvm::Constant *scalarZero = llvm::Constant::getNullValue(scalarTy);
1670249423Sdim
1671249423Sdim    // Build phis for both coordinates.
1672249423Sdim    llvm::PHINode *real = CGF.Builder.CreatePHI(scalarTy, 2);
1673249423Sdim    real->addIncoming(callResult.first, callBB);
1674249423Sdim    real->addIncoming(scalarZero, NullBB);
1675249423Sdim    llvm::PHINode *imag = CGF.Builder.CreatePHI(scalarTy, 2);
1676249423Sdim    imag->addIncoming(callResult.second, callBB);
1677249423Sdim    imag->addIncoming(scalarZero, NullBB);
1678249423Sdim    return RValue::getComplex(real, imag);
1679223017Sdim  }
1680223017Sdim};
1681223017Sdim
1682193326Sed} // end anonymous namespace
1683193326Sed
1684193326Sed/* *** Helper Functions *** */
1685193326Sed
1686193326Sed/// getConstantGEP() - Help routine to construct simple GEPs.
1687198092Srdivackystatic llvm::Constant *getConstantGEP(llvm::LLVMContext &VMContext,
1688198092Srdivacky                                      llvm::Constant *C,
1689193326Sed                                      unsigned idx0,
1690193326Sed                                      unsigned idx1) {
1691193326Sed  llvm::Value *Idxs[] = {
1692198092Srdivacky    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx0),
1693198092Srdivacky    llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), idx1)
1694193326Sed  };
1695226633Sdim  return llvm::ConstantExpr::getGetElementPtr(C, Idxs);
1696193326Sed}
1697193326Sed
1698193326Sed/// hasObjCExceptionAttribute - Return true if this class or any super
1699193326Sed/// class has the __objc_exception__ attribute.
1700198092Srdivackystatic bool hasObjCExceptionAttribute(ASTContext &Context,
1701194613Sed                                      const ObjCInterfaceDecl *OID) {
1702195341Sed  if (OID->hasAttr<ObjCExceptionAttr>())
1703193326Sed    return true;
1704193326Sed  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
1705194613Sed    return hasObjCExceptionAttribute(Context, Super);
1706193326Sed  return false;
1707193326Sed}
1708193326Sed
1709193326Sed/* *** CGObjCMac Public Interface *** */
1710198092Srdivacky
1711193326SedCGObjCMac::CGObjCMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm),
1712198092Srdivacky                                                    ObjCTypes(cgm) {
1713193326Sed  ObjCABI = 1;
1714198092Srdivacky  EmitImageInfo();
1715193326Sed}
1716193326Sed
1717193326Sed/// GetClass - Return a reference to the class for the given interface
1718193326Sed/// decl.
1719249423Sdimllvm::Value *CGObjCMac::GetClass(CodeGenFunction &CGF,
1720193326Sed                                 const ObjCInterfaceDecl *ID) {
1721249423Sdim  return EmitClassRef(CGF, ID);
1722193326Sed}
1723193326Sed
1724193326Sed/// GetSelector - Return the pointer to the unique'd string for this selector.
1725249423Sdimllvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, Selector Sel,
1726210299Sed                                    bool lval) {
1727249423Sdim  return EmitSelector(CGF, Sel, lval);
1728193326Sed}
1729249423Sdimllvm::Value *CGObjCMac::GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
1730198092Srdivacky                                    *Method) {
1731249423Sdim  return EmitSelector(CGF, Method->getSelector());
1732193326Sed}
1733193326Sed
1734212904Sdimllvm::Constant *CGObjCMac::GetEHType(QualType T) {
1735224145Sdim  if (T->isObjCIdType() ||
1736224145Sdim      T->isObjCQualifiedIdType()) {
1737224145Sdim    return CGM.GetAddrOfRTTIDescriptor(
1738226633Sdim              CGM.getContext().getObjCIdRedefinitionType(), /*ForEH=*/true);
1739224145Sdim  }
1740224145Sdim  if (T->isObjCClassType() ||
1741224145Sdim      T->isObjCQualifiedClassType()) {
1742224145Sdim    return CGM.GetAddrOfRTTIDescriptor(
1743226633Sdim             CGM.getContext().getObjCClassRedefinitionType(), /*ForEH=*/true);
1744224145Sdim  }
1745224145Sdim  if (T->isObjCObjectPointerType())
1746224145Sdim    return CGM.GetAddrOfRTTIDescriptor(T,  /*ForEH=*/true);
1747224145Sdim
1748212904Sdim  llvm_unreachable("asking for catch type for ObjC type in fragile runtime");
1749212904Sdim}
1750212904Sdim
1751193326Sed/// Generate a constant CFString object.
1752198092Srdivacky/*
1753198092Srdivacky  struct __builtin_CFString {
1754198092Srdivacky  const int *isa; // point to __CFConstantStringClassReference
1755198092Srdivacky  int flags;
1756198092Srdivacky  const char *str;
1757198092Srdivacky  long length;
1758198092Srdivacky  };
1759193326Sed*/
1760193326Sed
1761207619Srdivacky/// or Generate a constant NSString object.
1762207619Srdivacky/*
1763207619Srdivacky   struct __builtin_NSString {
1764207619Srdivacky     const int *isa; // point to __NSConstantStringClassReference
1765207619Srdivacky     const char *str;
1766207619Srdivacky     unsigned int length;
1767207619Srdivacky   };
1768207619Srdivacky*/
1769207619Srdivacky
1770193326Sedllvm::Constant *CGObjCCommonMac::GenerateConstantString(
1771202879Srdivacky  const StringLiteral *SL) {
1772234353Sdim  return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
1773207619Srdivacky          CGM.GetAddrOfConstantCFString(SL) :
1774218893Sdim          CGM.GetAddrOfConstantString(SL));
1775193326Sed}
1776193326Sed
1777234353Sdimenum {
1778234353Sdim  kCFTaggedObjectID_Integer = (1 << 1) + 1
1779234353Sdim};
1780234353Sdim
1781193326Sed/// Generates a message send where the super is the receiver.  This is
1782193326Sed/// a message send to self with special delivery semantics indicating
1783193326Sed/// which class's method should be called.
1784193326SedCodeGen::RValue
1785193326SedCGObjCMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
1786208600Srdivacky                                    ReturnValueSlot Return,
1787193326Sed                                    QualType ResultType,
1788193326Sed                                    Selector Sel,
1789193326Sed                                    const ObjCInterfaceDecl *Class,
1790193326Sed                                    bool isCategoryImpl,
1791193326Sed                                    llvm::Value *Receiver,
1792193326Sed                                    bool IsClassMessage,
1793198092Srdivacky                                    const CodeGen::CallArgList &CallArgs,
1794198092Srdivacky                                    const ObjCMethodDecl *Method) {
1795193326Sed  // Create and init a super structure; this is a (receiver, class)
1796193326Sed  // pair we will pass to objc_msgSendSuper.
1797198092Srdivacky  llvm::Value *ObjCSuper =
1798221345Sdim    CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
1799198092Srdivacky  llvm::Value *ReceiverAsObject =
1800193326Sed    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
1801198092Srdivacky  CGF.Builder.CreateStore(ReceiverAsObject,
1802193326Sed                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
1803193326Sed
1804193326Sed  // If this is a class message the metaclass is passed as the target.
1805193326Sed  llvm::Value *Target;
1806193326Sed  if (IsClassMessage) {
1807193326Sed    if (isCategoryImpl) {
1808193326Sed      // Message sent to 'super' in a class method defined in a category
1809193326Sed      // implementation requires an odd treatment.
1810193326Sed      // If we are in a class method, we must retrieve the
1811193326Sed      // _metaclass_ for the current class, pointed at by
1812193326Sed      // the class's "isa" pointer.  The following assumes that
1813193326Sed      // isa" is the first ivar in a class (which it must be).
1814249423Sdim      Target = EmitClassRef(CGF, Class->getSuperClass());
1815193326Sed      Target = CGF.Builder.CreateStructGEP(Target, 0);
1816193326Sed      Target = CGF.Builder.CreateLoad(Target);
1817198092Srdivacky    } else {
1818193326Sed      llvm::Value *MetaClassPtr = EmitMetaClassRef(Class);
1819193326Sed      llvm::Value *SuperPtr = CGF.Builder.CreateStructGEP(MetaClassPtr, 1);
1820193326Sed      llvm::Value *Super = CGF.Builder.CreateLoad(SuperPtr);
1821193326Sed      Target = Super;
1822198092Srdivacky    }
1823199482Srdivacky  }
1824199482Srdivacky  else if (isCategoryImpl)
1825249423Sdim    Target = EmitClassRef(CGF, Class->getSuperClass());
1826199482Srdivacky  else {
1827199482Srdivacky    llvm::Value *ClassPtr = EmitSuperClassRef(Class);
1828199482Srdivacky    ClassPtr = CGF.Builder.CreateStructGEP(ClassPtr, 1);
1829199482Srdivacky    Target = CGF.Builder.CreateLoad(ClassPtr);
1830193326Sed  }
1831193326Sed  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
1832193326Sed  // ObjCTypes types.
1833226633Sdim  llvm::Type *ClassTy =
1834193326Sed    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
1835193326Sed  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
1836198092Srdivacky  CGF.Builder.CreateStore(Target,
1837193326Sed                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
1838223017Sdim  return EmitMessageSend(CGF, Return, ResultType,
1839249423Sdim                         EmitSelector(CGF, Sel),
1840223017Sdim                         ObjCSuper, ObjCTypes.SuperPtrCTy,
1841223017Sdim                         true, CallArgs, Method, ObjCTypes);
1842193326Sed}
1843198092Srdivacky
1844198092Srdivacky/// Generate code for a message send expression.
1845193326SedCodeGen::RValue CGObjCMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
1846208600Srdivacky                                               ReturnValueSlot Return,
1847193326Sed                                               QualType ResultType,
1848193326Sed                                               Selector Sel,
1849193326Sed                                               llvm::Value *Receiver,
1850193326Sed                                               const CallArgList &CallArgs,
1851207619Srdivacky                                               const ObjCInterfaceDecl *Class,
1852193326Sed                                               const ObjCMethodDecl *Method) {
1853223017Sdim  return EmitMessageSend(CGF, Return, ResultType,
1854249423Sdim                         EmitSelector(CGF, Sel),
1855223017Sdim                         Receiver, CGF.getContext().getObjCIdType(),
1856223017Sdim                         false, CallArgs, Method, ObjCTypes);
1857193326Sed}
1858193326Sed
1859198092SrdivackyCodeGen::RValue
1860223017SdimCGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF,
1861223017Sdim                                 ReturnValueSlot Return,
1862223017Sdim                                 QualType ResultType,
1863223017Sdim                                 llvm::Value *Sel,
1864223017Sdim                                 llvm::Value *Arg0,
1865223017Sdim                                 QualType Arg0Ty,
1866223017Sdim                                 bool IsSuper,
1867223017Sdim                                 const CallArgList &CallArgs,
1868223017Sdim                                 const ObjCMethodDecl *Method,
1869223017Sdim                                 const ObjCCommonTypesHelper &ObjCTypes) {
1870193326Sed  CallArgList ActualArgs;
1871193326Sed  if (!IsSuper)
1872226633Sdim    Arg0 = CGF.Builder.CreateBitCast(Arg0, ObjCTypes.ObjectPtrTy);
1873221345Sdim  ActualArgs.add(RValue::get(Arg0), Arg0Ty);
1874221345Sdim  ActualArgs.add(RValue::get(Sel), CGF.getContext().getObjCSelType());
1875224145Sdim  ActualArgs.addFrom(CallArgs);
1876198092Srdivacky
1877234353Sdim  // If we're calling a method, use the formal signature.
1878234353Sdim  MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
1879198092Srdivacky
1880210299Sed  if (Method)
1881210299Sed    assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
1882210299Sed           CGM.getContext().getCanonicalType(ResultType) &&
1883210299Sed           "Result type mismatch!");
1884210299Sed
1885223017Sdim  NullReturnState nullReturn;
1886223017Sdim
1887193326Sed  llvm::Constant *Fn = NULL;
1888234353Sdim  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
1889223017Sdim    if (!IsSuper) nullReturn.init(CGF, Arg0);
1890193326Sed    Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
1891198092Srdivacky      : ObjCTypes.getSendStretFn(IsSuper);
1892210299Sed  } else if (CGM.ReturnTypeUsesFPRet(ResultType)) {
1893210299Sed    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFpretFn2(IsSuper)
1894210299Sed      : ObjCTypes.getSendFpretFn(IsSuper);
1895234353Sdim  } else if (CGM.ReturnTypeUsesFP2Ret(ResultType)) {
1896234353Sdim    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
1897234353Sdim      : ObjCTypes.getSendFp2retFn(IsSuper);
1898193326Sed  } else {
1899193326Sed    Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
1900198092Srdivacky      : ObjCTypes.getSendFn(IsSuper);
1901193326Sed  }
1902234353Sdim
1903234353Sdim  bool requiresnullCheck = false;
1904234353Sdim  if (CGM.getLangOpts().ObjCAutoRefCount && Method)
1905234353Sdim    for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
1906234353Sdim         e = Method->param_end(); i != e; ++i) {
1907234353Sdim      const ParmVarDecl *ParamDecl = (*i);
1908234353Sdim      if (ParamDecl->hasAttr<NSConsumedAttr>()) {
1909234353Sdim        if (!nullReturn.NullBB)
1910234353Sdim          nullReturn.init(CGF, Arg0);
1911234353Sdim        requiresnullCheck = true;
1912234353Sdim        break;
1913234353Sdim      }
1914234353Sdim    }
1915234353Sdim
1916234353Sdim  Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
1917234353Sdim  RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
1918234353Sdim  return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
1919234353Sdim                             requiresnullCheck ? Method : 0);
1920193326Sed}
1921193326Sed
1922212904Sdimstatic Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
1923212904Sdim  if (FQT.isObjCGCStrong())
1924212904Sdim    return Qualifiers::Strong;
1925212904Sdim
1926224145Sdim  if (FQT.isObjCGCWeak() || FQT.getObjCLifetime() == Qualifiers::OCL_Weak)
1927212904Sdim    return Qualifiers::Weak;
1928212904Sdim
1929234353Sdim  // check for __unsafe_unretained
1930234353Sdim  if (FQT.getObjCLifetime() == Qualifiers::OCL_ExplicitNone)
1931234353Sdim    return Qualifiers::GCNone;
1932234353Sdim
1933212904Sdim  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
1934212904Sdim    return Qualifiers::Strong;
1935212904Sdim
1936212904Sdim  if (const PointerType *PT = FQT->getAs<PointerType>())
1937212904Sdim    return GetGCAttrTypeForType(Ctx, PT->getPointeeType());
1938212904Sdim
1939212904Sdim  return Qualifiers::GCNone;
1940212904Sdim}
1941212904Sdim
1942218893Sdimllvm::Constant *CGObjCCommonMac::BuildGCBlockLayout(CodeGenModule &CGM,
1943218893Sdim                                                const CGBlockInfo &blockInfo) {
1944243830Sdim
1945234353Sdim  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1946234353Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
1947234353Sdim      !CGM.getLangOpts().ObjCAutoRefCount)
1948218893Sdim    return nullPtr;
1949218893Sdim
1950212904Sdim  bool hasUnion = false;
1951212904Sdim  SkipIvars.clear();
1952212904Sdim  IvarsInfo.clear();
1953251662Sdim  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
1954251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
1955212904Sdim
1956218893Sdim  // __isa is the first field in block descriptor and must assume by runtime's
1957218893Sdim  // convention that it is GC'able.
1958218893Sdim  IvarsInfo.push_back(GC_IVAR(0, 1));
1959218893Sdim
1960218893Sdim  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
1961218893Sdim
1962218893Sdim  // Calculate the basic layout of the block structure.
1963218893Sdim  const llvm::StructLayout *layout =
1964243830Sdim    CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
1965218893Sdim
1966218893Sdim  // Ignore the optional 'this' capture: C++ objects are not assumed
1967218893Sdim  // to be GC'ed.
1968218893Sdim
1969218893Sdim  // Walk the captured variables.
1970218893Sdim  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
1971218893Sdim         ce = blockDecl->capture_end(); ci != ce; ++ci) {
1972218893Sdim    const VarDecl *variable = ci->getVariable();
1973218893Sdim    QualType type = variable->getType();
1974218893Sdim
1975218893Sdim    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
1976218893Sdim
1977218893Sdim    // Ignore constant captures.
1978218893Sdim    if (capture.isConstant()) continue;
1979218893Sdim
1980218893Sdim    uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
1981218893Sdim
1982218893Sdim    // __block variables are passed by their descriptor address.
1983218893Sdim    if (ci->isByRef()) {
1984218893Sdim      IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
1985212904Sdim      continue;
1986212904Sdim    }
1987218893Sdim
1988218893Sdim    assert(!type->isArrayType() && "array variable should not be caught");
1989218893Sdim    if (const RecordType *record = type->getAs<RecordType>()) {
1990218893Sdim      BuildAggrIvarRecordLayout(record, fieldOffset, true, hasUnion);
1991218893Sdim      continue;
1992218893Sdim    }
1993212904Sdim
1994218893Sdim    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), type);
1995218893Sdim    unsigned fieldSize = CGM.getContext().getTypeSize(type);
1996218893Sdim
1997218893Sdim    if (GCAttr == Qualifiers::Strong)
1998218893Sdim      IvarsInfo.push_back(GC_IVAR(fieldOffset,
1999218893Sdim                                  fieldSize / WordSizeInBits));
2000212904Sdim    else if (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak)
2001218893Sdim      SkipIvars.push_back(GC_IVAR(fieldOffset,
2002218893Sdim                                  fieldSize / ByteSizeInBits));
2003212904Sdim  }
2004212904Sdim
2005212904Sdim  if (IvarsInfo.empty())
2006218893Sdim    return nullPtr;
2007218893Sdim
2008218893Sdim  // Sort on byte position; captures might not be allocated in order,
2009218893Sdim  // and unions can do funny things.
2010218893Sdim  llvm::array_pod_sort(IvarsInfo.begin(), IvarsInfo.end());
2011218893Sdim  llvm::array_pod_sort(SkipIvars.begin(), SkipIvars.end());
2012212904Sdim
2013212904Sdim  std::string BitMap;
2014212904Sdim  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
2015234353Sdim  if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2016212904Sdim    printf("\n block variable layout for block: ");
2017243830Sdim    const unsigned char *s = (const unsigned char*)BitMap.c_str();
2018234353Sdim    for (unsigned i = 0, e = BitMap.size(); i < e; i++)
2019212904Sdim      if (!(s[i] & 0xf0))
2020212904Sdim        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
2021212904Sdim      else
2022212904Sdim        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
2023212904Sdim    printf("\n");
2024212904Sdim  }
2025212904Sdim
2026212904Sdim  return C;
2027212904Sdim}
2028212904Sdim
2029243830Sdim/// getBlockCaptureLifetime - This routine returns life time of the captured
2030243830Sdim/// block variable for the purpose of block layout meta-data generation. FQT is
2031243830Sdim/// the type of the variable captured in the block.
2032249423SdimQualifiers::ObjCLifetime CGObjCCommonMac::getBlockCaptureLifetime(QualType FQT,
2033249423Sdim                                                                  bool ByrefLayout) {
2034243830Sdim  if (CGM.getLangOpts().ObjCAutoRefCount)
2035243830Sdim    return FQT.getObjCLifetime();
2036243830Sdim
2037243830Sdim  // MRR.
2038243830Sdim  if (FQT->isObjCObjectPointerType() || FQT->isBlockPointerType())
2039249423Sdim    return ByrefLayout ? Qualifiers::OCL_ExplicitNone : Qualifiers::OCL_Strong;
2040243830Sdim
2041243830Sdim  return Qualifiers::OCL_None;
2042243830Sdim}
2043243830Sdim
2044243830Sdimvoid CGObjCCommonMac::UpdateRunSkipBlockVars(bool IsByref,
2045243830Sdim                                             Qualifiers::ObjCLifetime LifeTime,
2046243830Sdim                                             CharUnits FieldOffset,
2047243830Sdim                                             CharUnits FieldSize) {
2048243830Sdim  // __block variables are passed by their descriptor address.
2049243830Sdim  if (IsByref)
2050243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_BYREF, FieldOffset,
2051243830Sdim                                        FieldSize));
2052243830Sdim  else if (LifeTime == Qualifiers::OCL_Strong)
2053243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_STRONG, FieldOffset,
2054243830Sdim                                        FieldSize));
2055243830Sdim  else if (LifeTime == Qualifiers::OCL_Weak)
2056243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_WEAK, FieldOffset,
2057243830Sdim                                        FieldSize));
2058243830Sdim  else if (LifeTime == Qualifiers::OCL_ExplicitNone)
2059243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_UNRETAINED, FieldOffset,
2060243830Sdim                                        FieldSize));
2061243830Sdim  else
2062243830Sdim    RunSkipBlockVars.push_back(RUN_SKIP(BLOCK_LAYOUT_NON_OBJECT_BYTES,
2063243830Sdim                                        FieldOffset,
2064243830Sdim                                        FieldSize));
2065243830Sdim}
2066243830Sdim
2067243830Sdimvoid CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout,
2068243830Sdim                                          const RecordDecl *RD,
2069243830Sdim                                          ArrayRef<const FieldDecl*> RecFields,
2070249423Sdim                                          CharUnits BytePos, bool &HasUnion,
2071249423Sdim                                          bool ByrefLayout) {
2072243830Sdim  bool IsUnion = (RD && RD->isUnion());
2073243830Sdim  CharUnits MaxUnionSize = CharUnits::Zero();
2074243830Sdim  const FieldDecl *MaxField = 0;
2075243830Sdim  const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
2076243830Sdim  CharUnits MaxFieldOffset = CharUnits::Zero();
2077243830Sdim  CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
2078243830Sdim
2079243830Sdim  if (RecFields.empty())
2080243830Sdim    return;
2081251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2082243830Sdim
2083243830Sdim  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
2084243830Sdim    const FieldDecl *Field = RecFields[i];
2085243830Sdim    // Note that 'i' here is actually the field index inside RD of Field,
2086243830Sdim    // although this dependency is hidden.
2087243830Sdim    const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
2088243830Sdim    CharUnits FieldOffset =
2089243830Sdim      CGM.getContext().toCharUnitsFromBits(RL.getFieldOffset(i));
2090243830Sdim
2091243830Sdim    // Skip over unnamed or bitfields
2092243830Sdim    if (!Field->getIdentifier() || Field->isBitField()) {
2093243830Sdim      LastFieldBitfieldOrUnnamed = Field;
2094243830Sdim      LastBitfieldOrUnnamedOffset = FieldOffset;
2095243830Sdim      continue;
2096243830Sdim    }
2097243830Sdim
2098243830Sdim    LastFieldBitfieldOrUnnamed = 0;
2099243830Sdim    QualType FQT = Field->getType();
2100243830Sdim    if (FQT->isRecordType() || FQT->isUnionType()) {
2101243830Sdim      if (FQT->isUnionType())
2102243830Sdim        HasUnion = true;
2103243830Sdim
2104243830Sdim      BuildRCBlockVarRecordLayout(FQT->getAs<RecordType>(),
2105243830Sdim                                  BytePos + FieldOffset, HasUnion);
2106243830Sdim      continue;
2107243830Sdim    }
2108243830Sdim
2109243830Sdim    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2110243830Sdim      const ConstantArrayType *CArray =
2111243830Sdim        dyn_cast_or_null<ConstantArrayType>(Array);
2112243830Sdim      uint64_t ElCount = CArray->getSize().getZExtValue();
2113243830Sdim      assert(CArray && "only array with known element size is supported");
2114243830Sdim      FQT = CArray->getElementType();
2115243830Sdim      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
2116243830Sdim        const ConstantArrayType *CArray =
2117243830Sdim          dyn_cast_or_null<ConstantArrayType>(Array);
2118243830Sdim        ElCount *= CArray->getSize().getZExtValue();
2119243830Sdim        FQT = CArray->getElementType();
2120243830Sdim      }
2121243830Sdim
2122243830Sdim      assert(!FQT->isUnionType() &&
2123243830Sdim             "layout for array of unions not supported");
2124243830Sdim      if (FQT->isRecordType() && ElCount) {
2125243830Sdim        int OldIndex = RunSkipBlockVars.size() - 1;
2126243830Sdim        const RecordType *RT = FQT->getAs<RecordType>();
2127243830Sdim        BuildRCBlockVarRecordLayout(RT, BytePos + FieldOffset,
2128243830Sdim                                    HasUnion);
2129243830Sdim
2130243830Sdim        // Replicate layout information for each array element. Note that
2131243830Sdim        // one element is already done.
2132243830Sdim        uint64_t ElIx = 1;
2133243830Sdim        for (int FirstIndex = RunSkipBlockVars.size() - 1 ;ElIx < ElCount; ElIx++) {
2134243830Sdim          CharUnits Size = CGM.getContext().getTypeSizeInChars(RT);
2135243830Sdim          for (int i = OldIndex+1; i <= FirstIndex; ++i)
2136243830Sdim            RunSkipBlockVars.push_back(
2137243830Sdim              RUN_SKIP(RunSkipBlockVars[i].opcode,
2138243830Sdim              RunSkipBlockVars[i].block_var_bytepos + Size*ElIx,
2139243830Sdim              RunSkipBlockVars[i].block_var_size));
2140243830Sdim        }
2141243830Sdim        continue;
2142243830Sdim      }
2143243830Sdim    }
2144243830Sdim    CharUnits FieldSize = CGM.getContext().getTypeSizeInChars(Field->getType());
2145243830Sdim    if (IsUnion) {
2146243830Sdim      CharUnits UnionIvarSize = FieldSize;
2147243830Sdim      if (UnionIvarSize > MaxUnionSize) {
2148243830Sdim        MaxUnionSize = UnionIvarSize;
2149243830Sdim        MaxField = Field;
2150243830Sdim        MaxFieldOffset = FieldOffset;
2151243830Sdim      }
2152243830Sdim    } else {
2153243830Sdim      UpdateRunSkipBlockVars(false,
2154249423Sdim                             getBlockCaptureLifetime(FQT, ByrefLayout),
2155243830Sdim                             BytePos + FieldOffset,
2156243830Sdim                             FieldSize);
2157243830Sdim    }
2158243830Sdim  }
2159243830Sdim
2160243830Sdim  if (LastFieldBitfieldOrUnnamed) {
2161243830Sdim    if (LastFieldBitfieldOrUnnamed->isBitField()) {
2162243830Sdim      // Last field was a bitfield. Must update the info.
2163243830Sdim      uint64_t BitFieldSize
2164243830Sdim        = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
2165243830Sdim      unsigned UnsSize = (BitFieldSize / ByteSizeInBits) +
2166243830Sdim                        ((BitFieldSize % ByteSizeInBits) != 0);
2167243830Sdim      CharUnits Size = CharUnits::fromQuantity(UnsSize);
2168243830Sdim      Size += LastBitfieldOrUnnamedOffset;
2169243830Sdim      UpdateRunSkipBlockVars(false,
2170249423Sdim                             getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2171249423Sdim                                                     ByrefLayout),
2172243830Sdim                             BytePos + LastBitfieldOrUnnamedOffset,
2173243830Sdim                             Size);
2174243830Sdim    } else {
2175243830Sdim      assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
2176243830Sdim      // Last field was unnamed. Must update skip info.
2177243830Sdim      CharUnits FieldSize
2178243830Sdim        = CGM.getContext().getTypeSizeInChars(LastFieldBitfieldOrUnnamed->getType());
2179243830Sdim      UpdateRunSkipBlockVars(false,
2180249423Sdim                             getBlockCaptureLifetime(LastFieldBitfieldOrUnnamed->getType(),
2181249423Sdim                                                     ByrefLayout),
2182243830Sdim                             BytePos + LastBitfieldOrUnnamedOffset,
2183243830Sdim                             FieldSize);
2184243830Sdim    }
2185243830Sdim  }
2186243830Sdim
2187243830Sdim  if (MaxField)
2188243830Sdim    UpdateRunSkipBlockVars(false,
2189249423Sdim                           getBlockCaptureLifetime(MaxField->getType(), ByrefLayout),
2190243830Sdim                           BytePos + MaxFieldOffset,
2191243830Sdim                           MaxUnionSize);
2192243830Sdim}
2193243830Sdim
2194243830Sdimvoid CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
2195243830Sdim                                                  CharUnits BytePos,
2196249423Sdim                                                  bool &HasUnion,
2197249423Sdim                                                  bool ByrefLayout) {
2198243830Sdim  const RecordDecl *RD = RT->getDecl();
2199243830Sdim  SmallVector<const FieldDecl*, 16> Fields;
2200243830Sdim  for (RecordDecl::field_iterator i = RD->field_begin(),
2201243830Sdim       e = RD->field_end(); i != e; ++i)
2202243830Sdim    Fields.push_back(*i);
2203243830Sdim  llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
2204243830Sdim  const llvm::StructLayout *RecLayout =
2205243830Sdim    CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
2206243830Sdim
2207249423Sdim  BuildRCRecordLayout(RecLayout, RD, Fields, BytePos, HasUnion, ByrefLayout);
2208243830Sdim}
2209243830Sdim
2210243830Sdim/// InlineLayoutInstruction - This routine produce an inline instruction for the
2211243830Sdim/// block variable layout if it can. If not, it returns 0. Rules are as follow:
2212243830Sdim/// If ((uintptr_t) layout) < (1 << 12), the layout is inline. In the 64bit world,
2213243830Sdim/// an inline layout of value 0x0000000000000xyz is interpreted as follows:
2214243830Sdim/// x captured object pointers of BLOCK_LAYOUT_STRONG. Followed by
2215243830Sdim/// y captured object of BLOCK_LAYOUT_BYREF. Followed by
2216243830Sdim/// z captured object of BLOCK_LAYOUT_WEAK. If any of the above is missing, zero
2217243830Sdim/// replaces it. For example, 0x00000x00 means x BLOCK_LAYOUT_STRONG and no
2218243830Sdim/// BLOCK_LAYOUT_BYREF and no BLOCK_LAYOUT_WEAK objects are captured.
2219243830Sdimuint64_t CGObjCCommonMac::InlineLayoutInstruction(
2220243830Sdim                                    SmallVectorImpl<unsigned char> &Layout) {
2221243830Sdim  uint64_t Result = 0;
2222243830Sdim  if (Layout.size() <= 3) {
2223243830Sdim    unsigned size = Layout.size();
2224243830Sdim    unsigned strong_word_count = 0, byref_word_count=0, weak_word_count=0;
2225243830Sdim    unsigned char inst;
2226243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode ;
2227243830Sdim    switch (size) {
2228243830Sdim      case 3:
2229243830Sdim        inst = Layout[0];
2230243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2231243830Sdim        if (opcode == BLOCK_LAYOUT_STRONG)
2232243830Sdim          strong_word_count = (inst & 0xF)+1;
2233243830Sdim        else
2234243830Sdim          return 0;
2235243830Sdim        inst = Layout[1];
2236243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2237243830Sdim        if (opcode == BLOCK_LAYOUT_BYREF)
2238243830Sdim          byref_word_count = (inst & 0xF)+1;
2239243830Sdim        else
2240243830Sdim          return 0;
2241243830Sdim        inst = Layout[2];
2242243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2243243830Sdim        if (opcode == BLOCK_LAYOUT_WEAK)
2244243830Sdim          weak_word_count = (inst & 0xF)+1;
2245243830Sdim        else
2246243830Sdim          return 0;
2247243830Sdim        break;
2248243830Sdim
2249243830Sdim      case 2:
2250243830Sdim        inst = Layout[0];
2251243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2252243830Sdim        if (opcode == BLOCK_LAYOUT_STRONG) {
2253243830Sdim          strong_word_count = (inst & 0xF)+1;
2254243830Sdim          inst = Layout[1];
2255243830Sdim          opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2256243830Sdim          if (opcode == BLOCK_LAYOUT_BYREF)
2257243830Sdim            byref_word_count = (inst & 0xF)+1;
2258243830Sdim          else if (opcode == BLOCK_LAYOUT_WEAK)
2259243830Sdim            weak_word_count = (inst & 0xF)+1;
2260243830Sdim          else
2261243830Sdim            return 0;
2262243830Sdim        }
2263243830Sdim        else if (opcode == BLOCK_LAYOUT_BYREF) {
2264243830Sdim          byref_word_count = (inst & 0xF)+1;
2265243830Sdim          inst = Layout[1];
2266243830Sdim          opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2267243830Sdim          if (opcode == BLOCK_LAYOUT_WEAK)
2268243830Sdim            weak_word_count = (inst & 0xF)+1;
2269243830Sdim          else
2270243830Sdim            return 0;
2271243830Sdim        }
2272243830Sdim        else
2273243830Sdim          return 0;
2274243830Sdim        break;
2275243830Sdim
2276243830Sdim      case 1:
2277243830Sdim        inst = Layout[0];
2278243830Sdim        opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2279243830Sdim        if (opcode == BLOCK_LAYOUT_STRONG)
2280243830Sdim          strong_word_count = (inst & 0xF)+1;
2281243830Sdim        else if (opcode == BLOCK_LAYOUT_BYREF)
2282243830Sdim          byref_word_count = (inst & 0xF)+1;
2283243830Sdim        else if (opcode == BLOCK_LAYOUT_WEAK)
2284243830Sdim          weak_word_count = (inst & 0xF)+1;
2285243830Sdim        else
2286243830Sdim          return 0;
2287243830Sdim        break;
2288243830Sdim
2289243830Sdim      default:
2290243830Sdim        return 0;
2291243830Sdim    }
2292243830Sdim
2293243830Sdim    // Cannot inline when any of the word counts is 15. Because this is one less
2294243830Sdim    // than the actual work count (so 15 means 16 actual word counts),
2295243830Sdim    // and we can only display 0 thru 15 word counts.
2296243830Sdim    if (strong_word_count == 16 || byref_word_count == 16 || weak_word_count == 16)
2297243830Sdim      return 0;
2298243830Sdim
2299243830Sdim    unsigned count =
2300243830Sdim      (strong_word_count != 0) + (byref_word_count != 0) + (weak_word_count != 0);
2301243830Sdim
2302243830Sdim    if (size == count) {
2303243830Sdim      if (strong_word_count)
2304243830Sdim        Result = strong_word_count;
2305243830Sdim      Result <<= 4;
2306243830Sdim      if (byref_word_count)
2307243830Sdim        Result += byref_word_count;
2308243830Sdim      Result <<= 4;
2309243830Sdim      if (weak_word_count)
2310243830Sdim        Result += weak_word_count;
2311243830Sdim    }
2312243830Sdim  }
2313243830Sdim  return Result;
2314243830Sdim}
2315243830Sdim
2316249423Sdimllvm::Constant *CGObjCCommonMac::getBitmapBlockLayout(bool ComputeByrefLayout) {
2317243830Sdim  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2318249423Sdim  if (RunSkipBlockVars.empty())
2319249423Sdim    return nullPtr;
2320251662Sdim  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2321251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2322243830Sdim  unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2323243830Sdim
2324243830Sdim  // Sort on byte position; captures might not be allocated in order,
2325243830Sdim  // and unions can do funny things.
2326243830Sdim  llvm::array_pod_sort(RunSkipBlockVars.begin(), RunSkipBlockVars.end());
2327243830Sdim  SmallVector<unsigned char, 16> Layout;
2328249423Sdim
2329243830Sdim  unsigned size = RunSkipBlockVars.size();
2330243830Sdim  for (unsigned i = 0; i < size; i++) {
2331243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode = RunSkipBlockVars[i].opcode;
2332243830Sdim    CharUnits start_byte_pos = RunSkipBlockVars[i].block_var_bytepos;
2333243830Sdim    CharUnits end_byte_pos = start_byte_pos;
2334243830Sdim    unsigned j = i+1;
2335243830Sdim    while (j < size) {
2336243830Sdim      if (opcode == RunSkipBlockVars[j].opcode) {
2337243830Sdim        end_byte_pos = RunSkipBlockVars[j++].block_var_bytepos;
2338243830Sdim        i++;
2339243830Sdim      }
2340243830Sdim      else
2341243830Sdim        break;
2342243830Sdim    }
2343243830Sdim    CharUnits size_in_bytes =
2344249423Sdim    end_byte_pos - start_byte_pos + RunSkipBlockVars[j-1].block_var_size;
2345243830Sdim    if (j < size) {
2346243830Sdim      CharUnits gap =
2347249423Sdim      RunSkipBlockVars[j].block_var_bytepos -
2348249423Sdim      RunSkipBlockVars[j-1].block_var_bytepos - RunSkipBlockVars[j-1].block_var_size;
2349243830Sdim      size_in_bytes += gap;
2350243830Sdim    }
2351243830Sdim    CharUnits residue_in_bytes = CharUnits::Zero();
2352243830Sdim    if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES) {
2353243830Sdim      residue_in_bytes = size_in_bytes % WordSizeInBytes;
2354243830Sdim      size_in_bytes -= residue_in_bytes;
2355243830Sdim      opcode = BLOCK_LAYOUT_NON_OBJECT_WORDS;
2356243830Sdim    }
2357249423Sdim
2358243830Sdim    unsigned size_in_words = size_in_bytes.getQuantity() / WordSizeInBytes;
2359243830Sdim    while (size_in_words >= 16) {
2360243830Sdim      // Note that value in imm. is one less that the actual
2361243830Sdim      // value. So, 0xf means 16 words follow!
2362243830Sdim      unsigned char inst = (opcode << 4) | 0xf;
2363243830Sdim      Layout.push_back(inst);
2364243830Sdim      size_in_words -= 16;
2365243830Sdim    }
2366243830Sdim    if (size_in_words > 0) {
2367243830Sdim      // Note that value in imm. is one less that the actual
2368243830Sdim      // value. So, we subtract 1 away!
2369243830Sdim      unsigned char inst = (opcode << 4) | (size_in_words-1);
2370243830Sdim      Layout.push_back(inst);
2371243830Sdim    }
2372243830Sdim    if (residue_in_bytes > CharUnits::Zero()) {
2373243830Sdim      unsigned char inst =
2374249423Sdim      (BLOCK_LAYOUT_NON_OBJECT_BYTES << 4) | (residue_in_bytes.getQuantity()-1);
2375243830Sdim      Layout.push_back(inst);
2376243830Sdim    }
2377243830Sdim  }
2378243830Sdim
2379243830Sdim  int e = Layout.size()-1;
2380243830Sdim  while (e >= 0) {
2381243830Sdim    unsigned char inst = Layout[e--];
2382243830Sdim    enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2383243830Sdim    if (opcode == BLOCK_LAYOUT_NON_OBJECT_BYTES || opcode == BLOCK_LAYOUT_NON_OBJECT_WORDS)
2384243830Sdim      Layout.pop_back();
2385243830Sdim    else
2386243830Sdim      break;
2387243830Sdim  }
2388243830Sdim
2389243830Sdim  uint64_t Result = InlineLayoutInstruction(Layout);
2390243830Sdim  if (Result != 0) {
2391243830Sdim    // Block variable layout instruction has been inlined.
2392243830Sdim    if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2393249423Sdim      if (ComputeByrefLayout)
2394249423Sdim        printf("\n Inline instruction for BYREF variable layout: ");
2395249423Sdim      else
2396249423Sdim        printf("\n Inline instruction for block variable layout: ");
2397251662Sdim      printf("0x0%" PRIx64 "\n", Result);
2398243830Sdim    }
2399243830Sdim    if (WordSizeInBytes == 8) {
2400243830Sdim      const llvm::APInt Instruction(64, Result);
2401243830Sdim      return llvm::Constant::getIntegerValue(CGM.Int64Ty, Instruction);
2402243830Sdim    }
2403243830Sdim    else {
2404243830Sdim      const llvm::APInt Instruction(32, Result);
2405243830Sdim      return llvm::Constant::getIntegerValue(CGM.Int32Ty, Instruction);
2406243830Sdim    }
2407243830Sdim  }
2408243830Sdim
2409243830Sdim  unsigned char inst = (BLOCK_LAYOUT_OPERATOR << 4) | 0;
2410243830Sdim  Layout.push_back(inst);
2411243830Sdim  std::string BitMap;
2412243830Sdim  for (unsigned i = 0, e = Layout.size(); i != e; i++)
2413243830Sdim    BitMap += Layout[i];
2414243830Sdim
2415243830Sdim  if (CGM.getLangOpts().ObjCGCBitmapPrint) {
2416249423Sdim    if (ComputeByrefLayout)
2417249423Sdim      printf("\n BYREF variable layout: ");
2418249423Sdim    else
2419249423Sdim      printf("\n block variable layout: ");
2420243830Sdim    for (unsigned i = 0, e = BitMap.size(); i != e; i++) {
2421243830Sdim      unsigned char inst = BitMap[i];
2422243830Sdim      enum BLOCK_LAYOUT_OPCODE opcode = (enum BLOCK_LAYOUT_OPCODE) (inst >> 4);
2423243830Sdim      unsigned delta = 1;
2424243830Sdim      switch (opcode) {
2425243830Sdim        case BLOCK_LAYOUT_OPERATOR:
2426243830Sdim          printf("BL_OPERATOR:");
2427243830Sdim          delta = 0;
2428243830Sdim          break;
2429243830Sdim        case BLOCK_LAYOUT_NON_OBJECT_BYTES:
2430243830Sdim          printf("BL_NON_OBJECT_BYTES:");
2431243830Sdim          break;
2432243830Sdim        case BLOCK_LAYOUT_NON_OBJECT_WORDS:
2433243830Sdim          printf("BL_NON_OBJECT_WORD:");
2434243830Sdim          break;
2435243830Sdim        case BLOCK_LAYOUT_STRONG:
2436243830Sdim          printf("BL_STRONG:");
2437243830Sdim          break;
2438243830Sdim        case BLOCK_LAYOUT_BYREF:
2439243830Sdim          printf("BL_BYREF:");
2440243830Sdim          break;
2441243830Sdim        case BLOCK_LAYOUT_WEAK:
2442243830Sdim          printf("BL_WEAK:");
2443243830Sdim          break;
2444243830Sdim        case BLOCK_LAYOUT_UNRETAINED:
2445243830Sdim          printf("BL_UNRETAINED:");
2446243830Sdim          break;
2447249423Sdim      }
2448243830Sdim      // Actual value of word count is one more that what is in the imm.
2449243830Sdim      // field of the instruction
2450249423Sdim      printf("%d", (inst & 0xf) + delta);
2451243830Sdim      if (i < e-1)
2452243830Sdim        printf(", ");
2453243830Sdim      else
2454243830Sdim        printf("\n");
2455243830Sdim    }
2456243830Sdim  }
2457243830Sdim
2458243830Sdim  llvm::GlobalVariable * Entry =
2459249423Sdim  CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
2460243830Sdim                    llvm::ConstantDataArray::getString(VMContext, BitMap,false),
2461243830Sdim                    "__TEXT,__objc_classname,cstring_literals", 1, true);
2462243830Sdim  return getConstantGEP(VMContext, Entry, 0, 0);
2463243830Sdim}
2464243830Sdim
2465249423Sdimllvm::Constant *CGObjCCommonMac::BuildRCBlockLayout(CodeGenModule &CGM,
2466249423Sdim                                                    const CGBlockInfo &blockInfo) {
2467249423Sdim  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2468249423Sdim
2469249423Sdim  RunSkipBlockVars.clear();
2470249423Sdim  bool hasUnion = false;
2471249423Sdim
2472251662Sdim  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
2473251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
2474249423Sdim  unsigned WordSizeInBytes = WordSizeInBits/ByteSizeInBits;
2475249423Sdim
2476249423Sdim  const BlockDecl *blockDecl = blockInfo.getBlockDecl();
2477249423Sdim
2478249423Sdim  // Calculate the basic layout of the block structure.
2479249423Sdim  const llvm::StructLayout *layout =
2480249423Sdim  CGM.getDataLayout().getStructLayout(blockInfo.StructureType);
2481249423Sdim
2482249423Sdim  // Ignore the optional 'this' capture: C++ objects are not assumed
2483249423Sdim  // to be GC'ed.
2484249423Sdim  if (blockInfo.BlockHeaderForcedGapSize != CharUnits::Zero())
2485249423Sdim    UpdateRunSkipBlockVars(false, Qualifiers::OCL_None,
2486249423Sdim                           blockInfo.BlockHeaderForcedGapOffset,
2487249423Sdim                           blockInfo.BlockHeaderForcedGapSize);
2488249423Sdim  // Walk the captured variables.
2489249423Sdim  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
2490249423Sdim       ce = blockDecl->capture_end(); ci != ce; ++ci) {
2491249423Sdim    const VarDecl *variable = ci->getVariable();
2492249423Sdim    QualType type = variable->getType();
2493249423Sdim
2494249423Sdim    const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
2495249423Sdim
2496249423Sdim    // Ignore constant captures.
2497249423Sdim    if (capture.isConstant()) continue;
2498249423Sdim
2499249423Sdim    CharUnits fieldOffset =
2500249423Sdim       CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
2501249423Sdim
2502249423Sdim    assert(!type->isArrayType() && "array variable should not be caught");
2503249423Sdim    if (!ci->isByRef())
2504249423Sdim      if (const RecordType *record = type->getAs<RecordType>()) {
2505249423Sdim        BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
2506249423Sdim        continue;
2507249423Sdim      }
2508249423Sdim    CharUnits fieldSize;
2509249423Sdim    if (ci->isByRef())
2510249423Sdim      fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
2511249423Sdim    else
2512249423Sdim      fieldSize = CGM.getContext().getTypeSizeInChars(type);
2513249423Sdim    UpdateRunSkipBlockVars(ci->isByRef(), getBlockCaptureLifetime(type, false),
2514249423Sdim                           fieldOffset, fieldSize);
2515249423Sdim  }
2516249423Sdim  return getBitmapBlockLayout(false);
2517249423Sdim}
2518249423Sdim
2519249423Sdim
2520249423Sdimllvm::Constant *CGObjCCommonMac::BuildByrefLayout(CodeGen::CodeGenModule &CGM,
2521249423Sdim                                                  QualType T) {
2522249423Sdim  assert(CGM.getLangOpts().getGC() == LangOptions::NonGC);
2523249423Sdim  assert(!T->isArrayType() && "__block array variable should not be caught");
2524249423Sdim  CharUnits fieldOffset;
2525249423Sdim  RunSkipBlockVars.clear();
2526249423Sdim  bool hasUnion = false;
2527249423Sdim  if (const RecordType *record = T->getAs<RecordType>()) {
2528249423Sdim    BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion, true /*ByrefLayout */);
2529249423Sdim    llvm::Constant *Result = getBitmapBlockLayout(true);
2530249423Sdim    return Result;
2531249423Sdim  }
2532249423Sdim  llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
2533249423Sdim  return nullPtr;
2534249423Sdim}
2535249423Sdim
2536249423Sdimllvm::Value *CGObjCMac::GenerateProtocolRef(CodeGenFunction &CGF,
2537193326Sed                                            const ObjCProtocolDecl *PD) {
2538193326Sed  // FIXME: I don't understand why gcc generates this, or where it is
2539193326Sed  // resolved. Investigate. Its also wasteful to look this up over and over.
2540193326Sed  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2541193326Sed
2542193326Sed  return llvm::ConstantExpr::getBitCast(GetProtocolRef(PD),
2543234353Sdim                                        ObjCTypes.getExternalProtocolPtrTy());
2544193326Sed}
2545193326Sed
2546193326Sedvoid CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
2547193326Sed  // FIXME: We shouldn't need this, the protocol decl should contain enough
2548193326Sed  // information to tell us whether this was a declaration or a definition.
2549193326Sed  DefinedProtocols.insert(PD->getIdentifier());
2550193326Sed
2551193326Sed  // If we have generated a forward reference to this protocol, emit
2552193326Sed  // it now. Otherwise do nothing, the protocol objects are lazily
2553193326Sed  // emitted.
2554198092Srdivacky  if (Protocols.count(PD->getIdentifier()))
2555193326Sed    GetOrEmitProtocol(PD);
2556193326Sed}
2557193326Sed
2558193326Sedllvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
2559193326Sed  if (DefinedProtocols.count(PD->getIdentifier()))
2560193326Sed    return GetOrEmitProtocol(PD);
2561223017Sdim
2562193326Sed  return GetOrEmitProtocolRef(PD);
2563193326Sed}
2564193326Sed
2565193326Sed/*
2566198092Srdivacky// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
2567198092Srdivackystruct _objc_protocol {
2568198092Srdivackystruct _objc_protocol_extension *isa;
2569198092Srdivackychar *protocol_name;
2570198092Srdivackystruct _objc_protocol_list *protocol_list;
2571198092Srdivackystruct _objc__method_prototype_list *instance_methods;
2572198092Srdivackystruct _objc__method_prototype_list *class_methods
2573198092Srdivacky};
2574193326Sed
2575198092SrdivackySee EmitProtocolExtension().
2576193326Sed*/
2577193326Sedllvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
2578234353Sdim  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
2579193326Sed
2580193326Sed  // Early exit if a defining object has already been generated.
2581193326Sed  if (Entry && Entry->hasInitializer())
2582193326Sed    return Entry;
2583193326Sed
2584234353Sdim  // Use the protocol definition, if there is one.
2585234353Sdim  if (const ObjCProtocolDecl *Def = PD->getDefinition())
2586234353Sdim    PD = Def;
2587234353Sdim
2588193326Sed  // FIXME: I don't understand why gcc generates this, or where it is
2589193326Sed  // resolved. Investigate. Its also wasteful to look this up over and over.
2590193326Sed  LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
2591193326Sed
2592193326Sed  // Construct method lists.
2593193326Sed  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
2594193326Sed  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
2595234353Sdim  std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
2596198092Srdivacky  for (ObjCProtocolDecl::instmeth_iterator
2597195341Sed         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
2598193326Sed    ObjCMethodDecl *MD = *i;
2599193326Sed    llvm::Constant *C = GetMethodDescriptionConstant(MD);
2600223017Sdim    if (!C)
2601223017Sdim      return GetOrEmitProtocolRef(PD);
2602223017Sdim
2603193326Sed    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2604193326Sed      OptInstanceMethods.push_back(C);
2605234353Sdim      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2606193326Sed    } else {
2607193326Sed      InstanceMethods.push_back(C);
2608234353Sdim      MethodTypesExt.push_back(GetMethodVarType(MD, true));
2609198092Srdivacky    }
2610193326Sed  }
2611193326Sed
2612198092Srdivacky  for (ObjCProtocolDecl::classmeth_iterator
2613195341Sed         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
2614193326Sed    ObjCMethodDecl *MD = *i;
2615193326Sed    llvm::Constant *C = GetMethodDescriptionConstant(MD);
2616223017Sdim    if (!C)
2617223017Sdim      return GetOrEmitProtocolRef(PD);
2618223017Sdim
2619193326Sed    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
2620193326Sed      OptClassMethods.push_back(C);
2621234353Sdim      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
2622193326Sed    } else {
2623193326Sed      ClassMethods.push_back(C);
2624234353Sdim      MethodTypesExt.push_back(GetMethodVarType(MD, true));
2625198092Srdivacky    }
2626193326Sed  }
2627193326Sed
2628234353Sdim  MethodTypesExt.insert(MethodTypesExt.end(),
2629234353Sdim                        OptMethodTypesExt.begin(), OptMethodTypesExt.end());
2630234353Sdim
2631234353Sdim  llvm::Constant *Values[] = {
2632234353Sdim    EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods,
2633234353Sdim                          MethodTypesExt),
2634234353Sdim    GetClassName(PD->getIdentifier()),
2635198398Srdivacky    EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
2636193326Sed                     PD->protocol_begin(),
2637234353Sdim                     PD->protocol_end()),
2638198398Srdivacky    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_" + PD->getName(),
2639193326Sed                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2640234353Sdim                       InstanceMethods),
2641198398Srdivacky    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_" + PD->getName(),
2642193326Sed                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2643234353Sdim                       ClassMethods)
2644234353Sdim  };
2645193326Sed  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
2646193326Sed                                                   Values);
2647198092Srdivacky
2648193326Sed  if (Entry) {
2649193326Sed    // Already created, fix the linkage and update the initializer.
2650193326Sed    Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
2651193326Sed    Entry->setInitializer(Init);
2652193326Sed  } else {
2653198092Srdivacky    Entry =
2654198092Srdivacky      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
2655193326Sed                               llvm::GlobalValue::InternalLinkage,
2656198092Srdivacky                               Init,
2657198398Srdivacky                               "\01L_OBJC_PROTOCOL_" + PD->getName());
2658193326Sed    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2659193326Sed    // FIXME: Is this necessary? Why only for protocol?
2660193326Sed    Entry->setAlignment(4);
2661234353Sdim
2662234353Sdim    Protocols[PD->getIdentifier()] = Entry;
2663193326Sed  }
2664198092Srdivacky  CGM.AddUsedGlobal(Entry);
2665193326Sed
2666193326Sed  return Entry;
2667193326Sed}
2668193326Sed
2669193326Sedllvm::Constant *CGObjCMac::GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) {
2670193326Sed  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
2671193326Sed
2672193326Sed  if (!Entry) {
2673193326Sed    // We use the initializer as a marker of whether this is a forward
2674193326Sed    // reference or not. At module finalization we add the empty
2675193326Sed    // contents for protocols which were referenced but never defined.
2676198092Srdivacky    Entry =
2677198092Srdivacky      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
2678193326Sed                               llvm::GlobalValue::ExternalLinkage,
2679193326Sed                               0,
2680198398Srdivacky                               "\01L_OBJC_PROTOCOL_" + PD->getName());
2681193326Sed    Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
2682193326Sed    // FIXME: Is this necessary? Why only for protocol?
2683193326Sed    Entry->setAlignment(4);
2684193326Sed  }
2685198092Srdivacky
2686193326Sed  return Entry;
2687193326Sed}
2688193326Sed
2689193326Sed/*
2690193326Sed  struct _objc_protocol_extension {
2691198092Srdivacky  uint32_t size;
2692198092Srdivacky  struct objc_method_description_list *optional_instance_methods;
2693198092Srdivacky  struct objc_method_description_list *optional_class_methods;
2694198092Srdivacky  struct objc_property_list *instance_properties;
2695234353Sdim  const char ** extendedMethodTypes;
2696193326Sed  };
2697193326Sed*/
2698193326Sedllvm::Constant *
2699193326SedCGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
2700234353Sdim                                 ArrayRef<llvm::Constant*> OptInstanceMethods,
2701234353Sdim                                 ArrayRef<llvm::Constant*> OptClassMethods,
2702234353Sdim                                 ArrayRef<llvm::Constant*> MethodTypesExt) {
2703198092Srdivacky  uint64_t Size =
2704243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolExtensionTy);
2705234353Sdim  llvm::Constant *Values[] = {
2706234353Sdim    llvm::ConstantInt::get(ObjCTypes.IntTy, Size),
2707198092Srdivacky    EmitMethodDescList("\01L_OBJC_PROTOCOL_INSTANCE_METHODS_OPT_"
2708198398Srdivacky                       + PD->getName(),
2709193326Sed                       "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2710234353Sdim                       OptInstanceMethods),
2711198398Srdivacky    EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
2712193326Sed                       "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2713234353Sdim                       OptClassMethods),
2714234353Sdim    EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD,
2715234353Sdim                     ObjCTypes),
2716234353Sdim    EmitProtocolMethodTypes("\01L_OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
2717234353Sdim                            MethodTypesExt, ObjCTypes)
2718234353Sdim  };
2719193326Sed
2720193326Sed  // Return null if no extension bits are used.
2721198092Srdivacky  if (Values[1]->isNullValue() && Values[2]->isNullValue() &&
2722234353Sdim      Values[3]->isNullValue() && Values[4]->isNullValue())
2723193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
2724193326Sed
2725198092Srdivacky  llvm::Constant *Init =
2726193326Sed    llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
2727193326Sed
2728193326Sed  // No special section, but goes in llvm.used
2729198398Srdivacky  return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
2730198092Srdivacky                           Init,
2731193326Sed                           0, 0, true);
2732193326Sed}
2733193326Sed
2734193326Sed/*
2735193326Sed  struct objc_protocol_list {
2736234353Sdim    struct objc_protocol_list *next;
2737234353Sdim    long count;
2738234353Sdim    Protocol *list[];
2739193326Sed  };
2740193326Sed*/
2741193326Sedllvm::Constant *
2742226633SdimCGObjCMac::EmitProtocolList(Twine Name,
2743193326Sed                            ObjCProtocolDecl::protocol_iterator begin,
2744193326Sed                            ObjCProtocolDecl::protocol_iterator end) {
2745249423Sdim  SmallVector<llvm::Constant *, 16> ProtocolRefs;
2746193326Sed
2747193326Sed  for (; begin != end; ++begin)
2748193326Sed    ProtocolRefs.push_back(GetProtocolRef(*begin));
2749193326Sed
2750193326Sed  // Just return null for empty protocol lists
2751198092Srdivacky  if (ProtocolRefs.empty())
2752193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2753193326Sed
2754193326Sed  // This list is null terminated.
2755193326Sed  ProtocolRefs.push_back(llvm::Constant::getNullValue(ObjCTypes.ProtocolPtrTy));
2756193326Sed
2757224145Sdim  llvm::Constant *Values[3];
2758193326Sed  // This field is only used by the runtime.
2759193326Sed  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2760198092Srdivacky  Values[1] = llvm::ConstantInt::get(ObjCTypes.LongTy,
2761198092Srdivacky                                     ProtocolRefs.size() - 1);
2762198092Srdivacky  Values[2] =
2763198092Srdivacky    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolPtrTy,
2764198092Srdivacky                                                  ProtocolRefs.size()),
2765193326Sed                             ProtocolRefs);
2766198092Srdivacky
2767224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2768198092Srdivacky  llvm::GlobalVariable *GV =
2769193326Sed    CreateMetadataVar(Name, Init, "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2770193326Sed                      4, false);
2771193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListPtrTy);
2772193326Sed}
2773193326Sed
2774234353Sdimvoid CGObjCCommonMac::
2775234353SdimPushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
2776249423Sdim                       SmallVectorImpl<llvm::Constant *> &Properties,
2777234353Sdim                       const Decl *Container,
2778234353Sdim                       const ObjCProtocolDecl *PROTO,
2779234353Sdim                       const ObjCCommonTypesHelper &ObjCTypes) {
2780200583Srdivacky  for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
2781200583Srdivacky         E = PROTO->protocol_end(); P != E; ++P)
2782200583Srdivacky    PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
2783200583Srdivacky  for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
2784200583Srdivacky       E = PROTO->prop_end(); I != E; ++I) {
2785200583Srdivacky    const ObjCPropertyDecl *PD = *I;
2786200583Srdivacky    if (!PropertySet.insert(PD->getIdentifier()))
2787200583Srdivacky      continue;
2788234353Sdim    llvm::Constant *Prop[] = {
2789234353Sdim      GetPropertyName(PD->getIdentifier()),
2790234353Sdim      GetPropertyTypeString(PD, Container)
2791234353Sdim    };
2792200583Srdivacky    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy, Prop));
2793200583Srdivacky  }
2794200583Srdivacky}
2795200583Srdivacky
2796193326Sed/*
2797193326Sed  struct _objc_property {
2798234353Sdim    const char * const name;
2799234353Sdim    const char * const attributes;
2800193326Sed  };
2801193326Sed
2802193326Sed  struct _objc_property_list {
2803234353Sdim    uint32_t entsize; // sizeof (struct _objc_property)
2804234353Sdim    uint32_t prop_count;
2805234353Sdim    struct _objc_property[prop_count];
2806193326Sed  };
2807193326Sed*/
2808226633Sdimllvm::Constant *CGObjCCommonMac::EmitPropertyList(Twine Name,
2809198092Srdivacky                                       const Decl *Container,
2810198092Srdivacky                                       const ObjCContainerDecl *OCD,
2811198092Srdivacky                                       const ObjCCommonTypesHelper &ObjCTypes) {
2812249423Sdim  SmallVector<llvm::Constant *, 16> Properties;
2813200583Srdivacky  llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
2814198092Srdivacky  for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
2815198092Srdivacky         E = OCD->prop_end(); I != E; ++I) {
2816193326Sed    const ObjCPropertyDecl *PD = *I;
2817200583Srdivacky    PropertySet.insert(PD->getIdentifier());
2818234353Sdim    llvm::Constant *Prop[] = {
2819234353Sdim      GetPropertyName(PD->getIdentifier()),
2820234353Sdim      GetPropertyTypeString(PD, Container)
2821234353Sdim    };
2822193326Sed    Properties.push_back(llvm::ConstantStruct::get(ObjCTypes.PropertyTy,
2823193326Sed                                                   Prop));
2824193326Sed  }
2825210299Sed  if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
2826212904Sdim    for (ObjCInterfaceDecl::all_protocol_iterator
2827212904Sdim         P = OID->all_referenced_protocol_begin(),
2828212904Sdim         E = OID->all_referenced_protocol_end(); P != E; ++P)
2829210299Sed      PushProtocolProperties(PropertySet, Properties, Container, (*P),
2830210299Sed                             ObjCTypes);
2831210299Sed  }
2832210299Sed  else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
2833210299Sed    for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
2834210299Sed         E = CD->protocol_end(); P != E; ++P)
2835210299Sed      PushProtocolProperties(PropertySet, Properties, Container, (*P),
2836210299Sed                             ObjCTypes);
2837210299Sed  }
2838193326Sed
2839193326Sed  // Return null for empty list.
2840193326Sed  if (Properties.empty())
2841193326Sed    return llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2842193326Sed
2843198092Srdivacky  unsigned PropertySize =
2844243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.PropertyTy);
2845224145Sdim  llvm::Constant *Values[3];
2846193326Sed  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, PropertySize);
2847193326Sed  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Properties.size());
2848198092Srdivacky  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.PropertyTy,
2849193326Sed                                             Properties.size());
2850193326Sed  Values[2] = llvm::ConstantArray::get(AT, Properties);
2851224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2852193326Sed
2853198092Srdivacky  llvm::GlobalVariable *GV =
2854198092Srdivacky    CreateMetadataVar(Name, Init,
2855198092Srdivacky                      (ObjCABI == 2) ? "__DATA, __objc_const" :
2856193326Sed                      "__OBJC,__property,regular,no_dead_strip",
2857198092Srdivacky                      (ObjCABI == 2) ? 8 : 4,
2858193326Sed                      true);
2859193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.PropertyListPtrTy);
2860193326Sed}
2861193326Sed
2862234353Sdimllvm::Constant *
2863234353SdimCGObjCCommonMac::EmitProtocolMethodTypes(Twine Name,
2864234353Sdim                                         ArrayRef<llvm::Constant*> MethodTypes,
2865234353Sdim                                         const ObjCCommonTypesHelper &ObjCTypes) {
2866234353Sdim  // Return null for empty list.
2867234353Sdim  if (MethodTypes.empty())
2868234353Sdim    return llvm::Constant::getNullValue(ObjCTypes.Int8PtrPtrTy);
2869234353Sdim
2870234353Sdim  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
2871234353Sdim                                             MethodTypes.size());
2872234353Sdim  llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
2873234353Sdim
2874234353Sdim  llvm::GlobalVariable *GV =
2875234353Sdim    CreateMetadataVar(Name, Init,
2876234353Sdim                      (ObjCABI == 2) ? "__DATA, __objc_const" : 0,
2877234353Sdim                      (ObjCABI == 2) ? 8 : 4,
2878234353Sdim                      true);
2879234353Sdim  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
2880234353Sdim}
2881234353Sdim
2882193326Sed/*
2883193326Sed  struct objc_method_description_list {
2884198092Srdivacky  int count;
2885198092Srdivacky  struct objc_method_description list[];
2886193326Sed  };
2887193326Sed*/
2888193326Sedllvm::Constant *
2889193326SedCGObjCMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
2890234353Sdim  llvm::Constant *Desc[] = {
2891198092Srdivacky    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
2892234353Sdim                                   ObjCTypes.SelectorPtrTy),
2893234353Sdim    GetMethodVarType(MD)
2894234353Sdim  };
2895223017Sdim  if (!Desc[1])
2896223017Sdim    return 0;
2897223017Sdim
2898193326Sed  return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
2899193326Sed                                   Desc);
2900193326Sed}
2901193326Sed
2902234353Sdimllvm::Constant *
2903234353SdimCGObjCMac::EmitMethodDescList(Twine Name, const char *Section,
2904234353Sdim                              ArrayRef<llvm::Constant*> Methods) {
2905193326Sed  // Return null for empty list.
2906193326Sed  if (Methods.empty())
2907193326Sed    return llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
2908193326Sed
2909224145Sdim  llvm::Constant *Values[2];
2910193326Sed  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
2911198092Srdivacky  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodDescriptionTy,
2912193326Sed                                             Methods.size());
2913193326Sed  Values[1] = llvm::ConstantArray::get(AT, Methods);
2914224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
2915193326Sed
2916193326Sed  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
2917198092Srdivacky  return llvm::ConstantExpr::getBitCast(GV,
2918193326Sed                                        ObjCTypes.MethodDescriptionListPtrTy);
2919193326Sed}
2920193326Sed
2921193326Sed/*
2922193326Sed  struct _objc_category {
2923198092Srdivacky  char *category_name;
2924198092Srdivacky  char *class_name;
2925198092Srdivacky  struct _objc_method_list *instance_methods;
2926198092Srdivacky  struct _objc_method_list *class_methods;
2927198092Srdivacky  struct _objc_protocol_list *protocols;
2928198092Srdivacky  uint32_t size; // <rdar://4585769>
2929198092Srdivacky  struct _objc_property_list *instance_properties;
2930193326Sed  };
2931198092Srdivacky*/
2932193326Sedvoid CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
2933243830Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.CategoryTy);
2934193326Sed
2935193326Sed  // FIXME: This is poor design, the OCD should have a pointer to the category
2936193326Sed  // decl. Additionally, note that Category can be null for the @implementation
2937193326Sed  // w/o an @interface case. Sema should just create one for us as it does for
2938193326Sed  // @implementation so everyone else can live life under a clear blue sky.
2939193326Sed  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
2940198092Srdivacky  const ObjCCategoryDecl *Category =
2941193326Sed    Interface->FindCategoryDeclaration(OCD->getIdentifier());
2942193326Sed
2943234353Sdim  SmallString<256> ExtName;
2944198398Srdivacky  llvm::raw_svector_ostream(ExtName) << Interface->getName() << '_'
2945198398Srdivacky                                     << OCD->getName();
2946198398Srdivacky
2947249423Sdim  SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
2948198092Srdivacky  for (ObjCCategoryImplDecl::instmeth_iterator
2949195341Sed         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
2950193326Sed    // Instance methods should always be defined.
2951193326Sed    InstanceMethods.push_back(GetMethodConstant(*i));
2952193326Sed  }
2953198092Srdivacky  for (ObjCCategoryImplDecl::classmeth_iterator
2954195341Sed         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
2955193326Sed    // Class methods should always be defined.
2956193326Sed    ClassMethods.push_back(GetMethodConstant(*i));
2957193326Sed  }
2958193326Sed
2959224145Sdim  llvm::Constant *Values[7];
2960193326Sed  Values[0] = GetClassName(OCD->getIdentifier());
2961193326Sed  Values[1] = GetClassName(Interface->getIdentifier());
2962193326Sed  LazySymbols.insert(Interface->getIdentifier());
2963198092Srdivacky  Values[2] =
2964198398Srdivacky    EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
2965193326Sed                   "__OBJC,__cat_inst_meth,regular,no_dead_strip",
2966193326Sed                   InstanceMethods);
2967198092Srdivacky  Values[3] =
2968198398Srdivacky    EmitMethodList("\01L_OBJC_CATEGORY_CLASS_METHODS_" + ExtName.str(),
2969193326Sed                   "__OBJC,__cat_cls_meth,regular,no_dead_strip",
2970193326Sed                   ClassMethods);
2971193326Sed  if (Category) {
2972198092Srdivacky    Values[4] =
2973198398Srdivacky      EmitProtocolList("\01L_OBJC_CATEGORY_PROTOCOLS_" + ExtName.str(),
2974193326Sed                       Category->protocol_begin(),
2975193326Sed                       Category->protocol_end());
2976193326Sed  } else {
2977193326Sed    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
2978193326Sed  }
2979193326Sed  Values[5] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
2980193326Sed
2981193326Sed  // If there is no category @interface then there can be no properties.
2982193326Sed  if (Category) {
2983198398Srdivacky    Values[6] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
2984193326Sed                                 OCD, Category, ObjCTypes);
2985193326Sed  } else {
2986193326Sed    Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
2987193326Sed  }
2988198092Srdivacky
2989193326Sed  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.CategoryTy,
2990193326Sed                                                   Values);
2991193326Sed
2992198092Srdivacky  llvm::GlobalVariable *GV =
2993198398Srdivacky    CreateMetadataVar("\01L_OBJC_CATEGORY_" + ExtName.str(), Init,
2994193326Sed                      "__OBJC,__category,regular,no_dead_strip",
2995193326Sed                      4, true);
2996193326Sed  DefinedCategories.push_back(GV);
2997210299Sed  DefinedCategoryNames.insert(ExtName.str());
2998221345Sdim  // method definition entries must be clear for next implementation.
2999221345Sdim  MethodDefinitions.clear();
3000193326Sed}
3001193326Sed
3002243830Sdimenum FragileClassFlags {
3003243830Sdim  FragileABI_Class_Factory                 = 0x00001,
3004243830Sdim  FragileABI_Class_Meta                    = 0x00002,
3005243830Sdim  FragileABI_Class_HasCXXStructors         = 0x02000,
3006243830Sdim  FragileABI_Class_Hidden                  = 0x20000
3007193326Sed};
3008193326Sed
3009243830Sdimenum NonFragileClassFlags {
3010243830Sdim  /// Is a meta-class.
3011243830Sdim  NonFragileABI_Class_Meta                 = 0x00001,
3012243830Sdim
3013243830Sdim  /// Is a root class.
3014243830Sdim  NonFragileABI_Class_Root                 = 0x00002,
3015243830Sdim
3016243830Sdim  /// Has a C++ constructor and destructor.
3017243830Sdim  NonFragileABI_Class_HasCXXStructors      = 0x00004,
3018243830Sdim
3019243830Sdim  /// Has hidden visibility.
3020243830Sdim  NonFragileABI_Class_Hidden               = 0x00010,
3021243830Sdim
3022243830Sdim  /// Has the exception attribute.
3023243830Sdim  NonFragileABI_Class_Exception            = 0x00020,
3024243830Sdim
3025243830Sdim  /// (Obsolete) ARC-specific: this class has a .release_ivars method
3026243830Sdim  NonFragileABI_Class_HasIvarReleaser      = 0x00040,
3027243830Sdim
3028243830Sdim  /// Class implementation was compiled under ARC.
3029243830Sdim  NonFragileABI_Class_CompiledByARC        = 0x00080,
3030243830Sdim
3031243830Sdim  /// Class has non-trivial destructors, but zero-initialization is okay.
3032243830Sdim  NonFragileABI_Class_HasCXXDestructorOnly = 0x00100
3033243830Sdim};
3034243830Sdim
3035193326Sed/*
3036193326Sed  struct _objc_class {
3037198092Srdivacky  Class isa;
3038198092Srdivacky  Class super_class;
3039198092Srdivacky  const char *name;
3040198092Srdivacky  long version;
3041198092Srdivacky  long info;
3042198092Srdivacky  long instance_size;
3043198092Srdivacky  struct _objc_ivar_list *ivars;
3044198092Srdivacky  struct _objc_method_list *methods;
3045198092Srdivacky  struct _objc_cache *cache;
3046198092Srdivacky  struct _objc_protocol_list *protocols;
3047198092Srdivacky  // Objective-C 1.0 extensions (<rdr://4585769>)
3048198092Srdivacky  const char *ivar_layout;
3049198092Srdivacky  struct _objc_class_ext *ext;
3050193326Sed  };
3051193326Sed
3052193326Sed  See EmitClassExtension();
3053198092Srdivacky*/
3054193326Sedvoid CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
3055193326Sed  DefinedSymbols.insert(ID->getIdentifier());
3056193326Sed
3057193326Sed  std::string ClassName = ID->getNameAsString();
3058193326Sed  // FIXME: Gross
3059198092Srdivacky  ObjCInterfaceDecl *Interface =
3060193326Sed    const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
3061198092Srdivacky  llvm::Constant *Protocols =
3062198398Srdivacky    EmitProtocolList("\01L_OBJC_CLASS_PROTOCOLS_" + ID->getName(),
3063212904Sdim                     Interface->all_referenced_protocol_begin(),
3064212904Sdim                     Interface->all_referenced_protocol_end());
3065243830Sdim  unsigned Flags = FragileABI_Class_Factory;
3066243830Sdim  if (ID->hasNonZeroConstructors() || ID->hasDestructors())
3067243830Sdim    Flags |= FragileABI_Class_HasCXXStructors;
3068198092Srdivacky  unsigned Size =
3069218893Sdim    CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
3070193326Sed
3071193326Sed  // FIXME: Set CXX-structors flag.
3072218893Sdim  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3073243830Sdim    Flags |= FragileABI_Class_Hidden;
3074193326Sed
3075249423Sdim  SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
3076198092Srdivacky  for (ObjCImplementationDecl::instmeth_iterator
3077195341Sed         i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
3078193326Sed    // Instance methods should always be defined.
3079193326Sed    InstanceMethods.push_back(GetMethodConstant(*i));
3080193326Sed  }
3081198092Srdivacky  for (ObjCImplementationDecl::classmeth_iterator
3082195341Sed         i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
3083193326Sed    // Class methods should always be defined.
3084193326Sed    ClassMethods.push_back(GetMethodConstant(*i));
3085193326Sed  }
3086193326Sed
3087198092Srdivacky  for (ObjCImplementationDecl::propimpl_iterator
3088195341Sed         i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
3089193326Sed    ObjCPropertyImplDecl *PID = *i;
3090193326Sed
3091193326Sed    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
3092193326Sed      ObjCPropertyDecl *PD = PID->getPropertyDecl();
3093193326Sed
3094193326Sed      if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
3095193326Sed        if (llvm::Constant *C = GetMethodConstant(MD))
3096193326Sed          InstanceMethods.push_back(C);
3097193326Sed      if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
3098193326Sed        if (llvm::Constant *C = GetMethodConstant(MD))
3099193326Sed          InstanceMethods.push_back(C);
3100193326Sed    }
3101193326Sed  }
3102193326Sed
3103224145Sdim  llvm::Constant *Values[12];
3104193326Sed  Values[ 0] = EmitMetaClass(ID, Protocols, ClassMethods);
3105193326Sed  if (ObjCInterfaceDecl *Super = Interface->getSuperClass()) {
3106193326Sed    // Record a reference to the super class.
3107193326Sed    LazySymbols.insert(Super->getIdentifier());
3108193326Sed
3109198092Srdivacky    Values[ 1] =
3110193326Sed      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
3111193326Sed                                     ObjCTypes.ClassPtrTy);
3112193326Sed  } else {
3113193326Sed    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3114193326Sed  }
3115193326Sed  Values[ 2] = GetClassName(ID->getIdentifier());
3116193326Sed  // Version is always 0.
3117193326Sed  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3118193326Sed  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3119193326Sed  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3120193326Sed  Values[ 6] = EmitIvarList(ID, false);
3121198092Srdivacky  Values[ 7] =
3122198398Srdivacky    EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getName(),
3123193326Sed                   "__OBJC,__inst_meth,regular,no_dead_strip",
3124193326Sed                   InstanceMethods);
3125193326Sed  // cache is always NULL.
3126193326Sed  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3127193326Sed  Values[ 9] = Protocols;
3128198092Srdivacky  Values[10] = BuildIvarLayout(ID, true);
3129193326Sed  Values[11] = EmitClassExtension(ID);
3130193326Sed  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3131193326Sed                                                   Values);
3132199482Srdivacky  std::string Name("\01L_OBJC_CLASS_");
3133199482Srdivacky  Name += ClassName;
3134199482Srdivacky  const char *Section = "__OBJC,__class,regular,no_dead_strip";
3135199482Srdivacky  // Check for a forward reference.
3136199482Srdivacky  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
3137199482Srdivacky  if (GV) {
3138199482Srdivacky    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3139199482Srdivacky           "Forward metaclass reference has incorrect type.");
3140199482Srdivacky    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
3141199482Srdivacky    GV->setInitializer(Init);
3142199482Srdivacky    GV->setSection(Section);
3143199482Srdivacky    GV->setAlignment(4);
3144199482Srdivacky    CGM.AddUsedGlobal(GV);
3145199482Srdivacky  }
3146199482Srdivacky  else
3147199482Srdivacky    GV = CreateMetadataVar(Name, Init, Section, 4, true);
3148193326Sed  DefinedClasses.push_back(GV);
3149221345Sdim  // method definition entries must be clear for next implementation.
3150221345Sdim  MethodDefinitions.clear();
3151193326Sed}
3152193326Sed
3153193326Sedllvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
3154193326Sed                                         llvm::Constant *Protocols,
3155234353Sdim                                         ArrayRef<llvm::Constant*> Methods) {
3156243830Sdim  unsigned Flags = FragileABI_Class_Meta;
3157243830Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassTy);
3158193326Sed
3159218893Sdim  if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
3160243830Sdim    Flags |= FragileABI_Class_Hidden;
3161198092Srdivacky
3162224145Sdim  llvm::Constant *Values[12];
3163193326Sed  // The isa for the metaclass is the root of the hierarchy.
3164193326Sed  const ObjCInterfaceDecl *Root = ID->getClassInterface();
3165193326Sed  while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
3166193326Sed    Root = Super;
3167198092Srdivacky  Values[ 0] =
3168193326Sed    llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
3169193326Sed                                   ObjCTypes.ClassPtrTy);
3170193326Sed  // The super class for the metaclass is emitted as the name of the
3171193326Sed  // super class. The runtime fixes this up to point to the
3172193326Sed  // *metaclass* for the super class.
3173193326Sed  if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
3174198092Srdivacky    Values[ 1] =
3175193326Sed      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
3176193326Sed                                     ObjCTypes.ClassPtrTy);
3177193326Sed  } else {
3178193326Sed    Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
3179193326Sed  }
3180193326Sed  Values[ 2] = GetClassName(ID->getIdentifier());
3181193326Sed  // Version is always 0.
3182193326Sed  Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
3183193326Sed  Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
3184193326Sed  Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size);
3185193326Sed  Values[ 6] = EmitIvarList(ID, true);
3186198092Srdivacky  Values[ 7] =
3187193326Sed    EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(),
3188193326Sed                   "__OBJC,__cls_meth,regular,no_dead_strip",
3189193326Sed                   Methods);
3190193326Sed  // cache is always NULL.
3191193326Sed  Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.CachePtrTy);
3192193326Sed  Values[ 9] = Protocols;
3193193326Sed  // ivar_layout for metaclass is always NULL.
3194193326Sed  Values[10] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3195193326Sed  // The class extension is always unused for metaclasses.
3196193326Sed  Values[11] = llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3197193326Sed  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassTy,
3198193326Sed                                                   Values);
3199193326Sed
3200193326Sed  std::string Name("\01L_OBJC_METACLASS_");
3201239462Sdim  Name += ID->getName();
3202193326Sed
3203193326Sed  // Check for a forward reference.
3204193326Sed  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
3205193326Sed  if (GV) {
3206193326Sed    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3207193326Sed           "Forward metaclass reference has incorrect type.");
3208193326Sed    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
3209193326Sed    GV->setInitializer(Init);
3210193326Sed  } else {
3211198092Srdivacky    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3212193326Sed                                  llvm::GlobalValue::InternalLinkage,
3213198092Srdivacky                                  Init, Name);
3214193326Sed  }
3215193326Sed  GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
3216193326Sed  GV->setAlignment(4);
3217198092Srdivacky  CGM.AddUsedGlobal(GV);
3218193326Sed
3219193326Sed  return GV;
3220193326Sed}
3221193326Sed
3222198092Srdivackyllvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) {
3223193326Sed  std::string Name = "\01L_OBJC_METACLASS_" + ID->getNameAsString();
3224193326Sed
3225193326Sed  // FIXME: Should we look these up somewhere other than the module. Its a bit
3226193326Sed  // silly since we only generate these while processing an implementation, so
3227193326Sed  // exactly one pointer would work if know when we entered/exitted an
3228193326Sed  // implementation block.
3229193326Sed
3230193326Sed  // Check for an existing forward reference.
3231193326Sed  // Previously, metaclass with internal linkage may have been defined.
3232193326Sed  // pass 'true' as 2nd argument so it is returned.
3233198092Srdivacky  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
3234198092Srdivacky                                                                   true)) {
3235193326Sed    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3236193326Sed           "Forward metaclass reference has incorrect type.");
3237193326Sed    return GV;
3238193326Sed  } else {
3239193326Sed    // Generate as an external reference to keep a consistent
3240193326Sed    // module. This will be patched up when we emit the metaclass.
3241198092Srdivacky    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3242193326Sed                                    llvm::GlobalValue::ExternalLinkage,
3243193326Sed                                    0,
3244198092Srdivacky                                    Name);
3245193326Sed  }
3246193326Sed}
3247193326Sed
3248199482Srdivackyllvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
3249199482Srdivacky  std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
3250199482Srdivacky
3251199482Srdivacky  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
3252199482Srdivacky                                                                   true)) {
3253199482Srdivacky    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
3254199482Srdivacky           "Forward class metadata reference has incorrect type.");
3255199482Srdivacky    return GV;
3256199482Srdivacky  } else {
3257199482Srdivacky    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
3258199482Srdivacky                                    llvm::GlobalValue::ExternalLinkage,
3259199482Srdivacky                                    0,
3260199482Srdivacky                                    Name);
3261199482Srdivacky  }
3262199482Srdivacky}
3263199482Srdivacky
3264193326Sed/*
3265193326Sed  struct objc_class_ext {
3266198092Srdivacky  uint32_t size;
3267198092Srdivacky  const char *weak_ivar_layout;
3268198092Srdivacky  struct _objc_property_list *properties;
3269193326Sed  };
3270193326Sed*/
3271193326Sedllvm::Constant *
3272193326SedCGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
3273198092Srdivacky  uint64_t Size =
3274243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassExtensionTy);
3275193326Sed
3276224145Sdim  llvm::Constant *Values[3];
3277193326Sed  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
3278193326Sed  Values[1] = BuildIvarLayout(ID, false);
3279198398Srdivacky  Values[2] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
3280193326Sed                               ID, ID->getClassInterface(), ObjCTypes);
3281193326Sed
3282193326Sed  // Return null if no extension bits are used.
3283193326Sed  if (Values[1]->isNullValue() && Values[2]->isNullValue())
3284193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ClassExtensionPtrTy);
3285193326Sed
3286198092Srdivacky  llvm::Constant *Init =
3287193326Sed    llvm::ConstantStruct::get(ObjCTypes.ClassExtensionTy, Values);
3288198398Srdivacky  return CreateMetadataVar("\01L_OBJC_CLASSEXT_" + ID->getName(),
3289198092Srdivacky                           Init, "__OBJC,__class_ext,regular,no_dead_strip",
3290193326Sed                           4, true);
3291193326Sed}
3292193326Sed
3293193326Sed/*
3294193326Sed  struct objc_ivar {
3295234353Sdim    char *ivar_name;
3296234353Sdim    char *ivar_type;
3297234353Sdim    int ivar_offset;
3298193326Sed  };
3299193326Sed
3300193326Sed  struct objc_ivar_list {
3301234353Sdim    int ivar_count;
3302234353Sdim    struct objc_ivar list[count];
3303193326Sed  };
3304198092Srdivacky*/
3305193326Sedllvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID,
3306193326Sed                                        bool ForClass) {
3307234353Sdim  std::vector<llvm::Constant*> Ivars;
3308193326Sed
3309193326Sed  // When emitting the root class GCC emits ivar entries for the
3310193326Sed  // actual class structure. It is not clear if we need to follow this
3311193326Sed  // behavior; for now lets try and get away with not doing it. If so,
3312193326Sed  // the cleanest solution would be to make up an ObjCInterfaceDecl
3313193326Sed  // for the class.
3314193326Sed  if (ForClass)
3315193326Sed    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3316198092Srdivacky
3317226633Sdim  const ObjCInterfaceDecl *OID = ID->getClassInterface();
3318198092Srdivacky
3319226633Sdim  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
3320224145Sdim       IVD; IVD = IVD->getNextIvar()) {
3321193576Sed    // Ignore unnamed bit-fields.
3322193576Sed    if (!IVD->getDeclName())
3323198092Srdivacky      continue;
3324234353Sdim    llvm::Constant *Ivar[] = {
3325234353Sdim      GetMethodVarName(IVD->getIdentifier()),
3326234353Sdim      GetMethodVarType(IVD),
3327234353Sdim      llvm::ConstantInt::get(ObjCTypes.IntTy,
3328234353Sdim                             ComputeIvarBaseOffset(CGM, OID, IVD))
3329234353Sdim    };
3330193326Sed    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));
3331193326Sed  }
3332193326Sed
3333193326Sed  // Return null for empty list.
3334193326Sed  if (Ivars.empty())
3335193326Sed    return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy);
3336193326Sed
3337224145Sdim  llvm::Constant *Values[2];
3338193326Sed  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
3339193326Sed  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarTy,
3340193326Sed                                             Ivars.size());
3341193326Sed  Values[1] = llvm::ConstantArray::get(AT, Ivars);
3342224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3343193326Sed
3344193326Sed  llvm::GlobalVariable *GV;
3345193326Sed  if (ForClass)
3346198398Srdivacky    GV = CreateMetadataVar("\01L_OBJC_CLASS_VARIABLES_" + ID->getName(),
3347198092Srdivacky                           Init, "__OBJC,__class_vars,regular,no_dead_strip",
3348193326Sed                           4, true);
3349193326Sed  else
3350198398Srdivacky    GV = CreateMetadataVar("\01L_OBJC_INSTANCE_VARIABLES_" + ID->getName(),
3351193326Sed                           Init, "__OBJC,__instance_vars,regular,no_dead_strip",
3352193326Sed                           4, true);
3353193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListPtrTy);
3354193326Sed}
3355193326Sed
3356193326Sed/*
3357193326Sed  struct objc_method {
3358198092Srdivacky  SEL method_name;
3359198092Srdivacky  char *method_types;
3360198092Srdivacky  void *method;
3361193326Sed  };
3362198092Srdivacky
3363193326Sed  struct objc_method_list {
3364198092Srdivacky  struct objc_method_list *obsolete;
3365198092Srdivacky  int count;
3366198092Srdivacky  struct objc_method methods_list[count];
3367193326Sed  };
3368193326Sed*/
3369193326Sed
3370193326Sed/// GetMethodConstant - Return a struct objc_method constant for the
3371193326Sed/// given method if it has been defined. The result is null if the
3372193326Sed/// method has not been defined. The return value has type MethodPtrTy.
3373193326Sedllvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
3374212904Sdim  llvm::Function *Fn = GetMethodDefinition(MD);
3375193326Sed  if (!Fn)
3376193326Sed    return 0;
3377198092Srdivacky
3378234353Sdim  llvm::Constant *Method[] = {
3379193326Sed    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
3380234353Sdim                                   ObjCTypes.SelectorPtrTy),
3381234353Sdim    GetMethodVarType(MD),
3382234353Sdim    llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
3383234353Sdim  };
3384193326Sed  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
3385193326Sed}
3386193326Sed
3387226633Sdimllvm::Constant *CGObjCMac::EmitMethodList(Twine Name,
3388193326Sed                                          const char *Section,
3389234353Sdim                                          ArrayRef<llvm::Constant*> Methods) {
3390193326Sed  // Return null for empty list.
3391193326Sed  if (Methods.empty())
3392193326Sed    return llvm::Constant::getNullValue(ObjCTypes.MethodListPtrTy);
3393193326Sed
3394224145Sdim  llvm::Constant *Values[3];
3395193326Sed  Values[0] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
3396193326Sed  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
3397193326Sed  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
3398193326Sed                                             Methods.size());
3399193326Sed  Values[2] = llvm::ConstantArray::get(AT, Methods);
3400224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
3401193326Sed
3402193326Sed  llvm::GlobalVariable *GV = CreateMetadataVar(Name, Init, Section, 4, true);
3403224145Sdim  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListPtrTy);
3404193326Sed}
3405193326Sed
3406193326Sedllvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD,
3407198092Srdivacky                                                const ObjCContainerDecl *CD) {
3408234353Sdim  SmallString<256> Name;
3409193326Sed  GetNameForMethod(OMD, CD, Name);
3410193326Sed
3411193326Sed  CodeGenTypes &Types = CGM.getTypes();
3412226633Sdim  llvm::FunctionType *MethodTy =
3413234353Sdim    Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD));
3414198092Srdivacky  llvm::Function *Method =
3415193326Sed    llvm::Function::Create(MethodTy,
3416193326Sed                           llvm::GlobalValue::InternalLinkage,
3417198398Srdivacky                           Name.str(),
3418193326Sed                           &CGM.getModule());
3419193326Sed  MethodDefinitions.insert(std::make_pair(OMD, Method));
3420193326Sed
3421193326Sed  return Method;
3422193326Sed}
3423193326Sed
3424193326Sedllvm::GlobalVariable *
3425226633SdimCGObjCCommonMac::CreateMetadataVar(Twine Name,
3426193326Sed                                   llvm::Constant *Init,
3427193326Sed                                   const char *Section,
3428193326Sed                                   unsigned Align,
3429193326Sed                                   bool AddToUsed) {
3430226633Sdim  llvm::Type *Ty = Init->getType();
3431198092Srdivacky  llvm::GlobalVariable *GV =
3432198092Srdivacky    new llvm::GlobalVariable(CGM.getModule(), Ty, false,
3433198092Srdivacky                             llvm::GlobalValue::InternalLinkage, Init, Name);
3434193326Sed  if (Section)
3435193326Sed    GV->setSection(Section);
3436193326Sed  if (Align)
3437193326Sed    GV->setAlignment(Align);
3438193326Sed  if (AddToUsed)
3439198092Srdivacky    CGM.AddUsedGlobal(GV);
3440193326Sed  return GV;
3441193326Sed}
3442193326Sed
3443198092Srdivackyllvm::Function *CGObjCMac::ModuleInitFunction() {
3444193326Sed  // Abuse this interface function as a place to finalize.
3445193326Sed  FinishModule();
3446193326Sed  return NULL;
3447193326Sed}
3448193326Sed
3449193326Sedllvm::Constant *CGObjCMac::GetPropertyGetFunction() {
3450193326Sed  return ObjCTypes.getGetPropertyFn();
3451193326Sed}
3452193326Sed
3453193326Sedllvm::Constant *CGObjCMac::GetPropertySetFunction() {
3454193326Sed  return ObjCTypes.getSetPropertyFn();
3455193326Sed}
3456193326Sed
3457234353Sdimllvm::Constant *CGObjCMac::GetOptimizedPropertySetFunction(bool atomic,
3458234353Sdim                                                           bool copy) {
3459234353Sdim  return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
3460234353Sdim}
3461234353Sdim
3462218893Sdimllvm::Constant *CGObjCMac::GetGetStructFunction() {
3463207619Srdivacky  return ObjCTypes.getCopyStructFn();
3464207619Srdivacky}
3465218893Sdimllvm::Constant *CGObjCMac::GetSetStructFunction() {
3466218893Sdim  return ObjCTypes.getCopyStructFn();
3467218893Sdim}
3468207619Srdivacky
3469249423Sdimllvm::Constant *CGObjCMac::GetCppAtomicObjectGetFunction() {
3470234353Sdim  return ObjCTypes.getCppAtomicObjectFunction();
3471234353Sdim}
3472249423Sdimllvm::Constant *CGObjCMac::GetCppAtomicObjectSetFunction() {
3473249423Sdim  return ObjCTypes.getCppAtomicObjectFunction();
3474249423Sdim}
3475234353Sdim
3476193326Sedllvm::Constant *CGObjCMac::EnumerationMutationFunction() {
3477193326Sed  return ObjCTypes.getEnumerationMutationFn();
3478193326Sed}
3479193326Sed
3480210299Sedvoid CGObjCMac::EmitTryStmt(CodeGenFunction &CGF, const ObjCAtTryStmt &S) {
3481210299Sed  return EmitTryOrSynchronizedStmt(CGF, S);
3482210299Sed}
3483210299Sed
3484210299Sedvoid CGObjCMac::EmitSynchronizedStmt(CodeGenFunction &CGF,
3485210299Sed                                     const ObjCAtSynchronizedStmt &S) {
3486210299Sed  return EmitTryOrSynchronizedStmt(CGF, S);
3487210299Sed}
3488210299Sed
3489212904Sdimnamespace {
3490212904Sdim  struct PerformFragileFinally : EHScopeStack::Cleanup {
3491212904Sdim    const Stmt &S;
3492212904Sdim    llvm::Value *SyncArgSlot;
3493212904Sdim    llvm::Value *CallTryExitVar;
3494212904Sdim    llvm::Value *ExceptionData;
3495212904Sdim    ObjCTypesHelper &ObjCTypes;
3496212904Sdim    PerformFragileFinally(const Stmt *S,
3497212904Sdim                          llvm::Value *SyncArgSlot,
3498212904Sdim                          llvm::Value *CallTryExitVar,
3499212904Sdim                          llvm::Value *ExceptionData,
3500212904Sdim                          ObjCTypesHelper *ObjCTypes)
3501212904Sdim      : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
3502212904Sdim        ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
3503212904Sdim
3504224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
3505212904Sdim      // Check whether we need to call objc_exception_try_exit.
3506212904Sdim      // In optimized code, this branch will always be folded.
3507212904Sdim      llvm::BasicBlock *FinallyCallExit =
3508212904Sdim        CGF.createBasicBlock("finally.call_exit");
3509212904Sdim      llvm::BasicBlock *FinallyNoCallExit =
3510212904Sdim        CGF.createBasicBlock("finally.no_call_exit");
3511212904Sdim      CGF.Builder.CreateCondBr(CGF.Builder.CreateLoad(CallTryExitVar),
3512212904Sdim                               FinallyCallExit, FinallyNoCallExit);
3513212904Sdim
3514212904Sdim      CGF.EmitBlock(FinallyCallExit);
3515249423Sdim      CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryExitFn(),
3516249423Sdim                                  ExceptionData);
3517212904Sdim
3518212904Sdim      CGF.EmitBlock(FinallyNoCallExit);
3519212904Sdim
3520212904Sdim      if (isa<ObjCAtTryStmt>(S)) {
3521212904Sdim        if (const ObjCAtFinallyStmt* FinallyStmt =
3522212904Sdim              cast<ObjCAtTryStmt>(S).getFinallyStmt()) {
3523249423Sdim          // Don't try to do the @finally if this is an EH cleanup.
3524249423Sdim          if (flags.isForEHCleanup()) return;
3525249423Sdim
3526212904Sdim          // Save the current cleanup destination in case there's
3527212904Sdim          // control flow inside the finally statement.
3528212904Sdim          llvm::Value *CurCleanupDest =
3529212904Sdim            CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot());
3530212904Sdim
3531212904Sdim          CGF.EmitStmt(FinallyStmt->getFinallyBody());
3532212904Sdim
3533212904Sdim          if (CGF.HaveInsertPoint()) {
3534212904Sdim            CGF.Builder.CreateStore(CurCleanupDest,
3535212904Sdim                                    CGF.getNormalCleanupDestSlot());
3536212904Sdim          } else {
3537212904Sdim            // Currently, the end of the cleanup must always exist.
3538212904Sdim            CGF.EnsureInsertPoint();
3539212904Sdim          }
3540212904Sdim        }
3541212904Sdim      } else {
3542212904Sdim        // Emit objc_sync_exit(expr); as finally's sole statement for
3543212904Sdim        // @synchronized.
3544212904Sdim        llvm::Value *SyncArg = CGF.Builder.CreateLoad(SyncArgSlot);
3545249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncExitFn(), SyncArg);
3546212904Sdim      }
3547212904Sdim    }
3548212904Sdim  };
3549212904Sdim
3550212904Sdim  class FragileHazards {
3551212904Sdim    CodeGenFunction &CGF;
3552226633Sdim    SmallVector<llvm::Value*, 20> Locals;
3553212904Sdim    llvm::DenseSet<llvm::BasicBlock*> BlocksBeforeTry;
3554212904Sdim
3555212904Sdim    llvm::InlineAsm *ReadHazard;
3556212904Sdim    llvm::InlineAsm *WriteHazard;
3557212904Sdim
3558212904Sdim    llvm::FunctionType *GetAsmFnType();
3559212904Sdim
3560212904Sdim    void collectLocals();
3561212904Sdim    void emitReadHazard(CGBuilderTy &Builder);
3562212904Sdim
3563212904Sdim  public:
3564212904Sdim    FragileHazards(CodeGenFunction &CGF);
3565212904Sdim
3566212904Sdim    void emitWriteHazard();
3567212904Sdim    void emitHazardsInNewBlocks();
3568212904Sdim  };
3569212904Sdim}
3570212904Sdim
3571212904Sdim/// Create the fragile-ABI read and write hazards based on the current
3572212904Sdim/// state of the function, which is presumed to be immediately prior
3573212904Sdim/// to a @try block.  These hazards are used to maintain correct
3574212904Sdim/// semantics in the face of optimization and the fragile ABI's
3575212904Sdim/// cavalier use of setjmp/longjmp.
3576212904SdimFragileHazards::FragileHazards(CodeGenFunction &CGF) : CGF(CGF) {
3577212904Sdim  collectLocals();
3578212904Sdim
3579212904Sdim  if (Locals.empty()) return;
3580212904Sdim
3581212904Sdim  // Collect all the blocks in the function.
3582212904Sdim  for (llvm::Function::iterator
3583212904Sdim         I = CGF.CurFn->begin(), E = CGF.CurFn->end(); I != E; ++I)
3584212904Sdim    BlocksBeforeTry.insert(&*I);
3585212904Sdim
3586212904Sdim  llvm::FunctionType *AsmFnTy = GetAsmFnType();
3587212904Sdim
3588212904Sdim  // Create a read hazard for the allocas.  This inhibits dead-store
3589212904Sdim  // optimizations and forces the values to memory.  This hazard is
3590212904Sdim  // inserted before any 'throwing' calls in the protected scope to
3591212904Sdim  // reflect the possibility that the variables might be read from the
3592212904Sdim  // catch block if the call throws.
3593212904Sdim  {
3594212904Sdim    std::string Constraint;
3595212904Sdim    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3596212904Sdim      if (I) Constraint += ',';
3597212904Sdim      Constraint += "*m";
3598212904Sdim    }
3599212904Sdim
3600212904Sdim    ReadHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3601212904Sdim  }
3602212904Sdim
3603212904Sdim  // Create a write hazard for the allocas.  This inhibits folding
3604212904Sdim  // loads across the hazard.  This hazard is inserted at the
3605212904Sdim  // beginning of the catch path to reflect the possibility that the
3606212904Sdim  // variables might have been written within the protected scope.
3607212904Sdim  {
3608212904Sdim    std::string Constraint;
3609212904Sdim    for (unsigned I = 0, E = Locals.size(); I != E; ++I) {
3610212904Sdim      if (I) Constraint += ',';
3611212904Sdim      Constraint += "=*m";
3612212904Sdim    }
3613212904Sdim
3614212904Sdim    WriteHazard = llvm::InlineAsm::get(AsmFnTy, "", Constraint, true, false);
3615212904Sdim  }
3616212904Sdim}
3617212904Sdim
3618212904Sdim/// Emit a write hazard at the current location.
3619212904Sdimvoid FragileHazards::emitWriteHazard() {
3620212904Sdim  if (Locals.empty()) return;
3621212904Sdim
3622249423Sdim  CGF.EmitNounwindRuntimeCall(WriteHazard, Locals);
3623212904Sdim}
3624212904Sdim
3625212904Sdimvoid FragileHazards::emitReadHazard(CGBuilderTy &Builder) {
3626212904Sdim  assert(!Locals.empty());
3627249423Sdim  llvm::CallInst *call = Builder.CreateCall(ReadHazard, Locals);
3628249423Sdim  call->setDoesNotThrow();
3629249423Sdim  call->setCallingConv(CGF.getRuntimeCC());
3630212904Sdim}
3631212904Sdim
3632212904Sdim/// Emit read hazards in all the protected blocks, i.e. all the blocks
3633212904Sdim/// which have been inserted since the beginning of the try.
3634212904Sdimvoid FragileHazards::emitHazardsInNewBlocks() {
3635212904Sdim  if (Locals.empty()) return;
3636212904Sdim
3637212904Sdim  CGBuilderTy Builder(CGF.getLLVMContext());
3638212904Sdim
3639212904Sdim  // Iterate through all blocks, skipping those prior to the try.
3640212904Sdim  for (llvm::Function::iterator
3641212904Sdim         FI = CGF.CurFn->begin(), FE = CGF.CurFn->end(); FI != FE; ++FI) {
3642212904Sdim    llvm::BasicBlock &BB = *FI;
3643212904Sdim    if (BlocksBeforeTry.count(&BB)) continue;
3644212904Sdim
3645212904Sdim    // Walk through all the calls in the block.
3646212904Sdim    for (llvm::BasicBlock::iterator
3647212904Sdim           BI = BB.begin(), BE = BB.end(); BI != BE; ++BI) {
3648212904Sdim      llvm::Instruction &I = *BI;
3649212904Sdim
3650212904Sdim      // Ignore instructions that aren't non-intrinsic calls.
3651212904Sdim      // These are the only calls that can possibly call longjmp.
3652212904Sdim      if (!isa<llvm::CallInst>(I) && !isa<llvm::InvokeInst>(I)) continue;
3653212904Sdim      if (isa<llvm::IntrinsicInst>(I))
3654212904Sdim        continue;
3655212904Sdim
3656212904Sdim      // Ignore call sites marked nounwind.  This may be questionable,
3657212904Sdim      // since 'nounwind' doesn't necessarily mean 'does not call longjmp'.
3658212904Sdim      llvm::CallSite CS(&I);
3659212904Sdim      if (CS.doesNotThrow()) continue;
3660212904Sdim
3661212904Sdim      // Insert a read hazard before the call.  This will ensure that
3662212904Sdim      // any writes to the locals are performed before making the
3663212904Sdim      // call.  If the call throws, then this is sufficient to
3664212904Sdim      // guarantee correctness as long as it doesn't also write to any
3665212904Sdim      // locals.
3666212904Sdim      Builder.SetInsertPoint(&BB, BI);
3667212904Sdim      emitReadHazard(Builder);
3668212904Sdim    }
3669212904Sdim  }
3670212904Sdim}
3671212904Sdim
3672212904Sdimstatic void addIfPresent(llvm::DenseSet<llvm::Value*> &S, llvm::Value *V) {
3673212904Sdim  if (V) S.insert(V);
3674212904Sdim}
3675212904Sdim
3676212904Sdimvoid FragileHazards::collectLocals() {
3677212904Sdim  // Compute a set of allocas to ignore.
3678212904Sdim  llvm::DenseSet<llvm::Value*> AllocasToIgnore;
3679212904Sdim  addIfPresent(AllocasToIgnore, CGF.ReturnValue);
3680212904Sdim  addIfPresent(AllocasToIgnore, CGF.NormalCleanupDest);
3681212904Sdim
3682212904Sdim  // Collect all the allocas currently in the function.  This is
3683212904Sdim  // probably way too aggressive.
3684212904Sdim  llvm::BasicBlock &Entry = CGF.CurFn->getEntryBlock();
3685212904Sdim  for (llvm::BasicBlock::iterator
3686212904Sdim         I = Entry.begin(), E = Entry.end(); I != E; ++I)
3687212904Sdim    if (isa<llvm::AllocaInst>(*I) && !AllocasToIgnore.count(&*I))
3688212904Sdim      Locals.push_back(&*I);
3689212904Sdim}
3690212904Sdim
3691212904Sdimllvm::FunctionType *FragileHazards::GetAsmFnType() {
3692226633Sdim  SmallVector<llvm::Type *, 16> tys(Locals.size());
3693223017Sdim  for (unsigned i = 0, e = Locals.size(); i != e; ++i)
3694223017Sdim    tys[i] = Locals[i]->getType();
3695223017Sdim  return llvm::FunctionType::get(CGF.VoidTy, tys, false);
3696212904Sdim}
3697212904Sdim
3698198092Srdivacky/*
3699193326Sed
3700198092Srdivacky  Objective-C setjmp-longjmp (sjlj) Exception Handling
3701198092Srdivacky  --
3702193326Sed
3703210299Sed  A catch buffer is a setjmp buffer plus:
3704210299Sed    - a pointer to the exception that was caught
3705210299Sed    - a pointer to the previous exception data buffer
3706210299Sed    - two pointers of reserved storage
3707210299Sed  Therefore catch buffers form a stack, with a pointer to the top
3708210299Sed  of the stack kept in thread-local storage.
3709210299Sed
3710210299Sed  objc_exception_try_enter pushes a catch buffer onto the EH stack.
3711210299Sed  objc_exception_try_exit pops the given catch buffer, which is
3712210299Sed    required to be the top of the EH stack.
3713210299Sed  objc_exception_throw pops the top of the EH stack, writes the
3714210299Sed    thrown exception into the appropriate field, and longjmps
3715210299Sed    to the setjmp buffer.  It crashes the process (with a printf
3716210299Sed    and an abort()) if there are no catch buffers on the stack.
3717210299Sed  objc_exception_extract just reads the exception pointer out of the
3718210299Sed    catch buffer.
3719210299Sed
3720210299Sed  There's no reason an implementation couldn't use a light-weight
3721210299Sed  setjmp here --- something like __builtin_setjmp, but API-compatible
3722210299Sed  with the heavyweight setjmp.  This will be more important if we ever
3723210299Sed  want to implement correct ObjC/C++ exception interactions for the
3724210299Sed  fragile ABI.
3725210299Sed
3726210299Sed  Note that for this use of setjmp/longjmp to be correct, we may need
3727210299Sed  to mark some local variables volatile: if a non-volatile local
3728210299Sed  variable is modified between the setjmp and the longjmp, it has
3729210299Sed  indeterminate value.  For the purposes of LLVM IR, it may be
3730210299Sed  sufficient to make loads and stores within the @try (to variables
3731210299Sed  declared outside the @try) volatile.  This is necessary for
3732210299Sed  optimized correctness, but is not currently being done; this is
3733210299Sed  being tracked as rdar://problem/8160285
3734210299Sed
3735198092Srdivacky  The basic framework for a @try-catch-finally is as follows:
3736198092Srdivacky  {
3737193326Sed  objc_exception_data d;
3738193326Sed  id _rethrow = null;
3739193326Sed  bool _call_try_exit = true;
3740198092Srdivacky
3741193326Sed  objc_exception_try_enter(&d);
3742193326Sed  if (!setjmp(d.jmp_buf)) {
3743198092Srdivacky  ... try body ...
3744193326Sed  } else {
3745198092Srdivacky  // exception path
3746198092Srdivacky  id _caught = objc_exception_extract(&d);
3747198092Srdivacky
3748198092Srdivacky  // enter new try scope for handlers
3749198092Srdivacky  if (!setjmp(d.jmp_buf)) {
3750198092Srdivacky  ... match exception and execute catch blocks ...
3751198092Srdivacky
3752198092Srdivacky  // fell off end, rethrow.
3753198092Srdivacky  _rethrow = _caught;
3754198092Srdivacky  ... jump-through-finally to finally_rethrow ...
3755198092Srdivacky  } else {
3756198092Srdivacky  // exception in catch block
3757198092Srdivacky  _rethrow = objc_exception_extract(&d);
3758198092Srdivacky  _call_try_exit = false;
3759198092Srdivacky  ... jump-through-finally to finally_rethrow ...
3760193326Sed  }
3761198092Srdivacky  }
3762193326Sed  ... jump-through-finally to finally_end ...
3763193326Sed
3764198092Srdivacky  finally:
3765193326Sed  if (_call_try_exit)
3766198092Srdivacky  objc_exception_try_exit(&d);
3767193326Sed
3768193326Sed  ... finally block ....
3769193326Sed  ... dispatch to finally destination ...
3770193326Sed
3771198092Srdivacky  finally_rethrow:
3772193326Sed  objc_exception_throw(_rethrow);
3773193326Sed
3774198092Srdivacky  finally_end:
3775198092Srdivacky  }
3776193326Sed
3777198092Srdivacky  This framework differs slightly from the one gcc uses, in that gcc
3778198092Srdivacky  uses _rethrow to determine if objc_exception_try_exit should be called
3779198092Srdivacky  and if the object should be rethrown. This breaks in the face of
3780198092Srdivacky  throwing nil and introduces unnecessary branches.
3781193326Sed
3782198092Srdivacky  We specialize this framework for a few particular circumstances:
3783193326Sed
3784198092Srdivacky  - If there are no catch blocks, then we avoid emitting the second
3785198092Srdivacky  exception handling context.
3786193326Sed
3787198092Srdivacky  - If there is a catch-all catch block (i.e. @catch(...) or @catch(id
3788198092Srdivacky  e)) we avoid emitting the code to rethrow an uncaught exception.
3789193326Sed
3790198092Srdivacky  - FIXME: If there is no @finally block we can do a few more
3791198092Srdivacky  simplifications.
3792193326Sed
3793198092Srdivacky  Rethrows and Jumps-Through-Finally
3794198092Srdivacky  --
3795193326Sed
3796210299Sed  '@throw;' is supported by pushing the currently-caught exception
3797210299Sed  onto ObjCEHStack while the @catch blocks are emitted.
3798193326Sed
3799210299Sed  Branches through the @finally block are handled with an ordinary
3800210299Sed  normal cleanup.  We do not register an EH cleanup; fragile-ABI ObjC
3801210299Sed  exceptions are not compatible with C++ exceptions, and this is
3802210299Sed  hardly the only place where this will go wrong.
3803193326Sed
3804210299Sed  @synchronized(expr) { stmt; } is emitted as if it were:
3805210299Sed    id synch_value = expr;
3806210299Sed    objc_sync_enter(synch_value);
3807210299Sed    @try { stmt; } @finally { objc_sync_exit(synch_value); }
3808193326Sed*/
3809193326Sed
3810193326Sedvoid CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
3811193326Sed                                          const Stmt &S) {
3812193326Sed  bool isTry = isa<ObjCAtTryStmt>(S);
3813198092Srdivacky
3814210299Sed  // A destination for the fall-through edges of the catch handlers to
3815210299Sed  // jump to.
3816210299Sed  CodeGenFunction::JumpDest FinallyEnd =
3817210299Sed    CGF.getJumpDestInCurrentScope("finally.end");
3818210299Sed
3819210299Sed  // A destination for the rethrow edge of the catch handlers to jump
3820210299Sed  // to.
3821210299Sed  CodeGenFunction::JumpDest FinallyRethrow =
3822210299Sed    CGF.getJumpDestInCurrentScope("finally.rethrow");
3823210299Sed
3824193326Sed  // For @synchronized, call objc_sync_enter(sync.expr). The
3825193326Sed  // evaluation of the expression must occur before we enter the
3826212904Sdim  // @synchronized.  We can't avoid a temp here because we need the
3827212904Sdim  // value to be preserved.  If the backend ever does liveness
3828212904Sdim  // correctly after setjmp, this will be unnecessary.
3829212904Sdim  llvm::Value *SyncArgSlot = 0;
3830193326Sed  if (!isTry) {
3831212904Sdim    llvm::Value *SyncArg =
3832193326Sed      CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
3833193326Sed    SyncArg = CGF.Builder.CreateBitCast(SyncArg, ObjCTypes.ObjectPtrTy);
3834249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getSyncEnterFn(), SyncArg);
3835212904Sdim
3836212904Sdim    SyncArgSlot = CGF.CreateTempAlloca(SyncArg->getType(), "sync.arg");
3837212904Sdim    CGF.Builder.CreateStore(SyncArg, SyncArgSlot);
3838193326Sed  }
3839193326Sed
3840212904Sdim  // Allocate memory for the setjmp buffer.  This needs to be kept
3841212904Sdim  // live throughout the try and catch blocks.
3842193326Sed  llvm::Value *ExceptionData = CGF.CreateTempAlloca(ObjCTypes.ExceptionDataTy,
3843193326Sed                                                    "exceptiondata.ptr");
3844210299Sed
3845212904Sdim  // Create the fragile hazards.  Note that this will not capture any
3846212904Sdim  // of the allocas required for exception processing, but will
3847212904Sdim  // capture the current basic block (which extends all the way to the
3848212904Sdim  // setjmp call) as "before the @try".
3849212904Sdim  FragileHazards Hazards(CGF);
3850212904Sdim
3851210299Sed  // Create a flag indicating whether the cleanup needs to call
3852210299Sed  // objc_exception_try_exit.  This is true except when
3853210299Sed  //   - no catches match and we're branching through the cleanup
3854210299Sed  //     just to rethrow the exception, or
3855210299Sed  //   - a catch matched and we're falling out of the catch handler.
3856212904Sdim  // The setjmp-safety rule here is that we should always store to this
3857212904Sdim  // variable in a place that dominates the branch through the cleanup
3858212904Sdim  // without passing through any setjmps.
3859210299Sed  llvm::Value *CallTryExitVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(),
3860193326Sed                                                     "_call_try_exit");
3861198092Srdivacky
3862218893Sdim  // A slot containing the exception to rethrow.  Only needed when we
3863218893Sdim  // have both a @catch and a @finally.
3864218893Sdim  llvm::Value *PropagatingExnVar = 0;
3865218893Sdim
3866210299Sed  // Push a normal cleanup to leave the try scope.
3867249423Sdim  CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
3868212904Sdim                                                 SyncArgSlot,
3869212904Sdim                                                 CallTryExitVar,
3870212904Sdim                                                 ExceptionData,
3871212904Sdim                                                 &ObjCTypes);
3872193326Sed
3873210299Sed  // Enter a try block:
3874210299Sed  //  - Call objc_exception_try_enter to push ExceptionData on top of
3875210299Sed  //    the EH stack.
3876249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(), ExceptionData);
3877210299Sed
3878210299Sed  //  - Call setjmp on the exception data buffer.
3879210299Sed  llvm::Constant *Zero = llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
3880210299Sed  llvm::Value *GEPIndexes[] = { Zero, Zero, Zero };
3881210299Sed  llvm::Value *SetJmpBuffer =
3882226633Sdim    CGF.Builder.CreateGEP(ExceptionData, GEPIndexes, "setjmp_buffer");
3883210299Sed  llvm::CallInst *SetJmpResult =
3884249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(), SetJmpBuffer, "setjmp_result");
3885234353Sdim  SetJmpResult->setCanReturnTwice();
3886210299Sed
3887210299Sed  // If setjmp returned 0, enter the protected block; otherwise,
3888210299Sed  // branch to the handler.
3889193326Sed  llvm::BasicBlock *TryBlock = CGF.createBasicBlock("try");
3890193326Sed  llvm::BasicBlock *TryHandler = CGF.createBasicBlock("try.handler");
3891210299Sed  llvm::Value *DidCatch =
3892212904Sdim    CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3893212904Sdim  CGF.Builder.CreateCondBr(DidCatch, TryHandler, TryBlock);
3894193326Sed
3895210299Sed  // Emit the protected block.
3896193326Sed  CGF.EmitBlock(TryBlock);
3897212904Sdim  CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
3898198092Srdivacky  CGF.EmitStmt(isTry ? cast<ObjCAtTryStmt>(S).getTryBody()
3899210299Sed                     : cast<ObjCAtSynchronizedStmt>(S).getSynchBody());
3900198092Srdivacky
3901212904Sdim  CGBuilderTy::InsertPoint TryFallthroughIP = CGF.Builder.saveAndClearIP();
3902212904Sdim
3903210299Sed  // Emit the exception handler block.
3904193326Sed  CGF.EmitBlock(TryHandler);
3905193326Sed
3906212904Sdim  // Don't optimize loads of the in-scope locals across this point.
3907212904Sdim  Hazards.emitWriteHazard();
3908210299Sed
3909210299Sed  // For a @synchronized (or a @try with no catches), just branch
3910210299Sed  // through the cleanup to the rethrow block.
3911210299Sed  if (!isTry || !cast<ObjCAtTryStmt>(S).getNumCatchStmts()) {
3912210299Sed    // Tell the cleanup not to re-pop the exit.
3913212904Sdim    CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
3914193326Sed    CGF.EmitBranchThroughCleanup(FinallyRethrow);
3915210299Sed
3916210299Sed  // Otherwise, we have to match against the caught exceptions.
3917210299Sed  } else {
3918212904Sdim    // Retrieve the exception object.  We may emit multiple blocks but
3919212904Sdim    // nothing can cross this so the value is already in SSA form.
3920212904Sdim    llvm::CallInst *Caught =
3921249423Sdim      CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
3922249423Sdim                                  ExceptionData, "caught");
3923212904Sdim
3924210299Sed    // Push the exception to rethrow onto the EH value stack for the
3925210299Sed    // benefit of any @throws in the handlers.
3926210299Sed    CGF.ObjCEHValueStack.push_back(Caught);
3927210299Sed
3928207619Srdivacky    const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
3929198092Srdivacky
3930212904Sdim    bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
3931193326Sed
3932212904Sdim    llvm::BasicBlock *CatchBlock = 0;
3933212904Sdim    llvm::BasicBlock *CatchHandler = 0;
3934212904Sdim    if (HasFinally) {
3935218893Sdim      // Save the currently-propagating exception before
3936218893Sdim      // objc_exception_try_enter clears the exception slot.
3937218893Sdim      PropagatingExnVar = CGF.CreateTempAlloca(Caught->getType(),
3938218893Sdim                                               "propagating_exception");
3939218893Sdim      CGF.Builder.CreateStore(Caught, PropagatingExnVar);
3940218893Sdim
3941212904Sdim      // Enter a new exception try block (in case a @catch block
3942212904Sdim      // throws an exception).
3943249423Sdim      CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionTryEnterFn(),
3944249423Sdim                                  ExceptionData);
3945210299Sed
3946212904Sdim      llvm::CallInst *SetJmpResult =
3947249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getSetJmpFn(),
3948249423Sdim                                    SetJmpBuffer, "setjmp.result");
3949234353Sdim      SetJmpResult->setCanReturnTwice();
3950198092Srdivacky
3951212904Sdim      llvm::Value *Threw =
3952212904Sdim        CGF.Builder.CreateIsNotNull(SetJmpResult, "did_catch_exception");
3953198092Srdivacky
3954212904Sdim      CatchBlock = CGF.createBasicBlock("catch");
3955212904Sdim      CatchHandler = CGF.createBasicBlock("catch_for_catch");
3956212904Sdim      CGF.Builder.CreateCondBr(Threw, CatchHandler, CatchBlock);
3957212904Sdim
3958212904Sdim      CGF.EmitBlock(CatchBlock);
3959212904Sdim    }
3960212904Sdim
3961212904Sdim    CGF.Builder.CreateStore(CGF.Builder.getInt1(HasFinally), CallTryExitVar);
3962212904Sdim
3963193326Sed    // Handle catch list. As a special case we check if everything is
3964193326Sed    // matched and avoid generating code for falling off the end if
3965193326Sed    // so.
3966193326Sed    bool AllMatched = false;
3967207619Srdivacky    for (unsigned I = 0, N = AtTryStmt->getNumCatchStmts(); I != N; ++I) {
3968207619Srdivacky      const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
3969193326Sed
3970207619Srdivacky      const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
3971198092Srdivacky      const ObjCObjectPointerType *OPT = 0;
3972193326Sed
3973193326Sed      // catch(...) always matches.
3974193326Sed      if (!CatchParam) {
3975193326Sed        AllMatched = true;
3976193326Sed      } else {
3977198092Srdivacky        OPT = CatchParam->getType()->getAs<ObjCObjectPointerType>();
3978198092Srdivacky
3979210299Sed        // catch(id e) always matches under this ABI, since only
3980210299Sed        // ObjC exceptions end up here in the first place.
3981193326Sed        // FIXME: For the time being we also match id<X>; this should
3982193326Sed        // be rejected by Sema instead.
3983198092Srdivacky        if (OPT && (OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()))
3984193326Sed          AllMatched = true;
3985193326Sed      }
3986198092Srdivacky
3987210299Sed      // If this is a catch-all, we don't need to test anything.
3988198092Srdivacky      if (AllMatched) {
3989210299Sed        CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
3990210299Sed
3991193326Sed        if (CatchParam) {
3992218893Sdim          CGF.EmitAutoVarDecl(*CatchParam);
3993193326Sed          assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
3994210299Sed
3995210299Sed          // These types work out because ConvertType(id) == i8*.
3996193326Sed          CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(CatchParam));
3997193326Sed        }
3998198092Srdivacky
3999193326Sed        CGF.EmitStmt(CatchStmt->getCatchBody());
4000210299Sed
4001210299Sed        // The scope of the catch variable ends right here.
4002210299Sed        CatchVarCleanups.ForceCleanup();
4003210299Sed
4004193326Sed        CGF.EmitBranchThroughCleanup(FinallyEnd);
4005193326Sed        break;
4006193326Sed      }
4007198092Srdivacky
4008198092Srdivacky      assert(OPT && "Unexpected non-object pointer type in @catch");
4009208600Srdivacky      const ObjCObjectType *ObjTy = OPT->getObjectType();
4010210299Sed
4011210299Sed      // FIXME: @catch (Class c) ?
4012208600Srdivacky      ObjCInterfaceDecl *IDecl = ObjTy->getInterface();
4013208600Srdivacky      assert(IDecl && "Catch parameter must have Objective-C type!");
4014193326Sed
4015193326Sed      // Check if the @catch block matches the exception object.
4016249423Sdim      llvm::Value *Class = EmitClassRef(CGF, IDecl);
4017198092Srdivacky
4018249423Sdim      llvm::Value *matchArgs[] = { Class, Caught };
4019210299Sed      llvm::CallInst *Match =
4020249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionMatchFn(),
4021249423Sdim                                    matchArgs, "match");
4022198092Srdivacky
4023210299Sed      llvm::BasicBlock *MatchedBlock = CGF.createBasicBlock("match");
4024210299Sed      llvm::BasicBlock *NextCatchBlock = CGF.createBasicBlock("catch.next");
4025198092Srdivacky
4026198092Srdivacky      CGF.Builder.CreateCondBr(CGF.Builder.CreateIsNotNull(Match, "matched"),
4027193326Sed                               MatchedBlock, NextCatchBlock);
4028198092Srdivacky
4029193326Sed      // Emit the @catch block.
4030193326Sed      CGF.EmitBlock(MatchedBlock);
4031210299Sed
4032210299Sed      // Collect any cleanups for the catch variable.  The scope lasts until
4033210299Sed      // the end of the catch body.
4034212904Sdim      CodeGenFunction::RunCleanupsScope CatchVarCleanups(CGF);
4035210299Sed
4036218893Sdim      CGF.EmitAutoVarDecl(*CatchParam);
4037193326Sed      assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
4038193326Sed
4039210299Sed      // Initialize the catch variable.
4040198092Srdivacky      llvm::Value *Tmp =
4041198092Srdivacky        CGF.Builder.CreateBitCast(Caught,
4042226633Sdim                                  CGF.ConvertType(CatchParam->getType()));
4043193326Sed      CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(CatchParam));
4044198092Srdivacky
4045193326Sed      CGF.EmitStmt(CatchStmt->getCatchBody());
4046210299Sed
4047210299Sed      // We're done with the catch variable.
4048210299Sed      CatchVarCleanups.ForceCleanup();
4049210299Sed
4050193326Sed      CGF.EmitBranchThroughCleanup(FinallyEnd);
4051198092Srdivacky
4052193326Sed      CGF.EmitBlock(NextCatchBlock);
4053193326Sed    }
4054193326Sed
4055210299Sed    CGF.ObjCEHValueStack.pop_back();
4056210299Sed
4057212904Sdim    // If nothing wanted anything to do with the caught exception,
4058212904Sdim    // kill the extract call.
4059212904Sdim    if (Caught->use_empty())
4060212904Sdim      Caught->eraseFromParent();
4061212904Sdim
4062212904Sdim    if (!AllMatched)
4063193326Sed      CGF.EmitBranchThroughCleanup(FinallyRethrow);
4064198092Srdivacky
4065212904Sdim    if (HasFinally) {
4066212904Sdim      // Emit the exception handler for the @catch blocks.
4067212904Sdim      CGF.EmitBlock(CatchHandler);
4068210299Sed
4069212904Sdim      // In theory we might now need a write hazard, but actually it's
4070212904Sdim      // unnecessary because there's no local-accessing code between
4071212904Sdim      // the try's write hazard and here.
4072212904Sdim      //Hazards.emitWriteHazard();
4073210299Sed
4074218893Sdim      // Extract the new exception and save it to the
4075218893Sdim      // propagating-exception slot.
4076218893Sdim      assert(PropagatingExnVar);
4077218893Sdim      llvm::CallInst *NewCaught =
4078249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4079249423Sdim                                    ExceptionData, "caught");
4080218893Sdim      CGF.Builder.CreateStore(NewCaught, PropagatingExnVar);
4081218893Sdim
4082212904Sdim      // Don't pop the catch handler; the throw already did.
4083212904Sdim      CGF.Builder.CreateStore(CGF.Builder.getFalse(), CallTryExitVar);
4084212904Sdim      CGF.EmitBranchThroughCleanup(FinallyRethrow);
4085212904Sdim    }
4086193326Sed  }
4087198092Srdivacky
4088212904Sdim  // Insert read hazards as required in the new blocks.
4089212904Sdim  Hazards.emitHazardsInNewBlocks();
4090212904Sdim
4091210299Sed  // Pop the cleanup.
4092212904Sdim  CGF.Builder.restoreIP(TryFallthroughIP);
4093212904Sdim  if (CGF.HaveInsertPoint())
4094212904Sdim    CGF.Builder.CreateStore(CGF.Builder.getTrue(), CallTryExitVar);
4095210299Sed  CGF.PopCleanupBlock();
4096212904Sdim  CGF.EmitBlock(FinallyEnd.getBlock(), true);
4097193326Sed
4098210299Sed  // Emit the rethrow block.
4099212904Sdim  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
4100212904Sdim  CGF.EmitBlock(FinallyRethrow.getBlock(), true);
4101210299Sed  if (CGF.HaveInsertPoint()) {
4102218893Sdim    // If we have a propagating-exception variable, check it.
4103218893Sdim    llvm::Value *PropagatingExn;
4104218893Sdim    if (PropagatingExnVar) {
4105218893Sdim      PropagatingExn = CGF.Builder.CreateLoad(PropagatingExnVar);
4106212904Sdim
4107218893Sdim    // Otherwise, just look in the buffer for the exception to throw.
4108218893Sdim    } else {
4109218893Sdim      llvm::CallInst *Caught =
4110249423Sdim        CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionExtractFn(),
4111249423Sdim                                    ExceptionData);
4112218893Sdim      PropagatingExn = Caught;
4113218893Sdim    }
4114218893Sdim
4115249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getExceptionThrowFn(),
4116249423Sdim                                PropagatingExn);
4117210299Sed    CGF.Builder.CreateUnreachable();
4118193326Sed  }
4119193326Sed
4120212904Sdim  CGF.Builder.restoreIP(SavedIP);
4121193326Sed}
4122193326Sed
4123193326Sedvoid CGObjCMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
4124249423Sdim                              const ObjCAtThrowStmt &S,
4125249423Sdim                              bool ClearInsertionPoint) {
4126193326Sed  llvm::Value *ExceptionAsObject;
4127198092Srdivacky
4128193326Sed  if (const Expr *ThrowExpr = S.getThrowExpr()) {
4129226633Sdim    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
4130198092Srdivacky    ExceptionAsObject =
4131226633Sdim      CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
4132193326Sed  } else {
4133198092Srdivacky    assert((!CGF.ObjCEHValueStack.empty() && CGF.ObjCEHValueStack.back()) &&
4134193326Sed           "Unexpected rethrow outside @catch block.");
4135193326Sed    ExceptionAsObject = CGF.ObjCEHValueStack.back();
4136193326Sed  }
4137198092Srdivacky
4138249423Sdim  CGF.EmitRuntimeCall(ObjCTypes.getExceptionThrowFn(), ExceptionAsObject)
4139210299Sed    ->setDoesNotReturn();
4140193326Sed  CGF.Builder.CreateUnreachable();
4141193326Sed
4142193326Sed  // Clear the insertion point to indicate we are in unreachable code.
4143249423Sdim  if (ClearInsertionPoint)
4144249423Sdim    CGF.Builder.ClearInsertionPoint();
4145193326Sed}
4146193326Sed
4147193326Sed/// EmitObjCWeakRead - Code gen for loading value of a __weak
4148193326Sed/// object: objc_read_weak (id *src)
4149193326Sed///
4150193326Sedllvm::Value * CGObjCMac::EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
4151198092Srdivacky                                          llvm::Value *AddrWeakObj) {
4152226633Sdim  llvm::Type* DestTy =
4153198092Srdivacky    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
4154198092Srdivacky  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj,
4155198092Srdivacky                                          ObjCTypes.PtrObjectPtrTy);
4156249423Sdim  llvm::Value *read_weak =
4157249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
4158249423Sdim                                AddrWeakObj, "weakread");
4159193326Sed  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
4160193326Sed  return read_weak;
4161193326Sed}
4162193326Sed
4163193326Sed/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
4164193326Sed/// objc_assign_weak (id src, id *dst)
4165193326Sed///
4166193326Sedvoid CGObjCMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
4167198092Srdivacky                                   llvm::Value *src, llvm::Value *dst) {
4168226633Sdim  llvm::Type * SrcTy = src->getType();
4169193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
4170243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4171193326Sed    assert(Size <= 8 && "does not support size > 8");
4172193326Sed    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4173198092Srdivacky      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4174193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4175193326Sed  }
4176193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4177193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4178249423Sdim  llvm::Value *args[] = { src, dst };
4179249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
4180249423Sdim                              args, "weakassign");
4181193326Sed  return;
4182193326Sed}
4183193326Sed
4184193326Sed/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
4185193326Sed/// objc_assign_global (id src, id *dst)
4186193326Sed///
4187193326Sedvoid CGObjCMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
4188212904Sdim                                     llvm::Value *src, llvm::Value *dst,
4189212904Sdim                                     bool threadlocal) {
4190226633Sdim  llvm::Type * SrcTy = src->getType();
4191193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
4192243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4193193326Sed    assert(Size <= 8 && "does not support size > 8");
4194193326Sed    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4195198092Srdivacky      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4196193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4197193326Sed  }
4198193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4199193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4200249423Sdim  llvm::Value *args[] = { src, dst };
4201212904Sdim  if (!threadlocal)
4202249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
4203249423Sdim                                args, "globalassign");
4204212904Sdim  else
4205249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
4206249423Sdim                                args, "threadlocalassign");
4207193326Sed  return;
4208193326Sed}
4209193326Sed
4210193326Sed/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
4211198092Srdivacky/// objc_assign_ivar (id src, id *dst, ptrdiff_t ivaroffset)
4212193326Sed///
4213193326Sedvoid CGObjCMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
4214198092Srdivacky                                   llvm::Value *src, llvm::Value *dst,
4215198092Srdivacky                                   llvm::Value *ivarOffset) {
4216198092Srdivacky  assert(ivarOffset && "EmitObjCIvarAssign - ivarOffset is NULL");
4217226633Sdim  llvm::Type * SrcTy = src->getType();
4218193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
4219243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4220193326Sed    assert(Size <= 8 && "does not support size > 8");
4221193326Sed    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4222198092Srdivacky      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4223193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4224193326Sed  }
4225193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4226193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4227249423Sdim  llvm::Value *args[] = { src, dst, ivarOffset };
4228249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
4229193326Sed  return;
4230193326Sed}
4231193326Sed
4232193326Sed/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
4233193326Sed/// objc_assign_strongCast (id src, id *dst)
4234193326Sed///
4235193326Sedvoid CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
4236198092Srdivacky                                         llvm::Value *src, llvm::Value *dst) {
4237226633Sdim  llvm::Type * SrcTy = src->getType();
4238193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
4239243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
4240193326Sed    assert(Size <= 8 && "does not support size > 8");
4241193326Sed    src = (Size == 4) ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
4242198092Srdivacky      : CGF.Builder.CreateBitCast(src, ObjCTypes.LongLongTy);
4243193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
4244193326Sed  }
4245193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
4246193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
4247249423Sdim  llvm::Value *args[] = { src, dst };
4248249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
4249249423Sdim                              args, "weakassign");
4250193326Sed  return;
4251193326Sed}
4252193326Sed
4253198092Srdivackyvoid CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
4254198092Srdivacky                                         llvm::Value *DestPtr,
4255198092Srdivacky                                         llvm::Value *SrcPtr,
4256210299Sed                                         llvm::Value *size) {
4257198092Srdivacky  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
4258198092Srdivacky  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
4259249423Sdim  llvm::Value *args[] = { DestPtr, SrcPtr, size };
4260249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
4261198092Srdivacky}
4262198092Srdivacky
4263193326Sed/// EmitObjCValueForIvar - Code Gen for ivar reference.
4264193326Sed///
4265193326SedLValue CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
4266193326Sed                                       QualType ObjectTy,
4267193326Sed                                       llvm::Value *BaseValue,
4268193326Sed                                       const ObjCIvarDecl *Ivar,
4269193326Sed                                       unsigned CVRQualifiers) {
4270208600Srdivacky  const ObjCInterfaceDecl *ID =
4271208600Srdivacky    ObjectTy->getAs<ObjCObjectType>()->getInterface();
4272193326Sed  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
4273193326Sed                                  EmitIvarOffset(CGF, ID, Ivar));
4274193326Sed}
4275193326Sed
4276193326Sedllvm::Value *CGObjCMac::EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
4277193326Sed                                       const ObjCInterfaceDecl *Interface,
4278193326Sed                                       const ObjCIvarDecl *Ivar) {
4279193326Sed  uint64_t Offset = ComputeIvarBaseOffset(CGM, Interface, Ivar);
4280193326Sed  return llvm::ConstantInt::get(
4281198092Srdivacky    CGM.getTypes().ConvertType(CGM.getContext().LongTy),
4282198092Srdivacky    Offset);
4283193326Sed}
4284193326Sed
4285193326Sed/* *** Private Interface *** */
4286193326Sed
4287193326Sed/// EmitImageInfo - Emit the image info marker used to encode some module
4288193326Sed/// level information.
4289193326Sed///
4290193326Sed/// See: <rdr://4810609&4810587&4810587>
4291193326Sed/// struct IMAGE_INFO {
4292193326Sed///   unsigned version;
4293193326Sed///   unsigned flags;
4294193326Sed/// };
4295193326Sedenum ImageInfoFlags {
4296207619Srdivacky  eImageInfo_FixAndContinue      = (1 << 0),
4297198092Srdivacky  eImageInfo_GarbageCollected    = (1 << 1),
4298198092Srdivacky  eImageInfo_GCOnly              = (1 << 2),
4299193326Sed  eImageInfo_OptimizedByDyld     = (1 << 3), // FIXME: When is this set.
4300193326Sed
4301207619Srdivacky  // A flag indicating that the module has no instances of a @synthesize of a
4302207619Srdivacky  // superclass variable. <rdar://problem/6803242>
4303239462Sdim  eImageInfo_CorrectedSynthesize = (1 << 4),
4304239462Sdim  eImageInfo_ImageIsSimulated    = (1 << 5)
4305193326Sed};
4306193326Sed
4307207619Srdivackyvoid CGObjCCommonMac::EmitImageInfo() {
4308193326Sed  unsigned version = 0; // Version is unused?
4309234353Sdim  const char *Section = (ObjCABI == 1) ?
4310234353Sdim    "__OBJC, __image_info,regular" :
4311234353Sdim    "__DATA, __objc_imageinfo, regular, no_dead_strip";
4312193326Sed
4313234353Sdim  // Generate module-level named metadata to convey this information to the
4314234353Sdim  // linker and code-gen.
4315234353Sdim  llvm::Module &Mod = CGM.getModule();
4316198092Srdivacky
4317234353Sdim  // Add the ObjC ABI version to the module flags.
4318234353Sdim  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Version", ObjCABI);
4319234353Sdim  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Version",
4320234353Sdim                    version);
4321234353Sdim  Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
4322234353Sdim                    llvm::MDString::get(VMContext,Section));
4323193326Sed
4324234353Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
4325234353Sdim    // Non-GC overrides those files which specify GC.
4326234353Sdim    Mod.addModuleFlag(llvm::Module::Override,
4327234353Sdim                      "Objective-C Garbage Collection", (uint32_t)0);
4328234353Sdim  } else {
4329234353Sdim    // Add the ObjC garbage collection value.
4330234353Sdim    Mod.addModuleFlag(llvm::Module::Error,
4331234353Sdim                      "Objective-C Garbage Collection",
4332234353Sdim                      eImageInfo_GarbageCollected);
4333193326Sed
4334234353Sdim    if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
4335234353Sdim      // Add the ObjC GC Only value.
4336234353Sdim      Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
4337234353Sdim                        eImageInfo_GCOnly);
4338234353Sdim
4339234353Sdim      // Require that GC be specified and set to eImageInfo_GarbageCollected.
4340234353Sdim      llvm::Value *Ops[2] = {
4341234353Sdim        llvm::MDString::get(VMContext, "Objective-C Garbage Collection"),
4342234353Sdim        llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
4343234353Sdim                               eImageInfo_GarbageCollected)
4344234353Sdim      };
4345234353Sdim      Mod.addModuleFlag(llvm::Module::Require, "Objective-C GC Only",
4346234353Sdim                        llvm::MDNode::get(VMContext, Ops));
4347234353Sdim    }
4348234353Sdim  }
4349239462Sdim
4350239462Sdim  // Indicate whether we're compiling this to run on a simulator.
4351239462Sdim  const llvm::Triple &Triple = CGM.getTarget().getTriple();
4352263508Sdim  if (Triple.isiOS() &&
4353239462Sdim      (Triple.getArch() == llvm::Triple::x86 ||
4354239462Sdim       Triple.getArch() == llvm::Triple::x86_64))
4355239462Sdim    Mod.addModuleFlag(llvm::Module::Error, "Objective-C Is Simulated",
4356239462Sdim                      eImageInfo_ImageIsSimulated);
4357193326Sed}
4358193326Sed
4359193326Sed// struct objc_module {
4360193326Sed//   unsigned long version;
4361193326Sed//   unsigned long size;
4362193326Sed//   const char *name;
4363193326Sed//   Symtab symtab;
4364193326Sed// };
4365193326Sed
4366193326Sed// FIXME: Get from somewhere
4367193326Sedstatic const int ModuleVersion = 7;
4368193326Sed
4369193326Sedvoid CGObjCMac::EmitModuleInfo() {
4370243830Sdim  uint64_t Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ModuleTy);
4371198092Srdivacky
4372234353Sdim  llvm::Constant *Values[] = {
4373234353Sdim    llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
4374234353Sdim    llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
4375234353Sdim    // This used to be the filename, now it is unused. <rdr://4327263>
4376234353Sdim    GetClassName(&CGM.getContext().Idents.get("")),
4377234353Sdim    EmitModuleSymbols()
4378234353Sdim  };
4379198092Srdivacky  CreateMetadataVar("\01L_OBJC_MODULES",
4380193326Sed                    llvm::ConstantStruct::get(ObjCTypes.ModuleTy, Values),
4381193326Sed                    "__OBJC,__module_info,regular,no_dead_strip",
4382193326Sed                    4, true);
4383193326Sed}
4384193326Sed
4385193326Sedllvm::Constant *CGObjCMac::EmitModuleSymbols() {
4386193326Sed  unsigned NumClasses = DefinedClasses.size();
4387193326Sed  unsigned NumCategories = DefinedCategories.size();
4388193326Sed
4389193326Sed  // Return null if no symbols were defined.
4390193326Sed  if (!NumClasses && !NumCategories)
4391193326Sed    return llvm::Constant::getNullValue(ObjCTypes.SymtabPtrTy);
4392193326Sed
4393224145Sdim  llvm::Constant *Values[5];
4394193326Sed  Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
4395193326Sed  Values[1] = llvm::Constant::getNullValue(ObjCTypes.SelectorPtrTy);
4396193326Sed  Values[2] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumClasses);
4397193326Sed  Values[3] = llvm::ConstantInt::get(ObjCTypes.ShortTy, NumCategories);
4398193326Sed
4399193326Sed  // The runtime expects exactly the list of defined classes followed
4400193326Sed  // by the list of defined categories, in a single array.
4401234353Sdim  SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
4402193326Sed  for (unsigned i=0; i<NumClasses; i++)
4403193326Sed    Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
4404193326Sed                                                ObjCTypes.Int8PtrTy);
4405193326Sed  for (unsigned i=0; i<NumCategories; i++)
4406198092Srdivacky    Symbols[NumClasses + i] =
4407193326Sed      llvm::ConstantExpr::getBitCast(DefinedCategories[i],
4408193326Sed                                     ObjCTypes.Int8PtrTy);
4409193326Sed
4410198092Srdivacky  Values[4] =
4411193326Sed    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
4412234353Sdim                                                  Symbols.size()),
4413193326Sed                             Symbols);
4414193326Sed
4415224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
4416193326Sed
4417193326Sed  llvm::GlobalVariable *GV =
4418193326Sed    CreateMetadataVar("\01L_OBJC_SYMBOLS", Init,
4419193326Sed                      "__OBJC,__symbols,regular,no_dead_strip",
4420193326Sed                      4, true);
4421193326Sed  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.SymtabPtrTy);
4422193326Sed}
4423193326Sed
4424249423Sdimllvm::Value *CGObjCMac::EmitClassRefFromId(CodeGenFunction &CGF,
4425249423Sdim                                           IdentifierInfo *II) {
4426224145Sdim  LazySymbols.insert(II);
4427224145Sdim
4428224145Sdim  llvm::GlobalVariable *&Entry = ClassReferences[II];
4429224145Sdim
4430193326Sed  if (!Entry) {
4431198092Srdivacky    llvm::Constant *Casted =
4432224145Sdim    llvm::ConstantExpr::getBitCast(GetClassName(II),
4433224145Sdim                                   ObjCTypes.ClassPtrTy);
4434198092Srdivacky    Entry =
4435224145Sdim    CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
4436224145Sdim                      "__OBJC,__cls_refs,literal_pointers,no_dead_strip",
4437224145Sdim                      4, true);
4438193326Sed  }
4439224145Sdim
4440249423Sdim  return CGF.Builder.CreateLoad(Entry);
4441193326Sed}
4442193326Sed
4443249423Sdimllvm::Value *CGObjCMac::EmitClassRef(CodeGenFunction &CGF,
4444224145Sdim                                     const ObjCInterfaceDecl *ID) {
4445249423Sdim  return EmitClassRefFromId(CGF, ID->getIdentifier());
4446224145Sdim}
4447224145Sdim
4448249423Sdimllvm::Value *CGObjCMac::EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) {
4449224145Sdim  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
4450249423Sdim  return EmitClassRefFromId(CGF, II);
4451224145Sdim}
4452224145Sdim
4453249423Sdimllvm::Value *CGObjCMac::EmitSelector(CodeGenFunction &CGF, Selector Sel,
4454210299Sed                                     bool lvalue) {
4455193326Sed  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
4456198092Srdivacky
4457193326Sed  if (!Entry) {
4458198092Srdivacky    llvm::Constant *Casted =
4459193326Sed      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
4460193326Sed                                     ObjCTypes.SelectorPtrTy);
4461198092Srdivacky    Entry =
4462193326Sed      CreateMetadataVar("\01L_OBJC_SELECTOR_REFERENCES_", Casted,
4463193326Sed                        "__OBJC,__message_refs,literal_pointers,no_dead_strip",
4464193326Sed                        4, true);
4465249423Sdim    Entry->setExternallyInitialized(true);
4466193326Sed  }
4467193326Sed
4468210299Sed  if (lvalue)
4469210299Sed    return Entry;
4470249423Sdim  return CGF.Builder.CreateLoad(Entry);
4471193326Sed}
4472193326Sed
4473193326Sedllvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
4474193326Sed  llvm::GlobalVariable *&Entry = ClassNames[Ident];
4475193326Sed
4476193326Sed  if (!Entry)
4477198092Srdivacky    Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
4478234353Sdim                              llvm::ConstantDataArray::getString(VMContext,
4479234353Sdim                                                         Ident->getNameStart()),
4480221345Sdim                              ((ObjCABI == 2) ?
4481221345Sdim                               "__TEXT,__objc_classname,cstring_literals" :
4482221345Sdim                               "__TEXT,__cstring,cstring_literals"),
4483193326Sed                              1, true);
4484193326Sed
4485198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
4486193326Sed}
4487193326Sed
4488212904Sdimllvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
4489212904Sdim  llvm::DenseMap<const ObjCMethodDecl*, llvm::Function*>::iterator
4490212904Sdim      I = MethodDefinitions.find(MD);
4491212904Sdim  if (I != MethodDefinitions.end())
4492212904Sdim    return I->second;
4493212904Sdim
4494212904Sdim  return NULL;
4495212904Sdim}
4496212904Sdim
4497193326Sed/// GetIvarLayoutName - Returns a unique constant for the given
4498193326Sed/// ivar layout bitmap.
4499193326Sedllvm::Constant *CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
4500198092Srdivacky                                       const ObjCCommonTypesHelper &ObjCTypes) {
4501193326Sed  return llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
4502193326Sed}
4503193326Sed
4504193326Sedvoid CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
4505198092Srdivacky                                                unsigned int BytePos,
4506193326Sed                                                bool ForStrongLayout,
4507193326Sed                                                bool &HasUnion) {
4508193326Sed  const RecordDecl *RD = RT->getDecl();
4509193326Sed  // FIXME - Use iterator.
4510239462Sdim  SmallVector<const FieldDecl*, 16> Fields;
4511239462Sdim  for (RecordDecl::field_iterator i = RD->field_begin(),
4512239462Sdim                                  e = RD->field_end(); i != e; ++i)
4513239462Sdim    Fields.push_back(*i);
4514226633Sdim  llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
4515198092Srdivacky  const llvm::StructLayout *RecLayout =
4516243830Sdim    CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
4517198092Srdivacky
4518193326Sed  BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
4519193326Sed                      ForStrongLayout, HasUnion);
4520193326Sed}
4521193326Sed
4522193326Sedvoid CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
4523198092Srdivacky                             const llvm::StructLayout *Layout,
4524198092Srdivacky                             const RecordDecl *RD,
4525234353Sdim                             ArrayRef<const FieldDecl*> RecFields,
4526198092Srdivacky                             unsigned int BytePos, bool ForStrongLayout,
4527198092Srdivacky                             bool &HasUnion) {
4528193326Sed  bool IsUnion = (RD && RD->isUnion());
4529193326Sed  uint64_t MaxUnionIvarSize = 0;
4530193326Sed  uint64_t MaxSkippedUnionIvarSize = 0;
4531226633Sdim  const FieldDecl *MaxField = 0;
4532226633Sdim  const FieldDecl *MaxSkippedField = 0;
4533226633Sdim  const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
4534193326Sed  uint64_t MaxFieldOffset = 0;
4535193326Sed  uint64_t MaxSkippedFieldOffset = 0;
4536218893Sdim  uint64_t LastBitfieldOrUnnamedOffset = 0;
4537224145Sdim  uint64_t FirstFieldDelta = 0;
4538198092Srdivacky
4539193326Sed  if (RecFields.empty())
4540193326Sed    return;
4541251662Sdim  unsigned WordSizeInBits = CGM.getTarget().getPointerWidth(0);
4542251662Sdim  unsigned ByteSizeInBits = CGM.getTarget().getCharWidth();
4543234353Sdim  if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
4544226633Sdim    const FieldDecl *FirstField = RecFields[0];
4545224145Sdim    FirstFieldDelta =
4546224145Sdim      ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
4547224145Sdim  }
4548224145Sdim
4549193326Sed  for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
4550226633Sdim    const FieldDecl *Field = RecFields[i];
4551193326Sed    uint64_t FieldOffset;
4552198092Srdivacky    if (RD) {
4553207619Srdivacky      // Note that 'i' here is actually the field index inside RD of Field,
4554207619Srdivacky      // although this dependency is hidden.
4555207619Srdivacky      const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
4556224145Sdim      FieldOffset = (RL.getFieldOffset(i) / ByteSizeInBits) - FirstFieldDelta;
4557198092Srdivacky    } else
4558224145Sdim      FieldOffset =
4559224145Sdim        ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(Field)) - FirstFieldDelta;
4560193326Sed
4561193326Sed    // Skip over unnamed or bitfields
4562193326Sed    if (!Field->getIdentifier() || Field->isBitField()) {
4563218893Sdim      LastFieldBitfieldOrUnnamed = Field;
4564218893Sdim      LastBitfieldOrUnnamedOffset = FieldOffset;
4565193326Sed      continue;
4566193326Sed    }
4567193326Sed
4568218893Sdim    LastFieldBitfieldOrUnnamed = 0;
4569193326Sed    QualType FQT = Field->getType();
4570193326Sed    if (FQT->isRecordType() || FQT->isUnionType()) {
4571193326Sed      if (FQT->isUnionType())
4572193326Sed        HasUnion = true;
4573193326Sed
4574198092Srdivacky      BuildAggrIvarRecordLayout(FQT->getAs<RecordType>(),
4575193326Sed                                BytePos + FieldOffset,
4576193326Sed                                ForStrongLayout, HasUnion);
4577193326Sed      continue;
4578193326Sed    }
4579198092Srdivacky
4580193326Sed    if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4581198092Srdivacky      const ConstantArrayType *CArray =
4582193326Sed        dyn_cast_or_null<ConstantArrayType>(Array);
4583193326Sed      uint64_t ElCount = CArray->getSize().getZExtValue();
4584193326Sed      assert(CArray && "only array with known element size is supported");
4585193326Sed      FQT = CArray->getElementType();
4586193326Sed      while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) {
4587193326Sed        const ConstantArrayType *CArray =
4588193326Sed          dyn_cast_or_null<ConstantArrayType>(Array);
4589193326Sed        ElCount *= CArray->getSize().getZExtValue();
4590193326Sed        FQT = CArray->getElementType();
4591193326Sed      }
4592198092Srdivacky
4593198092Srdivacky      assert(!FQT->isUnionType() &&
4594193326Sed             "layout for array of unions not supported");
4595218893Sdim      if (FQT->isRecordType() && ElCount) {
4596193326Sed        int OldIndex = IvarsInfo.size() - 1;
4597193326Sed        int OldSkIndex = SkipIvars.size() -1;
4598198092Srdivacky
4599198092Srdivacky        const RecordType *RT = FQT->getAs<RecordType>();
4600193326Sed        BuildAggrIvarRecordLayout(RT, BytePos + FieldOffset,
4601193326Sed                                  ForStrongLayout, HasUnion);
4602198092Srdivacky
4603193326Sed        // Replicate layout information for each array element. Note that
4604193326Sed        // one element is already done.
4605193326Sed        uint64_t ElIx = 1;
4606198092Srdivacky        for (int FirstIndex = IvarsInfo.size() - 1,
4607198092Srdivacky               FirstSkIndex = SkipIvars.size() - 1 ;ElIx < ElCount; ElIx++) {
4608193326Sed          uint64_t Size = CGM.getContext().getTypeSize(RT)/ByteSizeInBits;
4609193326Sed          for (int i = OldIndex+1; i <= FirstIndex; ++i)
4610193326Sed            IvarsInfo.push_back(GC_IVAR(IvarsInfo[i].ivar_bytepos + Size*ElIx,
4611193326Sed                                        IvarsInfo[i].ivar_size));
4612193326Sed          for (int i = OldSkIndex+1; i <= FirstSkIndex; ++i)
4613193326Sed            SkipIvars.push_back(GC_IVAR(SkipIvars[i].ivar_bytepos + Size*ElIx,
4614193326Sed                                        SkipIvars[i].ivar_size));
4615193326Sed        }
4616193326Sed        continue;
4617193326Sed      }
4618193326Sed    }
4619193326Sed    // At this point, we are done with Record/Union and array there of.
4620193326Sed    // For other arrays we are down to its element type.
4621198092Srdivacky    Qualifiers::GC GCAttr = GetGCAttrTypeForType(CGM.getContext(), FQT);
4622193326Sed
4623193326Sed    unsigned FieldSize = CGM.getContext().getTypeSize(Field->getType());
4624198092Srdivacky    if ((ForStrongLayout && GCAttr == Qualifiers::Strong)
4625198092Srdivacky        || (!ForStrongLayout && GCAttr == Qualifiers::Weak)) {
4626193326Sed      if (IsUnion) {
4627193326Sed        uint64_t UnionIvarSize = FieldSize / WordSizeInBits;
4628193326Sed        if (UnionIvarSize > MaxUnionIvarSize) {
4629193326Sed          MaxUnionIvarSize = UnionIvarSize;
4630193326Sed          MaxField = Field;
4631193326Sed          MaxFieldOffset = FieldOffset;
4632193326Sed        }
4633193326Sed      } else {
4634193326Sed        IvarsInfo.push_back(GC_IVAR(BytePos + FieldOffset,
4635193326Sed                                    FieldSize / WordSizeInBits));
4636193326Sed      }
4637198092Srdivacky    } else if ((ForStrongLayout &&
4638198092Srdivacky                (GCAttr == Qualifiers::GCNone || GCAttr == Qualifiers::Weak))
4639198092Srdivacky               || (!ForStrongLayout && GCAttr != Qualifiers::Weak)) {
4640193326Sed      if (IsUnion) {
4641193326Sed        // FIXME: Why the asymmetry? We divide by word size in bits on other
4642193326Sed        // side.
4643243830Sdim        uint64_t UnionIvarSize = FieldSize / ByteSizeInBits;
4644193326Sed        if (UnionIvarSize > MaxSkippedUnionIvarSize) {
4645193326Sed          MaxSkippedUnionIvarSize = UnionIvarSize;
4646193326Sed          MaxSkippedField = Field;
4647193326Sed          MaxSkippedFieldOffset = FieldOffset;
4648193326Sed        }
4649193326Sed      } else {
4650193326Sed        // FIXME: Why the asymmetry, we divide by byte size in bits here?
4651193326Sed        SkipIvars.push_back(GC_IVAR(BytePos + FieldOffset,
4652193326Sed                                    FieldSize / ByteSizeInBits));
4653193326Sed      }
4654193326Sed    }
4655193326Sed  }
4656193326Sed
4657218893Sdim  if (LastFieldBitfieldOrUnnamed) {
4658218893Sdim    if (LastFieldBitfieldOrUnnamed->isBitField()) {
4659218893Sdim      // Last field was a bitfield. Must update skip info.
4660226633Sdim      uint64_t BitFieldSize
4661226633Sdim          = LastFieldBitfieldOrUnnamed->getBitWidthValue(CGM.getContext());
4662218893Sdim      GC_IVAR skivar;
4663218893Sdim      skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
4664218893Sdim      skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
4665218893Sdim        + ((BitFieldSize % ByteSizeInBits) != 0);
4666218893Sdim      SkipIvars.push_back(skivar);
4667218893Sdim    } else {
4668218893Sdim      assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
4669218893Sdim      // Last field was unnamed. Must update skip info.
4670218893Sdim      unsigned FieldSize
4671218893Sdim          = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
4672218893Sdim      SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
4673218893Sdim                                  FieldSize / ByteSizeInBits));
4674218893Sdim    }
4675193326Sed  }
4676198092Srdivacky
4677193326Sed  if (MaxField)
4678198092Srdivacky    IvarsInfo.push_back(GC_IVAR(BytePos + MaxFieldOffset,
4679193326Sed                                MaxUnionIvarSize));
4680193326Sed  if (MaxSkippedField)
4681193326Sed    SkipIvars.push_back(GC_IVAR(BytePos + MaxSkippedFieldOffset,
4682193326Sed                                MaxSkippedUnionIvarSize));
4683193326Sed}
4684193326Sed
4685212904Sdim/// BuildIvarLayoutBitmap - This routine is the horsework for doing all
4686212904Sdim/// the computations and returning the layout bitmap (for ivar or blocks) in
4687212904Sdim/// the given argument BitMap string container. Routine reads
4688212904Sdim/// two containers, IvarsInfo and SkipIvars which are assumed to be
4689212904Sdim/// filled already by the caller.
4690234353Sdimllvm::Constant *CGObjCCommonMac::BuildIvarLayoutBitmap(std::string &BitMap) {
4691193326Sed  unsigned int WordsToScan, WordsToSkip;
4692234353Sdim  llvm::Type *PtrTy = CGM.Int8PtrTy;
4693212904Sdim
4694193326Sed  // Build the string of skip/scan nibbles
4695226633Sdim  SmallVector<SKIP_SCAN, 32> SkipScanIvars;
4696198092Srdivacky  unsigned int WordSize =
4697243830Sdim  CGM.getTypes().getDataLayout().getTypeAllocSize(PtrTy);
4698193326Sed  if (IvarsInfo[0].ivar_bytepos == 0) {
4699193326Sed    WordsToSkip = 0;
4700193326Sed    WordsToScan = IvarsInfo[0].ivar_size;
4701193326Sed  } else {
4702193326Sed    WordsToSkip = IvarsInfo[0].ivar_bytepos/WordSize;
4703193326Sed    WordsToScan = IvarsInfo[0].ivar_size;
4704193326Sed  }
4705193326Sed  for (unsigned int i=1, Last=IvarsInfo.size(); i != Last; i++) {
4706198092Srdivacky    unsigned int TailPrevGCObjC =
4707212904Sdim    IvarsInfo[i-1].ivar_bytepos + IvarsInfo[i-1].ivar_size * WordSize;
4708193326Sed    if (IvarsInfo[i].ivar_bytepos == TailPrevGCObjC) {
4709193326Sed      // consecutive 'scanned' object pointers.
4710193326Sed      WordsToScan += IvarsInfo[i].ivar_size;
4711193326Sed    } else {
4712193326Sed      // Skip over 'gc'able object pointer which lay over each other.
4713193326Sed      if (TailPrevGCObjC > IvarsInfo[i].ivar_bytepos)
4714193326Sed        continue;
4715193326Sed      // Must skip over 1 or more words. We save current skip/scan values
4716193326Sed      //  and start a new pair.
4717193326Sed      SKIP_SCAN SkScan;
4718193326Sed      SkScan.skip = WordsToSkip;
4719193326Sed      SkScan.scan = WordsToScan;
4720193326Sed      SkipScanIvars.push_back(SkScan);
4721212904Sdim
4722193326Sed      // Skip the hole.
4723193326Sed      SkScan.skip = (IvarsInfo[i].ivar_bytepos - TailPrevGCObjC) / WordSize;
4724193326Sed      SkScan.scan = 0;
4725193326Sed      SkipScanIvars.push_back(SkScan);
4726193326Sed      WordsToSkip = 0;
4727193326Sed      WordsToScan = IvarsInfo[i].ivar_size;
4728193326Sed    }
4729193326Sed  }
4730193326Sed  if (WordsToScan > 0) {
4731193326Sed    SKIP_SCAN SkScan;
4732193326Sed    SkScan.skip = WordsToSkip;
4733193326Sed    SkScan.scan = WordsToScan;
4734193326Sed    SkipScanIvars.push_back(SkScan);
4735193326Sed  }
4736212904Sdim
4737193326Sed  if (!SkipIvars.empty()) {
4738193326Sed    unsigned int LastIndex = SkipIvars.size()-1;
4739198092Srdivacky    int LastByteSkipped =
4740212904Sdim    SkipIvars[LastIndex].ivar_bytepos + SkipIvars[LastIndex].ivar_size;
4741193326Sed    LastIndex = IvarsInfo.size()-1;
4742198092Srdivacky    int LastByteScanned =
4743212904Sdim    IvarsInfo[LastIndex].ivar_bytepos +
4744212904Sdim    IvarsInfo[LastIndex].ivar_size * WordSize;
4745193326Sed    // Compute number of bytes to skip at the tail end of the last ivar scanned.
4746201361Srdivacky    if (LastByteSkipped > LastByteScanned) {
4747193326Sed      unsigned int TotalWords = (LastByteSkipped + (WordSize -1)) / WordSize;
4748193326Sed      SKIP_SCAN SkScan;
4749193326Sed      SkScan.skip = TotalWords - (LastByteScanned/WordSize);
4750193326Sed      SkScan.scan = 0;
4751193326Sed      SkipScanIvars.push_back(SkScan);
4752193326Sed    }
4753193326Sed  }
4754193326Sed  // Mini optimization of nibbles such that an 0xM0 followed by 0x0N is produced
4755193326Sed  // as 0xMN.
4756193326Sed  int SkipScan = SkipScanIvars.size()-1;
4757193326Sed  for (int i = 0; i <= SkipScan; i++) {
4758193326Sed    if ((i < SkipScan) && SkipScanIvars[i].skip && SkipScanIvars[i].scan == 0
4759193326Sed        && SkipScanIvars[i+1].skip == 0 && SkipScanIvars[i+1].scan) {
4760193326Sed      // 0xM0 followed by 0x0N detected.
4761193326Sed      SkipScanIvars[i].scan = SkipScanIvars[i+1].scan;
4762193326Sed      for (int j = i+1; j < SkipScan; j++)
4763193326Sed        SkipScanIvars[j] = SkipScanIvars[j+1];
4764193326Sed      --SkipScan;
4765193326Sed    }
4766193326Sed  }
4767212904Sdim
4768193326Sed  // Generate the string.
4769193326Sed  for (int i = 0; i <= SkipScan; i++) {
4770193326Sed    unsigned char byte;
4771193326Sed    unsigned int skip_small = SkipScanIvars[i].skip % 0xf;
4772193326Sed    unsigned int scan_small = SkipScanIvars[i].scan % 0xf;
4773193326Sed    unsigned int skip_big  = SkipScanIvars[i].skip / 0xf;
4774193326Sed    unsigned int scan_big  = SkipScanIvars[i].scan / 0xf;
4775212904Sdim
4776193326Sed    // first skip big.
4777193326Sed    for (unsigned int ix = 0; ix < skip_big; ix++)
4778193326Sed      BitMap += (unsigned char)(0xf0);
4779212904Sdim
4780193326Sed    // next (skip small, scan)
4781193326Sed    if (skip_small) {
4782193326Sed      byte = skip_small << 4;
4783193326Sed      if (scan_big > 0) {
4784193326Sed        byte |= 0xf;
4785193326Sed        --scan_big;
4786193326Sed      } else if (scan_small) {
4787193326Sed        byte |= scan_small;
4788193326Sed        scan_small = 0;
4789193326Sed      }
4790193326Sed      BitMap += byte;
4791193326Sed    }
4792193326Sed    // next scan big
4793193326Sed    for (unsigned int ix = 0; ix < scan_big; ix++)
4794193326Sed      BitMap += (unsigned char)(0x0f);
4795193326Sed    // last scan small
4796193326Sed    if (scan_small) {
4797193326Sed      byte = scan_small;
4798193326Sed      BitMap += byte;
4799193326Sed    }
4800193326Sed  }
4801193326Sed  // null terminate string.
4802193326Sed  unsigned char zero = 0;
4803193326Sed  BitMap += zero;
4804212904Sdim
4805212904Sdim  llvm::GlobalVariable * Entry =
4806212904Sdim  CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
4807234353Sdim                    llvm::ConstantDataArray::getString(VMContext, BitMap,false),
4808221345Sdim                    ((ObjCABI == 2) ?
4809221345Sdim                     "__TEXT,__objc_classname,cstring_literals" :
4810221345Sdim                     "__TEXT,__cstring,cstring_literals"),
4811212904Sdim                    1, true);
4812212904Sdim  return getConstantGEP(VMContext, Entry, 0, 0);
4813212904Sdim}
4814198092Srdivacky
4815212904Sdim/// BuildIvarLayout - Builds ivar layout bitmap for the class
4816212904Sdim/// implementation for the __strong or __weak case.
4817212904Sdim/// The layout map displays which words in ivar list must be skipped
4818212904Sdim/// and which must be scanned by GC (see below). String is built of bytes.
4819212904Sdim/// Each byte is divided up in two nibbles (4-bit each). Left nibble is count
4820212904Sdim/// of words to skip and right nibble is count of words to scan. So, each
4821212904Sdim/// nibble represents up to 15 workds to skip or scan. Skipping the rest is
4822212904Sdim/// represented by a 0x00 byte which also ends the string.
4823212904Sdim/// 1. when ForStrongLayout is true, following ivars are scanned:
4824212904Sdim/// - id, Class
4825212904Sdim/// - object *
4826212904Sdim/// - __strong anything
4827212904Sdim///
4828212904Sdim/// 2. When ForStrongLayout is false, following ivars are scanned:
4829212904Sdim/// - __weak anything
4830212904Sdim///
4831212904Sdimllvm::Constant *CGObjCCommonMac::BuildIvarLayout(
4832212904Sdim  const ObjCImplementationDecl *OMD,
4833212904Sdim  bool ForStrongLayout) {
4834212904Sdim  bool hasUnion = false;
4835212904Sdim
4836234353Sdim  llvm::Type *PtrTy = CGM.Int8PtrTy;
4837234353Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
4838234353Sdim      !CGM.getLangOpts().ObjCAutoRefCount)
4839212904Sdim    return llvm::Constant::getNullValue(PtrTy);
4840212904Sdim
4841226633Sdim  const ObjCInterfaceDecl *OI = OMD->getClassInterface();
4842226633Sdim  SmallVector<const FieldDecl*, 32> RecFields;
4843234353Sdim  if (CGM.getLangOpts().ObjCAutoRefCount) {
4844226633Sdim    for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
4845224145Sdim         IVD; IVD = IVD->getNextIvar())
4846224145Sdim      RecFields.push_back(cast<FieldDecl>(IVD));
4847224145Sdim  }
4848224145Sdim  else {
4849226633Sdim    SmallVector<const ObjCIvarDecl*, 32> Ivars;
4850224145Sdim    CGM.getContext().DeepCollectObjCIvars(OI, true, Ivars);
4851212904Sdim
4852226633Sdim    // FIXME: This is not ideal; we shouldn't have to do this copy.
4853226633Sdim    RecFields.append(Ivars.begin(), Ivars.end());
4854224145Sdim  }
4855224145Sdim
4856212904Sdim  if (RecFields.empty())
4857212904Sdim    return llvm::Constant::getNullValue(PtrTy);
4858212904Sdim
4859212904Sdim  SkipIvars.clear();
4860212904Sdim  IvarsInfo.clear();
4861212904Sdim
4862212904Sdim  BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
4863212904Sdim  if (IvarsInfo.empty())
4864212904Sdim    return llvm::Constant::getNullValue(PtrTy);
4865212904Sdim  // Sort on byte position in case we encounterred a union nested in
4866212904Sdim  // the ivar list.
4867212904Sdim  if (hasUnion && !IvarsInfo.empty())
4868212904Sdim    std::sort(IvarsInfo.begin(), IvarsInfo.end());
4869212904Sdim  if (hasUnion && !SkipIvars.empty())
4870212904Sdim    std::sort(SkipIvars.begin(), SkipIvars.end());
4871212904Sdim
4872212904Sdim  std::string BitMap;
4873212904Sdim  llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
4874212904Sdim
4875234353Sdim   if (CGM.getLangOpts().ObjCGCBitmapPrint) {
4876198092Srdivacky    printf("\n%s ivar layout for class '%s': ",
4877193326Sed           ForStrongLayout ? "strong" : "weak",
4878212904Sdim           OMD->getClassInterface()->getName().data());
4879243830Sdim    const unsigned char *s = (const unsigned char*)BitMap.c_str();
4880234353Sdim    for (unsigned i = 0, e = BitMap.size(); i < e; i++)
4881193326Sed      if (!(s[i] & 0xf0))
4882193326Sed        printf("0x0%x%s", s[i], s[i] != 0 ? ", " : "");
4883193326Sed      else
4884193326Sed        printf("0x%x%s",  s[i], s[i] != 0 ? ", " : "");
4885193326Sed    printf("\n");
4886193326Sed  }
4887212904Sdim  return C;
4888193326Sed}
4889193326Sed
4890193326Sedllvm::Constant *CGObjCCommonMac::GetMethodVarName(Selector Sel) {
4891193326Sed  llvm::GlobalVariable *&Entry = MethodVarNames[Sel];
4892193326Sed
4893234353Sdim  // FIXME: Avoid std::string in "Sel.getAsString()"
4894193326Sed  if (!Entry)
4895198092Srdivacky    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_NAME_",
4896234353Sdim               llvm::ConstantDataArray::getString(VMContext, Sel.getAsString()),
4897221345Sdim                              ((ObjCABI == 2) ?
4898221345Sdim                               "__TEXT,__objc_methname,cstring_literals" :
4899221345Sdim                               "__TEXT,__cstring,cstring_literals"),
4900193326Sed                              1, true);
4901193326Sed
4902198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
4903193326Sed}
4904193326Sed
4905193326Sed// FIXME: Merge into a single cstring creation function.
4906193326Sedllvm::Constant *CGObjCCommonMac::GetMethodVarName(IdentifierInfo *ID) {
4907193326Sed  return GetMethodVarName(CGM.getContext().Selectors.getNullarySelector(ID));
4908193326Sed}
4909193326Sed
4910193326Sedllvm::Constant *CGObjCCommonMac::GetMethodVarType(const FieldDecl *Field) {
4911193326Sed  std::string TypeStr;
4912193326Sed  CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field);
4913193326Sed
4914193326Sed  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4915193326Sed
4916193326Sed  if (!Entry)
4917193326Sed    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
4918234353Sdim                         llvm::ConstantDataArray::getString(VMContext, TypeStr),
4919221345Sdim                              ((ObjCABI == 2) ?
4920221345Sdim                               "__TEXT,__objc_methtype,cstring_literals" :
4921221345Sdim                               "__TEXT,__cstring,cstring_literals"),
4922193326Sed                              1, true);
4923198092Srdivacky
4924198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
4925193326Sed}
4926193326Sed
4927234353Sdimllvm::Constant *CGObjCCommonMac::GetMethodVarType(const ObjCMethodDecl *D,
4928234353Sdim                                                  bool Extended) {
4929193326Sed  std::string TypeStr;
4930234353Sdim  if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
4931223017Sdim    return 0;
4932193326Sed
4933193326Sed  llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
4934193326Sed
4935193326Sed  if (!Entry)
4936193326Sed    Entry = CreateMetadataVar("\01L_OBJC_METH_VAR_TYPE_",
4937234353Sdim                         llvm::ConstantDataArray::getString(VMContext, TypeStr),
4938221345Sdim                              ((ObjCABI == 2) ?
4939221345Sdim                               "__TEXT,__objc_methtype,cstring_literals" :
4940221345Sdim                               "__TEXT,__cstring,cstring_literals"),
4941193326Sed                              1, true);
4942193326Sed
4943198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
4944193326Sed}
4945193326Sed
4946193326Sed// FIXME: Merge into a single cstring creation function.
4947193326Sedllvm::Constant *CGObjCCommonMac::GetPropertyName(IdentifierInfo *Ident) {
4948193326Sed  llvm::GlobalVariable *&Entry = PropertyNames[Ident];
4949198092Srdivacky
4950193326Sed  if (!Entry)
4951198092Srdivacky    Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
4952234353Sdim                        llvm::ConstantDataArray::getString(VMContext,
4953234353Sdim                                                       Ident->getNameStart()),
4954193326Sed                              "__TEXT,__cstring,cstring_literals",
4955193326Sed                              1, true);
4956193326Sed
4957198092Srdivacky  return getConstantGEP(VMContext, Entry, 0, 0);
4958193326Sed}
4959193326Sed
4960193326Sed// FIXME: Merge into a single cstring creation function.
4961193326Sed// FIXME: This Decl should be more precise.
4962193326Sedllvm::Constant *
4963198092SrdivackyCGObjCCommonMac::GetPropertyTypeString(const ObjCPropertyDecl *PD,
4964198092Srdivacky                                       const Decl *Container) {
4965193326Sed  std::string TypeStr;
4966193326Sed  CGM.getContext().getObjCEncodingForPropertyDecl(PD, Container, TypeStr);
4967193326Sed  return GetPropertyName(&CGM.getContext().Idents.get(TypeStr));
4968193326Sed}
4969193326Sed
4970198092Srdivackyvoid CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D,
4971193326Sed                                       const ObjCContainerDecl *CD,
4972226633Sdim                                       SmallVectorImpl<char> &Name) {
4973198398Srdivacky  llvm::raw_svector_ostream OS(Name);
4974193326Sed  assert (CD && "Missing container decl in GetNameForMethod");
4975198398Srdivacky  OS << '\01' << (D->isInstanceMethod() ? '-' : '+')
4976198398Srdivacky     << '[' << CD->getName();
4977198092Srdivacky  if (const ObjCCategoryImplDecl *CID =
4978198398Srdivacky      dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
4979234353Sdim    OS << '(' << *CID << ')';
4980198398Srdivacky  OS << ' ' << D->getSelector().getAsString() << ']';
4981193326Sed}
4982193326Sed
4983193326Sedvoid CGObjCMac::FinishModule() {
4984193326Sed  EmitModuleInfo();
4985193326Sed
4986193326Sed  // Emit the dummy bodies for any protocols which were referenced but
4987193326Sed  // never defined.
4988198092Srdivacky  for (llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*>::iterator
4989198092Srdivacky         I = Protocols.begin(), e = Protocols.end(); I != e; ++I) {
4990198092Srdivacky    if (I->second->hasInitializer())
4991193326Sed      continue;
4992193326Sed
4993234353Sdim    llvm::Constant *Values[5];
4994193326Sed    Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
4995198092Srdivacky    Values[1] = GetClassName(I->first);
4996193326Sed    Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
4997193326Sed    Values[3] = Values[4] =
4998193326Sed      llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
4999198092Srdivacky    I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
5000198092Srdivacky    I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
5001193326Sed                                                        Values));
5002198092Srdivacky    CGM.AddUsedGlobal(I->second);
5003193326Sed  }
5004193326Sed
5005193326Sed  // Add assembler directives to add lazy undefined symbol references
5006193326Sed  // for classes which are referenced but not defined. This is
5007193326Sed  // important for correct linker interaction.
5008198092Srdivacky  //
5009198092Srdivacky  // FIXME: It would be nice if we had an LLVM construct for this.
5010198092Srdivacky  if (!LazySymbols.empty() || !DefinedSymbols.empty()) {
5011234353Sdim    SmallString<256> Asm;
5012198092Srdivacky    Asm += CGM.getModule().getModuleInlineAsm();
5013198092Srdivacky    if (!Asm.empty() && Asm.back() != '\n')
5014198092Srdivacky      Asm += '\n';
5015193326Sed
5016198092Srdivacky    llvm::raw_svector_ostream OS(Asm);
5017198092Srdivacky    for (llvm::SetVector<IdentifierInfo*>::iterator I = DefinedSymbols.begin(),
5018198092Srdivacky           e = DefinedSymbols.end(); I != e; ++I)
5019198092Srdivacky      OS << "\t.objc_class_name_" << (*I)->getName() << "=0\n"
5020198092Srdivacky         << "\t.globl .objc_class_name_" << (*I)->getName() << "\n";
5021207619Srdivacky    for (llvm::SetVector<IdentifierInfo*>::iterator I = LazySymbols.begin(),
5022210299Sed         e = LazySymbols.end(); I != e; ++I) {
5023207619Srdivacky      OS << "\t.lazy_reference .objc_class_name_" << (*I)->getName() << "\n";
5024210299Sed    }
5025210299Sed
5026234353Sdim    for (size_t i = 0, e = DefinedCategoryNames.size(); i < e; ++i) {
5027210299Sed      OS << "\t.objc_category_name_" << DefinedCategoryNames[i] << "=0\n"
5028210299Sed         << "\t.globl .objc_category_name_" << DefinedCategoryNames[i] << "\n";
5029210299Sed    }
5030207619Srdivacky
5031198092Srdivacky    CGM.getModule().setModuleInlineAsm(OS.str());
5032193326Sed  }
5033193326Sed}
5034193326Sed
5035198092SrdivackyCGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
5036193326Sed  : CGObjCCommonMac(cgm),
5037198092Srdivacky    ObjCTypes(cgm) {
5038193326Sed  ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
5039193326Sed  ObjCABI = 2;
5040193326Sed}
5041193326Sed
5042193326Sed/* *** */
5043193326Sed
5044193326SedObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
5045234353Sdim  : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(0)
5046234353Sdim{
5047193326Sed  CodeGen::CodeGenTypes &Types = CGM.getTypes();
5048193326Sed  ASTContext &Ctx = CGM.getContext();
5049198092Srdivacky
5050193326Sed  ShortTy = Types.ConvertType(Ctx.ShortTy);
5051193326Sed  IntTy = Types.ConvertType(Ctx.IntTy);
5052193326Sed  LongTy = Types.ConvertType(Ctx.LongTy);
5053193326Sed  LongLongTy = Types.ConvertType(Ctx.LongLongTy);
5054234353Sdim  Int8PtrTy = CGM.Int8PtrTy;
5055234353Sdim  Int8PtrPtrTy = CGM.Int8PtrPtrTy;
5056198092Srdivacky
5057193326Sed  ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
5058193326Sed  PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
5059193326Sed  SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
5060198092Srdivacky
5061193326Sed  // I'm not sure I like this. The implicit coordination is a bit
5062193326Sed  // gross. We should solve this in a reasonable fashion because this
5063193326Sed  // is a pretty common task (match some runtime data structure with
5064193326Sed  // an LLVM data structure).
5065198092Srdivacky
5066193326Sed  // FIXME: This is leaked.
5067193326Sed  // FIXME: Merge with rewriter code?
5068198092Srdivacky
5069193326Sed  // struct _objc_super {
5070193326Sed  //   id self;
5071193326Sed  //   Class cls;
5072193326Sed  // }
5073208600Srdivacky  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5074207619Srdivacky                                      Ctx.getTranslationUnitDecl(),
5075221345Sdim                                      SourceLocation(), SourceLocation(),
5076198092Srdivacky                                      &Ctx.Idents.get("_objc_super"));
5077221345Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
5078239462Sdim                                Ctx.getObjCIdType(), 0, 0, false, ICIS_NoInit));
5079221345Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
5080239462Sdim                                Ctx.getObjCClassType(), 0, 0, false,
5081239462Sdim                                ICIS_NoInit));
5082203955Srdivacky  RD->completeDefinition();
5083198092Srdivacky
5084193326Sed  SuperCTy = Ctx.getTagDeclType(RD);
5085193326Sed  SuperPtrCTy = Ctx.getPointerType(SuperCTy);
5086198092Srdivacky
5087193326Sed  SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
5088198092Srdivacky  SuperPtrTy = llvm::PointerType::getUnqual(SuperTy);
5089198092Srdivacky
5090193326Sed  // struct _prop_t {
5091193326Sed  //   char *name;
5092198092Srdivacky  //   char *attributes;
5093193326Sed  // }
5094226633Sdim  PropertyTy = llvm::StructType::create("struct._prop_t",
5095226633Sdim                                        Int8PtrTy, Int8PtrTy, NULL);
5096198092Srdivacky
5097193326Sed  // struct _prop_list_t {
5098193326Sed  //   uint32_t entsize;      // sizeof(struct _prop_t)
5099193326Sed  //   uint32_t count_of_properties;
5100193326Sed  //   struct _prop_t prop_list[count_of_properties];
5101193326Sed  // }
5102224145Sdim  PropertyListTy =
5103226633Sdim    llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
5104226633Sdim                             llvm::ArrayType::get(PropertyTy, 0), NULL);
5105193326Sed  // struct _prop_list_t *
5106193326Sed  PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
5107198092Srdivacky
5108193326Sed  // struct _objc_method {
5109193326Sed  //   SEL _cmd;
5110193326Sed  //   char *method_type;
5111193326Sed  //   char *_imp;
5112193326Sed  // }
5113226633Sdim  MethodTy = llvm::StructType::create("struct._objc_method",
5114226633Sdim                                      SelectorPtrTy, Int8PtrTy, Int8PtrTy,
5115226633Sdim                                      NULL);
5116198092Srdivacky
5117193326Sed  // struct _objc_cache *
5118226633Sdim  CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
5119193326Sed  CachePtrTy = llvm::PointerType::getUnqual(CacheTy);
5120224145Sdim
5121193326Sed}
5122193326Sed
5123198092SrdivackyObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
5124198092Srdivacky  : ObjCCommonTypesHelper(cgm) {
5125193326Sed  // struct _objc_method_description {
5126193326Sed  //   SEL name;
5127193326Sed  //   char *types;
5128193326Sed  // }
5129198092Srdivacky  MethodDescriptionTy =
5130226633Sdim    llvm::StructType::create("struct._objc_method_description",
5131226633Sdim                             SelectorPtrTy, Int8PtrTy, NULL);
5132193326Sed
5133193326Sed  // struct _objc_method_description_list {
5134193326Sed  //   int count;
5135193326Sed  //   struct _objc_method_description[1];
5136193326Sed  // }
5137198092Srdivacky  MethodDescriptionListTy =
5138226633Sdim    llvm::StructType::create("struct._objc_method_description_list",
5139226633Sdim                             IntTy,
5140226633Sdim                             llvm::ArrayType::get(MethodDescriptionTy, 0),NULL);
5141198092Srdivacky
5142193326Sed  // struct _objc_method_description_list *
5143198092Srdivacky  MethodDescriptionListPtrTy =
5144193326Sed    llvm::PointerType::getUnqual(MethodDescriptionListTy);
5145193326Sed
5146193326Sed  // Protocol description structures
5147193326Sed
5148193326Sed  // struct _objc_protocol_extension {
5149193326Sed  //   uint32_t size;  // sizeof(struct _objc_protocol_extension)
5150193326Sed  //   struct _objc_method_description_list *optional_instance_methods;
5151193326Sed  //   struct _objc_method_description_list *optional_class_methods;
5152193326Sed  //   struct _objc_property_list *instance_properties;
5153234353Sdim  //   const char ** extendedMethodTypes;
5154193326Sed  // }
5155198092Srdivacky  ProtocolExtensionTy =
5156226633Sdim    llvm::StructType::create("struct._objc_protocol_extension",
5157226633Sdim                             IntTy, MethodDescriptionListPtrTy,
5158226633Sdim                             MethodDescriptionListPtrTy, PropertyListPtrTy,
5159234353Sdim                             Int8PtrPtrTy, NULL);
5160198092Srdivacky
5161193326Sed  // struct _objc_protocol_extension *
5162193326Sed  ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
5163193326Sed
5164193326Sed  // Handle recursive construction of Protocol and ProtocolList types
5165193326Sed
5166224145Sdim  ProtocolTy =
5167226633Sdim    llvm::StructType::create(VMContext, "struct._objc_protocol");
5168193326Sed
5169224145Sdim  ProtocolListTy =
5170226633Sdim    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5171224145Sdim  ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
5172193326Sed                          LongTy,
5173224145Sdim                          llvm::ArrayType::get(ProtocolTy, 0),
5174193326Sed                          NULL);
5175193326Sed
5176193326Sed  // struct _objc_protocol {
5177193326Sed  //   struct _objc_protocol_extension *isa;
5178193326Sed  //   char *protocol_name;
5179193326Sed  //   struct _objc_protocol **_objc_protocol_list;
5180193326Sed  //   struct _objc_method_description_list *instance_methods;
5181193326Sed  //   struct _objc_method_description_list *class_methods;
5182193326Sed  // }
5183224145Sdim  ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
5184224145Sdim                      llvm::PointerType::getUnqual(ProtocolListTy),
5185224145Sdim                      MethodDescriptionListPtrTy,
5186224145Sdim                      MethodDescriptionListPtrTy,
5187224145Sdim                      NULL);
5188193326Sed
5189193326Sed  // struct _objc_protocol_list *
5190193326Sed  ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
5191193326Sed
5192193326Sed  ProtocolPtrTy = llvm::PointerType::getUnqual(ProtocolTy);
5193193326Sed
5194193326Sed  // Class description structures
5195193326Sed
5196193326Sed  // struct _objc_ivar {
5197193326Sed  //   char *ivar_name;
5198193326Sed  //   char *ivar_type;
5199193326Sed  //   int  ivar_offset;
5200193326Sed  // }
5201226633Sdim  IvarTy = llvm::StructType::create("struct._objc_ivar",
5202226633Sdim                                    Int8PtrTy, Int8PtrTy, IntTy, NULL);
5203193326Sed
5204193326Sed  // struct _objc_ivar_list *
5205224145Sdim  IvarListTy =
5206226633Sdim    llvm::StructType::create(VMContext, "struct._objc_ivar_list");
5207193326Sed  IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy);
5208193326Sed
5209193326Sed  // struct _objc_method_list *
5210224145Sdim  MethodListTy =
5211226633Sdim    llvm::StructType::create(VMContext, "struct._objc_method_list");
5212193326Sed  MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
5213193326Sed
5214193326Sed  // struct _objc_class_extension *
5215198092Srdivacky  ClassExtensionTy =
5216226633Sdim    llvm::StructType::create("struct._objc_class_extension",
5217226633Sdim                             IntTy, Int8PtrTy, PropertyListPtrTy, NULL);
5218193326Sed  ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
5219193326Sed
5220226633Sdim  ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
5221193326Sed
5222193326Sed  // struct _objc_class {
5223193326Sed  //   Class isa;
5224193326Sed  //   Class super_class;
5225193326Sed  //   char *name;
5226193326Sed  //   long version;
5227193326Sed  //   long info;
5228193326Sed  //   long instance_size;
5229193326Sed  //   struct _objc_ivar_list *ivars;
5230193326Sed  //   struct _objc_method_list *methods;
5231193326Sed  //   struct _objc_cache *cache;
5232193326Sed  //   struct _objc_protocol_list *protocols;
5233193326Sed  //   char *ivar_layout;
5234193326Sed  //   struct _objc_class_ext *ext;
5235193326Sed  // };
5236224145Sdim  ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
5237224145Sdim                   llvm::PointerType::getUnqual(ClassTy),
5238224145Sdim                   Int8PtrTy,
5239224145Sdim                   LongTy,
5240224145Sdim                   LongTy,
5241224145Sdim                   LongTy,
5242224145Sdim                   IvarListPtrTy,
5243224145Sdim                   MethodListPtrTy,
5244224145Sdim                   CachePtrTy,
5245224145Sdim                   ProtocolListPtrTy,
5246224145Sdim                   Int8PtrTy,
5247224145Sdim                   ClassExtensionPtrTy,
5248224145Sdim                   NULL);
5249198092Srdivacky
5250193326Sed  ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
5251193326Sed
5252193326Sed  // struct _objc_category {
5253193326Sed  //   char *category_name;
5254193326Sed  //   char *class_name;
5255193326Sed  //   struct _objc_method_list *instance_method;
5256193326Sed  //   struct _objc_method_list *class_method;
5257193326Sed  //   uint32_t size;  // sizeof(struct _objc_category)
5258193326Sed  //   struct _objc_property_list *instance_properties;// category's @property
5259193326Sed  // }
5260224145Sdim  CategoryTy =
5261226633Sdim    llvm::StructType::create("struct._objc_category",
5262226633Sdim                             Int8PtrTy, Int8PtrTy, MethodListPtrTy,
5263226633Sdim                             MethodListPtrTy, ProtocolListPtrTy,
5264226633Sdim                             IntTy, PropertyListPtrTy, NULL);
5265193326Sed
5266193326Sed  // Global metadata structures
5267193326Sed
5268193326Sed  // struct _objc_symtab {
5269193326Sed  //   long sel_ref_cnt;
5270193326Sed  //   SEL *refs;
5271193326Sed  //   short cls_def_cnt;
5272193326Sed  //   short cat_def_cnt;
5273193326Sed  //   char *defs[cls_def_cnt + cat_def_cnt];
5274193326Sed  // }
5275224145Sdim  SymtabTy =
5276226633Sdim    llvm::StructType::create("struct._objc_symtab",
5277226633Sdim                             LongTy, SelectorPtrTy, ShortTy, ShortTy,
5278226633Sdim                             llvm::ArrayType::get(Int8PtrTy, 0), NULL);
5279193326Sed  SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
5280193326Sed
5281193326Sed  // struct _objc_module {
5282193326Sed  //   long version;
5283193326Sed  //   long size;   // sizeof(struct _objc_module)
5284193326Sed  //   char *name;
5285193326Sed  //   struct _objc_symtab* symtab;
5286193326Sed  //  }
5287198092Srdivacky  ModuleTy =
5288226633Sdim    llvm::StructType::create("struct._objc_module",
5289226633Sdim                             LongTy, LongTy, Int8PtrTy, SymtabPtrTy, NULL);
5290193326Sed
5291198092Srdivacky
5292193326Sed  // FIXME: This is the size of the setjmp buffer and should be target
5293193326Sed  // specific. 18 is what's used on 32-bit X86.
5294193326Sed  uint64_t SetJmpBufferSize = 18;
5295198092Srdivacky
5296193326Sed  // Exceptions
5297234353Sdim  llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
5298198092Srdivacky
5299198092Srdivacky  ExceptionDataTy =
5300226633Sdim    llvm::StructType::create("struct._objc_exception_data",
5301234353Sdim                             llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
5302234353Sdim                             StackPtrTy, NULL);
5303193326Sed
5304193326Sed}
5305193326Sed
5306198092SrdivackyObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
5307198092Srdivacky  : ObjCCommonTypesHelper(cgm) {
5308193326Sed  // struct _method_list_t {
5309193326Sed  //   uint32_t entsize;  // sizeof(struct _objc_method)
5310193326Sed  //   uint32_t method_count;
5311193326Sed  //   struct _objc_method method_list[method_count];
5312193326Sed  // }
5313224145Sdim  MethodListnfABITy =
5314226633Sdim    llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
5315226633Sdim                             llvm::ArrayType::get(MethodTy, 0), NULL);
5316193326Sed  // struct method_list_t *
5317193326Sed  MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
5318198092Srdivacky
5319193326Sed  // struct _protocol_t {
5320193326Sed  //   id isa;  // NULL
5321193326Sed  //   const char * const protocol_name;
5322193326Sed  //   const struct _protocol_list_t * protocol_list; // super protocols
5323193326Sed  //   const struct method_list_t * const instance_methods;
5324193326Sed  //   const struct method_list_t * const class_methods;
5325193326Sed  //   const struct method_list_t *optionalInstanceMethods;
5326193326Sed  //   const struct method_list_t *optionalClassMethods;
5327193326Sed  //   const struct _prop_list_t * properties;
5328193326Sed  //   const uint32_t size;  // sizeof(struct _protocol_t)
5329193326Sed  //   const uint32_t flags;  // = 0
5330234353Sdim  //   const char ** extendedMethodTypes;
5331193326Sed  // }
5332198092Srdivacky
5333193326Sed  // Holder for struct _protocol_list_t *
5334224145Sdim  ProtocolListnfABITy =
5335226633Sdim    llvm::StructType::create(VMContext, "struct._objc_protocol_list");
5336198092Srdivacky
5337224145Sdim  ProtocolnfABITy =
5338226633Sdim    llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
5339226633Sdim                             llvm::PointerType::getUnqual(ProtocolListnfABITy),
5340226633Sdim                             MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5341226633Sdim                             MethodListnfABIPtrTy, MethodListnfABIPtrTy,
5342234353Sdim                             PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
5343234353Sdim                             NULL);
5344193326Sed
5345193326Sed  // struct _protocol_t*
5346193326Sed  ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
5347198092Srdivacky
5348193326Sed  // struct _protocol_list_t {
5349193326Sed  //   long protocol_count;   // Note, this is 32/64 bit
5350193326Sed  //   struct _protocol_t *[protocol_count];
5351193326Sed  // }
5352224145Sdim  ProtocolListnfABITy->setBody(LongTy,
5353224145Sdim                               llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
5354224145Sdim                               NULL);
5355198092Srdivacky
5356193326Sed  // struct _objc_protocol_list*
5357193326Sed  ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
5358198092Srdivacky
5359193326Sed  // struct _ivar_t {
5360193326Sed  //   unsigned long int *offset;  // pointer to ivar offset location
5361193326Sed  //   char *name;
5362193326Sed  //   char *type;
5363193326Sed  //   uint32_t alignment;
5364193326Sed  //   uint32_t size;
5365193326Sed  // }
5366224145Sdim  IvarnfABITy =
5367226633Sdim    llvm::StructType::create("struct._ivar_t",
5368226633Sdim                             llvm::PointerType::getUnqual(LongTy),
5369226633Sdim                             Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
5370198092Srdivacky
5371193326Sed  // struct _ivar_list_t {
5372193326Sed  //   uint32 entsize;  // sizeof(struct _ivar_t)
5373193326Sed  //   uint32 count;
5374193326Sed  //   struct _iver_t list[count];
5375193326Sed  // }
5376224145Sdim  IvarListnfABITy =
5377226633Sdim    llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
5378226633Sdim                             llvm::ArrayType::get(IvarnfABITy, 0), NULL);
5379198092Srdivacky
5380193326Sed  IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
5381198092Srdivacky
5382193326Sed  // struct _class_ro_t {
5383193326Sed  //   uint32_t const flags;
5384193326Sed  //   uint32_t const instanceStart;
5385193326Sed  //   uint32_t const instanceSize;
5386193326Sed  //   uint32_t const reserved;  // only when building for 64bit targets
5387193326Sed  //   const uint8_t * const ivarLayout;
5388193326Sed  //   const char *const name;
5389193326Sed  //   const struct _method_list_t * const baseMethods;
5390193326Sed  //   const struct _objc_protocol_list *const baseProtocols;
5391193326Sed  //   const struct _ivar_list_t *const ivars;
5392193326Sed  //   const uint8_t * const weakIvarLayout;
5393193326Sed  //   const struct _prop_list_t * const properties;
5394193326Sed  // }
5395198092Srdivacky
5396193326Sed  // FIXME. Add 'reserved' field in 64bit abi mode!
5397226633Sdim  ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
5398226633Sdim                                            IntTy, IntTy, IntTy, Int8PtrTy,
5399226633Sdim                                            Int8PtrTy, MethodListnfABIPtrTy,
5400226633Sdim                                            ProtocolListnfABIPtrTy,
5401226633Sdim                                            IvarListnfABIPtrTy,
5402226633Sdim                                            Int8PtrTy, PropertyListPtrTy, NULL);
5403198092Srdivacky
5404193326Sed  // ImpnfABITy - LLVM for id (*)(id, SEL, ...)
5405224145Sdim  llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
5406223017Sdim  ImpnfABITy = llvm::FunctionType::get(ObjectPtrTy, params, false)
5407223017Sdim                 ->getPointerTo();
5408198092Srdivacky
5409193326Sed  // struct _class_t {
5410193326Sed  //   struct _class_t *isa;
5411193326Sed  //   struct _class_t * const superclass;
5412193326Sed  //   void *cache;
5413193326Sed  //   IMP *vtable;
5414193326Sed  //   struct class_ro_t *ro;
5415193326Sed  // }
5416198092Srdivacky
5417226633Sdim  ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
5418224145Sdim  ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
5419224145Sdim                        llvm::PointerType::getUnqual(ClassnfABITy),
5420224145Sdim                        CachePtrTy,
5421224145Sdim                        llvm::PointerType::getUnqual(ImpnfABITy),
5422224145Sdim                        llvm::PointerType::getUnqual(ClassRonfABITy),
5423224145Sdim                        NULL);
5424193326Sed
5425193326Sed  // LLVM for struct _class_t *
5426193326Sed  ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
5427198092Srdivacky
5428193326Sed  // struct _category_t {
5429193326Sed  //   const char * const name;
5430193326Sed  //   struct _class_t *const cls;
5431193326Sed  //   const struct _method_list_t * const instance_methods;
5432193326Sed  //   const struct _method_list_t * const class_methods;
5433193326Sed  //   const struct _protocol_list_t * const protocols;
5434193326Sed  //   const struct _prop_list_t * const properties;
5435193326Sed  // }
5436226633Sdim  CategorynfABITy = llvm::StructType::create("struct._category_t",
5437226633Sdim                                             Int8PtrTy, ClassnfABIPtrTy,
5438226633Sdim                                             MethodListnfABIPtrTy,
5439226633Sdim                                             MethodListnfABIPtrTy,
5440226633Sdim                                             ProtocolListnfABIPtrTy,
5441226633Sdim                                             PropertyListPtrTy,
5442226633Sdim                                             NULL);
5443198092Srdivacky
5444193326Sed  // New types for nonfragile abi messaging.
5445193326Sed  CodeGen::CodeGenTypes &Types = CGM.getTypes();
5446193326Sed  ASTContext &Ctx = CGM.getContext();
5447198092Srdivacky
5448193326Sed  // MessageRefTy - LLVM for:
5449193326Sed  // struct _message_ref_t {
5450193326Sed  //   IMP messenger;
5451193326Sed  //   SEL name;
5452193326Sed  // };
5453198092Srdivacky
5454193326Sed  // First the clang type for struct _message_ref_t
5455208600Srdivacky  RecordDecl *RD = RecordDecl::Create(Ctx, TTK_Struct,
5456207619Srdivacky                                      Ctx.getTranslationUnitDecl(),
5457221345Sdim                                      SourceLocation(), SourceLocation(),
5458193326Sed                                      &Ctx.Idents.get("_message_ref_t"));
5459221345Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
5460239462Sdim                                Ctx.VoidPtrTy, 0, 0, false, ICIS_NoInit));
5461221345Sdim  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
5462239462Sdim                                Ctx.getObjCSelType(), 0, 0, false,
5463239462Sdim                                ICIS_NoInit));
5464203955Srdivacky  RD->completeDefinition();
5465198092Srdivacky
5466193326Sed  MessageRefCTy = Ctx.getTagDeclType(RD);
5467193326Sed  MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
5468193326Sed  MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
5469198092Srdivacky
5470193326Sed  // MessageRefPtrTy - LLVM for struct _message_ref_t*
5471193326Sed  MessageRefPtrTy = llvm::PointerType::getUnqual(MessageRefTy);
5472198092Srdivacky
5473193326Sed  // SuperMessageRefTy - LLVM for:
5474193326Sed  // struct _super_message_ref_t {
5475193326Sed  //   SUPER_IMP messenger;
5476193326Sed  //   SEL name;
5477193326Sed  // };
5478224145Sdim  SuperMessageRefTy =
5479226633Sdim    llvm::StructType::create("struct._super_message_ref_t",
5480226633Sdim                             ImpnfABITy, SelectorPtrTy, NULL);
5481198092Srdivacky
5482193326Sed  // SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
5483198092Srdivacky  SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
5484224145Sdim
5485193326Sed
5486193326Sed  // struct objc_typeinfo {
5487193326Sed  //   const void** vtable; // objc_ehtype_vtable + 2
5488193326Sed  //   const char*  name;    // c++ typeinfo string
5489193326Sed  //   Class        cls;
5490193326Sed  // };
5491224145Sdim  EHTypeTy =
5492226633Sdim    llvm::StructType::create("struct._objc_typeinfo",
5493226633Sdim                             llvm::PointerType::getUnqual(Int8PtrTy),
5494226633Sdim                             Int8PtrTy, ClassnfABIPtrTy, NULL);
5495193326Sed  EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
5496193326Sed}
5497193326Sed
5498198092Srdivackyllvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
5499193326Sed  FinishNonFragileABIModule();
5500198092Srdivacky
5501193326Sed  return NULL;
5502193326Sed}
5503193326Sed
5504234353Sdimvoid CGObjCNonFragileABIMac::
5505234353SdimAddModuleClassList(ArrayRef<llvm::GlobalValue*> Container,
5506234353Sdim                   const char *SymbolName,
5507234353Sdim                   const char *SectionName) {
5508193326Sed  unsigned NumClasses = Container.size();
5509198092Srdivacky
5510193326Sed  if (!NumClasses)
5511193326Sed    return;
5512198092Srdivacky
5513234353Sdim  SmallVector<llvm::Constant*, 8> Symbols(NumClasses);
5514193326Sed  for (unsigned i=0; i<NumClasses; i++)
5515193326Sed    Symbols[i] = llvm::ConstantExpr::getBitCast(Container[i],
5516193326Sed                                                ObjCTypes.Int8PtrTy);
5517234353Sdim  llvm::Constant *Init =
5518193326Sed    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.Int8PtrTy,
5519234353Sdim                                                  Symbols.size()),
5520193326Sed                             Symbols);
5521198092Srdivacky
5522193326Sed  llvm::GlobalVariable *GV =
5523198092Srdivacky    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
5524193326Sed                             llvm::GlobalValue::InternalLinkage,
5525193326Sed                             Init,
5526198092Srdivacky                             SymbolName);
5527243830Sdim  GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
5528193326Sed  GV->setSection(SectionName);
5529198092Srdivacky  CGM.AddUsedGlobal(GV);
5530193326Sed}
5531198092Srdivacky
5532193326Sedvoid CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
5533193326Sed  // nonfragile abi has no module definition.
5534198092Srdivacky
5535193326Sed  // Build list of all implemented class addresses in array
5536193326Sed  // L_OBJC_LABEL_CLASS_$.
5537198092Srdivacky  AddModuleClassList(DefinedClasses,
5538193326Sed                     "\01L_OBJC_LABEL_CLASS_$",
5539193326Sed                     "__DATA, __objc_classlist, regular, no_dead_strip");
5540199482Srdivacky
5541234353Sdim  for (unsigned i = 0, e = DefinedClasses.size(); i < e; i++) {
5542199482Srdivacky    llvm::GlobalValue *IMPLGV = DefinedClasses[i];
5543199482Srdivacky    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
5544199482Srdivacky      continue;
5545199482Srdivacky    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
5546199482Srdivacky  }
5547199482Srdivacky
5548234353Sdim  for (unsigned i = 0, e = DefinedMetaClasses.size(); i < e; i++) {
5549200583Srdivacky    llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
5550200583Srdivacky    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
5551200583Srdivacky      continue;
5552200583Srdivacky    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
5553200583Srdivacky  }
5554199482Srdivacky
5555198092Srdivacky  AddModuleClassList(DefinedNonLazyClasses,
5556193326Sed                     "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
5557193326Sed                     "__DATA, __objc_nlclslist, regular, no_dead_strip");
5558198092Srdivacky
5559193326Sed  // Build list of all implemented category addresses in array
5560193326Sed  // L_OBJC_LABEL_CATEGORY_$.
5561198092Srdivacky  AddModuleClassList(DefinedCategories,
5562193326Sed                     "\01L_OBJC_LABEL_CATEGORY_$",
5563193326Sed                     "__DATA, __objc_catlist, regular, no_dead_strip");
5564198092Srdivacky  AddModuleClassList(DefinedNonLazyCategories,
5565193326Sed                     "\01L_OBJC_LABEL_NONLAZY_CATEGORY_$",
5566193326Sed                     "__DATA, __objc_nlcatlist, regular, no_dead_strip");
5567198092Srdivacky
5568207619Srdivacky  EmitImageInfo();
5569193326Sed}
5570193326Sed
5571223017Sdim/// isVTableDispatchedSelector - Returns true if SEL is not in the list of
5572223017Sdim/// VTableDispatchMethods; false otherwise. What this means is that
5573198092Srdivacky/// except for the 19 selectors in the list, we generate 32bit-style
5574193326Sed/// message dispatch call for all the rest.
5575223017Sdimbool CGObjCNonFragileABIMac::isVTableDispatchedSelector(Selector Sel) {
5576223017Sdim  // At various points we've experimented with using vtable-based
5577223017Sdim  // dispatch for all methods.
5578207619Srdivacky  switch (CGM.getCodeGenOpts().getObjCDispatchMethod()) {
5579207619Srdivacky  case CodeGenOptions::Legacy:
5580223017Sdim    return false;
5581223017Sdim  case CodeGenOptions::NonLegacy:
5582203955Srdivacky    return true;
5583207619Srdivacky  case CodeGenOptions::Mixed:
5584207619Srdivacky    break;
5585207619Srdivacky  }
5586203955Srdivacky
5587207619Srdivacky  // If so, see whether this selector is in the white-list of things which must
5588207619Srdivacky  // use the new dispatch convention. We lazily build a dense set for this.
5589223017Sdim  if (VTableDispatchMethods.empty()) {
5590223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("alloc"));
5591223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("class"));
5592223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("self"));
5593223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("isFlipped"));
5594223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("length"));
5595223017Sdim    VTableDispatchMethods.insert(GetNullarySelector("count"));
5596198092Srdivacky
5597223017Sdim    // These are vtable-based if GC is disabled.
5598223017Sdim    // Optimistically use vtable dispatch for hybrid compiles.
5599234353Sdim    if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
5600223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("retain"));
5601223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("release"));
5602223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
5603223017Sdim    }
5604223017Sdim
5605223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("allocWithZone"));
5606223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("isKindOfClass"));
5607223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("respondsToSelector"));
5608223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("objectForKey"));
5609223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("objectAtIndex"));
5610223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("isEqualToString"));
5611223017Sdim    VTableDispatchMethods.insert(GetUnarySelector("isEqual"));
5612223017Sdim
5613223017Sdim    // These are vtable-based if GC is enabled.
5614223017Sdim    // Optimistically use vtable dispatch for hybrid compiles.
5615234353Sdim    if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
5616223017Sdim      VTableDispatchMethods.insert(GetNullarySelector("hash"));
5617223017Sdim      VTableDispatchMethods.insert(GetUnarySelector("addObject"));
5618223017Sdim
5619223017Sdim      // "countByEnumeratingWithState:objects:count"
5620223017Sdim      IdentifierInfo *KeyIdents[] = {
5621223017Sdim        &CGM.getContext().Idents.get("countByEnumeratingWithState"),
5622223017Sdim        &CGM.getContext().Idents.get("objects"),
5623223017Sdim        &CGM.getContext().Idents.get("count")
5624223017Sdim      };
5625223017Sdim      VTableDispatchMethods.insert(
5626223017Sdim        CGM.getContext().Selectors.getSelector(3, KeyIdents));
5627223017Sdim    }
5628193326Sed  }
5629207619Srdivacky
5630223017Sdim  return VTableDispatchMethods.count(Sel);
5631193326Sed}
5632193326Sed
5633193326Sed/// BuildClassRoTInitializer - generate meta-data for:
5634193326Sed/// struct _class_ro_t {
5635193326Sed///   uint32_t const flags;
5636193326Sed///   uint32_t const instanceStart;
5637193326Sed///   uint32_t const instanceSize;
5638193326Sed///   uint32_t const reserved;  // only when building for 64bit targets
5639193326Sed///   const uint8_t * const ivarLayout;
5640193326Sed///   const char *const name;
5641193326Sed///   const struct _method_list_t * const baseMethods;
5642193326Sed///   const struct _protocol_list_t *const baseProtocols;
5643193326Sed///   const struct _ivar_list_t *const ivars;
5644193326Sed///   const uint8_t * const weakIvarLayout;
5645193326Sed///   const struct _prop_list_t * const properties;
5646193326Sed/// }
5647193326Sed///
5648193326Sedllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
5649198092Srdivacky  unsigned flags,
5650198092Srdivacky  unsigned InstanceStart,
5651198092Srdivacky  unsigned InstanceSize,
5652198092Srdivacky  const ObjCImplementationDecl *ID) {
5653193326Sed  std::string ClassName = ID->getNameAsString();
5654234353Sdim  llvm::Constant *Values[10]; // 11 for 64bit targets!
5655224145Sdim
5656234353Sdim  if (CGM.getLangOpts().ObjCAutoRefCount)
5657243830Sdim    flags |= NonFragileABI_Class_CompiledByARC;
5658224145Sdim
5659193326Sed  Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
5660193326Sed  Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
5661193326Sed  Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
5662193326Sed  // FIXME. For 64bit targets add 0 here.
5663243830Sdim  Values[ 3] = (flags & NonFragileABI_Class_Meta)
5664243830Sdim    ? GetIvarLayoutName(0, ObjCTypes)
5665198092Srdivacky    : BuildIvarLayout(ID, true);
5666193326Sed  Values[ 4] = GetClassName(ID->getIdentifier());
5667193326Sed  // const struct _method_list_t * const baseMethods;
5668193326Sed  std::vector<llvm::Constant*> Methods;
5669193326Sed  std::string MethodListName("\01l_OBJC_$_");
5670243830Sdim  if (flags & NonFragileABI_Class_Meta) {
5671193326Sed    MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
5672198092Srdivacky    for (ObjCImplementationDecl::classmeth_iterator
5673195341Sed           i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
5674193326Sed      // Class methods should always be defined.
5675193326Sed      Methods.push_back(GetMethodConstant(*i));
5676193326Sed    }
5677193326Sed  } else {
5678193326Sed    MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
5679198092Srdivacky    for (ObjCImplementationDecl::instmeth_iterator
5680195341Sed           i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
5681193326Sed      // Instance methods should always be defined.
5682193326Sed      Methods.push_back(GetMethodConstant(*i));
5683193326Sed    }
5684198092Srdivacky    for (ObjCImplementationDecl::propimpl_iterator
5685195341Sed           i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
5686193326Sed      ObjCPropertyImplDecl *PID = *i;
5687198092Srdivacky
5688193326Sed      if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
5689193326Sed        ObjCPropertyDecl *PD = PID->getPropertyDecl();
5690198092Srdivacky
5691193326Sed        if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
5692193326Sed          if (llvm::Constant *C = GetMethodConstant(MD))
5693193326Sed            Methods.push_back(C);
5694193326Sed        if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
5695193326Sed          if (llvm::Constant *C = GetMethodConstant(MD))
5696193326Sed            Methods.push_back(C);
5697193326Sed      }
5698193326Sed    }
5699193326Sed  }
5700198092Srdivacky  Values[ 5] = EmitMethodList(MethodListName,
5701198092Srdivacky                              "__DATA, __objc_const", Methods);
5702198092Srdivacky
5703193326Sed  const ObjCInterfaceDecl *OID = ID->getClassInterface();
5704193326Sed  assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
5705198092Srdivacky  Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
5706198398Srdivacky                                + OID->getName(),
5707212904Sdim                                OID->all_referenced_protocol_begin(),
5708212904Sdim                                OID->all_referenced_protocol_end());
5709198092Srdivacky
5710243830Sdim  if (flags & NonFragileABI_Class_Meta) {
5711193326Sed    Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
5712243830Sdim    Values[ 8] = GetIvarLayoutName(0, ObjCTypes);
5713243830Sdim    Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
5714243830Sdim  } else {
5715193326Sed    Values[ 7] = EmitIvarList(ID);
5716243830Sdim    Values[ 8] = BuildIvarLayout(ID, false);
5717198398Srdivacky    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
5718198398Srdivacky                                  ID, ID->getClassInterface(), ObjCTypes);
5719243830Sdim  }
5720193326Sed  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
5721193326Sed                                                   Values);
5722193326Sed  llvm::GlobalVariable *CLASS_RO_GV =
5723198092Srdivacky    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
5724198092Srdivacky                             llvm::GlobalValue::InternalLinkage,
5725198092Srdivacky                             Init,
5726243830Sdim                             (flags & NonFragileABI_Class_Meta) ?
5727198092Srdivacky                             std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
5728198092Srdivacky                             std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
5729193326Sed  CLASS_RO_GV->setAlignment(
5730243830Sdim    CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
5731193326Sed  CLASS_RO_GV->setSection("__DATA, __objc_const");
5732193326Sed  return CLASS_RO_GV;
5733193326Sed
5734193326Sed}
5735193326Sed
5736193326Sed/// BuildClassMetaData - This routine defines that to-level meta-data
5737193326Sed/// for the given ClassName for:
5738193326Sed/// struct _class_t {
5739193326Sed///   struct _class_t *isa;
5740193326Sed///   struct _class_t * const superclass;
5741193326Sed///   void *cache;
5742193326Sed///   IMP *vtable;
5743193326Sed///   struct class_ro_t *ro;
5744193326Sed/// }
5745193326Sed///
5746193326Sedllvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
5747198092Srdivacky  std::string &ClassName,
5748198092Srdivacky  llvm::Constant *IsAGV,
5749198092Srdivacky  llvm::Constant *SuperClassGV,
5750198092Srdivacky  llvm::Constant *ClassRoGV,
5751198092Srdivacky  bool HiddenVisibility) {
5752234353Sdim  llvm::Constant *Values[] = {
5753234353Sdim    IsAGV,
5754234353Sdim    SuperClassGV,
5755234353Sdim    ObjCEmptyCacheVar,  // &ObjCEmptyCacheVar
5756234353Sdim    ObjCEmptyVtableVar, // &ObjCEmptyVtableVar
5757234353Sdim    ClassRoGV           // &CLASS_RO_GV
5758234353Sdim  };
5759198092Srdivacky  if (!Values[1])
5760198092Srdivacky    Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy);
5761263508Sdim  if (!Values[3])
5762263508Sdim    Values[3] = llvm::Constant::getNullValue(
5763263508Sdim                  llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
5764198092Srdivacky  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
5765193326Sed                                                   Values);
5766193326Sed  llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
5767193326Sed  GV->setInitializer(Init);
5768193326Sed  GV->setSection("__DATA, __objc_data");
5769193326Sed  GV->setAlignment(
5770243830Sdim    CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABITy));
5771193326Sed  if (HiddenVisibility)
5772193326Sed    GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5773193326Sed  return GV;
5774193326Sed}
5775193326Sed
5776198092Srdivackybool
5777193326SedCGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
5778195341Sed  return OD->getClassMethod(GetNullarySelector("load")) != 0;
5779193326Sed}
5780193326Sed
5781193326Sedvoid CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
5782193326Sed                                              uint32_t &InstanceStart,
5783193326Sed                                              uint32_t &InstanceSize) {
5784198092Srdivacky  const ASTRecordLayout &RL =
5785193326Sed    CGM.getContext().getASTObjCImplementationLayout(OID);
5786198092Srdivacky
5787193326Sed  // InstanceSize is really instance end.
5788218893Sdim  InstanceSize = RL.getDataSize().getQuantity();
5789193326Sed
5790193326Sed  // If there are no fields, the start is the same as the end.
5791193326Sed  if (!RL.getFieldCount())
5792193326Sed    InstanceStart = InstanceSize;
5793193326Sed  else
5794221345Sdim    InstanceStart = RL.getFieldOffset(0) / CGM.getContext().getCharWidth();
5795193326Sed}
5796193326Sed
5797193326Sedvoid CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
5798193326Sed  std::string ClassName = ID->getNameAsString();
5799193326Sed  if (!ObjCEmptyCacheVar) {
5800193326Sed    ObjCEmptyCacheVar = new llvm::GlobalVariable(
5801198092Srdivacky      CGM.getModule(),
5802198092Srdivacky      ObjCTypes.CacheTy,
5803198092Srdivacky      false,
5804198092Srdivacky      llvm::GlobalValue::ExternalLinkage,
5805198092Srdivacky      0,
5806198092Srdivacky      "_objc_empty_cache");
5807263508Sdim
5808263508Sdim    // Make this entry NULL for any iOS device target, any iOS simulator target,
5809263508Sdim    // OS X with deployment target 10.9 or later.
5810263508Sdim    const llvm::Triple &Triple = CGM.getTarget().getTriple();
5811263508Sdim    if (Triple.isiOS() || (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9)))
5812263508Sdim      // This entry will be null.
5813263508Sdim      ObjCEmptyVtableVar = 0;
5814263508Sdim    else
5815263508Sdim      ObjCEmptyVtableVar = new llvm::GlobalVariable(
5816263508Sdim                                                    CGM.getModule(),
5817263508Sdim                                                    ObjCTypes.ImpnfABITy,
5818263508Sdim                                                    false,
5819263508Sdim                                                    llvm::GlobalValue::ExternalLinkage,
5820263508Sdim                                                    0,
5821263508Sdim                                                    "_objc_empty_vtable");
5822193326Sed  }
5823198092Srdivacky  assert(ID->getClassInterface() &&
5824193326Sed         "CGObjCNonFragileABIMac::GenerateClass - class is 0");
5825193326Sed  // FIXME: Is this correct (that meta class size is never computed)?
5826198092Srdivacky  uint32_t InstanceStart =
5827243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
5828193326Sed  uint32_t InstanceSize = InstanceStart;
5829243830Sdim  uint32_t flags = NonFragileABI_Class_Meta;
5830193326Sed  std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
5831193326Sed  std::string ObjCClassName(getClassSymbolPrefix());
5832198092Srdivacky
5833193326Sed  llvm::GlobalVariable *SuperClassGV, *IsAGV;
5834198092Srdivacky
5835243830Sdim  // Build the flags for the metaclass.
5836198092Srdivacky  bool classIsHidden =
5837218893Sdim    ID->getClassInterface()->getVisibility() == HiddenVisibility;
5838193326Sed  if (classIsHidden)
5839243830Sdim    flags |= NonFragileABI_Class_Hidden;
5840243830Sdim
5841243830Sdim  // FIXME: why is this flag set on the metaclass?
5842243830Sdim  // ObjC metaclasses have no fields and don't really get constructed.
5843243830Sdim  if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
5844243830Sdim    flags |= NonFragileABI_Class_HasCXXStructors;
5845243830Sdim    if (!ID->hasNonZeroConstructors())
5846243830Sdim      flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5847243830Sdim  }
5848243830Sdim
5849193326Sed  if (!ID->getClassInterface()->getSuperClass()) {
5850193326Sed    // class is root
5851243830Sdim    flags |= NonFragileABI_Class_Root;
5852193326Sed    SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
5853193326Sed    IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
5854193326Sed  } else {
5855193326Sed    // Has a root. Current class is not a root.
5856193326Sed    const ObjCInterfaceDecl *Root = ID->getClassInterface();
5857193326Sed    while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
5858193326Sed      Root = Super;
5859193326Sed    IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
5860221345Sdim    if (Root->isWeakImported())
5861200583Srdivacky      IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5862193326Sed    // work on super class metadata symbol.
5863198092Srdivacky    std::string SuperClassName =
5864200583Srdivacky      ObjCMetaClassName +
5865200583Srdivacky        ID->getClassInterface()->getSuperClass()->getNameAsString();
5866193326Sed    SuperClassGV = GetClassGlobal(SuperClassName);
5867221345Sdim    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5868199482Srdivacky      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5869193326Sed  }
5870193326Sed  llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
5871193326Sed                                                               InstanceStart,
5872193326Sed                                                               InstanceSize,ID);
5873193326Sed  std::string TClassName = ObjCMetaClassName + ClassName;
5874198092Srdivacky  llvm::GlobalVariable *MetaTClass =
5875193326Sed    BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
5876193326Sed                       classIsHidden);
5877199482Srdivacky  DefinedMetaClasses.push_back(MetaTClass);
5878193326Sed
5879193326Sed  // Metadata for the class
5880243830Sdim  flags = 0;
5881193326Sed  if (classIsHidden)
5882243830Sdim    flags |= NonFragileABI_Class_Hidden;
5883193326Sed
5884243830Sdim  if (ID->hasNonZeroConstructors() || ID->hasDestructors()) {
5885243830Sdim    flags |= NonFragileABI_Class_HasCXXStructors;
5886243830Sdim
5887243830Sdim    // Set a flag to enable a runtime optimization when a class has
5888243830Sdim    // fields that require destruction but which don't require
5889243830Sdim    // anything except zero-initialization during construction.  This
5890243830Sdim    // is most notably true of __strong and __weak types, but you can
5891243830Sdim    // also imagine there being C++ types with non-trivial default
5892243830Sdim    // constructors that merely set all fields to null.
5893243830Sdim    if (!ID->hasNonZeroConstructors())
5894243830Sdim      flags |= NonFragileABI_Class_HasCXXDestructorOnly;
5895243830Sdim  }
5896243830Sdim
5897194613Sed  if (hasObjCExceptionAttribute(CGM.getContext(), ID->getClassInterface()))
5898243830Sdim    flags |= NonFragileABI_Class_Exception;
5899193326Sed
5900193326Sed  if (!ID->getClassInterface()->getSuperClass()) {
5901243830Sdim    flags |= NonFragileABI_Class_Root;
5902193326Sed    SuperClassGV = 0;
5903193326Sed  } else {
5904193326Sed    // Has a root. Current class is not a root.
5905193326Sed    std::string RootClassName =
5906193326Sed      ID->getClassInterface()->getSuperClass()->getNameAsString();
5907193326Sed    SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
5908221345Sdim    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
5909199482Srdivacky      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5910193326Sed  }
5911193326Sed  GetClassSizeInfo(ID, InstanceStart, InstanceSize);
5912193326Sed  CLASS_RO_GV = BuildClassRoTInitializer(flags,
5913193326Sed                                         InstanceStart,
5914198092Srdivacky                                         InstanceSize,
5915193326Sed                                         ID);
5916198092Srdivacky
5917193326Sed  TClassName = ObjCClassName + ClassName;
5918198092Srdivacky  llvm::GlobalVariable *ClassMD =
5919193326Sed    BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
5920193326Sed                       classIsHidden);
5921193326Sed  DefinedClasses.push_back(ClassMD);
5922193326Sed
5923193326Sed  // Determine if this class is also "non-lazy".
5924193326Sed  if (ImplementationIsNonLazy(ID))
5925193326Sed    DefinedNonLazyClasses.push_back(ClassMD);
5926193326Sed
5927193326Sed  // Force the definition of the EHType if necessary.
5928243830Sdim  if (flags & NonFragileABI_Class_Exception)
5929193326Sed    GetInterfaceEHType(ID->getClassInterface(), true);
5930221345Sdim  // Make sure method definition entries are all clear for next implementation.
5931221345Sdim  MethodDefinitions.clear();
5932193326Sed}
5933193326Sed
5934193326Sed/// GenerateProtocolRef - This routine is called to generate code for
5935193326Sed/// a protocol reference expression; as in:
5936193326Sed/// @code
5937193326Sed///   @protocol(Proto1);
5938193326Sed/// @endcode
5939193326Sed/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1
5940193326Sed/// which will hold address of the protocol meta-data.
5941193326Sed///
5942249423Sdimllvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF,
5943198092Srdivacky                                                         const ObjCProtocolDecl *PD) {
5944198092Srdivacky
5945193326Sed  // This routine is called for @protocol only. So, we must build definition
5946193326Sed  // of protocol's meta-data (not a reference to it!)
5947193326Sed  //
5948198092Srdivacky  llvm::Constant *Init =
5949198092Srdivacky    llvm::ConstantExpr::getBitCast(GetOrEmitProtocol(PD),
5950234353Sdim                                   ObjCTypes.getExternalProtocolPtrTy());
5951198092Srdivacky
5952193326Sed  std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
5953212904Sdim  ProtocolName += PD->getName();
5954198092Srdivacky
5955193326Sed  llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
5956193326Sed  if (PTGV)
5957249423Sdim    return CGF.Builder.CreateLoad(PTGV);
5958193326Sed  PTGV = new llvm::GlobalVariable(
5959198092Srdivacky    CGM.getModule(),
5960198092Srdivacky    Init->getType(), false,
5961198092Srdivacky    llvm::GlobalValue::WeakAnyLinkage,
5962198092Srdivacky    Init,
5963198092Srdivacky    ProtocolName);
5964193326Sed  PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
5965193326Sed  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
5966198092Srdivacky  CGM.AddUsedGlobal(PTGV);
5967249423Sdim  return CGF.Builder.CreateLoad(PTGV);
5968193326Sed}
5969193326Sed
5970193326Sed/// GenerateCategory - Build metadata for a category implementation.
5971193326Sed/// struct _category_t {
5972193326Sed///   const char * const name;
5973193326Sed///   struct _class_t *const cls;
5974193326Sed///   const struct _method_list_t * const instance_methods;
5975193326Sed///   const struct _method_list_t * const class_methods;
5976193326Sed///   const struct _protocol_list_t * const protocols;
5977193326Sed///   const struct _prop_list_t * const properties;
5978193326Sed/// }
5979193326Sed///
5980193326Sedvoid CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
5981193326Sed  const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
5982193326Sed  const char *Prefix = "\01l_OBJC_$_CATEGORY_";
5983198092Srdivacky  std::string ExtCatName(Prefix + Interface->getNameAsString()+
5984198092Srdivacky                         "_$_" + OCD->getNameAsString());
5985198092Srdivacky  std::string ExtClassName(getClassSymbolPrefix() +
5986193326Sed                           Interface->getNameAsString());
5987198092Srdivacky
5988234353Sdim  llvm::Constant *Values[6];
5989193326Sed  Values[0] = GetClassName(OCD->getIdentifier());
5990193326Sed  // meta-class entry symbol
5991193326Sed  llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
5992221345Sdim  if (Interface->isWeakImported())
5993199482Srdivacky    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
5994199482Srdivacky
5995193326Sed  Values[1] = ClassGV;
5996193326Sed  std::vector<llvm::Constant*> Methods;
5997193326Sed  std::string MethodListName(Prefix);
5998198092Srdivacky  MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
5999193326Sed    "_$_" + OCD->getNameAsString();
6000198092Srdivacky
6001198092Srdivacky  for (ObjCCategoryImplDecl::instmeth_iterator
6002195341Sed         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
6003193326Sed    // Instance methods should always be defined.
6004193326Sed    Methods.push_back(GetMethodConstant(*i));
6005193326Sed  }
6006198092Srdivacky
6007198092Srdivacky  Values[2] = EmitMethodList(MethodListName,
6008198092Srdivacky                             "__DATA, __objc_const",
6009193326Sed                             Methods);
6010193326Sed
6011193326Sed  MethodListName = Prefix;
6012193326Sed  MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
6013193326Sed    OCD->getNameAsString();
6014193326Sed  Methods.clear();
6015198092Srdivacky  for (ObjCCategoryImplDecl::classmeth_iterator
6016195341Sed         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
6017193326Sed    // Class methods should always be defined.
6018193326Sed    Methods.push_back(GetMethodConstant(*i));
6019193326Sed  }
6020198092Srdivacky
6021198092Srdivacky  Values[3] = EmitMethodList(MethodListName,
6022198092Srdivacky                             "__DATA, __objc_const",
6023193326Sed                             Methods);
6024198092Srdivacky  const ObjCCategoryDecl *Category =
6025193326Sed    Interface->FindCategoryDeclaration(OCD->getIdentifier());
6026193326Sed  if (Category) {
6027234353Sdim    SmallString<256> ExtName;
6028198398Srdivacky    llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
6029198398Srdivacky                                       << OCD->getName();
6030193326Sed    Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
6031198398Srdivacky                                 + Interface->getName() + "_$_"
6032198398Srdivacky                                 + Category->getName(),
6033193326Sed                                 Category->protocol_begin(),
6034193326Sed                                 Category->protocol_end());
6035198398Srdivacky    Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
6036198398Srdivacky                                 OCD, Category, ObjCTypes);
6037198092Srdivacky  } else {
6038193326Sed    Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6039193326Sed    Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
6040193326Sed  }
6041198092Srdivacky
6042198092Srdivacky  llvm::Constant *Init =
6043198092Srdivacky    llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy,
6044193326Sed                              Values);
6045193326Sed  llvm::GlobalVariable *GCATV
6046198092Srdivacky    = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
6047193326Sed                               false,
6048193326Sed                               llvm::GlobalValue::InternalLinkage,
6049193326Sed                               Init,
6050198092Srdivacky                               ExtCatName);
6051193326Sed  GCATV->setAlignment(
6052243830Sdim    CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
6053193326Sed  GCATV->setSection("__DATA, __objc_const");
6054198092Srdivacky  CGM.AddUsedGlobal(GCATV);
6055193326Sed  DefinedCategories.push_back(GCATV);
6056193326Sed
6057193326Sed  // Determine if this category is also "non-lazy".
6058193326Sed  if (ImplementationIsNonLazy(OCD))
6059193326Sed    DefinedNonLazyCategories.push_back(GCATV);
6060221345Sdim  // method definition entries must be clear for next implementation.
6061221345Sdim  MethodDefinitions.clear();
6062193326Sed}
6063193326Sed
6064193326Sed/// GetMethodConstant - Return a struct objc_method constant for the
6065193326Sed/// given method if it has been defined. The result is null if the
6066193326Sed/// method has not been defined. The return value has type MethodPtrTy.
6067193326Sedllvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant(
6068198092Srdivacky  const ObjCMethodDecl *MD) {
6069212904Sdim  llvm::Function *Fn = GetMethodDefinition(MD);
6070193326Sed  if (!Fn)
6071193326Sed    return 0;
6072198092Srdivacky
6073234353Sdim  llvm::Constant *Method[] = {
6074198092Srdivacky    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6075234353Sdim                                   ObjCTypes.SelectorPtrTy),
6076234353Sdim    GetMethodVarType(MD),
6077234353Sdim    llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy)
6078234353Sdim  };
6079193326Sed  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method);
6080193326Sed}
6081193326Sed
6082193326Sed/// EmitMethodList - Build meta-data for method declarations
6083193326Sed/// struct _method_list_t {
6084193326Sed///   uint32_t entsize;  // sizeof(struct _objc_method)
6085193326Sed///   uint32_t method_count;
6086193326Sed///   struct _objc_method method_list[method_count];
6087193326Sed/// }
6088193326Sed///
6089234353Sdimllvm::Constant *
6090234353SdimCGObjCNonFragileABIMac::EmitMethodList(Twine Name,
6091234353Sdim                                       const char *Section,
6092234353Sdim                                       ArrayRef<llvm::Constant*> Methods) {
6093193326Sed  // Return null for empty list.
6094193326Sed  if (Methods.empty())
6095193326Sed    return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy);
6096198092Srdivacky
6097224145Sdim  llvm::Constant *Values[3];
6098193326Sed  // sizeof(struct _objc_method)
6099243830Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.MethodTy);
6100193326Sed  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6101193326Sed  // method_count
6102193326Sed  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size());
6103193326Sed  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy,
6104193326Sed                                             Methods.size());
6105193326Sed  Values[2] = llvm::ConstantArray::get(AT, Methods);
6106224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6107198092Srdivacky
6108193326Sed  llvm::GlobalVariable *GV =
6109198092Srdivacky    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6110224145Sdim                             llvm::GlobalValue::InternalLinkage, Init, Name);
6111243830Sdim  GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6112193326Sed  GV->setSection(Section);
6113198092Srdivacky  CGM.AddUsedGlobal(GV);
6114224145Sdim  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
6115193326Sed}
6116193326Sed
6117193326Sed/// ObjCIvarOffsetVariable - Returns the ivar offset variable for
6118193326Sed/// the given ivar.
6119206125Srdivackyllvm::GlobalVariable *
6120206125SrdivackyCGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
6121206125Srdivacky                                               const ObjCIvarDecl *Ivar) {
6122206125Srdivacky  const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
6123193326Sed  std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
6124193326Sed    '.' + Ivar->getNameAsString();
6125198092Srdivacky  llvm::GlobalVariable *IvarOffsetGV =
6126193326Sed    CGM.getModule().getGlobalVariable(Name);
6127193326Sed  if (!IvarOffsetGV)
6128198092Srdivacky    IvarOffsetGV =
6129198092Srdivacky      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
6130193326Sed                               false,
6131193326Sed                               llvm::GlobalValue::ExternalLinkage,
6132193326Sed                               0,
6133198092Srdivacky                               Name);
6134193326Sed  return IvarOffsetGV;
6135193326Sed}
6136193326Sed
6137206125Srdivackyllvm::Constant *
6138206125SrdivackyCGObjCNonFragileABIMac::EmitIvarOffsetVar(const ObjCInterfaceDecl *ID,
6139206125Srdivacky                                          const ObjCIvarDecl *Ivar,
6140206125Srdivacky                                          unsigned long int Offset) {
6141193326Sed  llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
6142198092Srdivacky  IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
6143193326Sed                                                      Offset));
6144193326Sed  IvarOffsetGV->setAlignment(
6145243830Sdim    CGM.getDataLayout().getABITypeAlignment(ObjCTypes.LongTy));
6146193326Sed
6147193326Sed  // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
6148193326Sed  // well (i.e., in ObjCIvarOffsetVariable).
6149193326Sed  if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
6150193326Sed      Ivar->getAccessControl() == ObjCIvarDecl::Package ||
6151218893Sdim      ID->getVisibility() == HiddenVisibility)
6152193326Sed    IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6153193326Sed  else
6154193326Sed    IvarOffsetGV->setVisibility(llvm::GlobalValue::DefaultVisibility);
6155223017Sdim  IvarOffsetGV->setSection("__DATA, __objc_ivar");
6156193326Sed  return IvarOffsetGV;
6157193326Sed}
6158193326Sed
6159193326Sed/// EmitIvarList - Emit the ivar list for the given
6160193326Sed/// implementation. The return value has type
6161193326Sed/// IvarListnfABIPtrTy.
6162193326Sed///  struct _ivar_t {
6163193326Sed///   unsigned long int *offset;  // pointer to ivar offset location
6164193326Sed///   char *name;
6165193326Sed///   char *type;
6166193326Sed///   uint32_t alignment;
6167193326Sed///   uint32_t size;
6168193326Sed/// }
6169193326Sed/// struct _ivar_list_t {
6170193326Sed///   uint32 entsize;  // sizeof(struct _ivar_t)
6171193326Sed///   uint32 count;
6172193326Sed///   struct _iver_t list[count];
6173193326Sed/// }
6174193326Sed///
6175193326Sed
6176193326Sedllvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
6177198092Srdivacky  const ObjCImplementationDecl *ID) {
6178198092Srdivacky
6179234353Sdim  std::vector<llvm::Constant*> Ivars;
6180198092Srdivacky
6181226633Sdim  const ObjCInterfaceDecl *OID = ID->getClassInterface();
6182193326Sed  assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface");
6183198092Srdivacky
6184193326Sed  // FIXME. Consolidate this with similar code in GenerateClass.
6185198092Srdivacky
6186226633Sdim  for (const ObjCIvarDecl *IVD = OID->all_declared_ivar_begin();
6187224145Sdim       IVD; IVD = IVD->getNextIvar()) {
6188193576Sed    // Ignore unnamed bit-fields.
6189193576Sed    if (!IVD->getDeclName())
6190193576Sed      continue;
6191234353Sdim    llvm::Constant *Ivar[5];
6192198092Srdivacky    Ivar[0] = EmitIvarOffsetVar(ID->getClassInterface(), IVD,
6193193326Sed                                ComputeIvarBaseOffset(CGM, ID, IVD));
6194193326Sed    Ivar[1] = GetMethodVarName(IVD->getIdentifier());
6195193326Sed    Ivar[2] = GetMethodVarType(IVD);
6196226633Sdim    llvm::Type *FieldTy =
6197193326Sed      CGM.getTypes().ConvertTypeForMem(IVD->getType());
6198243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(FieldTy);
6199193326Sed    unsigned Align = CGM.getContext().getPreferredTypeAlign(
6200198092Srdivacky      IVD->getType().getTypePtr()) >> 3;
6201193326Sed    Align = llvm::Log2_32(Align);
6202193326Sed    Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align);
6203193326Sed    // NOTE. Size of a bitfield does not match gcc's, because of the
6204193326Sed    // way bitfields are treated special in each. But I am told that
6205193326Sed    // 'size' for bitfield ivars is ignored by the runtime so it does
6206193326Sed    // not matter.  If it matters, there is enough info to get the
6207193326Sed    // bitfield right!
6208193326Sed    Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6209193326Sed    Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar));
6210193326Sed  }
6211193326Sed  // Return null for empty list.
6212193326Sed  if (Ivars.empty())
6213193326Sed    return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
6214224145Sdim
6215224145Sdim  llvm::Constant *Values[3];
6216243830Sdim  unsigned Size = CGM.getDataLayout().getTypeAllocSize(ObjCTypes.IvarnfABITy);
6217193326Sed  Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6218193326Sed  Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size());
6219193326Sed  llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy,
6220193326Sed                                             Ivars.size());
6221193326Sed  Values[2] = llvm::ConstantArray::get(AT, Ivars);
6222224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6223193326Sed  const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
6224193326Sed  llvm::GlobalVariable *GV =
6225198092Srdivacky    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6226193326Sed                             llvm::GlobalValue::InternalLinkage,
6227193326Sed                             Init,
6228198398Srdivacky                             Prefix + OID->getName());
6229193326Sed  GV->setAlignment(
6230243830Sdim    CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6231193326Sed  GV->setSection("__DATA, __objc_const");
6232198092Srdivacky
6233198092Srdivacky  CGM.AddUsedGlobal(GV);
6234198092Srdivacky  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
6235193326Sed}
6236193326Sed
6237193326Sedllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
6238198092Srdivacky  const ObjCProtocolDecl *PD) {
6239193326Sed  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
6240198092Srdivacky
6241193326Sed  if (!Entry) {
6242193326Sed    // We use the initializer as a marker of whether this is a forward
6243193326Sed    // reference or not. At module finalization we add the empty
6244193326Sed    // contents for protocols which were referenced but never defined.
6245198092Srdivacky    Entry =
6246198092Srdivacky      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
6247198092Srdivacky                               llvm::GlobalValue::ExternalLinkage,
6248198092Srdivacky                               0,
6249198398Srdivacky                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
6250193326Sed    Entry->setSection("__DATA,__datacoal_nt,coalesced");
6251193326Sed  }
6252198092Srdivacky
6253193326Sed  return Entry;
6254193326Sed}
6255193326Sed
6256193326Sed/// GetOrEmitProtocol - Generate the protocol meta-data:
6257193326Sed/// @code
6258193326Sed/// struct _protocol_t {
6259193326Sed///   id isa;  // NULL
6260193326Sed///   const char * const protocol_name;
6261193326Sed///   const struct _protocol_list_t * protocol_list; // super protocols
6262193326Sed///   const struct method_list_t * const instance_methods;
6263193326Sed///   const struct method_list_t * const class_methods;
6264193326Sed///   const struct method_list_t *optionalInstanceMethods;
6265193326Sed///   const struct method_list_t *optionalClassMethods;
6266193326Sed///   const struct _prop_list_t * properties;
6267193326Sed///   const uint32_t size;  // sizeof(struct _protocol_t)
6268193326Sed///   const uint32_t flags;  // = 0
6269234353Sdim///   const char ** extendedMethodTypes;
6270193326Sed/// }
6271193326Sed/// @endcode
6272193326Sed///
6273193326Sed
6274193326Sedllvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
6275198092Srdivacky  const ObjCProtocolDecl *PD) {
6276234353Sdim  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
6277198092Srdivacky
6278193326Sed  // Early exit if a defining object has already been generated.
6279193326Sed  if (Entry && Entry->hasInitializer())
6280193326Sed    return Entry;
6281193326Sed
6282234353Sdim  // Use the protocol definition, if there is one.
6283234353Sdim  if (const ObjCProtocolDecl *Def = PD->getDefinition())
6284234353Sdim    PD = Def;
6285234353Sdim
6286193326Sed  // Construct method lists.
6287193326Sed  std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
6288193326Sed  std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
6289234353Sdim  std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
6290198092Srdivacky  for (ObjCProtocolDecl::instmeth_iterator
6291195341Sed         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
6292193326Sed    ObjCMethodDecl *MD = *i;
6293193326Sed    llvm::Constant *C = GetMethodDescriptionConstant(MD);
6294223017Sdim    if (!C)
6295223017Sdim      return GetOrEmitProtocolRef(PD);
6296223017Sdim
6297193326Sed    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6298193326Sed      OptInstanceMethods.push_back(C);
6299234353Sdim      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6300193326Sed    } else {
6301193326Sed      InstanceMethods.push_back(C);
6302234353Sdim      MethodTypesExt.push_back(GetMethodVarType(MD, true));
6303198092Srdivacky    }
6304193326Sed  }
6305198092Srdivacky
6306198092Srdivacky  for (ObjCProtocolDecl::classmeth_iterator
6307195341Sed         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
6308193326Sed    ObjCMethodDecl *MD = *i;
6309193326Sed    llvm::Constant *C = GetMethodDescriptionConstant(MD);
6310223017Sdim    if (!C)
6311223017Sdim      return GetOrEmitProtocolRef(PD);
6312223017Sdim
6313193326Sed    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
6314193326Sed      OptClassMethods.push_back(C);
6315234353Sdim      OptMethodTypesExt.push_back(GetMethodVarType(MD, true));
6316193326Sed    } else {
6317193326Sed      ClassMethods.push_back(C);
6318234353Sdim      MethodTypesExt.push_back(GetMethodVarType(MD, true));
6319198092Srdivacky    }
6320193326Sed  }
6321198092Srdivacky
6322234353Sdim  MethodTypesExt.insert(MethodTypesExt.end(),
6323234353Sdim                        OptMethodTypesExt.begin(), OptMethodTypesExt.end());
6324234353Sdim
6325234353Sdim  llvm::Constant *Values[11];
6326193326Sed  // isa is NULL
6327193326Sed  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
6328193326Sed  Values[1] = GetClassName(PD->getIdentifier());
6329198398Srdivacky  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
6330198398Srdivacky                               PD->protocol_begin(),
6331198398Srdivacky                               PD->protocol_end());
6332198092Srdivacky
6333193326Sed  Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
6334198398Srdivacky                             + PD->getName(),
6335193326Sed                             "__DATA, __objc_const",
6336193326Sed                             InstanceMethods);
6337198092Srdivacky  Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
6338198398Srdivacky                             + PD->getName(),
6339193326Sed                             "__DATA, __objc_const",
6340193326Sed                             ClassMethods);
6341193326Sed  Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
6342198398Srdivacky                             + PD->getName(),
6343193326Sed                             "__DATA, __objc_const",
6344193326Sed                             OptInstanceMethods);
6345198092Srdivacky  Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
6346198398Srdivacky                             + PD->getName(),
6347193326Sed                             "__DATA, __objc_const",
6348193326Sed                             OptClassMethods);
6349198398Srdivacky  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
6350193326Sed                               0, PD, ObjCTypes);
6351198092Srdivacky  uint32_t Size =
6352243830Sdim    CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
6353193326Sed  Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
6354193326Sed  Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
6355234353Sdim  Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
6356234353Sdim                                       + PD->getName(),
6357234353Sdim                                       MethodTypesExt, ObjCTypes);
6358193326Sed  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
6359193326Sed                                                   Values);
6360198092Srdivacky
6361193326Sed  if (Entry) {
6362193326Sed    // Already created, fix the linkage and update the initializer.
6363193326Sed    Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6364193326Sed    Entry->setInitializer(Init);
6365193326Sed  } else {
6366198092Srdivacky    Entry =
6367198398Srdivacky      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
6368198398Srdivacky                               false, llvm::GlobalValue::WeakAnyLinkage, Init,
6369198398Srdivacky                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
6370193326Sed    Entry->setAlignment(
6371243830Sdim      CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
6372193326Sed    Entry->setSection("__DATA,__datacoal_nt,coalesced");
6373234353Sdim
6374234353Sdim    Protocols[PD->getIdentifier()] = Entry;
6375193326Sed  }
6376193326Sed  Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
6377198092Srdivacky  CGM.AddUsedGlobal(Entry);
6378198092Srdivacky
6379193326Sed  // Use this protocol meta-data to build protocol list table in section
6380193326Sed  // __DATA, __objc_protolist
6381198398Srdivacky  llvm::GlobalVariable *PTGV =
6382198398Srdivacky    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
6383198398Srdivacky                             false, llvm::GlobalValue::WeakAnyLinkage, Entry,
6384198398Srdivacky                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
6385193326Sed  PTGV->setAlignment(
6386243830Sdim    CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
6387193326Sed  PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
6388193326Sed  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
6389198092Srdivacky  CGM.AddUsedGlobal(PTGV);
6390193326Sed  return Entry;
6391193326Sed}
6392193326Sed
6393193326Sed/// EmitProtocolList - Generate protocol list meta-data:
6394193326Sed/// @code
6395193326Sed/// struct _protocol_list_t {
6396193326Sed///   long protocol_count;   // Note, this is 32/64 bit
6397193326Sed///   struct _protocol_t[protocol_count];
6398193326Sed/// }
6399193326Sed/// @endcode
6400193326Sed///
6401193326Sedllvm::Constant *
6402226633SdimCGObjCNonFragileABIMac::EmitProtocolList(Twine Name,
6403198398Srdivacky                                      ObjCProtocolDecl::protocol_iterator begin,
6404198398Srdivacky                                      ObjCProtocolDecl::protocol_iterator end) {
6405249423Sdim  SmallVector<llvm::Constant *, 16> ProtocolRefs;
6406198092Srdivacky
6407193326Sed  // Just return null for empty protocol lists
6408198092Srdivacky  if (begin == end)
6409193326Sed    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
6410198092Srdivacky
6411193326Sed  // FIXME: We shouldn't need to do this lookup here, should we?
6412234353Sdim  SmallString<256> TmpName;
6413198398Srdivacky  Name.toVector(TmpName);
6414198398Srdivacky  llvm::GlobalVariable *GV =
6415198398Srdivacky    CGM.getModule().getGlobalVariable(TmpName.str(), true);
6416193326Sed  if (GV)
6417198398Srdivacky    return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
6418198092Srdivacky
6419193326Sed  for (; begin != end; ++begin)
6420193326Sed    ProtocolRefs.push_back(GetProtocolRef(*begin));  // Implemented???
6421193326Sed
6422193326Sed  // This list is null terminated.
6423193326Sed  ProtocolRefs.push_back(llvm::Constant::getNullValue(
6424198092Srdivacky                           ObjCTypes.ProtocolnfABIPtrTy));
6425198092Srdivacky
6426224145Sdim  llvm::Constant *Values[2];
6427198092Srdivacky  Values[0] =
6428198092Srdivacky    llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
6429198092Srdivacky  Values[1] =
6430234353Sdim    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolnfABIPtrTy,
6431234353Sdim                                                  ProtocolRefs.size()),
6432234353Sdim                             ProtocolRefs);
6433198092Srdivacky
6434224145Sdim  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
6435198092Srdivacky  GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
6436193326Sed                                llvm::GlobalValue::InternalLinkage,
6437224145Sdim                                Init, Name);
6438193326Sed  GV->setSection("__DATA, __objc_const");
6439193326Sed  GV->setAlignment(
6440243830Sdim    CGM.getDataLayout().getABITypeAlignment(Init->getType()));
6441198092Srdivacky  CGM.AddUsedGlobal(GV);
6442198092Srdivacky  return llvm::ConstantExpr::getBitCast(GV,
6443193326Sed                                        ObjCTypes.ProtocolListnfABIPtrTy);
6444193326Sed}
6445193326Sed
6446193326Sed/// GetMethodDescriptionConstant - This routine build following meta-data:
6447193326Sed/// struct _objc_method {
6448193326Sed///   SEL _cmd;
6449193326Sed///   char *method_type;
6450193326Sed///   char *_imp;
6451193326Sed/// }
6452193326Sed
6453193326Sedllvm::Constant *
6454193326SedCGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
6455234353Sdim  llvm::Constant *Desc[3];
6456198092Srdivacky  Desc[0] =
6457198092Srdivacky    llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
6458198092Srdivacky                                   ObjCTypes.SelectorPtrTy);
6459193326Sed  Desc[1] = GetMethodVarType(MD);
6460223017Sdim  if (!Desc[1])
6461223017Sdim    return 0;
6462223017Sdim
6463193326Sed  // Protocol methods have no implementation. So, this entry is always NULL.
6464193326Sed  Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
6465193326Sed  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
6466193326Sed}
6467193326Sed
6468193326Sed/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference.
6469193326Sed/// This code gen. amounts to generating code for:
6470193326Sed/// @code
6471193326Sed/// (type *)((char *)base + _OBJC_IVAR_$_.ivar;
6472193326Sed/// @encode
6473198092Srdivacky///
6474193326SedLValue CGObjCNonFragileABIMac::EmitObjCValueForIvar(
6475208600Srdivacky                                               CodeGen::CodeGenFunction &CGF,
6476208600Srdivacky                                               QualType ObjectTy,
6477208600Srdivacky                                               llvm::Value *BaseValue,
6478208600Srdivacky                                               const ObjCIvarDecl *Ivar,
6479208600Srdivacky                                               unsigned CVRQualifiers) {
6480208600Srdivacky  ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
6481234353Sdim  llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
6482249423Sdim
6483249423Sdim  if (IsIvarOffsetKnownIdempotent(CGF, ID, Ivar))
6484249423Sdim    if (llvm::LoadInst *LI = cast<llvm::LoadInst>(Offset))
6485249423Sdim      LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6486249423Sdim                      llvm::MDNode::get(VMContext, ArrayRef<llvm::Value*>()));
6487249423Sdim
6488193326Sed  return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
6489234353Sdim                                  Offset);
6490193326Sed}
6491193326Sed
6492193326Sedllvm::Value *CGObjCNonFragileABIMac::EmitIvarOffset(
6493198092Srdivacky  CodeGen::CodeGenFunction &CGF,
6494198092Srdivacky  const ObjCInterfaceDecl *Interface,
6495198092Srdivacky  const ObjCIvarDecl *Ivar) {
6496199990Srdivacky  return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
6497193326Sed}
6498193326Sed
6499223017Sdimstatic void appendSelectorForMessageRefTable(std::string &buffer,
6500223017Sdim                                             Selector selector) {
6501223017Sdim  if (selector.isUnarySelector()) {
6502223017Sdim    buffer += selector.getNameForSlot(0);
6503223017Sdim    return;
6504223017Sdim  }
6505198092Srdivacky
6506223017Sdim  for (unsigned i = 0, e = selector.getNumArgs(); i != e; ++i) {
6507223017Sdim    buffer += selector.getNameForSlot(i);
6508223017Sdim    buffer += '_';
6509223017Sdim  }
6510223017Sdim}
6511223017Sdim
6512223017Sdim/// Emit a "v-table" message send.  We emit a weak hidden-visibility
6513223017Sdim/// struct, initially containing the selector pointer and a pointer to
6514223017Sdim/// a "fixup" variant of the appropriate objc_msgSend.  To call, we
6515223017Sdim/// load and call the function pointer, passing the address of the
6516223017Sdim/// struct as the second parameter.  The runtime determines whether
6517223017Sdim/// the selector is currently emitted using vtable dispatch; if so, it
6518223017Sdim/// substitutes a stub function which simply tail-calls through the
6519223017Sdim/// appropriate vtable slot, and if not, it substitues a stub function
6520223017Sdim/// which tail-calls objc_msgSend.  Both stubs adjust the selector
6521223017Sdim/// argument to correctly point to the selector.
6522223017SdimRValue
6523223017SdimCGObjCNonFragileABIMac::EmitVTableMessageSend(CodeGenFunction &CGF,
6524223017Sdim                                              ReturnValueSlot returnSlot,
6525223017Sdim                                              QualType resultType,
6526223017Sdim                                              Selector selector,
6527223017Sdim                                              llvm::Value *arg0,
6528223017Sdim                                              QualType arg0Type,
6529223017Sdim                                              bool isSuper,
6530223017Sdim                                              const CallArgList &formalArgs,
6531223017Sdim                                              const ObjCMethodDecl *method) {
6532223017Sdim  // Compute the actual arguments.
6533223017Sdim  CallArgList args;
6534223017Sdim
6535223017Sdim  // First argument: the receiver / super-call structure.
6536223017Sdim  if (!isSuper)
6537223017Sdim    arg0 = CGF.Builder.CreateBitCast(arg0, ObjCTypes.ObjectPtrTy);
6538223017Sdim  args.add(RValue::get(arg0), arg0Type);
6539223017Sdim
6540223017Sdim  // Second argument: a pointer to the message ref structure.  Leave
6541223017Sdim  // the actual argument value blank for now.
6542223017Sdim  args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
6543223017Sdim
6544223017Sdim  args.insert(args.end(), formalArgs.begin(), formalArgs.end());
6545223017Sdim
6546234353Sdim  MessageSendInfo MSI = getMessageSendInfo(method, resultType, args);
6547223017Sdim
6548223017Sdim  NullReturnState nullReturn;
6549223017Sdim
6550223017Sdim  // Find the function to call and the mangled name for the message
6551223017Sdim  // ref structure.  Using a different mangled name wouldn't actually
6552223017Sdim  // be a problem; it would just be a waste.
6553223017Sdim  //
6554223017Sdim  // The runtime currently never uses vtable dispatch for anything
6555223017Sdim  // except normal, non-super message-sends.
6556223017Sdim  // FIXME: don't use this for that.
6557223017Sdim  llvm::Constant *fn = 0;
6558223017Sdim  std::string messageRefName("\01l_");
6559234353Sdim  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
6560223017Sdim    if (isSuper) {
6561223017Sdim      fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
6562223017Sdim      messageRefName += "objc_msgSendSuper2_stret_fixup";
6563212904Sdim    } else {
6564223017Sdim      nullReturn.init(CGF, arg0);
6565223017Sdim      fn = ObjCTypes.getMessageSendStretFixupFn();
6566223017Sdim      messageRefName += "objc_msgSend_stret_fixup";
6567212904Sdim    }
6568223017Sdim  } else if (!isSuper && CGM.ReturnTypeUsesFPRet(resultType)) {
6569223017Sdim    fn = ObjCTypes.getMessageSendFpretFixupFn();
6570223017Sdim    messageRefName += "objc_msgSend_fpret_fixup";
6571198092Srdivacky  } else {
6572223017Sdim    if (isSuper) {
6573223017Sdim      fn = ObjCTypes.getMessageSendSuper2FixupFn();
6574223017Sdim      messageRefName += "objc_msgSendSuper2_fixup";
6575212904Sdim    } else {
6576223017Sdim      fn = ObjCTypes.getMessageSendFixupFn();
6577223017Sdim      messageRefName += "objc_msgSend_fixup";
6578212904Sdim    }
6579193326Sed  }
6580223017Sdim  assert(fn && "CGObjCNonFragileABIMac::EmitMessageSend");
6581223017Sdim  messageRefName += '_';
6582223017Sdim
6583223017Sdim  // Append the selector name, except use underscores anywhere we
6584223017Sdim  // would have used colons.
6585223017Sdim  appendSelectorForMessageRefTable(messageRefName, selector);
6586223017Sdim
6587223017Sdim  llvm::GlobalVariable *messageRef
6588223017Sdim    = CGM.getModule().getGlobalVariable(messageRefName);
6589223017Sdim  if (!messageRef) {
6590223017Sdim    // Build the message ref structure.
6591223017Sdim    llvm::Constant *values[] = { fn, GetMethodVarName(selector) };
6592224145Sdim    llvm::Constant *init = llvm::ConstantStruct::getAnon(values);
6593223017Sdim    messageRef = new llvm::GlobalVariable(CGM.getModule(),
6594223017Sdim                                          init->getType(),
6595223017Sdim                                          /*constant*/ false,
6596223017Sdim                                          llvm::GlobalValue::WeakAnyLinkage,
6597223017Sdim                                          init,
6598223017Sdim                                          messageRefName);
6599223017Sdim    messageRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
6600223017Sdim    messageRef->setAlignment(16);
6601223017Sdim    messageRef->setSection("__DATA, __objc_msgrefs, coalesced");
6602193326Sed  }
6603234353Sdim
6604234353Sdim  bool requiresnullCheck = false;
6605234353Sdim  if (CGM.getLangOpts().ObjCAutoRefCount && method)
6606234353Sdim    for (ObjCMethodDecl::param_const_iterator i = method->param_begin(),
6607234353Sdim         e = method->param_end(); i != e; ++i) {
6608234353Sdim      const ParmVarDecl *ParamDecl = (*i);
6609234353Sdim      if (ParamDecl->hasAttr<NSConsumedAttr>()) {
6610234353Sdim        if (!nullReturn.NullBB)
6611234353Sdim          nullReturn.init(CGF, arg0);
6612234353Sdim        requiresnullCheck = true;
6613234353Sdim        break;
6614234353Sdim      }
6615234353Sdim    }
6616234353Sdim
6617223017Sdim  llvm::Value *mref =
6618223017Sdim    CGF.Builder.CreateBitCast(messageRef, ObjCTypes.MessageRefPtrTy);
6619198092Srdivacky
6620223017Sdim  // Update the message ref argument.
6621223017Sdim  args[1].RV = RValue::get(mref);
6622223017Sdim
6623223017Sdim  // Load the function to call from the message ref table.
6624223017Sdim  llvm::Value *callee = CGF.Builder.CreateStructGEP(mref, 0);
6625223017Sdim  callee = CGF.Builder.CreateLoad(callee, "msgSend_fn");
6626223017Sdim
6627234353Sdim  callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
6628223017Sdim
6629234353Sdim  RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
6630234353Sdim  return nullReturn.complete(CGF, result, resultType, formalArgs,
6631234353Sdim                             requiresnullCheck ? method : 0);
6632193326Sed}
6633193326Sed
6634193326Sed/// Generate code for a message send expression in the nonfragile abi.
6635198092SrdivackyCodeGen::RValue
6636198092SrdivackyCGObjCNonFragileABIMac::GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
6637208600Srdivacky                                            ReturnValueSlot Return,
6638198092Srdivacky                                            QualType ResultType,
6639198092Srdivacky                                            Selector Sel,
6640198092Srdivacky                                            llvm::Value *Receiver,
6641198092Srdivacky                                            const CallArgList &CallArgs,
6642207619Srdivacky                                            const ObjCInterfaceDecl *Class,
6643198092Srdivacky                                            const ObjCMethodDecl *Method) {
6644223017Sdim  return isVTableDispatchedSelector(Sel)
6645223017Sdim    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6646198092Srdivacky                            Receiver, CGF.getContext().getObjCIdType(),
6647223017Sdim                            false, CallArgs, Method)
6648223017Sdim    : EmitMessageSend(CGF, Return, ResultType,
6649249423Sdim                      EmitSelector(CGF, Sel),
6650198092Srdivacky                      Receiver, CGF.getContext().getObjCIdType(),
6651223017Sdim                      false, CallArgs, Method, ObjCTypes);
6652193326Sed}
6653193326Sed
6654193326Sedllvm::GlobalVariable *
6655193326SedCGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
6656193326Sed  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
6657193326Sed
6658193326Sed  if (!GV) {
6659198092Srdivacky    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
6660198092Srdivacky                                  false, llvm::GlobalValue::ExternalLinkage,
6661198092Srdivacky                                  0, Name);
6662193326Sed  }
6663193326Sed
6664193326Sed  return GV;
6665193326Sed}
6666193326Sed
6667249423Sdimllvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
6668224145Sdim                                                        IdentifierInfo *II) {
6669224145Sdim  llvm::GlobalVariable *&Entry = ClassReferences[II];
6670224145Sdim
6671193326Sed  if (!Entry) {
6672224145Sdim    std::string ClassName(getClassSymbolPrefix() + II->getName().str());
6673193326Sed    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6674198092Srdivacky    Entry =
6675224145Sdim    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6676224145Sdim                             false, llvm::GlobalValue::InternalLinkage,
6677224145Sdim                             ClassGV,
6678224145Sdim                             "\01L_OBJC_CLASSLIST_REFERENCES_$_");
6679193326Sed    Entry->setAlignment(
6680243830Sdim                        CGM.getDataLayout().getABITypeAlignment(
6681224145Sdim                                                                ObjCTypes.ClassnfABIPtrTy));
6682193326Sed    Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
6683198092Srdivacky    CGM.AddUsedGlobal(Entry);
6684193326Sed  }
6685224145Sdim
6686249423Sdim  return CGF.Builder.CreateLoad(Entry);
6687193326Sed}
6688193326Sed
6689249423Sdimllvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
6690224145Sdim                                                  const ObjCInterfaceDecl *ID) {
6691249423Sdim  return EmitClassRefFromId(CGF, ID->getIdentifier());
6692224145Sdim}
6693224145Sdim
6694224145Sdimllvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
6695249423Sdim                                                    CodeGenFunction &CGF) {
6696224145Sdim  IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
6697249423Sdim  return EmitClassRefFromId(CGF, II);
6698224145Sdim}
6699224145Sdim
6700193326Sedllvm::Value *
6701249423SdimCGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF,
6702193326Sed                                          const ObjCInterfaceDecl *ID) {
6703193326Sed  llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
6704198092Srdivacky
6705193326Sed  if (!Entry) {
6706193326Sed    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6707193326Sed    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6708198092Srdivacky    Entry =
6709198092Srdivacky      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
6710198092Srdivacky                               false, llvm::GlobalValue::InternalLinkage,
6711198092Srdivacky                               ClassGV,
6712198092Srdivacky                               "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
6713193326Sed    Entry->setAlignment(
6714243830Sdim      CGM.getDataLayout().getABITypeAlignment(
6715198092Srdivacky        ObjCTypes.ClassnfABIPtrTy));
6716193326Sed    Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6717198092Srdivacky    CGM.AddUsedGlobal(Entry);
6718193326Sed  }
6719198092Srdivacky
6720249423Sdim  return CGF.Builder.CreateLoad(Entry);
6721193326Sed}
6722193326Sed
6723193326Sed/// EmitMetaClassRef - Return a Value * of the address of _class_t
6724193326Sed/// meta-data
6725193326Sed///
6726249423Sdimllvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
6727198092Srdivacky                                                      const ObjCInterfaceDecl *ID) {
6728193326Sed  llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
6729193326Sed  if (Entry)
6730249423Sdim    return CGF.Builder.CreateLoad(Entry);
6731198092Srdivacky
6732193326Sed  std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
6733193326Sed  llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
6734198092Srdivacky  Entry =
6735198092Srdivacky    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
6736193326Sed                             llvm::GlobalValue::InternalLinkage,
6737198092Srdivacky                             MetaClassGV,
6738198092Srdivacky                             "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
6739193326Sed  Entry->setAlignment(
6740243830Sdim    CGM.getDataLayout().getABITypeAlignment(
6741198092Srdivacky      ObjCTypes.ClassnfABIPtrTy));
6742198092Srdivacky
6743193326Sed  Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
6744198092Srdivacky  CGM.AddUsedGlobal(Entry);
6745198092Srdivacky
6746249423Sdim  return CGF.Builder.CreateLoad(Entry);
6747193326Sed}
6748193326Sed
6749193326Sed/// GetClass - Return a reference to the class for the given interface
6750193326Sed/// decl.
6751249423Sdimllvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
6752193326Sed                                              const ObjCInterfaceDecl *ID) {
6753221345Sdim  if (ID->isWeakImported()) {
6754199482Srdivacky    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
6755199482Srdivacky    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
6756199482Srdivacky    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
6757199482Srdivacky  }
6758199482Srdivacky
6759249423Sdim  return EmitClassRef(CGF, ID);
6760193326Sed}
6761193326Sed
6762193326Sed/// Generates a message send where the super is the receiver.  This is
6763193326Sed/// a message send to self with special delivery semantics indicating
6764193326Sed/// which class's method should be called.
6765193326SedCodeGen::RValue
6766193326SedCGObjCNonFragileABIMac::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
6767208600Srdivacky                                                 ReturnValueSlot Return,
6768198092Srdivacky                                                 QualType ResultType,
6769198092Srdivacky                                                 Selector Sel,
6770198092Srdivacky                                                 const ObjCInterfaceDecl *Class,
6771198092Srdivacky                                                 bool isCategoryImpl,
6772198092Srdivacky                                                 llvm::Value *Receiver,
6773198092Srdivacky                                                 bool IsClassMessage,
6774198092Srdivacky                                                 const CodeGen::CallArgList &CallArgs,
6775198092Srdivacky                                                 const ObjCMethodDecl *Method) {
6776193326Sed  // ...
6777193326Sed  // Create and init a super structure; this is a (receiver, class)
6778193326Sed  // pair we will pass to objc_msgSendSuper.
6779193326Sed  llvm::Value *ObjCSuper =
6780221345Sdim    CGF.CreateTempAlloca(ObjCTypes.SuperTy, "objc_super");
6781198092Srdivacky
6782193326Sed  llvm::Value *ReceiverAsObject =
6783193326Sed    CGF.Builder.CreateBitCast(Receiver, ObjCTypes.ObjectPtrTy);
6784193326Sed  CGF.Builder.CreateStore(ReceiverAsObject,
6785193326Sed                          CGF.Builder.CreateStructGEP(ObjCSuper, 0));
6786198092Srdivacky
6787193326Sed  // If this is a class message the metaclass is passed as the target.
6788193326Sed  llvm::Value *Target;
6789243830Sdim  if (IsClassMessage)
6790249423Sdim      Target = EmitMetaClassRef(CGF, Class);
6791243830Sdim  else
6792249423Sdim    Target = EmitSuperClassRef(CGF, Class);
6793198092Srdivacky
6794193326Sed  // FIXME: We shouldn't need to do this cast, rectify the ASTContext and
6795193326Sed  // ObjCTypes types.
6796226633Sdim  llvm::Type *ClassTy =
6797193326Sed    CGM.getTypes().ConvertType(CGF.getContext().getObjCClassType());
6798193326Sed  Target = CGF.Builder.CreateBitCast(Target, ClassTy);
6799193326Sed  CGF.Builder.CreateStore(Target,
6800193326Sed                          CGF.Builder.CreateStructGEP(ObjCSuper, 1));
6801198092Srdivacky
6802223017Sdim  return (isVTableDispatchedSelector(Sel))
6803223017Sdim    ? EmitVTableMessageSend(CGF, Return, ResultType, Sel,
6804198092Srdivacky                            ObjCSuper, ObjCTypes.SuperPtrCTy,
6805223017Sdim                            true, CallArgs, Method)
6806223017Sdim    : EmitMessageSend(CGF, Return, ResultType,
6807249423Sdim                      EmitSelector(CGF, Sel),
6808198092Srdivacky                      ObjCSuper, ObjCTypes.SuperPtrCTy,
6809223017Sdim                      true, CallArgs, Method, ObjCTypes);
6810193326Sed}
6811193326Sed
6812249423Sdimllvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF,
6813210299Sed                                                  Selector Sel, bool lval) {
6814193326Sed  llvm::GlobalVariable *&Entry = SelectorReferences[Sel];
6815198092Srdivacky
6816193326Sed  if (!Entry) {
6817198092Srdivacky    llvm::Constant *Casted =
6818198092Srdivacky      llvm::ConstantExpr::getBitCast(GetMethodVarName(Sel),
6819198092Srdivacky                                     ObjCTypes.SelectorPtrTy);
6820198092Srdivacky    Entry =
6821198092Srdivacky      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
6822198092Srdivacky                               llvm::GlobalValue::InternalLinkage,
6823198092Srdivacky                               Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
6824249423Sdim    Entry->setExternallyInitialized(true);
6825193326Sed    Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
6826198092Srdivacky    CGM.AddUsedGlobal(Entry);
6827193326Sed  }
6828198092Srdivacky
6829210299Sed  if (lval)
6830210299Sed    return Entry;
6831249423Sdim  llvm::LoadInst* LI = CGF.Builder.CreateLoad(Entry);
6832234353Sdim
6833234353Sdim  LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
6834234353Sdim                  llvm::MDNode::get(VMContext,
6835234353Sdim                                    ArrayRef<llvm::Value*>()));
6836234353Sdim  return LI;
6837193326Sed}
6838193326Sed/// EmitObjCIvarAssign - Code gen for assigning to a __strong object.
6839198092Srdivacky/// objc_assign_ivar (id src, id *dst, ptrdiff_t)
6840193326Sed///
6841193326Sedvoid CGObjCNonFragileABIMac::EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
6842198092Srdivacky                                                llvm::Value *src,
6843198092Srdivacky                                                llvm::Value *dst,
6844198092Srdivacky                                                llvm::Value *ivarOffset) {
6845226633Sdim  llvm::Type * SrcTy = src->getType();
6846193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
6847243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6848193326Sed    assert(Size <= 8 && "does not support size > 8");
6849193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6850193326Sed           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6851193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6852193326Sed  }
6853193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6854193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6855249423Sdim  llvm::Value *args[] = { src, dst, ivarOffset };
6856249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignIvarFn(), args);
6857193326Sed}
6858193326Sed
6859193326Sed/// EmitObjCStrongCastAssign - Code gen for assigning to a __strong cast object.
6860193326Sed/// objc_assign_strongCast (id src, id *dst)
6861193326Sed///
6862193326Sedvoid CGObjCNonFragileABIMac::EmitObjCStrongCastAssign(
6863198092Srdivacky  CodeGen::CodeGenFunction &CGF,
6864198092Srdivacky  llvm::Value *src, llvm::Value *dst) {
6865226633Sdim  llvm::Type * SrcTy = src->getType();
6866193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
6867243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6868193326Sed    assert(Size <= 8 && "does not support size > 8");
6869193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6870198092Srdivacky           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6871193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6872193326Sed  }
6873193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6874193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6875249423Sdim  llvm::Value *args[] = { src, dst };
6876249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignStrongCastFn(),
6877249423Sdim                              args, "weakassign");
6878193326Sed}
6879193326Sed
6880198092Srdivackyvoid CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
6881198092Srdivacky  CodeGen::CodeGenFunction &CGF,
6882198092Srdivacky  llvm::Value *DestPtr,
6883198092Srdivacky  llvm::Value *SrcPtr,
6884210299Sed  llvm::Value *Size) {
6885198092Srdivacky  SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
6886198092Srdivacky  DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
6887249423Sdim  llvm::Value *args[] = { DestPtr, SrcPtr, Size };
6888249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.GcMemmoveCollectableFn(), args);
6889198092Srdivacky}
6890198092Srdivacky
6891193326Sed/// EmitObjCWeakRead - Code gen for loading value of a __weak
6892193326Sed/// object: objc_read_weak (id *src)
6893193326Sed///
6894193326Sedllvm::Value * CGObjCNonFragileABIMac::EmitObjCWeakRead(
6895198092Srdivacky  CodeGen::CodeGenFunction &CGF,
6896198092Srdivacky  llvm::Value *AddrWeakObj) {
6897226633Sdim  llvm::Type* DestTy =
6898198092Srdivacky    cast<llvm::PointerType>(AddrWeakObj->getType())->getElementType();
6899198092Srdivacky  AddrWeakObj = CGF.Builder.CreateBitCast(AddrWeakObj, ObjCTypes.PtrObjectPtrTy);
6900249423Sdim  llvm::Value *read_weak =
6901249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcReadWeakFn(),
6902249423Sdim                                AddrWeakObj, "weakread");
6903193326Sed  read_weak = CGF.Builder.CreateBitCast(read_weak, DestTy);
6904193326Sed  return read_weak;
6905193326Sed}
6906193326Sed
6907193326Sed/// EmitObjCWeakAssign - Code gen for assigning to a __weak object.
6908193326Sed/// objc_assign_weak (id src, id *dst)
6909193326Sed///
6910193326Sedvoid CGObjCNonFragileABIMac::EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
6911198092Srdivacky                                                llvm::Value *src, llvm::Value *dst) {
6912226633Sdim  llvm::Type * SrcTy = src->getType();
6913193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
6914243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6915193326Sed    assert(Size <= 8 && "does not support size > 8");
6916193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6917193326Sed           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6918193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6919193326Sed  }
6920193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6921193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6922249423Sdim  llvm::Value *args[] = { src, dst };
6923249423Sdim  CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignWeakFn(),
6924249423Sdim                              args, "weakassign");
6925193326Sed}
6926193326Sed
6927193326Sed/// EmitObjCGlobalAssign - Code gen for assigning to a __strong object.
6928193326Sed/// objc_assign_global (id src, id *dst)
6929193326Sed///
6930193326Sedvoid CGObjCNonFragileABIMac::EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
6931212904Sdim                                          llvm::Value *src, llvm::Value *dst,
6932212904Sdim                                          bool threadlocal) {
6933226633Sdim  llvm::Type * SrcTy = src->getType();
6934193326Sed  if (!isa<llvm::PointerType>(SrcTy)) {
6935243830Sdim    unsigned Size = CGM.getDataLayout().getTypeAllocSize(SrcTy);
6936193326Sed    assert(Size <= 8 && "does not support size > 8");
6937193326Sed    src = (Size == 4 ? CGF.Builder.CreateBitCast(src, ObjCTypes.IntTy)
6938193326Sed           : CGF.Builder.CreateBitCast(src, ObjCTypes.LongTy));
6939193326Sed    src = CGF.Builder.CreateIntToPtr(src, ObjCTypes.Int8PtrTy);
6940193326Sed  }
6941193326Sed  src = CGF.Builder.CreateBitCast(src, ObjCTypes.ObjectPtrTy);
6942193326Sed  dst = CGF.Builder.CreateBitCast(dst, ObjCTypes.PtrObjectPtrTy);
6943249423Sdim  llvm::Value *args[] = { src, dst };
6944212904Sdim  if (!threadlocal)
6945249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignGlobalFn(),
6946249423Sdim                                args, "globalassign");
6947212904Sdim  else
6948249423Sdim    CGF.EmitNounwindRuntimeCall(ObjCTypes.getGcAssignThreadLocalFn(),
6949249423Sdim                                args, "threadlocalassign");
6950193326Sed}
6951193326Sed
6952198092Srdivackyvoid
6953210299SedCGObjCNonFragileABIMac::EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
6954210299Sed                                             const ObjCAtSynchronizedStmt &S) {
6955221345Sdim  EmitAtSynchronizedStmt(CGF, S,
6956221345Sdim      cast<llvm::Function>(ObjCTypes.getSyncEnterFn()),
6957221345Sdim      cast<llvm::Function>(ObjCTypes.getSyncExitFn()));
6958210299Sed}
6959193326Sed
6960212904Sdimllvm::Constant *
6961212904SdimCGObjCNonFragileABIMac::GetEHType(QualType T) {
6962212904Sdim  // There's a particular fixed type info for 'id'.
6963212904Sdim  if (T->isObjCIdType() ||
6964212904Sdim      T->isObjCQualifiedIdType()) {
6965212904Sdim    llvm::Constant *IDEHType =
6966212904Sdim      CGM.getModule().getGlobalVariable("OBJC_EHTYPE_id");
6967212904Sdim    if (!IDEHType)
6968212904Sdim      IDEHType =
6969212904Sdim        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
6970212904Sdim                                 false,
6971212904Sdim                                 llvm::GlobalValue::ExternalLinkage,
6972212904Sdim                                 0, "OBJC_EHTYPE_id");
6973212904Sdim    return IDEHType;
6974212904Sdim  }
6975212904Sdim
6976212904Sdim  // All other types should be Objective-C interface pointer types.
6977212904Sdim  const ObjCObjectPointerType *PT =
6978212904Sdim    T->getAs<ObjCObjectPointerType>();
6979212904Sdim  assert(PT && "Invalid @catch type.");
6980212904Sdim  const ObjCInterfaceType *IT = PT->getInterfaceType();
6981212904Sdim  assert(IT && "Invalid @catch type.");
6982212904Sdim  return GetInterfaceEHType(IT->getDecl(), false);
6983212904Sdim}
6984212904Sdim
6985210299Sedvoid CGObjCNonFragileABIMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
6986210299Sed                                         const ObjCAtTryStmt &S) {
6987221345Sdim  EmitTryCatchStmt(CGF, S,
6988221345Sdim      cast<llvm::Function>(ObjCTypes.getObjCBeginCatchFn()),
6989221345Sdim      cast<llvm::Function>(ObjCTypes.getObjCEndCatchFn()),
6990221345Sdim      cast<llvm::Function>(ObjCTypes.getExceptionRethrowFn()));
6991193326Sed}
6992193326Sed
6993193326Sed/// EmitThrowStmt - Generate code for a throw statement.
6994193326Sedvoid CGObjCNonFragileABIMac::EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
6995249423Sdim                                           const ObjCAtThrowStmt &S,
6996249423Sdim                                           bool ClearInsertionPoint) {
6997193326Sed  if (const Expr *ThrowExpr = S.getThrowExpr()) {
6998226633Sdim    llvm::Value *Exception = CGF.EmitObjCThrowOperand(ThrowExpr);
6999226633Sdim    Exception = CGF.Builder.CreateBitCast(Exception, ObjCTypes.ObjectPtrTy);
7000249423Sdim    CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionThrowFn(), Exception)
7001218893Sdim      .setDoesNotReturn();
7002193326Sed  } else {
7003249423Sdim    CGF.EmitRuntimeCallOrInvoke(ObjCTypes.getExceptionRethrowFn())
7004218893Sdim      .setDoesNotReturn();
7005193326Sed  }
7006193326Sed
7007218893Sdim  CGF.Builder.CreateUnreachable();
7008249423Sdim  if (ClearInsertionPoint)
7009249423Sdim    CGF.Builder.ClearInsertionPoint();
7010193326Sed}
7011193326Sed
7012212904Sdimllvm::Constant *
7013198092SrdivackyCGObjCNonFragileABIMac::GetInterfaceEHType(const ObjCInterfaceDecl *ID,
7014193326Sed                                           bool ForDefinition) {
7015193326Sed  llvm::GlobalVariable * &Entry = EHTypeReferences[ID->getIdentifier()];
7016193326Sed
7017193326Sed  // If we don't need a definition, return the entry if found or check
7018193326Sed  // if we use an external reference.
7019193326Sed  if (!ForDefinition) {
7020193326Sed    if (Entry)
7021193326Sed      return Entry;
7022193326Sed
7023193326Sed    // If this type (or a super class) has the __objc_exception__
7024193326Sed    // attribute, emit an external reference.
7025194613Sed    if (hasObjCExceptionAttribute(CGM.getContext(), ID))
7026198092Srdivacky      return Entry =
7027198092Srdivacky        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7028193326Sed                                 llvm::GlobalValue::ExternalLinkage,
7029198092Srdivacky                                 0,
7030198398Srdivacky                                 ("OBJC_EHTYPE_$_" +
7031198092Srdivacky                                  ID->getIdentifier()->getName()));
7032193326Sed  }
7033198092Srdivacky
7034193326Sed  // Otherwise we need to either make a new entry or fill in the
7035193326Sed  // initializer.
7036193326Sed  assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
7037193326Sed  std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
7038193326Sed  std::string VTableName = "objc_ehtype_vtable";
7039198092Srdivacky  llvm::GlobalVariable *VTableGV =
7040193326Sed    CGM.getModule().getGlobalVariable(VTableName);
7041193326Sed  if (!VTableGV)
7042198092Srdivacky    VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
7043198092Srdivacky                                        false,
7044193326Sed                                        llvm::GlobalValue::ExternalLinkage,
7045198092Srdivacky                                        0, VTableName);
7046193326Sed
7047234353Sdim  llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
7048193326Sed
7049234353Sdim  llvm::Constant *Values[] = {
7050234353Sdim    llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
7051234353Sdim    GetClassName(ID->getIdentifier()),
7052234353Sdim    GetClassGlobal(ClassName)
7053234353Sdim  };
7054198092Srdivacky  llvm::Constant *Init =
7055198092Srdivacky    llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
7056193326Sed
7057193326Sed  if (Entry) {
7058193326Sed    Entry->setInitializer(Init);
7059193326Sed  } else {
7060198092Srdivacky    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
7061193326Sed                                     llvm::GlobalValue::WeakAnyLinkage,
7062198092Srdivacky                                     Init,
7063198398Srdivacky                                     ("OBJC_EHTYPE_$_" +
7064198092Srdivacky                                      ID->getIdentifier()->getName()));
7065193326Sed  }
7066193326Sed
7067249423Sdim  if (ID->getVisibility() == HiddenVisibility)
7068193326Sed    Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
7069243830Sdim  Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
7070207619Srdivacky      ObjCTypes.EHTypeTy));
7071193326Sed
7072193326Sed  if (ForDefinition) {
7073193326Sed    Entry->setSection("__DATA,__objc_const");
7074193326Sed    Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
7075193326Sed  } else {
7076193326Sed    Entry->setSection("__DATA,__datacoal_nt,coalesced");
7077193326Sed  }
7078193326Sed
7079193326Sed  return Entry;
7080193326Sed}
7081198092Srdivacky
7082193326Sed/* *** */
7083193326Sed
7084193326SedCodeGen::CGObjCRuntime *
7085193326SedCodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
7086239462Sdim  switch (CGM.getLangOpts().ObjCRuntime.getKind()) {
7087239462Sdim  case ObjCRuntime::FragileMacOSX:
7088239462Sdim  return new CGObjCMac(CGM);
7089239462Sdim
7090239462Sdim  case ObjCRuntime::MacOSX:
7091239462Sdim  case ObjCRuntime::iOS:
7092221345Sdim    return new CGObjCNonFragileABIMac(CGM);
7093239462Sdim
7094239462Sdim  case ObjCRuntime::GNUstep:
7095239462Sdim  case ObjCRuntime::GCC:
7096239462Sdim  case ObjCRuntime::ObjFW:
7097239462Sdim    llvm_unreachable("these runtimes are not Mac runtimes");
7098239462Sdim  }
7099239462Sdim  llvm_unreachable("bad runtime");
7100193326Sed}
7101