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"
23263508Sdim#include "clang/CodeGen/CGFunctionInfo.h"
24193326Sed#include "llvm/ADT/STLExtras.h"
25251662Sdim#include "llvm/Support/CallSite.h"
26249423Sdim#include "llvm/IR/DataLayout.h"
27249423Sdim#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);
34234353Sdimstatic RValue AdjustRelatedResultType(CodeGenFunction &CGF,
35239462Sdim                                      QualType ET,
36234353Sdim                                      const ObjCMethodDecl *Method,
37234353Sdim                                      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) {
42226633Sdim  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
56239462Sdim/// EmitObjCBoxedExpr - This routine generates code to call
57239462Sdim/// the appropriate expression boxing method. This will either be
58239462Sdim/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:].
59234353Sdim///
60234353Sdimllvm::Value *
61239462SdimCodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {
62234353Sdim  // Generate the correct selector for this literal's concrete type.
63239462Sdim  const Expr *SubExpr = E->getSubExpr();
64234353Sdim  // Get the method.
65239462Sdim  const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();
66239462Sdim  assert(BoxingMethod && "BoxingMethod is null");
67239462Sdim  assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");
68239462Sdim  Selector Sel = BoxingMethod->getSelector();
69234353Sdim
70234353Sdim  // Generate a reference to the class pointer, which will be the receiver.
71239462Sdim  // Assumes that the method was introduced in the class that should be
72239462Sdim  // messaged (avoids pulling it out of the result type).
73234353Sdim  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
74239462Sdim  const ObjCInterfaceDecl *ClassDecl = BoxingMethod->getClassInterface();
75249423Sdim  llvm::Value *Receiver = Runtime.GetClass(*this, ClassDecl);
76239462Sdim
77239462Sdim  const ParmVarDecl *argDecl = *BoxingMethod->param_begin();
78234353Sdim  QualType ArgQT = argDecl->getType().getUnqualifiedType();
79239462Sdim  RValue RV = EmitAnyExpr(SubExpr);
80234353Sdim  CallArgList Args;
81234353Sdim  Args.add(RV, ArgQT);
82239462Sdim
83234353Sdim  RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
84239462Sdim                                              BoxingMethod->getResultType(), Sel, Receiver, Args,
85239462Sdim                                              ClassDecl, BoxingMethod);
86234353Sdim  return Builder.CreateBitCast(result.getScalarVal(),
87234353Sdim                               ConvertType(E->getType()));
88234353Sdim}
89234353Sdim
90234353Sdimllvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
91234353Sdim                                    const ObjCMethodDecl *MethodWithObjects) {
92234353Sdim  ASTContext &Context = CGM.getContext();
93234353Sdim  const ObjCDictionaryLiteral *DLE = 0;
94234353Sdim  const ObjCArrayLiteral *ALE = dyn_cast<ObjCArrayLiteral>(E);
95234353Sdim  if (!ALE)
96234353Sdim    DLE = cast<ObjCDictionaryLiteral>(E);
97234353Sdim
98234353Sdim  // Compute the type of the array we're initializing.
99234353Sdim  uint64_t NumElements =
100234353Sdim    ALE ? ALE->getNumElements() : DLE->getNumElements();
101234353Sdim  llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()),
102234353Sdim                            NumElements);
103234353Sdim  QualType ElementType = Context.getObjCIdType().withConst();
104234353Sdim  QualType ElementArrayType
105234353Sdim    = Context.getConstantArrayType(ElementType, APNumElements,
106234353Sdim                                   ArrayType::Normal, /*IndexTypeQuals=*/0);
107234353Sdim
108234353Sdim  // Allocate the temporary array(s).
109234353Sdim  llvm::Value *Objects = CreateMemTemp(ElementArrayType, "objects");
110234353Sdim  llvm::Value *Keys = 0;
111234353Sdim  if (DLE)
112234353Sdim    Keys = CreateMemTemp(ElementArrayType, "keys");
113234353Sdim
114249423Sdim  // In ARC, we may need to do extra work to keep all the keys and
115249423Sdim  // values alive until after the call.
116249423Sdim  SmallVector<llvm::Value *, 16> NeededObjects;
117249423Sdim  bool TrackNeededObjects =
118249423Sdim    (getLangOpts().ObjCAutoRefCount &&
119249423Sdim    CGM.getCodeGenOpts().OptimizationLevel != 0);
120249423Sdim
121234353Sdim  // Perform the actual initialialization of the array(s).
122234353Sdim  for (uint64_t i = 0; i < NumElements; i++) {
123234353Sdim    if (ALE) {
124249423Sdim      // Emit the element and store it to the appropriate array slot.
125234353Sdim      const Expr *Rhs = ALE->getElement(i);
126234353Sdim      LValue LV = LValue::MakeAddr(Builder.CreateStructGEP(Objects, i),
127234353Sdim                                   ElementType,
128234353Sdim                                   Context.getTypeAlignInChars(Rhs->getType()),
129234353Sdim                                   Context);
130249423Sdim
131249423Sdim      llvm::Value *value = EmitScalarExpr(Rhs);
132249423Sdim      EmitStoreThroughLValue(RValue::get(value), LV, true);
133249423Sdim      if (TrackNeededObjects) {
134249423Sdim        NeededObjects.push_back(value);
135249423Sdim      }
136234353Sdim    } else {
137249423Sdim      // Emit the key and store it to the appropriate array slot.
138234353Sdim      const Expr *Key = DLE->getKeyValueElement(i).Key;
139234353Sdim      LValue KeyLV = LValue::MakeAddr(Builder.CreateStructGEP(Keys, i),
140234353Sdim                                      ElementType,
141234353Sdim                                    Context.getTypeAlignInChars(Key->getType()),
142234353Sdim                                      Context);
143249423Sdim      llvm::Value *keyValue = EmitScalarExpr(Key);
144249423Sdim      EmitStoreThroughLValue(RValue::get(keyValue), KeyLV, /*isInit=*/true);
145234353Sdim
146249423Sdim      // Emit the value and store it to the appropriate array slot.
147234353Sdim      const Expr *Value = DLE->getKeyValueElement(i).Value;
148234353Sdim      LValue ValueLV = LValue::MakeAddr(Builder.CreateStructGEP(Objects, i),
149234353Sdim                                        ElementType,
150234353Sdim                                  Context.getTypeAlignInChars(Value->getType()),
151234353Sdim                                        Context);
152249423Sdim      llvm::Value *valueValue = EmitScalarExpr(Value);
153249423Sdim      EmitStoreThroughLValue(RValue::get(valueValue), ValueLV, /*isInit=*/true);
154249423Sdim      if (TrackNeededObjects) {
155249423Sdim        NeededObjects.push_back(keyValue);
156249423Sdim        NeededObjects.push_back(valueValue);
157249423Sdim      }
158234353Sdim    }
159234353Sdim  }
160234353Sdim
161234353Sdim  // Generate the argument list.
162234353Sdim  CallArgList Args;
163234353Sdim  ObjCMethodDecl::param_const_iterator PI = MethodWithObjects->param_begin();
164234353Sdim  const ParmVarDecl *argDecl = *PI++;
165234353Sdim  QualType ArgQT = argDecl->getType().getUnqualifiedType();
166234353Sdim  Args.add(RValue::get(Objects), ArgQT);
167234353Sdim  if (DLE) {
168234353Sdim    argDecl = *PI++;
169234353Sdim    ArgQT = argDecl->getType().getUnqualifiedType();
170234353Sdim    Args.add(RValue::get(Keys), ArgQT);
171234353Sdim  }
172234353Sdim  argDecl = *PI;
173234353Sdim  ArgQT = argDecl->getType().getUnqualifiedType();
174234353Sdim  llvm::Value *Count =
175234353Sdim    llvm::ConstantInt::get(CGM.getTypes().ConvertType(ArgQT), NumElements);
176234353Sdim  Args.add(RValue::get(Count), ArgQT);
177234353Sdim
178234353Sdim  // Generate a reference to the class pointer, which will be the receiver.
179234353Sdim  Selector Sel = MethodWithObjects->getSelector();
180234353Sdim  QualType ResultType = E->getType();
181234353Sdim  const ObjCObjectPointerType *InterfacePointerType
182234353Sdim    = ResultType->getAsObjCInterfacePointerType();
183234353Sdim  ObjCInterfaceDecl *Class
184234353Sdim    = InterfacePointerType->getObjectType()->getInterface();
185234353Sdim  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
186249423Sdim  llvm::Value *Receiver = Runtime.GetClass(*this, Class);
187234353Sdim
188234353Sdim  // Generate the message send.
189234353Sdim  RValue result
190234353Sdim    = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
191234353Sdim                                  MethodWithObjects->getResultType(),
192234353Sdim                                  Sel,
193234353Sdim                                  Receiver, Args, Class,
194234353Sdim                                  MethodWithObjects);
195249423Sdim
196249423Sdim  // The above message send needs these objects, but in ARC they are
197249423Sdim  // passed in a buffer that is essentially __unsafe_unretained.
198249423Sdim  // Therefore we must prevent the optimizer from releasing them until
199249423Sdim  // after the call.
200249423Sdim  if (TrackNeededObjects) {
201249423Sdim    EmitARCIntrinsicUse(NeededObjects);
202249423Sdim  }
203249423Sdim
204234353Sdim  return Builder.CreateBitCast(result.getScalarVal(),
205234353Sdim                               ConvertType(E->getType()));
206234353Sdim}
207234353Sdim
208234353Sdimllvm::Value *CodeGenFunction::EmitObjCArrayLiteral(const ObjCArrayLiteral *E) {
209234353Sdim  return EmitObjCCollectionLiteral(E, E->getArrayWithObjectsMethod());
210234353Sdim}
211234353Sdim
212234353Sdimllvm::Value *CodeGenFunction::EmitObjCDictionaryLiteral(
213234353Sdim                                            const ObjCDictionaryLiteral *E) {
214234353Sdim  return EmitObjCCollectionLiteral(E, E->getDictWithObjectsMethod());
215234353Sdim}
216234353Sdim
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.
223249423Sdim  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.
228249423Sdim  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,
234239462Sdim                                      QualType ExpT,
235223017Sdim                                      const ObjCMethodDecl *Method,
236223017Sdim                                      RValue Result) {
237223017Sdim  if (!Method)
238223017Sdim    return Result;
239224145Sdim
240223017Sdim  if (!Method->hasRelatedResultType() ||
241239462Sdim      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(),
247239462Sdim                                               CGF.ConvertType(ExpT)));
248223017Sdim}
249193326Sed
250226633Sdim/// Decide whether to extend the lifetime of the receiver of a
251226633Sdim/// returns-inner-pointer message.
252226633Sdimstatic bool
253226633SdimshouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message) {
254226633Sdim  switch (message->getReceiverKind()) {
255226633Sdim
256226633Sdim  // For a normal instance message, we should extend unless the
257226633Sdim  // receiver is loaded from a variable with precise lifetime.
258226633Sdim  case ObjCMessageExpr::Instance: {
259226633Sdim    const Expr *receiver = message->getInstanceReceiver();
260226633Sdim    const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(receiver);
261226633Sdim    if (!ice || ice->getCastKind() != CK_LValueToRValue) return true;
262226633Sdim    receiver = ice->getSubExpr()->IgnoreParens();
263226633Sdim
264226633Sdim    // Only __strong variables.
265226633Sdim    if (receiver->getType().getObjCLifetime() != Qualifiers::OCL_Strong)
266226633Sdim      return true;
267226633Sdim
268226633Sdim    // All ivars and fields have precise lifetime.
269226633Sdim    if (isa<MemberExpr>(receiver) || isa<ObjCIvarRefExpr>(receiver))
270226633Sdim      return false;
271226633Sdim
272226633Sdim    // Otherwise, check for variables.
273226633Sdim    const DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(ice->getSubExpr());
274226633Sdim    if (!declRef) return true;
275226633Sdim    const VarDecl *var = dyn_cast<VarDecl>(declRef->getDecl());
276226633Sdim    if (!var) return true;
277226633Sdim
278226633Sdim    // All variables have precise lifetime except local variables with
279226633Sdim    // automatic storage duration that aren't specially marked.
280226633Sdim    return (var->hasLocalStorage() &&
281226633Sdim            !var->hasAttr<ObjCPreciseLifetimeAttr>());
282226633Sdim  }
283226633Sdim
284226633Sdim  case ObjCMessageExpr::Class:
285226633Sdim  case ObjCMessageExpr::SuperClass:
286226633Sdim    // It's never necessary for class objects.
287226633Sdim    return false;
288226633Sdim
289226633Sdim  case ObjCMessageExpr::SuperInstance:
290226633Sdim    // We generally assume that 'self' lives throughout a method call.
291226633Sdim    return false;
292226633Sdim  }
293226633Sdim
294226633Sdim  llvm_unreachable("invalid receiver kind");
295226633Sdim}
296226633Sdim
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
305226633Sdim  const ObjCMethodDecl *method = E->getMethodDecl();
306226633Sdim
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 &&
313234353Sdim     CGM.getLangOpts().ObjCAutoRefCount &&
314226633Sdim     method &&
315226633Sdim     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();
331226633Sdim      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");
342249423Sdim    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
361226633Sdim  if (retainSelf)
362226633Sdim    Receiver = EmitARCRetainNonBlock(Receiver);
363226633Sdim
364226633Sdim  // In ARC, we sometimes want to "extend the lifetime"
365226633Sdim  // (i.e. retain+autorelease) of receivers of returns-inner-pointer
366226633Sdim  // messages.
367234353Sdim  if (getLangOpts().ObjCAutoRefCount && method &&
368226633Sdim      method->hasAttr<ObjCReturnsInnerPointerAttr>() &&
369226633Sdim      shouldExtendReceiverForInnerPointerMessage(E))
370226633Sdim    Receiver = EmitARCRetainAutorelease(ReceiverType, Receiver);
371226633Sdim
372224145Sdim  QualType ResultType =
373226633Sdim    method ? method->getResultType() : E->getType();
374224145Sdim
375193326Sed  CallArgList Args;
376226633Sdim  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) {
386234353Sdim    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,
409226633Sdim                                              method);
410223017Sdim  } else {
411223017Sdim    result = Runtime.GenerateMessageSend(*this, Return, ResultType,
412223017Sdim                                         E->getSelector(),
413223017Sdim                                         Receiver, Args, OID,
414226633Sdim                                         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'.
426226633Sdim    llvm::Type *selfTy =
427224145Sdim      cast<llvm::PointerType>(selfAddr->getType())->getElementType();
428224145Sdim    newSelf = Builder.CreateBitCast(newSelf, selfTy);
429224145Sdim
430224145Sdim    Builder.CreateStore(newSelf, selfAddr);
431224145Sdim  }
432224145Sdim
433239462Sdim  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.
472263508Sdim  if (OMD->hasAttr<NoDebugAttr>())
473263508Sdim    DebugInfo = NULL; // disable debug info indefinitely for this function
474206275Srdivacky
475193326Sed  llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
476193326Sed
477234353Sdim  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
483226633Sdim  for (ObjCMethodDecl::param_const_iterator PI = OMD->param_begin(),
484234353Sdim         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.
492234353Sdim  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
513226633Sdim/// emitStructGetterCall - Call the runtime function to load a property
514226633Sdim/// into the return value slot.
515226633Sdimstatic void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
516226633Sdim                                 bool isAtomic, bool hasStrong) {
517226633Sdim  ASTContext &Context = CGF.getContext();
518193326Sed
519226633Sdim  llvm::Value *src =
520226633Sdim    CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(),
521226633Sdim                          ivar, 0).getAddress();
522226633Sdim
523226633Sdim  // objc_copyStruct (ReturnValue, &structIvar,
524226633Sdim  //                  sizeof (Type of Ivar), isAtomic, false);
525226633Sdim  CallArgList args;
526226633Sdim
527226633Sdim  llvm::Value *dest = CGF.Builder.CreateBitCast(CGF.ReturnValue, CGF.VoidPtrTy);
528226633Sdim  args.add(RValue::get(dest), Context.VoidPtrTy);
529226633Sdim
530226633Sdim  src = CGF.Builder.CreateBitCast(src, CGF.VoidPtrTy);
531226633Sdim  args.add(RValue::get(src), Context.VoidPtrTy);
532226633Sdim
533226633Sdim  CharUnits size = CGF.getContext().getTypeSizeInChars(ivar->getType());
534226633Sdim  args.add(RValue::get(CGF.CGM.getSize(size)), Context.getSizeType());
535226633Sdim  args.add(RValue::get(CGF.Builder.getInt1(isAtomic)), Context.BoolTy);
536226633Sdim  args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy);
537226633Sdim
538226633Sdim  llvm::Value *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
539239462Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(Context.VoidTy, args,
540239462Sdim                                                      FunctionType::ExtInfo(),
541239462Sdim                                                      RequiredArgs::All),
542226633Sdim               fn, ReturnValueSlot(), args);
543226633Sdim}
544226633Sdim
545226633Sdim/// Determine whether the given architecture supports unaligned atomic
546226633Sdim/// accesses.  They don't have to be fast, just faster than a function
547226633Sdim/// call and a mutex.
548226633Sdimstatic bool hasUnalignedAtomics(llvm::Triple::ArchType arch) {
549226633Sdim  // FIXME: Allow unaligned atomic load/store on x86.  (It is not
550226633Sdim  // currently supported by the backend.)
551226633Sdim  return 0;
552226633Sdim}
553226633Sdim
554226633Sdim/// Return the maximum size that permits atomic accesses for the given
555226633Sdim/// architecture.
556226633Sdimstatic CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM,
557226633Sdim                                        llvm::Triple::ArchType arch) {
558226633Sdim  // ARM has 8-byte atomic accesses, but it's not clear whether we
559226633Sdim  // want to rely on them here.
560226633Sdim
561226633Sdim  // In the default case, just assume that any size up to a pointer is
562226633Sdim  // fine given adequate alignment.
563226633Sdim  return CharUnits::fromQuantity(CGM.PointerSizeInBytes);
564226633Sdim}
565226633Sdim
566226633Sdimnamespace {
567226633Sdim  class PropertyImplStrategy {
568226633Sdim  public:
569226633Sdim    enum StrategyKind {
570226633Sdim      /// The 'native' strategy is to use the architecture's provided
571226633Sdim      /// reads and writes.
572226633Sdim      Native,
573226633Sdim
574226633Sdim      /// Use objc_setProperty and objc_getProperty.
575226633Sdim      GetSetProperty,
576226633Sdim
577226633Sdim      /// Use objc_setProperty for the setter, but use expression
578226633Sdim      /// evaluation for the getter.
579226633Sdim      SetPropertyAndExpressionGet,
580226633Sdim
581226633Sdim      /// Use objc_copyStruct.
582226633Sdim      CopyStruct,
583226633Sdim
584226633Sdim      /// The 'expression' strategy is to emit normal assignment or
585226633Sdim      /// lvalue-to-rvalue expressions.
586226633Sdim      Expression
587226633Sdim    };
588226633Sdim
589226633Sdim    StrategyKind getKind() const { return StrategyKind(Kind); }
590226633Sdim
591226633Sdim    bool hasStrongMember() const { return HasStrong; }
592226633Sdim    bool isAtomic() const { return IsAtomic; }
593226633Sdim    bool isCopy() const { return IsCopy; }
594226633Sdim
595226633Sdim    CharUnits getIvarSize() const { return IvarSize; }
596226633Sdim    CharUnits getIvarAlignment() const { return IvarAlignment; }
597226633Sdim
598226633Sdim    PropertyImplStrategy(CodeGenModule &CGM,
599226633Sdim                         const ObjCPropertyImplDecl *propImpl);
600226633Sdim
601226633Sdim  private:
602226633Sdim    unsigned Kind : 8;
603226633Sdim    unsigned IsAtomic : 1;
604226633Sdim    unsigned IsCopy : 1;
605226633Sdim    unsigned HasStrong : 1;
606226633Sdim
607226633Sdim    CharUnits IvarSize;
608226633Sdim    CharUnits IvarAlignment;
609226633Sdim  };
610226633Sdim}
611226633Sdim
612239462Sdim/// Pick an implementation strategy for the given property synthesis.
613226633SdimPropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
614226633Sdim                                     const ObjCPropertyImplDecl *propImpl) {
615226633Sdim  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
616226633Sdim  ObjCPropertyDecl::SetterKind setterKind = prop->getSetterKind();
617226633Sdim
618226633Sdim  IsCopy = (setterKind == ObjCPropertyDecl::Copy);
619226633Sdim  IsAtomic = prop->isAtomic();
620226633Sdim  HasStrong = false; // doesn't matter here.
621226633Sdim
622226633Sdim  // Evaluate the ivar's size and alignment.
623226633Sdim  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
624226633Sdim  QualType ivarType = ivar->getType();
625226633Sdim  llvm::tie(IvarSize, IvarAlignment)
626226633Sdim    = CGM.getContext().getTypeInfoInChars(ivarType);
627226633Sdim
628226633Sdim  // If we have a copy property, we always have to use getProperty/setProperty.
629226633Sdim  // TODO: we could actually use setProperty and an expression for non-atomics.
630226633Sdim  if (IsCopy) {
631226633Sdim    Kind = GetSetProperty;
632226633Sdim    return;
633226633Sdim  }
634226633Sdim
635226633Sdim  // Handle retain.
636226633Sdim  if (setterKind == ObjCPropertyDecl::Retain) {
637226633Sdim    // In GC-only, there's nothing special that needs to be done.
638234353Sdim    if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
639226633Sdim      // fallthrough
640226633Sdim
641226633Sdim    // In ARC, if the property is non-atomic, use expression emission,
642226633Sdim    // which translates to objc_storeStrong.  This isn't required, but
643226633Sdim    // it's slightly nicer.
644234353Sdim    } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) {
645243830Sdim      // Using standard expression emission for the setter is only
646243830Sdim      // acceptable if the ivar is __strong, which won't be true if
647243830Sdim      // the property is annotated with __attribute__((NSObject)).
648243830Sdim      // TODO: falling all the way back to objc_setProperty here is
649243830Sdim      // just laziness, though;  we could still use objc_storeStrong
650243830Sdim      // if we hacked it right.
651243830Sdim      if (ivarType.getObjCLifetime() == Qualifiers::OCL_Strong)
652243830Sdim        Kind = Expression;
653243830Sdim      else
654243830Sdim        Kind = SetPropertyAndExpressionGet;
655226633Sdim      return;
656226633Sdim
657226633Sdim    // Otherwise, we need to at least use setProperty.  However, if
658226633Sdim    // the property isn't atomic, we can use normal expression
659226633Sdim    // emission for the getter.
660226633Sdim    } else if (!IsAtomic) {
661226633Sdim      Kind = SetPropertyAndExpressionGet;
662226633Sdim      return;
663226633Sdim
664226633Sdim    // Otherwise, we have to use both setProperty and getProperty.
665226633Sdim    } else {
666226633Sdim      Kind = GetSetProperty;
667226633Sdim      return;
668226633Sdim    }
669226633Sdim  }
670226633Sdim
671226633Sdim  // If we're not atomic, just use expression accesses.
672226633Sdim  if (!IsAtomic) {
673226633Sdim    Kind = Expression;
674226633Sdim    return;
675226633Sdim  }
676226633Sdim
677226633Sdim  // Properties on bitfield ivars need to be emitted using expression
678226633Sdim  // accesses even if they're nominally atomic.
679226633Sdim  if (ivar->isBitField()) {
680226633Sdim    Kind = Expression;
681226633Sdim    return;
682226633Sdim  }
683226633Sdim
684226633Sdim  // GC-qualified or ARC-qualified ivars need to be emitted as
685226633Sdim  // expressions.  This actually works out to being atomic anyway,
686226633Sdim  // except for ARC __strong, but that should trigger the above code.
687226633Sdim  if (ivarType.hasNonTrivialObjCLifetime() ||
688234353Sdim      (CGM.getLangOpts().getGC() &&
689226633Sdim       CGM.getContext().getObjCGCAttrKind(ivarType))) {
690226633Sdim    Kind = Expression;
691226633Sdim    return;
692226633Sdim  }
693226633Sdim
694226633Sdim  // Compute whether the ivar has strong members.
695234353Sdim  if (CGM.getLangOpts().getGC())
696226633Sdim    if (const RecordType *recordType = ivarType->getAs<RecordType>())
697226633Sdim      HasStrong = recordType->getDecl()->hasObjectMember();
698226633Sdim
699226633Sdim  // We can never access structs with object members with a native
700226633Sdim  // access, because we need to use write barriers.  This is what
701226633Sdim  // objc_copyStruct is for.
702226633Sdim  if (HasStrong) {
703226633Sdim    Kind = CopyStruct;
704226633Sdim    return;
705226633Sdim  }
706226633Sdim
707226633Sdim  // Otherwise, this is target-dependent and based on the size and
708226633Sdim  // alignment of the ivar.
709226633Sdim
710226633Sdim  // If the size of the ivar is not a power of two, give up.  We don't
711226633Sdim  // want to get into the business of doing compare-and-swaps.
712226633Sdim  if (!IvarSize.isPowerOfTwo()) {
713226633Sdim    Kind = CopyStruct;
714226633Sdim    return;
715226633Sdim  }
716226633Sdim
717226633Sdim  llvm::Triple::ArchType arch =
718251662Sdim    CGM.getTarget().getTriple().getArch();
719226633Sdim
720226633Sdim  // Most architectures require memory to fit within a single cache
721226633Sdim  // line, so the alignment has to be at least the size of the access.
722226633Sdim  // Otherwise we have to grab a lock.
723226633Sdim  if (IvarAlignment < IvarSize && !hasUnalignedAtomics(arch)) {
724226633Sdim    Kind = CopyStruct;
725226633Sdim    return;
726226633Sdim  }
727226633Sdim
728226633Sdim  // If the ivar's size exceeds the architecture's maximum atomic
729226633Sdim  // access size, we have to use CopyStruct.
730226633Sdim  if (IvarSize > getMaxAtomicAccessSize(CGM, arch)) {
731226633Sdim    Kind = CopyStruct;
732226633Sdim    return;
733226633Sdim  }
734226633Sdim
735226633Sdim  // Otherwise, we can use native loads and stores.
736226633Sdim  Kind = Native;
737226633Sdim}
738226633Sdim
739239462Sdim/// \brief Generate an Objective-C property getter function.
740239462Sdim///
741239462Sdim/// The given Decl must be an ObjCImplementationDecl. \@synthesize
742193326Sed/// is illegal within a category.
743193326Sedvoid CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
744193326Sed                                         const ObjCPropertyImplDecl *PID) {
745234353Sdim  llvm::Constant *AtomicHelperFn =
746234353Sdim    GenerateObjCAtomicGetterCopyHelperFunction(PID);
747193326Sed  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
748193326Sed  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
749193326Sed  assert(OMD && "Invalid call to generate getter (empty method)");
750234353Sdim  StartObjCMethod(OMD, IMP->getClassInterface(), OMD->getLocStart());
751226633Sdim
752239462Sdim  generateObjCGetterBody(IMP, PID, OMD, AtomicHelperFn);
753226633Sdim
754226633Sdim  FinishFunction();
755226633Sdim}
756226633Sdim
757226633Sdimstatic bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl) {
758226633Sdim  const Expr *getter = propImpl->getGetterCXXConstructor();
759226633Sdim  if (!getter) return true;
760226633Sdim
761226633Sdim  // Sema only makes only of these when the ivar has a C++ class type,
762226633Sdim  // so the form is pretty constrained.
763226633Sdim
764226633Sdim  // If the property has a reference type, we might just be binding a
765226633Sdim  // reference, in which case the result will be a gl-value.  We should
766226633Sdim  // treat this as a non-trivial operation.
767226633Sdim  if (getter->isGLValue())
768226633Sdim    return false;
769226633Sdim
770226633Sdim  // If we selected a trivial copy-constructor, we're okay.
771226633Sdim  if (const CXXConstructExpr *construct = dyn_cast<CXXConstructExpr>(getter))
772226633Sdim    return (construct->getConstructor()->isTrivial());
773226633Sdim
774226633Sdim  // The constructor might require cleanups (in which case it's never
775226633Sdim  // trivial).
776226633Sdim  assert(isa<ExprWithCleanups>(getter));
777226633Sdim  return false;
778226633Sdim}
779226633Sdim
780234353Sdim/// emitCPPObjectAtomicGetterCall - Call the runtime function to
781234353Sdim/// copy the ivar into the resturn slot.
782234353Sdimstatic void emitCPPObjectAtomicGetterCall(CodeGenFunction &CGF,
783234353Sdim                                          llvm::Value *returnAddr,
784234353Sdim                                          ObjCIvarDecl *ivar,
785234353Sdim                                          llvm::Constant *AtomicHelperFn) {
786234353Sdim  // objc_copyCppObjectAtomic (&returnSlot, &CppObjectIvar,
787234353Sdim  //                           AtomicHelperFn);
788234353Sdim  CallArgList args;
789234353Sdim
790234353Sdim  // The 1st argument is the return Slot.
791234353Sdim  args.add(RValue::get(returnAddr), CGF.getContext().VoidPtrTy);
792234353Sdim
793234353Sdim  // The 2nd argument is the address of the ivar.
794234353Sdim  llvm::Value *ivarAddr =
795234353Sdim  CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
796234353Sdim                        CGF.LoadObjCSelf(), ivar, 0).getAddress();
797234353Sdim  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
798234353Sdim  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
799234353Sdim
800234353Sdim  // Third argument is the helper function.
801234353Sdim  args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
802234353Sdim
803234353Sdim  llvm::Value *copyCppAtomicObjectFn =
804249423Sdim    CGF.CGM.getObjCRuntime().GetCppAtomicObjectGetFunction();
805239462Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
806239462Sdim                                                      args,
807239462Sdim                                                      FunctionType::ExtInfo(),
808239462Sdim                                                      RequiredArgs::All),
809234353Sdim               copyCppAtomicObjectFn, ReturnValueSlot(), args);
810234353Sdim}
811234353Sdim
812226633Sdimvoid
813226633SdimCodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
814234353Sdim                                        const ObjCPropertyImplDecl *propImpl,
815239462Sdim                                        const ObjCMethodDecl *GetterMethodDecl,
816234353Sdim                                        llvm::Constant *AtomicHelperFn) {
817226633Sdim  // If there's a non-trivial 'get' expression, we just have to emit that.
818226633Sdim  if (!hasTrivialGetExpr(propImpl)) {
819234353Sdim    if (!AtomicHelperFn) {
820234353Sdim      ReturnStmt ret(SourceLocation(), propImpl->getGetterCXXConstructor(),
821234353Sdim                     /*nrvo*/ 0);
822234353Sdim      EmitReturnStmt(ret);
823234353Sdim    }
824234353Sdim    else {
825234353Sdim      ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
826234353Sdim      emitCPPObjectAtomicGetterCall(*this, ReturnValue,
827234353Sdim                                    ivar, AtomicHelperFn);
828234353Sdim    }
829226633Sdim    return;
830226633Sdim  }
831226633Sdim
832226633Sdim  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
833226633Sdim  QualType propType = prop->getType();
834226633Sdim  ObjCMethodDecl *getterMethod = prop->getGetterMethodDecl();
835226633Sdim
836226633Sdim  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
837226633Sdim
838226633Sdim  // Pick an implementation strategy.
839226633Sdim  PropertyImplStrategy strategy(CGM, propImpl);
840226633Sdim  switch (strategy.getKind()) {
841226633Sdim  case PropertyImplStrategy::Native: {
842243830Sdim    // We don't need to do anything for a zero-size struct.
843243830Sdim    if (strategy.getIvarSize().isZero())
844243830Sdim      return;
845243830Sdim
846226633Sdim    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0);
847226633Sdim
848226633Sdim    // Currently, all atomic accesses have to be through integer
849226633Sdim    // types, so there's no point in trying to pick a prettier type.
850226633Sdim    llvm::Type *bitcastType =
851226633Sdim      llvm::Type::getIntNTy(getLLVMContext(),
852226633Sdim                            getContext().toBits(strategy.getIvarSize()));
853226633Sdim    bitcastType = bitcastType->getPointerTo(); // addrspace 0 okay
854226633Sdim
855226633Sdim    // Perform an atomic load.  This does not impose ordering constraints.
856226633Sdim    llvm::Value *ivarAddr = LV.getAddress();
857226633Sdim    ivarAddr = Builder.CreateBitCast(ivarAddr, bitcastType);
858226633Sdim    llvm::LoadInst *load = Builder.CreateLoad(ivarAddr, "load");
859226633Sdim    load->setAlignment(strategy.getIvarAlignment().getQuantity());
860226633Sdim    load->setAtomic(llvm::Unordered);
861226633Sdim
862226633Sdim    // Store that value into the return address.  Doing this with a
863226633Sdim    // bitcast is likely to produce some pretty ugly IR, but it's not
864226633Sdim    // the *most* terrible thing in the world.
865226633Sdim    Builder.CreateStore(load, Builder.CreateBitCast(ReturnValue, bitcastType));
866226633Sdim
867226633Sdim    // Make sure we don't do an autorelease.
868226633Sdim    AutoreleaseResult = false;
869226633Sdim    return;
870226633Sdim  }
871226633Sdim
872226633Sdim  case PropertyImplStrategy::GetSetProperty: {
873226633Sdim    llvm::Value *getPropertyFn =
874193326Sed      CGM.getObjCRuntime().GetPropertyGetFunction();
875226633Sdim    if (!getPropertyFn) {
876226633Sdim      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.
883226633Sdim    llvm::Value *cmd =
884226633Sdim      Builder.CreateLoad(LocalDeclMap[getterMethod->getCmdDecl()], "cmd");
885226633Sdim    llvm::Value *self = Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
886226633Sdim    llvm::Value *ivarOffset =
887226633Sdim      EmitIvarOffset(classImpl->getClassInterface(), ivar);
888226633Sdim
889226633Sdim    CallArgList args;
890226633Sdim    args.add(RValue::get(self), getContext().getObjCIdType());
891226633Sdim    args.add(RValue::get(cmd), getContext().getObjCSelType());
892226633Sdim    args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
893226633Sdim    args.add(RValue::get(Builder.getInt1(strategy.isAtomic())),
894226633Sdim             getContext().BoolTy);
895226633Sdim
896193326Sed    // FIXME: We shouldn't need to get the function info here, the
897193326Sed    // runtime already should have computed it to build the function.
898239462Sdim    RValue RV = EmitCall(getTypes().arrangeFreeFunctionCall(propType, args,
899239462Sdim                                                       FunctionType::ExtInfo(),
900239462Sdim                                                            RequiredArgs::All),
901226633Sdim                         getPropertyFn, ReturnValueSlot(), args);
902226633Sdim
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(),
907239462Sdim           getTypes().ConvertType(getterMethod->getResultType())));
908224145Sdim
909226633Sdim    EmitReturnOfRValue(RV, propType);
910226633Sdim
911224145Sdim    // objc_getProperty does an autorelease, so we should suppress ours.
912224145Sdim    AutoreleaseResult = false;
913226633Sdim
914226633Sdim    return;
915226633Sdim  }
916226633Sdim
917226633Sdim  case PropertyImplStrategy::CopyStruct:
918226633Sdim    emitStructGetterCall(*this, ivar, strategy.isAtomic(),
919226633Sdim                         strategy.hasStrongMember());
920226633Sdim    return;
921226633Sdim
922226633Sdim  case PropertyImplStrategy::Expression:
923226633Sdim  case PropertyImplStrategy::SetPropertyAndExpressionGet: {
924226633Sdim    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0);
925226633Sdim
926226633Sdim    QualType ivarType = ivar->getType();
927249423Sdim    switch (getEvaluationKind(ivarType)) {
928249423Sdim    case TEK_Complex: {
929263508Sdim      ComplexPairTy pair = EmitLoadOfComplex(LV, SourceLocation());
930249423Sdim      EmitStoreOfComplex(pair,
931249423Sdim                         MakeNaturalAlignAddrLValue(ReturnValue, ivarType),
932249423Sdim                         /*init*/ true);
933249423Sdim      return;
934249423Sdim    }
935249423Sdim    case TEK_Aggregate:
936226633Sdim      // The return value slot is guaranteed to not be aliased, but
937226633Sdim      // that's not necessarily the same as "on the stack", so
938226633Sdim      // we still potentially need objc_memmove_collectable.
939226633Sdim      EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType);
940249423Sdim      return;
941249423Sdim    case TEK_Scalar: {
942226633Sdim      llvm::Value *value;
943226633Sdim      if (propType->isReferenceType()) {
944226633Sdim        value = LV.getAddress();
945226633Sdim      } else {
946226633Sdim        // We want to load and autoreleaseReturnValue ARC __weak ivars.
947226633Sdim        if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {
948226633Sdim          value = emitARCRetainLoadOfScalar(*this, LV, ivarType);
949224145Sdim
950226633Sdim        // Otherwise we want to do a simple load, suppressing the
951226633Sdim        // final autorelease.
952224145Sdim        } else {
953263508Sdim          value = EmitLoadOfLValue(LV, SourceLocation()).getScalarVal();
954226633Sdim          AutoreleaseResult = false;
955221345Sdim        }
956224145Sdim
957226633Sdim        value = Builder.CreateBitCast(value, ConvertType(propType));
958239462Sdim        value = Builder.CreateBitCast(value,
959239462Sdim                  ConvertType(GetterMethodDecl->getResultType()));
960226633Sdim      }
961226633Sdim
962226633Sdim      EmitReturnOfRValue(RValue::get(value), propType);
963249423Sdim      return;
964193326Sed    }
965249423Sdim    }
966249423Sdim    llvm_unreachable("bad evaluation kind");
967193326Sed  }
968193326Sed
969226633Sdim  }
970226633Sdim  llvm_unreachable("bad @property implementation strategy!");
971193326Sed}
972193326Sed
973226633Sdim/// emitStructSetterCall - Call the runtime function to store the value
974226633Sdim/// from the first formal parameter into the given ivar.
975226633Sdimstatic void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
976226633Sdim                                 ObjCIvarDecl *ivar) {
977218893Sdim  // objc_copyStruct (&structIvar, &Arg,
978218893Sdim  //                  sizeof (struct something), true, false);
979226633Sdim  CallArgList args;
980226633Sdim
981226633Sdim  // The first argument is the address of the ivar.
982226633Sdim  llvm::Value *ivarAddr = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
983226633Sdim                                                CGF.LoadObjCSelf(), ivar, 0)
984226633Sdim    .getAddress();
985226633Sdim  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
986226633Sdim  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
987226633Sdim
988226633Sdim  // The second argument is the address of the parameter variable.
989226633Sdim  ParmVarDecl *argVar = *OMD->param_begin();
990234353Sdim  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
991234353Sdim                     VK_LValue, SourceLocation());
992226633Sdim  llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
993226633Sdim  argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
994226633Sdim  args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
995226633Sdim
996226633Sdim  // The third argument is the sizeof the type.
997226633Sdim  llvm::Value *size =
998226633Sdim    CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(ivar->getType()));
999226633Sdim  args.add(RValue::get(size), CGF.getContext().getSizeType());
1000226633Sdim
1001226633Sdim  // The fourth argument is the 'isAtomic' flag.
1002226633Sdim  args.add(RValue::get(CGF.Builder.getTrue()), CGF.getContext().BoolTy);
1003226633Sdim
1004226633Sdim  // The fifth argument is the 'hasStrong' flag.
1005226633Sdim  // FIXME: should this really always be false?
1006226633Sdim  args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy);
1007226633Sdim
1008226633Sdim  llvm::Value *copyStructFn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
1009239462Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
1010239462Sdim                                                      args,
1011239462Sdim                                                      FunctionType::ExtInfo(),
1012239462Sdim                                                      RequiredArgs::All),
1013226633Sdim               copyStructFn, ReturnValueSlot(), args);
1014218893Sdim}
1015218893Sdim
1016234353Sdim/// emitCPPObjectAtomicSetterCall - Call the runtime function to store
1017234353Sdim/// the value from the first formal parameter into the given ivar, using
1018234353Sdim/// the Cpp API for atomic Cpp objects with non-trivial copy assignment.
1019234353Sdimstatic void emitCPPObjectAtomicSetterCall(CodeGenFunction &CGF,
1020234353Sdim                                          ObjCMethodDecl *OMD,
1021234353Sdim                                          ObjCIvarDecl *ivar,
1022234353Sdim                                          llvm::Constant *AtomicHelperFn) {
1023234353Sdim  // objc_copyCppObjectAtomic (&CppObjectIvar, &Arg,
1024234353Sdim  //                           AtomicHelperFn);
1025234353Sdim  CallArgList args;
1026234353Sdim
1027234353Sdim  // The first argument is the address of the ivar.
1028234353Sdim  llvm::Value *ivarAddr =
1029234353Sdim    CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
1030234353Sdim                          CGF.LoadObjCSelf(), ivar, 0).getAddress();
1031234353Sdim  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
1032234353Sdim  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
1033234353Sdim
1034234353Sdim  // The second argument is the address of the parameter variable.
1035234353Sdim  ParmVarDecl *argVar = *OMD->param_begin();
1036234353Sdim  DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
1037234353Sdim                     VK_LValue, SourceLocation());
1038234353Sdim  llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
1039234353Sdim  argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
1040234353Sdim  args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
1041234353Sdim
1042234353Sdim  // Third argument is the helper function.
1043234353Sdim  args.add(RValue::get(AtomicHelperFn), CGF.getContext().VoidPtrTy);
1044234353Sdim
1045234353Sdim  llvm::Value *copyCppAtomicObjectFn =
1046249423Sdim    CGF.CGM.getObjCRuntime().GetCppAtomicObjectSetFunction();
1047239462Sdim  CGF.EmitCall(CGF.getTypes().arrangeFreeFunctionCall(CGF.getContext().VoidTy,
1048239462Sdim                                                      args,
1049239462Sdim                                                      FunctionType::ExtInfo(),
1050239462Sdim                                                      RequiredArgs::All),
1051234353Sdim               copyCppAtomicObjectFn, ReturnValueSlot(), args);
1052234353Sdim}
1053234353Sdim
1054234353Sdim
1055226633Sdimstatic bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID) {
1056226633Sdim  Expr *setter = PID->getSetterCXXAssignment();
1057226633Sdim  if (!setter) return true;
1058226633Sdim
1059226633Sdim  // Sema only makes only of these when the ivar has a C++ class type,
1060226633Sdim  // so the form is pretty constrained.
1061226633Sdim
1062226633Sdim  // An operator call is trivial if the function it calls is trivial.
1063226633Sdim  // This also implies that there's nothing non-trivial going on with
1064226633Sdim  // the arguments, because operator= can only be trivial if it's a
1065226633Sdim  // synthesized assignment operator and therefore both parameters are
1066226633Sdim  // references.
1067226633Sdim  if (CallExpr *call = dyn_cast<CallExpr>(setter)) {
1068226633Sdim    if (const FunctionDecl *callee
1069226633Sdim          = dyn_cast_or_null<FunctionDecl>(call->getCalleeDecl()))
1070226633Sdim      if (callee->isTrivial())
1071226633Sdim        return true;
1072226633Sdim    return false;
1073221345Sdim  }
1074226633Sdim
1075226633Sdim  assert(isa<ExprWithCleanups>(setter));
1076226633Sdim  return false;
1077221345Sdim}
1078221345Sdim
1079234353Sdimstatic bool UseOptimizedSetter(CodeGenModule &CGM) {
1080234353Sdim  if (CGM.getLangOpts().getGC() != LangOptions::NonGC)
1081234353Sdim    return false;
1082243830Sdim  return CGM.getLangOpts().ObjCRuntime.hasOptimizedSetter();
1083234353Sdim}
1084234353Sdim
1085226633Sdimvoid
1086226633SdimCodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
1087234353Sdim                                        const ObjCPropertyImplDecl *propImpl,
1088234353Sdim                                        llvm::Constant *AtomicHelperFn) {
1089234353Sdim  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
1090234353Sdim  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
1091234353Sdim  ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
1092234353Sdim
1093226633Sdim  // Just use the setter expression if Sema gave us one and it's
1094234353Sdim  // non-trivial.
1095226633Sdim  if (!hasTrivialSetExpr(propImpl)) {
1096234353Sdim    if (!AtomicHelperFn)
1097234353Sdim      // If non-atomic, assignment is called directly.
1098234353Sdim      EmitStmt(propImpl->getSetterCXXAssignment());
1099234353Sdim    else
1100234353Sdim      // If atomic, assignment is called via a locking api.
1101234353Sdim      emitCPPObjectAtomicSetterCall(*this, setterMethod, ivar,
1102234353Sdim                                    AtomicHelperFn);
1103226633Sdim    return;
1104226633Sdim  }
1105193326Sed
1106226633Sdim  PropertyImplStrategy strategy(CGM, propImpl);
1107226633Sdim  switch (strategy.getKind()) {
1108226633Sdim  case PropertyImplStrategy::Native: {
1109243830Sdim    // We don't need to do anything for a zero-size struct.
1110243830Sdim    if (strategy.getIvarSize().isZero())
1111243830Sdim      return;
1112243830Sdim
1113226633Sdim    llvm::Value *argAddr = LocalDeclMap[*setterMethod->param_begin()];
1114226633Sdim
1115226633Sdim    LValue ivarLValue =
1116226633Sdim      EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, /*quals*/ 0);
1117226633Sdim    llvm::Value *ivarAddr = ivarLValue.getAddress();
1118226633Sdim
1119226633Sdim    // Currently, all atomic accesses have to be through integer
1120226633Sdim    // types, so there's no point in trying to pick a prettier type.
1121226633Sdim    llvm::Type *bitcastType =
1122226633Sdim      llvm::Type::getIntNTy(getLLVMContext(),
1123226633Sdim                            getContext().toBits(strategy.getIvarSize()));
1124226633Sdim    bitcastType = bitcastType->getPointerTo(); // addrspace 0 okay
1125226633Sdim
1126226633Sdim    // Cast both arguments to the chosen operation type.
1127226633Sdim    argAddr = Builder.CreateBitCast(argAddr, bitcastType);
1128226633Sdim    ivarAddr = Builder.CreateBitCast(ivarAddr, bitcastType);
1129226633Sdim
1130226633Sdim    // This bitcast load is likely to cause some nasty IR.
1131226633Sdim    llvm::Value *load = Builder.CreateLoad(argAddr);
1132226633Sdim
1133226633Sdim    // Perform an atomic store.  There are no memory ordering requirements.
1134226633Sdim    llvm::StoreInst *store = Builder.CreateStore(load, ivarAddr);
1135226633Sdim    store->setAlignment(strategy.getIvarAlignment().getQuantity());
1136226633Sdim    store->setAtomic(llvm::Unordered);
1137226633Sdim    return;
1138226633Sdim  }
1139226633Sdim
1140226633Sdim  case PropertyImplStrategy::GetSetProperty:
1141226633Sdim  case PropertyImplStrategy::SetPropertyAndExpressionGet: {
1142234353Sdim
1143234353Sdim    llvm::Value *setOptimizedPropertyFn = 0;
1144234353Sdim    llvm::Value *setPropertyFn = 0;
1145234353Sdim    if (UseOptimizedSetter(CGM)) {
1146243830Sdim      // 10.8 and iOS 6.0 code and GC is off
1147234353Sdim      setOptimizedPropertyFn =
1148234353Sdim        CGM.getObjCRuntime()
1149234353Sdim           .GetOptimizedPropertySetFunction(strategy.isAtomic(),
1150234353Sdim                                            strategy.isCopy());
1151234353Sdim      if (!setOptimizedPropertyFn) {
1152234353Sdim        CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI");
1153234353Sdim        return;
1154234353Sdim      }
1155193326Sed    }
1156234353Sdim    else {
1157234353Sdim      setPropertyFn = CGM.getObjCRuntime().GetPropertySetFunction();
1158234353Sdim      if (!setPropertyFn) {
1159234353Sdim        CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");
1160234353Sdim        return;
1161234353Sdim      }
1162234353Sdim    }
1163234353Sdim
1164198092Srdivacky    // Emit objc_setProperty((id) self, _cmd, offset, arg,
1165193326Sed    //                       <is-atomic>, <is-copy>).
1166226633Sdim    llvm::Value *cmd =
1167226633Sdim      Builder.CreateLoad(LocalDeclMap[setterMethod->getCmdDecl()]);
1168226633Sdim    llvm::Value *self =
1169226633Sdim      Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
1170226633Sdim    llvm::Value *ivarOffset =
1171226633Sdim      EmitIvarOffset(classImpl->getClassInterface(), ivar);
1172226633Sdim    llvm::Value *arg = LocalDeclMap[*setterMethod->param_begin()];
1173226633Sdim    arg = Builder.CreateBitCast(Builder.CreateLoad(arg, "arg"), VoidPtrTy);
1174226633Sdim
1175226633Sdim    CallArgList args;
1176226633Sdim    args.add(RValue::get(self), getContext().getObjCIdType());
1177226633Sdim    args.add(RValue::get(cmd), getContext().getObjCSelType());
1178234353Sdim    if (setOptimizedPropertyFn) {
1179234353Sdim      args.add(RValue::get(arg), getContext().getObjCIdType());
1180234353Sdim      args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
1181239462Sdim      EmitCall(getTypes().arrangeFreeFunctionCall(getContext().VoidTy, args,
1182239462Sdim                                                  FunctionType::ExtInfo(),
1183239462Sdim                                                  RequiredArgs::All),
1184234353Sdim               setOptimizedPropertyFn, ReturnValueSlot(), args);
1185234353Sdim    } else {
1186234353Sdim      args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
1187234353Sdim      args.add(RValue::get(arg), getContext().getObjCIdType());
1188234353Sdim      args.add(RValue::get(Builder.getInt1(strategy.isAtomic())),
1189234353Sdim               getContext().BoolTy);
1190234353Sdim      args.add(RValue::get(Builder.getInt1(strategy.isCopy())),
1191234353Sdim               getContext().BoolTy);
1192234353Sdim      // FIXME: We shouldn't need to get the function info here, the runtime
1193234353Sdim      // already should have computed it to build the function.
1194239462Sdim      EmitCall(getTypes().arrangeFreeFunctionCall(getContext().VoidTy, args,
1195239462Sdim                                                  FunctionType::ExtInfo(),
1196239462Sdim                                                  RequiredArgs::All),
1197234353Sdim               setPropertyFn, ReturnValueSlot(), args);
1198234353Sdim    }
1199234353Sdim
1200226633Sdim    return;
1201226633Sdim  }
1202226633Sdim
1203226633Sdim  case PropertyImplStrategy::CopyStruct:
1204226633Sdim    emitStructSetterCall(*this, setterMethod, ivar);
1205226633Sdim    return;
1206226633Sdim
1207226633Sdim  case PropertyImplStrategy::Expression:
1208226633Sdim    break;
1209226633Sdim  }
1210226633Sdim
1211226633Sdim  // Otherwise, fake up some ASTs and emit a normal assignment.
1212226633Sdim  ValueDecl *selfDecl = setterMethod->getSelfDecl();
1213234353Sdim  DeclRefExpr self(selfDecl, false, selfDecl->getType(),
1214234353Sdim                   VK_LValue, SourceLocation());
1215226633Sdim  ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
1216226633Sdim                            selfDecl->getType(), CK_LValueToRValue, &self,
1217226633Sdim                            VK_RValue);
1218226633Sdim  ObjCIvarRefExpr ivarRef(ivar, ivar->getType().getNonReferenceType(),
1219249423Sdim                          SourceLocation(), SourceLocation(),
1220249423Sdim                          &selfLoad, true, true);
1221226633Sdim
1222226633Sdim  ParmVarDecl *argDecl = *setterMethod->param_begin();
1223226633Sdim  QualType argType = argDecl->getType().getNonReferenceType();
1224234353Sdim  DeclRefExpr arg(argDecl, false, argType, VK_LValue, SourceLocation());
1225226633Sdim  ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
1226226633Sdim                           argType.getUnqualifiedType(), CK_LValueToRValue,
1227226633Sdim                           &arg, VK_RValue);
1228198893Srdivacky
1229226633Sdim  // The property type can differ from the ivar type in some situations with
1230226633Sdim  // Objective-C pointer types, we can always bit cast the RHS in these cases.
1231226633Sdim  // The following absurdity is just to ensure well-formed IR.
1232226633Sdim  CastKind argCK = CK_NoOp;
1233226633Sdim  if (ivarRef.getType()->isObjCObjectPointerType()) {
1234226633Sdim    if (argLoad.getType()->isObjCObjectPointerType())
1235226633Sdim      argCK = CK_BitCast;
1236226633Sdim    else if (argLoad.getType()->isBlockPointerType())
1237226633Sdim      argCK = CK_BlockPointerToObjCPointerCast;
1238226633Sdim    else
1239226633Sdim      argCK = CK_CPointerToObjCPointerCast;
1240226633Sdim  } else if (ivarRef.getType()->isBlockPointerType()) {
1241226633Sdim     if (argLoad.getType()->isBlockPointerType())
1242226633Sdim      argCK = CK_BitCast;
1243226633Sdim    else
1244226633Sdim      argCK = CK_AnyPointerToBlockPointerCast;
1245226633Sdim  } else if (ivarRef.getType()->isPointerType()) {
1246226633Sdim    argCK = CK_BitCast;
1247193326Sed  }
1248226633Sdim  ImplicitCastExpr argCast(ImplicitCastExpr::OnStack,
1249226633Sdim                           ivarRef.getType(), argCK, &argLoad,
1250226633Sdim                           VK_RValue);
1251226633Sdim  Expr *finalArg = &argLoad;
1252226633Sdim  if (!getContext().hasSameUnqualifiedType(ivarRef.getType(),
1253226633Sdim                                           argLoad.getType()))
1254226633Sdim    finalArg = &argCast;
1255193326Sed
1256226633Sdim
1257226633Sdim  BinaryOperator assign(&ivarRef, finalArg, BO_Assign,
1258226633Sdim                        ivarRef.getType(), VK_RValue, OK_Ordinary,
1259243830Sdim                        SourceLocation(), false);
1260226633Sdim  EmitStmt(&assign);
1261226633Sdim}
1262226633Sdim
1263239462Sdim/// \brief Generate an Objective-C property setter function.
1264239462Sdim///
1265239462Sdim/// The given Decl must be an ObjCImplementationDecl. \@synthesize
1266226633Sdim/// is illegal within a category.
1267226633Sdimvoid CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
1268226633Sdim                                         const ObjCPropertyImplDecl *PID) {
1269234353Sdim  llvm::Constant *AtomicHelperFn =
1270234353Sdim    GenerateObjCAtomicSetterCopyHelperFunction(PID);
1271226633Sdim  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
1272226633Sdim  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
1273226633Sdim  assert(OMD && "Invalid call to generate setter (empty method)");
1274234353Sdim  StartObjCMethod(OMD, IMP->getClassInterface(), OMD->getLocStart());
1275226633Sdim
1276234353Sdim  generateObjCSetterBody(IMP, PID, AtomicHelperFn);
1277226633Sdim
1278193326Sed  FinishFunction();
1279193326Sed}
1280193326Sed
1281221345Sdimnamespace {
1282224145Sdim  struct DestroyIvar : EHScopeStack::Cleanup {
1283224145Sdim  private:
1284224145Sdim    llvm::Value *addr;
1285221345Sdim    const ObjCIvarDecl *ivar;
1286234353Sdim    CodeGenFunction::Destroyer *destroyer;
1287224145Sdim    bool useEHCleanupForArray;
1288224145Sdim  public:
1289224145Sdim    DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
1290224145Sdim                CodeGenFunction::Destroyer *destroyer,
1291224145Sdim                bool useEHCleanupForArray)
1292234353Sdim      : 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
1318226633Sdim  const ObjCInterfaceDecl *iface = impl->getClassInterface();
1319226633Sdim  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) {
1332234353Sdim      destroyer = destroyARCStrongWithStore;
1333224145Sdim
1334224145Sdim    // Otherwise use the default for the destruction kind.
1335224145Sdim    } else {
1336234353Sdim      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
1359226633Sdim    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);
1367226633Sdim      EmitAggExpr(IvarInit->getInit(),
1368226633Sdim                  AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed,
1369226633Sdim                                          AggValueSlot::DoesNotNeedGCBarriers,
1370226633Sdim                                          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) {
1395234353Sdim  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() {
1403251662Sdim  VarDecl *Self = cast<ObjCMethodDecl>(CurFuncDecl)->getSelfDecl();
1404251662Sdim  DeclRefExpr DRE(Self, /*is enclosing local*/ (CurFuncDecl != CurCodeDecl),
1405251662Sdim                  Self->getType(), VK_LValue, SourceLocation());
1406263508Sdim  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();
1427226633Sdim  if (DI)
1428226633Sdim    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.
1438226633Sdim  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
1460226633Sdim  // Emit the collection pointer.  In ARC, we do a retain.
1461226633Sdim  llvm::Value *Collection;
1462234353Sdim  if (getLangOpts().ObjCAutoRefCount) {
1463226633Sdim    Collection = EmitARCRetainScalarExpr(S.getCollection());
1464198092Srdivacky
1465226633Sdim    // Enter a cleanup to do the release.
1466226633Sdim    EmitObjCConsumeObject(S.getCollection()->getType(), Collection);
1467226633Sdim  } else {
1468226633Sdim    Collection = EmitScalarExpr(S.getCollection());
1469226633Sdim  }
1470226633Sdim
1471226633Sdim  // The 'continue' label needs to appear within the cleanup for the
1472226633Sdim  // collection object.
1473226633Sdim  JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
1474226633Sdim
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.
1489226633Sdim  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,
1557226633Sdim                          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.
1562239462Sdim  EmitCall(CGM.getTypes().arrangeFreeFunctionCall(getContext().VoidTy, Args2,
1563239462Sdim                                                  FunctionType::ExtInfo(),
1564239462Sdim                                                  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());
1580234353Sdim    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  }
1593226633Sdim  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
1683226633Sdim  if (DI)
1684226633Sdim    DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
1685193326Sed
1686226633Sdim  // Leave the cleanup we entered in ARC.
1687234353Sdim  if (getLangOpts().ObjCAutoRefCount)
1688226633Sdim    PopCleanupBlock();
1689226633Sdim
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
1706226633Sdim/// 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 {
1715226633Sdim    CallObjCRelease(llvm::Value *object) : object(object) {}
1716226633Sdim    llvm::Value *object;
1717224145Sdim
1718224145Sdim    void Emit(CodeGenFunction &CGF, Flags flags) {
1719249423Sdim      // Releases at the end of the full-expression are imprecise.
1720249423Sdim      CGF.EmitARCRelease(object, ARCImpreciseLifetime);
1721224145Sdim    }
1722224145Sdim  };
1723224145Sdim}
1724224145Sdim
1725226633Sdim/// 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
1730226633Sdim  // conditional.
1731226633Sdim  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
1740249423Sdim/// Given a number of pointers, inform the optimizer that they're
1741249423Sdim/// being intrinsically used up until this point in the program.
1742249423Sdimvoid CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) {
1743249423Sdim  llvm::Constant *&fn = CGM.getARCEntrypoints().clang_arc_use;
1744249423Sdim  if (!fn) {
1745249423Sdim    llvm::FunctionType *fnType =
1746249423Sdim      llvm::FunctionType::get(CGM.VoidTy, ArrayRef<llvm::Type*>(), true);
1747249423Sdim    fn = CGM.CreateRuntimeFunction(fnType, "clang.arc.use");
1748249423Sdim  }
1749224145Sdim
1750249423Sdim  // This isn't really a "runtime" function, but as an intrinsic it
1751249423Sdim  // doesn't really matter as long as we align things up.
1752249423Sdim  EmitNounwindRuntimeCall(fn, values);
1753249423Sdim}
1754249423Sdim
1755249423Sdim
1756224145Sdimstatic llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
1757226633Sdim                                                llvm::FunctionType *type,
1758226633Sdim                                                StringRef fnName) {
1759224145Sdim  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
1760224145Sdim
1761239462Sdim  if (llvm::Function *f = dyn_cast<llvm::Function>(fn)) {
1762249423Sdim    // If the target runtime doesn't naturally support ARC, emit weak
1763249423Sdim    // references to the runtime support library.  We don't really
1764249423Sdim    // permit this to fail, but we need a particular relocation style.
1765249423Sdim    if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC()) {
1766224145Sdim      f->setLinkage(llvm::Function::ExternalWeakLinkage);
1767249423Sdim    } else if (fnName == "objc_retain" || fnName  == "objc_release") {
1768249423Sdim      // If we have Native ARC, set nonlazybind attribute for these APIs for
1769249423Sdim      // performance.
1770249423Sdim      f->addFnAttr(llvm::Attribute::NonLazyBind);
1771249423Sdim    }
1772239462Sdim  }
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,
1783249423Sdim                                          StringRef fnName,
1784249423Sdim                                          bool isTailCall = false) {
1785224145Sdim  if (isa<llvm::ConstantPointerNull>(value)) return value;
1786224145Sdim
1787224145Sdim  if (!fn) {
1788226633Sdim    llvm::FunctionType *fnType =
1789249423Sdim      llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrTy, false);
1790224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1791224145Sdim  }
1792224145Sdim
1793224145Sdim  // Cast the argument to 'id'.
1794226633Sdim  llvm::Type *origType = value->getType();
1795224145Sdim  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1796224145Sdim
1797224145Sdim  // Call the function.
1798249423Sdim  llvm::CallInst *call = CGF.EmitNounwindRuntimeCall(fn, value);
1799249423Sdim  if (isTailCall)
1800249423Sdim    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,
1811226633Sdim                                         StringRef fnName) {
1812224145Sdim  if (!fn) {
1813226633Sdim    llvm::FunctionType *fnType =
1814249423Sdim      llvm::FunctionType::get(CGF.Int8PtrTy, CGF.Int8PtrPtrTy, false);
1815224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1816224145Sdim  }
1817224145Sdim
1818224145Sdim  // Cast the argument to 'id*'.
1819226633Sdim  llvm::Type *origType = addr->getType();
1820224145Sdim  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1821224145Sdim
1822224145Sdim  // Call the function.
1823249423Sdim  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,
1839226633Sdim                                          StringRef fnName,
1840224145Sdim                                          bool ignored) {
1841224145Sdim  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1842224145Sdim           == value->getType());
1843224145Sdim
1844224145Sdim  if (!fn) {
1845234353Sdim    llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrTy };
1846224145Sdim
1847226633Sdim    llvm::FunctionType *fnType
1848224145Sdim      = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false);
1849224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1850224145Sdim  }
1851224145Sdim
1852226633Sdim  llvm::Type *origType = value->getType();
1853224145Sdim
1854249423Sdim  llvm::Value *args[] = {
1855249423Sdim    CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy),
1856249423Sdim    CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy)
1857249423Sdim  };
1858249423Sdim  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,
1871226633Sdim                                 StringRef fnName) {
1872224145Sdim  assert(dst->getType() == src->getType());
1873224145Sdim
1874224145Sdim  if (!fn) {
1875249423Sdim    llvm::Type *argTypes[] = { CGF.Int8PtrPtrTy, CGF.Int8PtrPtrTy };
1876249423Sdim
1877226633Sdim    llvm::FunctionType *fnType
1878224145Sdim      = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false);
1879224145Sdim    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1880224145Sdim  }
1881224145Sdim
1882249423Sdim  llvm::Value *args[] = {
1883249423Sdim    CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy),
1884249423Sdim    CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy)
1885249423Sdim  };
1886249423Sdim  CGF.EmitNounwindRuntimeCall(fn, args);
1887224145Sdim}
1888224145Sdim
1889224145Sdim/// Produce the code to do a retain.  Based on the type, calls one of:
1890239462Sdim///   call i8* \@objc_retain(i8* %value)
1891239462Sdim///   call i8* \@objc_retainBlock(i8* %value)
1892224145Sdimllvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {
1893224145Sdim  if (type->isBlockPointerType())
1894226633Sdim    return EmitARCRetainBlock(value, /*mandatory*/ false);
1895224145Sdim  else
1896224145Sdim    return EmitARCRetainNonBlock(value);
1897224145Sdim}
1898224145Sdim
1899224145Sdim/// Retain the given object, with normal retain semantics.
1900239462Sdim///   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.
1908239462Sdim///   call i8* \@objc_retainBlock(i8* %value)
1909226633Sdim///
1910226633Sdim/// \param mandatory - If false, emit the call with metadata
1911226633Sdim/// indicating that it's okay for the optimizer to eliminate this call
1912226633Sdim/// if it can prove that the block never escapes except down the stack.
1913226633Sdimllvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value,
1914226633Sdim                                                 bool mandatory) {
1915226633Sdim  llvm::Value *result
1916226633Sdim    = emitARCValueOperation(*this, value,
1917226633Sdim                            CGM.getARCEntrypoints().objc_retainBlock,
1918226633Sdim                            "objc_retainBlock");
1919226633Sdim
1920226633Sdim  // If the copy isn't mandatory, add !clang.arc.copy_on_escape to
1921226633Sdim  // tell the optimizer that it doesn't need to do this copy if the
1922226633Sdim  // block doesn't escape, where being passed as an argument doesn't
1923226633Sdim  // count as escaping.
1924226633Sdim  if (!mandatory && isa<llvm::Instruction>(result)) {
1925226633Sdim    llvm::CallInst *call
1926226633Sdim      = cast<llvm::CallInst>(result->stripPointerCasts());
1927226633Sdim    assert(call->getCalledValue() == CGM.getARCEntrypoints().objc_retainBlock);
1928226633Sdim
1929226633Sdim    SmallVector<llvm::Value*,1> args;
1930226633Sdim    call->setMetadata("clang.arc.copy_on_escape",
1931226633Sdim                      llvm::MDNode::get(Builder.getContext(), args));
1932226633Sdim  }
1933226633Sdim
1934226633Sdim  return result;
1935224145Sdim}
1936224145Sdim
1937224145Sdim/// Retain the given object which is the result of a function call.
1938239462Sdim///   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) {
1949226633Sdim    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 =
1960234353Sdim        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);
1974226633Sdim        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.
1988239462Sdim///   call void \@objc_release(i8* %value)
1989249423Sdimvoid CodeGenFunction::EmitARCRelease(llvm::Value *value,
1990249423Sdim                                     ARCPreciseLifetime_t precise) {
1991224145Sdim  if (isa<llvm::ConstantPointerNull>(value)) return;
1992224145Sdim
1993224145Sdim  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_release;
1994224145Sdim  if (!fn) {
1995226633Sdim    llvm::FunctionType *fnType =
1996249423Sdim      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.
2004249423Sdim  llvm::CallInst *call = EmitNounwindRuntimeCall(fn, value);
2005224145Sdim
2006249423Sdim  if (precise == ARCImpreciseLifetime) {
2007226633Sdim    SmallVector<llvm::Value*,1> args;
2008224145Sdim    call->setMetadata("clang.imprecise_release",
2009224145Sdim                      llvm::MDNode::get(Builder.getContext(), args));
2010224145Sdim  }
2011224145Sdim}
2012224145Sdim
2013243830Sdim/// Destroy a __strong variable.
2014243830Sdim///
2015243830Sdim/// At -O0, emit a call to store 'null' into the address;
2016243830Sdim/// instrumenting tools prefer this because the address is exposed,
2017243830Sdim/// but it's relatively cumbersome to optimize.
2018243830Sdim///
2019243830Sdim/// At -O1 and above, just load and call objc_release.
2020243830Sdim///
2021243830Sdim///   call void \@objc_storeStrong(i8** %addr, i8* null)
2022249423Sdimvoid CodeGenFunction::EmitARCDestroyStrong(llvm::Value *addr,
2023249423Sdim                                           ARCPreciseLifetime_t precise) {
2024243830Sdim  if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
2025243830Sdim    llvm::PointerType *addrTy = cast<llvm::PointerType>(addr->getType());
2026243830Sdim    llvm::Value *null = llvm::ConstantPointerNull::get(
2027243830Sdim                          cast<llvm::PointerType>(addrTy->getElementType()));
2028243830Sdim    EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
2029243830Sdim    return;
2030243830Sdim  }
2031243830Sdim
2032243830Sdim  llvm::Value *value = Builder.CreateLoad(addr);
2033243830Sdim  EmitARCRelease(value, precise);
2034243830Sdim}
2035243830Sdim
2036224145Sdim/// Store into a strong object.  Always calls this:
2037239462Sdim///   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 };
2047226633Sdim    llvm::FunctionType *fnType
2048224145Sdim      = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false);
2049224145Sdim    fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong");
2050224145Sdim  }
2051224145Sdim
2052249423Sdim  llvm::Value *args[] = {
2053249423Sdim    Builder.CreateBitCast(addr, Int8PtrPtrTy),
2054249423Sdim    Builder.CreateBitCast(value, Int8PtrTy)
2055249423Sdim  };
2056249423Sdim  EmitNounwindRuntimeCall(fn, args);
2057224145Sdim
2058224145Sdim  if (ignored) return 0;
2059224145Sdim  return value;
2060224145Sdim}
2061224145Sdim
2062224145Sdim/// Store into a strong object.  Sometimes calls this:
2063239462Sdim///   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 &&
2075234353Sdim      (dst.getAlignment().isZero() ||
2076234353Sdim       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.
2086263508Sdim  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.
2093249423Sdim  EmitARCRelease(oldValue, dst.isARCPreciseLifetime());
2094224145Sdim
2095224145Sdim  return newValue;
2096224145Sdim}
2097224145Sdim
2098224145Sdim/// Autorelease the given object.
2099239462Sdim///   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.
2107239462Sdim///   call i8* \@objc_autoreleaseReturnValue(i8* %value)
2108224145Sdimllvm::Value *
2109224145SdimCodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
2110224145Sdim  return emitARCValueOperation(*this, value,
2111224145Sdim                            CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
2112249423Sdim                               "objc_autoreleaseReturnValue",
2113249423Sdim                               /*isTailCall*/ true);
2114224145Sdim}
2115224145Sdim
2116224145Sdim/// Do a fused retain/autorelease of the given object.
2117239462Sdim///   call i8* \@objc_retainAutoreleaseReturnValue(i8* %value)
2118224145Sdimllvm::Value *
2119224145SdimCodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
2120224145Sdim  return emitARCValueOperation(*this, value,
2121224145Sdim                     CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
2122249423Sdim                               "objc_retainAutoreleaseReturnValue",
2123249423Sdim                               /*isTailCall*/ true);
2124224145Sdim}
2125224145Sdim
2126224145Sdim/// Do a fused retain/autorelease of the given object.
2127239462Sdim///   call i8* \@objc_retainAutorelease(i8* %value)
2128224145Sdim/// or
2129239462Sdim///   %retain = call i8* \@objc_retainBlock(i8* %value)
2130239462Sdim///   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
2138226633Sdim  llvm::Type *origType = value->getType();
2139224145Sdim  value = Builder.CreateBitCast(value, Int8PtrTy);
2140226633Sdim  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.
2146239462Sdim///   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
2154239462Sdim/// 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
2162239462Sdim/// 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
2169239462Sdim/// 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
2179239462Sdim/// 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
2199239462Sdim/// 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) {
2204226633Sdim    llvm::FunctionType *fnType =
2205249423Sdim      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
2212249423Sdim  EmitNounwindRuntimeCall(fn, addr);
2213224145Sdim}
2214224145Sdim
2215239462Sdim/// 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
2224239462Sdim/// 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.
2234239462Sdim///   call i8* \@objc_autoreleasePoolPush(void)
2235224145Sdimllvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
2236224145Sdim  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPush;
2237224145Sdim  if (!fn) {
2238226633Sdim    llvm::FunctionType *fnType =
2239224145Sdim      llvm::FunctionType::get(Int8PtrTy, false);
2240224145Sdim    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush");
2241224145Sdim  }
2242224145Sdim
2243249423Sdim  return EmitNounwindRuntimeCall(fn);
2244224145Sdim}
2245224145Sdim
2246224145Sdim/// Produce the code to do a primitive release.
2247239462Sdim///   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) {
2253226633Sdim    llvm::FunctionType *fnType =
2254249423Sdim      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
2261251662Sdim  // objc_autoreleasePoolPop can throw.
2262251662Sdim  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();
2272249423Sdim  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) {
2306249423Sdim  CGF.EmitARCDestroyStrong(addr, ARCPreciseLifetime);
2307224145Sdim}
2308224145Sdim
2309224145Sdimvoid CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
2310224145Sdim                                                llvm::Value *addr,
2311224145Sdim                                                QualType type) {
2312249423Sdim  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) {
2343234353Sdim  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:
2357263508Sdim    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue,
2358263508Sdim                                              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
2374226633Sdim  // If we're loading retained from a __strong xvalue, we can avoid
2375226633Sdim  // an extra retain/release pair by zeroing out the source of this
2376226633Sdim  // "move" operation.
2377226633Sdim  if (e->isXValue() &&
2378226633Sdim      !type.isConstQualified() &&
2379226633Sdim      type.getObjCLifetime() == Qualifiers::OCL_Strong) {
2380226633Sdim    // Emit the lvalue.
2381226633Sdim    LValue lv = CGF.EmitLValue(e);
2382226633Sdim
2383226633Sdim    // Load the object pointer.
2384263508Sdim    llvm::Value *result = CGF.EmitLoadOfLValue(lv,
2385263508Sdim                                               SourceLocation()).getScalarVal();
2386226633Sdim
2387226633Sdim    // Set the source pointer to NULL.
2388226633Sdim    CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress()), lv);
2389226633Sdim
2390226633Sdim    return TryEmitResult(result, true);
2391226633Sdim  }
2392226633Sdim
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.
2396234353Sdim  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
2455226633Sdim/// Determine whether it might be important to emit a separate
2456226633Sdim/// objc_retain_block on the result of the given expression, or
2457226633Sdim/// whether it's okay to just emit it in a +1 context.
2458226633Sdimstatic bool shouldEmitSeparateBlockRetain(const Expr *e) {
2459226633Sdim  assert(e->getType()->isBlockPointerType());
2460226633Sdim  e = e->IgnoreParens();
2461226633Sdim
2462226633Sdim  // For future goodness, emit block expressions directly in +1
2463226633Sdim  // contexts if we can.
2464226633Sdim  if (isa<BlockExpr>(e))
2465226633Sdim    return false;
2466226633Sdim
2467226633Sdim  if (const CastExpr *cast = dyn_cast<CastExpr>(e)) {
2468226633Sdim    switch (cast->getCastKind()) {
2469226633Sdim    // Emitting these operations in +1 contexts is goodness.
2470226633Sdim    case CK_LValueToRValue:
2471226633Sdim    case CK_ARCReclaimReturnedObject:
2472226633Sdim    case CK_ARCConsumeObject:
2473226633Sdim    case CK_ARCProduceObject:
2474226633Sdim      return false;
2475226633Sdim
2476226633Sdim    // These operations preserve a block type.
2477226633Sdim    case CK_NoOp:
2478226633Sdim    case CK_BitCast:
2479226633Sdim      return shouldEmitSeparateBlockRetain(cast->getSubExpr());
2480226633Sdim
2481226633Sdim    // These operations are known to be bad (or haven't been considered).
2482226633Sdim    case CK_AnyPointerToBlockPointerCast:
2483226633Sdim    default:
2484226633Sdim      return true;
2485226633Sdim    }
2486226633Sdim  }
2487226633Sdim
2488226633Sdim  return true;
2489226633Sdim}
2490226633Sdim
2491234353Sdim/// Try to emit a PseudoObjectExpr at +1.
2492234353Sdim///
2493234353Sdim/// This massively duplicates emitPseudoObjectRValue.
2494234353Sdimstatic TryEmitResult tryEmitARCRetainPseudoObject(CodeGenFunction &CGF,
2495234353Sdim                                                  const PseudoObjectExpr *E) {
2496249423Sdim  SmallVector<CodeGenFunction::OpaqueValueMappingData, 4> opaques;
2497234353Sdim
2498234353Sdim  // Find the result expression.
2499234353Sdim  const Expr *resultExpr = E->getResultExpr();
2500234353Sdim  assert(resultExpr);
2501234353Sdim  TryEmitResult result;
2502234353Sdim
2503234353Sdim  for (PseudoObjectExpr::const_semantics_iterator
2504234353Sdim         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
2505234353Sdim    const Expr *semantic = *i;
2506234353Sdim
2507234353Sdim    // If this semantic expression is an opaque value, bind it
2508234353Sdim    // to the result of its source expression.
2509234353Sdim    if (const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
2510234353Sdim      typedef CodeGenFunction::OpaqueValueMappingData OVMA;
2511234353Sdim      OVMA opaqueData;
2512234353Sdim
2513234353Sdim      // If this semantic is the result of the pseudo-object
2514234353Sdim      // expression, try to evaluate the source as +1.
2515234353Sdim      if (ov == resultExpr) {
2516234353Sdim        assert(!OVMA::shouldBindAsLValue(ov));
2517234353Sdim        result = tryEmitARCRetainScalarExpr(CGF, ov->getSourceExpr());
2518234353Sdim        opaqueData = OVMA::bind(CGF, ov, RValue::get(result.getPointer()));
2519234353Sdim
2520234353Sdim      // Otherwise, just bind it.
2521234353Sdim      } else {
2522234353Sdim        opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
2523234353Sdim      }
2524234353Sdim      opaques.push_back(opaqueData);
2525234353Sdim
2526234353Sdim    // Otherwise, if the expression is the result, evaluate it
2527234353Sdim    // and remember the result.
2528234353Sdim    } else if (semantic == resultExpr) {
2529234353Sdim      result = tryEmitARCRetainScalarExpr(CGF, semantic);
2530234353Sdim
2531234353Sdim    // Otherwise, evaluate the expression in an ignored context.
2532234353Sdim    } else {
2533234353Sdim      CGF.EmitIgnoredExpr(semantic);
2534234353Sdim    }
2535234353Sdim  }
2536234353Sdim
2537234353Sdim  // Unbind all the opaques now.
2538234353Sdim  for (unsigned i = 0, e = opaques.size(); i != e; ++i)
2539234353Sdim    opaques[i].unbind(CGF);
2540234353Sdim
2541234353Sdim  return result;
2542234353Sdim}
2543234353Sdim
2544224145Sdimstatic TryEmitResult
2545224145SdimtryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
2546249423Sdim  // We should *never* see a nested full-expression here, because if
2547249423Sdim  // we fail to emit at +1, our caller must not retain after we close
2548249423Sdim  // out the full-expression.
2549249423Sdim  assert(!isa<ExprWithCleanups>(e));
2550226633Sdim
2551224145Sdim  // The desired result type, if it differs from the type of the
2552224145Sdim  // ultimate opaque expression.
2553226633Sdim  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.
2581226633Sdim      case CK_CPointerToObjCPointerCast:
2582226633Sdim      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.
2593226633Sdim      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
2599226633Sdim      // Block extends are net +0.  Naively, we could just recurse on
2600226633Sdim      // the subexpression, but actually we need to ensure that the
2601226633Sdim      // value is copied as a block, so there's a little filter here.
2602226633Sdim      case CK_ARCExtendBlockObject: {
2603226633Sdim        llvm::Value *result; // will be a +0 value
2604226633Sdim
2605226633Sdim        // If we can't safely assume the sub-expression will produce a
2606226633Sdim        // block-copied value, emit the sub-expression at +0.
2607226633Sdim        if (shouldEmitSeparateBlockRetain(ce->getSubExpr())) {
2608226633Sdim          result = CGF.EmitScalarExpr(ce->getSubExpr());
2609226633Sdim
2610226633Sdim        // Otherwise, try to emit the sub-expression at +1 recursively.
2611226633Sdim        } else {
2612226633Sdim          TryEmitResult subresult
2613226633Sdim            = tryEmitARCRetainScalarExpr(CGF, ce->getSubExpr());
2614226633Sdim          result = subresult.getPointer();
2615226633Sdim
2616226633Sdim          // If that produced a retained value, just use that,
2617226633Sdim          // possibly casting down.
2618226633Sdim          if (subresult.getInt()) {
2619226633Sdim            if (resultType)
2620226633Sdim              result = CGF.Builder.CreateBitCast(result, resultType);
2621226633Sdim            return TryEmitResult(result, true);
2622226633Sdim          }
2623226633Sdim
2624226633Sdim          // Otherwise it's +0.
2625226633Sdim        }
2626226633Sdim
2627226633Sdim        // Retain the object as a block, then cast down.
2628226633Sdim        result = CGF.EmitARCRetainBlock(result, /*mandatory*/ true);
2629226633Sdim        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2630226633Sdim        return TryEmitResult(result, true);
2631226633Sdim      }
2632226633Sdim
2633224145Sdim      // For reclaims, emit the subexpression as a retained call and
2634224145Sdim      // skip the consumption.
2635226633Sdim      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);
2662234353Sdim
2663234353Sdim    // Look through pseudo-object expressions.
2664234353Sdim    } else if (const PseudoObjectExpr *pseudo = dyn_cast<PseudoObjectExpr>(e)) {
2665234353Sdim      TryEmitResult result
2666234353Sdim        = tryEmitARCRetainPseudoObject(CGF, pseudo);
2667234353Sdim      if (resultType) {
2668234353Sdim        llvm::Value *value = result.getPointer();
2669234353Sdim        value = CGF.Builder.CreateBitCast(value, resultType);
2670234353Sdim        result.setPointer(value);
2671234353Sdim      }
2672234353Sdim      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) {
2701249423Sdim  // The retain needs to happen within the full-expression.
2702249423Sdim  if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
2703249423Sdim    enterFullExpression(cleanups);
2704249423Sdim    RunCleanupsScope scope(*this);
2705249423Sdim    return EmitARCRetainScalarExpr(cleanups->getSubExpr());
2706249423Sdim  }
2707249423Sdim
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) {
2717249423Sdim  // The retain needs to happen within the full-expression.
2718249423Sdim  if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
2719249423Sdim    enterFullExpression(cleanups);
2720249423Sdim    RunCleanupsScope scope(*this);
2721249423Sdim    return EmitARCRetainAutoreleaseScalarExpr(cleanups->getSubExpr());
2722249423Sdim  }
2723249423Sdim
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
2733226633Sdimllvm::Value *CodeGenFunction::EmitARCExtendBlockObject(const Expr *e) {
2734226633Sdim  llvm::Value *result;
2735226633Sdim  bool doRetain;
2736226633Sdim
2737226633Sdim  if (shouldEmitSeparateBlockRetain(e)) {
2738226633Sdim    result = EmitScalarExpr(e);
2739226633Sdim    doRetain = true;
2740226633Sdim  } else {
2741226633Sdim    TryEmitResult subresult = tryEmitARCRetainScalarExpr(*this, e);
2742226633Sdim    result = subresult.getPointer();
2743226633Sdim    doRetain = !subresult.getInt();
2744226633Sdim  }
2745226633Sdim
2746226633Sdim  if (doRetain)
2747226633Sdim    result = EmitARCRetainBlock(result, /*mandatory*/ true);
2748226633Sdim  return EmitObjCConsumeObject(e->getType(), result);
2749226633Sdim}
2750226633Sdim
2751226633Sdimllvm::Value *CodeGenFunction::EmitObjCThrowOperand(const Expr *expr) {
2752226633Sdim  // In ARC, retain and autorelease the expression.
2753234353Sdim  if (getLangOpts().ObjCAutoRefCount) {
2754226633Sdim    // Do so before running any cleanups for the full-expression.
2755249423Sdim    // EmitARCRetainAutoreleaseScalarExpr does this for us.
2756226633Sdim    return EmitARCRetainAutoreleaseScalarExpr(expr);
2757226633Sdim  }
2758226633Sdim
2759226633Sdim  // Otherwise, use the normal scalar-expression emission.  The
2760226633Sdim  // exception machinery doesn't do anything special with the
2761226633Sdim  // exception like retaining it, so there's no safety associated with
2762226633Sdim  // only running cleanups after the throw has started, and when it
2763226633Sdim  // matters it tends to be substantially inferior code.
2764226633Sdim  return EmitScalarExpr(expr);
2765226633Sdim}
2766226633Sdim
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
2774226633Sdim  bool hasImmediateRetain = result.getInt();
2775226633Sdim
2776226633Sdim  // If we didn't emit a retained object, and the l-value is of block
2777226633Sdim  // type, then we need to emit the block-retain immediately in case
2778226633Sdim  // it invalidates the l-value.
2779226633Sdim  if (!hasImmediateRetain && e->getType()->isBlockPointerType()) {
2780226633Sdim    value = EmitARCRetainBlock(value, /*mandatory*/ false);
2781226633Sdim    hasImmediateRetain = true;
2782226633Sdim  }
2783226633Sdim
2784224145Sdim  LValue lvalue = EmitLValue(e->getLHS());
2785224145Sdim
2786224145Sdim  // If the RHS was emitted retained, expand this.
2787226633Sdim  if (hasImmediateRetain) {
2788263508Sdim    llvm::Value *oldValue = EmitLoadOfScalar(lvalue, SourceLocation());
2789234353Sdim    EmitStoreOfScalar(value, lvalue);
2790249423Sdim    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
2803234353Sdim  EmitStoreOfScalar(value, lvalue);
2804224145Sdim
2805224145Sdim  return std::pair<LValue,llvm::Value*>(lvalue, value);
2806224145Sdim}
2807224145Sdim
2808224145Sdimvoid CodeGenFunction::EmitObjCAutoreleasePoolStmt(
2809234353Sdim                                          const ObjCAutoreleasePoolStmt &ARPS) {
2810224145Sdim  const Stmt *subStmt = ARPS.getSubStmt();
2811224145Sdim  const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
2812224145Sdim
2813224145Sdim  CGDebugInfo *DI = getDebugInfo();
2814226633Sdim  if (DI)
2815226633Sdim    DI->EmitLexicalBlockStart(Builder, S.getLBracLoc());
2816224145Sdim
2817224145Sdim  // Keep track of the current cleanup stack depth.
2818224145Sdim  RunCleanupsScope Scope(*this);
2819243830Sdim  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
2831226633Sdim  if (DI)
2832226633Sdim    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
2840234353Sdim    = 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);
2848249423Sdim  EmitNounwindRuntimeCall(extender, object);
2849224145Sdim}
2850224145Sdim
2851234353Sdim/// GenerateObjCAtomicSetterCopyHelperFunction - Given a c++ object type with
2852234353Sdim/// non-trivial copy assignment function, produce following helper function.
2853234353Sdim/// static void copyHelper(Ty *dest, const Ty *source) { *dest = *source; }
2854234353Sdim///
2855234353Sdimllvm::Constant *
2856234353SdimCodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
2857234353Sdim                                        const ObjCPropertyImplDecl *PID) {
2858239462Sdim  if (!getLangOpts().CPlusPlus ||
2859249423Sdim      !getLangOpts().ObjCRuntime.hasAtomicCopyHelper())
2860234353Sdim    return 0;
2861234353Sdim  QualType Ty = PID->getPropertyIvarDecl()->getType();
2862234353Sdim  if (!Ty->isRecordType())
2863234353Sdim    return 0;
2864234353Sdim  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
2865234353Sdim  if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
2866234353Sdim    return 0;
2867234353Sdim  llvm::Constant * HelperFn = 0;
2868234353Sdim  if (hasTrivialSetExpr(PID))
2869234353Sdim    return 0;
2870234353Sdim  assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null");
2871234353Sdim  if ((HelperFn = CGM.getAtomicSetterHelperFnMap(Ty)))
2872234353Sdim    return HelperFn;
2873234353Sdim
2874234353Sdim  ASTContext &C = getContext();
2875234353Sdim  IdentifierInfo *II
2876234353Sdim    = &CGM.getContext().Idents.get("__assign_helper_atomic_property_");
2877234353Sdim  FunctionDecl *FD = FunctionDecl::Create(C,
2878234353Sdim                                          C.getTranslationUnitDecl(),
2879234353Sdim                                          SourceLocation(),
2880234353Sdim                                          SourceLocation(), II, C.VoidTy, 0,
2881234353Sdim                                          SC_Static,
2882234353Sdim                                          false,
2883234353Sdim                                          false);
2884234353Sdim
2885234353Sdim  QualType DestTy = C.getPointerType(Ty);
2886234353Sdim  QualType SrcTy = Ty;
2887234353Sdim  SrcTy.addConst();
2888234353Sdim  SrcTy = C.getPointerType(SrcTy);
2889234353Sdim
2890234353Sdim  FunctionArgList args;
2891234353Sdim  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
2892234353Sdim  args.push_back(&dstDecl);
2893234353Sdim  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
2894234353Sdim  args.push_back(&srcDecl);
2895234353Sdim
2896234353Sdim  const CGFunctionInfo &FI =
2897234353Sdim    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
2898234353Sdim                                              FunctionType::ExtInfo(),
2899234353Sdim                                              RequiredArgs::All);
2900234353Sdim
2901234353Sdim  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
2902234353Sdim
2903234353Sdim  llvm::Function *Fn =
2904234353Sdim    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
2905234353Sdim                           "__assign_helper_atomic_property_",
2906234353Sdim                           &CGM.getModule());
2907234353Sdim
2908234353Sdim  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
2909234353Sdim
2910234353Sdim  DeclRefExpr DstExpr(&dstDecl, false, DestTy,
2911234353Sdim                      VK_RValue, SourceLocation());
2912234353Sdim  UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(),
2913234353Sdim                    VK_LValue, OK_Ordinary, SourceLocation());
2914234353Sdim
2915234353Sdim  DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
2916234353Sdim                      VK_RValue, SourceLocation());
2917234353Sdim  UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
2918234353Sdim                    VK_LValue, OK_Ordinary, SourceLocation());
2919234353Sdim
2920234353Sdim  Expr *Args[2] = { &DST, &SRC };
2921234353Sdim  CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
2922234353Sdim  CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
2923243830Sdim                              Args, DestTy->getPointeeType(),
2924243830Sdim                              VK_LValue, SourceLocation(), false);
2925234353Sdim
2926234353Sdim  EmitStmt(&TheCall);
2927234353Sdim
2928234353Sdim  FinishFunction();
2929234353Sdim  HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
2930234353Sdim  CGM.setAtomicSetterHelperFnMap(Ty, HelperFn);
2931234353Sdim  return HelperFn;
2932234353Sdim}
2933234353Sdim
2934234353Sdimllvm::Constant *
2935234353SdimCodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
2936234353Sdim                                            const ObjCPropertyImplDecl *PID) {
2937239462Sdim  if (!getLangOpts().CPlusPlus ||
2938249423Sdim      !getLangOpts().ObjCRuntime.hasAtomicCopyHelper())
2939234353Sdim    return 0;
2940234353Sdim  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
2941234353Sdim  QualType Ty = PD->getType();
2942234353Sdim  if (!Ty->isRecordType())
2943234353Sdim    return 0;
2944234353Sdim  if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
2945234353Sdim    return 0;
2946234353Sdim  llvm::Constant * HelperFn = 0;
2947234353Sdim
2948234353Sdim  if (hasTrivialGetExpr(PID))
2949234353Sdim    return 0;
2950234353Sdim  assert(PID->getGetterCXXConstructor() && "getGetterCXXConstructor - null");
2951234353Sdim  if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty)))
2952234353Sdim    return HelperFn;
2953234353Sdim
2954234353Sdim
2955234353Sdim  ASTContext &C = getContext();
2956234353Sdim  IdentifierInfo *II
2957234353Sdim  = &CGM.getContext().Idents.get("__copy_helper_atomic_property_");
2958234353Sdim  FunctionDecl *FD = FunctionDecl::Create(C,
2959234353Sdim                                          C.getTranslationUnitDecl(),
2960234353Sdim                                          SourceLocation(),
2961234353Sdim                                          SourceLocation(), II, C.VoidTy, 0,
2962234353Sdim                                          SC_Static,
2963234353Sdim                                          false,
2964234353Sdim                                          false);
2965234353Sdim
2966234353Sdim  QualType DestTy = C.getPointerType(Ty);
2967234353Sdim  QualType SrcTy = Ty;
2968234353Sdim  SrcTy.addConst();
2969234353Sdim  SrcTy = C.getPointerType(SrcTy);
2970234353Sdim
2971234353Sdim  FunctionArgList args;
2972234353Sdim  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
2973234353Sdim  args.push_back(&dstDecl);
2974234353Sdim  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
2975234353Sdim  args.push_back(&srcDecl);
2976234353Sdim
2977234353Sdim  const CGFunctionInfo &FI =
2978234353Sdim  CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
2979234353Sdim                                            FunctionType::ExtInfo(),
2980234353Sdim                                            RequiredArgs::All);
2981234353Sdim
2982234353Sdim  llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
2983234353Sdim
2984234353Sdim  llvm::Function *Fn =
2985234353Sdim  llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
2986234353Sdim                         "__copy_helper_atomic_property_", &CGM.getModule());
2987234353Sdim
2988234353Sdim  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
2989234353Sdim
2990234353Sdim  DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
2991234353Sdim                      VK_RValue, SourceLocation());
2992234353Sdim
2993234353Sdim  UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
2994234353Sdim                    VK_LValue, OK_Ordinary, SourceLocation());
2995234353Sdim
2996234353Sdim  CXXConstructExpr *CXXConstExpr =
2997234353Sdim    cast<CXXConstructExpr>(PID->getGetterCXXConstructor());
2998234353Sdim
2999234353Sdim  SmallVector<Expr*, 4> ConstructorArgs;
3000234353Sdim  ConstructorArgs.push_back(&SRC);
3001234353Sdim  CXXConstructExpr::arg_iterator A = CXXConstExpr->arg_begin();
3002234353Sdim  ++A;
3003234353Sdim
3004234353Sdim  for (CXXConstructExpr::arg_iterator AEnd = CXXConstExpr->arg_end();
3005234353Sdim       A != AEnd; ++A)
3006234353Sdim    ConstructorArgs.push_back(*A);
3007234353Sdim
3008234353Sdim  CXXConstructExpr *TheCXXConstructExpr =
3009234353Sdim    CXXConstructExpr::Create(C, Ty, SourceLocation(),
3010234353Sdim                             CXXConstExpr->getConstructor(),
3011234353Sdim                             CXXConstExpr->isElidable(),
3012243830Sdim                             ConstructorArgs,
3013234353Sdim                             CXXConstExpr->hadMultipleCandidates(),
3014234353Sdim                             CXXConstExpr->isListInitialization(),
3015234353Sdim                             CXXConstExpr->requiresZeroInitialization(),
3016234353Sdim                             CXXConstExpr->getConstructionKind(),
3017234353Sdim                             SourceRange());
3018234353Sdim
3019234353Sdim  DeclRefExpr DstExpr(&dstDecl, false, DestTy,
3020234353Sdim                      VK_RValue, SourceLocation());
3021234353Sdim
3022234353Sdim  RValue DV = EmitAnyExpr(&DstExpr);
3023234353Sdim  CharUnits Alignment
3024234353Sdim    = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType());
3025234353Sdim  EmitAggExpr(TheCXXConstructExpr,
3026234353Sdim              AggValueSlot::forAddr(DV.getScalarVal(), Alignment, Qualifiers(),
3027234353Sdim                                    AggValueSlot::IsDestructed,
3028234353Sdim                                    AggValueSlot::DoesNotNeedGCBarriers,
3029234353Sdim                                    AggValueSlot::IsNotAliased));
3030234353Sdim
3031234353Sdim  FinishFunction();
3032234353Sdim  HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
3033234353Sdim  CGM.setAtomicGetterHelperFnMap(Ty, HelperFn);
3034234353Sdim  return HelperFn;
3035234353Sdim}
3036234353Sdim
3037234353Sdimllvm::Value *
3038234353SdimCodeGenFunction::EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty) {
3039234353Sdim  // Get selectors for retain/autorelease.
3040234353Sdim  IdentifierInfo *CopyID = &getContext().Idents.get("copy");
3041234353Sdim  Selector CopySelector =
3042234353Sdim      getContext().Selectors.getNullarySelector(CopyID);
3043234353Sdim  IdentifierInfo *AutoreleaseID = &getContext().Idents.get("autorelease");
3044234353Sdim  Selector AutoreleaseSelector =
3045234353Sdim      getContext().Selectors.getNullarySelector(AutoreleaseID);
3046234353Sdim
3047234353Sdim  // Emit calls to retain/autorelease.
3048234353Sdim  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
3049234353Sdim  llvm::Value *Val = Block;
3050234353Sdim  RValue Result;
3051234353Sdim  Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
3052234353Sdim                                       Ty, CopySelector,
3053234353Sdim                                       Val, CallArgList(), 0, 0);
3054234353Sdim  Val = Result.getScalarVal();
3055234353Sdim  Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
3056234353Sdim                                       Ty, AutoreleaseSelector,
3057234353Sdim                                       Val, CallArgList(), 0, 0);
3058234353Sdim  Val = Result.getScalarVal();
3059234353Sdim  return Val;
3060234353Sdim}
3061234353Sdim
3062234353Sdim
3063193326SedCGObjCRuntime::~CGObjCRuntime() {}
3064