1193326Sed//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
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//
10193326Sed// This contains code to emit Objective-C code as LLVM code.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14218893Sdim#include "CGDebugInfo.h"
15193326Sed#include "CGObjCRuntime.h"
16193326Sed#include "CodeGenFunction.h"
17193326Sed#include "CodeGenModule.h"
18224145Sdim#include "TargetInfo.h"
19193326Sed#include "clang/AST/ASTContext.h"
20193326Sed#include "clang/AST/DeclObjC.h"
21193326Sed#include "clang/AST/StmtObjC.h"
22193326Sed#include "clang/Basic/Diagnostic.h"
23263509Sdim#include "clang/CodeGen/CGFunctionInfo.h"
24193326Sed#include "llvm/ADT/STLExtras.h"
25252723Sdim#include "llvm/Support/CallSite.h"
26252723Sdim#include "llvm/IR/DataLayout.h"
27252723Sdim#include "llvm/IR/InlineAsm.h"
28193326Sedusing namespace clang;
29193326Sedusing namespace CodeGen;
30193326Sed
31224145Sdimtypedef llvm::PointerIntPair<llvm::Value*,1,bool> TryEmitResult;
32224145Sdimstatic TryEmitResult
33224145SdimtryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e);
34235633Sdimstatic RValue AdjustRelatedResultType(CodeGenFunction &CGF,
35245431Sdim                                      QualType ET,
36235633Sdim                                      const ObjCMethodDecl *Method,
37235633Sdim                                      RValue Result);
38224145Sdim
39224145Sdim/// Given the address of a variable of pointer type, find the correct
40224145Sdim/// null to store into it.
41224145Sdimstatic llvm::Constant *getNullForVariable(llvm::Value *addr) {
42226890Sdim  llvm::Type *type =
43224145Sdim    cast<llvm::PointerType>(addr->getType())->getElementType();
44224145Sdim  return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(type));
45224145Sdim}
46224145Sdim
47193326Sed/// Emits an instance of NSConstantString representing the object.
48198092Srdivackyllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
49193326Sed{
50202879Srdivacky  llvm::Constant *C =
51202879Srdivacky      CGM.getObjCRuntime().GenerateConstantString(E->getString());
52193326Sed  // FIXME: This bitcast should just be made an invariant on the Runtime.
53193326Sed  return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
54193326Sed}
55193326Sed
56245431Sdim/// EmitObjCBoxedExpr - This routine generates code to call
57245431Sdim/// the appropriate expression boxing method. This will either be
58245431Sdim/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:].
59235633Sdim///
60235633Sdimllvm::Value *
61245431SdimCodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {
62235633Sdim  // Generate the correct selector for this literal's concrete type.
63245431Sdim  const Expr *SubExpr = E->getSubExpr();
64235633Sdim  // Get the method.
65245431Sdim  const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();
66245431Sdim  assert(BoxingMethod && "BoxingMethod is null");
67245431Sdim  assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");
68245431Sdim  Selector Sel = BoxingMethod->getSelector();
69235633Sdim
70235633Sdim  // Generate a reference to the class pointer, which will be the receiver.
71245431Sdim  // Assumes that the method was introduced in the class that should be
72245431Sdim  // messaged (avoids pulling it out of the result type).
73235633Sdim  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
74245431Sdim  const ObjCInterfaceDecl *ClassDecl = BoxingMethod->getClassInterface();
75252723Sdim  llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl);
76245431Sdim
77245431Sdim  const ParmVarDecl *argDecl = *BoxingMethod->param_begin();
78235633Sdim  QualType ArgQT = argDecl->getType().getUnqualifiedType();
79245431Sdim  RValue RV = EmitAnyExpr(SubExpr);
80235633Sdim  CallArgList Args;
81235633Sdim  Args.add(RV, ArgQT);
82245431Sdim
83235633Sdim  RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
84245431Sdim                                              BoxingMethod->getResultType(), Sel, Receiver, Args,
85245431Sdim                                              ClassDecl, BoxingMethod);
86235633Sdim  return Builder.CreateBitCast(result.getScalarVal(),
87235633Sdim                               ConvertType(E->getType()));
88235633Sdim}
89235633Sdim
90235633Sdimllvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
91235633Sdim                                    const ObjCMethodDecl *MethodWithObjects) {
92235633Sdim  ASTContext &Context = CGM.getContext();
93235633Sdim  const ObjCDictionaryLiteral *DLE = 0;
94235633Sdim  const ObjCArrayLiteral *ALE = dyn_cast<ObjCArrayLiteral>(E);
95235633Sdim  if (!ALE)
96235633Sdim    DLE = cast<ObjCDictionaryLiteral>(E);
97235633Sdim
98235633Sdim  // Compute the type of the array we're initializing.
99235633Sdim  uint64_t NumElements =
100235633Sdim    ALE ? ALE->getNumElements() : DLE->getNumElements();
101235633Sdim  llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()),
102235633Sdim                            NumElements);
103235633Sdim  QualType ElementType = Context.getObjCIdType().withConst();
104235633Sdim  QualType ElementArrayType
105235633Sdim    = Context.getConstantArrayType(ElementType, APNumElements,
106235633Sdim                                   ArrayType::Normal, /*IndexTypeQuals=*/0);
107235633Sdim
108235633Sdim  // Allocate the temporary array(s).
109235633Sdim  llvm::Value *Objects = CreateMemTemp(ElementArrayType, "objects");
110235633Sdim  llvm::Value *Keys = 0;
111235633Sdim  if (DLE)
112235633Sdim    Keys = CreateMemTemp(ElementArrayType, "keys");
113235633Sdim
114252723Sdim  // In ARC, we may need to do extra work to keep all the keys and
115252723Sdim  // values alive until after the call.
116252723Sdim  SmallVector<llvm::Value *, 16> NeededObjects;
117252723Sdim  bool TrackNeededObjects =
118252723Sdim    (getLangOpts().ObjCAutoRefCount &&
119252723Sdim    CGM.getCodeGenOpts().OptimizationLevel != 0);
120252723Sdim
121235633Sdim  // Perform the actual initialialization of the array(s).
122235633Sdim  for (uint64_t i = 0; i < NumElements; i++) {
123235633Sdim    if (ALE) {
124252723Sdim      // Emit the element and store it to the appropriate array slot.
125235633Sdim      const Expr *Rhs = ALE->getElement(i);
126235633Sdim      LValue LV = LValue::MakeAddr(Builder.CreateStructGEP(Objects, i),
127235633Sdim                                   ElementType,
128235633Sdim                                   Context.getTypeAlignInChars(Rhs->getType()),
129235633Sdim                                   Context);
130252723Sdim
131252723Sdim      llvm::Value *value = EmitScalarExpr(Rhs);
132252723Sdim      EmitStoreThroughLValue(RValue::get(value), LV, true);
133252723Sdim      if (TrackNeededObjects) {
134252723Sdim        NeededObjects.push_back(value);
135252723Sdim      }
136235633Sdim    } else {
137252723Sdim      // Emit the key and store it to the appropriate array slot.
138235633Sdim      const Expr *Key = DLE->getKeyValueElement(i).Key;
139235633Sdim      LValue KeyLV = LValue::MakeAddr(Builder.CreateStructGEP(Keys, i),
140235633Sdim                                      ElementType,
141235633Sdim                                    Context.getTypeAlignInChars(Key->getType()),
142235633Sdim                                      Context);
143252723Sdim      llvm::Value *keyValue = EmitScalarExpr(Key);
144252723Sdim      EmitStoreThroughLValue(RValue::get(keyValue), KeyLV, /*isInit=*/true);
145235633Sdim
146252723Sdim      // Emit the value and store it to the appropriate array slot.
147235633Sdim      const Expr *Value = DLE->getKeyValueElement(i).Value;
148235633Sdim      LValue ValueLV = LValue::MakeAddr(Builder.CreateStructGEP(Objects, i),
149235633Sdim                                        ElementType,
150235633Sdim                                  Context.getTypeAlignInChars(Value->getType()),
151235633Sdim                                        Context);
152252723Sdim      llvm::Value *valueValue = EmitScalarExpr(Value);
153252723Sdim      EmitStoreThroughLValue(RValue::get(valueValue), ValueLV, /*isInit=*/true);
154252723Sdim      if (TrackNeededObjects) {
155252723Sdim        NeededObjects.push_back(keyValue);
156252723Sdim        NeededObjects.push_back(valueValue);
157252723Sdim      }
158235633Sdim    }
159235633Sdim  }
160235633Sdim
161235633Sdim  // Generate the argument list.
162235633Sdim  CallArgList Args;
163235633Sdim  ObjCMethodDecl::param_const_iterator PI = MethodWithObjects->param_begin();
164235633Sdim  const ParmVarDecl *argDecl = *PI++;
165235633Sdim  QualType ArgQT = argDecl->getType().getUnqualifiedType();
166235633Sdim  Args.add(RValue::get(Objects), ArgQT);
167235633Sdim  if (DLE) {
168235633Sdim    argDecl = *PI++;
169235633Sdim    ArgQT = argDecl->getType().getUnqualifiedType();
170235633Sdim    Args.add(RValue::get(Keys), ArgQT);
171235633Sdim  }
172235633Sdim  argDecl = *PI;
173235633Sdim  ArgQT = argDecl->getType().getUnqualifiedType();
174235633Sdim  llvm::Value *Count =
175235633Sdim    llvm::ConstantInt::get(CGM.getTypes().ConvertType(ArgQT), NumElements);
176235633Sdim  Args.add(RValue::get(Count), ArgQT);
177235633Sdim
178235633Sdim  // Generate a reference to the class pointer, which will be the receiver.
179235633Sdim  Selector Sel = MethodWithObjects->getSelector();
180235633Sdim  QualType ResultType = E->getType();
181235633Sdim  const ObjCObjectPointerType *InterfacePointerType
182235633Sdim    = ResultType->getAsObjCInterfacePointerType();
183235633Sdim  ObjCInterfaceDecl *Class
184235633Sdim    = InterfacePointerType->getObjectType()->getInterface();
185235633Sdim  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
186252723Sdim  llvm::Value *Receiver = Runtime.GetClass(*this, Class);
187235633Sdim
188235633Sdim  // Generate the message send.
189235633Sdim  RValue result
190235633Sdim    = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
191235633Sdim                                  MethodWithObjects->getResultType(),
192235633Sdim                                  Sel,
193235633Sdim                                  Receiver, Args, Class,
194235633Sdim                                  MethodWithObjects);
195252723Sdim
196252723Sdim  // The above message send needs these objects, but in ARC they are
197252723Sdim  // passed in a buffer that is essentially __unsafe_unretained.
198252723Sdim  // Therefore we must prevent the optimizer from releasing them until
199252723Sdim  // after the call.
200252723Sdim  if (TrackNeededObjects) {
201252723Sdim    EmitARCIntrinsicUse(NeededObjects);
202252723Sdim  }
203252723Sdim
204235633Sdim  return Builder.CreateBitCast(result.getScalarVal(),
205235633Sdim                               ConvertType(E->getType()));
206235633Sdim}
207235633Sdim
208235633Sdimllvm::Value *CodeGenFunction::EmitObjCArrayLiteral(const ObjCArrayLiteral *E) {
209235633Sdim  return EmitObjCCollectionLiteral(E, E->getArrayWithObjectsMethod());
210235633Sdim}
211235633Sdim
212235633Sdimllvm::Value *CodeGenFunction::EmitObjCDictionaryLiteral(
213235633Sdim                                            const ObjCDictionaryLiteral *E) {
214235633Sdim  return EmitObjCCollectionLiteral(E, E->getDictWithObjectsMethod());
215235633Sdim}
216235633Sdim
217193326Sed/// Emit a selector.
218193326Sedllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
219193326Sed  // Untyped selector.
220193326Sed  // Note that this implementation allows for non-constant strings to be passed
221193326Sed  // as arguments to @selector().  Currently, the only thing preventing this
222193326Sed  // behaviour is the type checking in the front end.
223252723Sdim  return CGM.getObjCRuntime().GetSelector(*this, E->getSelector());
224193326Sed}
225193326Sed
226193326Sedllvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
227193326Sed  // FIXME: This should pass the Decl not the name.
228252723Sdim  return CGM.getObjCRuntime().GenerateProtocolRef(*this, E->getProtocol());
229193326Sed}
230193326Sed
231223017Sdim/// \brief Adjust the type of the result of an Objective-C message send
232223017Sdim/// expression when the method has a related result type.
233223017Sdimstatic RValue AdjustRelatedResultType(CodeGenFunction &CGF,
234245431Sdim                                      QualType ExpT,
235223017Sdim                                      const ObjCMethodDecl *Method,
236223017Sdim                                      RValue Result) {
237223017Sdim  if (!Method)
238223017Sdim    return Result;
239224145Sdim
240223017Sdim  if (!Method->hasRelatedResultType() ||
241245431Sdim      CGF.getContext().hasSameType(ExpT, Method->getResultType()) ||
242223017Sdim      !Result.isScalar())
243223017Sdim    return Result;
244223017Sdim
245223017Sdim  // We have applied a related result type. Cast the rvalue appropriately.
246223017Sdim  return RValue::get(CGF.Builder.CreateBitCast(Result.getScalarVal(),
247245431Sdim                                               CGF.ConvertType(ExpT)));
248223017Sdim}
249193326Sed
250226890Sdim/// Decide whether to extend the lifetime of the receiver of a
251226890Sdim/// returns-inner-pointer message.
252226890Sdimstatic bool
253226890SdimshouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message) {
254226890Sdim  switch (message->getReceiverKind()) {
255226890Sdim
256226890Sdim  // For a normal instance message, we should extend unless the
257226890Sdim  // receiver is loaded from a variable with precise lifetime.
258226890Sdim  case ObjCMessageExpr::Instance: {
259226890Sdim    const Expr *receiver = message->getInstanceReceiver();
260226890Sdim    const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(receiver);
261226890Sdim    if (!ice || ice->getCastKind() != CK_LValueToRValue) return true;
262226890Sdim    receiver = ice->getSubExpr()->IgnoreParens();
263226890Sdim
264226890Sdim    // Only __strong variables.
265226890Sdim    if (receiver->getType().getObjCLifetime() != Qualifiers::OCL_Strong)
266226890Sdim      return true;
267226890Sdim
268226890Sdim    // All ivars and fields have precise lifetime.
269226890Sdim    if (isa<MemberExpr>(receiver) || isa<ObjCIvarRefExpr>(receiver))
270226890Sdim      return false;
271226890Sdim
272226890Sdim    // Otherwise, check for variables.
273226890Sdim    const DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(ice->getSubExpr());
274226890Sdim    if (!declRef) return true;
275226890Sdim    const VarDecl *var = dyn_cast<VarDecl>(declRef->getDecl());
276226890Sdim    if (!var) return true;
277226890Sdim
278226890Sdim    // All variables have precise lifetime except local variables with
279226890Sdim    // automatic storage duration that aren't specially marked.
280226890Sdim    return (var->hasLocalStorage() &&
281226890Sdim            !var->hasAttr<ObjCPreciseLifetimeAttr>());
282226890Sdim  }
283226890Sdim
284226890Sdim  case ObjCMessageExpr::Class:
285226890Sdim  case ObjCMessageExpr::SuperClass:
286226890Sdim    // It's never necessary for class objects.
287226890Sdim    return false;
288226890Sdim
289226890Sdim  case ObjCMessageExpr::SuperInstance:
290226890Sdim    // We generally assume that 'self' lives throughout a method call.
291226890Sdim    return false;
292226890Sdim  }
293226890Sdim
294226890Sdim  llvm_unreachable("invalid receiver kind");
295226890Sdim}
296226890Sdim
297208600SrdivackyRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
298208600Srdivacky                                            ReturnValueSlot Return) {
299193326Sed  // Only the lookup mechanism and first two arguments of the method
300193326Sed  // implementation vary between runtimes.  We can get the receiver and
301193326Sed  // arguments in generic code.
302198092Srdivacky
303224145Sdim  bool isDelegateInit = E->isDelegateInitCall();
304224145Sdim
305226890Sdim  const ObjCMethodDecl *method = E->getMethodDecl();
306226890Sdim
307224145Sdim  // We don't retain the receiver in delegate init calls, and this is
308224145Sdim  // safe because the receiver value is always loaded from 'self',
309224145Sdim  // which we zero out.  We don't want to Block_copy block receivers,
310224145Sdim  // though.
311224145Sdim  bool retainSelf =
312224145Sdim    (!isDelegateInit &&
313235633Sdim     CGM.getLangOpts().ObjCAutoRefCount &&
314226890Sdim     method &&
315226890Sdim     method->hasAttr<NSConsumesSelfAttr>());
316224145Sdim
317193326Sed  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
318193326Sed  bool isSuperMessage = false;
319193326Sed  bool isClassMessage = false;
320207619Srdivacky  ObjCInterfaceDecl *OID = 0;
321193326Sed  // Find the receiver
322223017Sdim  QualType ReceiverType;
323207619Srdivacky  llvm::Value *Receiver = 0;
324207619Srdivacky  switch (E->getReceiverKind()) {
325207619Srdivacky  case ObjCMessageExpr::Instance:
326223017Sdim    ReceiverType = E->getInstanceReceiver()->getType();
327224145Sdim    if (retainSelf) {
328224145Sdim      TryEmitResult ter = tryEmitARCRetainScalarExpr(*this,
329224145Sdim                                                   E->getInstanceReceiver());
330224145Sdim      Receiver = ter.getPointer();
331226890Sdim      if (ter.getInt()) retainSelf = false;
332224145Sdim    } else
333224145Sdim      Receiver = EmitScalarExpr(E->getInstanceReceiver());
334207619Srdivacky    break;
335193326Sed
336207619Srdivacky  case ObjCMessageExpr::Class: {
337223017Sdim    ReceiverType = E->getClassReceiver();
338223017Sdim    const ObjCObjectType *ObjTy = ReceiverType->getAs<ObjCObjectType>();
339208600Srdivacky    assert(ObjTy && "Invalid Objective-C class message send");
340208600Srdivacky    OID = ObjTy->getInterface();
341208600Srdivacky    assert(OID && "Invalid Objective-C class message send");
342252723Sdim    Receiver = Runtime.GetClass(*this, OID);
343207619Srdivacky    isClassMessage = true;
344207619Srdivacky    break;
345207619Srdivacky  }
346198092Srdivacky
347207619Srdivacky  case ObjCMessageExpr::SuperInstance:
348223017Sdim    ReceiverType = E->getSuperType();
349207619Srdivacky    Receiver = LoadObjCSelf();
350193326Sed    isSuperMessage = true;
351207619Srdivacky    break;
352207619Srdivacky
353207619Srdivacky  case ObjCMessageExpr::SuperClass:
354223017Sdim    ReceiverType = E->getSuperType();
355193326Sed    Receiver = LoadObjCSelf();
356207619Srdivacky    isSuperMessage = true;
357207619Srdivacky    isClassMessage = true;
358207619Srdivacky    break;
359193326Sed  }
360193326Sed
361226890Sdim  if (retainSelf)
362226890Sdim    Receiver = EmitARCRetainNonBlock(Receiver);
363226890Sdim
364226890Sdim  // In ARC, we sometimes want to "extend the lifetime"
365226890Sdim  // (i.e. retain+autorelease) of receivers of returns-inner-pointer
366226890Sdim  // messages.
367235633Sdim  if (getLangOpts().ObjCAutoRefCount && method &&
368226890Sdim      method->hasAttr<ObjCReturnsInnerPointerAttr>() &&
369226890Sdim      shouldExtendReceiverForInnerPointerMessage(E))
370226890Sdim    Receiver = EmitARCRetainAutorelease(ReceiverType, Receiver);
371226890Sdim
372224145Sdim  QualType ResultType =
373226890Sdim    method ? method->getResultType() : E->getType();
374224145Sdim
375193326Sed  CallArgList Args;
376226890Sdim  EmitCallArgs(Args, method, E->arg_begin(), E->arg_end());
377198092Srdivacky
378224145Sdim  // For delegate init calls in ARC, do an unsafe store of null into
379224145Sdim  // self.  This represents the call taking direct ownership of that
380224145Sdim  // value.  We have to do this after emitting the other call
381224145Sdim  // arguments because they might also reference self, but we don't
382224145Sdim  // have to worry about any of them modifying self because that would
383224145Sdim  // be an undefined read and write of an object in unordered
384224145Sdim  // expressions.
385224145Sdim  if (isDelegateInit) {
386235633Sdim    assert(getLangOpts().ObjCAutoRefCount &&
387224145Sdim           "delegate init calls should only be marked in ARC");
388210299Sed
389224145Sdim    // Do an unsafe store of null into self.
390224145Sdim    llvm::Value *selfAddr =
391224145Sdim      LocalDeclMap[cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()];
392224145Sdim    assert(selfAddr && "no self entry for a delegate init call?");
393224145Sdim
394224145Sdim    Builder.CreateStore(getNullForVariable(selfAddr), selfAddr);
395224145Sdim  }
396224145Sdim
397223017Sdim  RValue result;
398193326Sed  if (isSuperMessage) {
399193326Sed    // super is only valid in an Objective-C method
400193326Sed    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
401193326Sed    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
402223017Sdim    result = Runtime.GenerateMessageSendSuper(*this, Return, ResultType,
403223017Sdim                                              E->getSelector(),
404223017Sdim                                              OMD->getClassInterface(),
405223017Sdim                                              isCategoryImpl,
406223017Sdim                                              Receiver,
407223017Sdim                                              isClassMessage,
408223017Sdim                                              Args,
409226890Sdim                                              method);
410223017Sdim  } else {
411223017Sdim    result = Runtime.GenerateMessageSend(*this, Return, ResultType,
412223017Sdim                                         E->getSelector(),
413223017Sdim                                         Receiver, Args, OID,
414226890Sdim                                         method);
415193326Sed  }
416224145Sdim
417224145Sdim  // For delegate init calls in ARC, implicitly store the result of
418224145Sdim  // the call back into self.  This takes ownership of the value.
419224145Sdim  if (isDelegateInit) {
420224145Sdim    llvm::Value *selfAddr =
421224145Sdim      LocalDeclMap[cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()];
422224145Sdim    llvm::Value *newSelf = result.getScalarVal();
423224145Sdim
424224145Sdim    // The delegate return type isn't necessarily a matching type; in
425224145Sdim    // fact, it's quite likely to be 'id'.
426226890Sdim    llvm::Type *selfTy =
427224145Sdim      cast<llvm::PointerType>(selfAddr->getType())->getElementType();
428224145Sdim    newSelf = Builder.CreateBitCast(newSelf, selfTy);
429224145Sdim
430224145Sdim    Builder.CreateStore(newSelf, selfAddr);
431224145Sdim  }
432224145Sdim
433245431Sdim  return AdjustRelatedResultType(*this, E->getType(), method, result);
434193326Sed}
435193326Sed
436224145Sdimnamespace {
437224145Sdimstruct FinishARCDealloc : EHScopeStack::Cleanup {
438224145Sdim  void Emit(CodeGenFunction &CGF, Flags flags) {
439224145Sdim    const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CGF.CurCodeDecl);
440224145Sdim
441224145Sdim    const ObjCImplDecl *impl = cast<ObjCImplDecl>(method->getDeclContext());
442224145Sdim    const ObjCInterfaceDecl *iface = impl->getClassInterface();
443224145Sdim    if (!iface->getSuperClass()) return;
444224145Sdim
445224145Sdim    bool isCategory = isa<ObjCCategoryImplDecl>(impl);
446224145Sdim
447224145Sdim    // Call [super dealloc] if we have a superclass.
448224145Sdim    llvm::Value *self = CGF.LoadObjCSelf();
449224145Sdim
450224145Sdim    CallArgList args;
451224145Sdim    CGF.CGM.getObjCRuntime().GenerateMessageSendSuper(CGF, ReturnValueSlot(),
452224145Sdim                                                      CGF.getContext().VoidTy,
453224145Sdim                                                      method->getSelector(),
454224145Sdim                                                      iface,
455224145Sdim                                                      isCategory,
456224145Sdim                                                      self,
457224145Sdim                                                      /*is class msg*/ false,
458224145Sdim                                                      args,
459224145Sdim                                                      method);
460224145Sdim  }
461224145Sdim};
462224145Sdim}
463224145Sdim
464193326Sed/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
465193326Sed/// the LLVM function and sets the other context used by
466193326Sed/// CodeGenFunction.
467193326Sedvoid CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
468223017Sdim                                      const ObjCContainerDecl *CD,
469223017Sdim                                      SourceLocation StartLoc) {
470221345Sdim  FunctionArgList args;
471206275Srdivacky  // Check if we should generate debug info for this method.
472263509Sdim  if (OMD->hasAttr<NoDebugAttr>())
473263509Sdim    DebugInfo = NULL; // disable debug info indefinitely for this function
474206275Srdivacky
475193326Sed  llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
476193326Sed
477235633Sdim  const CGFunctionInfo &FI = CGM.getTypes().arrangeObjCMethodDeclaration(OMD);
478193326Sed  CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
479193326Sed
480221345Sdim  args.push_back(OMD->getSelfDecl());
481221345Sdim  args.push_back(OMD->getCmdDecl());
482193326Sed
483226890Sdim  for (ObjCMethodDecl::param_const_iterator PI = OMD->param_begin(),
484235633Sdim         E = OMD->param_end(); PI != E; ++PI)
485221345Sdim    args.push_back(*PI);
486193326Sed
487218893Sdim  CurGD = OMD;
488218893Sdim
489223017Sdim  StartFunction(OMD, OMD->getResultType(), Fn, FI, args, StartLoc);
490224145Sdim
491224145Sdim  // In ARC, certain methods get an extra cleanup.
492235633Sdim  if (CGM.getLangOpts().ObjCAutoRefCount &&
493224145Sdim      OMD->isInstanceMethod() &&
494224145Sdim      OMD->getSelector().isUnarySelector()) {
495224145Sdim    const IdentifierInfo *ident =
496224145Sdim      OMD->getSelector().getIdentifierInfoForSlot(0);
497224145Sdim    if (ident->isStr("dealloc"))
498224145Sdim      EHStack.pushCleanup<FinishARCDealloc>(getARCCleanupKind());
499224145Sdim  }
500193326Sed}
501193326Sed
502224145Sdimstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
503224145Sdim                                              LValue lvalue, QualType type);
504224145Sdim
505193326Sed/// Generate an Objective-C method.  An Objective-C method is a C function with
506198092Srdivacky/// its pointer, name, and types registered in the class struture.
507193326Sedvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
508223017Sdim  StartObjCMethod(OMD, OMD->getClassInterface(), OMD->getLocStart());
509195341Sed  EmitStmt(OMD->getBody());
510195341Sed  FinishFunction(OMD->getBodyRBrace());
511193326Sed}
512193326Sed
513226890Sdim/// emitStructGetterCall - Call the runtime function to load a property
514226890Sdim/// into the return value slot.
515226890Sdimstatic void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
516226890Sdim                                 bool isAtomic, bool hasStrong) {
517226890Sdim  ASTContext &Context = CGF.getContext();
518193326Sed
519226890Sdim  llvm::Value *src =
520226890Sdim    CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(),
521226890Sdim                          ivar, 0).getAddress();
522226890Sdim
523226890Sdim  // objc_copyStruct (ReturnValue, &structIvar,
524226890Sdim  //                  sizeof (Type of Ivar), isAtomic, false);
525226890Sdim  CallArgList args;
526226890Sdim
527226890Sdim  llvm::Value *dest = CGF.Builder.CreateBitCast(CGF.ReturnValue, CGF.VoidPtrTy);
528226890Sdim  args.add(RValue::get(dest), Context.VoidPtrTy);
529226890Sdim
530226890Sdim  src = CGF.Builder.CreateBitCast(src, CGF.VoidPtrTy);
531226890Sdim  args.add(RValue::get(src), Context.VoidPtrTy);
532226890Sdim
533226890Sdim  CharUnits size = CGF.getContext().getTypeSizeInChars(ivar->getType());
534226890Sdim  args.add(RValue::get(CGF.CGM.getSize(size)), Context.getSizeType());
535226890Sdim  args.add(RValue::get(CGF.Builder.getInt1(isAtomic)), Context.BoolTy);
536226890Sdim  args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy);
537226890Sdim
538226890Sdim  llvm::Value *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
539245431Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Context.VoidTy, args,
540245431Sdim                                                      FunctionType::ExtInfo(),
541245431Sdim                                                      RequiredArgs::All),
542226890Sdim               fn, ReturnValueSlot(), args);
543226890Sdim}
544226890Sdim
545226890Sdim/// Determine whether the given architecture supports unaligned atomic
546226890Sdim/// accesses.  They don't have to be fast, just faster than a function
547226890Sdim/// call and a mutex.
548226890Sdimstatic bool hasUnalignedAtomics(llvm::Triple::ArchType arch) {
549226890Sdim  // FIXME: Allow unaligned atomic load/store on x86.  (It is not
550226890Sdim  // currently supported by the backend.)
551226890Sdim  return 0;
552226890Sdim}
553226890Sdim
554226890Sdim/// Return the maximum size that permits atomic accesses for the given
555226890Sdim/// architecture.
556226890Sdimstatic CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM,
557226890Sdim                                        llvm::Triple::ArchType arch) {
558226890Sdim  // ARM has 8-byte atomic accesses, but it's not clear whether we
559226890Sdim  // want to rely on them here.
560226890Sdim
561226890Sdim  // In the default case, just assume that any size up to a pointer is
562226890Sdim  // fine given adequate alignment.
563226890Sdim  return CharUnits::fromQuantity(CGM.PointerSizeInBytes);
564226890Sdim}
565226890Sdim
566226890Sdimnamespace {
567226890Sdim  class PropertyImplStrategy {
568226890Sdim  public:
569226890Sdim    enum StrategyKind {
570226890Sdim      /// The 'native' strategy is to use the architecture's provided
571226890Sdim      /// reads and writes.
572226890Sdim      Native,
573226890Sdim
574226890Sdim      /// Use objc_setProperty and objc_getProperty.
575226890Sdim      GetSetProperty,
576226890Sdim
577226890Sdim      /// Use objc_setProperty for the setter, but use expression
578226890Sdim      /// evaluation for the getter.
579226890Sdim      SetPropertyAndExpressionGet,
580226890Sdim
581226890Sdim      /// Use objc_copyStruct.
582226890Sdim      CopyStruct,
583226890Sdim
584226890Sdim      /// The 'expression' strategy is to emit normal assignment or
585226890Sdim      /// lvalue-to-rvalue expressions.
586226890Sdim      Expression
587226890Sdim    };
588226890Sdim
589226890Sdim    StrategyKind getKind() const { return StrategyKind(Kind); }
590226890Sdim
591226890Sdim    bool hasStrongMember() const { return HasStrong; }
592226890Sdim    bool isAtomic() const { return IsAtomic; }
593226890Sdim    bool isCopy() const { return IsCopy; }
594226890Sdim
595226890Sdim    CharUnits getIvarSize() const { return IvarSize; }
596226890Sdim    CharUnits getIvarAlignment() const { return IvarAlignment; }
597226890Sdim
598226890Sdim    PropertyImplStrategy(CodeGenModule &CGM,
599226890Sdim                         const ObjCPropertyImplDecl *propImpl);
600226890Sdim
601226890Sdim  private:
602226890Sdim    unsigned Kind : 8;
603226890Sdim    unsigned IsAtomic : 1;
604226890Sdim    unsigned IsCopy : 1;
605226890Sdim    unsigned HasStrong : 1;
606226890Sdim
607226890Sdim    CharUnits IvarSize;
608226890Sdim    CharUnits IvarAlignment;
609226890Sdim  };
610226890Sdim}
611226890Sdim
612245431Sdim/// Pick an implementation strategy for the given property synthesis.
613226890SdimPropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
614226890Sdim                                     const ObjCPropertyImplDecl *propImpl) {
615226890Sdim  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
616226890Sdim  ObjCPropertyDecl::SetterKind setterKind = prop->getSetterKind();
617226890Sdim
618226890Sdim  IsCopy = (setterKind == ObjCPropertyDecl::Copy);
619226890Sdim  IsAtomic = prop->isAtomic();
620226890Sdim  HasStrong = false; // doesn't matter here.
621226890Sdim
622226890Sdim  // Evaluate the ivar's size and alignment.
623226890Sdim  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
624226890Sdim  QualType ivarType = ivar->getType();
625226890Sdim  llvm::tie(IvarSize, IvarAlignment)
626226890Sdim    = CGM.getContext().getTypeInfoInChars(ivarType);
627226890Sdim
628226890Sdim  // If we have a copy property, we always have to use getProperty/setProperty.
629226890Sdim  // TODO: we could actually use setProperty and an expression for non-atomics.
630226890Sdim  if (IsCopy) {
631226890Sdim    Kind = GetSetProperty;
632226890Sdim    return;
633226890Sdim  }
634226890Sdim
635226890Sdim  // Handle retain.
636226890Sdim  if (setterKind == ObjCPropertyDecl::Retain) {
637226890Sdim    // In GC-only, there's nothing special that needs to be done.
638235633Sdim    if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
639226890Sdim      // fallthrough
640226890Sdim
641226890Sdim    // In ARC, if the property is non-atomic, use expression emission,
642226890Sdim    // which translates to objc_storeStrong.  This isn't required, but
643226890Sdim    // it's slightly nicer.
644235633Sdim    } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) {
645245431Sdim      // Using standard expression emission for the setter is only
646245431Sdim      // acceptable if the ivar is __strong, which won't be true if
647245431Sdim      // the property is annotated with __attribute__((NSObject)).
648245431Sdim      // TODO: falling all the way back to objc_setProperty here is
649245431Sdim      // just laziness, though;  we could still use objc_storeStrong
650245431Sdim      // if we hacked it right.
651245431Sdim      if (ivarType.getObjCLifetime() == Qualifiers::OCL_Strong)
652245431Sdim        Kind = Expression;
653245431Sdim      else
654245431Sdim        Kind = SetPropertyAndExpressionGet;
655226890Sdim      return;
656226890Sdim
657226890Sdim    // Otherwise, we need to at least use setProperty.  However, if
658226890Sdim    // the property isn't atomic, we can use normal expression
659226890Sdim    // emission for the getter.
660226890Sdim    } else if (!IsAtomic) {
661226890Sdim      Kind = SetPropertyAndExpressionGet;
662226890Sdim      return;
663226890Sdim
664226890Sdim    // Otherwise, we have to use both setProperty and getProperty.
665226890Sdim    } else {
666226890Sdim      Kind = GetSetProperty;
667226890Sdim      return;
668226890Sdim    }
669226890Sdim  }
670226890Sdim
671226890Sdim  // If we're not atomic, just use expression accesses.
672226890Sdim  if (!IsAtomic) {
673226890Sdim    Kind = Expression;
674226890Sdim    return;
675226890Sdim  }
676226890Sdim
677226890Sdim  // Properties on bitfield ivars need to be emitted using expression
678226890Sdim  // accesses even if they're nominally atomic.
679226890Sdim  if (ivar->isBitField()) {
680226890Sdim    Kind = Expression;
681226890Sdim    return;
682226890Sdim  }
683226890Sdim
684226890Sdim  // GC-qualified or ARC-qualified ivars need to be emitted as
685226890Sdim  // expressions.  This actually works out to being atomic anyway,
686226890Sdim  // except for ARC __strong, but that should trigger the above code.
687226890Sdim  if (ivarType.hasNonTrivialObjCLifetime() ||
688235633Sdim      (CGM.getLangOpts().getGC() &&
689226890Sdim       CGM.getContext().getObjCGCAttrKind(ivarType))) {
690226890Sdim    Kind = Expression;
691226890Sdim    return;
692226890Sdim  }
693226890Sdim
694226890Sdim  // Compute whether the ivar has strong members.
695235633Sdim  if (CGM.getLangOpts().getGC())
696226890Sdim    if (const RecordType *recordType = ivarType->getAs<RecordType>())
697226890Sdim      HasStrong = recordType->getDecl()->hasObjectMember();
698226890Sdim
699226890Sdim  // We can never access structs with object members with a native
700226890Sdim  // access, because we need to use write barriers.  This is what
701226890Sdim  // objc_copyStruct is for.
702226890Sdim  if (HasStrong) {
703226890Sdim    Kind = CopyStruct;
704226890Sdim    return;
705226890Sdim  }
706226890Sdim
707226890Sdim  // Otherwise, this is target-dependent and based on the size and
708226890Sdim  // alignment of the ivar.
709226890Sdim
710226890Sdim  // If the size of the ivar is not a power of two, give up.  We don't
711226890Sdim  // want to get into the business of doing compare-and-swaps.
712226890Sdim  if (!IvarSize.isPowerOfTwo()) {
713226890Sdim    Kind = CopyStruct;
714226890Sdim    return;
715226890Sdim  }
716226890Sdim
717226890Sdim  llvm::Triple::ArchType arch =
718252723Sdim    CGM.getTarget().getTriple().getArch();
719226890Sdim
720226890Sdim  // Most architectures require memory to fit within a single cache
721226890Sdim  // line, so the alignment has to be at least the size of the access.
722226890Sdim  // Otherwise we have to grab a lock.
723226890Sdim  if (IvarAlignment < IvarSize && !hasUnalignedAtomics(arch)) {
724226890Sdim    Kind = CopyStruct;
725226890Sdim    return;
726226890Sdim  }
727226890Sdim
728226890Sdim  // If the ivar's size exceeds the architecture's maximum atomic
729226890Sdim  // access size, we have to use CopyStruct.
730226890Sdim  if (IvarSize > getMaxAtomicAccessSize(CGM, arch)) {
731226890Sdim    Kind = CopyStruct;
732226890Sdim    return;
733226890Sdim  }
734226890Sdim
735226890Sdim  // Otherwise, we can use native loads and stores.
736226890Sdim  Kind = Native;
737226890Sdim}
738226890Sdim
739245431Sdim/// \brief Generate an Objective-C property getter function.
740245431Sdim///
741245431Sdim/// The given Decl must be an ObjCImplementationDecl. \@synthesize
742193326Sed/// is illegal within a category.
743193326Sedvoid CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
744193326Sed                                         const ObjCPropertyImplDecl *PID) {
745235633Sdim  llvm::Constant *AtomicHelperFn =
746235633Sdim    GenerateObjCAtomicGetterCopyHelperFunction(PID);
747193326Sed  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
748193326Sed  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
749193326Sed  assert(OMD && "Invalid call to generate getter (empty method)");
750235633Sdim  StartObjCMethod(OMD, IMP->getClassInterface(), OMD->getLocStart());
751226890Sdim
752245431Sdim  generateObjCGetterBody(IMP, PID, OMD, AtomicHelperFn);
753226890Sdim
754226890Sdim  FinishFunction();
755226890Sdim}
756226890Sdim
757226890Sdimstatic bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl) {
758226890Sdim  const Expr *getter = propImpl->getGetterCXXConstructor();
759226890Sdim  if (!getter) return true;
760226890Sdim
761226890Sdim  // Sema only makes only of these when the ivar has a C++ class type,
762226890Sdim  // so the form is pretty constrained.
763226890Sdim
764226890Sdim  // If the property has a reference type, we might just be binding a
765226890Sdim  // reference, in which case the result will be a gl-value.  We should
766226890Sdim  // treat this as a non-trivial operation.
767226890Sdim  if (getter->isGLValue())
768226890Sdim    return false;
769226890Sdim
770226890Sdim  // If we selected a trivial copy-constructor, we're okay.
771226890Sdim  if (const CXXConstructExpr *construct = dyn_cast<CXXConstructExpr>(getter))
772226890Sdim    return (construct->getConstructor()->isTrivial());
773226890Sdim
774226890Sdim  // The constructor might require cleanups (in which case it's never
775226890Sdim  // trivial).
776226890Sdim  assert(isa<ExprWithCleanups>(getter));
777226890Sdim  return false;
778226890Sdim}
779226890Sdim
780235633Sdim/// emitCPPObjectAtomicGetterCall - Call the runtime function to
781235633Sdim/// copy the ivar into the resturn slot.
782235633Sdimstatic void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF,
783235633Sdim                                          llvm::Value *returnAddr,
784235633Sdim                                          ObjCIvarDecl *ivar,
785235633Sdim                                          llvm::Constant *AtomicHelperFn) {
786235633Sdim  // objc_copyCppObjectAtomic (&returnSlot, &CppObjectIvar,
787235633Sdim  //                           AtomicHelperFn);
788235633Sdim  CallArgList args;
789235633Sdim
790235633Sdim  // The 1st argument is the return Slot.
791235633Sdim  args.add(RValue::get(returnAddr), CGF.getContext().VoidPtrTy);
792235633Sdim
793235633Sdim  // The 2nd argument is the address of the ivar.
794235633Sdim  llvm::Value *ivarAddr =
795235633Sdim  CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
796235633Sdim                        CGF.LoadObjCSelf(), ivar, 0).getAddress();
797235633Sdim  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
798235633Sdim  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
799235633Sdim
800235633Sdim  // Third argument is the helper function.
801235633Sdim  args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
802235633Sdim
803235633Sdim  llvm::Value *copyCppAtomicObjectFn =
804252723Sdim    CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction();
805245431Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
806245431Sdim                                                      args,
807245431Sdim                                                      FunctionType::ExtInfo(),
808245431Sdim                                                      RequiredArgs::All),
809235633Sdim               copyCppAtomicObjectFn, ReturnValueSlot(), args);
810235633Sdim}
811235633Sdim
812226890Sdimvoid
813226890SdimCodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
814235633Sdim                                        const ObjCPropertyImplDecl *propImpl,
815245431Sdim                                        const ObjCMethodDecl *GetterMethodDecl,
816235633Sdim                                        llvm::Constant *AtomicHelperFn) {
817226890Sdim  // If there's a non-trivial 'get' expression, we just have to emit that.
818226890Sdim  if (!hasTrivialGetExpr(propImpl)) {
819235633Sdim    if (!AtomicHelperFn) {
820235633Sdim      ReturnStmt ret(SourceLocation(), propImpl->getGetterCXXConstructor(),
821235633Sdim                     /*nrvo*/ 0);
822235633Sdim      EmitReturnStmt(ret);
823235633Sdim    }
824235633Sdim    else {
825235633Sdim      ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
826235633Sdim      emitCPPObjectAtomicGetterCall(*this, ReturnValue,
827235633Sdim                                    ivar, AtomicHelperFn);
828235633Sdim    }
829226890Sdim    return;
830226890Sdim  }
831226890Sdim
832226890Sdim  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
833226890Sdim  QualType propType = prop->getType();
834226890Sdim  ObjCMethodDecl *getterMethod = prop->getGetterMethodDecl();
835226890Sdim
836226890Sdim  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
837226890Sdim
838226890Sdim  // Pick an implementation strategy.
839226890Sdim  PropertyImplStrategy strategy(CGM, propImpl);
840226890Sdim  switch (strategy.getKind()) {
841226890Sdim  case PropertyImplStrategy::Native: {
842245431Sdim    // We don't need to do anything for a zero-size struct.
843245431Sdim    if (strategy.getIvarSize().isZero())
844245431Sdim      return;
845245431Sdim
846226890Sdim    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0);
847226890Sdim
848226890Sdim    // Currently, all atomic accesses have to be through integer
849226890Sdim    // types, so there's no point in trying to pick a prettier type.
850226890Sdim    llvm::Type *bitcastType =
851226890Sdim      llvm::Type::getIntNTy(getLLVMContext(),
852226890Sdim                            getContext().toBits(strategy.getIvarSize()));
853226890Sdim    bitcastType = bitcastType->getPointerTo(); // addrspace 0 okay
854226890Sdim
855226890Sdim    // Perform an atomic load.  This does not impose ordering constraints.
856226890Sdim    llvm::Value *ivarAddr = LV.getAddress();
857226890Sdim    ivarAddr = Builder.CreateBitCast(ivarAddr, bitcastType);
858226890Sdim    llvm::LoadInst *load = Builder.CreateLoad(ivarAddr, "load");
859226890Sdim    load->setAlignment(strategy.getIvarAlignment().getQuantity());
860226890Sdim    load->setAtomic(llvm::Unordered);
861226890Sdim
862226890Sdim    // Store that value into the return address.  Doing this with a
863226890Sdim    // bitcast is likely to produce some pretty ugly IR, but it's not
864226890Sdim    // the *most* terrible thing in the world.
865226890Sdim    Builder.CreateStore(load, Builder.CreateBitCast(ReturnValue, bitcastType));
866226890Sdim
867226890Sdim    // Make sure we don't do an autorelease.
868226890Sdim    AutoreleaseResult = false;
869226890Sdim    return;
870226890Sdim  }
871226890Sdim
872226890Sdim  case PropertyImplStrategy::GetSetProperty: {
873226890Sdim    llvm::Value *getPropertyFn =
874193326Sed      CGM.getObjCRuntime().GetPropertyGetFunction();
875226890Sdim    if (!getPropertyFn) {
876226890Sdim      CGM.ErrorUnsupported(propImpl, "Obj-C getter requiring atomic copy");
877193326Sed      return;
878193326Sed    }
879193326Sed
880193326Sed    // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
881193326Sed    // FIXME: Can't this be simpler? This might even be worse than the
882193326Sed    // corresponding gcc code.
883226890Sdim    llvm::Value *cmd =
884226890Sdim      Builder.CreateLoad(LocalDeclMap[getterMethod->getCmdDecl()], "cmd");
885226890Sdim    llvm::Value *self = Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
886226890Sdim    llvm::Value *ivarOffset =
887226890Sdim      EmitIvarOffset(classImpl->getClassInterface(), ivar);
888226890Sdim
889226890Sdim    CallArgList args;
890226890Sdim    args.add(RValue::get(self), getContext().getObjCIdType());
891226890Sdim    args.add(RValue::get(cmd), getContext().getObjCSelType());
892226890Sdim    args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
893226890Sdim    args.add(RValue::get(Builder.getInt1(strategy.isAtomic())),
894226890Sdim             getContext().BoolTy);
895226890Sdim
896193326Sed    // FIXME: We shouldn't need to get the function info here, the
897193326Sed    // runtime already should have computed it to build the function.
898245431Sdim    RValue RV = EmitCall(getTypes().arrangeFreeFunctionCall(propType, args,
899245431Sdim                                                       FunctionType::ExtInfo(),
900245431Sdim                                                            RequiredArgs::All),
901226890Sdim                         getPropertyFn, ReturnValueSlot(), args);
902226890Sdim
903193326Sed    // We need to fix the type here. Ivars with copy & retain are
904193326Sed    // always objects so we don't need to worry about complex or
905193326Sed    // aggregates.
906198092Srdivacky    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
907245431Sdim           getTypes().ConvertType(getterMethod->getResultType())));
908224145Sdim
909226890Sdim    EmitReturnOfRValue(RV, propType);
910226890Sdim
911224145Sdim    // objc_getProperty does an autorelease, so we should suppress ours.
912224145Sdim    AutoreleaseResult = false;
913226890Sdim
914226890Sdim    return;
915226890Sdim  }
916226890Sdim
917226890Sdim  case PropertyImplStrategy::CopyStruct:
918226890Sdim    emitStructGetterCall(*this, ivar, strategy.isAtomic(),
919226890Sdim                         strategy.hasStrongMember());
920226890Sdim    return;
921226890Sdim
922226890Sdim  case PropertyImplStrategy::Expression:
923226890Sdim  case PropertyImplStrategy::SetPropertyAndExpressionGet: {
924226890Sdim    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0);
925226890Sdim
926226890Sdim    QualType ivarType = ivar->getType();
927252723Sdim    switch (getEvaluationKind(ivarType)) {
928252723Sdim    case TEK_Complex: {
929263509Sdim      ComplexPairTy pair = EmitLoadOfComplex(LV, SourceLocation());
930252723Sdim      EmitStoreOfComplex(pair,
931252723Sdim                         MakeNaturalAlignAddrLValue(ReturnValue, ivarType),
932252723Sdim                         /*init*/ true);
933252723Sdim      return;
934252723Sdim    }
935252723Sdim    case TEK_Aggregate:
936226890Sdim      // The return value slot is guaranteed to not be aliased, but
937226890Sdim      // that's not necessarily the same as "on the stack", so
938226890Sdim      // we still potentially need objc_memmove_collectable.
939226890Sdim      EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType);
940252723Sdim      return;
941252723Sdim    case TEK_Scalar: {
942226890Sdim      llvm::Value *value;
943226890Sdim      if (propType->isReferenceType()) {
944226890Sdim        value = LV.getAddress();
945226890Sdim      } else {
946226890Sdim        // We want to load and autoreleaseReturnValue ARC __weak ivars.
947226890Sdim        if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {
948226890Sdim          value = emitARCRetainLoadOfScalar(*this, LV, ivarType);
949224145Sdim
950226890Sdim        // Otherwise we want to do a simple load, suppressing the
951226890Sdim        // final autorelease.
952224145Sdim        } else {
953263509Sdim          value = EmitLoadOfLValue(LV, SourceLocation()).getScalarVal();
954226890Sdim          AutoreleaseResult = false;
955221345Sdim        }
956224145Sdim
957226890Sdim        value = Builder.CreateBitCast(value, ConvertType(propType));
958245431Sdim        value = Builder.CreateBitCast(value,
959245431Sdim                  ConvertType(GetterMethodDecl->getResultType()));
960226890Sdim      }
961226890Sdim
962226890Sdim      EmitReturnOfRValue(RValue::get(value), propType);
963252723Sdim      return;
964193326Sed    }
965252723Sdim    }
966252723Sdim    llvm_unreachable("bad evaluation kind");
967193326Sed  }
968193326Sed
969226890Sdim  }
970226890Sdim  llvm_unreachable("bad @property implementation strategy!");
971193326Sed}
972193326Sed
973226890Sdim/// emitStructSetterCall - Call the runtime function to store the value
974226890Sdim/// from the first formal parameter into the given ivar.
975226890Sdimstatic void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
976226890Sdim                                 ObjCIvarDecl *ivar) {
977218893Sdim  // objc_copyStruct (&structIvar, &Arg,
978218893Sdim  //                  sizeof (struct something), true, false);
979226890Sdim  CallArgList args;
980226890Sdim
981226890Sdim  // The first argument is the address of the ivar.
982226890Sdim  llvm::Value *ivarAddr = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
983226890Sdim                                                CGF.LoadObjCSelf(), ivar, 0)
984226890Sdim    .getAddress();
985226890Sdim  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
986226890Sdim  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
987226890Sdim
988226890Sdim  // The second argument is the address of the parameter variable.
989226890Sdim  ParmVarDecl *argVar = *OMD->param_begin();
990235633Sdim  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
991235633Sdim                     VK_LValue, SourceLocation());
992226890Sdim  llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
993226890Sdim  argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
994226890Sdim  args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
995226890Sdim
996226890Sdim  // The third argument is the sizeof the type.
997226890Sdim  llvm::Value *size =
998226890Sdim    CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(ivar->getType()));
999226890Sdim  args.add(RValue::get(size), CGF.getContext().getSizeType());
1000226890Sdim
1001226890Sdim  // The fourth argument is the 'isAtomic' flag.
1002226890Sdim  args.add(RValue::get(CGF.Builder.getTrue()), CGF.getContext().BoolTy);
1003226890Sdim
1004226890Sdim  // The fifth argument is the 'hasStrong' flag.
1005226890Sdim  // FIXME: should this really always be false?
1006226890Sdim  args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy);
1007226890Sdim
1008226890Sdim  llvm::Value *copyStructFn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
1009245431Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
1010245431Sdim                                                      args,
1011245431Sdim                                                      FunctionType::ExtInfo(),
1012245431Sdim                                                      RequiredArgs::All),
1013226890Sdim               copyStructFn, ReturnValueSlot(), args);
1014218893Sdim}
1015218893Sdim
1016235633Sdim/// emitCPPObjectAtomicSetterCall - Call the runtime function to store
1017235633Sdim/// the value from the first formal parameter into the given ivar, using
1018235633Sdim/// the Cpp API for atomic Cpp objects with non-trivial copy assignment.
1019235633Sdimstatic void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
1020235633Sdim                                          ObjCMethodDecl *OMD,
1021235633Sdim                                          ObjCIvarDecl *ivar,
1022235633Sdim                                          llvm::Constant *AtomicHelperFn) {
1023235633Sdim  // objc_copyCppObjectAtomic (&CppObjectIvar, &Arg,
1024235633Sdim  //                           AtomicHelperFn);
1025235633Sdim  CallArgList args;
1026235633Sdim
1027235633Sdim  // The first argument is the address of the ivar.
1028235633Sdim  llvm::Value *ivarAddr =
1029235633Sdim    CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
1030235633Sdim                          CGF.LoadObjCSelf(), ivar, 0).getAddress();
1031235633Sdim  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
1032235633Sdim  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
1033235633Sdim
1034235633Sdim  // The second argument is the address of the parameter variable.
1035235633Sdim  ParmVarDecl *argVar = *OMD->param_begin();
1036235633Sdim  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
1037235633Sdim                     VK_LValue, SourceLocation());
1038235633Sdim  llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
1039235633Sdim  argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
1040235633Sdim  args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
1041235633Sdim
1042235633Sdim  // Third argument is the helper function.
1043235633Sdim  args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
1044235633Sdim
1045235633Sdim  llvm::Value *copyCppAtomicObjectFn =
1046252723Sdim    CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction();
1047245431Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
1048245431Sdim                                                      args,
1049245431Sdim                                                      FunctionType::ExtInfo(),
1050245431Sdim                                                      RequiredArgs::All),
1051235633Sdim               copyCppAtomicObjectFn, ReturnValueSlot(), args);
1052235633Sdim}
1053235633Sdim
1054235633Sdim
1055226890Sdimstatic bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID) {
1056226890Sdim  Expr *setter = PID->getSetterCXXAssignment();
1057226890Sdim  if (!setter) return true;
1058226890Sdim
1059226890Sdim  // Sema only makes only of these when the ivar has a C++ class type,
1060226890Sdim  // so the form is pretty constrained.
1061226890Sdim
1062226890Sdim  // An operator call is trivial if the function it calls is trivial.
1063226890Sdim  // This also implies that there's nothing non-trivial going on with
1064226890Sdim  // the arguments, because operator= can only be trivial if it's a
1065226890Sdim  // synthesized assignment operator and therefore both parameters are
1066226890Sdim  // references.
1067226890Sdim  if (CallExpr *call = dyn_cast<CallExpr>(setter)) {
1068226890Sdim    if (const FunctionDecl *callee
1069226890Sdim          = dyn_cast_or_null<FunctionDecl>(call->getCalleeDecl()))
1070226890Sdim      if (callee->isTrivial())
1071226890Sdim        return true;
1072226890Sdim    return false;
1073221345Sdim  }
1074226890Sdim
1075226890Sdim  assert(isa<ExprWithCleanups>(setter));
1076226890Sdim  return false;
1077221345Sdim}
1078221345Sdim
1079235633Sdimstatic bool UseOptimizedSetter(CodeGenModule &CGM) {
1080235633Sdim  if (CGM.getLangOpts().getGC() != LangOptions::NonGC)
1081235633Sdim    return false;
1082245431Sdim  return CGM.getLangOpts().ObjCRuntime.hasOptimizedSetter();
1083235633Sdim}
1084235633Sdim
1085226890Sdimvoid
1086226890SdimCodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
1087235633Sdim                                        const ObjCPropertyImplDecl *propImpl,
1088235633Sdim                                        llvm::Constant *AtomicHelperFn) {
1089235633Sdim  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
1090235633Sdim  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
1091235633Sdim  ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
1092235633Sdim
1093226890Sdim  // Just use the setter expression if Sema gave us one and it's
1094235633Sdim  // non-trivial.
1095226890Sdim  if (!hasTrivialSetExpr(propImpl)) {
1096235633Sdim    if (!AtomicHelperFn)
1097235633Sdim      // If non-atomic, assignment is called directly.
1098235633Sdim      EmitStmt(propImpl->getSetterCXXAssignment());
1099235633Sdim    else
1100235633Sdim      // If atomic, assignment is called via a locking api.
1101235633Sdim      emitCPPObjectAtomicSetterCall(*this, setterMethod, ivar,
1102235633Sdim                                    AtomicHelperFn);
1103226890Sdim    return;
1104226890Sdim  }
1105193326Sed
1106226890Sdim  PropertyImplStrategy strategy(CGM, propImpl);
1107226890Sdim  switch (strategy.getKind()) {
1108226890Sdim  case PropertyImplStrategy::Native: {
1109245431Sdim    // We don't need to do anything for a zero-size struct.
1110245431Sdim    if (strategy.getIvarSize().isZero())
1111245431Sdim      return;
1112245431Sdim
1113226890Sdim    llvm::Value *argAddr = LocalDeclMap[*setterMethod->param_begin()];
1114226890Sdim
1115226890Sdim    LValue ivarLValue =
1116226890Sdim      EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, /*quals*/ 0);
1117226890Sdim    llvm::Value *ivarAddr = ivarLValue.getAddress();
1118226890Sdim
1119226890Sdim    // Currently, all atomic accesses have to be through integer
1120226890Sdim    // types, so there's no point in trying to pick a prettier type.
1121226890Sdim    llvm::Type *bitcastType =
1122226890Sdim      llvm::Type::getIntNTy(getLLVMContext(),
1123226890Sdim                            getContext().toBits(strategy.getIvarSize()));
1124226890Sdim    bitcastType = bitcastType->getPointerTo(); // addrspace 0 okay
1125226890Sdim
1126226890Sdim    // Cast both arguments to the chosen operation type.
1127226890Sdim    argAddr = Builder.CreateBitCast(argAddr, bitcastType);
1128226890Sdim    ivarAddr = Builder.CreateBitCast(ivarAddr, bitcastType);
1129226890Sdim
1130226890Sdim    // This bitcast load is likely to cause some nasty IR.
1131226890Sdim    llvm::Value *load = Builder.CreateLoad(argAddr);
1132226890Sdim
1133226890Sdim    // Perform an atomic store.  There are no memory ordering requirements.
1134226890Sdim    llvm::StoreInst *store = Builder.CreateStore(load, ivarAddr);
1135226890Sdim    store->setAlignment(strategy.getIvarAlignment().getQuantity());
1136226890Sdim    store->setAtomic(llvm::Unordered);
1137226890Sdim    return;
1138226890Sdim  }
1139226890Sdim
1140226890Sdim  case PropertyImplStrategy::GetSetProperty:
1141226890Sdim  case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1142235633Sdim
1143235633Sdim    llvm::Value *setOptimizedPropertyFn = 0;
1144235633Sdim    llvm::Value *setPropertyFn = 0;
1145235633Sdim    if (UseOptimizedSetter(CGM)) {
1146245431Sdim      // 10.8 and iOS 6.0 code and GC is off
1147235633Sdim      setOptimizedPropertyFn =
1148235633Sdim        CGM.getObjCRuntime()
1149235633Sdim           .GetOptimizedPropertySetFunction(strategy.isAtomic(),
1150235633Sdim                                            strategy.isCopy());
1151235633Sdim      if (!setOptimizedPropertyFn) {
1152235633Sdim        CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI");
1153235633Sdim        return;
1154235633Sdim      }
1155193326Sed    }
1156235633Sdim    else {
1157235633Sdim      setPropertyFn = CGM.getObjCRuntime().GetPropertySetFunction();
1158235633Sdim      if (!setPropertyFn) {
1159235633Sdim        CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");
1160235633Sdim        return;
1161235633Sdim      }
1162235633Sdim    }
1163235633Sdim
1164198092Srdivacky    // Emit objc_setProperty((id) self, _cmd, offset, arg,
1165193326Sed    //                       <is-atomic>, <is-copy>).
1166226890Sdim    llvm::Value *cmd =
1167226890Sdim      Builder.CreateLoad(LocalDeclMap[setterMethod->getCmdDecl()]);
1168226890Sdim    llvm::Value *self =
1169226890Sdim      Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
1170226890Sdim    llvm::Value *ivarOffset =
1171226890Sdim      EmitIvarOffset(classImpl->getClassInterface(), ivar);
1172226890Sdim    llvm::Value *arg = LocalDeclMap[*setterMethod->param_begin()];
1173226890Sdim    arg = Builder.CreateBitCast(Builder.CreateLoad(arg, "arg"), VoidPtrTy);
1174226890Sdim
1175226890Sdim    CallArgList args;
1176226890Sdim    args.add(RValue::get(self), getContext().getObjCIdType());
1177226890Sdim    args.add(RValue::get(cmd), getContext().getObjCSelType());
1178235633Sdim    if (setOptimizedPropertyFn) {
1179235633Sdim      args.add(RValue::get(arg), getContext().getObjCIdType());
1180235633Sdim      args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
1181245431Sdim      EmitCall(getTypes().arrangeFreeFunctionCall(getContext().VoidTy, args,
1182245431Sdim                                                  FunctionType::ExtInfo(),
1183245431Sdim                                                  RequiredArgs::All),
1184235633Sdim               setOptimizedPropertyFn, ReturnValueSlot(), args);
1185235633Sdim    } else {
1186235633Sdim      args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
1187235633Sdim      args.add(RValue::get(arg), getContext().getObjCIdType());
1188235633Sdim      args.add(RValue::get(Builder.getInt1(strategy.isAtomic())),
1189235633Sdim               getContext().BoolTy);
1190235633Sdim      args.add(RValue::get(Builder.getInt1(strategy.isCopy())),
1191235633Sdim               getContext().BoolTy);
1192235633Sdim      // FIXME: We shouldn't need to get the function info here, the runtime
1193235633Sdim      // already should have computed it to build the function.
1194245431Sdim      EmitCall(getTypes().arrangeFreeFunctionCall(getContext().VoidTy, args,
1195245431Sdim                                                  FunctionType::ExtInfo(),
1196245431Sdim                                                  RequiredArgs::All),
1197235633Sdim               setPropertyFn, ReturnValueSlot(), args);
1198235633Sdim    }
1199235633Sdim
1200226890Sdim    return;
1201226890Sdim  }
1202226890Sdim
1203226890Sdim  case PropertyImplStrategy::CopyStruct:
1204226890Sdim    emitStructSetterCall(*this, setterMethod, ivar);
1205226890Sdim    return;
1206226890Sdim
1207226890Sdim  case PropertyImplStrategy::Expression:
1208226890Sdim    break;
1209226890Sdim  }
1210226890Sdim
1211226890Sdim  // Otherwise, fake up some ASTs and emit a normal assignment.
1212226890Sdim  ValueDecl *selfDecl = setterMethod->getSelfDecl();
1213235633Sdim  DeclRefExpr self(selfDecl, false, selfDecl->getType(),
1214235633Sdim                   VK_LValue, SourceLocation());
1215226890Sdim  ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
1216226890Sdim                            selfDecl->getType(), CK_LValueToRValue, &self,
1217226890Sdim                            VK_RValue);
1218226890Sdim  ObjCIvarRefExpr ivarRef(ivar, ivar->getType().getNonReferenceType(),
1219252723Sdim                          SourceLocation(), SourceLocation(),
1220252723Sdim                          &selfLoad, true, true);
1221226890Sdim
1222226890Sdim  ParmVarDecl *argDecl = *setterMethod->param_begin();
1223226890Sdim  QualType argType = argDecl->getType().getNonReferenceType();
1224235633Sdim  DeclRefExpr arg(argDecl, false, argType, VK_LValue, SourceLocation());
1225226890Sdim  ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
1226226890Sdim                           argType.getUnqualifiedType(), CK_LValueToRValue,
1227226890Sdim                           &arg, VK_RValue);
1228198893Srdivacky
1229226890Sdim  // The property type can differ from the ivar type in some situations with
1230226890Sdim  // Objective-C pointer types, we can always bit cast the RHS in these cases.
1231226890Sdim  // The following absurdity is just to ensure well-formed IR.
1232226890Sdim  CastKind argCK = CK_NoOp;
1233226890Sdim  if (ivarRef.getType()->isObjCObjectPointerType()) {
1234226890Sdim    if (argLoad.getType()->isObjCObjectPointerType())
1235226890Sdim      argCK = CK_BitCast;
1236226890Sdim    else if (argLoad.getType()->isBlockPointerType())
1237226890Sdim      argCK = CK_BlockPointerToObjCPointerCast;
1238226890Sdim    else
1239226890Sdim      argCK = CK_CPointerToObjCPointerCast;
1240226890Sdim  } else if (ivarRef.getType()->isBlockPointerType()) {
1241226890Sdim     if (argLoad.getType()->isBlockPointerType())
1242226890Sdim      argCK = CK_BitCast;
1243226890Sdim    else
1244226890Sdim      argCK = CK_AnyPointerToBlockPointerCast;
1245226890Sdim  } else if (ivarRef.getType()->isPointerType()) {
1246226890Sdim    argCK = CK_BitCast;
1247193326Sed  }
1248226890Sdim  ImplicitCastExpr argCast(ImplicitCastExpr::OnStack,
1249226890Sdim                           ivarRef.getType(), argCK, &argLoad,
1250226890Sdim                           VK_RValue);
1251226890Sdim  Expr *finalArg = &argLoad;
1252226890Sdim  if (!getContext().hasSameUnqualifiedType(ivarRef.getType(),
1253226890Sdim                                           argLoad.getType()))
1254226890Sdim    finalArg = &argCast;
1255193326Sed
1256226890Sdim
1257226890Sdim  BinaryOperator assign(&ivarRef, finalArg, BO_Assign,
1258226890Sdim                        ivarRef.getType(), VK_RValue, OK_Ordinary,
1259245431Sdim                        SourceLocation(), false);
1260226890Sdim  EmitStmt(&assign);
1261226890Sdim}
1262226890Sdim
1263245431Sdim/// \brief Generate an Objective-C property setter function.
1264245431Sdim///
1265245431Sdim/// The given Decl must be an ObjCImplementationDecl. \@synthesize
1266226890Sdim/// is illegal within a category.
1267226890Sdimvoid CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
1268226890Sdim                                         const ObjCPropertyImplDecl *PID) {
1269235633Sdim  llvm::Constant *AtomicHelperFn =
1270235633Sdim    GenerateObjCAtomicSetterCopyHelperFunction(PID);
1271226890Sdim  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
1272226890Sdim  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
1273226890Sdim  assert(OMD && "Invalid call to generate setter (empty method)");
1274235633Sdim  StartObjCMethod(OMD, IMP->getClassInterface(), OMD->getLocStart());
1275226890Sdim
1276235633Sdim  generateObjCSetterBody(IMP, PID, AtomicHelperFn);
1277226890Sdim
1278193326Sed  FinishFunction();
1279193326Sed}
1280193326Sed
1281221345Sdimnamespace {
1282224145Sdim  struct DestroyIvar : EHScopeStack::Cleanup {
1283224145Sdim  private:
1284224145Sdim    llvm::Value *addr;
1285221345Sdim    const ObjCIvarDecl *ivar;
1286235633Sdim    CodeGenFunction::Destroyer *destroyer;
1287224145Sdim    bool useEHCleanupForArray;
1288224145Sdim  public:
1289224145Sdim    DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
1290224145Sdim                CodeGenFunction::Destroyer *destroyer,
1291224145Sdim                bool useEHCleanupForArray)
1292235633Sdim      : addr(addr), ivar(ivar), destroyer(destroyer),
1293224145Sdim        useEHCleanupForArray(useEHCleanupForArray) {}
1294221345Sdim
1295224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
1296224145Sdim      LValue lvalue
1297224145Sdim        = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0);
1298224145Sdim      CGF.emitDestroy(lvalue.getAddress(), ivar->getType(), destroyer,
1299224145Sdim                      flags.isForNormalCleanup() && useEHCleanupForArray);
1300221345Sdim    }
1301221345Sdim  };
1302224145Sdim}
1303221345Sdim
1304224145Sdim/// Like CodeGenFunction::destroyARCStrong, but do it with a call.
1305224145Sdimstatic void destroyARCStrongWithStore(CodeGenFunction &CGF,
1306224145Sdim                                      llvm::Value *addr,
1307224145Sdim                                      QualType type) {
1308224145Sdim  llvm::Value *null = getNullForVariable(addr);
1309224145Sdim  CGF.EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
1310221345Sdim}
1311221345Sdim
1312221345Sdimstatic void emitCXXDestructMethod(CodeGenFunction &CGF,
1313221345Sdim                                  ObjCImplementationDecl *impl) {
1314221345Sdim  CodeGenFunction::RunCleanupsScope scope(CGF);
1315221345Sdim
1316221345Sdim  llvm::Value *self = CGF.LoadObjCSelf();
1317221345Sdim
1318226890Sdim  const ObjCInterfaceDecl *iface = impl->getClassInterface();
1319226890Sdim  for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
1320221345Sdim       ivar; ivar = ivar->getNextIvar()) {
1321221345Sdim    QualType type = ivar->getType();
1322221345Sdim
1323221345Sdim    // Check whether the ivar is a destructible type.
1324224145Sdim    QualType::DestructionKind dtorKind = type.isDestructedType();
1325224145Sdim    if (!dtorKind) continue;
1326221345Sdim
1327224145Sdim    CodeGenFunction::Destroyer *destroyer = 0;
1328221345Sdim
1329224145Sdim    // Use a call to objc_storeStrong to destroy strong ivars, for the
1330224145Sdim    // general benefit of the tools.
1331224145Sdim    if (dtorKind == QualType::DK_objc_strong_lifetime) {
1332235633Sdim      destroyer = destroyARCStrongWithStore;
1333224145Sdim
1334224145Sdim    // Otherwise use the default for the destruction kind.
1335224145Sdim    } else {
1336235633Sdim      destroyer = CGF.getDestroyer(dtorKind);
1337221345Sdim    }
1338224145Sdim
1339224145Sdim    CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind);
1340224145Sdim
1341224145Sdim    CGF.EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
1342224145Sdim                                         cleanupKind & EHCleanup);
1343221345Sdim  }
1344221345Sdim
1345221345Sdim  assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
1346221345Sdim}
1347221345Sdim
1348207619Srdivackyvoid CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
1349207619Srdivacky                                                 ObjCMethodDecl *MD,
1350207619Srdivacky                                                 bool ctor) {
1351207619Srdivacky  MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
1352223017Sdim  StartObjCMethod(MD, IMP->getClassInterface(), MD->getLocStart());
1353221345Sdim
1354221345Sdim  // Emit .cxx_construct.
1355207619Srdivacky  if (ctor) {
1356224145Sdim    // Suppress the final autorelease in ARC.
1357224145Sdim    AutoreleaseResult = false;
1358224145Sdim
1359226890Sdim    SmallVector<CXXCtorInitializer *, 8> IvarInitializers;
1360221345Sdim    for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
1361221345Sdim           E = IMP->init_end(); B != E; ++B) {
1362221345Sdim      CXXCtorInitializer *IvarInit = (*B);
1363218893Sdim      FieldDecl *Field = IvarInit->getAnyMember();
1364207619Srdivacky      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
1365207619Srdivacky      LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
1366207619Srdivacky                                    LoadObjCSelf(), Ivar, 0);
1367226890Sdim      EmitAggExpr(IvarInit->getInit(),
1368226890Sdim                  AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed,
1369226890Sdim                                          AggValueSlot::DoesNotNeedGCBarriers,
1370226890Sdim                                          AggValueSlot::IsNotAliased));
1371207619Srdivacky    }
1372207619Srdivacky    // constructor returns 'self'.
1373207619Srdivacky    CodeGenTypes &Types = CGM.getTypes();
1374207619Srdivacky    QualType IdTy(CGM.getContext().getObjCIdType());
1375207619Srdivacky    llvm::Value *SelfAsId =
1376207619Srdivacky      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
1377207619Srdivacky    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
1378221345Sdim
1379221345Sdim  // Emit .cxx_destruct.
1380208600Srdivacky  } else {
1381221345Sdim    emitCXXDestructMethod(*this, IMP);
1382207619Srdivacky  }
1383207619Srdivacky  FinishFunction();
1384207619Srdivacky}
1385207619Srdivacky
1386207619Srdivackybool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
1387207619Srdivacky  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
1388207619Srdivacky  it++; it++;
1389207619Srdivacky  const ABIArgInfo &AI = it->info;
1390207619Srdivacky  // FIXME. Is this sufficient check?
1391207619Srdivacky  return (AI.getKind() == ABIArgInfo::Indirect);
1392207619Srdivacky}
1393207619Srdivacky
1394207619Srdivackybool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
1395235633Sdim  if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
1396207619Srdivacky    return false;
1397207619Srdivacky  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
1398207619Srdivacky    return FDTTy->getDecl()->hasObjectMember();
1399207619Srdivacky  return false;
1400207619Srdivacky}
1401207619Srdivacky
1402193326Sedllvm::Value *CodeGenFunction::LoadObjCSelf() {
1403252723Sdim  VarDecl *Self = cast<ObjCMethodDecl>(CurFuncDecl)->getSelfDecl();
1404252723Sdim  DeclRefExpr DRE(Self, /*is enclosing local*/ (CurFuncDecl != CurCodeDecl),
1405252723Sdim                  Self->getType(), VK_LValue, SourceLocation());
1406263509Sdim  return EmitLoadOfScalar(EmitDeclRefLValue(&DRE), SourceLocation());
1407193326Sed}
1408193326Sed
1409193326SedQualType CodeGenFunction::TypeOfSelfObject() {
1410193326Sed  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
1411193326Sed  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
1412198092Srdivacky  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
1413198092Srdivacky    getContext().getCanonicalType(selfDecl->getType()));
1414193326Sed  return PTy->getPointeeType();
1415193326Sed}
1416193326Sed
1417193326Sedvoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
1418198092Srdivacky  llvm::Constant *EnumerationMutationFn =
1419193326Sed    CGM.getObjCRuntime().EnumerationMutationFunction();
1420198092Srdivacky
1421193326Sed  if (!EnumerationMutationFn) {
1422193326Sed    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
1423193326Sed    return;
1424193326Sed  }
1425193326Sed
1426218893Sdim  CGDebugInfo *DI = getDebugInfo();
1427226890Sdim  if (DI)
1428226890Sdim    DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
1429198092Srdivacky
1430224145Sdim  // The local variable comes into scope immediately.
1431224145Sdim  AutoVarEmission variable = AutoVarEmission::invalid();
1432224145Sdim  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
1433224145Sdim    variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl()));
1434224145Sdim
1435218893Sdim  JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
1436218893Sdim
1437193326Sed  // Fast enumeration state.
1438226890Sdim  QualType StateTy = CGM.getObjCFastEnumerationStateType();
1439203955Srdivacky  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
1440208600Srdivacky  EmitNullInitialization(StatePtr, StateTy);
1441198092Srdivacky
1442193326Sed  // Number of elements in the items array.
1443193326Sed  static const unsigned NumItems = 16;
1444198092Srdivacky
1445218893Sdim  // Fetch the countByEnumeratingWithState:objects:count: selector.
1446206084Srdivacky  IdentifierInfo *II[] = {
1447206084Srdivacky    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
1448206084Srdivacky    &CGM.getContext().Idents.get("objects"),
1449206084Srdivacky    &CGM.getContext().Idents.get("count")
1450206084Srdivacky  };
1451206084Srdivacky  Selector FastEnumSel =
1452206084Srdivacky    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
1453193326Sed
1454193326Sed  QualType ItemsTy =
1455193326Sed    getContext().getConstantArrayType(getContext().getObjCIdType(),
1456198092Srdivacky                                      llvm::APInt(32, NumItems),
1457193326Sed                                      ArrayType::Normal, 0);
1458203955Srdivacky  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
1459198092Srdivacky
1460226890Sdim  // Emit the collection pointer.  In ARC, we do a retain.
1461226890Sdim  llvm::Value *Collection;
1462235633Sdim  if (getLangOpts().ObjCAutoRefCount) {
1463226890Sdim    Collection = EmitARCRetainScalarExpr(S.getCollection());
1464198092Srdivacky
1465226890Sdim    // Enter a cleanup to do the release.
1466226890Sdim    EmitObjCConsumeObject(S.getCollection()->getType(), Collection);
1467226890Sdim  } else {
1468226890Sdim    Collection = EmitScalarExpr(S.getCollection());
1469226890Sdim  }
1470226890Sdim
1471226890Sdim  // The 'continue' label needs to appear within the cleanup for the
1472226890Sdim  // collection object.
1473226890Sdim  JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
1474226890Sdim
1475218893Sdim  // Send it our message:
1476193326Sed  CallArgList Args;
1477218893Sdim
1478218893Sdim  // The first argument is a temporary of the enumeration-state type.
1479221345Sdim  Args.add(RValue::get(StatePtr), getContext().getPointerType(StateTy));
1480198092Srdivacky
1481218893Sdim  // The second argument is a temporary array with space for NumItems
1482218893Sdim  // pointers.  We'll actually be loading elements from the array
1483218893Sdim  // pointer written into the control state; this buffer is so that
1484218893Sdim  // collections that *aren't* backed by arrays can still queue up
1485218893Sdim  // batches of elements.
1486221345Sdim  Args.add(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy));
1487198092Srdivacky
1488218893Sdim  // The third argument is the capacity of that temporary array.
1489226890Sdim  llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
1490193326Sed  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
1491221345Sdim  Args.add(RValue::get(Count), getContext().UnsignedLongTy);
1492198092Srdivacky
1493218893Sdim  // Start the enumeration.
1494198092Srdivacky  RValue CountRV =
1495208600Srdivacky    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1496193326Sed                                             getContext().UnsignedLongTy,
1497193326Sed                                             FastEnumSel,
1498207619Srdivacky                                             Collection, Args);
1499193326Sed
1500218893Sdim  // The initial number of objects that were returned in the buffer.
1501218893Sdim  llvm::Value *initialBufferLimit = CountRV.getScalarVal();
1502198092Srdivacky
1503218893Sdim  llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1504218893Sdim  llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1505198092Srdivacky
1506218893Sdim  llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
1507193326Sed
1508218893Sdim  // If the limit pointer was zero to begin with, the collection is
1509218893Sdim  // empty; skip all this.
1510218893Sdim  Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
1511218893Sdim                       EmptyBB, LoopInitBB);
1512193326Sed
1513218893Sdim  // Otherwise, initialize the loop.
1514218893Sdim  EmitBlock(LoopInitBB);
1515198092Srdivacky
1516218893Sdim  // Save the initial mutations value.  This is the value at an
1517218893Sdim  // address that was written into the state object by
1518218893Sdim  // countByEnumeratingWithState:objects:count:.
1519198092Srdivacky  llvm::Value *StateMutationsPtrPtr =
1520193326Sed    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
1521198092Srdivacky  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
1522193326Sed                                                      "mutationsptr");
1523198092Srdivacky
1524218893Sdim  llvm::Value *initialMutations =
1525218893Sdim    Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations");
1526198092Srdivacky
1527218893Sdim  // Start looping.  This is the point we return to whenever we have a
1528218893Sdim  // fresh, non-empty batch of objects.
1529218893Sdim  llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1530218893Sdim  EmitBlock(LoopBodyBB);
1531198092Srdivacky
1532218893Sdim  // The current index into the buffer.
1533221345Sdim  llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
1534218893Sdim  index->addIncoming(zero, LoopInitBB);
1535193326Sed
1536218893Sdim  // The current buffer size.
1537221345Sdim  llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
1538218893Sdim  count->addIncoming(initialBufferLimit, LoopInitBB);
1539198092Srdivacky
1540218893Sdim  // Check whether the mutations value has changed from where it was
1541218893Sdim  // at start.  StateMutationsPtr should actually be invariant between
1542218893Sdim  // refreshes.
1543193326Sed  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1544218893Sdim  llvm::Value *currentMutations
1545218893Sdim    = Builder.CreateLoad(StateMutationsPtr, "statemutations");
1546193326Sed
1547218893Sdim  llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1548221345Sdim  llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
1549198092Srdivacky
1550218893Sdim  Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1551218893Sdim                       WasNotMutatedBB, WasMutatedBB);
1552198092Srdivacky
1553218893Sdim  // If so, call the enumeration-mutation function.
1554218893Sdim  EmitBlock(WasMutatedBB);
1555193326Sed  llvm::Value *V =
1556198092Srdivacky    Builder.CreateBitCast(Collection,
1557226890Sdim                          ConvertType(getContext().getObjCIdType()));
1558193326Sed  CallArgList Args2;
1559221345Sdim  Args2.add(RValue::get(V), getContext().getObjCIdType());
1560193326Sed  // FIXME: We shouldn't need to get the function info here, the runtime already
1561193326Sed  // should have computed it to build the function.
1562245431Sdim  EmitCall(CGM.getTypes().arrangeFreeFunctionCall(getContext().VoidTy, Args2,
1563245431Sdim                                                  FunctionType::ExtInfo(),
1564245431Sdim                                                  RequiredArgs::All),
1565201361Srdivacky           EnumerationMutationFn, ReturnValueSlot(), Args2);
1566198092Srdivacky
1567218893Sdim  // Otherwise, or if the mutation function returns, just continue.
1568218893Sdim  EmitBlock(WasNotMutatedBB);
1569198092Srdivacky
1570218893Sdim  // Initialize the element variable.
1571218893Sdim  RunCleanupsScope elementVariableScope(*this);
1572219077Sdim  bool elementIsVariable;
1573218893Sdim  LValue elementLValue;
1574218893Sdim  QualType elementType;
1575218893Sdim  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
1576219077Sdim    // Initialize the variable, in case it's a __block variable or something.
1577219077Sdim    EmitAutoVarInit(variable);
1578219077Sdim
1579218893Sdim    const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
1580235633Sdim    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), false, D->getType(),
1581218893Sdim                        VK_LValue, SourceLocation());
1582218893Sdim    elementLValue = EmitLValue(&tempDRE);
1583218893Sdim    elementType = D->getType();
1584219077Sdim    elementIsVariable = true;
1585224145Sdim
1586224145Sdim    if (D->isARCPseudoStrong())
1587224145Sdim      elementLValue.getQuals().setObjCLifetime(Qualifiers::OCL_ExplicitNone);
1588218893Sdim  } else {
1589218893Sdim    elementLValue = LValue(); // suppress warning
1590218893Sdim    elementType = cast<Expr>(S.getElement())->getType();
1591219077Sdim    elementIsVariable = false;
1592218893Sdim  }
1593226890Sdim  llvm::Type *convertedElementType = ConvertType(elementType);
1594218893Sdim
1595218893Sdim  // Fetch the buffer out of the enumeration state.
1596218893Sdim  // TODO: this pointer should actually be invariant between
1597218893Sdim  // refreshes, which would help us do certain loop optimizations.
1598198092Srdivacky  llvm::Value *StateItemsPtr =
1599193326Sed    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
1600218893Sdim  llvm::Value *EnumStateItems =
1601218893Sdim    Builder.CreateLoad(StateItemsPtr, "stateitems");
1602193326Sed
1603218893Sdim  // Fetch the value at the current index from the buffer.
1604198092Srdivacky  llvm::Value *CurrentItemPtr =
1605218893Sdim    Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr");
1606218893Sdim  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr);
1607198092Srdivacky
1608218893Sdim  // Cast that value to the right type.
1609218893Sdim  CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
1610218893Sdim                                      "currentitem");
1611198092Srdivacky
1612218893Sdim  // Make sure we have an l-value.  Yes, this gets evaluated every
1613218893Sdim  // time through the loop.
1614224145Sdim  if (!elementIsVariable) {
1615218893Sdim    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1616224145Sdim    EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue);
1617224145Sdim  } else {
1618224145Sdim    EmitScalarInit(CurrentItem, elementLValue);
1619224145Sdim  }
1620198092Srdivacky
1621219077Sdim  // If we do have an element variable, this assignment is the end of
1622219077Sdim  // its initialization.
1623219077Sdim  if (elementIsVariable)
1624219077Sdim    EmitAutoVarCleanups(variable);
1625219077Sdim
1626218893Sdim  // Perform the loop body, setting up break and continue labels.
1627218893Sdim  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
1628218893Sdim  {
1629218893Sdim    RunCleanupsScope Scope(*this);
1630218893Sdim    EmitStmt(S.getBody());
1631218893Sdim  }
1632218893Sdim  BreakContinueStack.pop_back();
1633198092Srdivacky
1634218893Sdim  // Destroy the element variable now.
1635218893Sdim  elementVariableScope.ForceCleanup();
1636198092Srdivacky
1637218893Sdim  // Check whether there are more elements.
1638218893Sdim  EmitBlock(AfterBody.getBlock());
1639198092Srdivacky
1640218893Sdim  llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
1641193326Sed
1642218893Sdim  // First we check in the local buffer.
1643218893Sdim  llvm::Value *indexPlusOne
1644218893Sdim    = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
1645198092Srdivacky
1646218893Sdim  // If we haven't overrun the buffer yet, we can continue.
1647218893Sdim  Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
1648218893Sdim                       LoopBodyBB, FetchMoreBB);
1649198092Srdivacky
1650218893Sdim  index->addIncoming(indexPlusOne, AfterBody.getBlock());
1651218893Sdim  count->addIncoming(count, AfterBody.getBlock());
1652198092Srdivacky
1653218893Sdim  // Otherwise, we have to fetch more elements.
1654218893Sdim  EmitBlock(FetchMoreBB);
1655193326Sed
1656198092Srdivacky  CountRV =
1657208600Srdivacky    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1658193326Sed                                             getContext().UnsignedLongTy,
1659198092Srdivacky                                             FastEnumSel,
1660207619Srdivacky                                             Collection, Args);
1661198092Srdivacky
1662218893Sdim  // If we got a zero count, we're done.
1663218893Sdim  llvm::Value *refetchCount = CountRV.getScalarVal();
1664198092Srdivacky
1665218893Sdim  // (note that the message send might split FetchMoreBB)
1666218893Sdim  index->addIncoming(zero, Builder.GetInsertBlock());
1667218893Sdim  count->addIncoming(refetchCount, Builder.GetInsertBlock());
1668218893Sdim
1669218893Sdim  Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
1670218893Sdim                       EmptyBB, LoopBodyBB);
1671218893Sdim
1672193326Sed  // No more elements.
1673218893Sdim  EmitBlock(EmptyBB);
1674193326Sed
1675219077Sdim  if (!elementIsVariable) {
1676193326Sed    // If the element was not a declaration, set it to be null.
1677193326Sed
1678218893Sdim    llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
1679218893Sdim    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1680224145Sdim    EmitStoreThroughLValue(RValue::get(null), elementLValue);
1681218893Sdim  }
1682198092Srdivacky
1683226890Sdim  if (DI)
1684226890Sdim    DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
1685193326Sed
1686226890Sdim  // Leave the cleanup we entered in ARC.
1687235633Sdim  if (getLangOpts().ObjCAutoRefCount)
1688226890Sdim    PopCleanupBlock();
1689226890Sdim
1690212904Sdim  EmitBlock(LoopEnd.getBlock());
1691193326Sed}
1692193326Sed
1693198092Srdivackyvoid CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
1694210299Sed  CGM.getObjCRuntime().EmitTryStmt(*this, S);
1695193326Sed}
1696193326Sed
1697198092Srdivackyvoid CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
1698193326Sed  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
1699193326Sed}
1700193326Sed
1701193326Sedvoid CodeGenFunction::EmitObjCAtSynchronizedStmt(
1702198092Srdivacky                                              const ObjCAtSynchronizedStmt &S) {
1703210299Sed  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
1704193326Sed}
1705193326Sed
1706226890Sdim/// Produce the code for a CK_ARCProduceObject.  Just does a
1707224145Sdim/// primitive retain.
1708224145Sdimllvm::Value *CodeGenFunction::EmitObjCProduceObject(QualType type,
1709224145Sdim                                                    llvm::Value *value) {
1710224145Sdim  return EmitARCRetain(type, value);
1711224145Sdim}
1712224145Sdim
1713224145Sdimnamespace {
1714224145Sdim  struct CallObjCRelease : EHScopeStack::Cleanup {
1715226890Sdim    CallObjCRelease(llvm::Value *object) : object(object) {}
1716226890Sdim    llvm::Value *object;
1717224145Sdim
1718224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
1719252723Sdim      // Releases at the end of the full-expression are imprecise.
1720252723Sdim      CGF.EmitARCRelease(object, ARCImpreciseLifetime);
1721224145Sdim    }
1722224145Sdim  };
1723224145Sdim}
1724224145Sdim
1725226890Sdim/// Produce the code for a CK_ARCConsumeObject.  Does a primitive
1726224145Sdim/// release at the end of the full-expression.
1727224145Sdimllvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
1728224145Sdim                                                    llvm::Value *object) {
1729224145Sdim  // If we're in a conditional branch, we need to make the cleanup
1730226890Sdim  // conditional.
1731226890Sdim  pushFullExprCleanup<CallObjCRelease>(getARCCleanupKind(), object);
1732224145Sdim  return object;
1733224145Sdim}
1734224145Sdim
1735224145Sdimllvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
1736224145Sdim                                                           llvm::Value *value) {
1737224145Sdim  return EmitARCRetainAutorelease(type, value);
1738224145Sdim}
1739224145Sdim
1740252723Sdim/// Given a number of pointers, inform the optimizer that they're
1741252723Sdim/// being intrinsically used up until this point in the program.
1742252723Sdimvoid CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) {
1743252723Sdim  llvm::Constant *&fn = CGM.getARCEntrypoints().clang_arc_use;
1744252723Sdim  if (!fn) {
1745252723Sdim    llvm::FunctionType *fnType =
1746252723Sdim      llvm::FunctionType::get(CGM.VoidTy, ArrayRef<llvm::Type*>(), true);
1747252723Sdim    fn = CGM.CreateRuntimeFunction(fnType, "clang.arc.use");
1748252723Sdim  }
1749224145Sdim
1750252723Sdim  // This isn't really a "runtime" function, but as an intrinsic it
1751252723Sdim  // doesn't really matter as long as we align things up.
1752252723Sdim  EmitNounwindRuntimeCall(fn, values);
1753252723Sdim}
1754252723Sdim
1755252723Sdim
1756224145Sdimstatic llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
1757226890Sdim                                                llvm::FunctionType *type,
1758226890Sdim                                                StringRef fnName) {
1759224145Sdim  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
1760224145Sdim
1761245431Sdim  if (llvm::Function *f = dyn_cast<llvm::Function>(fn)) {
1762252723Sdim    // If the target runtime doesn't naturally support ARC, emit weak
1763252723Sdim    // references to the runtime support library.  We don't really
1764252723Sdim    // permit this to fail, but we need a particular relocation style.
1765252723Sdim    if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC()) {
1766224145Sdim      f->setLinkage(llvm::Function::ExternalWeakLinkage);
1767252723Sdim    } else if (fnName == "objc_retain" || fnName  == "objc_release") {
1768252723Sdim      // If we have Native ARC, set nonlazybind attribute for these APIs for
1769252723Sdim      // performance.
1770252723Sdim      f->addFnAttr(llvm::Attribute::NonLazyBind);
1771252723Sdim    }
1772245431Sdim  }
1773224145Sdim
1774224145Sdim  return fn;
1775224145Sdim}
1776224145Sdim
1777224145Sdim/// Perform an operation having the signature
1778224145Sdim///   i8* (i8*)
1779224145Sdim/// where a null input causes a no-op and returns null.
1780224145Sdimstatic llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
1781224145Sdim                                          llvm::Value *value,
1782224145Sdim                                          llvm::Constant *&fn,
1783252723Sdim                                          StringRef fnName,
1784252723Sdim                                          bool isTailCall = false) {
1785224145Sdim  if (isa<llvm::ConstantPointerNull>(value)) return value;
1786224145Sdim
1787224145Sdim  if (!fn) {
1788226890Sdim    llvm::FunctionType *fnType =
1789252723Sdim      llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false);
1790224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1791224145Sdim  }
1792224145Sdim
1793224145Sdim  // Cast the argument to 'id'.
1794226890Sdim  llvm::Type *origType = value->getType();
1795224145Sdim  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1796224145Sdim
1797224145Sdim  // Call the function.
1798252723Sdim  llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value);
1799252723Sdim  if (isTailCall)
1800252723Sdim    call->setTailCall();
1801224145Sdim
1802224145Sdim  // Cast the result back to the original type.
1803224145Sdim  return CGF.Builder.CreateBitCast(call, origType);
1804224145Sdim}
1805224145Sdim
1806224145Sdim/// Perform an operation having the following signature:
1807224145Sdim///   i8* (i8**)
1808224145Sdimstatic llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
1809224145Sdim                                         llvm::Value *addr,
1810224145Sdim                                         llvm::Constant *&fn,
1811226890Sdim                                         StringRef fnName) {
1812224145Sdim  if (!fn) {
1813226890Sdim    llvm::FunctionType *fnType =
1814252723Sdim      llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrPtrTy, false);
1815224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1816224145Sdim  }
1817224145Sdim
1818224145Sdim  // Cast the argument to 'id*'.
1819226890Sdim  llvm::Type *origType = addr->getType();
1820224145Sdim  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1821224145Sdim
1822224145Sdim  // Call the function.
1823252723Sdim  llvm::Value *result = CGF.EmitNounwindRuntimeCall(fn, addr);
1824224145Sdim
1825224145Sdim  // Cast the result back to a dereference of the original type.
1826224145Sdim  if (origType != CGF.Int8PtrPtrTy)
1827224145Sdim    result = CGF.Builder.CreateBitCast(result,
1828224145Sdim                        cast<llvm::PointerType>(origType)->getElementType());
1829224145Sdim
1830224145Sdim  return result;
1831224145Sdim}
1832224145Sdim
1833224145Sdim/// Perform an operation having the following signature:
1834224145Sdim///   i8* (i8**, i8*)
1835224145Sdimstatic llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
1836224145Sdim                                          llvm::Value *addr,
1837224145Sdim                                          llvm::Value *value,
1838224145Sdim                                          llvm::Constant *&fn,
1839226890Sdim                                          StringRef fnName,
1840224145Sdim                                          bool ignored) {
1841224145Sdim  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1842224145Sdim           == value->getType());
1843224145Sdim
1844224145Sdim  if (!fn) {
1845235633Sdim    llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrTy };
1846224145Sdim
1847226890Sdim    llvm::FunctionType *fnType
1848224145Sdim      = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false);
1849224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1850224145Sdim  }
1851224145Sdim
1852226890Sdim  llvm::Type *origType = value->getType();
1853224145Sdim
1854252723Sdim  llvm::Value *args[] = {
1855252723Sdim    CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy),
1856252723Sdim    CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy)
1857252723Sdim  };
1858252723Sdim  llvm::CallInst *result = CGF.EmitNounwindRuntimeCall(fn, args);
1859224145Sdim
1860224145Sdim  if (ignored) return 0;
1861224145Sdim
1862224145Sdim  return CGF.Builder.CreateBitCast(result, origType);
1863224145Sdim}
1864224145Sdim
1865224145Sdim/// Perform an operation having the following signature:
1866224145Sdim///   void (i8**, i8**)
1867224145Sdimstatic void emitARCCopyOperation(CodeGenFunction &CGF,
1868224145Sdim                                 llvm::Value *dst,
1869224145Sdim                                 llvm::Value *src,
1870224145Sdim                                 llvm::Constant *&fn,
1871226890Sdim                                 StringRef fnName) {
1872224145Sdim  assert(dst->getType() == src->getType());
1873224145Sdim
1874224145Sdim  if (!fn) {
1875252723Sdim    llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrPtrTy };
1876252723Sdim
1877226890Sdim    llvm::FunctionType *fnType
1878224145Sdim      = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false);
1879224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1880224145Sdim  }
1881224145Sdim
1882252723Sdim  llvm::Value *args[] = {
1883252723Sdim    CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy),
1884252723Sdim    CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy)
1885252723Sdim  };
1886252723Sdim  CGF.EmitNounwindRuntimeCall(fn, args);
1887224145Sdim}
1888224145Sdim
1889224145Sdim/// Produce the code to do a retain.  Based on the type, calls one of:
1890245431Sdim///   call i8* \@objc_retain(i8* %value)
1891245431Sdim///   call i8* \@objc_retainBlock(i8* %value)
1892224145Sdimllvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {
1893224145Sdim  if (type->isBlockPointerType())
1894226890Sdim    return EmitARCRetainBlock(value, /*mandatory*/ false);
1895224145Sdim  else
1896224145Sdim    return EmitARCRetainNonBlock(value);
1897224145Sdim}
1898224145Sdim
1899224145Sdim/// Retain the given object, with normal retain semantics.
1900245431Sdim///   call i8* \@objc_retain(i8* %value)
1901224145Sdimllvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) {
1902224145Sdim  return emitARCValueOperation(*this, value,
1903224145Sdim                               CGM.getARCEntrypoints().objc_retain,
1904224145Sdim                               "objc_retain");
1905224145Sdim}
1906224145Sdim
1907224145Sdim/// Retain the given block, with _Block_copy semantics.
1908245431Sdim///   call i8* \@objc_retainBlock(i8* %value)
1909226890Sdim///
1910226890Sdim/// \param mandatory - If false, emit the call with metadata
1911226890Sdim/// indicating that it's okay for the optimizer to eliminate this call
1912226890Sdim/// if it can prove that the block never escapes except down the stack.
1913226890Sdimllvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value,
1914226890Sdim                                                 bool mandatory) {
1915226890Sdim  llvm::Value *result
1916226890Sdim    = emitARCValueOperation(*this, value,
1917226890Sdim                            CGM.getARCEntrypoints().objc_retainBlock,
1918226890Sdim                            "objc_retainBlock");
1919226890Sdim
1920226890Sdim  // If the copy isn't mandatory, add !clang.arc.copy_on_escape to
1921226890Sdim  // tell the optimizer that it doesn't need to do this copy if the
1922226890Sdim  // block doesn't escape, where being passed as an argument doesn't
1923226890Sdim  // count as escaping.
1924226890Sdim  if (!mandatory && isa<llvm::Instruction>(result)) {
1925226890Sdim    llvm::CallInst *call
1926226890Sdim      = cast<llvm::CallInst>(result->stripPointerCasts());
1927226890Sdim    assert(call->getCalledValue() == CGM.getARCEntrypoints().objc_retainBlock);
1928226890Sdim
1929226890Sdim    SmallVector<llvm::Value*,1> args;
1930226890Sdim    call->setMetadata("clang.arc.copy_on_escape",
1931226890Sdim                      llvm::MDNode::get(Builder.getContext(), args));
1932226890Sdim  }
1933226890Sdim
1934226890Sdim  return result;
1935224145Sdim}
1936224145Sdim
1937224145Sdim/// Retain the given object which is the result of a function call.
1938245431Sdim///   call i8* \@objc_retainAutoreleasedReturnValue(i8* %value)
1939224145Sdim///
1940224145Sdim/// Yes, this function name is one character away from a different
1941224145Sdim/// call with completely different semantics.
1942224145Sdimllvm::Value *
1943224145SdimCodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
1944224145Sdim  // Fetch the void(void) inline asm which marks that we're going to
1945224145Sdim  // retain the autoreleased return value.
1946224145Sdim  llvm::InlineAsm *&marker
1947224145Sdim    = CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker;
1948224145Sdim  if (!marker) {
1949226890Sdim    StringRef assembly
1950224145Sdim      = CGM.getTargetCodeGenInfo()
1951224145Sdim           .getARCRetainAutoreleasedReturnValueMarker();
1952224145Sdim
1953224145Sdim    // If we have an empty assembly string, there's nothing to do.
1954224145Sdim    if (assembly.empty()) {
1955224145Sdim
1956224145Sdim    // Otherwise, at -O0, build an inline asm that we're going to call
1957224145Sdim    // in a moment.
1958224145Sdim    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1959224145Sdim      llvm::FunctionType *type =
1960235633Sdim        llvm::FunctionType::get(VoidTy, /*variadic*/false);
1961224145Sdim
1962224145Sdim      marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true);
1963224145Sdim
1964224145Sdim    // If we're at -O1 and above, we don't want to litter the code
1965224145Sdim    // with this marker yet, so leave a breadcrumb for the ARC
1966224145Sdim    // optimizer to pick up.
1967224145Sdim    } else {
1968224145Sdim      llvm::NamedMDNode *metadata =
1969224145Sdim        CGM.getModule().getOrInsertNamedMetadata(
1970224145Sdim                            "clang.arc.retainAutoreleasedReturnValueMarker");
1971224145Sdim      assert(metadata->getNumOperands() <= 1);
1972224145Sdim      if (metadata->getNumOperands() == 0) {
1973224145Sdim        llvm::Value *string = llvm::MDString::get(getLLVMContext(), assembly);
1974226890Sdim        metadata->addOperand(llvm::MDNode::get(getLLVMContext(), string));
1975224145Sdim      }
1976224145Sdim    }
1977224145Sdim  }
1978224145Sdim
1979224145Sdim  // Call the marker asm if we made one, which we do only at -O0.
1980224145Sdim  if (marker) Builder.CreateCall(marker);
1981224145Sdim
1982224145Sdim  return emitARCValueOperation(*this, value,
1983224145Sdim                     CGM.getARCEntrypoints().objc_retainAutoreleasedReturnValue,
1984224145Sdim                               "objc_retainAutoreleasedReturnValue");
1985224145Sdim}
1986224145Sdim
1987224145Sdim/// Release the given object.
1988245431Sdim///   call void \@objc_release(i8* %value)
1989252723Sdimvoid CodeGenFunction::EmitARCRelease(llvm::Value *value,
1990252723Sdim                                     ARCPreciseLifetime_t precise) {
1991224145Sdim  if (isa<llvm::ConstantPointerNull>(value)) return;
1992224145Sdim
1993224145Sdim  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_release;
1994224145Sdim  if (!fn) {
1995226890Sdim    llvm::FunctionType *fnType =
1996252723Sdim      llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
1997224145Sdim    fn = createARCRuntimeFunction(CGM, fnType, "objc_release");
1998224145Sdim  }
1999224145Sdim
2000224145Sdim  // Cast the argument to 'id'.
2001224145Sdim  value = Builder.CreateBitCast(value, Int8PtrTy);
2002224145Sdim
2003224145Sdim  // Call objc_release.
2004252723Sdim  llvm::CallInst *call = EmitNounwindRuntimeCall(fn, value);
2005224145Sdim
2006252723Sdim  if (precise == ARCImpreciseLifetime) {
2007226890Sdim    SmallVector<llvm::Value*,1> args;
2008224145Sdim    call->setMetadata("clang.imprecise_release",
2009224145Sdim                      llvm::MDNode::get(Builder.getContext(), args));
2010224145Sdim  }
2011224145Sdim}
2012224145Sdim
2013245431Sdim/// Destroy a __strong variable.
2014245431Sdim///
2015245431Sdim/// At -O0, emit a call to store 'null' into the address;
2016245431Sdim/// instrumenting tools prefer this because the address is exposed,
2017245431Sdim/// but it's relatively cumbersome to optimize.
2018245431Sdim///
2019245431Sdim/// At -O1 and above, just load and call objc_release.
2020245431Sdim///
2021245431Sdim///   call void \@objc_storeStrong(i8** %addr, i8* null)
2022252723Sdimvoid CodeGenFunction::EmitARCDestroyStrong(llvm::Value *addr,
2023252723Sdim                                           ARCPreciseLifetime_t precise) {
2024245431Sdim  if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
2025245431Sdim    llvm::PointerType *addrTy = cast<llvm::PointerType>(addr->getType());
2026245431Sdim    llvm::Value *null = llvm::ConstantPointerNull::get(
2027245431Sdim                          cast<llvm::PointerType>(addrTy->getElementType()));
2028245431Sdim    EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
2029245431Sdim    return;
2030245431Sdim  }
2031245431Sdim
2032245431Sdim  llvm::Value *value = Builder.CreateLoad(addr);
2033245431Sdim  EmitARCRelease(value, precise);
2034245431Sdim}
2035245431Sdim
2036224145Sdim/// Store into a strong object.  Always calls this:
2037245431Sdim///   call void \@objc_storeStrong(i8** %addr, i8* %value)
2038224145Sdimllvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr,
2039224145Sdim                                                     llvm::Value *value,
2040224145Sdim                                                     bool ignored) {
2041224145Sdim  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
2042224145Sdim           == value->getType());
2043224145Sdim
2044224145Sdim  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_storeStrong;
2045224145Sdim  if (!fn) {
2046224145Sdim    llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy };
2047226890Sdim    llvm::FunctionType *fnType
2048224145Sdim      = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false);
2049224145Sdim    fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong");
2050224145Sdim  }
2051224145Sdim
2052252723Sdim  llvm::Value *args[] = {
2053252723Sdim    Builder.CreateBitCast(addr, Int8PtrPtrTy),
2054252723Sdim    Builder.CreateBitCast(value, Int8PtrTy)
2055252723Sdim  };
2056252723Sdim  EmitNounwindRuntimeCall(fn, args);
2057224145Sdim
2058224145Sdim  if (ignored) return 0;
2059224145Sdim  return value;
2060224145Sdim}
2061224145Sdim
2062224145Sdim/// Store into a strong object.  Sometimes calls this:
2063245431Sdim///   call void \@objc_storeStrong(i8** %addr, i8* %value)
2064224145Sdim/// Other times, breaks it down into components.
2065224145Sdimllvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
2066224145Sdim                                                 llvm::Value *newValue,
2067224145Sdim                                                 bool ignored) {
2068224145Sdim  QualType type = dst.getType();
2069224145Sdim  bool isBlock = type->isBlockPointerType();
2070224145Sdim
2071224145Sdim  // Use a store barrier at -O0 unless this is a block type or the
2072224145Sdim  // lvalue is inadequately aligned.
2073224145Sdim  if (shouldUseFusedARCCalls() &&
2074224145Sdim      !isBlock &&
2075235633Sdim      (dst.getAlignment().isZero() ||
2076235633Sdim       dst.getAlignment() >= CharUnits::fromQuantity(PointerAlignInBytes))) {
2077224145Sdim    return EmitARCStoreStrongCall(dst.getAddress(), newValue, ignored);
2078224145Sdim  }
2079224145Sdim
2080224145Sdim  // Otherwise, split it out.
2081224145Sdim
2082224145Sdim  // Retain the new value.
2083224145Sdim  newValue = EmitARCRetain(type, newValue);
2084224145Sdim
2085224145Sdim  // Read the old value.
2086263509Sdim  llvm::Value *oldValue = EmitLoadOfScalar(dst, SourceLocation());
2087224145Sdim
2088224145Sdim  // Store.  We do this before the release so that any deallocs won't
2089224145Sdim  // see the old value.
2090224145Sdim  EmitStoreOfScalar(newValue, dst);
2091224145Sdim
2092224145Sdim  // Finally, release the old value.
2093252723Sdim  EmitARCRelease(oldValue, dst.isARCPreciseLifetime());
2094224145Sdim
2095224145Sdim  return newValue;
2096224145Sdim}
2097224145Sdim
2098224145Sdim/// Autorelease the given object.
2099245431Sdim///   call i8* \@objc_autorelease(i8* %value)
2100224145Sdimllvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) {
2101224145Sdim  return emitARCValueOperation(*this, value,
2102224145Sdim                               CGM.getARCEntrypoints().objc_autorelease,
2103224145Sdim                               "objc_autorelease");
2104224145Sdim}
2105224145Sdim
2106224145Sdim/// Autorelease the given object.
2107245431Sdim///   call i8* \@objc_autoreleaseReturnValue(i8* %value)
2108224145Sdimllvm::Value *
2109224145SdimCodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
2110224145Sdim  return emitARCValueOperation(*this, value,
2111224145Sdim                            CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
2112252723Sdim                               "objc_autoreleaseReturnValue",
2113252723Sdim                               /*isTailCall*/ true);
2114224145Sdim}
2115224145Sdim
2116224145Sdim/// Do a fused retain/autorelease of the given object.
2117245431Sdim///   call i8* \@objc_retainAutoreleaseReturnValue(i8* %value)
2118224145Sdimllvm::Value *
2119224145SdimCodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
2120224145Sdim  return emitARCValueOperation(*this, value,
2121224145Sdim                     CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
2122252723Sdim                               "objc_retainAutoreleaseReturnValue",
2123252723Sdim                               /*isTailCall*/ true);
2124224145Sdim}
2125224145Sdim
2126224145Sdim/// Do a fused retain/autorelease of the given object.
2127245431Sdim///   call i8* \@objc_retainAutorelease(i8* %value)
2128224145Sdim/// or
2129245431Sdim///   %retain = call i8* \@objc_retainBlock(i8* %value)
2130245431Sdim///   call i8* \@objc_autorelease(i8* %retain)
2131224145Sdimllvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
2132224145Sdim                                                       llvm::Value *value) {
2133224145Sdim  if (!type->isBlockPointerType())
2134224145Sdim    return EmitARCRetainAutoreleaseNonBlock(value);
2135224145Sdim
2136224145Sdim  if (isa<llvm::ConstantPointerNull>(value)) return value;
2137224145Sdim
2138226890Sdim  llvm::Type *origType = value->getType();
2139224145Sdim  value = Builder.CreateBitCast(value, Int8PtrTy);
2140226890Sdim  value = EmitARCRetainBlock(value, /*mandatory*/ true);
2141224145Sdim  value = EmitARCAutorelease(value);
2142224145Sdim  return Builder.CreateBitCast(value, origType);
2143224145Sdim}
2144224145Sdim
2145224145Sdim/// Do a fused retain/autorelease of the given object.
2146245431Sdim///   call i8* \@objc_retainAutorelease(i8* %value)
2147224145Sdimllvm::Value *
2148224145SdimCodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) {
2149224145Sdim  return emitARCValueOperation(*this, value,
2150224145Sdim                               CGM.getARCEntrypoints().objc_retainAutorelease,
2151224145Sdim                               "objc_retainAutorelease");
2152224145Sdim}
2153224145Sdim
2154245431Sdim/// i8* \@objc_loadWeak(i8** %addr)
2155224145Sdim/// Essentially objc_autorelease(objc_loadWeakRetained(addr)).
2156224145Sdimllvm::Value *CodeGenFunction::EmitARCLoadWeak(llvm::Value *addr) {
2157224145Sdim  return emitARCLoadOperation(*this, addr,
2158224145Sdim                              CGM.getARCEntrypoints().objc_loadWeak,
2159224145Sdim                              "objc_loadWeak");
2160224145Sdim}
2161224145Sdim
2162245431Sdim/// i8* \@objc_loadWeakRetained(i8** %addr)
2163224145Sdimllvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(llvm::Value *addr) {
2164224145Sdim  return emitARCLoadOperation(*this, addr,
2165224145Sdim                              CGM.getARCEntrypoints().objc_loadWeakRetained,
2166224145Sdim                              "objc_loadWeakRetained");
2167224145Sdim}
2168224145Sdim
2169245431Sdim/// i8* \@objc_storeWeak(i8** %addr, i8* %value)
2170224145Sdim/// Returns %value.
2171224145Sdimllvm::Value *CodeGenFunction::EmitARCStoreWeak(llvm::Value *addr,
2172224145Sdim                                               llvm::Value *value,
2173224145Sdim                                               bool ignored) {
2174224145Sdim  return emitARCStoreOperation(*this, addr, value,
2175224145Sdim                               CGM.getARCEntrypoints().objc_storeWeak,
2176224145Sdim                               "objc_storeWeak", ignored);
2177224145Sdim}
2178224145Sdim
2179245431Sdim/// i8* \@objc_initWeak(i8** %addr, i8* %value)
2180224145Sdim/// Returns %value.  %addr is known to not have a current weak entry.
2181224145Sdim/// Essentially equivalent to:
2182224145Sdim///   *addr = nil; objc_storeWeak(addr, value);
2183224145Sdimvoid CodeGenFunction::EmitARCInitWeak(llvm::Value *addr, llvm::Value *value) {
2184224145Sdim  // If we're initializing to null, just write null to memory; no need
2185224145Sdim  // to get the runtime involved.  But don't do this if optimization
2186224145Sdim  // is enabled, because accounting for this would make the optimizer
2187224145Sdim  // much more complicated.
2188224145Sdim  if (isa<llvm::ConstantPointerNull>(value) &&
2189224145Sdim      CGM.getCodeGenOpts().OptimizationLevel == 0) {
2190224145Sdim    Builder.CreateStore(value, addr);
2191224145Sdim    return;
2192224145Sdim  }
2193224145Sdim
2194224145Sdim  emitARCStoreOperation(*this, addr, value,
2195224145Sdim                        CGM.getARCEntrypoints().objc_initWeak,
2196224145Sdim                        "objc_initWeak", /*ignored*/ true);
2197224145Sdim}
2198224145Sdim
2199245431Sdim/// void \@objc_destroyWeak(i8** %addr)
2200224145Sdim/// Essentially objc_storeWeak(addr, nil).
2201224145Sdimvoid CodeGenFunction::EmitARCDestroyWeak(llvm::Value *addr) {
2202224145Sdim  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_destroyWeak;
2203224145Sdim  if (!fn) {
2204226890Sdim    llvm::FunctionType *fnType =
2205252723Sdim      llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrPtrTy, false);
2206224145Sdim    fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak");
2207224145Sdim  }
2208224145Sdim
2209224145Sdim  // Cast the argument to 'id*'.
2210224145Sdim  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
2211224145Sdim
2212252723Sdim  EmitNounwindRuntimeCall(fn, addr);
2213224145Sdim}
2214224145Sdim
2215245431Sdim/// void \@objc_moveWeak(i8** %dest, i8** %src)
2216224145Sdim/// Disregards the current value in %dest.  Leaves %src pointing to nothing.
2217224145Sdim/// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)).
2218224145Sdimvoid CodeGenFunction::EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src) {
2219224145Sdim  emitARCCopyOperation(*this, dst, src,
2220224145Sdim                       CGM.getARCEntrypoints().objc_moveWeak,
2221224145Sdim                       "objc_moveWeak");
2222224145Sdim}
2223224145Sdim
2224245431Sdim/// void \@objc_copyWeak(i8** %dest, i8** %src)
2225224145Sdim/// Disregards the current value in %dest.  Essentially
2226224145Sdim///   objc_release(objc_initWeak(dest, objc_readWeakRetained(src)))
2227224145Sdimvoid CodeGenFunction::EmitARCCopyWeak(llvm::Value *dst, llvm::Value *src) {
2228224145Sdim  emitARCCopyOperation(*this, dst, src,
2229224145Sdim                       CGM.getARCEntrypoints().objc_copyWeak,
2230224145Sdim                       "objc_copyWeak");
2231224145Sdim}
2232224145Sdim
2233224145Sdim/// Produce the code to do a objc_autoreleasepool_push.
2234245431Sdim///   call i8* \@objc_autoreleasePoolPush(void)
2235224145Sdimllvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
2236224145Sdim  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPush;
2237224145Sdim  if (!fn) {
2238226890Sdim    llvm::FunctionType *fnType =
2239224145Sdim      llvm::FunctionType::get(Int8PtrTy, false);
2240224145Sdim    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush");
2241224145Sdim  }
2242224145Sdim
2243252723Sdim  return EmitNounwindRuntimeCall(fn);
2244224145Sdim}
2245224145Sdim
2246224145Sdim/// Produce the code to do a primitive release.
2247245431Sdim///   call void \@objc_autoreleasePoolPop(i8* %ptr)
2248224145Sdimvoid CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
2249224145Sdim  assert(value->getType() == Int8PtrTy);
2250224145Sdim
2251224145Sdim  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPop;
2252224145Sdim  if (!fn) {
2253226890Sdim    llvm::FunctionType *fnType =
2254252723Sdim      llvm::FunctionType::get(Builder.getVoidTy(), Int8PtrTy, false);
2255224145Sdim
2256224145Sdim    // We don't want to use a weak import here; instead we should not
2257224145Sdim    // fall into this path.
2258224145Sdim    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop");
2259224145Sdim  }
2260224145Sdim
2261252723Sdim  // objc_autoreleasePoolPop can throw.
2262252723Sdim  EmitRuntimeCallOrInvoke(fn, value);
2263224145Sdim}
2264224145Sdim
2265224145Sdim/// Produce the code to do an MRR version objc_autoreleasepool_push.
2266224145Sdim/// Which is: [[NSAutoreleasePool alloc] init];
2267224145Sdim/// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class.
2268224145Sdim/// init is declared as: - (id) init; in its NSObject super class.
2269224145Sdim///
2270224145Sdimllvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() {
2271224145Sdim  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
2272252723Sdim  llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(*this);
2273224145Sdim  // [NSAutoreleasePool alloc]
2274224145Sdim  IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");
2275224145Sdim  Selector AllocSel = getContext().Selectors.getSelector(0, &II);
2276224145Sdim  CallArgList Args;
2277224145Sdim  RValue AllocRV =
2278224145Sdim    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
2279224145Sdim                                getContext().getObjCIdType(),
2280224145Sdim                                AllocSel, Receiver, Args);
2281224145Sdim
2282224145Sdim  // [Receiver init]
2283224145Sdim  Receiver = AllocRV.getScalarVal();
2284224145Sdim  II = &CGM.getContext().Idents.get("init");
2285224145Sdim  Selector InitSel = getContext().Selectors.getSelector(0, &II);
2286224145Sdim  RValue InitRV =
2287224145Sdim    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
2288224145Sdim                                getContext().getObjCIdType(),
2289224145Sdim                                InitSel, Receiver, Args);
2290224145Sdim  return InitRV.getScalarVal();
2291224145Sdim}
2292224145Sdim
2293224145Sdim/// Produce the code to do a primitive release.
2294224145Sdim/// [tmp drain];
2295224145Sdimvoid CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) {
2296224145Sdim  IdentifierInfo *II = &CGM.getContext().Idents.get("drain");
2297224145Sdim  Selector DrainSel = getContext().Selectors.getSelector(0, &II);
2298224145Sdim  CallArgList Args;
2299224145Sdim  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
2300224145Sdim                              getContext().VoidTy, DrainSel, Arg, Args);
2301224145Sdim}
2302224145Sdim
2303224145Sdimvoid CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
2304224145Sdim                                              llvm::Value *addr,
2305224145Sdim                                              QualType type) {
2306252723Sdim  CGF.EmitARCDestroyStrong(addr, ARCPreciseLifetime);
2307224145Sdim}
2308224145Sdim
2309224145Sdimvoid CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
2310224145Sdim                                                llvm::Value *addr,
2311224145Sdim                                                QualType type) {
2312252723Sdim  CGF.EmitARCDestroyStrong(addr, ARCImpreciseLifetime);
2313224145Sdim}
2314224145Sdim
2315224145Sdimvoid CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
2316224145Sdim                                     llvm::Value *addr,
2317224145Sdim                                     QualType type) {
2318224145Sdim  CGF.EmitARCDestroyWeak(addr);
2319224145Sdim}
2320224145Sdim
2321224145Sdimnamespace {
2322224145Sdim  struct CallObjCAutoreleasePoolObject : EHScopeStack::Cleanup {
2323224145Sdim    llvm::Value *Token;
2324224145Sdim
2325224145Sdim    CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2326224145Sdim
2327224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
2328224145Sdim      CGF.EmitObjCAutoreleasePoolPop(Token);
2329224145Sdim    }
2330224145Sdim  };
2331224145Sdim  struct CallObjCMRRAutoreleasePoolObject : EHScopeStack::Cleanup {
2332224145Sdim    llvm::Value *Token;
2333224145Sdim
2334224145Sdim    CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2335224145Sdim
2336224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
2337224145Sdim      CGF.EmitObjCMRRAutoreleasePoolPop(Token);
2338224145Sdim    }
2339224145Sdim  };
2340224145Sdim}
2341224145Sdim
2342224145Sdimvoid CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
2343235633Sdim  if (CGM.getLangOpts().ObjCAutoRefCount)
2344224145Sdim    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr);
2345224145Sdim  else
2346224145Sdim    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr);
2347224145Sdim}
2348224145Sdim
2349224145Sdimstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2350224145Sdim                                                  LValue lvalue,
2351224145Sdim                                                  QualType type) {
2352224145Sdim  switch (type.getObjCLifetime()) {
2353224145Sdim  case Qualifiers::OCL_None:
2354224145Sdim  case Qualifiers::OCL_ExplicitNone:
2355224145Sdim  case Qualifiers::OCL_Strong:
2356224145Sdim  case Qualifiers::OCL_Autoreleasing:
2357263509Sdim    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue,
2358263509Sdim                                              SourceLocation()).getScalarVal(),
2359224145Sdim                         false);
2360224145Sdim
2361224145Sdim  case Qualifiers::OCL_Weak:
2362224145Sdim    return TryEmitResult(CGF.EmitARCLoadWeakRetained(lvalue.getAddress()),
2363224145Sdim                         true);
2364224145Sdim  }
2365224145Sdim
2366224145Sdim  llvm_unreachable("impossible lifetime!");
2367224145Sdim}
2368224145Sdim
2369224145Sdimstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2370224145Sdim                                                  const Expr *e) {
2371224145Sdim  e = e->IgnoreParens();
2372224145Sdim  QualType type = e->getType();
2373224145Sdim
2374226890Sdim  // If we're loading retained from a __strong xvalue, we can avoid
2375226890Sdim  // an extra retain/release pair by zeroing out the source of this
2376226890Sdim  // "move" operation.
2377226890Sdim  if (e->isXValue() &&
2378226890Sdim      !type.isConstQualified() &&
2379226890Sdim      type.getObjCLifetime() == Qualifiers::OCL_Strong) {
2380226890Sdim    // Emit the lvalue.
2381226890Sdim    LValue lv = CGF.EmitLValue(e);
2382226890Sdim
2383226890Sdim    // Load the object pointer.
2384263509Sdim    llvm::Value *result = CGF.EmitLoadOfLValue(lv,
2385263509Sdim                                               SourceLocation()).getScalarVal();
2386226890Sdim
2387226890Sdim    // Set the source pointer to NULL.
2388226890Sdim    CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress()), lv);
2389226890Sdim
2390226890Sdim    return TryEmitResult(result, true);
2391226890Sdim  }
2392226890Sdim
2393224145Sdim  // As a very special optimization, in ARC++, if the l-value is the
2394224145Sdim  // result of a non-volatile assignment, do a simple retain of the
2395224145Sdim  // result of the call to objc_storeWeak instead of reloading.
2396235633Sdim  if (CGF.getLangOpts().CPlusPlus &&
2397224145Sdim      !type.isVolatileQualified() &&
2398224145Sdim      type.getObjCLifetime() == Qualifiers::OCL_Weak &&
2399224145Sdim      isa<BinaryOperator>(e) &&
2400224145Sdim      cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
2401224145Sdim    return TryEmitResult(CGF.EmitScalarExpr(e), false);
2402224145Sdim
2403224145Sdim  return tryEmitARCRetainLoadOfScalar(CGF, CGF.EmitLValue(e), type);
2404224145Sdim}
2405224145Sdim
2406224145Sdimstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
2407224145Sdim                                           llvm::Value *value);
2408224145Sdim
2409224145Sdim/// Given that the given expression is some sort of call (which does
2410224145Sdim/// not return retained), emit a retain following it.
2411224145Sdimstatic llvm::Value *emitARCRetainCall(CodeGenFunction &CGF, const Expr *e) {
2412224145Sdim  llvm::Value *value = CGF.EmitScalarExpr(e);
2413224145Sdim  return emitARCRetainAfterCall(CGF, value);
2414224145Sdim}
2415224145Sdim
2416224145Sdimstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
2417224145Sdim                                           llvm::Value *value) {
2418224145Sdim  if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
2419224145Sdim    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
2420224145Sdim
2421224145Sdim    // Place the retain immediately following the call.
2422224145Sdim    CGF.Builder.SetInsertPoint(call->getParent(),
2423224145Sdim                               ++llvm::BasicBlock::iterator(call));
2424224145Sdim    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
2425224145Sdim
2426224145Sdim    CGF.Builder.restoreIP(ip);
2427224145Sdim    return value;
2428224145Sdim  } else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
2429224145Sdim    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
2430224145Sdim
2431224145Sdim    // Place the retain at the beginning of the normal destination block.
2432224145Sdim    llvm::BasicBlock *BB = invoke->getNormalDest();
2433224145Sdim    CGF.Builder.SetInsertPoint(BB, BB->begin());
2434224145Sdim    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
2435224145Sdim
2436224145Sdim    CGF.Builder.restoreIP(ip);
2437224145Sdim    return value;
2438224145Sdim
2439224145Sdim  // Bitcasts can arise because of related-result returns.  Rewrite
2440224145Sdim  // the operand.
2441224145Sdim  } else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
2442224145Sdim    llvm::Value *operand = bitcast->getOperand(0);
2443224145Sdim    operand = emitARCRetainAfterCall(CGF, operand);
2444224145Sdim    bitcast->setOperand(0, operand);
2445224145Sdim    return bitcast;
2446224145Sdim
2447224145Sdim  // Generic fall-back case.
2448224145Sdim  } else {
2449224145Sdim    // Retain using the non-block variant: we never need to do a copy
2450224145Sdim    // of a block that's been returned to us.
2451224145Sdim    return CGF.EmitARCRetainNonBlock(value);
2452224145Sdim  }
2453224145Sdim}
2454224145Sdim
2455226890Sdim/// Determine whether it might be important to emit a separate
2456226890Sdim/// objc_retain_block on the result of the given expression, or
2457226890Sdim/// whether it's okay to just emit it in a +1 context.
2458226890Sdimstatic bool shouldEmitSeparateBlockRetain(const Expr *e) {
2459226890Sdim  assert(e->getType()->isBlockPointerType());
2460226890Sdim  e = e->IgnoreParens();
2461226890Sdim
2462226890Sdim  // For future goodness, emit block expressions directly in +1
2463226890Sdim  // contexts if we can.
2464226890Sdim  if (isa<BlockExpr>(e))
2465226890Sdim    return false;
2466226890Sdim
2467226890Sdim  if (const CastExpr *cast = dyn_cast<CastExpr>(e)) {
2468226890Sdim    switch (cast->getCastKind()) {
2469226890Sdim    // Emitting these operations in +1 contexts is goodness.
2470226890Sdim    case CK_LValueToRValue:
2471226890Sdim    case CK_ARCReclaimReturnedObject:
2472226890Sdim    case CK_ARCConsumeObject:
2473226890Sdim    case CK_ARCProduceObject:
2474226890Sdim      return false;
2475226890Sdim
2476226890Sdim    // These operations preserve a block type.
2477226890Sdim    case CK_NoOp:
2478226890Sdim    case CK_BitCast:
2479226890Sdim      return shouldEmitSeparateBlockRetain(cast->getSubExpr());
2480226890Sdim
2481226890Sdim    // These operations are known to be bad (or haven't been considered).
2482226890Sdim    case CK_AnyPointerToBlockPointerCast:
2483226890Sdim    default:
2484226890Sdim      return true;
2485226890Sdim    }
2486226890Sdim  }
2487226890Sdim
2488226890Sdim  return true;
2489226890Sdim}
2490226890Sdim
2491235633Sdim/// Try to emit a PseudoObjectExpr at +1.
2492235633Sdim///
2493235633Sdim/// This massively duplicates emitPseudoObjectRValue.
2494235633Sdimstatic TryEmitResult tryEmitARCRetainPseudoObject(CodeGenFunction &CGF,
2495235633Sdim                                                  const PseudoObjectExpr *E) {
2496252723Sdim  SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;
2497235633Sdim
2498235633Sdim  // Find the result expression.
2499235633Sdim  const Expr *resultExpr = E->getResultExpr();
2500235633Sdim  assert(resultExpr);
2501235633Sdim  TryEmitResult result;
2502235633Sdim
2503235633Sdim  for (PseudoObjectExpr::const_semantics_iterator
2504235633Sdim         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
2505235633Sdim    const Expr *semantic = *i;
2506235633Sdim
2507235633Sdim    // If this semantic expression is an opaque value, bind it
2508235633Sdim    // to the result of its source expression.
2509235633Sdim    if (const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
2510235633Sdim      typedef CodeGenFunction::OpaqueValueMappingData OVMA;
2511235633Sdim      OVMA opaqueData;
2512235633Sdim
2513235633Sdim      // If this semantic is the result of the pseudo-object
2514235633Sdim      // expression, try to evaluate the source as +1.
2515235633Sdim      if (ov == resultExpr) {
2516235633Sdim        assert(!OVMA::shouldBindAsLValue(ov));
2517235633Sdim        result = tryEmitARCRetainScalarExpr(CGF, ov->getSourceExpr());
2518235633Sdim        opaqueData = OVMA::bind(CGF, ov, RValue::get(result.getPointer()));
2519235633Sdim
2520235633Sdim      // Otherwise, just bind it.
2521235633Sdim      } else {
2522235633Sdim        opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
2523235633Sdim      }
2524235633Sdim      opaques.push_back(opaqueData);
2525235633Sdim
2526235633Sdim    // Otherwise, if the expression is the result, evaluate it
2527235633Sdim    // and remember the result.
2528235633Sdim    } else if (semantic == resultExpr) {
2529235633Sdim      result = tryEmitARCRetainScalarExpr(CGF, semantic);
2530235633Sdim
2531235633Sdim    // Otherwise, evaluate the expression in an ignored context.
2532235633Sdim    } else {
2533235633Sdim      CGF.EmitIgnoredExpr(semantic);
2534235633Sdim    }
2535235633Sdim  }
2536235633Sdim
2537235633Sdim  // Unbind all the opaques now.
2538235633Sdim  for (unsigned i = 0, e = opaques.size(); i != e; ++i)
2539235633Sdim    opaques[i].unbind(CGF);
2540235633Sdim
2541235633Sdim  return result;
2542235633Sdim}
2543235633Sdim
2544224145Sdimstatic TryEmitResult
2545224145SdimtryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
2546252723Sdim  // We should *never* see a nested full-expression here, because if
2547252723Sdim  // we fail to emit at +1, our caller must not retain after we close
2548252723Sdim  // out the full-expression.
2549252723Sdim  assert(!isa<ExprWithCleanups>(e));
2550226890Sdim
2551224145Sdim  // The desired result type, if it differs from the type of the
2552224145Sdim  // ultimate opaque expression.
2553226890Sdim  llvm::Type *resultType = 0;
2554224145Sdim
2555224145Sdim  while (true) {
2556224145Sdim    e = e->IgnoreParens();
2557224145Sdim
2558224145Sdim    // There's a break at the end of this if-chain;  anything
2559224145Sdim    // that wants to keep looping has to explicitly continue.
2560224145Sdim    if (const CastExpr *ce = dyn_cast<CastExpr>(e)) {
2561224145Sdim      switch (ce->getCastKind()) {
2562224145Sdim      // No-op casts don't change the type, so we just ignore them.
2563224145Sdim      case CK_NoOp:
2564224145Sdim        e = ce->getSubExpr();
2565224145Sdim        continue;
2566224145Sdim
2567224145Sdim      case CK_LValueToRValue: {
2568224145Sdim        TryEmitResult loadResult
2569224145Sdim          = tryEmitARCRetainLoadOfScalar(CGF, ce->getSubExpr());
2570224145Sdim        if (resultType) {
2571224145Sdim          llvm::Value *value = loadResult.getPointer();
2572224145Sdim          value = CGF.Builder.CreateBitCast(value, resultType);
2573224145Sdim          loadResult.setPointer(value);
2574224145Sdim        }
2575224145Sdim        return loadResult;
2576224145Sdim      }
2577224145Sdim
2578224145Sdim      // These casts can change the type, so remember that and
2579224145Sdim      // soldier on.  We only need to remember the outermost such
2580224145Sdim      // cast, though.
2581226890Sdim      case CK_CPointerToObjCPointerCast:
2582226890Sdim      case CK_BlockPointerToObjCPointerCast:
2583224145Sdim      case CK_AnyPointerToBlockPointerCast:
2584224145Sdim      case CK_BitCast:
2585224145Sdim        if (!resultType)
2586224145Sdim          resultType = CGF.ConvertType(ce->getType());
2587224145Sdim        e = ce->getSubExpr();
2588224145Sdim        assert(e->getType()->hasPointerRepresentation());
2589224145Sdim        continue;
2590224145Sdim
2591224145Sdim      // For consumptions, just emit the subexpression and thus elide
2592224145Sdim      // the retain/release pair.
2593226890Sdim      case CK_ARCConsumeObject: {
2594224145Sdim        llvm::Value *result = CGF.EmitScalarExpr(ce->getSubExpr());
2595224145Sdim        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2596224145Sdim        return TryEmitResult(result, true);
2597224145Sdim      }
2598224145Sdim
2599226890Sdim      // Block extends are net +0.  Naively, we could just recurse on
2600226890Sdim      // the subexpression, but actually we need to ensure that the
2601226890Sdim      // value is copied as a block, so there's a little filter here.
2602226890Sdim      case CK_ARCExtendBlockObject: {
2603226890Sdim        llvm::Value *result; // will be a +0 value
2604226890Sdim
2605226890Sdim        // If we can't safely assume the sub-expression will produce a
2606226890Sdim        // block-copied value, emit the sub-expression at +0.
2607226890Sdim        if (shouldEmitSeparateBlockRetain(ce->getSubExpr())) {
2608226890Sdim          result = CGF.EmitScalarExpr(ce->getSubExpr());
2609226890Sdim
2610226890Sdim        // Otherwise, try to emit the sub-expression at +1 recursively.
2611226890Sdim        } else {
2612226890Sdim          TryEmitResult subresult
2613226890Sdim            = tryEmitARCRetainScalarExpr(CGF, ce->getSubExpr());
2614226890Sdim          result = subresult.getPointer();
2615226890Sdim
2616226890Sdim          // If that produced a retained value, just use that,
2617226890Sdim          // possibly casting down.
2618226890Sdim          if (subresult.getInt()) {
2619226890Sdim            if (resultType)
2620226890Sdim              result = CGF.Builder.CreateBitCast(result, resultType);
2621226890Sdim            return TryEmitResult(result, true);
2622226890Sdim          }
2623226890Sdim
2624226890Sdim          // Otherwise it's +0.
2625226890Sdim        }
2626226890Sdim
2627226890Sdim        // Retain the object as a block, then cast down.
2628226890Sdim        result = CGF.EmitARCRetainBlock(result, /*mandatory*/ true);
2629226890Sdim        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2630226890Sdim        return TryEmitResult(result, true);
2631226890Sdim      }
2632226890Sdim
2633224145Sdim      // For reclaims, emit the subexpression as a retained call and
2634224145Sdim      // skip the consumption.
2635226890Sdim      case CK_ARCReclaimReturnedObject: {
2636224145Sdim        llvm::Value *result = emitARCRetainCall(CGF, ce->getSubExpr());
2637224145Sdim        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2638224145Sdim        return TryEmitResult(result, true);
2639224145Sdim      }
2640224145Sdim
2641224145Sdim      default:
2642224145Sdim        break;
2643224145Sdim      }
2644224145Sdim
2645224145Sdim    // Skip __extension__.
2646224145Sdim    } else if (const UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
2647224145Sdim      if (op->getOpcode() == UO_Extension) {
2648224145Sdim        e = op->getSubExpr();
2649224145Sdim        continue;
2650224145Sdim      }
2651224145Sdim
2652224145Sdim    // For calls and message sends, use the retained-call logic.
2653224145Sdim    // Delegate inits are a special case in that they're the only
2654224145Sdim    // returns-retained expression that *isn't* surrounded by
2655224145Sdim    // a consume.
2656224145Sdim    } else if (isa<CallExpr>(e) ||
2657224145Sdim               (isa<ObjCMessageExpr>(e) &&
2658224145Sdim                !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
2659224145Sdim      llvm::Value *result = emitARCRetainCall(CGF, e);
2660224145Sdim      if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2661224145Sdim      return TryEmitResult(result, true);
2662235633Sdim
2663235633Sdim    // Look through pseudo-object expressions.
2664235633Sdim    } else if (const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
2665235633Sdim      TryEmitResult result
2666235633Sdim        = tryEmitARCRetainPseudoObject(CGF, pseudo);
2667235633Sdim      if (resultType) {
2668235633Sdim        llvm::Value *value = result.getPointer();
2669235633Sdim        value = CGF.Builder.CreateBitCast(value, resultType);
2670235633Sdim        result.setPointer(value);
2671235633Sdim      }
2672235633Sdim      return result;
2673224145Sdim    }
2674224145Sdim
2675224145Sdim    // Conservatively halt the search at any other expression kind.
2676224145Sdim    break;
2677224145Sdim  }
2678224145Sdim
2679224145Sdim  // We didn't find an obvious production, so emit what we've got and
2680224145Sdim  // tell the caller that we didn't manage to retain.
2681224145Sdim  llvm::Value *result = CGF.EmitScalarExpr(e);
2682224145Sdim  if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2683224145Sdim  return TryEmitResult(result, false);
2684224145Sdim}
2685224145Sdim
2686224145Sdimstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2687224145Sdim                                                LValue lvalue,
2688224145Sdim                                                QualType type) {
2689224145Sdim  TryEmitResult result = tryEmitARCRetainLoadOfScalar(CGF, lvalue, type);
2690224145Sdim  llvm::Value *value = result.getPointer();
2691224145Sdim  if (!result.getInt())
2692224145Sdim    value = CGF.EmitARCRetain(type, value);
2693224145Sdim  return value;
2694224145Sdim}
2695224145Sdim
2696224145Sdim/// EmitARCRetainScalarExpr - Semantically equivalent to
2697224145Sdim/// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a
2698224145Sdim/// best-effort attempt to peephole expressions that naturally produce
2699224145Sdim/// retained objects.
2700224145Sdimllvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
2701252723Sdim  // The retain needs to happen within the full-expression.
2702252723Sdim  if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
2703252723Sdim    enterFullExpression(cleanups);
2704252723Sdim    RunCleanupsScope scope(*this);
2705252723Sdim    return EmitARCRetainScalarExpr(cleanups->getSubExpr());
2706252723Sdim  }
2707252723Sdim
2708224145Sdim  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2709224145Sdim  llvm::Value *value = result.getPointer();
2710224145Sdim  if (!result.getInt())
2711224145Sdim    value = EmitARCRetain(e->getType(), value);
2712224145Sdim  return value;
2713224145Sdim}
2714224145Sdim
2715224145Sdimllvm::Value *
2716224145SdimCodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {
2717252723Sdim  // The retain needs to happen within the full-expression.
2718252723Sdim  if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
2719252723Sdim    enterFullExpression(cleanups);
2720252723Sdim    RunCleanupsScope scope(*this);
2721252723Sdim    return EmitARCRetainAutoreleaseScalarExpr(cleanups->getSubExpr());
2722252723Sdim  }
2723252723Sdim
2724224145Sdim  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2725224145Sdim  llvm::Value *value = result.getPointer();
2726224145Sdim  if (result.getInt())
2727224145Sdim    value = EmitARCAutorelease(value);
2728224145Sdim  else
2729224145Sdim    value = EmitARCRetainAutorelease(e->getType(), value);
2730224145Sdim  return value;
2731224145Sdim}
2732224145Sdim
2733226890Sdimllvm::Value *CodeGenFunction::EmitARCExtendBlockObject(const Expr *e) {
2734226890Sdim  llvm::Value *result;
2735226890Sdim  bool doRetain;
2736226890Sdim
2737226890Sdim  if (shouldEmitSeparateBlockRetain(e)) {
2738226890Sdim    result = EmitScalarExpr(e);
2739226890Sdim    doRetain = true;
2740226890Sdim  } else {
2741226890Sdim    TryEmitResult subresult = tryEmitARCRetainScalarExpr(*this, e);
2742226890Sdim    result = subresult.getPointer();
2743226890Sdim    doRetain = !subresult.getInt();
2744226890Sdim  }
2745226890Sdim
2746226890Sdim  if (doRetain)
2747226890Sdim    result = EmitARCRetainBlock(result, /*mandatory*/ true);
2748226890Sdim  return EmitObjCConsumeObject(e->getType(), result);
2749226890Sdim}
2750226890Sdim
2751226890Sdimllvm::Value *CodeGenFunction::EmitObjCThrowOperand(const Expr *expr) {
2752226890Sdim  // In ARC, retain and autorelease the expression.
2753235633Sdim  if (getLangOpts().ObjCAutoRefCount) {
2754226890Sdim    // Do so before running any cleanups for the full-expression.
2755252723Sdim    // EmitARCRetainAutoreleaseScalarExpr does this for us.
2756226890Sdim    return EmitARCRetainAutoreleaseScalarExpr(expr);
2757226890Sdim  }
2758226890Sdim
2759226890Sdim  // Otherwise, use the normal scalar-expression emission.  The
2760226890Sdim  // exception machinery doesn't do anything special with the
2761226890Sdim  // exception like retaining it, so there's no safety associated with
2762226890Sdim  // only running cleanups after the throw has started, and when it
2763226890Sdim  // matters it tends to be substantially inferior code.
2764226890Sdim  return EmitScalarExpr(expr);
2765226890Sdim}
2766226890Sdim
2767224145Sdimstd::pair<LValue,llvm::Value*>
2768224145SdimCodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
2769224145Sdim                                    bool ignored) {
2770224145Sdim  // Evaluate the RHS first.
2771224145Sdim  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS());
2772224145Sdim  llvm::Value *value = result.getPointer();
2773224145Sdim
2774226890Sdim  bool hasImmediateRetain = result.getInt();
2775226890Sdim
2776226890Sdim  // If we didn't emit a retained object, and the l-value is of block
2777226890Sdim  // type, then we need to emit the block-retain immediately in case
2778226890Sdim  // it invalidates the l-value.
2779226890Sdim  if (!hasImmediateRetain && e->getType()->isBlockPointerType()) {
2780226890Sdim    value = EmitARCRetainBlock(value, /*mandatory*/ false);
2781226890Sdim    hasImmediateRetain = true;
2782226890Sdim  }
2783226890Sdim
2784224145Sdim  LValue lvalue = EmitLValue(e->getLHS());
2785224145Sdim
2786224145Sdim  // If the RHS was emitted retained, expand this.
2787226890Sdim  if (hasImmediateRetain) {
2788263509Sdim    llvm::Value *oldValue = EmitLoadOfScalar(lvalue, SourceLocation());
2789235633Sdim    EmitStoreOfScalar(value, lvalue);
2790252723Sdim    EmitARCRelease(oldValue, lvalue.isARCPreciseLifetime());
2791224145Sdim  } else {
2792224145Sdim    value = EmitARCStoreStrong(lvalue, value, ignored);
2793224145Sdim  }
2794224145Sdim
2795224145Sdim  return std::pair<LValue,llvm::Value*>(lvalue, value);
2796224145Sdim}
2797224145Sdim
2798224145Sdimstd::pair<LValue,llvm::Value*>
2799224145SdimCodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) {
2800224145Sdim  llvm::Value *value = EmitARCRetainAutoreleaseScalarExpr(e->getRHS());
2801224145Sdim  LValue lvalue = EmitLValue(e->getLHS());
2802224145Sdim
2803235633Sdim  EmitStoreOfScalar(value, lvalue);
2804224145Sdim
2805224145Sdim  return std::pair<LValue,llvm::Value*>(lvalue, value);
2806224145Sdim}
2807224145Sdim
2808224145Sdimvoid CodeGenFunction::EmitObjCAutoreleasePoolStmt(
2809235633Sdim                                          const ObjCAutoreleasePoolStmt &ARPS) {
2810224145Sdim  const Stmt *subStmt = ARPS.getSubStmt();
2811224145Sdim  const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
2812224145Sdim
2813224145Sdim  CGDebugInfo *DI = getDebugInfo();
2814226890Sdim  if (DI)
2815226890Sdim    DI->EmitLexicalBlockStart(Builder, S.getLBracLoc());
2816224145Sdim
2817224145Sdim  // Keep track of the current cleanup stack depth.
2818224145Sdim  RunCleanupsScope Scope(*this);
2819245431Sdim  if (CGM.getLangOpts().ObjCRuntime.hasNativeARC()) {
2820224145Sdim    llvm::Value *token = EmitObjCAutoreleasePoolPush();
2821224145Sdim    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token);
2822224145Sdim  } else {
2823224145Sdim    llvm::Value *token = EmitObjCMRRAutoreleasePoolPush();
2824224145Sdim    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token);
2825224145Sdim  }
2826224145Sdim
2827224145Sdim  for (CompoundStmt::const_body_iterator I = S.body_begin(),
2828224145Sdim       E = S.body_end(); I != E; ++I)
2829224145Sdim    EmitStmt(*I);
2830224145Sdim
2831226890Sdim  if (DI)
2832226890Sdim    DI->EmitLexicalBlockEnd(Builder, S.getRBracLoc());
2833224145Sdim}
2834224145Sdim
2835224145Sdim/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
2836224145Sdim/// make sure it survives garbage collection until this point.
2837224145Sdimvoid CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
2838224145Sdim  // We just use an inline assembly.
2839224145Sdim  llvm::FunctionType *extenderType
2840235633Sdim    = llvm::FunctionType::get(VoidTy, VoidPtrTy, RequiredArgs::All);
2841224145Sdim  llvm::Value *extender
2842224145Sdim    = llvm::InlineAsm::get(extenderType,
2843224145Sdim                           /* assembly */ "",
2844224145Sdim                           /* constraints */ "r",
2845224145Sdim                           /* side effects */ true);
2846224145Sdim
2847224145Sdim  object = Builder.CreateBitCast(object, VoidPtrTy);
2848252723Sdim  EmitNounwindRuntimeCall(extender, object);
2849224145Sdim}
2850224145Sdim
2851235633Sdim/// GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with
2852235633Sdim/// non-trivial copy assignment function, produce following helper function.
2853235633Sdim/// static void copyHelper(Ty *dest, const Ty *source) { *dest = *source; }
2854235633Sdim///
2855235633Sdimllvm::Constant *
2856235633SdimCodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
2857235633Sdim                                        const ObjCPropertyImplDecl *PID) {
2858245431Sdim  if (!getLangOpts().CPlusPlus ||
2859252723Sdim      !getLangOpts().ObjCRuntime.hasAtomicCopyHelper())
2860235633Sdim    return 0;
2861235633Sdim  QualType Ty = PID->getPropertyIvarDecl()->getType();
2862235633Sdim  if (!Ty->isRecordType())
2863235633Sdim    return 0;
2864235633Sdim  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
2865235633Sdim  if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
2866235633Sdim    return 0;
2867235633Sdim  llvm::Constant * HelperFn = 0;
2868235633Sdim  if (hasTrivialSetExpr(PID))
2869235633Sdim    return 0;
2870235633Sdim  assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null");
2871235633Sdim  if ((HelperFn = CGM.getAtomicSetterHelperFnMap(Ty)))
2872235633Sdim    return HelperFn;
2873235633Sdim
2874235633Sdim  ASTContext &C = getContext();
2875235633Sdim  IdentifierInfo *II
2876235633Sdim    = &CGM.getContext().Idents.get("__assign_helper_atomic_property_");
2877235633Sdim  FunctionDecl *FD = FunctionDecl::Create(C,
2878235633Sdim                                          C.getTranslationUnitDecl(),
2879235633Sdim                                          SourceLocation(),
2880235633Sdim                                          SourceLocation(), II, C.VoidTy, 0,
2881235633Sdim                                          SC_Static,
2882235633Sdim                                          false,
2883235633Sdim                                          false);
2884235633Sdim
2885235633Sdim  QualType DestTy = C.getPointerType(Ty);
2886235633Sdim  QualType SrcTy = Ty;
2887235633Sdim  SrcTy.addConst();
2888235633Sdim  SrcTy = C.getPointerType(SrcTy);
2889235633Sdim
2890235633Sdim  FunctionArgList args;
2891235633Sdim  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
2892235633Sdim  args.push_back(&dstDecl);
2893235633Sdim  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
2894235633Sdim  args.push_back(&srcDecl);
2895235633Sdim
2896235633Sdim  const CGFunctionInfo &FI =
2897235633Sdim    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
2898235633Sdim                                              FunctionType::ExtInfo(),
2899235633Sdim                                              RequiredArgs::All);
2900235633Sdim
2901235633Sdim  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
2902235633Sdim
2903235633Sdim  llvm::Function *Fn =
2904235633Sdim    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
2905235633Sdim                           "__assign_helper_atomic_property_",
2906235633Sdim                           &CGM.getModule());
2907235633Sdim
2908235633Sdim  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
2909235633Sdim
2910235633Sdim  DeclRefExpr DstExpr(&dstDecl, false, DestTy,
2911235633Sdim                      VK_RValue, SourceLocation());
2912235633Sdim  UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(),
2913235633Sdim                    VK_LValue, OK_Ordinary, SourceLocation());
2914235633Sdim
2915235633Sdim  DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
2916235633Sdim                      VK_RValue, SourceLocation());
2917235633Sdim  UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
2918235633Sdim                    VK_LValue, OK_Ordinary, SourceLocation());
2919235633Sdim
2920235633Sdim  Expr *Args[2] = { &DST, &SRC };
2921235633Sdim  CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
2922235633Sdim  CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
2923245431Sdim                              Args, DestTy->getPointeeType(),
2924245431Sdim                              VK_LValue, SourceLocation(), false);
2925235633Sdim
2926235633Sdim  EmitStmt(&TheCall);
2927235633Sdim
2928235633Sdim  FinishFunction();
2929235633Sdim  HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
2930235633Sdim  CGM.setAtomicSetterHelperFnMap(Ty, HelperFn);
2931235633Sdim  return HelperFn;
2932235633Sdim}
2933235633Sdim
2934235633Sdimllvm::Constant *
2935235633SdimCodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
2936235633Sdim                                            const ObjCPropertyImplDecl *PID) {
2937245431Sdim  if (!getLangOpts().CPlusPlus ||
2938252723Sdim      !getLangOpts().ObjCRuntime.hasAtomicCopyHelper())
2939235633Sdim    return 0;
2940235633Sdim  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
2941235633Sdim  QualType Ty = PD->getType();
2942235633Sdim  if (!Ty->isRecordType())
2943235633Sdim    return 0;
2944235633Sdim  if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
2945235633Sdim    return 0;
2946235633Sdim  llvm::Constant * HelperFn = 0;
2947235633Sdim
2948235633Sdim  if (hasTrivialGetExpr(PID))
2949235633Sdim    return 0;
2950235633Sdim  assert(PID->getGetterCXXConstructor() && "getGetterCXXConstructor - null");
2951235633Sdim  if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty)))
2952235633Sdim    return HelperFn;
2953235633Sdim
2954235633Sdim
2955235633Sdim  ASTContext &C = getContext();
2956235633Sdim  IdentifierInfo *II
2957235633Sdim  = &CGM.getContext().Idents.get("__copy_helper_atomic_property_");
2958235633Sdim  FunctionDecl *FD = FunctionDecl::Create(C,
2959235633Sdim                                          C.getTranslationUnitDecl(),
2960235633Sdim                                          SourceLocation(),
2961235633Sdim                                          SourceLocation(), II, C.VoidTy, 0,
2962235633Sdim                                          SC_Static,
2963235633Sdim                                          false,
2964235633Sdim                                          false);
2965235633Sdim
2966235633Sdim  QualType DestTy = C.getPointerType(Ty);
2967235633Sdim  QualType SrcTy = Ty;
2968235633Sdim  SrcTy.addConst();
2969235633Sdim  SrcTy = C.getPointerType(SrcTy);
2970235633Sdim
2971235633Sdim  FunctionArgList args;
2972235633Sdim  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
2973235633Sdim  args.push_back(&dstDecl);
2974235633Sdim  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
2975235633Sdim  args.push_back(&srcDecl);
2976235633Sdim
2977235633Sdim  const CGFunctionInfo &FI =
2978235633Sdim  CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
2979235633Sdim                                            FunctionType::ExtInfo(),
2980235633Sdim                                            RequiredArgs::All);
2981235633Sdim
2982235633Sdim  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
2983235633Sdim
2984235633Sdim  llvm::Function *Fn =
2985235633Sdim  llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
2986235633Sdim                         "__copy_helper_atomic_property_", &CGM.getModule());
2987235633Sdim
2988235633Sdim  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
2989235633Sdim
2990235633Sdim  DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
2991235633Sdim                      VK_RValue, SourceLocation());
2992235633Sdim
2993235633Sdim  UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
2994235633Sdim                    VK_LValue, OK_Ordinary, SourceLocation());
2995235633Sdim
2996235633Sdim  CXXConstructExpr *CXXConstExpr =
2997235633Sdim    cast<CXXConstructExpr>(PID->getGetterCXXConstructor());
2998235633Sdim
2999235633Sdim  SmallVector<Expr*, 4> ConstructorArgs;
3000235633Sdim  ConstructorArgs.push_back(&SRC);
3001235633Sdim  CXXConstructExpr::arg_iterator A = CXXConstExpr->arg_begin();
3002235633Sdim  ++A;
3003235633Sdim
3004235633Sdim  for (CXXConstructExpr::arg_iterator AEnd = CXXConstExpr->arg_end();
3005235633Sdim       A != AEnd; ++A)
3006235633Sdim    ConstructorArgs.push_back(*A);
3007235633Sdim
3008235633Sdim  CXXConstructExpr *TheCXXConstructExpr =
3009235633Sdim    CXXConstructExpr::Create(C, Ty, SourceLocation(),
3010235633Sdim                             CXXConstExpr->getConstructor(),
3011235633Sdim                             CXXConstExpr->isElidable(),
3012245431Sdim                             ConstructorArgs,
3013235633Sdim                             CXXConstExpr->hadMultipleCandidates(),
3014235633Sdim                             CXXConstExpr->isListInitialization(),
3015235633Sdim                             CXXConstExpr->requiresZeroInitialization(),
3016235633Sdim                             CXXConstExpr->getConstructionKind(),
3017235633Sdim                             SourceRange());
3018235633Sdim
3019235633Sdim  DeclRefExpr DstExpr(&dstDecl, false, DestTy,
3020235633Sdim                      VK_RValue, SourceLocation());
3021235633Sdim
3022235633Sdim  RValue DV = EmitAnyExpr(&DstExpr);
3023235633Sdim  CharUnits Alignment
3024235633Sdim    = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType());
3025235633Sdim  EmitAggExpr(TheCXXConstructExpr,
3026235633Sdim              AggValueSlot::forAddr(DV.getScalarVal(), Alignment, Qualifiers(),
3027235633Sdim                                    AggValueSlot::IsDestructed,
3028235633Sdim                                    AggValueSlot::DoesNotNeedGCBarriers,
3029235633Sdim                                    AggValueSlot::IsNotAliased));
3030235633Sdim
3031235633Sdim  FinishFunction();
3032235633Sdim  HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
3033235633Sdim  CGM.setAtomicGetterHelperFnMap(Ty, HelperFn);
3034235633Sdim  return HelperFn;
3035235633Sdim}
3036235633Sdim
3037235633Sdimllvm::Value *
3038235633SdimCodeGenFunction::EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty) {
3039235633Sdim  // Get selectors for retain/autorelease.
3040235633Sdim  IdentifierInfo *CopyID = &getContext().Idents.get("copy");
3041235633Sdim  Selector CopySelector =
3042235633Sdim      getContext().Selectors.getNullarySelector(CopyID);
3043235633Sdim  IdentifierInfo *AutoreleaseID = &getContext().Idents.get("autorelease");
3044235633Sdim  Selector AutoreleaseSelector =
3045235633Sdim      getContext().Selectors.getNullarySelector(AutoreleaseID);
3046235633Sdim
3047235633Sdim  // Emit calls to retain/autorelease.
3048235633Sdim  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
3049235633Sdim  llvm::Value *Val = Block;
3050235633Sdim  RValue Result;
3051235633Sdim  Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
3052235633Sdim                                       Ty, CopySelector,
3053235633Sdim                                       Val, CallArgList(), 0, 0);
3054235633Sdim  Val = Result.getScalarVal();
3055235633Sdim  Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
3056235633Sdim                                       Ty, AutoreleaseSelector,
3057235633Sdim                                       Val, CallArgList(), 0, 0);
3058235633Sdim  Val = Result.getScalarVal();
3059235633Sdim  return Val;
3060235633Sdim}
3061235633Sdim
3062235633Sdim
3063193326SedCGObjCRuntime::~CGObjCRuntime() {}
3064