CGObjC.cpp revision 71c758d3f4ecc8b511e6ae4a7210486aa994c182
15508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
25508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//
35508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//                     The LLVM Compiler Infrastructure
45508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//
85508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//===----------------------------------------------------------------------===//
95508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//
105508518a2702b00be3b15a26d772bde968972f54Anders Carlsson// This contains code to emit Objective-C code as LLVM code.
115508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//
125508518a2702b00be3b15a26d772bde968972f54Anders Carlsson//===----------------------------------------------------------------------===//
135508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
14bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel#include "CGDebugInfo.h"
152979ec73b4f974d85f2ce84167712177a44c6f09Ted Kremenek#include "CGObjCRuntime.h"
165508518a2702b00be3b15a26d772bde968972f54Anders Carlsson#include "CodeGenFunction.h"
175508518a2702b00be3b15a26d772bde968972f54Anders Carlsson#include "CodeGenModule.h"
18f85e193739c953358c865005855253af4f68a497John McCall#include "TargetInfo.h"
1985c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar#include "clang/AST/ASTContext.h"
20c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/DeclObjC.h"
2116f0049415ec596504891259e2a83e19871c0d52Chris Lattner#include "clang/AST/StmtObjC.h"
22e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar#include "clang/Basic/Diagnostic.h"
233d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson#include "llvm/ADT/STLExtras.h"
24c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar#include "llvm/Target/TargetData.h"
25f85e193739c953358c865005855253af4f68a497John McCall#include "llvm/InlineAsm.h"
265508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace clang;
275508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace CodeGen;
285508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
29f85e193739c953358c865005855253af4f68a497John McCalltypedef llvm::PointerIntPair<llvm::Value*,1,bool> TryEmitResult;
30f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult
31f85e193739c953358c865005855253af4f68a497John McCalltryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e);
32f85e193739c953358c865005855253af4f68a497John McCall
33f85e193739c953358c865005855253af4f68a497John McCall/// Given the address of a variable of pointer type, find the correct
34f85e193739c953358c865005855253af4f68a497John McCall/// null to store into it.
35f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Constant *getNullForVariable(llvm::Value *addr) {
362acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *type =
37f85e193739c953358c865005855253af4f68a497John McCall    cast<llvm::PointerType>(addr->getType())->getElementType();
38f85e193739c953358c865005855253af4f68a497John McCall  return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(type));
39f85e193739c953358c865005855253af4f68a497John McCall}
40f85e193739c953358c865005855253af4f68a497John McCall
418fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emits an instance of NSConstantString representing the object.
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
4371fcec9abf2ce66d5e17a24bd021680e94e42f0dDaniel Dunbar{
440d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall  llvm::Constant *C =
450d13f6fdbdd6f06e2449b8834dda53334abd399aDavid Chisnall      CGM.getObjCRuntime().GenerateConstantString(E->getString());
46ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar  // FIXME: This bitcast should just be made an invariant on the Runtime.
473c4972def972f8ca44dcd0561779a12aaa6fec97Owen Anderson  return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
488fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
498fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
508fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emit a selector.
518fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattnerllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
528fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Untyped selector.
538fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Note that this implementation allows for non-constant strings to be passed
548fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // as arguments to @selector().  Currently, the only thing preventing this
558fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // behaviour is the type checking in the front end.
566d5a1c28593443f3973ef38f8fa042d59182412dDaniel Dunbar  return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
578fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
588fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
59ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbarllvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
60ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar  // FIXME: This should pass the Decl not the name.
61ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar  return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol());
62ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar}
638fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
64926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// \brief Adjust the type of the result of an Objective-C message send
65926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor/// expression when the method has a related result type.
66926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregorstatic RValue AdjustRelatedResultType(CodeGenFunction &CGF,
67926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                      const Expr *E,
68926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                      const ObjCMethodDecl *Method,
69926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                      RValue Result) {
70926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (!Method)
71926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return Result;
72f85e193739c953358c865005855253af4f68a497John McCall
73926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  if (!Method->hasRelatedResultType() ||
74926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      CGF.getContext().hasSameType(E->getType(), Method->getResultType()) ||
75926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor      !Result.isScalar())
76926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return Result;
77926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor
78926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  // We have applied a related result type. Cast the rvalue appropriately.
79926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return RValue::get(CGF.Builder.CreateBitCast(Result.getScalarVal(),
80926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                               CGF.ConvertType(E->getType())));
81926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor}
828fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
83dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall/// Decide whether to extend the lifetime of the receiver of a
84dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall/// returns-inner-pointer message.
85dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallstatic bool
86dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCallshouldExtendReceiverForInnerPointerMessage(const ObjCMessageExpr *message) {
87dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  switch (message->getReceiverKind()) {
88dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
89dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // For a normal instance message, we should extend unless the
90dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // receiver is loaded from a variable with precise lifetime.
91dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case ObjCMessageExpr::Instance: {
92dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    const Expr *receiver = message->getInstanceReceiver();
93dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    const ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(receiver);
94dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    if (!ice || ice->getCastKind() != CK_LValueToRValue) return true;
95dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    receiver = ice->getSubExpr()->IgnoreParens();
96dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
97dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Only __strong variables.
98dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    if (receiver->getType().getObjCLifetime() != Qualifiers::OCL_Strong)
99dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      return true;
100dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
101dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // All ivars and fields have precise lifetime.
102dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    if (isa<MemberExpr>(receiver) || isa<ObjCIvarRefExpr>(receiver))
103dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      return false;
104dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
105dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // Otherwise, check for variables.
106dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    const DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(ice->getSubExpr());
107dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    if (!declRef) return true;
108dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    const VarDecl *var = dyn_cast<VarDecl>(declRef->getDecl());
109dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    if (!var) return true;
110dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
111dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // All variables have precise lifetime except local variables with
112dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // automatic storage duration that aren't specially marked.
113dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return (var->hasLocalStorage() &&
114dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall            !var->hasAttr<ObjCPreciseLifetimeAttr>());
115dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
116dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
117dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case ObjCMessageExpr::Class:
118dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case ObjCMessageExpr::SuperClass:
119dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // It's never necessary for class objects.
120dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return false;
121dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
122dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  case ObjCMessageExpr::SuperInstance:
123dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    // We generally assume that 'self' lives throughout a method call.
124dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    return false;
125dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  }
126dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
127dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  llvm_unreachable("invalid receiver kind");
128dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall}
129dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
130ef072fd2f3347cfd857d6eb787b245b950771430John McCallRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
131ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                            ReturnValueSlot Return) {
1328fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Only the lookup mechanism and first two arguments of the method
1338fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // implementation vary between runtimes.  We can get the receiver and
1348fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // arguments in generic code.
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
136f85e193739c953358c865005855253af4f68a497John McCall  bool isDelegateInit = E->isDelegateInitCall();
137f85e193739c953358c865005855253af4f68a497John McCall
138dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  const ObjCMethodDecl *method = E->getMethodDecl();
139dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
140f85e193739c953358c865005855253af4f68a497John McCall  // We don't retain the receiver in delegate init calls, and this is
141f85e193739c953358c865005855253af4f68a497John McCall  // safe because the receiver value is always loaded from 'self',
142f85e193739c953358c865005855253af4f68a497John McCall  // which we zero out.  We don't want to Block_copy block receivers,
143f85e193739c953358c865005855253af4f68a497John McCall  // though.
144f85e193739c953358c865005855253af4f68a497John McCall  bool retainSelf =
145f85e193739c953358c865005855253af4f68a497John McCall    (!isDelegateInit &&
146f85e193739c953358c865005855253af4f68a497John McCall     CGM.getLangOptions().ObjCAutoRefCount &&
147dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall     method &&
148dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall     method->hasAttr<NSConsumesSelfAttr>());
149f85e193739c953358c865005855253af4f68a497John McCall
150208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
1518fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  bool isSuperMessage = false;
152f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  bool isClassMessage = false;
153c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall  ObjCInterfaceDecl *OID = 0;
1548fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Find the receiver
155926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  QualType ReceiverType;
1560b647a6ea18151149d624ab373e6fe0e819e4a9aDaniel Dunbar  llvm::Value *Receiver = 0;
15704badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  switch (E->getReceiverKind()) {
15804badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::Instance:
159926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getInstanceReceiver()->getType();
160f85e193739c953358c865005855253af4f68a497John McCall    if (retainSelf) {
161f85e193739c953358c865005855253af4f68a497John McCall      TryEmitResult ter = tryEmitARCRetainScalarExpr(*this,
162f85e193739c953358c865005855253af4f68a497John McCall                                                   E->getInstanceReceiver());
163f85e193739c953358c865005855253af4f68a497John McCall      Receiver = ter.getPointer();
164dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      if (ter.getInt()) retainSelf = false;
165f85e193739c953358c865005855253af4f68a497John McCall    } else
166f85e193739c953358c865005855253af4f68a497John McCall      Receiver = EmitScalarExpr(E->getInstanceReceiver());
16704badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16904badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::Class: {
170926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getClassReceiver();
171926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    const ObjCObjectType *ObjTy = ReceiverType->getAs<ObjCObjectType>();
1723031c63f7b5b09d5f64609fa7a1922a05b520fa7John McCall    assert(ObjTy && "Invalid Objective-C class message send");
1733031c63f7b5b09d5f64609fa7a1922a05b520fa7John McCall    OID = ObjTy->getInterface();
1743031c63f7b5b09d5f64609fa7a1922a05b520fa7John McCall    assert(OID && "Invalid Objective-C class message send");
175c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall    Receiver = Runtime.GetClass(Builder, OID);
176f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    isClassMessage = true;
17704badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
17804badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  }
17904badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor
18004badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::SuperInstance:
181926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getSuperType();
18204badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    Receiver = LoadObjCSelf();
1838fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    isSuperMessage = true;
18404badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
18504badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor
18604badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::SuperClass:
187926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getSuperType();
1888fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    Receiver = LoadObjCSelf();
18904badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    isSuperMessage = true;
19004badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    isClassMessage = true;
19104badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
1928fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
1938fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
194dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (retainSelf)
195dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    Receiver = EmitARCRetainNonBlock(Receiver);
196dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
197dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // In ARC, we sometimes want to "extend the lifetime"
198dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // (i.e. retain+autorelease) of receivers of returns-inner-pointer
199dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  // messages.
200dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  if (getLangOptions().ObjCAutoRefCount && method &&
201dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      method->hasAttr<ObjCReturnsInnerPointerAttr>() &&
202dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall      shouldExtendReceiverForInnerPointerMessage(E))
203dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    Receiver = EmitARCRetainAutorelease(ReceiverType, Receiver);
204dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall
205f85e193739c953358c865005855253af4f68a497John McCall  QualType ResultType =
206dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall    method ? method->getResultType() : E->getType();
207f85e193739c953358c865005855253af4f68a497John McCall
20819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  CallArgList Args;
209dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  EmitCallArgs(Args, method, E->arg_begin(), E->arg_end());
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
211f85e193739c953358c865005855253af4f68a497John McCall  // For delegate init calls in ARC, do an unsafe store of null into
212f85e193739c953358c865005855253af4f68a497John McCall  // self.  This represents the call taking direct ownership of that
213f85e193739c953358c865005855253af4f68a497John McCall  // value.  We have to do this after emitting the other call
214f85e193739c953358c865005855253af4f68a497John McCall  // arguments because they might also reference self, but we don't
215f85e193739c953358c865005855253af4f68a497John McCall  // have to worry about any of them modifying self because that would
216f85e193739c953358c865005855253af4f68a497John McCall  // be an undefined read and write of an object in unordered
217f85e193739c953358c865005855253af4f68a497John McCall  // expressions.
218f85e193739c953358c865005855253af4f68a497John McCall  if (isDelegateInit) {
219f85e193739c953358c865005855253af4f68a497John McCall    assert(getLangOptions().ObjCAutoRefCount &&
220f85e193739c953358c865005855253af4f68a497John McCall           "delegate init calls should only be marked in ARC");
221f85e193739c953358c865005855253af4f68a497John McCall
222f85e193739c953358c865005855253af4f68a497John McCall    // Do an unsafe store of null into self.
223f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *selfAddr =
224f85e193739c953358c865005855253af4f68a497John McCall      LocalDeclMap[cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()];
225f85e193739c953358c865005855253af4f68a497John McCall    assert(selfAddr && "no self entry for a delegate init call?");
226f85e193739c953358c865005855253af4f68a497John McCall
227f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(getNullForVariable(selfAddr), selfAddr);
228f85e193739c953358c865005855253af4f68a497John McCall  }
2297e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson
230926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  RValue result;
2318fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  if (isSuperMessage) {
2329384c768e93f270118a30ce96546083a666da284Chris Lattner    // super is only valid in an Objective-C method
2339384c768e93f270118a30ce96546083a666da284Chris Lattner    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
2347ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
235926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    result = Runtime.GenerateMessageSendSuper(*this, Return, ResultType,
236926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              E->getSelector(),
237926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              OMD->getClassInterface(),
238926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              isCategoryImpl,
239926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              Receiver,
240926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              isClassMessage,
241926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              Args,
242dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                              method);
243926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  } else {
244926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    result = Runtime.GenerateMessageSend(*this, Return, ResultType,
245926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                         E->getSelector(),
246926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                         Receiver, Args, OID,
247dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall                                         method);
2488fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
249f85e193739c953358c865005855253af4f68a497John McCall
250f85e193739c953358c865005855253af4f68a497John McCall  // For delegate init calls in ARC, implicitly store the result of
251f85e193739c953358c865005855253af4f68a497John McCall  // the call back into self.  This takes ownership of the value.
252f85e193739c953358c865005855253af4f68a497John McCall  if (isDelegateInit) {
253f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *selfAddr =
254f85e193739c953358c865005855253af4f68a497John McCall      LocalDeclMap[cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()];
255f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *newSelf = result.getScalarVal();
256f85e193739c953358c865005855253af4f68a497John McCall
257f85e193739c953358c865005855253af4f68a497John McCall    // The delegate return type isn't necessarily a matching type; in
258f85e193739c953358c865005855253af4f68a497John McCall    // fact, it's quite likely to be 'id'.
2592acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *selfTy =
260f85e193739c953358c865005855253af4f68a497John McCall      cast<llvm::PointerType>(selfAddr->getType())->getElementType();
261f85e193739c953358c865005855253af4f68a497John McCall    newSelf = Builder.CreateBitCast(newSelf, selfTy);
262f85e193739c953358c865005855253af4f68a497John McCall
263f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(newSelf, selfAddr);
264f85e193739c953358c865005855253af4f68a497John McCall  }
265f85e193739c953358c865005855253af4f68a497John McCall
266dc7c5ad7a15914b7ae24f31f18a20ad2f8ecd0bcJohn McCall  return AdjustRelatedResultType(*this, E, method, result);
2675508518a2702b00be3b15a26d772bde968972f54Anders Carlsson}
2685508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
269f85e193739c953358c865005855253af4f68a497John McCallnamespace {
270f85e193739c953358c865005855253af4f68a497John McCallstruct FinishARCDealloc : EHScopeStack::Cleanup {
271ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall  void Emit(CodeGenFunction &CGF, Flags flags) {
272f85e193739c953358c865005855253af4f68a497John McCall    const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CGF.CurCodeDecl);
273799d34e9505a833549c71f2ac5f842da157ea031John McCall
274799d34e9505a833549c71f2ac5f842da157ea031John McCall    const ObjCImplDecl *impl = cast<ObjCImplDecl>(method->getDeclContext());
275f85e193739c953358c865005855253af4f68a497John McCall    const ObjCInterfaceDecl *iface = impl->getClassInterface();
276f85e193739c953358c865005855253af4f68a497John McCall    if (!iface->getSuperClass()) return;
277f85e193739c953358c865005855253af4f68a497John McCall
278799d34e9505a833549c71f2ac5f842da157ea031John McCall    bool isCategory = isa<ObjCCategoryImplDecl>(impl);
279799d34e9505a833549c71f2ac5f842da157ea031John McCall
280f85e193739c953358c865005855253af4f68a497John McCall    // Call [super dealloc] if we have a superclass.
281f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *self = CGF.LoadObjCSelf();
282f85e193739c953358c865005855253af4f68a497John McCall
283f85e193739c953358c865005855253af4f68a497John McCall    CallArgList args;
284f85e193739c953358c865005855253af4f68a497John McCall    CGF.CGM.getObjCRuntime().GenerateMessageSendSuper(CGF, ReturnValueSlot(),
285f85e193739c953358c865005855253af4f68a497John McCall                                                      CGF.getContext().VoidTy,
286f85e193739c953358c865005855253af4f68a497John McCall                                                      method->getSelector(),
287f85e193739c953358c865005855253af4f68a497John McCall                                                      iface,
288799d34e9505a833549c71f2ac5f842da157ea031John McCall                                                      isCategory,
289f85e193739c953358c865005855253af4f68a497John McCall                                                      self,
290f85e193739c953358c865005855253af4f68a497John McCall                                                      /*is class msg*/ false,
291f85e193739c953358c865005855253af4f68a497John McCall                                                      args,
292f85e193739c953358c865005855253af4f68a497John McCall                                                      method);
293f85e193739c953358c865005855253af4f68a497John McCall  }
294f85e193739c953358c865005855253af4f68a497John McCall};
295f85e193739c953358c865005855253af4f68a497John McCall}
296f85e193739c953358c865005855253af4f68a497John McCall
297af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
298af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// the LLVM function and sets the other context used by
299af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// CodeGenFunction.
300679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanianvoid CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
3018d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel                                      const ObjCContainerDecl *CD,
3028d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel                                      SourceLocation StartLoc) {
303d26bc76c98006609002d9930f8840490e88ac5b5John McCall  FunctionArgList args;
3044800ea6ff8017cf803c32a5fd63b94c0614014e3Devang Patel  // Check if we should generate debug info for this method.
305aa11289f754d220c9c155b68a4f84cdcfcefef6aDevang Patel  if (CGM.getModuleDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
306aa11289f754d220c9c155b68a4f84cdcfcefef6aDevang Patel    DebugInfo = CGM.getModuleDebugInfo();
3074800ea6ff8017cf803c32a5fd63b94c0614014e3Devang Patel
308679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian  llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
309f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar
3100e4f40e1bbc4dce16bbb9870300a435419f1b3d5Daniel Dunbar  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
3110e4f40e1bbc4dce16bbb9870300a435419f1b3d5Daniel Dunbar  CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
3124111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
313d26bc76c98006609002d9930f8840490e88ac5b5John McCall  args.push_back(OMD->getSelfDecl());
314d26bc76c98006609002d9930f8840490e88ac5b5John McCall  args.push_back(OMD->getCmdDecl());
3154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
31689951a86b594513c2a013532ed45d197413b1087Chris Lattner  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
31789951a86b594513c2a013532ed45d197413b1087Chris Lattner       E = OMD->param_end(); PI != E; ++PI)
318d26bc76c98006609002d9930f8840490e88ac5b5John McCall    args.push_back(*PI);
319b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
32014110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  CurGD = OMD;
32114110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
3228d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartFunction(OMD, OMD->getResultType(), Fn, FI, args, StartLoc);
323f85e193739c953358c865005855253af4f68a497John McCall
324f85e193739c953358c865005855253af4f68a497John McCall  // In ARC, certain methods get an extra cleanup.
325f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount &&
326f85e193739c953358c865005855253af4f68a497John McCall      OMD->isInstanceMethod() &&
327f85e193739c953358c865005855253af4f68a497John McCall      OMD->getSelector().isUnarySelector()) {
328f85e193739c953358c865005855253af4f68a497John McCall    const IdentifierInfo *ident =
329f85e193739c953358c865005855253af4f68a497John McCall      OMD->getSelector().getIdentifierInfoForSlot(0);
330f85e193739c953358c865005855253af4f68a497John McCall    if (ident->isStr("dealloc"))
331f85e193739c953358c865005855253af4f68a497John McCall      EHStack.pushCleanup<FinishARCDealloc>(getARCCleanupKind());
332f85e193739c953358c865005855253af4f68a497John McCall  }
333af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
334af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
335f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
336f85e193739c953358c865005855253af4f68a497John McCall                                              LValue lvalue, QualType type);
337f85e193739c953358c865005855253af4f68a497John McCall
3382846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanianvoid CodeGenFunction::GenerateObjCGetterBody(ObjCIvarDecl *Ivar,
3392846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                             bool IsAtomic, bool IsStrong) {
3402846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
3412846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                Ivar, 0);
3422846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *GetCopyStructFn =
3432846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CGM.getObjCRuntime().GetGetStructFunction();
3442846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CodeGenTypes &Types = CGM.getTypes();
3452846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // objc_copyStruct (ReturnValue, &structIvar,
3462846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  //                  sizeof (Type of Ivar), isAtomic, false);
3472846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CallArgList Args;
3480774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  RValue RV = RValue::get(Builder.CreateBitCast(ReturnValue, VoidPtrTy));
34904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
3500774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  RV = RValue::get(Builder.CreateBitCast(LV.getAddress(), VoidPtrTy));
35104c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
3522846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // sizeof (Type of Ivar)
3532846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CharUnits Size =  getContext().getTypeSizeInChars(Ivar->getType());
3542846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *SizeVal =
3550774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy),
3562846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         Size.getQuantity());
35704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(SizeVal), getContext().LongTy);
3582846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *isAtomic =
3592846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
3602846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         IsAtomic ? 1 : 0);
36104c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(isAtomic), getContext().BoolTy);
3622846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *hasStrong =
3632846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
3642846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         IsStrong ? 1 : 0);
36504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(hasStrong), getContext().BoolTy);
3662846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
3672846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                 FunctionType::ExtInfo()),
3682846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian           GetCopyStructFn, ReturnValueSlot(), Args);
3692846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian}
3702846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian
371af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method.  An Objective-C method is a C function with
3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// its pointer, name, and types registered in the class struture.
373af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
3748d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, OMD->getClassInterface(), OMD->getLocStart());
3756fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis  EmitStmt(OMD->getBody());
3766fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis  FinishFunction(OMD->getBodyRBrace());
377af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
378af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
379f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump// FIXME: I wasn't sure about the synthesis approach. If we end up generating an
380f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump// AST for the whole body we can just fall back to having a GenerateFunction
381f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump// which takes the body Stmt.
382af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
383af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter
384489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
385489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// is illegal within a category.
386fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanianvoid CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
387fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian                                         const ObjCPropertyImplDecl *PID) {
388c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
389af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
39015bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  bool IsAtomic =
39115bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
392af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
393af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate getter (empty method)");
3948d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
39515bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian
396c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  // Determine if we should use an objc_getProperty call for
397447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian  // this. Non-atomic properties are directly evaluated.
398447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian  // atomic 'copy' and 'retain' properties are also directly
399447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian  // evaluated in gc-only mode.
400c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
40115bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian      IsAtomic &&
402447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian      (PD->getSetterKind() == ObjCPropertyDecl::Copy ||
403447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
4041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *GetPropertyFn =
405c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      CGM.getObjCRuntime().GetPropertyGetFunction();
4061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
407c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    if (!GetPropertyFn) {
408c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
409c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      FinishFunction();
410c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      return;
411c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    }
412c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
413c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
414c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // FIXME: Can't this be simpler? This might even be worse than the
415c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // corresponding gcc code.
416c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CodeGenTypes &Types = CGM.getTypes();
417c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    ValueDecl *Cmd = OMD->getCmdDecl();
418c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
419c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    QualType IdTy = getContext().getObjCIdType();
4201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *SelfAsId =
421c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
422fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
423c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    llvm::Value *True =
4244a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
425c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CallArgList Args;
42604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(SelfAsId), IdTy);
42704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(CmdVal), Cmd->getType());
42804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(Offset), getContext().getPointerDiffType());
42904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(True), getContext().BoolTy);
430e4be5a66072f7c7618071284c8d2a9c6d8e691cfDaniel Dunbar    // FIXME: We shouldn't need to get the function info here, the
431e4be5a66072f7c7618071284c8d2a9c6d8e691cfDaniel Dunbar    // runtime already should have computed it to build the function.
43204a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args,
433264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                               FunctionType::ExtInfo()),
434f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson                         GetPropertyFn, ReturnValueSlot(), Args);
435c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // We need to fix the type here. Ivars with copy & retain are
436c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // always objects so we don't need to worry about complex or
437c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // aggregates.
4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
439c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar                                           Types.ConvertType(PD->getType())));
440c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    EmitReturnOfRValue(RV, PD->getType());
441f85e193739c953358c865005855253af4f68a497John McCall
442f85e193739c953358c865005855253af4f68a497John McCall    // objc_getProperty does an autorelease, so we should suppress ours.
443f85e193739c953358c865005855253af4f68a497John McCall    AutoreleaseResult = false;
444c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  } else {
445bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    const llvm::Triple &Triple = getContext().getTargetInfo().getTriple();
4462846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    QualType IVART = Ivar->getType();
4472846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    if (IsAtomic &&
4482846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        IVART->isScalarType() &&
4492846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (Triple.getArch() == llvm::Triple::arm ||
4502846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian         Triple.getArch() == llvm::Triple::thumb) &&
4512846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (getContext().getTypeSizeInChars(IVART)
4522846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian         > CharUnits::fromQuantity(4)) &&
4532846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        CGM.getObjCRuntime().GetGetStructFunction()) {
4542846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      GenerateObjCGetterBody(Ivar, true, false);
4552846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    }
4561d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
4571d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
4581d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86 &&
4591d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
4601d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(4)) &&
4611d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
4621d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCGetterBody(Ivar, true, false);
4631d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
4641d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
4651d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
4661d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86_64 &&
4671d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
4681d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(8)) &&
4691d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
4701d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCGetterBody(Ivar, true, false);
4711d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
4722846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    else if (IVART->isAnyComplexType()) {
47397a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
47497a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian                                    Ivar, 0);
4751b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian      ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(),
4761b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian                                               LV.isVolatileQualified());
4771b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian      StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
4781b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian    }
4792846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    else if (hasAggregateLLVMType(IVART)) {
48015bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian      bool IsStrong = false;
4815fb6509b402d052aa661b15bfa5b71b7cdd7d0e9Fariborz Jahanian      if ((IsStrong = IvarTypeWithAggrGCObjects(IVART))
4820b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian          && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
4838fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall          && CGM.getObjCRuntime().GetGetStructFunction()) {
4842846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        GenerateObjCGetterBody(Ivar, IsAtomic, IsStrong);
4850b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian      }
48697a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian      else {
48701cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian        const CXXRecordDecl *classDecl = IVART->getAsCXXRecordDecl();
48801cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian
48901cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian        if (PID->getGetterCXXConstructor() &&
490023df37c27ee8035664fb62f206ca58f4e2a169dSean Hunt            classDecl && !classDecl->hasTrivialDefaultConstructor()) {
49197a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian          ReturnStmt *Stmt =
49297a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian            new (getContext()) ReturnStmt(SourceLocation(),
4935077c3876beeaed32280af88244e8050078619a8Douglas Gregor                                          PID->getGetterCXXConstructor(),
4945077c3876beeaed32280af88244e8050078619a8Douglas Gregor                                          0);
49597a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian          EmitReturnStmt(*Stmt);
4961d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian        } else if (IsAtomic &&
4971d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   !IVART->isAnyComplexType() &&
4981d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   Triple.getArch() == llvm::Triple::x86 &&
4991d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   (getContext().getTypeSizeInChars(IVART)
5001d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                    > CharUnits::fromQuantity(4)) &&
5011d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   CGM.getObjCRuntime().GetGetStructFunction()) {
5021d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          GenerateObjCGetterBody(Ivar, true, false);
5031d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian        }
5041d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian        else if (IsAtomic &&
5051d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 !IVART->isAnyComplexType() &&
5061d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 Triple.getArch() == llvm::Triple::x86_64 &&
5071d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 (getContext().getTypeSizeInChars(IVART)
5081d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                  > CharUnits::fromQuantity(8)) &&
5091d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 CGM.getObjCRuntime().GetGetStructFunction()) {
5101d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          GenerateObjCGetterBody(Ivar, true, false);
51197a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian        }
51297a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian        else {
51397a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian          LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
51497a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian                                        Ivar, 0);
5152846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian          EmitAggregateCopy(ReturnValue, LV.getAddress(), IVART);
51697a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian        }
51797a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian      }
518ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall    } else {
519ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
520ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall                                    Ivar, 0);
521ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      QualType propType = PD->getType();
522ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall
523ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      llvm::Value *value;
524ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      if (propType->isReferenceType()) {
525ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        value = LV.getAddress();
526ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      } else {
527ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        // We want to load and autoreleaseReturnValue ARC __weak ivars.
528ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {
529ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall          value = emitARCRetainLoadOfScalar(*this, LV, IVART);
530ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall
531ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        // Otherwise we want to do a simple load, suppressing the
532ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        // final autorelease.
533f85e193739c953358c865005855253af4f68a497John McCall        } else {
534ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall          value = EmitLoadOfLValue(LV).getScalarVal();
535ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall          AutoreleaseResult = false;
53614086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian        }
537f85e193739c953358c865005855253af4f68a497John McCall
538ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        value = Builder.CreateBitCast(value, ConvertType(propType));
539ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      }
540ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall
541ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      EmitReturnOfRValue(RValue::get(value), propType);
542ed1d29d62595a83ccf6ef23eb2759d355206df2eFariborz Jahanian    }
543c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
544af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
545af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
546af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
547af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
5482846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanianvoid CodeGenFunction::GenerateObjCAtomicSetterBody(ObjCMethodDecl *OMD,
5492846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                                   ObjCIvarDecl *Ivar) {
5502846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // objc_copyStruct (&structIvar, &Arg,
5512846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  //                  sizeof (struct something), true, false);
5522846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *GetCopyStructFn =
5532846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CGM.getObjCRuntime().GetSetStructFunction();
5542846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CodeGenTypes &Types = CGM.getTypes();
5552846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CallArgList Args;
5562846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
5572846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  RValue RV =
5582846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    RValue::get(Builder.CreateBitCast(LV.getAddress(),
5592846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                Types.ConvertType(getContext().VoidPtrTy)));
56004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
5612846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
5622846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *ArgAsPtrTy =
5632846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  Builder.CreateBitCast(Arg,
5642846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                      Types.ConvertType(getContext().VoidPtrTy));
5652846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  RV = RValue::get(ArgAsPtrTy);
56604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
5672846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // sizeof (Type of Ivar)
5682846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CharUnits Size =  getContext().getTypeSizeInChars(Ivar->getType());
5692846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *SizeVal =
5702846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy),
5712846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         Size.getQuantity());
57204c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(SizeVal), getContext().LongTy);
5732846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *True =
5742846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
57504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(True), getContext().BoolTy);
5762846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *False =
5772846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
57804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(False), getContext().BoolTy);
5792846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
5802846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                 FunctionType::ExtInfo()),
5812846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian           GetCopyStructFn, ReturnValueSlot(), Args);
5822846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian}
5832846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian
58471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallstatic bool hasTrivialAssignment(const ObjCPropertyImplDecl *PID) {
58571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  Expr *assign = PID->getSetterCXXAssignment();
58671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (!assign) return true;
58771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
58871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // An operator call is trivial if the function it calls is trivial.
58971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (CallExpr *call = dyn_cast<CallExpr>(assign)) {
59071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (const FunctionDecl *callee
59171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall          = dyn_cast_or_null<FunctionDecl>(call->getCalleeDecl()))
59271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      if (callee->isTrivial())
59371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall        return true;
59471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return false;
59501cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  }
59671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
59771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  assert(isa<BinaryOperator>(assign));
59871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  return true;
59901cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian}
60001cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian
60171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall/// Should the setter use objc_setProperty?
60271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallstatic bool shouldUseSetProperty(CodeGenFunction &CGF,
60371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                 ObjCPropertyDecl::SetterKind setterKind) {
60471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Copy setters require objc_setProperty.
60571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (setterKind == ObjCPropertyDecl::Copy)
60671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return true;
60771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
60871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // So do retain setters, if we're not in GC-only mode (where
60971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // 'retain' is ignored).
61071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (setterKind == ObjCPropertyDecl::Retain &&
61171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      CGF.getLangOptions().getGCMode() != LangOptions::GCOnly)
61271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return true;
61371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
61471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Otherwise, we don't need this.
61571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  return false;
61671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall}
61786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar
61871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallstatic bool isAssignmentImplicitlyAtomic(CodeGenFunction &CGF,
61971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                         const ObjCIvarDecl *ivar) {
62071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Aggregate assignment is not implicitly atomic if it includes a GC
62171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // barrier.
62271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  QualType ivarType = ivar->getType();
62371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (CGF.getLangOptions().getGCMode())
62471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (const RecordType *ivarRecordTy = ivarType->getAs<RecordType>())
62571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      if (ivarRecordTy->getDecl()->hasObjectMember())
62671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall        return false;
62771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
62871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Assume that any store no larger than a pointer, and as aligned as
62971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // the required size, can be performed atomically.
63071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ASTContext &Context = CGF.getContext();
63171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  std::pair<CharUnits,CharUnits> ivarSizeAndAlignment
63271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    = Context.getTypeInfoInChars(ivar->getType());
63371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
63471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  return (ivarSizeAndAlignment.first
63571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall            <= CharUnits::fromQuantity(CGF.PointerSizeInBytes) &&
63671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall          ivarSizeAndAlignment.second >= ivarSizeAndAlignment.first);
63771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall}
6381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallvoid
64071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallCodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
64171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                        const ObjCPropertyImplDecl *propImpl) {
64271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Just use the setter expression if Sema gave us one and it's
64371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // non-trivial.  There's no way to do this atomically.
64471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (!hasTrivialAssignment(propImpl)) {
64571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    EmitStmt(propImpl->getSetterCXXAssignment());
64671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return;
64771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  }
64871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
64971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
65071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
65171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
65271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
65371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // A property is copy if it says it's copy.
65471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCPropertyDecl::SetterKind setterKind = prop->getSetterKind();
65571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  bool isCopy = (setterKind == ObjCPropertyDecl::Copy);
65671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
65771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // A property is atomic if it doesn't say it's nonatomic.
65871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  bool isAtomic =
65971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    !(prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
66071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
66171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Should we call the runtime's set property function?
66271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (shouldUseSetProperty(*this, setterKind)) {
66371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *setPropertyFn =
66471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      CGM.getObjCRuntime().GetPropertySetFunction();
66571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (!setPropertyFn) {
66671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");
66786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      return;
66886957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    }
6691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Emit objc_setProperty((id) self, _cmd, offset, arg,
67186957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    //                       <is-atomic>, <is-copy>).
67271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *cmd =
67371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      Builder.CreateLoad(LocalDeclMap[setterMethod->getCmdDecl()]);
67471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *self =
67571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
67671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *ivarOffset =
67771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      EmitIvarOffset(classImpl->getClassInterface(), ivar);
67871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *arg = LocalDeclMap[*setterMethod->param_begin()];
67971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    arg = Builder.CreateBitCast(Builder.CreateLoad(arg, "arg"), VoidPtrTy);
68071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
68171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    CallArgList args;
68271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(self), getContext().getObjCIdType());
68371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(cmd), getContext().getObjCSelType());
68471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
68571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(arg), getContext().getObjCIdType());
68671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(Builder.getInt1(isAtomic)), getContext().BoolTy);
68771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(Builder.getInt1(isCopy)), getContext().BoolTy);
688f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // FIXME: We shouldn't need to get the function info here, the runtime
689f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // already should have computed it to build the function.
69071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    EmitCall(getTypes().getFunctionInfo(getContext().VoidTy, args,
69171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                        FunctionType::ExtInfo()),
69271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall             setPropertyFn, ReturnValueSlot(), args);
69371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return;
69471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  }
69571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
69671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // If the property is atomic but has ARC or GC qualification, we
69771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // must use the expression expansion.  This isn't actually right for
69871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // ARC strong, but we shouldn't actually get here for ARC strong,
69971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // which should always end up using setProperty.
70071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (isAtomic &&
70171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      (ivar->getType().hasNonTrivialObjCLifetime() ||
70271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall       (getLangOptions().getGCMode() &&
70371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall        getContext().getObjCGCAttrKind(ivar->getType())))) {
70471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    // fallthrough
70571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
70671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // If the property is atomic and can be implicitly performed
70771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // atomically with an assignment, do so.
70871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  } else if (isAtomic && isAssignmentImplicitlyAtomic(*this, ivar)) {
70971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *argAddr = LocalDeclMap[*setterMethod->param_begin()];
71071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
71171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    LValue ivarLValue =
71271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, /*quals*/ 0);
71371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *ivarAddr = ivarLValue.getAddress();
71471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
71571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    // If necessary, use a non-aggregate type.
71671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Type *eltType =
71771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      cast<llvm::PointerType>(ivarAddr->getType())->getElementType();
71871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (eltType->isAggregateType()) {
71971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      eltType = llvm::Type::getIntNTy(getLLVMContext(),
72071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                  getContext().getTypeSize(ivar->getType()));
7212846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    }
72271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
72371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    // Cast both arguments to the chosen operation type.
72471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    argAddr = Builder.CreateBitCast(argAddr, eltType->getPointerTo());
72571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    ivarAddr = Builder.CreateBitCast(ivarAddr, eltType->getPointerTo());
72671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
72771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    // Emit a single store.
72871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    // TODO: this should be a 'store atomic unordered'.
72971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    Builder.CreateStore(Builder.CreateLoad(argAddr), ivarAddr);
73071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return;
73171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
73271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Otherwise, if the property is atomic, try to use the runtime's
73371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // atomic-store-struct routine.
73471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  } else if (isAtomic && CGM.getObjCRuntime().GetSetStructFunction()) {
73571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    GenerateObjCAtomicSetterBody(setterMethod, ivar);
73671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return;
73771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  }
73871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
73971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Otherwise, fake up some ASTs and emit a normal assignment.
74071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ValueDecl *selfDecl = setterMethod->getSelfDecl();
74171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  DeclRefExpr self(selfDecl, selfDecl->getType(), VK_LValue, SourceLocation());
74271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
74371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                            selfDecl->getType(), CK_LValueToRValue, &self,
74471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                            VK_RValue);
74571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCIvarRefExpr ivarRef(ivar, ivar->getType().getNonReferenceType(),
74671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                          SourceLocation(), &selfLoad, true, true);
74771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
74871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ParmVarDecl *argDecl = *setterMethod->param_begin();
74971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  QualType argType = argDecl->getType().getNonReferenceType();
75071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  DeclRefExpr arg(argDecl, argType, VK_LValue, SourceLocation());
75171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
75271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           argType.getUnqualifiedType(), CK_LValueToRValue,
75371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           &arg, VK_RValue);
75445e8423d7dcea657c14c55347e8a30ac904d7501Daniel Dunbar
75571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // The property type can differ from the ivar type in some situations with
75671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Objective-C pointer types, we can always bit cast the RHS in these cases.
75771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // The following absurdity is just to ensure well-formed IR.
75871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  CastKind argCK = CK_NoOp;
75971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (ivarRef.getType()->isObjCObjectPointerType()) {
76071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (argLoad.getType()->isObjCObjectPointerType())
76171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_BitCast;
76271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    else if (argLoad.getType()->isBlockPointerType())
76371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_BlockPointerToObjCPointerCast;
76471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    else
76571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_CPointerToObjCPointerCast;
76671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  } else if (ivarRef.getType()->isBlockPointerType()) {
76771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall     if (argLoad.getType()->isBlockPointerType())
76871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_BitCast;
76971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    else
77071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_AnyPointerToBlockPointerCast;
77171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  } else if (ivarRef.getType()->isPointerType()) {
77271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    argCK = CK_BitCast;
77386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  }
77471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ImplicitCastExpr argCast(ImplicitCastExpr::OnStack,
77571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           ivarRef.getType(), argCK, &argLoad,
77671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           VK_RValue);
77771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  Expr *finalArg = &argLoad;
77871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (!getContext().hasSameUnqualifiedType(ivarRef.getType(),
77971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                           argLoad.getType()))
78071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    finalArg = &argCast;
78171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
78271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
78371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  BinaryOperator assign(&ivarRef, finalArg, BO_Assign,
78471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                        ivarRef.getType(), VK_RValue, OK_Ordinary,
78571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                        SourceLocation());
78671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  EmitStmt(&assign);
78771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall}
78871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
78971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall/// GenerateObjCSetter - Generate an Objective-C property setter
79071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
79171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall/// is illegal within a category.
79271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallvoid CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
79371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                         const ObjCPropertyImplDecl *PID) {
79471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
79571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
79671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  assert(OMD && "Invalid call to generate setter (empty method)");
79771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
79871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
79971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  generateObjCSetterBody(IMP, PID);
800af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
801af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
8024111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
8034111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
804e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallnamespace {
8059928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  struct DestroyIvar : EHScopeStack::Cleanup {
8069928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  private:
8079928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    llvm::Value *addr;
808e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    const ObjCIvarDecl *ivar;
8099928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer &destroyer;
8109928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    bool useEHCleanupForArray;
8119928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  public:
8129928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
8139928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                CodeGenFunction::Destroyer *destroyer,
8149928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                bool useEHCleanupForArray)
8159928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      : addr(addr), ivar(ivar), destroyer(*destroyer),
8169928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        useEHCleanupForArray(useEHCleanupForArray) {}
817e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
818ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
8199928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      LValue lvalue
8209928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0);
8219928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      CGF.emitDestroy(lvalue.getAddress(), ivar->getType(), destroyer,
822ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall                      flags.isForNormalCleanup() && useEHCleanupForArray);
823e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
824e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  };
825e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
826e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
8279928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall/// Like CodeGenFunction::destroyARCStrong, but do it with a call.
8289928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCallstatic void destroyARCStrongWithStore(CodeGenFunction &CGF,
8299928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      llvm::Value *addr,
8309928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      QualType type) {
8319928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  llvm::Value *null = getNullForVariable(addr);
8329928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  CGF.EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
8339928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall}
834f85e193739c953358c865005855253af4f68a497John McCall
835e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallstatic void emitCXXDestructMethod(CodeGenFunction &CGF,
836e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall                                  ObjCImplementationDecl *impl) {
837e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  CodeGenFunction::RunCleanupsScope scope(CGF);
838e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
839e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  llvm::Value *self = CGF.LoadObjCSelf();
840e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
841db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *iface = impl->getClassInterface();
842db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
843e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall       ivar; ivar = ivar->getNextIvar()) {
844e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    QualType type = ivar->getType();
845e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
846e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    // Check whether the ivar is a destructible type.
8479928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    QualType::DestructionKind dtorKind = type.isDestructedType();
8489928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (!dtorKind) continue;
8499928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
8509928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer *destroyer = 0;
8519928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
8529928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Use a call to objc_storeStrong to destroy strong ivars, for the
8539928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // general benefit of the tools.
8549928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (dtorKind == QualType::DK_objc_strong_lifetime) {
8559928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &destroyARCStrongWithStore;
8569928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
8579928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Otherwise use the default for the destruction kind.
8589928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    } else {
8599928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &CGF.getDestroyer(dtorKind);
860e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
8619928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
8629928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind);
8639928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
8649928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CGF.EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
8659928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                         cleanupKind & EHCleanup);
866e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  }
867e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
868e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
869e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
870e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
871109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanianvoid CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
872109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 ObjCMethodDecl *MD,
873109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 bool ctor) {
874109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
8758d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(MD, IMP->getClassInterface(), MD->getLocStart());
876e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
877e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_construct.
878109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  if (ctor) {
879f85e193739c953358c865005855253af4f68a497John McCall    // Suppress the final autorelease in ARC.
880f85e193739c953358c865005855253af4f68a497John McCall    AutoreleaseResult = false;
881f85e193739c953358c865005855253af4f68a497John McCall
8825f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CXXCtorInitializer *, 8> IvarInitializers;
883e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
884e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall           E = IMP->init_end(); B != E; ++B) {
885e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall      CXXCtorInitializer *IvarInit = (*B);
88600eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet      FieldDecl *Field = IvarInit->getAnyMember();
887109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
8889b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian      LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
8899b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian                                    LoadObjCSelf(), Ivar, 0);
8907c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall      EmitAggExpr(IvarInit->getInit(),
8917c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall                  AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed,
892410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall                                          AggValueSlot::DoesNotNeedGCBarriers,
893410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall                                          AggValueSlot::IsNotAliased));
894109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    }
895109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    // constructor returns 'self'.
896109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    CodeGenTypes &Types = CGM.getTypes();
897109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    QualType IdTy(CGM.getContext().getObjCIdType());
898109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    llvm::Value *SelfAsId =
899109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
900109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
901e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
902e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_destruct.
903bc397cf90355f17c974b0bdf3960e8fb38caf5d6Chandler Carruth  } else {
904e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    emitCXXDestructMethod(*this, IMP);
905109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  }
906109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  FinishFunction();
907109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian}
908109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian
9090b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanianbool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
9100b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
9110b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  it++; it++;
9120b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  const ABIArgInfo &AI = it->info;
9130b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  // FIXME. Is this sufficient check?
9140b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  return (AI.getKind() == ABIArgInfo::Indirect);
9150b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian}
9160b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian
91715bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanianbool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
91815bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
91915bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return false;
92015bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
92115bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return FDTTy->getDecl()->hasObjectMember();
92215bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  return false;
92315bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian}
92415bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian
925c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf() {
926b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
927b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
9284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
9294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
93045012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz JahanianQualType CodeGenFunction::TypeOfSelfObject() {
93145012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
93245012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
93314108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
93414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    getContext().getCanonicalType(selfDecl->getType()));
93545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  return PTy->getPointeeType();
93645012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian}
93745012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
938e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallLValue
939e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallCodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
940e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // This is a special l-value that just issues sends when we load or
941e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // store through it.
942e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
943e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // For certain base kinds, we need to emit the base immediately.
944e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Base;
945e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  if (E->isSuperReceiver())
946e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = LoadObjCSelf();
947e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else if (E->isClassReceiver())
948e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver());
949e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else
950e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = EmitScalarExpr(E->getBase());
951e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return LValue::MakePropertyRef(E, Base);
952e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall}
953e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
954e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallstatic RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
955e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       ReturnValueSlot Return,
956e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       QualType ResultType,
957e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       Selector S,
958e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       llvm::Value *Receiver,
959e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       const CallArgList &CallArgs) {
960e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl);
961f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isClassMessage = OMD->isClassMethod();
962f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
963e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return CGF.CGM.getObjCRuntime()
964e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                .GenerateMessageSendSuper(CGF, Return, ResultType,
965e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          S, OMD->getClassInterface(),
966e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isCategoryImpl, Receiver,
967e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isClassMessage, CallArgs);
968f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian}
969f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian
970119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallRValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
971119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                    ReturnValueSlot Return) {
972119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr();
97368af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ResultType = E->getGetterResultType();
97412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S;
975926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  const ObjCMethodDecl *method;
97612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isExplicitProperty()) {
97712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    const ObjCPropertyDecl *Property = E->getExplicitProperty();
97812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    S = Property->getGetterName();
979926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = Property->getGetterMethodDecl();
980b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
981926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = E->getImplicitPropertyGetter();
982926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    S = method->getSelector();
9835daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian  }
98412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
985e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = LV.getPropertyRefBaseAddr();
986e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
987f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount) {
988f85e193739c953358c865005855253af4f68a497John McCall    QualType receiverType;
989f85e193739c953358c865005855253af4f68a497John McCall    if (E->isSuperReceiver())
990f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getSuperReceiverType();
991f85e193739c953358c865005855253af4f68a497John McCall    else if (E->isClassReceiver())
992f85e193739c953358c865005855253af4f68a497John McCall      receiverType = getContext().getObjCClassType();
993f85e193739c953358c865005855253af4f68a497John McCall    else
994f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getBase()->getType();
995f85e193739c953358c865005855253af4f68a497John McCall  }
996f85e193739c953358c865005855253af4f68a497John McCall
997e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // Accesses to 'super' follow a different code path.
99812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver())
999926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return AdjustRelatedResultType(*this, E, method,
1000926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                   GenerateMessageSendSuper(*this, Return,
1001926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            ResultType,
1002926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            S, Receiver,
1003926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            CallArgList()));
1004119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
1005119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
1006926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return AdjustRelatedResultType(*this, E, method,
1007f85e193739c953358c865005855253af4f68a497John McCall          CGM.getObjCRuntime().
1008f85e193739c953358c865005855253af4f68a497John McCall             GenerateMessageSend(*this, Return, ResultType, S,
1009f85e193739c953358c865005855253af4f68a497John McCall                                 Receiver, CallArgList(), ReceiverClass));
10109c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar}
10119c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
1012119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallvoid CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
1013119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                        LValue Dst) {
1014119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr();
101512f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S = E->getSetterSelector();
101668af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ArgType = E->getSetterArgType();
101768af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian
1018b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // FIXME. Other than scalars, AST is not adequate for setter and
1019b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // getter type mismatches which require conversion.
1020b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  if (Src.isScalar()) {
1021b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    llvm::Value *SrcVal = Src.getScalarVal();
1022b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    QualType DstType = getContext().getCanonicalType(ArgType);
10232acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *DstTy = ConvertType(DstType);
1024b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    if (SrcVal->getType() != DstTy)
1025b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian      Src =
1026b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian        RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType));
1027b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  }
1028b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian
1029e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  CallArgList Args;
103004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(Src, ArgType);
1031e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
1032e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = Dst.getPropertyRefBaseAddr();
1033e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  QualType ResultType = getContext().VoidTy;
1034e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
103512f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver()) {
1036e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    GenerateMessageSendSuper(*this, ReturnValueSlot(),
1037e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                             ResultType, S, Receiver, Args);
103812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    return;
103912f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  }
104012f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
1041119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
1042119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
104312f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
104412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1045e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ResultType, S, Receiver, Args,
1046e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ReceiverClass);
104785c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar}
104885c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar
104974391b48b4791cded373683a3baf67314f358d50Chris Lattnervoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
10501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Constant *EnumerationMutationFn =
1051c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.getObjCRuntime().EnumerationMutationFunction();
10521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1053c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  if (!EnumerationMutationFn) {
1054c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
1055c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    return;
1056c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
1057c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
1058bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  CGDebugInfo *DI = getDebugInfo();
1059bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
1060bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getBegin());
1061bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionStart(Builder);
1062bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
1063bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
10649d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  // The local variable comes into scope immediately.
10659d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  AutoVarEmission variable = AutoVarEmission::invalid();
10669d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
10679d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel    variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl()));
10689d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel
1069d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
10701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1071f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fast enumeration state.
10720815b579b31cb3129f732bb7ea36fd6ba6949e98Douglas Gregor  QualType StateTy = CGM.getObjCFastEnumerationStateType();
1073195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
10741884eb0b5c55edda4893ddec45e7dbad79758782Anders Carlsson  EmitNullInitialization(StatePtr, StateTy);
10751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1076f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Number of elements in the items array.
10772abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  static const unsigned NumItems = 16;
10781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1079d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the countByEnumeratingWithState:objects:count: selector.
1080ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  IdentifierInfo *II[] = {
1081ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
1082ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("objects"),
1083ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("count")
1084ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  };
1085ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  Selector FastEnumSel =
1086ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
1087f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1088f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ItemsTy =
1089f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    getContext().getConstantArrayType(getContext().getObjCIdType(),
10901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      llvm::APInt(32, NumItems),
1091f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ArrayType::Normal, 0);
1092195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
10931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1094990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Emit the collection pointer.  In ARC, we do a retain.
1095990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  llvm::Value *Collection;
1096990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (getLangOptions().ObjCAutoRefCount) {
1097990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    Collection = EmitARCRetainScalarExpr(S.getCollection());
1098990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1099990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    // Enter a cleanup to do the release.
1100990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    EmitObjCConsumeObject(S.getCollection()->getType(), Collection);
1101990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  } else {
1102990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    Collection = EmitScalarExpr(S.getCollection());
1103990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
11041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11054b302d32378b364703b212834f908762e570c29cJohn McCall  // The 'continue' label needs to appear within the cleanup for the
11064b302d32378b364703b212834f908762e570c29cJohn McCall  // collection object.
11074b302d32378b364703b212834f908762e570c29cJohn McCall  JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
11084b302d32378b364703b212834f908762e570c29cJohn McCall
1109d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Send it our message:
1110f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CallArgList Args;
1111d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1112d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The first argument is a temporary of the enumeration-state type.
111304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(StatePtr), getContext().getPointerType(StateTy));
11141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1115d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The second argument is a temporary array with space for NumItems
1116d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointers.  We'll actually be loading elements from the array
1117d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointer written into the control state; this buffer is so that
1118d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // collections that *aren't* backed by arrays can still queue up
1119d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // batches of elements.
112004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy));
11211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1122d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The third argument is the capacity of that temporary array.
11232acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
11244a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
112504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(Count), getContext().UnsignedLongTy);
11261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1127d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start the enumeration.
11281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  RValue CountRV =
1129ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1130f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
1131f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
1132c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
1133f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1134d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The initial number of objects that were returned in the buffer.
1135d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialBufferLimit = CountRV.getScalarVal();
11361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1137d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1138d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1139f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1140d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
1141f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1142d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If the limit pointer was zero to begin with, the collection is
1143d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // empty; skip all this.
1144d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
1145d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopInitBB);
11461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1147d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, initialize the loop.
1148d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopInitBB);
11491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1150d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Save the initial mutations value.  This is the value at an
1151d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // address that was written into the state object by
1152d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // countByEnumeratingWithState:objects:count:.
11531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtrPtr =
11542abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
11551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
11562abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                      "mutationsptr");
11571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1158d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialMutations =
1159d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations");
11601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1161d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start looping.  This is the point we return to whenever we have a
1162d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // fresh, non-empty batch of objects.
1163d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1164d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopBodyBB);
11651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1166d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current index into the buffer.
1167bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
1168d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, LoopInitBB);
1169f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1170d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current buffer size.
1171bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
1172d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(initialBufferLimit, LoopInitBB);
1173f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1174d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether the mutations value has changed from where it was
1175d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // at start.  StateMutationsPtr should actually be invariant between
1176d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes.
11772abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1178d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *currentMutations
1179d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateLoad(StateMutationsPtr, "statemutations");
11801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1181d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1182361cf980a7d976ef11a37b49567412b6b63a89d7Dan Gohman  llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
11831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1184d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1185d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       WasNotMutatedBB, WasMutatedBB);
11861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1187d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If so, call the enumeration-mutation function.
1188d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasMutatedBB);
11892abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *V =
11901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Builder.CreateBitCast(Collection,
11912abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          ConvertType(getContext().getObjCIdType()),
11922abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          "tmp");
11932b2105e92fc77016992dae3f117f526e73af5ea9Daniel Dunbar  CallArgList Args2;
119404c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args2.add(RValue::get(V), getContext().getObjCIdType());
1195f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to get the function info here, the runtime already
1196f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // should have computed it to build the function.
119704a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
1198264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                          FunctionType::ExtInfo()),
1199f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson           EnumerationMutationFn, ReturnValueSlot(), Args2);
12001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1201d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, or if the mutation function returns, just continue.
1202d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasNotMutatedBB);
12031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1204d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Initialize the element variable.
1205d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  RunCleanupsScope elementVariableScope(*this);
120657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  bool elementIsVariable;
1207d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  LValue elementLValue;
1208d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  QualType elementType;
1209d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
121057b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    // Initialize the variable, in case it's a __block variable or something.
121157b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarInit(variable);
1212f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
121357b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
1214d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
1215d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                        VK_LValue, SourceLocation());
1216d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(&tempDRE);
1217d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = D->getType();
121857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = true;
12197acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall
12207acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    if (D->isARCPseudoStrong())
12217acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall      elementLValue.getQuals().setObjCLifetime(Qualifiers::OCL_ExplicitNone);
1222d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  } else {
1223d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = LValue(); // suppress warning
1224d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = cast<Expr>(S.getElement())->getType();
122557b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = false;
1226d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
12272acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *convertedElementType = ConvertType(elementType);
1228f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1229d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the buffer out of the enumeration state.
1230d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // TODO: this pointer should actually be invariant between
1231d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes, which would help us do certain loop optimizations.
1232d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *StateItemsPtr =
1233d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
1234d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *EnumStateItems =
1235d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateItemsPtr, "stateitems");
1236f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1237d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the value at the current index from the buffer.
12381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *CurrentItemPtr =
1239d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr");
1240d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr);
12411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1242d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Cast that value to the right type.
1243d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
1244d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                                      "currentitem");
12451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1246d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Make sure we have an l-value.  Yes, this gets evaluated every
1247d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // time through the loop.
12487acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  if (!elementIsVariable) {
1249d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1250545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue);
12517acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  } else {
12527acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    EmitScalarInit(CurrentItem, elementLValue);
12537acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  }
12541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
125557b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // If we do have an element variable, this assignment is the end of
125657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // its initialization.
125757b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (elementIsVariable)
125857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarCleanups(variable);
125957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall
1260d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Perform the loop body, setting up break and continue labels.
1261e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
1262d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  {
1263d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    RunCleanupsScope Scope(*this);
1264d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    EmitStmt(S.getBody());
1265d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
1266f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.pop_back();
12671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1268d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Destroy the element variable now.
1269d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  elementVariableScope.ForceCleanup();
1270d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1271d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether there are more elements.
1272ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(AfterBody.getBlock());
12731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1274d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
1275d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1276d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // First we check in the local buffer.
1277d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *indexPlusOne
1278d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
1279d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1280d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we haven't overrun the buffer yet, we can continue.
1281d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
1282d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       LoopBodyBB, FetchMoreBB);
1283f0906c4edb37b20141428ca77fa7dfd00b976eafFariborz Jahanian
1284d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(indexPlusOne, AfterBody.getBlock());
1285d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(count, AfterBody.getBlock());
1286f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1287d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, we have to fetch more elements.
1288d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(FetchMoreBB);
12891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CountRV =
1291ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1292f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
12931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             FastEnumSel,
1294c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
12951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1296d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we got a zero count, we're done.
1297d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *refetchCount = CountRV.getScalarVal();
1298d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1299d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // (note that the message send might split FetchMoreBB)
1300d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, Builder.GetInsertBlock());
1301d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(refetchCount, Builder.GetInsertBlock());
1302d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1303d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
1304d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopBodyBB);
13051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1306f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // No more elements.
1307d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(EmptyBB);
1308f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
130957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (!elementIsVariable) {
1310f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // If the element was not a declaration, set it to be null.
1311f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1312d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
1313d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1314545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(null), elementLValue);
1315f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
1316f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1317bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
1318bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getEnd());
1319bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionEnd(Builder);
1320bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
1321bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
1322990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Leave the cleanup we entered in ARC.
1323990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (getLangOptions().ObjCAutoRefCount)
1324990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    PopCleanupBlock();
1325990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1326ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(LoopEnd.getBlock());
13273d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
13283d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
13291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
1330f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitTryStmt(*this, S);
133164d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
133264d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
13331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
133464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
133564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
133664d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
133710cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattnervoid CodeGenFunction::EmitObjCAtSynchronizedStmt(
13381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              const ObjCAtSynchronizedStmt &S) {
1339f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
134010cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner}
134110cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner
134233e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall/// Produce the code for a CK_ARCProduceObject.  Just does a
1343f85e193739c953358c865005855253af4f68a497John McCall/// primitive retain.
1344f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCProduceObject(QualType type,
1345f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *value) {
1346f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetain(type, value);
1347f85e193739c953358c865005855253af4f68a497John McCall}
1348f85e193739c953358c865005855253af4f68a497John McCall
1349f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1350f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCRelease : EHScopeStack::Cleanup {
1351bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall    CallObjCRelease(llvm::Value *object) : object(object) {}
1352bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall    llvm::Value *object;
1353f85e193739c953358c865005855253af4f68a497John McCall
1354ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1355f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitARCRelease(object, /*precise*/ true);
1356f85e193739c953358c865005855253af4f68a497John McCall    }
1357f85e193739c953358c865005855253af4f68a497John McCall  };
1358f85e193739c953358c865005855253af4f68a497John McCall}
1359f85e193739c953358c865005855253af4f68a497John McCall
136033e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall/// Produce the code for a CK_ARCConsumeObject.  Does a primitive
1361f85e193739c953358c865005855253af4f68a497John McCall/// release at the end of the full-expression.
1362f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
1363f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *object) {
1364f85e193739c953358c865005855253af4f68a497John McCall  // If we're in a conditional branch, we need to make the cleanup
1365bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall  // conditional.
1366bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall  pushFullExprCleanup<CallObjCRelease>(getARCCleanupKind(), object);
1367f85e193739c953358c865005855253af4f68a497John McCall  return object;
1368f85e193739c953358c865005855253af4f68a497John McCall}
1369f85e193739c953358c865005855253af4f68a497John McCall
1370f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
1371f85e193739c953358c865005855253af4f68a497John McCall                                                           llvm::Value *value) {
1372f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetainAutorelease(type, value);
1373f85e193739c953358c865005855253af4f68a497John McCall}
1374f85e193739c953358c865005855253af4f68a497John McCall
1375f85e193739c953358c865005855253af4f68a497John McCall
1376f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
13772acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner                                                llvm::FunctionType *type,
13785f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                                StringRef fnName) {
1379f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
1380f85e193739c953358c865005855253af4f68a497John McCall
1381f85e193739c953358c865005855253af4f68a497John McCall  // In -fobjc-no-arc-runtime, emit weak references to the runtime
1382f85e193739c953358c865005855253af4f68a497John McCall  // support library.
13839f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (!CGM.getCodeGenOpts().ObjCRuntimeHasARC)
1384f85e193739c953358c865005855253af4f68a497John McCall    if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
1385f85e193739c953358c865005855253af4f68a497John McCall      f->setLinkage(llvm::Function::ExternalWeakLinkage);
1386f85e193739c953358c865005855253af4f68a497John McCall
1387f85e193739c953358c865005855253af4f68a497John McCall  return fn;
1388f85e193739c953358c865005855253af4f68a497John McCall}
1389f85e193739c953358c865005855253af4f68a497John McCall
1390f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the signature
1391f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8*)
1392f85e193739c953358c865005855253af4f68a497John McCall/// where a null input causes a no-op and returns null.
1393f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
1394f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1395f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
13965f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName) {
1397f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1398f85e193739c953358c865005855253af4f68a497John McCall
1399f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrTy);
14012acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1402f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1403f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1404f85e193739c953358c865005855253af4f68a497John McCall  }
1405f85e193739c953358c865005855253af4f68a497John McCall
1406f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
14072acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1408f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1409f85e193739c953358c865005855253af4f68a497John McCall
1410f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1411f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, value);
1412f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1413f85e193739c953358c865005855253af4f68a497John McCall
1414f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to the original type.
1415f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(call, origType);
1416f85e193739c953358c865005855253af4f68a497John McCall}
1417f85e193739c953358c865005855253af4f68a497John McCall
1418f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1419f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**)
1420f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
1421f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Value *addr,
1422f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Constant *&fn,
14235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                         StringRef fnName) {
1424f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrPtrTy);
14262acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1427f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1428f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1429f85e193739c953358c865005855253af4f68a497John McCall  }
1430f85e193739c953358c865005855253af4f68a497John McCall
1431f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
14322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = addr->getType();
1433f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1434f85e193739c953358c865005855253af4f68a497John McCall
1435f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1436f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, addr);
1437f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1438f85e193739c953358c865005855253af4f68a497John McCall
1439f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to a dereference of the original type.
1440f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = call;
1441f85e193739c953358c865005855253af4f68a497John McCall  if (origType != CGF.Int8PtrPtrTy)
1442f85e193739c953358c865005855253af4f68a497John McCall    result = CGF.Builder.CreateBitCast(result,
1443f85e193739c953358c865005855253af4f68a497John McCall                        cast<llvm::PointerType>(origType)->getElementType());
1444f85e193739c953358c865005855253af4f68a497John McCall
1445f85e193739c953358c865005855253af4f68a497John McCall  return result;
1446f85e193739c953358c865005855253af4f68a497John McCall}
1447f85e193739c953358c865005855253af4f68a497John McCall
1448f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1449f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**, i8*)
1450f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
1451f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *addr,
1452f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1453f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
14545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName,
1455f85e193739c953358c865005855253af4f68a497John McCall                                          bool ignored) {
1456f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1457f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1458f85e193739c953358c865005855253af4f68a497John McCall
1459f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2);
1461f85e193739c953358c865005855253af4f68a497John McCall    argTypes[0] = CGF.Int8PtrPtrTy;
1462f85e193739c953358c865005855253af4f68a497John McCall    argTypes[1] = CGF.Int8PtrTy;
1463f85e193739c953358c865005855253af4f68a497John McCall
14642acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1465f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false);
1466f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1467f85e193739c953358c865005855253af4f68a497John McCall  }
1468f85e193739c953358c865005855253af4f68a497John McCall
14692acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1470f85e193739c953358c865005855253af4f68a497John McCall
1471f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1472f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1473f85e193739c953358c865005855253af4f68a497John McCall
1474f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, addr, value);
1475f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1476f85e193739c953358c865005855253af4f68a497John McCall
1477f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1478f85e193739c953358c865005855253af4f68a497John McCall
1479f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(result, origType);
1480f85e193739c953358c865005855253af4f68a497John McCall}
1481f85e193739c953358c865005855253af4f68a497John McCall
1482f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1483f85e193739c953358c865005855253af4f68a497John McCall///   void (i8**, i8**)
1484f85e193739c953358c865005855253af4f68a497John McCallstatic void emitARCCopyOperation(CodeGenFunction &CGF,
1485f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *dst,
1486f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *src,
1487f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Constant *&fn,
14885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                 StringRef fnName) {
1489f85e193739c953358c865005855253af4f68a497John McCall  assert(dst->getType() == src->getType());
1490f85e193739c953358c865005855253af4f68a497John McCall
1491f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2, CGF.Int8PtrPtrTy);
14932acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1494f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false);
1495f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1496f85e193739c953358c865005855253af4f68a497John McCall  }
1497f85e193739c953358c865005855253af4f68a497John McCall
1498f85e193739c953358c865005855253af4f68a497John McCall  dst = CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy);
1499f85e193739c953358c865005855253af4f68a497John McCall  src = CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy);
1500f85e193739c953358c865005855253af4f68a497John McCall
1501f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, dst, src);
1502f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1503f85e193739c953358c865005855253af4f68a497John McCall}
1504f85e193739c953358c865005855253af4f68a497John McCall
1505f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a retain.  Based on the type, calls one of:
1506f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1507f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1508f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {
1509f85e193739c953358c865005855253af4f68a497John McCall  if (type->isBlockPointerType())
1510f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainBlock(value);
1511f85e193739c953358c865005855253af4f68a497John McCall  else
1512f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainNonBlock(value);
1513f85e193739c953358c865005855253af4f68a497John McCall}
1514f85e193739c953358c865005855253af4f68a497John McCall
1515f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object, with normal retain semantics.
1516f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1517f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) {
1518f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1519f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retain,
1520f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retain");
1521f85e193739c953358c865005855253af4f68a497John McCall}
1522f85e193739c953358c865005855253af4f68a497John McCall
1523f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given block, with _Block_copy semantics.
1524f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1525f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value) {
1526f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1527f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainBlock,
1528f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainBlock");
1529f85e193739c953358c865005855253af4f68a497John McCall}
1530f85e193739c953358c865005855253af4f68a497John McCall
1531f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object which is the result of a function call.
1532f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleasedReturnValue(i8* %value)
1533f85e193739c953358c865005855253af4f68a497John McCall///
1534f85e193739c953358c865005855253af4f68a497John McCall/// Yes, this function name is one character away from a different
1535f85e193739c953358c865005855253af4f68a497John McCall/// call with completely different semantics.
1536f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1537f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
1538f85e193739c953358c865005855253af4f68a497John McCall  // Fetch the void(void) inline asm which marks that we're going to
1539f85e193739c953358c865005855253af4f68a497John McCall  // retain the autoreleased return value.
1540f85e193739c953358c865005855253af4f68a497John McCall  llvm::InlineAsm *&marker
1541f85e193739c953358c865005855253af4f68a497John McCall    = CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker;
1542f85e193739c953358c865005855253af4f68a497John McCall  if (!marker) {
15435f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef assembly
1544f85e193739c953358c865005855253af4f68a497John McCall      = CGM.getTargetCodeGenInfo()
1545f85e193739c953358c865005855253af4f68a497John McCall           .getARCRetainAutoreleasedReturnValueMarker();
1546f85e193739c953358c865005855253af4f68a497John McCall
1547f85e193739c953358c865005855253af4f68a497John McCall    // If we have an empty assembly string, there's nothing to do.
1548f85e193739c953358c865005855253af4f68a497John McCall    if (assembly.empty()) {
1549f85e193739c953358c865005855253af4f68a497John McCall
1550f85e193739c953358c865005855253af4f68a497John McCall    // Otherwise, at -O0, build an inline asm that we're going to call
1551f85e193739c953358c865005855253af4f68a497John McCall    // in a moment.
1552f85e193739c953358c865005855253af4f68a497John McCall    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1553f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType *type =
1554f85e193739c953358c865005855253af4f68a497John McCall        llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
1555f85e193739c953358c865005855253af4f68a497John McCall                                /*variadic*/ false);
1556f85e193739c953358c865005855253af4f68a497John McCall
1557f85e193739c953358c865005855253af4f68a497John McCall      marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true);
1558f85e193739c953358c865005855253af4f68a497John McCall
1559f85e193739c953358c865005855253af4f68a497John McCall    // If we're at -O1 and above, we don't want to litter the code
1560f85e193739c953358c865005855253af4f68a497John McCall    // with this marker yet, so leave a breadcrumb for the ARC
1561f85e193739c953358c865005855253af4f68a497John McCall    // optimizer to pick up.
1562f85e193739c953358c865005855253af4f68a497John McCall    } else {
1563f85e193739c953358c865005855253af4f68a497John McCall      llvm::NamedMDNode *metadata =
1564f85e193739c953358c865005855253af4f68a497John McCall        CGM.getModule().getOrInsertNamedMetadata(
1565f85e193739c953358c865005855253af4f68a497John McCall                            "clang.arc.retainAutoreleasedReturnValueMarker");
1566f85e193739c953358c865005855253af4f68a497John McCall      assert(metadata->getNumOperands() <= 1);
1567f85e193739c953358c865005855253af4f68a497John McCall      if (metadata->getNumOperands() == 0) {
1568f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *string = llvm::MDString::get(getLLVMContext(), assembly);
1569da549e8995c447542d5631b8b67fcc3a9582797aJay Foad        metadata->addOperand(llvm::MDNode::get(getLLVMContext(), string));
1570f85e193739c953358c865005855253af4f68a497John McCall      }
1571f85e193739c953358c865005855253af4f68a497John McCall    }
1572f85e193739c953358c865005855253af4f68a497John McCall  }
1573f85e193739c953358c865005855253af4f68a497John McCall
1574f85e193739c953358c865005855253af4f68a497John McCall  // Call the marker asm if we made one, which we do only at -O0.
1575f85e193739c953358c865005855253af4f68a497John McCall  if (marker) Builder.CreateCall(marker);
1576f85e193739c953358c865005855253af4f68a497John McCall
1577f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1578f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleasedReturnValue,
1579f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleasedReturnValue");
1580f85e193739c953358c865005855253af4f68a497John McCall}
1581f85e193739c953358c865005855253af4f68a497John McCall
1582f85e193739c953358c865005855253af4f68a497John McCall/// Release the given object.
1583f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_release(i8* %value)
1584f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCRelease(llvm::Value *value, bool precise) {
1585f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return;
1586f85e193739c953358c865005855253af4f68a497John McCall
1587f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_release;
1588f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15899cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
15902acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1591f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1592f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_release");
1593f85e193739c953358c865005855253af4f68a497John McCall  }
1594f85e193739c953358c865005855253af4f68a497John McCall
1595f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
1596f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1597f85e193739c953358c865005855253af4f68a497John McCall
1598f85e193739c953358c865005855253af4f68a497John McCall  // Call objc_release.
1599f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1600f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1601f85e193739c953358c865005855253af4f68a497John McCall
1602f85e193739c953358c865005855253af4f68a497John McCall  if (!precise) {
16035f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<llvm::Value*,1> args;
1604f85e193739c953358c865005855253af4f68a497John McCall    call->setMetadata("clang.imprecise_release",
1605f85e193739c953358c865005855253af4f68a497John McCall                      llvm::MDNode::get(Builder.getContext(), args));
1606f85e193739c953358c865005855253af4f68a497John McCall  }
1607f85e193739c953358c865005855253af4f68a497John McCall}
1608f85e193739c953358c865005855253af4f68a497John McCall
1609f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Always calls this:
1610f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1611f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr,
1612f85e193739c953358c865005855253af4f68a497John McCall                                                     llvm::Value *value,
1613f85e193739c953358c865005855253af4f68a497John McCall                                                     bool ignored) {
1614f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1615f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1616f85e193739c953358c865005855253af4f68a497John McCall
1617f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_storeStrong;
1618f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
16199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy };
16202acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1621f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false);
1622f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong");
1623f85e193739c953358c865005855253af4f68a497John McCall  }
1624f85e193739c953358c865005855253af4f68a497John McCall
1625f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1626f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *castValue = Builder.CreateBitCast(value, Int8PtrTy);
1627f85e193739c953358c865005855253af4f68a497John McCall
1628f85e193739c953358c865005855253af4f68a497John McCall  Builder.CreateCall2(fn, addr, castValue)->setDoesNotThrow();
1629f85e193739c953358c865005855253af4f68a497John McCall
1630f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1631f85e193739c953358c865005855253af4f68a497John McCall  return value;
1632f85e193739c953358c865005855253af4f68a497John McCall}
1633f85e193739c953358c865005855253af4f68a497John McCall
1634f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Sometimes calls this:
1635f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1636f85e193739c953358c865005855253af4f68a497John McCall/// Other times, breaks it down into components.
1637545d996ec5a3113f046944f11b27cc2d6cb055b4John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
1638f85e193739c953358c865005855253af4f68a497John McCall                                                 llvm::Value *newValue,
1639f85e193739c953358c865005855253af4f68a497John McCall                                                 bool ignored) {
1640545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  QualType type = dst.getType();
1641f85e193739c953358c865005855253af4f68a497John McCall  bool isBlock = type->isBlockPointerType();
1642f85e193739c953358c865005855253af4f68a497John McCall
1643f85e193739c953358c865005855253af4f68a497John McCall  // Use a store barrier at -O0 unless this is a block type or the
1644f85e193739c953358c865005855253af4f68a497John McCall  // lvalue is inadequately aligned.
1645f85e193739c953358c865005855253af4f68a497John McCall  if (shouldUseFusedARCCalls() &&
1646f85e193739c953358c865005855253af4f68a497John McCall      !isBlock &&
1647f85e193739c953358c865005855253af4f68a497John McCall      !(dst.getAlignment() && dst.getAlignment() < PointerAlignInBytes)) {
1648f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCStoreStrongCall(dst.getAddress(), newValue, ignored);
1649f85e193739c953358c865005855253af4f68a497John McCall  }
1650f85e193739c953358c865005855253af4f68a497John McCall
1651f85e193739c953358c865005855253af4f68a497John McCall  // Otherwise, split it out.
1652f85e193739c953358c865005855253af4f68a497John McCall
1653f85e193739c953358c865005855253af4f68a497John McCall  // Retain the new value.
1654f85e193739c953358c865005855253af4f68a497John McCall  newValue = EmitARCRetain(type, newValue);
1655f85e193739c953358c865005855253af4f68a497John McCall
1656f85e193739c953358c865005855253af4f68a497John McCall  // Read the old value.
1657545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  llvm::Value *oldValue = EmitLoadOfScalar(dst);
1658f85e193739c953358c865005855253af4f68a497John McCall
1659f85e193739c953358c865005855253af4f68a497John McCall  // Store.  We do this before the release so that any deallocs won't
1660f85e193739c953358c865005855253af4f68a497John McCall  // see the old value.
1661545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  EmitStoreOfScalar(newValue, dst);
1662f85e193739c953358c865005855253af4f68a497John McCall
1663f85e193739c953358c865005855253af4f68a497John McCall  // Finally, release the old value.
1664f85e193739c953358c865005855253af4f68a497John McCall  EmitARCRelease(oldValue, /*precise*/ false);
1665f85e193739c953358c865005855253af4f68a497John McCall
1666f85e193739c953358c865005855253af4f68a497John McCall  return newValue;
1667f85e193739c953358c865005855253af4f68a497John McCall}
1668f85e193739c953358c865005855253af4f68a497John McCall
1669f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1670f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %value)
1671f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) {
1672f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1673f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_autorelease,
1674f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autorelease");
1675f85e193739c953358c865005855253af4f68a497John McCall}
1676f85e193739c953358c865005855253af4f68a497John McCall
1677f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1678f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleaseReturnValue(i8* %value)
1679f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1680f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
1681f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1682f85e193739c953358c865005855253af4f68a497John McCall                            CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
1683f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autoreleaseReturnValue");
1684f85e193739c953358c865005855253af4f68a497John McCall}
1685f85e193739c953358c865005855253af4f68a497John McCall
1686f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1687f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleaseReturnValue(i8* %value)
1688f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1689f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
1690f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1691f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
1692f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleaseReturnValue");
1693f85e193739c953358c865005855253af4f68a497John McCall}
1694f85e193739c953358c865005855253af4f68a497John McCall
1695f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1696f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1697f85e193739c953358c865005855253af4f68a497John McCall/// or
1698f85e193739c953358c865005855253af4f68a497John McCall///   %retain = call i8* @objc_retainBlock(i8* %value)
1699f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %retain)
1700f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
1701f85e193739c953358c865005855253af4f68a497John McCall                                                       llvm::Value *value) {
1702f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isBlockPointerType())
1703f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainAutoreleaseNonBlock(value);
1704f85e193739c953358c865005855253af4f68a497John McCall
1705f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1706f85e193739c953358c865005855253af4f68a497John McCall
17072acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1708f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1709f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCRetainBlock(value);
1710f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCAutorelease(value);
1711f85e193739c953358c865005855253af4f68a497John McCall  return Builder.CreateBitCast(value, origType);
1712f85e193739c953358c865005855253af4f68a497John McCall}
1713f85e193739c953358c865005855253af4f68a497John McCall
1714f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1715f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1716f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1717f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) {
1718f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1719f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainAutorelease,
1720f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutorelease");
1721f85e193739c953358c865005855253af4f68a497John McCall}
1722f85e193739c953358c865005855253af4f68a497John McCall
1723f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeak(i8** %addr)
1724f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_autorelease(objc_loadWeakRetained(addr)).
1725f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeak(llvm::Value *addr) {
1726f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1727f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeak,
1728f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeak");
1729f85e193739c953358c865005855253af4f68a497John McCall}
1730f85e193739c953358c865005855253af4f68a497John McCall
1731f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeakRetained(i8** %addr)
1732f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(llvm::Value *addr) {
1733f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1734f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeakRetained,
1735f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeakRetained");
1736f85e193739c953358c865005855253af4f68a497John McCall}
1737f85e193739c953358c865005855253af4f68a497John McCall
1738f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_storeWeak(i8** %addr, i8* %value)
1739f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.
1740f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreWeak(llvm::Value *addr,
1741f85e193739c953358c865005855253af4f68a497John McCall                                               llvm::Value *value,
1742f85e193739c953358c865005855253af4f68a497John McCall                                               bool ignored) {
1743f85e193739c953358c865005855253af4f68a497John McCall  return emitARCStoreOperation(*this, addr, value,
1744f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_storeWeak,
1745f85e193739c953358c865005855253af4f68a497John McCall                               "objc_storeWeak", ignored);
1746f85e193739c953358c865005855253af4f68a497John McCall}
1747f85e193739c953358c865005855253af4f68a497John McCall
1748f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_initWeak(i8** %addr, i8* %value)
1749f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.  %addr is known to not have a current weak entry.
1750f85e193739c953358c865005855253af4f68a497John McCall/// Essentially equivalent to:
1751f85e193739c953358c865005855253af4f68a497John McCall///   *addr = nil; objc_storeWeak(addr, value);
1752f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCInitWeak(llvm::Value *addr, llvm::Value *value) {
1753f85e193739c953358c865005855253af4f68a497John McCall  // If we're initializing to null, just write null to memory; no need
1754f85e193739c953358c865005855253af4f68a497John McCall  // to get the runtime involved.  But don't do this if optimization
1755f85e193739c953358c865005855253af4f68a497John McCall  // is enabled, because accounting for this would make the optimizer
1756f85e193739c953358c865005855253af4f68a497John McCall  // much more complicated.
1757f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value) &&
1758f85e193739c953358c865005855253af4f68a497John McCall      CGM.getCodeGenOpts().OptimizationLevel == 0) {
1759f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(value, addr);
1760f85e193739c953358c865005855253af4f68a497John McCall    return;
1761f85e193739c953358c865005855253af4f68a497John McCall  }
1762f85e193739c953358c865005855253af4f68a497John McCall
1763f85e193739c953358c865005855253af4f68a497John McCall  emitARCStoreOperation(*this, addr, value,
1764f85e193739c953358c865005855253af4f68a497John McCall                        CGM.getARCEntrypoints().objc_initWeak,
1765f85e193739c953358c865005855253af4f68a497John McCall                        "objc_initWeak", /*ignored*/ true);
1766f85e193739c953358c865005855253af4f68a497John McCall}
1767f85e193739c953358c865005855253af4f68a497John McCall
1768f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_destroyWeak(i8** %addr)
1769f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_storeWeak(addr, nil).
1770f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCDestroyWeak(llvm::Value *addr) {
1771f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_destroyWeak;
1772f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17739cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrPtrTy);
17742acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1775f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1776f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak");
1777f85e193739c953358c865005855253af4f68a497John McCall  }
1778f85e193739c953358c865005855253af4f68a497John McCall
1779f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
1780f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1781f85e193739c953358c865005855253af4f68a497John McCall
1782f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, addr);
1783f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1784f85e193739c953358c865005855253af4f68a497John McCall}
1785f85e193739c953358c865005855253af4f68a497John McCall
1786f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_moveWeak(i8** %dest, i8** %src)
1787f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Leaves %src pointing to nothing.
1788f85e193739c953358c865005855253af4f68a497John McCall/// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)).
1789f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src) {
1790f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1791f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_moveWeak,
1792f85e193739c953358c865005855253af4f68a497John McCall                       "objc_moveWeak");
1793f85e193739c953358c865005855253af4f68a497John McCall}
1794f85e193739c953358c865005855253af4f68a497John McCall
1795f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_copyWeak(i8** %dest, i8** %src)
1796f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Essentially
1797f85e193739c953358c865005855253af4f68a497John McCall///   objc_release(objc_initWeak(dest, objc_readWeakRetained(src)))
1798f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCCopyWeak(llvm::Value *dst, llvm::Value *src) {
1799f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1800f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_copyWeak,
1801f85e193739c953358c865005855253af4f68a497John McCall                       "objc_copyWeak");
1802f85e193739c953358c865005855253af4f68a497John McCall}
1803f85e193739c953358c865005855253af4f68a497John McCall
1804f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a objc_autoreleasepool_push.
1805f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleasePoolPush(void)
1806f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
1807f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPush;
1808f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
18092acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1810f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Int8PtrTy, false);
1811f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush");
1812f85e193739c953358c865005855253af4f68a497John McCall  }
1813f85e193739c953358c865005855253af4f68a497John McCall
1814f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn);
1815f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1816f85e193739c953358c865005855253af4f68a497John McCall
1817f85e193739c953358c865005855253af4f68a497John McCall  return call;
1818f85e193739c953358c865005855253af4f68a497John McCall}
1819f85e193739c953358c865005855253af4f68a497John McCall
1820f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1821f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_autoreleasePoolPop(i8* %ptr)
1822f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
1823f85e193739c953358c865005855253af4f68a497John McCall  assert(value->getType() == Int8PtrTy);
1824f85e193739c953358c865005855253af4f68a497John McCall
1825f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPop;
1826f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
18279cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
18282acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1829f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1830f85e193739c953358c865005855253af4f68a497John McCall
1831f85e193739c953358c865005855253af4f68a497John McCall    // We don't want to use a weak import here; instead we should not
1832f85e193739c953358c865005855253af4f68a497John McCall    // fall into this path.
1833f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop");
1834f85e193739c953358c865005855253af4f68a497John McCall  }
1835f85e193739c953358c865005855253af4f68a497John McCall
1836f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1837f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1838f85e193739c953358c865005855253af4f68a497John McCall}
1839f85e193739c953358c865005855253af4f68a497John McCall
1840f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do an MRR version objc_autoreleasepool_push.
1841f85e193739c953358c865005855253af4f68a497John McCall/// Which is: [[NSAutoreleasePool alloc] init];
1842f85e193739c953358c865005855253af4f68a497John McCall/// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class.
1843f85e193739c953358c865005855253af4f68a497John McCall/// init is declared as: - (id) init; in its NSObject super class.
1844f85e193739c953358c865005855253af4f68a497John McCall///
1845f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() {
1846f85e193739c953358c865005855253af4f68a497John McCall  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
1847f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(Builder);
1848f85e193739c953358c865005855253af4f68a497John McCall  // [NSAutoreleasePool alloc]
1849f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");
1850f85e193739c953358c865005855253af4f68a497John McCall  Selector AllocSel = getContext().Selectors.getSelector(0, &II);
1851f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1852f85e193739c953358c865005855253af4f68a497John McCall  RValue AllocRV =
1853f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1854f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1855f85e193739c953358c865005855253af4f68a497John McCall                                AllocSel, Receiver, Args);
1856f85e193739c953358c865005855253af4f68a497John McCall
1857f85e193739c953358c865005855253af4f68a497John McCall  // [Receiver init]
1858f85e193739c953358c865005855253af4f68a497John McCall  Receiver = AllocRV.getScalarVal();
1859f85e193739c953358c865005855253af4f68a497John McCall  II = &CGM.getContext().Idents.get("init");
1860f85e193739c953358c865005855253af4f68a497John McCall  Selector InitSel = getContext().Selectors.getSelector(0, &II);
1861f85e193739c953358c865005855253af4f68a497John McCall  RValue InitRV =
1862f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1863f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1864f85e193739c953358c865005855253af4f68a497John McCall                                InitSel, Receiver, Args);
1865f85e193739c953358c865005855253af4f68a497John McCall  return InitRV.getScalarVal();
1866f85e193739c953358c865005855253af4f68a497John McCall}
1867f85e193739c953358c865005855253af4f68a497John McCall
1868f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1869f85e193739c953358c865005855253af4f68a497John McCall/// [tmp drain];
1870f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) {
1871f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("drain");
1872f85e193739c953358c865005855253af4f68a497John McCall  Selector DrainSel = getContext().Selectors.getSelector(0, &II);
1873f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1874f85e193739c953358c865005855253af4f68a497John McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1875f85e193739c953358c865005855253af4f68a497John McCall                              getContext().VoidTy, DrainSel, Arg, Args);
1876f85e193739c953358c865005855253af4f68a497John McCall}
1877f85e193739c953358c865005855253af4f68a497John McCall
1878bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
1879bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              llvm::Value *addr,
1880bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              QualType type) {
1881bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1882bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ true);
1883bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1884bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1885bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
1886bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                llvm::Value *addr,
1887bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                QualType type) {
1888bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1889bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ false);
1890bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1891bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1892bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
1893bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     llvm::Value *addr,
1894bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     QualType type) {
1895bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCDestroyWeak(addr);
1896bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1897bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1898f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1899f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCAutoreleasePoolObject : EHScopeStack::Cleanup {
1900f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1901f85e193739c953358c865005855253af4f68a497John McCall
1902f85e193739c953358c865005855253af4f68a497John McCall    CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1903f85e193739c953358c865005855253af4f68a497John McCall
1904ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1905f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCAutoreleasePoolPop(Token);
1906f85e193739c953358c865005855253af4f68a497John McCall    }
1907f85e193739c953358c865005855253af4f68a497John McCall  };
1908f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCMRRAutoreleasePoolObject : EHScopeStack::Cleanup {
1909f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1910f85e193739c953358c865005855253af4f68a497John McCall
1911f85e193739c953358c865005855253af4f68a497John McCall    CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1912f85e193739c953358c865005855253af4f68a497John McCall
1913ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1914f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCMRRAutoreleasePoolPop(Token);
1915f85e193739c953358c865005855253af4f68a497John McCall    }
1916f85e193739c953358c865005855253af4f68a497John McCall  };
1917f85e193739c953358c865005855253af4f68a497John McCall}
1918f85e193739c953358c865005855253af4f68a497John McCall
1919f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
1920f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount)
1921f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr);
1922f85e193739c953358c865005855253af4f68a497John McCall  else
1923f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr);
1924f85e193739c953358c865005855253af4f68a497John McCall}
1925f85e193739c953358c865005855253af4f68a497John McCall
1926f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1927f85e193739c953358c865005855253af4f68a497John McCall                                                  LValue lvalue,
1928f85e193739c953358c865005855253af4f68a497John McCall                                                  QualType type) {
1929f85e193739c953358c865005855253af4f68a497John McCall  switch (type.getObjCLifetime()) {
1930f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
1931f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
1932f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong:
1933f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
1934545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue).getScalarVal(),
1935f85e193739c953358c865005855253af4f68a497John McCall                         false);
1936f85e193739c953358c865005855253af4f68a497John McCall
1937f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:
1938f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitARCLoadWeakRetained(lvalue.getAddress()),
1939f85e193739c953358c865005855253af4f68a497John McCall                         true);
1940f85e193739c953358c865005855253af4f68a497John McCall  }
1941f85e193739c953358c865005855253af4f68a497John McCall
1942f85e193739c953358c865005855253af4f68a497John McCall  llvm_unreachable("impossible lifetime!");
1943f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult();
1944f85e193739c953358c865005855253af4f68a497John McCall}
1945f85e193739c953358c865005855253af4f68a497John McCall
1946f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1947f85e193739c953358c865005855253af4f68a497John McCall                                                  const Expr *e) {
1948f85e193739c953358c865005855253af4f68a497John McCall  e = e->IgnoreParens();
1949f85e193739c953358c865005855253af4f68a497John McCall  QualType type = e->getType();
1950f85e193739c953358c865005855253af4f68a497John McCall
19512148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  // If we're loading retained from a __strong xvalue, we can avoid
19522148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  // an extra retain/release pair by zeroing out the source of this
19532148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  // "move" operation.
19542148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  if (e->isXValue() &&
19552148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall      !type.isConstQualified() &&
19562148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall      type.getObjCLifetime() == Qualifiers::OCL_Strong) {
19572148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    // Emit the lvalue.
19582148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    LValue lv = CGF.EmitLValue(e);
19592148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
19602148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    // Load the object pointer.
19612148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal();
19622148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
19632148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    // Set the source pointer to NULL.
19642148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress()), lv);
19652148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
19662148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    return TryEmitResult(result, true);
19672148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  }
19682148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
1969f85e193739c953358c865005855253af4f68a497John McCall  // As a very special optimization, in ARC++, if the l-value is the
1970f85e193739c953358c865005855253af4f68a497John McCall  // result of a non-volatile assignment, do a simple retain of the
1971f85e193739c953358c865005855253af4f68a497John McCall  // result of the call to objc_storeWeak instead of reloading.
1972f85e193739c953358c865005855253af4f68a497John McCall  if (CGF.getLangOptions().CPlusPlus &&
1973f85e193739c953358c865005855253af4f68a497John McCall      !type.isVolatileQualified() &&
1974f85e193739c953358c865005855253af4f68a497John McCall      type.getObjCLifetime() == Qualifiers::OCL_Weak &&
1975f85e193739c953358c865005855253af4f68a497John McCall      isa<BinaryOperator>(e) &&
1976f85e193739c953358c865005855253af4f68a497John McCall      cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
1977f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitScalarExpr(e), false);
1978f85e193739c953358c865005855253af4f68a497John McCall
1979f85e193739c953358c865005855253af4f68a497John McCall  return tryEmitARCRetainLoadOfScalar(CGF, CGF.EmitLValue(e), type);
1980f85e193739c953358c865005855253af4f68a497John McCall}
1981f85e193739c953358c865005855253af4f68a497John McCall
1982f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1983f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value);
1984f85e193739c953358c865005855253af4f68a497John McCall
1985f85e193739c953358c865005855253af4f68a497John McCall/// Given that the given expression is some sort of call (which does
1986f85e193739c953358c865005855253af4f68a497John McCall/// not return retained), emit a retain following it.
1987f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainCall(CodeGenFunction &CGF, const Expr *e) {
1988f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = CGF.EmitScalarExpr(e);
1989f85e193739c953358c865005855253af4f68a497John McCall  return emitARCRetainAfterCall(CGF, value);
1990f85e193739c953358c865005855253af4f68a497John McCall}
1991f85e193739c953358c865005855253af4f68a497John McCall
1992f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1993f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value) {
1994f85e193739c953358c865005855253af4f68a497John McCall  if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
1995f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
1996f85e193739c953358c865005855253af4f68a497John McCall
1997f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain immediately following the call.
1998f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(call->getParent(),
1999f85e193739c953358c865005855253af4f68a497John McCall                               ++llvm::BasicBlock::iterator(call));
2000f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
2001f85e193739c953358c865005855253af4f68a497John McCall
2002f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
2003f85e193739c953358c865005855253af4f68a497John McCall    return value;
2004f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
2005f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
2006f85e193739c953358c865005855253af4f68a497John McCall
2007f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain at the beginning of the normal destination block.
2008f85e193739c953358c865005855253af4f68a497John McCall    llvm::BasicBlock *BB = invoke->getNormalDest();
2009f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(BB, BB->begin());
2010f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
2011f85e193739c953358c865005855253af4f68a497John McCall
2012f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
2013f85e193739c953358c865005855253af4f68a497John McCall    return value;
2014f85e193739c953358c865005855253af4f68a497John McCall
2015f85e193739c953358c865005855253af4f68a497John McCall  // Bitcasts can arise because of related-result returns.  Rewrite
2016f85e193739c953358c865005855253af4f68a497John McCall  // the operand.
2017f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
2018f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *operand = bitcast->getOperand(0);
2019f85e193739c953358c865005855253af4f68a497John McCall    operand = emitARCRetainAfterCall(CGF, operand);
2020f85e193739c953358c865005855253af4f68a497John McCall    bitcast->setOperand(0, operand);
2021f85e193739c953358c865005855253af4f68a497John McCall    return bitcast;
2022f85e193739c953358c865005855253af4f68a497John McCall
2023f85e193739c953358c865005855253af4f68a497John McCall  // Generic fall-back case.
2024f85e193739c953358c865005855253af4f68a497John McCall  } else {
2025f85e193739c953358c865005855253af4f68a497John McCall    // Retain using the non-block variant: we never need to do a copy
2026f85e193739c953358c865005855253af4f68a497John McCall    // of a block that's been returned to us.
2027f85e193739c953358c865005855253af4f68a497John McCall    return CGF.EmitARCRetainNonBlock(value);
2028f85e193739c953358c865005855253af4f68a497John McCall  }
2029f85e193739c953358c865005855253af4f68a497John McCall}
2030f85e193739c953358c865005855253af4f68a497John McCall
2031dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall/// Determine whether it might be important to emit a separate
2032dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall/// objc_retain_block on the result of the given expression, or
2033dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall/// whether it's okay to just emit it in a +1 context.
2034dc05b11c67331016473fbc7909827b1b89c9616bJohn McCallstatic bool shouldEmitSeparateBlockRetain(const Expr *e) {
2035dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  assert(e->getType()->isBlockPointerType());
2036dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  e = e->IgnoreParens();
2037dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2038dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  // For future goodness, emit block expressions directly in +1
2039dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  // contexts if we can.
2040dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  if (isa<BlockExpr>(e))
2041dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    return false;
2042dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2043dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  if (const CastExpr *cast = dyn_cast<CastExpr>(e)) {
2044dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    switch (cast->getCastKind()) {
2045dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    // Emitting these operations in +1 contexts is goodness.
2046dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_LValueToRValue:
204733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    case CK_ARCReclaimReturnedObject:
204833e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    case CK_ARCConsumeObject:
204933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    case CK_ARCProduceObject:
2050dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      return false;
2051dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2052dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    // These operations preserve a block type.
2053dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_NoOp:
2054dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_BitCast:
2055dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      return shouldEmitSeparateBlockRetain(cast->getSubExpr());
2056dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2057dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    // These operations are known to be bad (or haven't been considered).
2058dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_AnyPointerToBlockPointerCast:
2059dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    default:
2060dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      return true;
2061dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    }
2062dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  }
2063dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2064dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  return true;
2065dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall}
2066dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2067f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult
2068f85e193739c953358c865005855253af4f68a497John McCalltryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
2069990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Look through cleanups.
2070990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
2071990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    CodeGenFunction::RunCleanupsScope scope(CGF);
2072990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    return tryEmitARCRetainScalarExpr(CGF, cleanups->getSubExpr());
2073990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
2074990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
2075f85e193739c953358c865005855253af4f68a497John McCall  // The desired result type, if it differs from the type of the
2076f85e193739c953358c865005855253af4f68a497John McCall  // ultimate opaque expression.
20772acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *resultType = 0;
2078f85e193739c953358c865005855253af4f68a497John McCall
2079f85e193739c953358c865005855253af4f68a497John McCall  while (true) {
2080f85e193739c953358c865005855253af4f68a497John McCall    e = e->IgnoreParens();
2081f85e193739c953358c865005855253af4f68a497John McCall
2082f85e193739c953358c865005855253af4f68a497John McCall    // There's a break at the end of this if-chain;  anything
2083f85e193739c953358c865005855253af4f68a497John McCall    // that wants to keep looping has to explicitly continue.
2084f85e193739c953358c865005855253af4f68a497John McCall    if (const CastExpr *ce = dyn_cast<CastExpr>(e)) {
2085f85e193739c953358c865005855253af4f68a497John McCall      switch (ce->getCastKind()) {
2086f85e193739c953358c865005855253af4f68a497John McCall      // No-op casts don't change the type, so we just ignore them.
2087f85e193739c953358c865005855253af4f68a497John McCall      case CK_NoOp:
2088f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
2089f85e193739c953358c865005855253af4f68a497John McCall        continue;
2090f85e193739c953358c865005855253af4f68a497John McCall
2091f85e193739c953358c865005855253af4f68a497John McCall      case CK_LValueToRValue: {
2092f85e193739c953358c865005855253af4f68a497John McCall        TryEmitResult loadResult
2093f85e193739c953358c865005855253af4f68a497John McCall          = tryEmitARCRetainLoadOfScalar(CGF, ce->getSubExpr());
2094f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) {
2095f85e193739c953358c865005855253af4f68a497John McCall          llvm::Value *value = loadResult.getPointer();
2096f85e193739c953358c865005855253af4f68a497John McCall          value = CGF.Builder.CreateBitCast(value, resultType);
2097f85e193739c953358c865005855253af4f68a497John McCall          loadResult.setPointer(value);
2098f85e193739c953358c865005855253af4f68a497John McCall        }
2099f85e193739c953358c865005855253af4f68a497John McCall        return loadResult;
2100f85e193739c953358c865005855253af4f68a497John McCall      }
2101f85e193739c953358c865005855253af4f68a497John McCall
2102f85e193739c953358c865005855253af4f68a497John McCall      // These casts can change the type, so remember that and
2103f85e193739c953358c865005855253af4f68a497John McCall      // soldier on.  We only need to remember the outermost such
2104f85e193739c953358c865005855253af4f68a497John McCall      // cast, though.
21051d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      case CK_CPointerToObjCPointerCast:
21061d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      case CK_BlockPointerToObjCPointerCast:
2107f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToBlockPointerCast:
2108f85e193739c953358c865005855253af4f68a497John McCall      case CK_BitCast:
2109f85e193739c953358c865005855253af4f68a497John McCall        if (!resultType)
2110f85e193739c953358c865005855253af4f68a497John McCall          resultType = CGF.ConvertType(ce->getType());
2111f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
2112f85e193739c953358c865005855253af4f68a497John McCall        assert(e->getType()->hasPointerRepresentation());
2113f85e193739c953358c865005855253af4f68a497John McCall        continue;
2114f85e193739c953358c865005855253af4f68a497John McCall
2115f85e193739c953358c865005855253af4f68a497John McCall      // For consumptions, just emit the subexpression and thus elide
2116f85e193739c953358c865005855253af4f68a497John McCall      // the retain/release pair.
211733e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      case CK_ARCConsumeObject: {
2118f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = CGF.EmitScalarExpr(ce->getSubExpr());
2119f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2120f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2121f85e193739c953358c865005855253af4f68a497John McCall      }
2122f85e193739c953358c865005855253af4f68a497John McCall
2123dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      // Block extends are net +0.  Naively, we could just recurse on
2124dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      // the subexpression, but actually we need to ensure that the
2125dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      // value is copied as a block, so there's a little filter here.
212633e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      case CK_ARCExtendBlockObject: {
2127dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        llvm::Value *result; // will be a +0 value
2128dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2129dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // If we can't safely assume the sub-expression will produce a
2130dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // block-copied value, emit the sub-expression at +0.
2131dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        if (shouldEmitSeparateBlockRetain(ce->getSubExpr())) {
2132dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          result = CGF.EmitScalarExpr(ce->getSubExpr());
2133dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2134dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // Otherwise, try to emit the sub-expression at +1 recursively.
2135dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        } else {
2136dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          TryEmitResult subresult
2137dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall            = tryEmitARCRetainScalarExpr(CGF, ce->getSubExpr());
2138dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          result = subresult.getPointer();
2139dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2140dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          // If that produced a retained value, just use that,
2141dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          // possibly casting down.
2142dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          if (subresult.getInt()) {
2143dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall            if (resultType)
2144dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall              result = CGF.Builder.CreateBitCast(result, resultType);
2145dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall            return TryEmitResult(result, true);
2146dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          }
2147dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2148dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          // Otherwise it's +0.
2149dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        }
2150dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2151dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // Retain the object as a block, then cast down.
2152dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        result = CGF.EmitARCRetainBlock(result);
2153dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2154dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        return TryEmitResult(result, true);
2155dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      }
2156dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
21577e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // For reclaims, emit the subexpression as a retained call and
21587e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // skip the consumption.
215933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      case CK_ARCReclaimReturnedObject: {
21607e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce->getSubExpr());
21617e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
21627e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        return TryEmitResult(result, true);
21637e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      }
21647e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall
2165f85e193739c953358c865005855253af4f68a497John McCall      case CK_GetObjCProperty: {
2166f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce);
2167f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2168f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2169f85e193739c953358c865005855253af4f68a497John McCall      }
2170f85e193739c953358c865005855253af4f68a497John McCall
2171f85e193739c953358c865005855253af4f68a497John McCall      default:
2172f85e193739c953358c865005855253af4f68a497John McCall        break;
2173f85e193739c953358c865005855253af4f68a497John McCall      }
2174f85e193739c953358c865005855253af4f68a497John McCall
2175f85e193739c953358c865005855253af4f68a497John McCall    // Skip __extension__.
2176f85e193739c953358c865005855253af4f68a497John McCall    } else if (const UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
2177f85e193739c953358c865005855253af4f68a497John McCall      if (op->getOpcode() == UO_Extension) {
2178f85e193739c953358c865005855253af4f68a497John McCall        e = op->getSubExpr();
2179f85e193739c953358c865005855253af4f68a497John McCall        continue;
2180f85e193739c953358c865005855253af4f68a497John McCall      }
2181f85e193739c953358c865005855253af4f68a497John McCall
2182f85e193739c953358c865005855253af4f68a497John McCall    // For calls and message sends, use the retained-call logic.
2183f85e193739c953358c865005855253af4f68a497John McCall    // Delegate inits are a special case in that they're the only
2184f85e193739c953358c865005855253af4f68a497John McCall    // returns-retained expression that *isn't* surrounded by
2185f85e193739c953358c865005855253af4f68a497John McCall    // a consume.
2186f85e193739c953358c865005855253af4f68a497John McCall    } else if (isa<CallExpr>(e) ||
2187f85e193739c953358c865005855253af4f68a497John McCall               (isa<ObjCMessageExpr>(e) &&
2188f85e193739c953358c865005855253af4f68a497John McCall                !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
2189f85e193739c953358c865005855253af4f68a497John McCall      llvm::Value *result = emitARCRetainCall(CGF, e);
2190f85e193739c953358c865005855253af4f68a497John McCall      if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2191f85e193739c953358c865005855253af4f68a497John McCall      return TryEmitResult(result, true);
2192f85e193739c953358c865005855253af4f68a497John McCall    }
2193f85e193739c953358c865005855253af4f68a497John McCall
2194f85e193739c953358c865005855253af4f68a497John McCall    // Conservatively halt the search at any other expression kind.
2195f85e193739c953358c865005855253af4f68a497John McCall    break;
2196f85e193739c953358c865005855253af4f68a497John McCall  }
2197f85e193739c953358c865005855253af4f68a497John McCall
2198f85e193739c953358c865005855253af4f68a497John McCall  // We didn't find an obvious production, so emit what we've got and
2199f85e193739c953358c865005855253af4f68a497John McCall  // tell the caller that we didn't manage to retain.
2200f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = CGF.EmitScalarExpr(e);
2201f85e193739c953358c865005855253af4f68a497John McCall  if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2202f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult(result, false);
2203f85e193739c953358c865005855253af4f68a497John McCall}
2204f85e193739c953358c865005855253af4f68a497John McCall
2205f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2206f85e193739c953358c865005855253af4f68a497John McCall                                                LValue lvalue,
2207f85e193739c953358c865005855253af4f68a497John McCall                                                QualType type) {
2208f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainLoadOfScalar(CGF, lvalue, type);
2209f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2210f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2211f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetain(type, value);
2212f85e193739c953358c865005855253af4f68a497John McCall  return value;
2213f85e193739c953358c865005855253af4f68a497John McCall}
2214f85e193739c953358c865005855253af4f68a497John McCall
2215f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainScalarExpr - Semantically equivalent to
2216f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a
2217f85e193739c953358c865005855253af4f68a497John McCall/// best-effort attempt to peephole expressions that naturally produce
2218f85e193739c953358c865005855253af4f68a497John McCall/// retained objects.
2219f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
2220f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2221f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2222f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2223f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetain(e->getType(), value);
2224f85e193739c953358c865005855253af4f68a497John McCall  return value;
2225f85e193739c953358c865005855253af4f68a497John McCall}
2226f85e193739c953358c865005855253af4f68a497John McCall
2227f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
2228f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {
2229f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2230f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2231f85e193739c953358c865005855253af4f68a497John McCall  if (result.getInt())
2232f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCAutorelease(value);
2233f85e193739c953358c865005855253af4f68a497John McCall  else
2234f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetainAutorelease(e->getType(), value);
2235f85e193739c953358c865005855253af4f68a497John McCall  return value;
2236f85e193739c953358c865005855253af4f68a497John McCall}
2237f85e193739c953358c865005855253af4f68a497John McCall
2238f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2239f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
2240f85e193739c953358c865005855253af4f68a497John McCall                                    bool ignored) {
2241f85e193739c953358c865005855253af4f68a497John McCall  // Evaluate the RHS first.
2242f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS());
2243f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2244f85e193739c953358c865005855253af4f68a497John McCall
2245fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  bool hasImmediateRetain = result.getInt();
2246fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall
2247fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // If we didn't emit a retained object, and the l-value is of block
2248fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // type, then we need to emit the block-retain immediately in case
2249fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // it invalidates the l-value.
2250fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  if (!hasImmediateRetain && e->getType()->isBlockPointerType()) {
2251fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall    value = EmitARCRetainBlock(value);
2252fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall    hasImmediateRetain = true;
2253fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  }
2254fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall
2255f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2256f85e193739c953358c865005855253af4f68a497John McCall
2257f85e193739c953358c865005855253af4f68a497John McCall  // If the RHS was emitted retained, expand this.
2258fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  if (hasImmediateRetain) {
2259f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *oldValue =
2260f85e193739c953358c865005855253af4f68a497John McCall      EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatileQualified(),
2261f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getAlignment(), e->getType(),
2262f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getTBAAInfo());
2263f85e193739c953358c865005855253af4f68a497John McCall    EmitStoreOfScalar(value, lvalue.getAddress(),
2264f85e193739c953358c865005855253af4f68a497John McCall                      lvalue.isVolatileQualified(), lvalue.getAlignment(),
2265f85e193739c953358c865005855253af4f68a497John McCall                      e->getType(), lvalue.getTBAAInfo());
2266f85e193739c953358c865005855253af4f68a497John McCall    EmitARCRelease(oldValue, /*precise*/ false);
2267f85e193739c953358c865005855253af4f68a497John McCall  } else {
2268545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    value = EmitARCStoreStrong(lvalue, value, ignored);
2269f85e193739c953358c865005855253af4f68a497John McCall  }
2270f85e193739c953358c865005855253af4f68a497John McCall
2271f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2272f85e193739c953358c865005855253af4f68a497John McCall}
2273f85e193739c953358c865005855253af4f68a497John McCall
2274f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2275f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) {
2276f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = EmitARCRetainAutoreleaseScalarExpr(e->getRHS());
2277f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2278f85e193739c953358c865005855253af4f68a497John McCall
2279f85e193739c953358c865005855253af4f68a497John McCall  EmitStoreOfScalar(value, lvalue.getAddress(),
2280f85e193739c953358c865005855253af4f68a497John McCall                    lvalue.isVolatileQualified(), lvalue.getAlignment(),
2281f85e193739c953358c865005855253af4f68a497John McCall                    e->getType(), lvalue.getTBAAInfo());
2282f85e193739c953358c865005855253af4f68a497John McCall
2283f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2284f85e193739c953358c865005855253af4f68a497John McCall}
2285f85e193739c953358c865005855253af4f68a497John McCall
2286f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolStmt(
2287f85e193739c953358c865005855253af4f68a497John McCall                                             const ObjCAutoreleasePoolStmt &ARPS) {
2288f85e193739c953358c865005855253af4f68a497John McCall  const Stmt *subStmt = ARPS.getSubStmt();
2289f85e193739c953358c865005855253af4f68a497John McCall  const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
2290f85e193739c953358c865005855253af4f68a497John McCall
2291f85e193739c953358c865005855253af4f68a497John McCall  CGDebugInfo *DI = getDebugInfo();
2292f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2293f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getLBracLoc());
2294f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionStart(Builder);
2295f85e193739c953358c865005855253af4f68a497John McCall  }
2296f85e193739c953358c865005855253af4f68a497John McCall
2297f85e193739c953358c865005855253af4f68a497John McCall  // Keep track of the current cleanup stack depth.
2298f85e193739c953358c865005855253af4f68a497John McCall  RunCleanupsScope Scope(*this);
22999f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (CGM.getCodeGenOpts().ObjCRuntimeHasARC) {
2300f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCAutoreleasePoolPush();
2301f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token);
2302f85e193739c953358c865005855253af4f68a497John McCall  } else {
2303f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCMRRAutoreleasePoolPush();
2304f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token);
2305f85e193739c953358c865005855253af4f68a497John McCall  }
2306f85e193739c953358c865005855253af4f68a497John McCall
2307f85e193739c953358c865005855253af4f68a497John McCall  for (CompoundStmt::const_body_iterator I = S.body_begin(),
2308f85e193739c953358c865005855253af4f68a497John McCall       E = S.body_end(); I != E; ++I)
2309f85e193739c953358c865005855253af4f68a497John McCall    EmitStmt(*I);
2310f85e193739c953358c865005855253af4f68a497John McCall
2311f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2312f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getRBracLoc());
2313f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionEnd(Builder);
2314f85e193739c953358c865005855253af4f68a497John McCall  }
2315f85e193739c953358c865005855253af4f68a497John McCall}
23160c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
23170c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
23180c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// make sure it survives garbage collection until this point.
23190c24c808e4dce43e88abf2d5f98546b901bd4315John McCallvoid CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
23200c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  // We just use an inline assembly.
23210c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::FunctionType *extenderType
2322da549e8995c447542d5631b8b67fcc3a9582797aJay Foad    = llvm::FunctionType::get(VoidTy, VoidPtrTy, /*variadic*/ false);
23230c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::Value *extender
23240c24c808e4dce43e88abf2d5f98546b901bd4315John McCall    = llvm::InlineAsm::get(extenderType,
23250c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* assembly */ "",
23260c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* constraints */ "r",
23270c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* side effects */ true);
23280c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
23290c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  object = Builder.CreateBitCast(object, VoidPtrTy);
23300c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  Builder.CreateCall(extender, object)->setDoesNotThrow();
23310c24c808e4dce43e88abf2d5f98546b901bd4315John McCall}
23320c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
23332979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
2334