CGObjC.cpp revision 410ffb2bc5f072d58a73c14560345bcf77dec1cc
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 {
4452846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    const llvm::Triple &Triple = getContext().Target.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
58401cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanianstatic bool
58501cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz JahanianIvarAssignHasTrvialAssignment(const ObjCPropertyImplDecl *PID,
58601cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian                              QualType IvarT) {
58701cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  bool HasTrvialAssignment = true;
58801cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  if (PID->getSetterCXXAssignment()) {
58901cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian    const CXXRecordDecl *classDecl = IvarT->getAsCXXRecordDecl();
59001cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian    HasTrvialAssignment =
59101cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian      (!classDecl || classDecl->hasTrivialCopyAssignment());
59201cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  }
59301cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  return HasTrvialAssignment;
59401cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian}
59501cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian
596af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCSetter - Generate an Objective-C property setter
597489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
598489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// is illegal within a category.
599fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanianvoid CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
600fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian                                         const ObjCPropertyImplDecl *PID) {
60186957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
602af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
603af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
604af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate setter (empty method)");
6058d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
6061d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian  const llvm::Triple &Triple = getContext().Target.getTriple();
6071d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian  QualType IVART = Ivar->getType();
60886957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
6091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool IsAtomic =
61086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
61186957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar
61286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // Determine if we should use an objc_setProperty call for
61386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // this. Properties with 'copy' semantics always use it, as do
61486957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // non-atomic properties with 'release' semantics as long as we are
61586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // not in gc-only mode.
61686957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  if (IsCopy ||
61786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
61886957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
6191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *SetPropertyFn =
62086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      CGM.getObjCRuntime().GetPropertySetFunction();
6211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    if (!SetPropertyFn) {
62386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
62486957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      FinishFunction();
62586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      return;
62686957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    }
6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Emit objc_setProperty((id) self, _cmd, offset, arg,
62986957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    //                       <is-atomic>, <is-copy>).
63086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    // FIXME: Can't this be simpler? This might even be worse than the
63186957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    // corresponding gcc code.
63286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    CodeGenTypes &Types = CGM.getTypes();
63386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    ValueDecl *Cmd = OMD->getCmdDecl();
63486957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
63586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    QualType IdTy = getContext().getObjCIdType();
6361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *SelfAsId =
63786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
638fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
63989951a86b594513c2a013532ed45d197413b1087Chris Lattner    llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
6401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *ArgAsId =
64186957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
64286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar                            Types.ConvertType(IdTy));
64386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    llvm::Value *True =
6444a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
64586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    llvm::Value *False =
6464a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
64786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    CallArgList Args;
64804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(SelfAsId), IdTy);
64904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(CmdVal), Cmd->getType());
65004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(Offset), getContext().getPointerDiffType());
65104c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(ArgAsId), IdTy);
65204c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(IsAtomic ? True : False),  getContext().BoolTy);
65304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(IsCopy ? True : False), getContext().BoolTy);
654f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // FIXME: We shouldn't need to get the function info here, the runtime
655f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // already should have computed it to build the function.
65604a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
657264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                   FunctionType::ExtInfo()),
658264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola             SetPropertyFn,
659f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson             ReturnValueSlot(), Args);
6601d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian  } else if (IsAtomic && hasAggregateLLVMType(IVART) &&
6611d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             !IVART->isAnyComplexType() &&
66201cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian             IvarAssignHasTrvialAssignment(PID, IVART) &&
6631d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             ((Triple.getArch() == llvm::Triple::x86 &&
6641d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              (getContext().getTypeSizeInChars(IVART)
6651d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian               > CharUnits::fromQuantity(4))) ||
6661d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              (Triple.getArch() == llvm::Triple::x86_64 &&
6671d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              (getContext().getTypeSizeInChars(IVART)
6681d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian               > CharUnits::fromQuantity(8))))
6698fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall             && CGM.getObjCRuntime().GetSetStructFunction()) {
6701d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          // objc_copyStruct (&structIvar, &Arg,
6711d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          //                  sizeof (struct something), true, false);
6722846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    GenerateObjCAtomicSetterBody(OMD, Ivar);
67397a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian  } else if (PID->getSetterCXXAssignment()) {
6742a41637a995affa1563f4d82a8b026e326a2faa0John McCall    EmitIgnoredExpr(PID->getSetterCXXAssignment());
67586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  } else {
6762846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    if (IsAtomic &&
6772846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        IVART->isScalarType() &&
6782846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (Triple.getArch() == llvm::Triple::arm ||
6792846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian         Triple.getArch() == llvm::Triple::thumb) &&
6802846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (getContext().getTypeSizeInChars(IVART)
6812846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian          > CharUnits::fromQuantity(4)) &&
6822846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        CGM.getObjCRuntime().GetGetStructFunction()) {
6832846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      GenerateObjCAtomicSetterBody(OMD, Ivar);
6841d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
6851d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
6861d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
6871d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86 &&
6881d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
6891d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(4)) &&
6901d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
6911d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCAtomicSetterBody(OMD, Ivar);
6921d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
6931d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
6941d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
6951d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86_64 &&
6961d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
6971d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(8)) &&
6981d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
6991d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCAtomicSetterBody(OMD, Ivar);
7002846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    }
7012846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    else {
7022846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      // FIXME: Find a clean way to avoid AST node creation.
7038d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel      SourceLocation Loc = PID->getLocStart();
7042846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ValueDecl *Self = OMD->getSelfDecl();
7052846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
7062846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      DeclRefExpr Base(Self, Self->getType(), VK_RValue, Loc);
7072846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ParmVarDecl *ArgDecl = *OMD->param_begin();
70814086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian      QualType T = ArgDecl->getType();
70914086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian      if (T->isReferenceType())
71014086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian        T = cast<ReferenceType>(T)->getPointeeType();
71114086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian      DeclRefExpr Arg(ArgDecl, T, VK_LValue, Loc);
7122846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true);
71345e8423d7dcea657c14c55347e8a30ac904d7501Daniel Dunbar
7142846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      // The property type can differ from the ivar type in some situations with
7152846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      // Objective-C pointer types, we can always bit cast the RHS in these cases.
7162846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      if (getContext().getCanonicalType(Ivar->getType()) !=
7172846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian          getContext().getCanonicalType(ArgDecl->getType())) {
7182846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        ImplicitCastExpr ArgCasted(ImplicitCastExpr::OnStack,
7192846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                   Ivar->getType(), CK_BitCast, &Arg,
7202846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                   VK_RValue);
7212846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        BinaryOperator Assign(&IvarRef, &ArgCasted, BO_Assign,
7222846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                              Ivar->getType(), VK_RValue, OK_Ordinary, Loc);
7232846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        EmitStmt(&Assign);
7242846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      } else {
7252846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        BinaryOperator Assign(&IvarRef, &Arg, BO_Assign,
7262846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                              Ivar->getType(), VK_RValue, OK_Ordinary, Loc);
7272846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        EmitStmt(&Assign);
7282846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      }
72945e8423d7dcea657c14c55347e8a30ac904d7501Daniel Dunbar    }
73086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  }
731af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
732af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
7334111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
7344111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
735e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallnamespace {
7369928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  struct DestroyIvar : EHScopeStack::Cleanup {
7379928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  private:
7389928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    llvm::Value *addr;
739e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    const ObjCIvarDecl *ivar;
7409928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer &destroyer;
7419928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    bool useEHCleanupForArray;
7429928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  public:
7439928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
7449928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                CodeGenFunction::Destroyer *destroyer,
7459928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                bool useEHCleanupForArray)
7469928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      : addr(addr), ivar(ivar), destroyer(*destroyer),
7479928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        useEHCleanupForArray(useEHCleanupForArray) {}
748e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
749ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
7509928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      LValue lvalue
7519928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0);
7529928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      CGF.emitDestroy(lvalue.getAddress(), ivar->getType(), destroyer,
753ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall                      flags.isForNormalCleanup() && useEHCleanupForArray);
754e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
755e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  };
756e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
757e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
7589928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall/// Like CodeGenFunction::destroyARCStrong, but do it with a call.
7599928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCallstatic void destroyARCStrongWithStore(CodeGenFunction &CGF,
7609928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      llvm::Value *addr,
7619928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      QualType type) {
7629928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  llvm::Value *null = getNullForVariable(addr);
7639928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  CGF.EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
7649928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall}
765f85e193739c953358c865005855253af4f68a497John McCall
766e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallstatic void emitCXXDestructMethod(CodeGenFunction &CGF,
767e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall                                  ObjCImplementationDecl *impl) {
768e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  CodeGenFunction::RunCleanupsScope scope(CGF);
769e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
770e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  llvm::Value *self = CGF.LoadObjCSelf();
771e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
772db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *iface = impl->getClassInterface();
773db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
774e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall       ivar; ivar = ivar->getNextIvar()) {
775e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    QualType type = ivar->getType();
776e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
777e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    // Check whether the ivar is a destructible type.
7789928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    QualType::DestructionKind dtorKind = type.isDestructedType();
7799928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (!dtorKind) continue;
7809928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7819928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer *destroyer = 0;
7829928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7839928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Use a call to objc_storeStrong to destroy strong ivars, for the
7849928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // general benefit of the tools.
7859928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (dtorKind == QualType::DK_objc_strong_lifetime) {
7869928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &destroyARCStrongWithStore;
7879928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7889928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Otherwise use the default for the destruction kind.
7899928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    } else {
7909928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &CGF.getDestroyer(dtorKind);
791e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
7929928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7939928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind);
7949928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7959928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CGF.EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
7969928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                         cleanupKind & EHCleanup);
797e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  }
798e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
799e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
800e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
801e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
802109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanianvoid CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
803109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 ObjCMethodDecl *MD,
804109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 bool ctor) {
805109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
8068d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(MD, IMP->getClassInterface(), MD->getLocStart());
807e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
808e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_construct.
809109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  if (ctor) {
810f85e193739c953358c865005855253af4f68a497John McCall    // Suppress the final autorelease in ARC.
811f85e193739c953358c865005855253af4f68a497John McCall    AutoreleaseResult = false;
812f85e193739c953358c865005855253af4f68a497John McCall
8135f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CXXCtorInitializer *, 8> IvarInitializers;
814e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
815e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall           E = IMP->init_end(); B != E; ++B) {
816e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall      CXXCtorInitializer *IvarInit = (*B);
81700eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet      FieldDecl *Field = IvarInit->getAnyMember();
818109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
8199b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian      LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
8209b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian                                    LoadObjCSelf(), Ivar, 0);
8217c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall      EmitAggExpr(IvarInit->getInit(),
8227c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall                  AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed,
823410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall                                          AggValueSlot::DoesNotNeedGCBarriers,
824410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall                                          AggValueSlot::IsNotAliased));
825109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    }
826109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    // constructor returns 'self'.
827109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    CodeGenTypes &Types = CGM.getTypes();
828109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    QualType IdTy(CGM.getContext().getObjCIdType());
829109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    llvm::Value *SelfAsId =
830109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
831109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
832e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
833e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_destruct.
834bc397cf90355f17c974b0bdf3960e8fb38caf5d6Chandler Carruth  } else {
835e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    emitCXXDestructMethod(*this, IMP);
836109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  }
837109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  FinishFunction();
838109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian}
839109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian
8400b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanianbool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
8410b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
8420b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  it++; it++;
8430b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  const ABIArgInfo &AI = it->info;
8440b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  // FIXME. Is this sufficient check?
8450b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  return (AI.getKind() == ABIArgInfo::Indirect);
8460b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian}
8470b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian
84815bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanianbool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
84915bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
85015bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return false;
85115bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
85215bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return FDTTy->getDecl()->hasObjectMember();
85315bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  return false;
85415bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian}
85515bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian
856c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf() {
857b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
858b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
8594111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
8604111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
86145012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz JahanianQualType CodeGenFunction::TypeOfSelfObject() {
86245012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
86345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
86414108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
86514108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    getContext().getCanonicalType(selfDecl->getType()));
86645012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  return PTy->getPointeeType();
86745012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian}
86845012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
869e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallLValue
870e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallCodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
871e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // This is a special l-value that just issues sends when we load or
872e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // store through it.
873e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
874e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // For certain base kinds, we need to emit the base immediately.
875e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Base;
876e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  if (E->isSuperReceiver())
877e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = LoadObjCSelf();
878e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else if (E->isClassReceiver())
879e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver());
880e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else
881e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = EmitScalarExpr(E->getBase());
882e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return LValue::MakePropertyRef(E, Base);
883e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall}
884e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
885e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallstatic RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
886e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       ReturnValueSlot Return,
887e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       QualType ResultType,
888e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       Selector S,
889e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       llvm::Value *Receiver,
890e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       const CallArgList &CallArgs) {
891e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl);
892f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isClassMessage = OMD->isClassMethod();
893f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
894e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return CGF.CGM.getObjCRuntime()
895e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                .GenerateMessageSendSuper(CGF, Return, ResultType,
896e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          S, OMD->getClassInterface(),
897e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isCategoryImpl, Receiver,
898e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isClassMessage, CallArgs);
899f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian}
900f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian
901119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallRValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
902119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                    ReturnValueSlot Return) {
903119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr();
90468af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ResultType = E->getGetterResultType();
90512f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S;
906926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  const ObjCMethodDecl *method;
90712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isExplicitProperty()) {
90812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    const ObjCPropertyDecl *Property = E->getExplicitProperty();
90912f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    S = Property->getGetterName();
910926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = Property->getGetterMethodDecl();
911b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
912926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = E->getImplicitPropertyGetter();
913926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    S = method->getSelector();
9145daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian  }
91512f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
916e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = LV.getPropertyRefBaseAddr();
917e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
918f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount) {
919f85e193739c953358c865005855253af4f68a497John McCall    QualType receiverType;
920f85e193739c953358c865005855253af4f68a497John McCall    if (E->isSuperReceiver())
921f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getSuperReceiverType();
922f85e193739c953358c865005855253af4f68a497John McCall    else if (E->isClassReceiver())
923f85e193739c953358c865005855253af4f68a497John McCall      receiverType = getContext().getObjCClassType();
924f85e193739c953358c865005855253af4f68a497John McCall    else
925f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getBase()->getType();
926f85e193739c953358c865005855253af4f68a497John McCall  }
927f85e193739c953358c865005855253af4f68a497John McCall
928e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // Accesses to 'super' follow a different code path.
92912f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver())
930926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return AdjustRelatedResultType(*this, E, method,
931926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                   GenerateMessageSendSuper(*this, Return,
932926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            ResultType,
933926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            S, Receiver,
934926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            CallArgList()));
935119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
936119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
937926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return AdjustRelatedResultType(*this, E, method,
938f85e193739c953358c865005855253af4f68a497John McCall          CGM.getObjCRuntime().
939f85e193739c953358c865005855253af4f68a497John McCall             GenerateMessageSend(*this, Return, ResultType, S,
940f85e193739c953358c865005855253af4f68a497John McCall                                 Receiver, CallArgList(), ReceiverClass));
9419c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar}
9429c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
943119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallvoid CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
944119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                        LValue Dst) {
945119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr();
94612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S = E->getSetterSelector();
94768af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ArgType = E->getSetterArgType();
94868af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian
949b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // FIXME. Other than scalars, AST is not adequate for setter and
950b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // getter type mismatches which require conversion.
951b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  if (Src.isScalar()) {
952b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    llvm::Value *SrcVal = Src.getScalarVal();
953b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    QualType DstType = getContext().getCanonicalType(ArgType);
9542acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *DstTy = ConvertType(DstType);
955b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    if (SrcVal->getType() != DstTy)
956b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian      Src =
957b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian        RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType));
958b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  }
959b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian
960e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  CallArgList Args;
96104c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(Src, ArgType);
962e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
963e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = Dst.getPropertyRefBaseAddr();
964e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  QualType ResultType = getContext().VoidTy;
965e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
96612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver()) {
967e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    GenerateMessageSendSuper(*this, ReturnValueSlot(),
968e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                             ResultType, S, Receiver, Args);
96912f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    return;
97012f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  }
97112f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
972119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
973119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
97412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
97512f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
976e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ResultType, S, Receiver, Args,
977e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ReceiverClass);
97885c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar}
97985c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar
98074391b48b4791cded373683a3baf67314f358d50Chris Lattnervoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
9811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Constant *EnumerationMutationFn =
982c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.getObjCRuntime().EnumerationMutationFunction();
9831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
984c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  if (!EnumerationMutationFn) {
985c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
986c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    return;
987c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
988c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
989bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  CGDebugInfo *DI = getDebugInfo();
990bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
991bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getBegin());
992bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionStart(Builder);
993bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
994bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
9959d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  // The local variable comes into scope immediately.
9969d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  AutoVarEmission variable = AutoVarEmission::invalid();
9979d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
9989d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel    variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl()));
9999d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel
1000d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
10011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1002f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fast enumeration state.
10030815b579b31cb3129f732bb7ea36fd6ba6949e98Douglas Gregor  QualType StateTy = CGM.getObjCFastEnumerationStateType();
1004195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
10051884eb0b5c55edda4893ddec45e7dbad79758782Anders Carlsson  EmitNullInitialization(StatePtr, StateTy);
10061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1007f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Number of elements in the items array.
10082abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  static const unsigned NumItems = 16;
10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1010d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the countByEnumeratingWithState:objects:count: selector.
1011ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  IdentifierInfo *II[] = {
1012ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
1013ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("objects"),
1014ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("count")
1015ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  };
1016ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  Selector FastEnumSel =
1017ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
1018f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1019f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ItemsTy =
1020f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    getContext().getConstantArrayType(getContext().getObjCIdType(),
10211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      llvm::APInt(32, NumItems),
1022f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ArrayType::Normal, 0);
1023195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
10241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1025990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Emit the collection pointer.  In ARC, we do a retain.
1026990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  llvm::Value *Collection;
1027990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (getLangOptions().ObjCAutoRefCount) {
1028990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    Collection = EmitARCRetainScalarExpr(S.getCollection());
1029990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1030990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    // Enter a cleanup to do the release.
1031990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    EmitObjCConsumeObject(S.getCollection()->getType(), Collection);
1032990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  } else {
1033990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    Collection = EmitScalarExpr(S.getCollection());
1034990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
10351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
10364b302d32378b364703b212834f908762e570c29cJohn McCall  // The 'continue' label needs to appear within the cleanup for the
10374b302d32378b364703b212834f908762e570c29cJohn McCall  // collection object.
10384b302d32378b364703b212834f908762e570c29cJohn McCall  JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
10394b302d32378b364703b212834f908762e570c29cJohn McCall
1040d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Send it our message:
1041f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CallArgList Args;
1042d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1043d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The first argument is a temporary of the enumeration-state type.
104404c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(StatePtr), getContext().getPointerType(StateTy));
10451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1046d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The second argument is a temporary array with space for NumItems
1047d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointers.  We'll actually be loading elements from the array
1048d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointer written into the control state; this buffer is so that
1049d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // collections that *aren't* backed by arrays can still queue up
1050d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // batches of elements.
105104c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy));
10521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1053d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The third argument is the capacity of that temporary array.
10542acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
10554a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
105604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(Count), getContext().UnsignedLongTy);
10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1058d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start the enumeration.
10591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  RValue CountRV =
1060ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1061f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
1062f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
1063c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
1064f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1065d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The initial number of objects that were returned in the buffer.
1066d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialBufferLimit = CountRV.getScalarVal();
10671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1068d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1069d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1070f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1071d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
1072f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1073d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If the limit pointer was zero to begin with, the collection is
1074d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // empty; skip all this.
1075d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
1076d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopInitBB);
10771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1078d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, initialize the loop.
1079d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopInitBB);
10801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1081d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Save the initial mutations value.  This is the value at an
1082d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // address that was written into the state object by
1083d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // countByEnumeratingWithState:objects:count:.
10841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtrPtr =
10852abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
10861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
10872abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                      "mutationsptr");
10881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1089d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialMutations =
1090d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations");
10911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1092d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start looping.  This is the point we return to whenever we have a
1093d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // fresh, non-empty batch of objects.
1094d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1095d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopBodyBB);
10961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1097d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current index into the buffer.
1098bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
1099d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, LoopInitBB);
1100f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1101d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current buffer size.
1102bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
1103d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(initialBufferLimit, LoopInitBB);
1104f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1105d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether the mutations value has changed from where it was
1106d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // at start.  StateMutationsPtr should actually be invariant between
1107d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes.
11082abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1109d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *currentMutations
1110d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateLoad(StateMutationsPtr, "statemutations");
11111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1112d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1113361cf980a7d976ef11a37b49567412b6b63a89d7Dan Gohman  llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
11141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1115d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1116d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       WasNotMutatedBB, WasMutatedBB);
11171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1118d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If so, call the enumeration-mutation function.
1119d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasMutatedBB);
11202abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *V =
11211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Builder.CreateBitCast(Collection,
11222abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          ConvertType(getContext().getObjCIdType()),
11232abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          "tmp");
11242b2105e92fc77016992dae3f117f526e73af5ea9Daniel Dunbar  CallArgList Args2;
112504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args2.add(RValue::get(V), getContext().getObjCIdType());
1126f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to get the function info here, the runtime already
1127f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // should have computed it to build the function.
112804a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
1129264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                          FunctionType::ExtInfo()),
1130f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson           EnumerationMutationFn, ReturnValueSlot(), Args2);
11311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1132d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, or if the mutation function returns, just continue.
1133d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasNotMutatedBB);
11341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1135d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Initialize the element variable.
1136d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  RunCleanupsScope elementVariableScope(*this);
113757b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  bool elementIsVariable;
1138d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  LValue elementLValue;
1139d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  QualType elementType;
1140d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
114157b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    // Initialize the variable, in case it's a __block variable or something.
114257b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarInit(variable);
1143f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
114457b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
1145d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
1146d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                        VK_LValue, SourceLocation());
1147d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(&tempDRE);
1148d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = D->getType();
114957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = true;
11507acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall
11517acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    if (D->isARCPseudoStrong())
11527acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall      elementLValue.getQuals().setObjCLifetime(Qualifiers::OCL_ExplicitNone);
1153d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  } else {
1154d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = LValue(); // suppress warning
1155d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = cast<Expr>(S.getElement())->getType();
115657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = false;
1157d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
11582acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *convertedElementType = ConvertType(elementType);
1159f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1160d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the buffer out of the enumeration state.
1161d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // TODO: this pointer should actually be invariant between
1162d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes, which would help us do certain loop optimizations.
1163d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *StateItemsPtr =
1164d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
1165d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *EnumStateItems =
1166d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateItemsPtr, "stateitems");
1167f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1168d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the value at the current index from the buffer.
11691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *CurrentItemPtr =
1170d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr");
1171d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr);
11721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1173d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Cast that value to the right type.
1174d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
1175d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                                      "currentitem");
11761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1177d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Make sure we have an l-value.  Yes, this gets evaluated every
1178d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // time through the loop.
11797acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  if (!elementIsVariable) {
1180d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1181545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue);
11827acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  } else {
11837acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    EmitScalarInit(CurrentItem, elementLValue);
11847acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  }
11851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
118657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // If we do have an element variable, this assignment is the end of
118757b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // its initialization.
118857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (elementIsVariable)
118957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarCleanups(variable);
119057b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall
1191d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Perform the loop body, setting up break and continue labels.
1192e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
1193d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  {
1194d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    RunCleanupsScope Scope(*this);
1195d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    EmitStmt(S.getBody());
1196d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
1197f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.pop_back();
11981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1199d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Destroy the element variable now.
1200d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  elementVariableScope.ForceCleanup();
1201d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1202d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether there are more elements.
1203ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(AfterBody.getBlock());
12041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1205d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
1206d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1207d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // First we check in the local buffer.
1208d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *indexPlusOne
1209d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
1210d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1211d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we haven't overrun the buffer yet, we can continue.
1212d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
1213d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       LoopBodyBB, FetchMoreBB);
1214f0906c4edb37b20141428ca77fa7dfd00b976eafFariborz Jahanian
1215d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(indexPlusOne, AfterBody.getBlock());
1216d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(count, AfterBody.getBlock());
1217f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1218d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, we have to fetch more elements.
1219d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(FetchMoreBB);
12201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CountRV =
1222ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1223f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
12241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             FastEnumSel,
1225c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
12261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1227d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we got a zero count, we're done.
1228d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *refetchCount = CountRV.getScalarVal();
1229d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1230d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // (note that the message send might split FetchMoreBB)
1231d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, Builder.GetInsertBlock());
1232d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(refetchCount, Builder.GetInsertBlock());
1233d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1234d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
1235d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopBodyBB);
12361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1237f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // No more elements.
1238d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(EmptyBB);
1239f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
124057b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (!elementIsVariable) {
1241f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // If the element was not a declaration, set it to be null.
1242f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1243d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
1244d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1245545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(null), elementLValue);
1246f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
1247f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1248bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
1249bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getEnd());
1250bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionEnd(Builder);
1251bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
1252bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
1253990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Leave the cleanup we entered in ARC.
1254990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (getLangOptions().ObjCAutoRefCount)
1255990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    PopCleanupBlock();
1256990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1257ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(LoopEnd.getBlock());
12583d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
12593d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
12601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
1261f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitTryStmt(*this, S);
126264d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
126364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
126564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
126664d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
126764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
126810cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattnervoid CodeGenFunction::EmitObjCAtSynchronizedStmt(
12691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              const ObjCAtSynchronizedStmt &S) {
1270f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
127110cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner}
127210cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner
1273f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code for a CK_ObjCProduceObject.  Just does a
1274f85e193739c953358c865005855253af4f68a497John McCall/// primitive retain.
1275f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCProduceObject(QualType type,
1276f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *value) {
1277f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetain(type, value);
1278f85e193739c953358c865005855253af4f68a497John McCall}
1279f85e193739c953358c865005855253af4f68a497John McCall
1280f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1281f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCRelease : EHScopeStack::Cleanup {
1282bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall    CallObjCRelease(llvm::Value *object) : object(object) {}
1283bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall    llvm::Value *object;
1284f85e193739c953358c865005855253af4f68a497John McCall
1285ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1286f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitARCRelease(object, /*precise*/ true);
1287f85e193739c953358c865005855253af4f68a497John McCall    }
1288f85e193739c953358c865005855253af4f68a497John McCall  };
1289f85e193739c953358c865005855253af4f68a497John McCall}
1290f85e193739c953358c865005855253af4f68a497John McCall
1291f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code for a CK_ObjCConsumeObject.  Does a primitive
1292f85e193739c953358c865005855253af4f68a497John McCall/// release at the end of the full-expression.
1293f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
1294f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *object) {
1295f85e193739c953358c865005855253af4f68a497John McCall  // If we're in a conditional branch, we need to make the cleanup
1296bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall  // conditional.
1297bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall  pushFullExprCleanup<CallObjCRelease>(getARCCleanupKind(), object);
1298f85e193739c953358c865005855253af4f68a497John McCall  return object;
1299f85e193739c953358c865005855253af4f68a497John McCall}
1300f85e193739c953358c865005855253af4f68a497John McCall
1301f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
1302f85e193739c953358c865005855253af4f68a497John McCall                                                           llvm::Value *value) {
1303f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetainAutorelease(type, value);
1304f85e193739c953358c865005855253af4f68a497John McCall}
1305f85e193739c953358c865005855253af4f68a497John McCall
1306f85e193739c953358c865005855253af4f68a497John McCall
1307f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
13082acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner                                                llvm::FunctionType *type,
13095f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                                StringRef fnName) {
1310f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
1311f85e193739c953358c865005855253af4f68a497John McCall
1312f85e193739c953358c865005855253af4f68a497John McCall  // In -fobjc-no-arc-runtime, emit weak references to the runtime
1313f85e193739c953358c865005855253af4f68a497John McCall  // support library.
13149f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (!CGM.getCodeGenOpts().ObjCRuntimeHasARC)
1315f85e193739c953358c865005855253af4f68a497John McCall    if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
1316f85e193739c953358c865005855253af4f68a497John McCall      f->setLinkage(llvm::Function::ExternalWeakLinkage);
1317f85e193739c953358c865005855253af4f68a497John McCall
1318f85e193739c953358c865005855253af4f68a497John McCall  return fn;
1319f85e193739c953358c865005855253af4f68a497John McCall}
1320f85e193739c953358c865005855253af4f68a497John McCall
1321f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the signature
1322f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8*)
1323f85e193739c953358c865005855253af4f68a497John McCall/// where a null input causes a no-op and returns null.
1324f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
1325f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1326f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
13275f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName) {
1328f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1329f85e193739c953358c865005855253af4f68a497John McCall
1330f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13319cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrTy);
13322acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1333f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1334f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1335f85e193739c953358c865005855253af4f68a497John McCall  }
1336f85e193739c953358c865005855253af4f68a497John McCall
1337f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
13382acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1339f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1340f85e193739c953358c865005855253af4f68a497John McCall
1341f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1342f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, value);
1343f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1344f85e193739c953358c865005855253af4f68a497John McCall
1345f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to the original type.
1346f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(call, origType);
1347f85e193739c953358c865005855253af4f68a497John McCall}
1348f85e193739c953358c865005855253af4f68a497John McCall
1349f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1350f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**)
1351f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
1352f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Value *addr,
1353f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Constant *&fn,
13545f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                         StringRef fnName) {
1355f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13569cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrPtrTy);
13572acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1358f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1359f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1360f85e193739c953358c865005855253af4f68a497John McCall  }
1361f85e193739c953358c865005855253af4f68a497John McCall
1362f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
13632acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = addr->getType();
1364f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1365f85e193739c953358c865005855253af4f68a497John McCall
1366f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1367f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, addr);
1368f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1369f85e193739c953358c865005855253af4f68a497John McCall
1370f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to a dereference of the original type.
1371f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = call;
1372f85e193739c953358c865005855253af4f68a497John McCall  if (origType != CGF.Int8PtrPtrTy)
1373f85e193739c953358c865005855253af4f68a497John McCall    result = CGF.Builder.CreateBitCast(result,
1374f85e193739c953358c865005855253af4f68a497John McCall                        cast<llvm::PointerType>(origType)->getElementType());
1375f85e193739c953358c865005855253af4f68a497John McCall
1376f85e193739c953358c865005855253af4f68a497John McCall  return result;
1377f85e193739c953358c865005855253af4f68a497John McCall}
1378f85e193739c953358c865005855253af4f68a497John McCall
1379f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1380f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**, i8*)
1381f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
1382f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *addr,
1383f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1384f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
13855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName,
1386f85e193739c953358c865005855253af4f68a497John McCall                                          bool ignored) {
1387f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1388f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1389f85e193739c953358c865005855253af4f68a497John McCall
1390f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13919cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2);
1392f85e193739c953358c865005855253af4f68a497John McCall    argTypes[0] = CGF.Int8PtrPtrTy;
1393f85e193739c953358c865005855253af4f68a497John McCall    argTypes[1] = CGF.Int8PtrTy;
1394f85e193739c953358c865005855253af4f68a497John McCall
13952acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1396f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false);
1397f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1398f85e193739c953358c865005855253af4f68a497John McCall  }
1399f85e193739c953358c865005855253af4f68a497John McCall
14002acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1401f85e193739c953358c865005855253af4f68a497John McCall
1402f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1403f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1404f85e193739c953358c865005855253af4f68a497John McCall
1405f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, addr, value);
1406f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1407f85e193739c953358c865005855253af4f68a497John McCall
1408f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1409f85e193739c953358c865005855253af4f68a497John McCall
1410f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(result, origType);
1411f85e193739c953358c865005855253af4f68a497John McCall}
1412f85e193739c953358c865005855253af4f68a497John McCall
1413f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1414f85e193739c953358c865005855253af4f68a497John McCall///   void (i8**, i8**)
1415f85e193739c953358c865005855253af4f68a497John McCallstatic void emitARCCopyOperation(CodeGenFunction &CGF,
1416f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *dst,
1417f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *src,
1418f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Constant *&fn,
14195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                 StringRef fnName) {
1420f85e193739c953358c865005855253af4f68a497John McCall  assert(dst->getType() == src->getType());
1421f85e193739c953358c865005855253af4f68a497John McCall
1422f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14239cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2, CGF.Int8PtrPtrTy);
14242acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1425f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false);
1426f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1427f85e193739c953358c865005855253af4f68a497John McCall  }
1428f85e193739c953358c865005855253af4f68a497John McCall
1429f85e193739c953358c865005855253af4f68a497John McCall  dst = CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy);
1430f85e193739c953358c865005855253af4f68a497John McCall  src = CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy);
1431f85e193739c953358c865005855253af4f68a497John McCall
1432f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, dst, src);
1433f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1434f85e193739c953358c865005855253af4f68a497John McCall}
1435f85e193739c953358c865005855253af4f68a497John McCall
1436f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a retain.  Based on the type, calls one of:
1437f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1438f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1439f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {
1440f85e193739c953358c865005855253af4f68a497John McCall  if (type->isBlockPointerType())
1441f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainBlock(value);
1442f85e193739c953358c865005855253af4f68a497John McCall  else
1443f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainNonBlock(value);
1444f85e193739c953358c865005855253af4f68a497John McCall}
1445f85e193739c953358c865005855253af4f68a497John McCall
1446f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object, with normal retain semantics.
1447f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1448f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) {
1449f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1450f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retain,
1451f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retain");
1452f85e193739c953358c865005855253af4f68a497John McCall}
1453f85e193739c953358c865005855253af4f68a497John McCall
1454f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given block, with _Block_copy semantics.
1455f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1456f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value) {
1457f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1458f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainBlock,
1459f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainBlock");
1460f85e193739c953358c865005855253af4f68a497John McCall}
1461f85e193739c953358c865005855253af4f68a497John McCall
1462f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object which is the result of a function call.
1463f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleasedReturnValue(i8* %value)
1464f85e193739c953358c865005855253af4f68a497John McCall///
1465f85e193739c953358c865005855253af4f68a497John McCall/// Yes, this function name is one character away from a different
1466f85e193739c953358c865005855253af4f68a497John McCall/// call with completely different semantics.
1467f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1468f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
1469f85e193739c953358c865005855253af4f68a497John McCall  // Fetch the void(void) inline asm which marks that we're going to
1470f85e193739c953358c865005855253af4f68a497John McCall  // retain the autoreleased return value.
1471f85e193739c953358c865005855253af4f68a497John McCall  llvm::InlineAsm *&marker
1472f85e193739c953358c865005855253af4f68a497John McCall    = CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker;
1473f85e193739c953358c865005855253af4f68a497John McCall  if (!marker) {
14745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef assembly
1475f85e193739c953358c865005855253af4f68a497John McCall      = CGM.getTargetCodeGenInfo()
1476f85e193739c953358c865005855253af4f68a497John McCall           .getARCRetainAutoreleasedReturnValueMarker();
1477f85e193739c953358c865005855253af4f68a497John McCall
1478f85e193739c953358c865005855253af4f68a497John McCall    // If we have an empty assembly string, there's nothing to do.
1479f85e193739c953358c865005855253af4f68a497John McCall    if (assembly.empty()) {
1480f85e193739c953358c865005855253af4f68a497John McCall
1481f85e193739c953358c865005855253af4f68a497John McCall    // Otherwise, at -O0, build an inline asm that we're going to call
1482f85e193739c953358c865005855253af4f68a497John McCall    // in a moment.
1483f85e193739c953358c865005855253af4f68a497John McCall    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1484f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType *type =
1485f85e193739c953358c865005855253af4f68a497John McCall        llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
1486f85e193739c953358c865005855253af4f68a497John McCall                                /*variadic*/ false);
1487f85e193739c953358c865005855253af4f68a497John McCall
1488f85e193739c953358c865005855253af4f68a497John McCall      marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true);
1489f85e193739c953358c865005855253af4f68a497John McCall
1490f85e193739c953358c865005855253af4f68a497John McCall    // If we're at -O1 and above, we don't want to litter the code
1491f85e193739c953358c865005855253af4f68a497John McCall    // with this marker yet, so leave a breadcrumb for the ARC
1492f85e193739c953358c865005855253af4f68a497John McCall    // optimizer to pick up.
1493f85e193739c953358c865005855253af4f68a497John McCall    } else {
1494f85e193739c953358c865005855253af4f68a497John McCall      llvm::NamedMDNode *metadata =
1495f85e193739c953358c865005855253af4f68a497John McCall        CGM.getModule().getOrInsertNamedMetadata(
1496f85e193739c953358c865005855253af4f68a497John McCall                            "clang.arc.retainAutoreleasedReturnValueMarker");
1497f85e193739c953358c865005855253af4f68a497John McCall      assert(metadata->getNumOperands() <= 1);
1498f85e193739c953358c865005855253af4f68a497John McCall      if (metadata->getNumOperands() == 0) {
1499f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *string = llvm::MDString::get(getLLVMContext(), assembly);
1500da549e8995c447542d5631b8b67fcc3a9582797aJay Foad        metadata->addOperand(llvm::MDNode::get(getLLVMContext(), string));
1501f85e193739c953358c865005855253af4f68a497John McCall      }
1502f85e193739c953358c865005855253af4f68a497John McCall    }
1503f85e193739c953358c865005855253af4f68a497John McCall  }
1504f85e193739c953358c865005855253af4f68a497John McCall
1505f85e193739c953358c865005855253af4f68a497John McCall  // Call the marker asm if we made one, which we do only at -O0.
1506f85e193739c953358c865005855253af4f68a497John McCall  if (marker) Builder.CreateCall(marker);
1507f85e193739c953358c865005855253af4f68a497John McCall
1508f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1509f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleasedReturnValue,
1510f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleasedReturnValue");
1511f85e193739c953358c865005855253af4f68a497John McCall}
1512f85e193739c953358c865005855253af4f68a497John McCall
1513f85e193739c953358c865005855253af4f68a497John McCall/// Release the given object.
1514f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_release(i8* %value)
1515f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCRelease(llvm::Value *value, bool precise) {
1516f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return;
1517f85e193739c953358c865005855253af4f68a497John McCall
1518f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_release;
1519f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15209cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
15212acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1522f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1523f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_release");
1524f85e193739c953358c865005855253af4f68a497John McCall  }
1525f85e193739c953358c865005855253af4f68a497John McCall
1526f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
1527f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1528f85e193739c953358c865005855253af4f68a497John McCall
1529f85e193739c953358c865005855253af4f68a497John McCall  // Call objc_release.
1530f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1531f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1532f85e193739c953358c865005855253af4f68a497John McCall
1533f85e193739c953358c865005855253af4f68a497John McCall  if (!precise) {
15345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<llvm::Value*,1> args;
1535f85e193739c953358c865005855253af4f68a497John McCall    call->setMetadata("clang.imprecise_release",
1536f85e193739c953358c865005855253af4f68a497John McCall                      llvm::MDNode::get(Builder.getContext(), args));
1537f85e193739c953358c865005855253af4f68a497John McCall  }
1538f85e193739c953358c865005855253af4f68a497John McCall}
1539f85e193739c953358c865005855253af4f68a497John McCall
1540f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Always calls this:
1541f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1542f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr,
1543f85e193739c953358c865005855253af4f68a497John McCall                                                     llvm::Value *value,
1544f85e193739c953358c865005855253af4f68a497John McCall                                                     bool ignored) {
1545f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1546f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1547f85e193739c953358c865005855253af4f68a497John McCall
1548f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_storeStrong;
1549f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15509cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy };
15512acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1552f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false);
1553f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong");
1554f85e193739c953358c865005855253af4f68a497John McCall  }
1555f85e193739c953358c865005855253af4f68a497John McCall
1556f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1557f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *castValue = Builder.CreateBitCast(value, Int8PtrTy);
1558f85e193739c953358c865005855253af4f68a497John McCall
1559f85e193739c953358c865005855253af4f68a497John McCall  Builder.CreateCall2(fn, addr, castValue)->setDoesNotThrow();
1560f85e193739c953358c865005855253af4f68a497John McCall
1561f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1562f85e193739c953358c865005855253af4f68a497John McCall  return value;
1563f85e193739c953358c865005855253af4f68a497John McCall}
1564f85e193739c953358c865005855253af4f68a497John McCall
1565f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Sometimes calls this:
1566f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1567f85e193739c953358c865005855253af4f68a497John McCall/// Other times, breaks it down into components.
1568545d996ec5a3113f046944f11b27cc2d6cb055b4John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
1569f85e193739c953358c865005855253af4f68a497John McCall                                                 llvm::Value *newValue,
1570f85e193739c953358c865005855253af4f68a497John McCall                                                 bool ignored) {
1571545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  QualType type = dst.getType();
1572f85e193739c953358c865005855253af4f68a497John McCall  bool isBlock = type->isBlockPointerType();
1573f85e193739c953358c865005855253af4f68a497John McCall
1574f85e193739c953358c865005855253af4f68a497John McCall  // Use a store barrier at -O0 unless this is a block type or the
1575f85e193739c953358c865005855253af4f68a497John McCall  // lvalue is inadequately aligned.
1576f85e193739c953358c865005855253af4f68a497John McCall  if (shouldUseFusedARCCalls() &&
1577f85e193739c953358c865005855253af4f68a497John McCall      !isBlock &&
1578f85e193739c953358c865005855253af4f68a497John McCall      !(dst.getAlignment() && dst.getAlignment() < PointerAlignInBytes)) {
1579f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCStoreStrongCall(dst.getAddress(), newValue, ignored);
1580f85e193739c953358c865005855253af4f68a497John McCall  }
1581f85e193739c953358c865005855253af4f68a497John McCall
1582f85e193739c953358c865005855253af4f68a497John McCall  // Otherwise, split it out.
1583f85e193739c953358c865005855253af4f68a497John McCall
1584f85e193739c953358c865005855253af4f68a497John McCall  // Retain the new value.
1585f85e193739c953358c865005855253af4f68a497John McCall  newValue = EmitARCRetain(type, newValue);
1586f85e193739c953358c865005855253af4f68a497John McCall
1587f85e193739c953358c865005855253af4f68a497John McCall  // Read the old value.
1588545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  llvm::Value *oldValue = EmitLoadOfScalar(dst);
1589f85e193739c953358c865005855253af4f68a497John McCall
1590f85e193739c953358c865005855253af4f68a497John McCall  // Store.  We do this before the release so that any deallocs won't
1591f85e193739c953358c865005855253af4f68a497John McCall  // see the old value.
1592545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  EmitStoreOfScalar(newValue, dst);
1593f85e193739c953358c865005855253af4f68a497John McCall
1594f85e193739c953358c865005855253af4f68a497John McCall  // Finally, release the old value.
1595f85e193739c953358c865005855253af4f68a497John McCall  EmitARCRelease(oldValue, /*precise*/ false);
1596f85e193739c953358c865005855253af4f68a497John McCall
1597f85e193739c953358c865005855253af4f68a497John McCall  return newValue;
1598f85e193739c953358c865005855253af4f68a497John McCall}
1599f85e193739c953358c865005855253af4f68a497John McCall
1600f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1601f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %value)
1602f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) {
1603f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1604f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_autorelease,
1605f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autorelease");
1606f85e193739c953358c865005855253af4f68a497John McCall}
1607f85e193739c953358c865005855253af4f68a497John McCall
1608f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1609f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleaseReturnValue(i8* %value)
1610f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1611f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
1612f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1613f85e193739c953358c865005855253af4f68a497John McCall                            CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
1614f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autoreleaseReturnValue");
1615f85e193739c953358c865005855253af4f68a497John McCall}
1616f85e193739c953358c865005855253af4f68a497John McCall
1617f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1618f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleaseReturnValue(i8* %value)
1619f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1620f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
1621f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1622f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
1623f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleaseReturnValue");
1624f85e193739c953358c865005855253af4f68a497John McCall}
1625f85e193739c953358c865005855253af4f68a497John McCall
1626f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1627f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1628f85e193739c953358c865005855253af4f68a497John McCall/// or
1629f85e193739c953358c865005855253af4f68a497John McCall///   %retain = call i8* @objc_retainBlock(i8* %value)
1630f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %retain)
1631f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
1632f85e193739c953358c865005855253af4f68a497John McCall                                                       llvm::Value *value) {
1633f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isBlockPointerType())
1634f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainAutoreleaseNonBlock(value);
1635f85e193739c953358c865005855253af4f68a497John McCall
1636f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1637f85e193739c953358c865005855253af4f68a497John McCall
16382acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1639f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1640f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCRetainBlock(value);
1641f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCAutorelease(value);
1642f85e193739c953358c865005855253af4f68a497John McCall  return Builder.CreateBitCast(value, origType);
1643f85e193739c953358c865005855253af4f68a497John McCall}
1644f85e193739c953358c865005855253af4f68a497John McCall
1645f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1646f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1647f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1648f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) {
1649f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1650f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainAutorelease,
1651f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutorelease");
1652f85e193739c953358c865005855253af4f68a497John McCall}
1653f85e193739c953358c865005855253af4f68a497John McCall
1654f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeak(i8** %addr)
1655f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_autorelease(objc_loadWeakRetained(addr)).
1656f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeak(llvm::Value *addr) {
1657f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1658f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeak,
1659f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeak");
1660f85e193739c953358c865005855253af4f68a497John McCall}
1661f85e193739c953358c865005855253af4f68a497John McCall
1662f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeakRetained(i8** %addr)
1663f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(llvm::Value *addr) {
1664f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1665f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeakRetained,
1666f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeakRetained");
1667f85e193739c953358c865005855253af4f68a497John McCall}
1668f85e193739c953358c865005855253af4f68a497John McCall
1669f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_storeWeak(i8** %addr, i8* %value)
1670f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.
1671f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreWeak(llvm::Value *addr,
1672f85e193739c953358c865005855253af4f68a497John McCall                                               llvm::Value *value,
1673f85e193739c953358c865005855253af4f68a497John McCall                                               bool ignored) {
1674f85e193739c953358c865005855253af4f68a497John McCall  return emitARCStoreOperation(*this, addr, value,
1675f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_storeWeak,
1676f85e193739c953358c865005855253af4f68a497John McCall                               "objc_storeWeak", ignored);
1677f85e193739c953358c865005855253af4f68a497John McCall}
1678f85e193739c953358c865005855253af4f68a497John McCall
1679f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_initWeak(i8** %addr, i8* %value)
1680f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.  %addr is known to not have a current weak entry.
1681f85e193739c953358c865005855253af4f68a497John McCall/// Essentially equivalent to:
1682f85e193739c953358c865005855253af4f68a497John McCall///   *addr = nil; objc_storeWeak(addr, value);
1683f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCInitWeak(llvm::Value *addr, llvm::Value *value) {
1684f85e193739c953358c865005855253af4f68a497John McCall  // If we're initializing to null, just write null to memory; no need
1685f85e193739c953358c865005855253af4f68a497John McCall  // to get the runtime involved.  But don't do this if optimization
1686f85e193739c953358c865005855253af4f68a497John McCall  // is enabled, because accounting for this would make the optimizer
1687f85e193739c953358c865005855253af4f68a497John McCall  // much more complicated.
1688f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value) &&
1689f85e193739c953358c865005855253af4f68a497John McCall      CGM.getCodeGenOpts().OptimizationLevel == 0) {
1690f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(value, addr);
1691f85e193739c953358c865005855253af4f68a497John McCall    return;
1692f85e193739c953358c865005855253af4f68a497John McCall  }
1693f85e193739c953358c865005855253af4f68a497John McCall
1694f85e193739c953358c865005855253af4f68a497John McCall  emitARCStoreOperation(*this, addr, value,
1695f85e193739c953358c865005855253af4f68a497John McCall                        CGM.getARCEntrypoints().objc_initWeak,
1696f85e193739c953358c865005855253af4f68a497John McCall                        "objc_initWeak", /*ignored*/ true);
1697f85e193739c953358c865005855253af4f68a497John McCall}
1698f85e193739c953358c865005855253af4f68a497John McCall
1699f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_destroyWeak(i8** %addr)
1700f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_storeWeak(addr, nil).
1701f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCDestroyWeak(llvm::Value *addr) {
1702f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_destroyWeak;
1703f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17049cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrPtrTy);
17052acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1706f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1707f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak");
1708f85e193739c953358c865005855253af4f68a497John McCall  }
1709f85e193739c953358c865005855253af4f68a497John McCall
1710f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
1711f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1712f85e193739c953358c865005855253af4f68a497John McCall
1713f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, addr);
1714f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1715f85e193739c953358c865005855253af4f68a497John McCall}
1716f85e193739c953358c865005855253af4f68a497John McCall
1717f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_moveWeak(i8** %dest, i8** %src)
1718f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Leaves %src pointing to nothing.
1719f85e193739c953358c865005855253af4f68a497John McCall/// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)).
1720f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src) {
1721f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1722f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_moveWeak,
1723f85e193739c953358c865005855253af4f68a497John McCall                       "objc_moveWeak");
1724f85e193739c953358c865005855253af4f68a497John McCall}
1725f85e193739c953358c865005855253af4f68a497John McCall
1726f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_copyWeak(i8** %dest, i8** %src)
1727f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Essentially
1728f85e193739c953358c865005855253af4f68a497John McCall///   objc_release(objc_initWeak(dest, objc_readWeakRetained(src)))
1729f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCCopyWeak(llvm::Value *dst, llvm::Value *src) {
1730f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1731f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_copyWeak,
1732f85e193739c953358c865005855253af4f68a497John McCall                       "objc_copyWeak");
1733f85e193739c953358c865005855253af4f68a497John McCall}
1734f85e193739c953358c865005855253af4f68a497John McCall
1735f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a objc_autoreleasepool_push.
1736f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleasePoolPush(void)
1737f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
1738f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPush;
1739f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17402acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1741f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Int8PtrTy, false);
1742f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush");
1743f85e193739c953358c865005855253af4f68a497John McCall  }
1744f85e193739c953358c865005855253af4f68a497John McCall
1745f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn);
1746f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1747f85e193739c953358c865005855253af4f68a497John McCall
1748f85e193739c953358c865005855253af4f68a497John McCall  return call;
1749f85e193739c953358c865005855253af4f68a497John McCall}
1750f85e193739c953358c865005855253af4f68a497John McCall
1751f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1752f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_autoreleasePoolPop(i8* %ptr)
1753f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
1754f85e193739c953358c865005855253af4f68a497John McCall  assert(value->getType() == Int8PtrTy);
1755f85e193739c953358c865005855253af4f68a497John McCall
1756f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPop;
1757f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17589cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
17592acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1760f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1761f85e193739c953358c865005855253af4f68a497John McCall
1762f85e193739c953358c865005855253af4f68a497John McCall    // We don't want to use a weak import here; instead we should not
1763f85e193739c953358c865005855253af4f68a497John McCall    // fall into this path.
1764f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop");
1765f85e193739c953358c865005855253af4f68a497John McCall  }
1766f85e193739c953358c865005855253af4f68a497John McCall
1767f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1768f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1769f85e193739c953358c865005855253af4f68a497John McCall}
1770f85e193739c953358c865005855253af4f68a497John McCall
1771f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do an MRR version objc_autoreleasepool_push.
1772f85e193739c953358c865005855253af4f68a497John McCall/// Which is: [[NSAutoreleasePool alloc] init];
1773f85e193739c953358c865005855253af4f68a497John McCall/// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class.
1774f85e193739c953358c865005855253af4f68a497John McCall/// init is declared as: - (id) init; in its NSObject super class.
1775f85e193739c953358c865005855253af4f68a497John McCall///
1776f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() {
1777f85e193739c953358c865005855253af4f68a497John McCall  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
1778f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(Builder);
1779f85e193739c953358c865005855253af4f68a497John McCall  // [NSAutoreleasePool alloc]
1780f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");
1781f85e193739c953358c865005855253af4f68a497John McCall  Selector AllocSel = getContext().Selectors.getSelector(0, &II);
1782f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1783f85e193739c953358c865005855253af4f68a497John McCall  RValue AllocRV =
1784f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1785f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1786f85e193739c953358c865005855253af4f68a497John McCall                                AllocSel, Receiver, Args);
1787f85e193739c953358c865005855253af4f68a497John McCall
1788f85e193739c953358c865005855253af4f68a497John McCall  // [Receiver init]
1789f85e193739c953358c865005855253af4f68a497John McCall  Receiver = AllocRV.getScalarVal();
1790f85e193739c953358c865005855253af4f68a497John McCall  II = &CGM.getContext().Idents.get("init");
1791f85e193739c953358c865005855253af4f68a497John McCall  Selector InitSel = getContext().Selectors.getSelector(0, &II);
1792f85e193739c953358c865005855253af4f68a497John McCall  RValue InitRV =
1793f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1794f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1795f85e193739c953358c865005855253af4f68a497John McCall                                InitSel, Receiver, Args);
1796f85e193739c953358c865005855253af4f68a497John McCall  return InitRV.getScalarVal();
1797f85e193739c953358c865005855253af4f68a497John McCall}
1798f85e193739c953358c865005855253af4f68a497John McCall
1799f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1800f85e193739c953358c865005855253af4f68a497John McCall/// [tmp drain];
1801f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) {
1802f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("drain");
1803f85e193739c953358c865005855253af4f68a497John McCall  Selector DrainSel = getContext().Selectors.getSelector(0, &II);
1804f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1805f85e193739c953358c865005855253af4f68a497John McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1806f85e193739c953358c865005855253af4f68a497John McCall                              getContext().VoidTy, DrainSel, Arg, Args);
1807f85e193739c953358c865005855253af4f68a497John McCall}
1808f85e193739c953358c865005855253af4f68a497John McCall
1809bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
1810bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              llvm::Value *addr,
1811bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              QualType type) {
1812bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1813bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ true);
1814bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1815bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1816bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
1817bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                llvm::Value *addr,
1818bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                QualType type) {
1819bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1820bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ false);
1821bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1822bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1823bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
1824bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     llvm::Value *addr,
1825bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     QualType type) {
1826bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCDestroyWeak(addr);
1827bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1828bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1829f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1830f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCAutoreleasePoolObject : EHScopeStack::Cleanup {
1831f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1832f85e193739c953358c865005855253af4f68a497John McCall
1833f85e193739c953358c865005855253af4f68a497John McCall    CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1834f85e193739c953358c865005855253af4f68a497John McCall
1835ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1836f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCAutoreleasePoolPop(Token);
1837f85e193739c953358c865005855253af4f68a497John McCall    }
1838f85e193739c953358c865005855253af4f68a497John McCall  };
1839f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCMRRAutoreleasePoolObject : EHScopeStack::Cleanup {
1840f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1841f85e193739c953358c865005855253af4f68a497John McCall
1842f85e193739c953358c865005855253af4f68a497John McCall    CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1843f85e193739c953358c865005855253af4f68a497John McCall
1844ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1845f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCMRRAutoreleasePoolPop(Token);
1846f85e193739c953358c865005855253af4f68a497John McCall    }
1847f85e193739c953358c865005855253af4f68a497John McCall  };
1848f85e193739c953358c865005855253af4f68a497John McCall}
1849f85e193739c953358c865005855253af4f68a497John McCall
1850f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
1851f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount)
1852f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr);
1853f85e193739c953358c865005855253af4f68a497John McCall  else
1854f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr);
1855f85e193739c953358c865005855253af4f68a497John McCall}
1856f85e193739c953358c865005855253af4f68a497John McCall
1857f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1858f85e193739c953358c865005855253af4f68a497John McCall                                                  LValue lvalue,
1859f85e193739c953358c865005855253af4f68a497John McCall                                                  QualType type) {
1860f85e193739c953358c865005855253af4f68a497John McCall  switch (type.getObjCLifetime()) {
1861f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
1862f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
1863f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong:
1864f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
1865545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue).getScalarVal(),
1866f85e193739c953358c865005855253af4f68a497John McCall                         false);
1867f85e193739c953358c865005855253af4f68a497John McCall
1868f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:
1869f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitARCLoadWeakRetained(lvalue.getAddress()),
1870f85e193739c953358c865005855253af4f68a497John McCall                         true);
1871f85e193739c953358c865005855253af4f68a497John McCall  }
1872f85e193739c953358c865005855253af4f68a497John McCall
1873f85e193739c953358c865005855253af4f68a497John McCall  llvm_unreachable("impossible lifetime!");
1874f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult();
1875f85e193739c953358c865005855253af4f68a497John McCall}
1876f85e193739c953358c865005855253af4f68a497John McCall
1877f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1878f85e193739c953358c865005855253af4f68a497John McCall                                                  const Expr *e) {
1879f85e193739c953358c865005855253af4f68a497John McCall  e = e->IgnoreParens();
1880f85e193739c953358c865005855253af4f68a497John McCall  QualType type = e->getType();
1881f85e193739c953358c865005855253af4f68a497John McCall
1882f85e193739c953358c865005855253af4f68a497John McCall  // As a very special optimization, in ARC++, if the l-value is the
1883f85e193739c953358c865005855253af4f68a497John McCall  // result of a non-volatile assignment, do a simple retain of the
1884f85e193739c953358c865005855253af4f68a497John McCall  // result of the call to objc_storeWeak instead of reloading.
1885f85e193739c953358c865005855253af4f68a497John McCall  if (CGF.getLangOptions().CPlusPlus &&
1886f85e193739c953358c865005855253af4f68a497John McCall      !type.isVolatileQualified() &&
1887f85e193739c953358c865005855253af4f68a497John McCall      type.getObjCLifetime() == Qualifiers::OCL_Weak &&
1888f85e193739c953358c865005855253af4f68a497John McCall      isa<BinaryOperator>(e) &&
1889f85e193739c953358c865005855253af4f68a497John McCall      cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
1890f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitScalarExpr(e), false);
1891f85e193739c953358c865005855253af4f68a497John McCall
1892f85e193739c953358c865005855253af4f68a497John McCall  return tryEmitARCRetainLoadOfScalar(CGF, CGF.EmitLValue(e), type);
1893f85e193739c953358c865005855253af4f68a497John McCall}
1894f85e193739c953358c865005855253af4f68a497John McCall
1895f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1896f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value);
1897f85e193739c953358c865005855253af4f68a497John McCall
1898f85e193739c953358c865005855253af4f68a497John McCall/// Given that the given expression is some sort of call (which does
1899f85e193739c953358c865005855253af4f68a497John McCall/// not return retained), emit a retain following it.
1900f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainCall(CodeGenFunction &CGF, const Expr *e) {
1901f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = CGF.EmitScalarExpr(e);
1902f85e193739c953358c865005855253af4f68a497John McCall  return emitARCRetainAfterCall(CGF, value);
1903f85e193739c953358c865005855253af4f68a497John McCall}
1904f85e193739c953358c865005855253af4f68a497John McCall
1905f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1906f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value) {
1907f85e193739c953358c865005855253af4f68a497John McCall  if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
1908f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
1909f85e193739c953358c865005855253af4f68a497John McCall
1910f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain immediately following the call.
1911f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(call->getParent(),
1912f85e193739c953358c865005855253af4f68a497John McCall                               ++llvm::BasicBlock::iterator(call));
1913f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
1914f85e193739c953358c865005855253af4f68a497John McCall
1915f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
1916f85e193739c953358c865005855253af4f68a497John McCall    return value;
1917f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
1918f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
1919f85e193739c953358c865005855253af4f68a497John McCall
1920f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain at the beginning of the normal destination block.
1921f85e193739c953358c865005855253af4f68a497John McCall    llvm::BasicBlock *BB = invoke->getNormalDest();
1922f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(BB, BB->begin());
1923f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
1924f85e193739c953358c865005855253af4f68a497John McCall
1925f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
1926f85e193739c953358c865005855253af4f68a497John McCall    return value;
1927f85e193739c953358c865005855253af4f68a497John McCall
1928f85e193739c953358c865005855253af4f68a497John McCall  // Bitcasts can arise because of related-result returns.  Rewrite
1929f85e193739c953358c865005855253af4f68a497John McCall  // the operand.
1930f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
1931f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *operand = bitcast->getOperand(0);
1932f85e193739c953358c865005855253af4f68a497John McCall    operand = emitARCRetainAfterCall(CGF, operand);
1933f85e193739c953358c865005855253af4f68a497John McCall    bitcast->setOperand(0, operand);
1934f85e193739c953358c865005855253af4f68a497John McCall    return bitcast;
1935f85e193739c953358c865005855253af4f68a497John McCall
1936f85e193739c953358c865005855253af4f68a497John McCall  // Generic fall-back case.
1937f85e193739c953358c865005855253af4f68a497John McCall  } else {
1938f85e193739c953358c865005855253af4f68a497John McCall    // Retain using the non-block variant: we never need to do a copy
1939f85e193739c953358c865005855253af4f68a497John McCall    // of a block that's been returned to us.
1940f85e193739c953358c865005855253af4f68a497John McCall    return CGF.EmitARCRetainNonBlock(value);
1941f85e193739c953358c865005855253af4f68a497John McCall  }
1942f85e193739c953358c865005855253af4f68a497John McCall}
1943f85e193739c953358c865005855253af4f68a497John McCall
1944f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult
1945f85e193739c953358c865005855253af4f68a497John McCalltryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
1946990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Look through cleanups.
1947990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
1948990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    CodeGenFunction::RunCleanupsScope scope(CGF);
1949990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    return tryEmitARCRetainScalarExpr(CGF, cleanups->getSubExpr());
1950990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
1951990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1952f85e193739c953358c865005855253af4f68a497John McCall  // The desired result type, if it differs from the type of the
1953f85e193739c953358c865005855253af4f68a497John McCall  // ultimate opaque expression.
19542acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *resultType = 0;
1955f85e193739c953358c865005855253af4f68a497John McCall
1956d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // If we're loading retained from a __strong xvalue, we can avoid
1957d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // an extra retain/release pair by zeroing out the source of this
1958d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // "move" operation.
1959df7b091c58ccdb402a32bfbde9c506074dba5f3dJohn McCall  if (e->isXValue() && !e->getType().isConstQualified() &&
1960d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      e->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
1961d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Emit the lvalue
1962d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    LValue lv = CGF.EmitLValue(e);
1963d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1964d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Load the object pointer and cast it to the appropriate type.
1965d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    QualType exprType = e->getType();
1966545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal();
1967d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1968d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    if (resultType)
1969d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      result = CGF.Builder.CreateBitCast(result, resultType);
1970d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1971d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Set the source pointer to NULL.
1972d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    llvm::Value *null
1973d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      = llvm::ConstantPointerNull::get(
1974d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor                            cast<llvm::PointerType>(CGF.ConvertType(exprType)));
1975545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    CGF.EmitStoreOfScalar(null, lv);
1976d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1977d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    return TryEmitResult(result, true);
1978d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  }
1979d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1980f85e193739c953358c865005855253af4f68a497John McCall  while (true) {
1981f85e193739c953358c865005855253af4f68a497John McCall    e = e->IgnoreParens();
1982f85e193739c953358c865005855253af4f68a497John McCall
1983f85e193739c953358c865005855253af4f68a497John McCall    // There's a break at the end of this if-chain;  anything
1984f85e193739c953358c865005855253af4f68a497John McCall    // that wants to keep looping has to explicitly continue.
1985f85e193739c953358c865005855253af4f68a497John McCall    if (const CastExpr *ce = dyn_cast<CastExpr>(e)) {
1986f85e193739c953358c865005855253af4f68a497John McCall      switch (ce->getCastKind()) {
1987f85e193739c953358c865005855253af4f68a497John McCall      // No-op casts don't change the type, so we just ignore them.
1988f85e193739c953358c865005855253af4f68a497John McCall      case CK_NoOp:
1989f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
1990f85e193739c953358c865005855253af4f68a497John McCall        continue;
1991f85e193739c953358c865005855253af4f68a497John McCall
1992f85e193739c953358c865005855253af4f68a497John McCall      case CK_LValueToRValue: {
1993f85e193739c953358c865005855253af4f68a497John McCall        TryEmitResult loadResult
1994f85e193739c953358c865005855253af4f68a497John McCall          = tryEmitARCRetainLoadOfScalar(CGF, ce->getSubExpr());
1995f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) {
1996f85e193739c953358c865005855253af4f68a497John McCall          llvm::Value *value = loadResult.getPointer();
1997f85e193739c953358c865005855253af4f68a497John McCall          value = CGF.Builder.CreateBitCast(value, resultType);
1998f85e193739c953358c865005855253af4f68a497John McCall          loadResult.setPointer(value);
1999f85e193739c953358c865005855253af4f68a497John McCall        }
2000f85e193739c953358c865005855253af4f68a497John McCall        return loadResult;
2001f85e193739c953358c865005855253af4f68a497John McCall      }
2002f85e193739c953358c865005855253af4f68a497John McCall
2003f85e193739c953358c865005855253af4f68a497John McCall      // These casts can change the type, so remember that and
2004f85e193739c953358c865005855253af4f68a497John McCall      // soldier on.  We only need to remember the outermost such
2005f85e193739c953358c865005855253af4f68a497John McCall      // cast, though.
2006f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToObjCPointerCast:
2007f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToBlockPointerCast:
2008f85e193739c953358c865005855253af4f68a497John McCall      case CK_BitCast:
2009f85e193739c953358c865005855253af4f68a497John McCall        if (!resultType)
2010f85e193739c953358c865005855253af4f68a497John McCall          resultType = CGF.ConvertType(ce->getType());
2011f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
2012f85e193739c953358c865005855253af4f68a497John McCall        assert(e->getType()->hasPointerRepresentation());
2013f85e193739c953358c865005855253af4f68a497John McCall        continue;
2014f85e193739c953358c865005855253af4f68a497John McCall
2015f85e193739c953358c865005855253af4f68a497John McCall      // For consumptions, just emit the subexpression and thus elide
2016f85e193739c953358c865005855253af4f68a497John McCall      // the retain/release pair.
2017f85e193739c953358c865005855253af4f68a497John McCall      case CK_ObjCConsumeObject: {
2018f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = CGF.EmitScalarExpr(ce->getSubExpr());
2019f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2020f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2021f85e193739c953358c865005855253af4f68a497John McCall      }
2022f85e193739c953358c865005855253af4f68a497John McCall
20237e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // For reclaims, emit the subexpression as a retained call and
20247e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // skip the consumption.
20257e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      case CK_ObjCReclaimReturnedObject: {
20267e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce->getSubExpr());
20277e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
20287e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        return TryEmitResult(result, true);
20297e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      }
20307e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall
2031f85e193739c953358c865005855253af4f68a497John McCall      case CK_GetObjCProperty: {
2032f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce);
2033f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2034f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2035f85e193739c953358c865005855253af4f68a497John McCall      }
2036f85e193739c953358c865005855253af4f68a497John McCall
2037f85e193739c953358c865005855253af4f68a497John McCall      default:
2038f85e193739c953358c865005855253af4f68a497John McCall        break;
2039f85e193739c953358c865005855253af4f68a497John McCall      }
2040f85e193739c953358c865005855253af4f68a497John McCall
2041f85e193739c953358c865005855253af4f68a497John McCall    // Skip __extension__.
2042f85e193739c953358c865005855253af4f68a497John McCall    } else if (const UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
2043f85e193739c953358c865005855253af4f68a497John McCall      if (op->getOpcode() == UO_Extension) {
2044f85e193739c953358c865005855253af4f68a497John McCall        e = op->getSubExpr();
2045f85e193739c953358c865005855253af4f68a497John McCall        continue;
2046f85e193739c953358c865005855253af4f68a497John McCall      }
2047f85e193739c953358c865005855253af4f68a497John McCall
2048f85e193739c953358c865005855253af4f68a497John McCall    // For calls and message sends, use the retained-call logic.
2049f85e193739c953358c865005855253af4f68a497John McCall    // Delegate inits are a special case in that they're the only
2050f85e193739c953358c865005855253af4f68a497John McCall    // returns-retained expression that *isn't* surrounded by
2051f85e193739c953358c865005855253af4f68a497John McCall    // a consume.
2052f85e193739c953358c865005855253af4f68a497John McCall    } else if (isa<CallExpr>(e) ||
2053f85e193739c953358c865005855253af4f68a497John McCall               (isa<ObjCMessageExpr>(e) &&
2054f85e193739c953358c865005855253af4f68a497John McCall                !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
2055f85e193739c953358c865005855253af4f68a497John McCall      llvm::Value *result = emitARCRetainCall(CGF, e);
2056f85e193739c953358c865005855253af4f68a497John McCall      if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2057f85e193739c953358c865005855253af4f68a497John McCall      return TryEmitResult(result, true);
2058f85e193739c953358c865005855253af4f68a497John McCall    }
2059f85e193739c953358c865005855253af4f68a497John McCall
2060f85e193739c953358c865005855253af4f68a497John McCall    // Conservatively halt the search at any other expression kind.
2061f85e193739c953358c865005855253af4f68a497John McCall    break;
2062f85e193739c953358c865005855253af4f68a497John McCall  }
2063f85e193739c953358c865005855253af4f68a497John McCall
2064f85e193739c953358c865005855253af4f68a497John McCall  // We didn't find an obvious production, so emit what we've got and
2065f85e193739c953358c865005855253af4f68a497John McCall  // tell the caller that we didn't manage to retain.
2066f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = CGF.EmitScalarExpr(e);
2067f85e193739c953358c865005855253af4f68a497John McCall  if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2068f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult(result, false);
2069f85e193739c953358c865005855253af4f68a497John McCall}
2070f85e193739c953358c865005855253af4f68a497John McCall
2071f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2072f85e193739c953358c865005855253af4f68a497John McCall                                                LValue lvalue,
2073f85e193739c953358c865005855253af4f68a497John McCall                                                QualType type) {
2074f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainLoadOfScalar(CGF, lvalue, type);
2075f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2076f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2077f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetain(type, value);
2078f85e193739c953358c865005855253af4f68a497John McCall  return value;
2079f85e193739c953358c865005855253af4f68a497John McCall}
2080f85e193739c953358c865005855253af4f68a497John McCall
2081f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainScalarExpr - Semantically equivalent to
2082f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a
2083f85e193739c953358c865005855253af4f68a497John McCall/// best-effort attempt to peephole expressions that naturally produce
2084f85e193739c953358c865005855253af4f68a497John McCall/// retained objects.
2085f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
2086f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2087f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2088f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2089f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetain(e->getType(), value);
2090f85e193739c953358c865005855253af4f68a497John McCall  return value;
2091f85e193739c953358c865005855253af4f68a497John McCall}
2092f85e193739c953358c865005855253af4f68a497John McCall
2093f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
2094f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {
2095f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2096f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2097f85e193739c953358c865005855253af4f68a497John McCall  if (result.getInt())
2098f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCAutorelease(value);
2099f85e193739c953358c865005855253af4f68a497John McCall  else
2100f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetainAutorelease(e->getType(), value);
2101f85e193739c953358c865005855253af4f68a497John McCall  return value;
2102f85e193739c953358c865005855253af4f68a497John McCall}
2103f85e193739c953358c865005855253af4f68a497John McCall
2104f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2105f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
2106f85e193739c953358c865005855253af4f68a497John McCall                                    bool ignored) {
2107f85e193739c953358c865005855253af4f68a497John McCall  // Evaluate the RHS first.
2108f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS());
2109f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2110f85e193739c953358c865005855253af4f68a497John McCall
2111fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  bool hasImmediateRetain = result.getInt();
2112fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall
2113fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // If we didn't emit a retained object, and the l-value is of block
2114fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // type, then we need to emit the block-retain immediately in case
2115fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // it invalidates the l-value.
2116fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  if (!hasImmediateRetain && e->getType()->isBlockPointerType()) {
2117fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall    value = EmitARCRetainBlock(value);
2118fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall    hasImmediateRetain = true;
2119fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  }
2120fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall
2121f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2122f85e193739c953358c865005855253af4f68a497John McCall
2123f85e193739c953358c865005855253af4f68a497John McCall  // If the RHS was emitted retained, expand this.
2124fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  if (hasImmediateRetain) {
2125f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *oldValue =
2126f85e193739c953358c865005855253af4f68a497John McCall      EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatileQualified(),
2127f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getAlignment(), e->getType(),
2128f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getTBAAInfo());
2129f85e193739c953358c865005855253af4f68a497John McCall    EmitStoreOfScalar(value, lvalue.getAddress(),
2130f85e193739c953358c865005855253af4f68a497John McCall                      lvalue.isVolatileQualified(), lvalue.getAlignment(),
2131f85e193739c953358c865005855253af4f68a497John McCall                      e->getType(), lvalue.getTBAAInfo());
2132f85e193739c953358c865005855253af4f68a497John McCall    EmitARCRelease(oldValue, /*precise*/ false);
2133f85e193739c953358c865005855253af4f68a497John McCall  } else {
2134545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    value = EmitARCStoreStrong(lvalue, value, ignored);
2135f85e193739c953358c865005855253af4f68a497John McCall  }
2136f85e193739c953358c865005855253af4f68a497John McCall
2137f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2138f85e193739c953358c865005855253af4f68a497John McCall}
2139f85e193739c953358c865005855253af4f68a497John McCall
2140f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2141f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) {
2142f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = EmitARCRetainAutoreleaseScalarExpr(e->getRHS());
2143f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2144f85e193739c953358c865005855253af4f68a497John McCall
2145f85e193739c953358c865005855253af4f68a497John McCall  EmitStoreOfScalar(value, lvalue.getAddress(),
2146f85e193739c953358c865005855253af4f68a497John McCall                    lvalue.isVolatileQualified(), lvalue.getAlignment(),
2147f85e193739c953358c865005855253af4f68a497John McCall                    e->getType(), lvalue.getTBAAInfo());
2148f85e193739c953358c865005855253af4f68a497John McCall
2149f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2150f85e193739c953358c865005855253af4f68a497John McCall}
2151f85e193739c953358c865005855253af4f68a497John McCall
2152f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolStmt(
2153f85e193739c953358c865005855253af4f68a497John McCall                                             const ObjCAutoreleasePoolStmt &ARPS) {
2154f85e193739c953358c865005855253af4f68a497John McCall  const Stmt *subStmt = ARPS.getSubStmt();
2155f85e193739c953358c865005855253af4f68a497John McCall  const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
2156f85e193739c953358c865005855253af4f68a497John McCall
2157f85e193739c953358c865005855253af4f68a497John McCall  CGDebugInfo *DI = getDebugInfo();
2158f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2159f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getLBracLoc());
2160f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionStart(Builder);
2161f85e193739c953358c865005855253af4f68a497John McCall  }
2162f85e193739c953358c865005855253af4f68a497John McCall
2163f85e193739c953358c865005855253af4f68a497John McCall  // Keep track of the current cleanup stack depth.
2164f85e193739c953358c865005855253af4f68a497John McCall  RunCleanupsScope Scope(*this);
21659f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (CGM.getCodeGenOpts().ObjCRuntimeHasARC) {
2166f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCAutoreleasePoolPush();
2167f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token);
2168f85e193739c953358c865005855253af4f68a497John McCall  } else {
2169f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCMRRAutoreleasePoolPush();
2170f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token);
2171f85e193739c953358c865005855253af4f68a497John McCall  }
2172f85e193739c953358c865005855253af4f68a497John McCall
2173f85e193739c953358c865005855253af4f68a497John McCall  for (CompoundStmt::const_body_iterator I = S.body_begin(),
2174f85e193739c953358c865005855253af4f68a497John McCall       E = S.body_end(); I != E; ++I)
2175f85e193739c953358c865005855253af4f68a497John McCall    EmitStmt(*I);
2176f85e193739c953358c865005855253af4f68a497John McCall
2177f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2178f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getRBracLoc());
2179f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionEnd(Builder);
2180f85e193739c953358c865005855253af4f68a497John McCall  }
2181f85e193739c953358c865005855253af4f68a497John McCall}
21820c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
21830c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
21840c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// make sure it survives garbage collection until this point.
21850c24c808e4dce43e88abf2d5f98546b901bd4315John McCallvoid CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
21860c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  // We just use an inline assembly.
21870c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::FunctionType *extenderType
2188da549e8995c447542d5631b8b67fcc3a9582797aJay Foad    = llvm::FunctionType::get(VoidTy, VoidPtrTy, /*variadic*/ false);
21890c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::Value *extender
21900c24c808e4dce43e88abf2d5f98546b901bd4315John McCall    = llvm::InlineAsm::get(extenderType,
21910c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* assembly */ "",
21920c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* constraints */ "r",
21930c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* side effects */ true);
21940c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
21950c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  object = Builder.CreateBitCast(object, VoidPtrTy);
21960c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  Builder.CreateCall(extender, object)->setDoesNotThrow();
21970c24c808e4dce43e88abf2d5f98546b901bd4315John McCall}
21980c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
21992979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
2200