CGObjC.cpp revision 5f9e272e632e951b1efe824cd16acb4d96077930
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);
821558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall      EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, true));
822109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    }
823109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    // constructor returns 'self'.
824109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    CodeGenTypes &Types = CGM.getTypes();
825109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    QualType IdTy(CGM.getContext().getObjCIdType());
826109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    llvm::Value *SelfAsId =
827109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
828109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
829e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
830e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_destruct.
831bc397cf90355f17c974b0bdf3960e8fb38caf5d6Chandler Carruth  } else {
832e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    emitCXXDestructMethod(*this, IMP);
833109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  }
834109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  FinishFunction();
835109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian}
836109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian
8370b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanianbool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
8380b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
8390b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  it++; it++;
8400b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  const ABIArgInfo &AI = it->info;
8410b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  // FIXME. Is this sufficient check?
8420b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  return (AI.getKind() == ABIArgInfo::Indirect);
8430b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian}
8440b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian
84515bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanianbool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
84615bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
84715bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return false;
84815bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
84915bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return FDTTy->getDecl()->hasObjectMember();
85015bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  return false;
85115bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian}
85215bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian
853c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf() {
854b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
855b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
8564111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
8574111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
85845012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz JahanianQualType CodeGenFunction::TypeOfSelfObject() {
85945012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
86045012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
86114108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
86214108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    getContext().getCanonicalType(selfDecl->getType()));
86345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  return PTy->getPointeeType();
86445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian}
86545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
866e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallLValue
867e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallCodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
868e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // This is a special l-value that just issues sends when we load or
869e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // store through it.
870e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
871e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // For certain base kinds, we need to emit the base immediately.
872e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Base;
873e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  if (E->isSuperReceiver())
874e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = LoadObjCSelf();
875e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else if (E->isClassReceiver())
876e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver());
877e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else
878e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = EmitScalarExpr(E->getBase());
879e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return LValue::MakePropertyRef(E, Base);
880e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall}
881e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
882e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallstatic RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
883e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       ReturnValueSlot Return,
884e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       QualType ResultType,
885e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       Selector S,
886e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       llvm::Value *Receiver,
887e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       const CallArgList &CallArgs) {
888e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl);
889f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isClassMessage = OMD->isClassMethod();
890f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
891e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return CGF.CGM.getObjCRuntime()
892e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                .GenerateMessageSendSuper(CGF, Return, ResultType,
893e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          S, OMD->getClassInterface(),
894e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isCategoryImpl, Receiver,
895e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isClassMessage, CallArgs);
896f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian}
897f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian
898119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallRValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
899119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                    ReturnValueSlot Return) {
900119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr();
90168af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ResultType = E->getGetterResultType();
90212f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S;
903926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  const ObjCMethodDecl *method;
90412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isExplicitProperty()) {
90512f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    const ObjCPropertyDecl *Property = E->getExplicitProperty();
90612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    S = Property->getGetterName();
907926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = Property->getGetterMethodDecl();
908b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
909926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = E->getImplicitPropertyGetter();
910926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    S = method->getSelector();
9115daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian  }
91212f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
913e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = LV.getPropertyRefBaseAddr();
914e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
915f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount) {
916f85e193739c953358c865005855253af4f68a497John McCall    QualType receiverType;
917f85e193739c953358c865005855253af4f68a497John McCall    if (E->isSuperReceiver())
918f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getSuperReceiverType();
919f85e193739c953358c865005855253af4f68a497John McCall    else if (E->isClassReceiver())
920f85e193739c953358c865005855253af4f68a497John McCall      receiverType = getContext().getObjCClassType();
921f85e193739c953358c865005855253af4f68a497John McCall    else
922f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getBase()->getType();
923f85e193739c953358c865005855253af4f68a497John McCall  }
924f85e193739c953358c865005855253af4f68a497John McCall
925e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // Accesses to 'super' follow a different code path.
92612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver())
927926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return AdjustRelatedResultType(*this, E, method,
928926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                   GenerateMessageSendSuper(*this, Return,
929926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            ResultType,
930926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            S, Receiver,
931926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            CallArgList()));
932119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
933119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
934926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return AdjustRelatedResultType(*this, E, method,
935f85e193739c953358c865005855253af4f68a497John McCall          CGM.getObjCRuntime().
936f85e193739c953358c865005855253af4f68a497John McCall             GenerateMessageSend(*this, Return, ResultType, S,
937f85e193739c953358c865005855253af4f68a497John McCall                                 Receiver, CallArgList(), ReceiverClass));
9389c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar}
9399c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
940119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallvoid CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
941119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                        LValue Dst) {
942119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr();
94312f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S = E->getSetterSelector();
94468af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ArgType = E->getSetterArgType();
94568af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian
946b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // FIXME. Other than scalars, AST is not adequate for setter and
947b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // getter type mismatches which require conversion.
948b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  if (Src.isScalar()) {
949b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    llvm::Value *SrcVal = Src.getScalarVal();
950b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    QualType DstType = getContext().getCanonicalType(ArgType);
9512acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *DstTy = ConvertType(DstType);
952b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    if (SrcVal->getType() != DstTy)
953b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian      Src =
954b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian        RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType));
955b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  }
956b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian
957e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  CallArgList Args;
95804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(Src, ArgType);
959e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
960e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = Dst.getPropertyRefBaseAddr();
961e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  QualType ResultType = getContext().VoidTy;
962e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
96312f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver()) {
964e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    GenerateMessageSendSuper(*this, ReturnValueSlot(),
965e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                             ResultType, S, Receiver, Args);
96612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    return;
96712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  }
96812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
969119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
970119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
97112f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
97212f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
973e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ResultType, S, Receiver, Args,
974e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ReceiverClass);
97585c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar}
97685c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar
97774391b48b4791cded373683a3baf67314f358d50Chris Lattnervoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
9781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Constant *EnumerationMutationFn =
979c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.getObjCRuntime().EnumerationMutationFunction();
9801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
981c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  if (!EnumerationMutationFn) {
982c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
983c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    return;
984c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
985c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
986bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  CGDebugInfo *DI = getDebugInfo();
987bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
988bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getBegin());
989bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionStart(Builder);
990bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
991bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
9929d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  // The local variable comes into scope immediately.
9939d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  AutoVarEmission variable = AutoVarEmission::invalid();
9949d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
9959d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel    variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl()));
9969d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel
997d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
998d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
9991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1000f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fast enumeration state.
1001f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType StateTy = getContext().getObjCFastEnumerationStateType();
1002195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
10031884eb0b5c55edda4893ddec45e7dbad79758782Anders Carlsson  EmitNullInitialization(StatePtr, StateTy);
10041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1005f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Number of elements in the items array.
10062abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  static const unsigned NumItems = 16;
10071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1008d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the countByEnumeratingWithState:objects:count: selector.
1009ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  IdentifierInfo *II[] = {
1010ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
1011ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("objects"),
1012ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("count")
1013ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  };
1014ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  Selector FastEnumSel =
1015ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
1016f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1017f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ItemsTy =
1018f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    getContext().getConstantArrayType(getContext().getObjCIdType(),
10191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      llvm::APInt(32, NumItems),
1020f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ArrayType::Normal, 0);
1021195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
10221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1023d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Emit the collection pointer.
1024f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Collection = EmitScalarExpr(S.getCollection());
10251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1026d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Send it our message:
1027f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CallArgList Args;
1028d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1029d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The first argument is a temporary of the enumeration-state type.
103004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(StatePtr), getContext().getPointerType(StateTy));
10311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1032d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The second argument is a temporary array with space for NumItems
1033d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointers.  We'll actually be loading elements from the array
1034d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointer written into the control state; this buffer is so that
1035d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // collections that *aren't* backed by arrays can still queue up
1036d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // batches of elements.
103704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy));
10381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1039d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The third argument is the capacity of that temporary array.
10402acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
10414a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
104204c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(Count), getContext().UnsignedLongTy);
10431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1044d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start the enumeration.
10451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  RValue CountRV =
1046ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1047f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
1048f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
1049c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
1050f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1051d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The initial number of objects that were returned in the buffer.
1052d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialBufferLimit = CountRV.getScalarVal();
10531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1054d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1055d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1056f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1057d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
1058f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1059d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If the limit pointer was zero to begin with, the collection is
1060d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // empty; skip all this.
1061d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
1062d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopInitBB);
10631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1064d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, initialize the loop.
1065d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopInitBB);
10661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1067d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Save the initial mutations value.  This is the value at an
1068d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // address that was written into the state object by
1069d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // countByEnumeratingWithState:objects:count:.
10701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtrPtr =
10712abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
10721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
10732abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                      "mutationsptr");
10741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1075d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialMutations =
1076d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations");
10771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1078d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start looping.  This is the point we return to whenever we have a
1079d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // fresh, non-empty batch of objects.
1080d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1081d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopBodyBB);
10821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1083d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current index into the buffer.
1084bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
1085d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, LoopInitBB);
1086f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1087d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current buffer size.
1088bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
1089d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(initialBufferLimit, LoopInitBB);
1090f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1091d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether the mutations value has changed from where it was
1092d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // at start.  StateMutationsPtr should actually be invariant between
1093d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes.
10942abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1095d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *currentMutations
1096d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateLoad(StateMutationsPtr, "statemutations");
10971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1098d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1099361cf980a7d976ef11a37b49567412b6b63a89d7Dan Gohman  llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
11001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1101d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1102d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       WasNotMutatedBB, WasMutatedBB);
11031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1104d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If so, call the enumeration-mutation function.
1105d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasMutatedBB);
11062abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *V =
11071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Builder.CreateBitCast(Collection,
11082abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          ConvertType(getContext().getObjCIdType()),
11092abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          "tmp");
11102b2105e92fc77016992dae3f117f526e73af5ea9Daniel Dunbar  CallArgList Args2;
111104c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args2.add(RValue::get(V), getContext().getObjCIdType());
1112f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to get the function info here, the runtime already
1113f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // should have computed it to build the function.
111404a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
1115264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                          FunctionType::ExtInfo()),
1116f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson           EnumerationMutationFn, ReturnValueSlot(), Args2);
11171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1118d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, or if the mutation function returns, just continue.
1119d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasNotMutatedBB);
11201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1121d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Initialize the element variable.
1122d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  RunCleanupsScope elementVariableScope(*this);
112357b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  bool elementIsVariable;
1124d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  LValue elementLValue;
1125d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  QualType elementType;
1126d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
112757b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    // Initialize the variable, in case it's a __block variable or something.
112857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarInit(variable);
1129f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
113057b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
1131d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
1132d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                        VK_LValue, SourceLocation());
1133d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(&tempDRE);
1134d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = D->getType();
113557b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = true;
11367acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall
11377acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    if (D->isARCPseudoStrong())
11387acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall      elementLValue.getQuals().setObjCLifetime(Qualifiers::OCL_ExplicitNone);
1139d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  } else {
1140d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = LValue(); // suppress warning
1141d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = cast<Expr>(S.getElement())->getType();
114257b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = false;
1143d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
11442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *convertedElementType = ConvertType(elementType);
1145f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1146d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the buffer out of the enumeration state.
1147d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // TODO: this pointer should actually be invariant between
1148d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes, which would help us do certain loop optimizations.
1149d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *StateItemsPtr =
1150d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
1151d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *EnumStateItems =
1152d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateItemsPtr, "stateitems");
1153f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1154d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the value at the current index from the buffer.
11551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *CurrentItemPtr =
1156d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr");
1157d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr);
11581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1159d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Cast that value to the right type.
1160d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
1161d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                                      "currentitem");
11621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1163d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Make sure we have an l-value.  Yes, this gets evaluated every
1164d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // time through the loop.
11657acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  if (!elementIsVariable) {
1166d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1167545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue);
11687acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  } else {
11697acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    EmitScalarInit(CurrentItem, elementLValue);
11707acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  }
11711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
117257b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // If we do have an element variable, this assignment is the end of
117357b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // its initialization.
117457b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (elementIsVariable)
117557b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarCleanups(variable);
117657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall
1177d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Perform the loop body, setting up break and continue labels.
1178e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
1179d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  {
1180d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    RunCleanupsScope Scope(*this);
1181d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    EmitStmt(S.getBody());
1182d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
1183f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.pop_back();
11841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1185d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Destroy the element variable now.
1186d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  elementVariableScope.ForceCleanup();
1187d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1188d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether there are more elements.
1189ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(AfterBody.getBlock());
11901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1191d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
1192d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1193d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // First we check in the local buffer.
1194d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *indexPlusOne
1195d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
1196d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1197d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we haven't overrun the buffer yet, we can continue.
1198d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
1199d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       LoopBodyBB, FetchMoreBB);
1200f0906c4edb37b20141428ca77fa7dfd00b976eafFariborz Jahanian
1201d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(indexPlusOne, AfterBody.getBlock());
1202d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(count, AfterBody.getBlock());
1203f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1204d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, we have to fetch more elements.
1205d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(FetchMoreBB);
12061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CountRV =
1208ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1209f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
12101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             FastEnumSel,
1211c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
12121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1213d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we got a zero count, we're done.
1214d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *refetchCount = CountRV.getScalarVal();
1215d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1216d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // (note that the message send might split FetchMoreBB)
1217d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, Builder.GetInsertBlock());
1218d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(refetchCount, Builder.GetInsertBlock());
1219d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1220d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
1221d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopBodyBB);
12221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1223f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // No more elements.
1224d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(EmptyBB);
1225f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
122657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (!elementIsVariable) {
1227f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // If the element was not a declaration, set it to be null.
1228f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1229d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
1230d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1231545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(null), elementLValue);
1232f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
1233f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1234bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
1235bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getEnd());
1236bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionEnd(Builder);
1237bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
1238bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
1239ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(LoopEnd.getBlock());
12403d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
12413d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
12421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
1243f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitTryStmt(*this, S);
124464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
124564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
12461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
124764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
124864d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
124964d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
125010cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattnervoid CodeGenFunction::EmitObjCAtSynchronizedStmt(
12511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              const ObjCAtSynchronizedStmt &S) {
1252f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
125310cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner}
125410cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner
1255f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code for a CK_ObjCProduceObject.  Just does a
1256f85e193739c953358c865005855253af4f68a497John McCall/// primitive retain.
1257f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCProduceObject(QualType type,
1258f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *value) {
1259f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetain(type, value);
1260f85e193739c953358c865005855253af4f68a497John McCall}
1261f85e193739c953358c865005855253af4f68a497John McCall
1262f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1263f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCRelease : EHScopeStack::Cleanup {
1264f85e193739c953358c865005855253af4f68a497John McCall    CallObjCRelease(QualType type, llvm::Value *ptr, llvm::Value *condition)
1265f85e193739c953358c865005855253af4f68a497John McCall      : type(type), ptr(ptr), condition(condition) {}
1266f85e193739c953358c865005855253af4f68a497John McCall    QualType type;
1267f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *ptr;
1268f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *condition;
1269f85e193739c953358c865005855253af4f68a497John McCall
1270ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1271f85e193739c953358c865005855253af4f68a497John McCall      llvm::Value *object;
1272f85e193739c953358c865005855253af4f68a497John McCall
1273f85e193739c953358c865005855253af4f68a497John McCall      // If we're in a conditional branch, we had to stash away in an
1274f85e193739c953358c865005855253af4f68a497John McCall      // alloca the pointer to be released.
1275f85e193739c953358c865005855253af4f68a497John McCall      llvm::BasicBlock *cont = 0;
1276f85e193739c953358c865005855253af4f68a497John McCall      if (condition) {
1277f85e193739c953358c865005855253af4f68a497John McCall        llvm::BasicBlock *release = CGF.createBasicBlock("release.yes");
1278f85e193739c953358c865005855253af4f68a497John McCall        cont = CGF.createBasicBlock("release.cont");
1279f85e193739c953358c865005855253af4f68a497John McCall
1280f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *cond = CGF.Builder.CreateLoad(condition);
1281f85e193739c953358c865005855253af4f68a497John McCall        CGF.Builder.CreateCondBr(cond, release, cont);
1282f85e193739c953358c865005855253af4f68a497John McCall        CGF.EmitBlock(release);
1283f85e193739c953358c865005855253af4f68a497John McCall        object = CGF.Builder.CreateLoad(ptr);
1284f85e193739c953358c865005855253af4f68a497John McCall      } else {
1285f85e193739c953358c865005855253af4f68a497John McCall        object = ptr;
1286f85e193739c953358c865005855253af4f68a497John McCall      }
1287f85e193739c953358c865005855253af4f68a497John McCall
1288f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitARCRelease(object, /*precise*/ true);
1289f85e193739c953358c865005855253af4f68a497John McCall
1290f85e193739c953358c865005855253af4f68a497John McCall      if (cont) CGF.EmitBlock(cont);
1291f85e193739c953358c865005855253af4f68a497John McCall    }
1292f85e193739c953358c865005855253af4f68a497John McCall  };
1293f85e193739c953358c865005855253af4f68a497John McCall}
1294f85e193739c953358c865005855253af4f68a497John McCall
1295f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code for a CK_ObjCConsumeObject.  Does a primitive
1296f85e193739c953358c865005855253af4f68a497John McCall/// release at the end of the full-expression.
1297f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
1298f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *object) {
1299f85e193739c953358c865005855253af4f68a497John McCall  // If we're in a conditional branch, we need to make the cleanup
1300f85e193739c953358c865005855253af4f68a497John McCall  // conditional.  FIXME: this really needs to be supported by the
1301f85e193739c953358c865005855253af4f68a497John McCall  // environment.
1302f85e193739c953358c865005855253af4f68a497John McCall  llvm::AllocaInst *cond;
1303f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *ptr;
1304f85e193739c953358c865005855253af4f68a497John McCall  if (isInConditionalBranch()) {
1305f85e193739c953358c865005855253af4f68a497John McCall    cond = CreateTempAlloca(Builder.getInt1Ty(), "release.cond");
1306f85e193739c953358c865005855253af4f68a497John McCall    ptr = CreateTempAlloca(object->getType(), "release.value");
1307f85e193739c953358c865005855253af4f68a497John McCall
1308f85e193739c953358c865005855253af4f68a497John McCall    // The alloca is false until we get here.
1309f85e193739c953358c865005855253af4f68a497John McCall    // FIXME: er. doesn't this need to be set at the start of the condition?
1310f85e193739c953358c865005855253af4f68a497John McCall    InitTempAlloca(cond, Builder.getFalse());
1311f85e193739c953358c865005855253af4f68a497John McCall
1312f85e193739c953358c865005855253af4f68a497John McCall    // Then it turns true.
1313f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(Builder.getTrue(), cond);
1314f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(object, ptr);
1315f85e193739c953358c865005855253af4f68a497John McCall  } else {
1316f85e193739c953358c865005855253af4f68a497John McCall    cond = 0;
1317f85e193739c953358c865005855253af4f68a497John McCall    ptr = object;
1318f85e193739c953358c865005855253af4f68a497John McCall  }
1319f85e193739c953358c865005855253af4f68a497John McCall
1320f85e193739c953358c865005855253af4f68a497John McCall  EHStack.pushCleanup<CallObjCRelease>(getARCCleanupKind(), type, ptr, cond);
1321f85e193739c953358c865005855253af4f68a497John McCall  return object;
1322f85e193739c953358c865005855253af4f68a497John McCall}
1323f85e193739c953358c865005855253af4f68a497John McCall
1324f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
1325f85e193739c953358c865005855253af4f68a497John McCall                                                           llvm::Value *value) {
1326f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetainAutorelease(type, value);
1327f85e193739c953358c865005855253af4f68a497John McCall}
1328f85e193739c953358c865005855253af4f68a497John McCall
1329f85e193739c953358c865005855253af4f68a497John McCall
1330f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
13312acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner                                                llvm::FunctionType *type,
13325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                                StringRef fnName) {
1333f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
1334f85e193739c953358c865005855253af4f68a497John McCall
1335f85e193739c953358c865005855253af4f68a497John McCall  // In -fobjc-no-arc-runtime, emit weak references to the runtime
1336f85e193739c953358c865005855253af4f68a497John McCall  // support library.
13379f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (!CGM.getCodeGenOpts().ObjCRuntimeHasARC)
1338f85e193739c953358c865005855253af4f68a497John McCall    if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
1339f85e193739c953358c865005855253af4f68a497John McCall      f->setLinkage(llvm::Function::ExternalWeakLinkage);
1340f85e193739c953358c865005855253af4f68a497John McCall
1341f85e193739c953358c865005855253af4f68a497John McCall  return fn;
1342f85e193739c953358c865005855253af4f68a497John McCall}
1343f85e193739c953358c865005855253af4f68a497John McCall
1344f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the signature
1345f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8*)
1346f85e193739c953358c865005855253af4f68a497John McCall/// where a null input causes a no-op and returns null.
1347f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
1348f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1349f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
13505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName) {
1351f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1352f85e193739c953358c865005855253af4f68a497John McCall
1353f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13549cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrTy);
13552acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1356f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1357f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1358f85e193739c953358c865005855253af4f68a497John McCall  }
1359f85e193739c953358c865005855253af4f68a497John McCall
1360f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
13612acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1362f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1363f85e193739c953358c865005855253af4f68a497John McCall
1364f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1365f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, value);
1366f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1367f85e193739c953358c865005855253af4f68a497John McCall
1368f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to the original type.
1369f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(call, origType);
1370f85e193739c953358c865005855253af4f68a497John McCall}
1371f85e193739c953358c865005855253af4f68a497John McCall
1372f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1373f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**)
1374f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
1375f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Value *addr,
1376f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Constant *&fn,
13775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                         StringRef fnName) {
1378f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13799cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrPtrTy);
13802acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1381f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1382f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1383f85e193739c953358c865005855253af4f68a497John McCall  }
1384f85e193739c953358c865005855253af4f68a497John McCall
1385f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
13862acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = addr->getType();
1387f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1388f85e193739c953358c865005855253af4f68a497John McCall
1389f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1390f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, addr);
1391f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1392f85e193739c953358c865005855253af4f68a497John McCall
1393f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to a dereference of the original type.
1394f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = call;
1395f85e193739c953358c865005855253af4f68a497John McCall  if (origType != CGF.Int8PtrPtrTy)
1396f85e193739c953358c865005855253af4f68a497John McCall    result = CGF.Builder.CreateBitCast(result,
1397f85e193739c953358c865005855253af4f68a497John McCall                        cast<llvm::PointerType>(origType)->getElementType());
1398f85e193739c953358c865005855253af4f68a497John McCall
1399f85e193739c953358c865005855253af4f68a497John McCall  return result;
1400f85e193739c953358c865005855253af4f68a497John McCall}
1401f85e193739c953358c865005855253af4f68a497John McCall
1402f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1403f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**, i8*)
1404f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
1405f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *addr,
1406f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1407f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
14085f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName,
1409f85e193739c953358c865005855253af4f68a497John McCall                                          bool ignored) {
1410f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1411f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1412f85e193739c953358c865005855253af4f68a497John McCall
1413f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14149cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2);
1415f85e193739c953358c865005855253af4f68a497John McCall    argTypes[0] = CGF.Int8PtrPtrTy;
1416f85e193739c953358c865005855253af4f68a497John McCall    argTypes[1] = CGF.Int8PtrTy;
1417f85e193739c953358c865005855253af4f68a497John McCall
14182acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1419f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false);
1420f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1421f85e193739c953358c865005855253af4f68a497John McCall  }
1422f85e193739c953358c865005855253af4f68a497John McCall
14232acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1424f85e193739c953358c865005855253af4f68a497John McCall
1425f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1426f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1427f85e193739c953358c865005855253af4f68a497John McCall
1428f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, addr, value);
1429f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1430f85e193739c953358c865005855253af4f68a497John McCall
1431f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1432f85e193739c953358c865005855253af4f68a497John McCall
1433f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(result, origType);
1434f85e193739c953358c865005855253af4f68a497John McCall}
1435f85e193739c953358c865005855253af4f68a497John McCall
1436f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1437f85e193739c953358c865005855253af4f68a497John McCall///   void (i8**, i8**)
1438f85e193739c953358c865005855253af4f68a497John McCallstatic void emitARCCopyOperation(CodeGenFunction &CGF,
1439f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *dst,
1440f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *src,
1441f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Constant *&fn,
14425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                 StringRef fnName) {
1443f85e193739c953358c865005855253af4f68a497John McCall  assert(dst->getType() == src->getType());
1444f85e193739c953358c865005855253af4f68a497John McCall
1445f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14469cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2, CGF.Int8PtrPtrTy);
14472acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1448f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false);
1449f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1450f85e193739c953358c865005855253af4f68a497John McCall  }
1451f85e193739c953358c865005855253af4f68a497John McCall
1452f85e193739c953358c865005855253af4f68a497John McCall  dst = CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy);
1453f85e193739c953358c865005855253af4f68a497John McCall  src = CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy);
1454f85e193739c953358c865005855253af4f68a497John McCall
1455f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, dst, src);
1456f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1457f85e193739c953358c865005855253af4f68a497John McCall}
1458f85e193739c953358c865005855253af4f68a497John McCall
1459f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a retain.  Based on the type, calls one of:
1460f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1461f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1462f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {
1463f85e193739c953358c865005855253af4f68a497John McCall  if (type->isBlockPointerType())
1464f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainBlock(value);
1465f85e193739c953358c865005855253af4f68a497John McCall  else
1466f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainNonBlock(value);
1467f85e193739c953358c865005855253af4f68a497John McCall}
1468f85e193739c953358c865005855253af4f68a497John McCall
1469f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object, with normal retain semantics.
1470f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1471f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) {
1472f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1473f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retain,
1474f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retain");
1475f85e193739c953358c865005855253af4f68a497John McCall}
1476f85e193739c953358c865005855253af4f68a497John McCall
1477f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given block, with _Block_copy semantics.
1478f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1479f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value) {
1480f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1481f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainBlock,
1482f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainBlock");
1483f85e193739c953358c865005855253af4f68a497John McCall}
1484f85e193739c953358c865005855253af4f68a497John McCall
1485f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object which is the result of a function call.
1486f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleasedReturnValue(i8* %value)
1487f85e193739c953358c865005855253af4f68a497John McCall///
1488f85e193739c953358c865005855253af4f68a497John McCall/// Yes, this function name is one character away from a different
1489f85e193739c953358c865005855253af4f68a497John McCall/// call with completely different semantics.
1490f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1491f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
1492f85e193739c953358c865005855253af4f68a497John McCall  // Fetch the void(void) inline asm which marks that we're going to
1493f85e193739c953358c865005855253af4f68a497John McCall  // retain the autoreleased return value.
1494f85e193739c953358c865005855253af4f68a497John McCall  llvm::InlineAsm *&marker
1495f85e193739c953358c865005855253af4f68a497John McCall    = CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker;
1496f85e193739c953358c865005855253af4f68a497John McCall  if (!marker) {
14975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef assembly
1498f85e193739c953358c865005855253af4f68a497John McCall      = CGM.getTargetCodeGenInfo()
1499f85e193739c953358c865005855253af4f68a497John McCall           .getARCRetainAutoreleasedReturnValueMarker();
1500f85e193739c953358c865005855253af4f68a497John McCall
1501f85e193739c953358c865005855253af4f68a497John McCall    // If we have an empty assembly string, there's nothing to do.
1502f85e193739c953358c865005855253af4f68a497John McCall    if (assembly.empty()) {
1503f85e193739c953358c865005855253af4f68a497John McCall
1504f85e193739c953358c865005855253af4f68a497John McCall    // Otherwise, at -O0, build an inline asm that we're going to call
1505f85e193739c953358c865005855253af4f68a497John McCall    // in a moment.
1506f85e193739c953358c865005855253af4f68a497John McCall    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1507f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType *type =
1508f85e193739c953358c865005855253af4f68a497John McCall        llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
1509f85e193739c953358c865005855253af4f68a497John McCall                                /*variadic*/ false);
1510f85e193739c953358c865005855253af4f68a497John McCall
1511f85e193739c953358c865005855253af4f68a497John McCall      marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true);
1512f85e193739c953358c865005855253af4f68a497John McCall
1513f85e193739c953358c865005855253af4f68a497John McCall    // If we're at -O1 and above, we don't want to litter the code
1514f85e193739c953358c865005855253af4f68a497John McCall    // with this marker yet, so leave a breadcrumb for the ARC
1515f85e193739c953358c865005855253af4f68a497John McCall    // optimizer to pick up.
1516f85e193739c953358c865005855253af4f68a497John McCall    } else {
1517f85e193739c953358c865005855253af4f68a497John McCall      llvm::NamedMDNode *metadata =
1518f85e193739c953358c865005855253af4f68a497John McCall        CGM.getModule().getOrInsertNamedMetadata(
1519f85e193739c953358c865005855253af4f68a497John McCall                            "clang.arc.retainAutoreleasedReturnValueMarker");
1520f85e193739c953358c865005855253af4f68a497John McCall      assert(metadata->getNumOperands() <= 1);
1521f85e193739c953358c865005855253af4f68a497John McCall      if (metadata->getNumOperands() == 0) {
1522f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *string = llvm::MDString::get(getLLVMContext(), assembly);
1523f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *args[] = { string };
1524f85e193739c953358c865005855253af4f68a497John McCall        metadata->addOperand(llvm::MDNode::get(getLLVMContext(), args));
1525f85e193739c953358c865005855253af4f68a497John McCall      }
1526f85e193739c953358c865005855253af4f68a497John McCall    }
1527f85e193739c953358c865005855253af4f68a497John McCall  }
1528f85e193739c953358c865005855253af4f68a497John McCall
1529f85e193739c953358c865005855253af4f68a497John McCall  // Call the marker asm if we made one, which we do only at -O0.
1530f85e193739c953358c865005855253af4f68a497John McCall  if (marker) Builder.CreateCall(marker);
1531f85e193739c953358c865005855253af4f68a497John McCall
1532f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1533f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleasedReturnValue,
1534f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleasedReturnValue");
1535f85e193739c953358c865005855253af4f68a497John McCall}
1536f85e193739c953358c865005855253af4f68a497John McCall
1537f85e193739c953358c865005855253af4f68a497John McCall/// Release the given object.
1538f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_release(i8* %value)
1539f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCRelease(llvm::Value *value, bool precise) {
1540f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return;
1541f85e193739c953358c865005855253af4f68a497John McCall
1542f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_release;
1543f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15449cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
15452acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1546f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1547f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_release");
1548f85e193739c953358c865005855253af4f68a497John McCall  }
1549f85e193739c953358c865005855253af4f68a497John McCall
1550f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
1551f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1552f85e193739c953358c865005855253af4f68a497John McCall
1553f85e193739c953358c865005855253af4f68a497John McCall  // Call objc_release.
1554f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1555f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1556f85e193739c953358c865005855253af4f68a497John McCall
1557f85e193739c953358c865005855253af4f68a497John McCall  if (!precise) {
15585f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<llvm::Value*,1> args;
1559f85e193739c953358c865005855253af4f68a497John McCall    call->setMetadata("clang.imprecise_release",
1560f85e193739c953358c865005855253af4f68a497John McCall                      llvm::MDNode::get(Builder.getContext(), args));
1561f85e193739c953358c865005855253af4f68a497John McCall  }
1562f85e193739c953358c865005855253af4f68a497John McCall}
1563f85e193739c953358c865005855253af4f68a497John McCall
1564f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Always calls this:
1565f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1566f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr,
1567f85e193739c953358c865005855253af4f68a497John McCall                                                     llvm::Value *value,
1568f85e193739c953358c865005855253af4f68a497John McCall                                                     bool ignored) {
1569f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1570f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1571f85e193739c953358c865005855253af4f68a497John McCall
1572f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_storeStrong;
1573f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy };
15752acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1576f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false);
1577f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong");
1578f85e193739c953358c865005855253af4f68a497John McCall  }
1579f85e193739c953358c865005855253af4f68a497John McCall
1580f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1581f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *castValue = Builder.CreateBitCast(value, Int8PtrTy);
1582f85e193739c953358c865005855253af4f68a497John McCall
1583f85e193739c953358c865005855253af4f68a497John McCall  Builder.CreateCall2(fn, addr, castValue)->setDoesNotThrow();
1584f85e193739c953358c865005855253af4f68a497John McCall
1585f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1586f85e193739c953358c865005855253af4f68a497John McCall  return value;
1587f85e193739c953358c865005855253af4f68a497John McCall}
1588f85e193739c953358c865005855253af4f68a497John McCall
1589f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Sometimes calls this:
1590f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1591f85e193739c953358c865005855253af4f68a497John McCall/// Other times, breaks it down into components.
1592545d996ec5a3113f046944f11b27cc2d6cb055b4John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
1593f85e193739c953358c865005855253af4f68a497John McCall                                                 llvm::Value *newValue,
1594f85e193739c953358c865005855253af4f68a497John McCall                                                 bool ignored) {
1595545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  QualType type = dst.getType();
1596f85e193739c953358c865005855253af4f68a497John McCall  bool isBlock = type->isBlockPointerType();
1597f85e193739c953358c865005855253af4f68a497John McCall
1598f85e193739c953358c865005855253af4f68a497John McCall  // Use a store barrier at -O0 unless this is a block type or the
1599f85e193739c953358c865005855253af4f68a497John McCall  // lvalue is inadequately aligned.
1600f85e193739c953358c865005855253af4f68a497John McCall  if (shouldUseFusedARCCalls() &&
1601f85e193739c953358c865005855253af4f68a497John McCall      !isBlock &&
1602f85e193739c953358c865005855253af4f68a497John McCall      !(dst.getAlignment() && dst.getAlignment() < PointerAlignInBytes)) {
1603f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCStoreStrongCall(dst.getAddress(), newValue, ignored);
1604f85e193739c953358c865005855253af4f68a497John McCall  }
1605f85e193739c953358c865005855253af4f68a497John McCall
1606f85e193739c953358c865005855253af4f68a497John McCall  // Otherwise, split it out.
1607f85e193739c953358c865005855253af4f68a497John McCall
1608f85e193739c953358c865005855253af4f68a497John McCall  // Retain the new value.
1609f85e193739c953358c865005855253af4f68a497John McCall  newValue = EmitARCRetain(type, newValue);
1610f85e193739c953358c865005855253af4f68a497John McCall
1611f85e193739c953358c865005855253af4f68a497John McCall  // Read the old value.
1612545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  llvm::Value *oldValue = EmitLoadOfScalar(dst);
1613f85e193739c953358c865005855253af4f68a497John McCall
1614f85e193739c953358c865005855253af4f68a497John McCall  // Store.  We do this before the release so that any deallocs won't
1615f85e193739c953358c865005855253af4f68a497John McCall  // see the old value.
1616545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  EmitStoreOfScalar(newValue, dst);
1617f85e193739c953358c865005855253af4f68a497John McCall
1618f85e193739c953358c865005855253af4f68a497John McCall  // Finally, release the old value.
1619f85e193739c953358c865005855253af4f68a497John McCall  EmitARCRelease(oldValue, /*precise*/ false);
1620f85e193739c953358c865005855253af4f68a497John McCall
1621f85e193739c953358c865005855253af4f68a497John McCall  return newValue;
1622f85e193739c953358c865005855253af4f68a497John McCall}
1623f85e193739c953358c865005855253af4f68a497John McCall
1624f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1625f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %value)
1626f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) {
1627f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1628f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_autorelease,
1629f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autorelease");
1630f85e193739c953358c865005855253af4f68a497John McCall}
1631f85e193739c953358c865005855253af4f68a497John McCall
1632f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1633f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleaseReturnValue(i8* %value)
1634f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1635f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
1636f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1637f85e193739c953358c865005855253af4f68a497John McCall                            CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
1638f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autoreleaseReturnValue");
1639f85e193739c953358c865005855253af4f68a497John McCall}
1640f85e193739c953358c865005855253af4f68a497John McCall
1641f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1642f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleaseReturnValue(i8* %value)
1643f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1644f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
1645f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1646f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
1647f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleaseReturnValue");
1648f85e193739c953358c865005855253af4f68a497John McCall}
1649f85e193739c953358c865005855253af4f68a497John McCall
1650f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1651f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1652f85e193739c953358c865005855253af4f68a497John McCall/// or
1653f85e193739c953358c865005855253af4f68a497John McCall///   %retain = call i8* @objc_retainBlock(i8* %value)
1654f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %retain)
1655f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
1656f85e193739c953358c865005855253af4f68a497John McCall                                                       llvm::Value *value) {
1657f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isBlockPointerType())
1658f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainAutoreleaseNonBlock(value);
1659f85e193739c953358c865005855253af4f68a497John McCall
1660f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1661f85e193739c953358c865005855253af4f68a497John McCall
16622acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1663f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1664f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCRetainBlock(value);
1665f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCAutorelease(value);
1666f85e193739c953358c865005855253af4f68a497John McCall  return Builder.CreateBitCast(value, origType);
1667f85e193739c953358c865005855253af4f68a497John McCall}
1668f85e193739c953358c865005855253af4f68a497John McCall
1669f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1670f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1671f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1672f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) {
1673f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1674f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainAutorelease,
1675f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutorelease");
1676f85e193739c953358c865005855253af4f68a497John McCall}
1677f85e193739c953358c865005855253af4f68a497John McCall
1678f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeak(i8** %addr)
1679f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_autorelease(objc_loadWeakRetained(addr)).
1680f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeak(llvm::Value *addr) {
1681f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1682f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeak,
1683f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeak");
1684f85e193739c953358c865005855253af4f68a497John McCall}
1685f85e193739c953358c865005855253af4f68a497John McCall
1686f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeakRetained(i8** %addr)
1687f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(llvm::Value *addr) {
1688f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1689f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeakRetained,
1690f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeakRetained");
1691f85e193739c953358c865005855253af4f68a497John McCall}
1692f85e193739c953358c865005855253af4f68a497John McCall
1693f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_storeWeak(i8** %addr, i8* %value)
1694f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.
1695f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreWeak(llvm::Value *addr,
1696f85e193739c953358c865005855253af4f68a497John McCall                                               llvm::Value *value,
1697f85e193739c953358c865005855253af4f68a497John McCall                                               bool ignored) {
1698f85e193739c953358c865005855253af4f68a497John McCall  return emitARCStoreOperation(*this, addr, value,
1699f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_storeWeak,
1700f85e193739c953358c865005855253af4f68a497John McCall                               "objc_storeWeak", ignored);
1701f85e193739c953358c865005855253af4f68a497John McCall}
1702f85e193739c953358c865005855253af4f68a497John McCall
1703f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_initWeak(i8** %addr, i8* %value)
1704f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.  %addr is known to not have a current weak entry.
1705f85e193739c953358c865005855253af4f68a497John McCall/// Essentially equivalent to:
1706f85e193739c953358c865005855253af4f68a497John McCall///   *addr = nil; objc_storeWeak(addr, value);
1707f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCInitWeak(llvm::Value *addr, llvm::Value *value) {
1708f85e193739c953358c865005855253af4f68a497John McCall  // If we're initializing to null, just write null to memory; no need
1709f85e193739c953358c865005855253af4f68a497John McCall  // to get the runtime involved.  But don't do this if optimization
1710f85e193739c953358c865005855253af4f68a497John McCall  // is enabled, because accounting for this would make the optimizer
1711f85e193739c953358c865005855253af4f68a497John McCall  // much more complicated.
1712f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value) &&
1713f85e193739c953358c865005855253af4f68a497John McCall      CGM.getCodeGenOpts().OptimizationLevel == 0) {
1714f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(value, addr);
1715f85e193739c953358c865005855253af4f68a497John McCall    return;
1716f85e193739c953358c865005855253af4f68a497John McCall  }
1717f85e193739c953358c865005855253af4f68a497John McCall
1718f85e193739c953358c865005855253af4f68a497John McCall  emitARCStoreOperation(*this, addr, value,
1719f85e193739c953358c865005855253af4f68a497John McCall                        CGM.getARCEntrypoints().objc_initWeak,
1720f85e193739c953358c865005855253af4f68a497John McCall                        "objc_initWeak", /*ignored*/ true);
1721f85e193739c953358c865005855253af4f68a497John McCall}
1722f85e193739c953358c865005855253af4f68a497John McCall
1723f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_destroyWeak(i8** %addr)
1724f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_storeWeak(addr, nil).
1725f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCDestroyWeak(llvm::Value *addr) {
1726f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_destroyWeak;
1727f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17289cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrPtrTy);
17292acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1730f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1731f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak");
1732f85e193739c953358c865005855253af4f68a497John McCall  }
1733f85e193739c953358c865005855253af4f68a497John McCall
1734f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
1735f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1736f85e193739c953358c865005855253af4f68a497John McCall
1737f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, addr);
1738f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1739f85e193739c953358c865005855253af4f68a497John McCall}
1740f85e193739c953358c865005855253af4f68a497John McCall
1741f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_moveWeak(i8** %dest, i8** %src)
1742f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Leaves %src pointing to nothing.
1743f85e193739c953358c865005855253af4f68a497John McCall/// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)).
1744f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src) {
1745f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1746f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_moveWeak,
1747f85e193739c953358c865005855253af4f68a497John McCall                       "objc_moveWeak");
1748f85e193739c953358c865005855253af4f68a497John McCall}
1749f85e193739c953358c865005855253af4f68a497John McCall
1750f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_copyWeak(i8** %dest, i8** %src)
1751f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Essentially
1752f85e193739c953358c865005855253af4f68a497John McCall///   objc_release(objc_initWeak(dest, objc_readWeakRetained(src)))
1753f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCCopyWeak(llvm::Value *dst, llvm::Value *src) {
1754f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1755f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_copyWeak,
1756f85e193739c953358c865005855253af4f68a497John McCall                       "objc_copyWeak");
1757f85e193739c953358c865005855253af4f68a497John McCall}
1758f85e193739c953358c865005855253af4f68a497John McCall
1759f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a objc_autoreleasepool_push.
1760f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleasePoolPush(void)
1761f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
1762f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPush;
1763f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17642acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1765f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Int8PtrTy, false);
1766f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush");
1767f85e193739c953358c865005855253af4f68a497John McCall  }
1768f85e193739c953358c865005855253af4f68a497John McCall
1769f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn);
1770f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1771f85e193739c953358c865005855253af4f68a497John McCall
1772f85e193739c953358c865005855253af4f68a497John McCall  return call;
1773f85e193739c953358c865005855253af4f68a497John McCall}
1774f85e193739c953358c865005855253af4f68a497John McCall
1775f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1776f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_autoreleasePoolPop(i8* %ptr)
1777f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
1778f85e193739c953358c865005855253af4f68a497John McCall  assert(value->getType() == Int8PtrTy);
1779f85e193739c953358c865005855253af4f68a497John McCall
1780f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPop;
1781f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17829cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
17832acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1784f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1785f85e193739c953358c865005855253af4f68a497John McCall
1786f85e193739c953358c865005855253af4f68a497John McCall    // We don't want to use a weak import here; instead we should not
1787f85e193739c953358c865005855253af4f68a497John McCall    // fall into this path.
1788f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop");
1789f85e193739c953358c865005855253af4f68a497John McCall  }
1790f85e193739c953358c865005855253af4f68a497John McCall
1791f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1792f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1793f85e193739c953358c865005855253af4f68a497John McCall}
1794f85e193739c953358c865005855253af4f68a497John McCall
1795f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do an MRR version objc_autoreleasepool_push.
1796f85e193739c953358c865005855253af4f68a497John McCall/// Which is: [[NSAutoreleasePool alloc] init];
1797f85e193739c953358c865005855253af4f68a497John McCall/// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class.
1798f85e193739c953358c865005855253af4f68a497John McCall/// init is declared as: - (id) init; in its NSObject super class.
1799f85e193739c953358c865005855253af4f68a497John McCall///
1800f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() {
1801f85e193739c953358c865005855253af4f68a497John McCall  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
1802f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(Builder);
1803f85e193739c953358c865005855253af4f68a497John McCall  // [NSAutoreleasePool alloc]
1804f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");
1805f85e193739c953358c865005855253af4f68a497John McCall  Selector AllocSel = getContext().Selectors.getSelector(0, &II);
1806f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1807f85e193739c953358c865005855253af4f68a497John McCall  RValue AllocRV =
1808f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1809f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1810f85e193739c953358c865005855253af4f68a497John McCall                                AllocSel, Receiver, Args);
1811f85e193739c953358c865005855253af4f68a497John McCall
1812f85e193739c953358c865005855253af4f68a497John McCall  // [Receiver init]
1813f85e193739c953358c865005855253af4f68a497John McCall  Receiver = AllocRV.getScalarVal();
1814f85e193739c953358c865005855253af4f68a497John McCall  II = &CGM.getContext().Idents.get("init");
1815f85e193739c953358c865005855253af4f68a497John McCall  Selector InitSel = getContext().Selectors.getSelector(0, &II);
1816f85e193739c953358c865005855253af4f68a497John McCall  RValue InitRV =
1817f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1818f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1819f85e193739c953358c865005855253af4f68a497John McCall                                InitSel, Receiver, Args);
1820f85e193739c953358c865005855253af4f68a497John McCall  return InitRV.getScalarVal();
1821f85e193739c953358c865005855253af4f68a497John McCall}
1822f85e193739c953358c865005855253af4f68a497John McCall
1823f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1824f85e193739c953358c865005855253af4f68a497John McCall/// [tmp drain];
1825f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) {
1826f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("drain");
1827f85e193739c953358c865005855253af4f68a497John McCall  Selector DrainSel = getContext().Selectors.getSelector(0, &II);
1828f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1829f85e193739c953358c865005855253af4f68a497John McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1830f85e193739c953358c865005855253af4f68a497John McCall                              getContext().VoidTy, DrainSel, Arg, Args);
1831f85e193739c953358c865005855253af4f68a497John McCall}
1832f85e193739c953358c865005855253af4f68a497John McCall
1833bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
1834bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              llvm::Value *addr,
1835bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              QualType type) {
1836bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1837bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ true);
1838bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1839bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1840bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
1841bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                llvm::Value *addr,
1842bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                QualType type) {
1843bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1844bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ false);
1845bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1846bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1847bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
1848bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     llvm::Value *addr,
1849bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     QualType type) {
1850bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCDestroyWeak(addr);
1851bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1852bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1853f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1854f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCAutoreleasePoolObject : EHScopeStack::Cleanup {
1855f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1856f85e193739c953358c865005855253af4f68a497John McCall
1857f85e193739c953358c865005855253af4f68a497John McCall    CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1858f85e193739c953358c865005855253af4f68a497John McCall
1859ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1860f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCAutoreleasePoolPop(Token);
1861f85e193739c953358c865005855253af4f68a497John McCall    }
1862f85e193739c953358c865005855253af4f68a497John McCall  };
1863f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCMRRAutoreleasePoolObject : EHScopeStack::Cleanup {
1864f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1865f85e193739c953358c865005855253af4f68a497John McCall
1866f85e193739c953358c865005855253af4f68a497John McCall    CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1867f85e193739c953358c865005855253af4f68a497John McCall
1868ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1869f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCMRRAutoreleasePoolPop(Token);
1870f85e193739c953358c865005855253af4f68a497John McCall    }
1871f85e193739c953358c865005855253af4f68a497John McCall  };
1872f85e193739c953358c865005855253af4f68a497John McCall}
1873f85e193739c953358c865005855253af4f68a497John McCall
1874f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
1875f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount)
1876f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr);
1877f85e193739c953358c865005855253af4f68a497John McCall  else
1878f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr);
1879f85e193739c953358c865005855253af4f68a497John McCall}
1880f85e193739c953358c865005855253af4f68a497John McCall
1881f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1882f85e193739c953358c865005855253af4f68a497John McCall                                                  LValue lvalue,
1883f85e193739c953358c865005855253af4f68a497John McCall                                                  QualType type) {
1884f85e193739c953358c865005855253af4f68a497John McCall  switch (type.getObjCLifetime()) {
1885f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
1886f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
1887f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong:
1888f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
1889545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue).getScalarVal(),
1890f85e193739c953358c865005855253af4f68a497John McCall                         false);
1891f85e193739c953358c865005855253af4f68a497John McCall
1892f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:
1893f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitARCLoadWeakRetained(lvalue.getAddress()),
1894f85e193739c953358c865005855253af4f68a497John McCall                         true);
1895f85e193739c953358c865005855253af4f68a497John McCall  }
1896f85e193739c953358c865005855253af4f68a497John McCall
1897f85e193739c953358c865005855253af4f68a497John McCall  llvm_unreachable("impossible lifetime!");
1898f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult();
1899f85e193739c953358c865005855253af4f68a497John McCall}
1900f85e193739c953358c865005855253af4f68a497John McCall
1901f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1902f85e193739c953358c865005855253af4f68a497John McCall                                                  const Expr *e) {
1903f85e193739c953358c865005855253af4f68a497John McCall  e = e->IgnoreParens();
1904f85e193739c953358c865005855253af4f68a497John McCall  QualType type = e->getType();
1905f85e193739c953358c865005855253af4f68a497John McCall
1906f85e193739c953358c865005855253af4f68a497John McCall  // As a very special optimization, in ARC++, if the l-value is the
1907f85e193739c953358c865005855253af4f68a497John McCall  // result of a non-volatile assignment, do a simple retain of the
1908f85e193739c953358c865005855253af4f68a497John McCall  // result of the call to objc_storeWeak instead of reloading.
1909f85e193739c953358c865005855253af4f68a497John McCall  if (CGF.getLangOptions().CPlusPlus &&
1910f85e193739c953358c865005855253af4f68a497John McCall      !type.isVolatileQualified() &&
1911f85e193739c953358c865005855253af4f68a497John McCall      type.getObjCLifetime() == Qualifiers::OCL_Weak &&
1912f85e193739c953358c865005855253af4f68a497John McCall      isa<BinaryOperator>(e) &&
1913f85e193739c953358c865005855253af4f68a497John McCall      cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
1914f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitScalarExpr(e), false);
1915f85e193739c953358c865005855253af4f68a497John McCall
1916f85e193739c953358c865005855253af4f68a497John McCall  return tryEmitARCRetainLoadOfScalar(CGF, CGF.EmitLValue(e), type);
1917f85e193739c953358c865005855253af4f68a497John McCall}
1918f85e193739c953358c865005855253af4f68a497John McCall
1919f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1920f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value);
1921f85e193739c953358c865005855253af4f68a497John McCall
1922f85e193739c953358c865005855253af4f68a497John McCall/// Given that the given expression is some sort of call (which does
1923f85e193739c953358c865005855253af4f68a497John McCall/// not return retained), emit a retain following it.
1924f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainCall(CodeGenFunction &CGF, const Expr *e) {
1925f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = CGF.EmitScalarExpr(e);
1926f85e193739c953358c865005855253af4f68a497John McCall  return emitARCRetainAfterCall(CGF, value);
1927f85e193739c953358c865005855253af4f68a497John McCall}
1928f85e193739c953358c865005855253af4f68a497John McCall
1929f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1930f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value) {
1931f85e193739c953358c865005855253af4f68a497John McCall  if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
1932f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
1933f85e193739c953358c865005855253af4f68a497John McCall
1934f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain immediately following the call.
1935f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(call->getParent(),
1936f85e193739c953358c865005855253af4f68a497John McCall                               ++llvm::BasicBlock::iterator(call));
1937f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
1938f85e193739c953358c865005855253af4f68a497John McCall
1939f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
1940f85e193739c953358c865005855253af4f68a497John McCall    return value;
1941f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
1942f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
1943f85e193739c953358c865005855253af4f68a497John McCall
1944f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain at the beginning of the normal destination block.
1945f85e193739c953358c865005855253af4f68a497John McCall    llvm::BasicBlock *BB = invoke->getNormalDest();
1946f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(BB, BB->begin());
1947f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
1948f85e193739c953358c865005855253af4f68a497John McCall
1949f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
1950f85e193739c953358c865005855253af4f68a497John McCall    return value;
1951f85e193739c953358c865005855253af4f68a497John McCall
1952f85e193739c953358c865005855253af4f68a497John McCall  // Bitcasts can arise because of related-result returns.  Rewrite
1953f85e193739c953358c865005855253af4f68a497John McCall  // the operand.
1954f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
1955f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *operand = bitcast->getOperand(0);
1956f85e193739c953358c865005855253af4f68a497John McCall    operand = emitARCRetainAfterCall(CGF, operand);
1957f85e193739c953358c865005855253af4f68a497John McCall    bitcast->setOperand(0, operand);
1958f85e193739c953358c865005855253af4f68a497John McCall    return bitcast;
1959f85e193739c953358c865005855253af4f68a497John McCall
1960f85e193739c953358c865005855253af4f68a497John McCall  // Generic fall-back case.
1961f85e193739c953358c865005855253af4f68a497John McCall  } else {
1962f85e193739c953358c865005855253af4f68a497John McCall    // Retain using the non-block variant: we never need to do a copy
1963f85e193739c953358c865005855253af4f68a497John McCall    // of a block that's been returned to us.
1964f85e193739c953358c865005855253af4f68a497John McCall    return CGF.EmitARCRetainNonBlock(value);
1965f85e193739c953358c865005855253af4f68a497John McCall  }
1966f85e193739c953358c865005855253af4f68a497John McCall}
1967f85e193739c953358c865005855253af4f68a497John McCall
1968f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult
1969f85e193739c953358c865005855253af4f68a497John McCalltryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
1970f85e193739c953358c865005855253af4f68a497John McCall  // The desired result type, if it differs from the type of the
1971f85e193739c953358c865005855253af4f68a497John McCall  // ultimate opaque expression.
19722acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *resultType = 0;
1973f85e193739c953358c865005855253af4f68a497John McCall
1974d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // If we're loading retained from a __strong xvalue, we can avoid
1975d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // an extra retain/release pair by zeroing out the source of this
1976d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // "move" operation.
1977df7b091c58ccdb402a32bfbde9c506074dba5f3dJohn McCall  if (e->isXValue() && !e->getType().isConstQualified() &&
1978d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      e->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
1979d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Emit the lvalue
1980d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    LValue lv = CGF.EmitLValue(e);
1981d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1982d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Load the object pointer and cast it to the appropriate type.
1983d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    QualType exprType = e->getType();
1984545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal();
1985d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1986d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    if (resultType)
1987d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      result = CGF.Builder.CreateBitCast(result, resultType);
1988d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1989d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Set the source pointer to NULL.
1990d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    llvm::Value *null
1991d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      = llvm::ConstantPointerNull::get(
1992d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor                            cast<llvm::PointerType>(CGF.ConvertType(exprType)));
1993545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    CGF.EmitStoreOfScalar(null, lv);
1994d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1995d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    return TryEmitResult(result, true);
1996d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  }
1997d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1998f85e193739c953358c865005855253af4f68a497John McCall  while (true) {
1999f85e193739c953358c865005855253af4f68a497John McCall    e = e->IgnoreParens();
2000f85e193739c953358c865005855253af4f68a497John McCall
2001f85e193739c953358c865005855253af4f68a497John McCall    // There's a break at the end of this if-chain;  anything
2002f85e193739c953358c865005855253af4f68a497John McCall    // that wants to keep looping has to explicitly continue.
2003f85e193739c953358c865005855253af4f68a497John McCall    if (const CastExpr *ce = dyn_cast<CastExpr>(e)) {
2004f85e193739c953358c865005855253af4f68a497John McCall      switch (ce->getCastKind()) {
2005f85e193739c953358c865005855253af4f68a497John McCall      // No-op casts don't change the type, so we just ignore them.
2006f85e193739c953358c865005855253af4f68a497John McCall      case CK_NoOp:
2007f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
2008f85e193739c953358c865005855253af4f68a497John McCall        continue;
2009f85e193739c953358c865005855253af4f68a497John McCall
2010f85e193739c953358c865005855253af4f68a497John McCall      case CK_LValueToRValue: {
2011f85e193739c953358c865005855253af4f68a497John McCall        TryEmitResult loadResult
2012f85e193739c953358c865005855253af4f68a497John McCall          = tryEmitARCRetainLoadOfScalar(CGF, ce->getSubExpr());
2013f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) {
2014f85e193739c953358c865005855253af4f68a497John McCall          llvm::Value *value = loadResult.getPointer();
2015f85e193739c953358c865005855253af4f68a497John McCall          value = CGF.Builder.CreateBitCast(value, resultType);
2016f85e193739c953358c865005855253af4f68a497John McCall          loadResult.setPointer(value);
2017f85e193739c953358c865005855253af4f68a497John McCall        }
2018f85e193739c953358c865005855253af4f68a497John McCall        return loadResult;
2019f85e193739c953358c865005855253af4f68a497John McCall      }
2020f85e193739c953358c865005855253af4f68a497John McCall
2021f85e193739c953358c865005855253af4f68a497John McCall      // These casts can change the type, so remember that and
2022f85e193739c953358c865005855253af4f68a497John McCall      // soldier on.  We only need to remember the outermost such
2023f85e193739c953358c865005855253af4f68a497John McCall      // cast, though.
2024f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToObjCPointerCast:
2025f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToBlockPointerCast:
2026f85e193739c953358c865005855253af4f68a497John McCall      case CK_BitCast:
2027f85e193739c953358c865005855253af4f68a497John McCall        if (!resultType)
2028f85e193739c953358c865005855253af4f68a497John McCall          resultType = CGF.ConvertType(ce->getType());
2029f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
2030f85e193739c953358c865005855253af4f68a497John McCall        assert(e->getType()->hasPointerRepresentation());
2031f85e193739c953358c865005855253af4f68a497John McCall        continue;
2032f85e193739c953358c865005855253af4f68a497John McCall
2033f85e193739c953358c865005855253af4f68a497John McCall      // For consumptions, just emit the subexpression and thus elide
2034f85e193739c953358c865005855253af4f68a497John McCall      // the retain/release pair.
2035f85e193739c953358c865005855253af4f68a497John McCall      case CK_ObjCConsumeObject: {
2036f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = CGF.EmitScalarExpr(ce->getSubExpr());
2037f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2038f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2039f85e193739c953358c865005855253af4f68a497John McCall      }
2040f85e193739c953358c865005855253af4f68a497John McCall
20417e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // For reclaims, emit the subexpression as a retained call and
20427e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // skip the consumption.
20437e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      case CK_ObjCReclaimReturnedObject: {
20447e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce->getSubExpr());
20457e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
20467e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        return TryEmitResult(result, true);
20477e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      }
20487e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall
2049f85e193739c953358c865005855253af4f68a497John McCall      case CK_GetObjCProperty: {
2050f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce);
2051f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2052f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2053f85e193739c953358c865005855253af4f68a497John McCall      }
2054f85e193739c953358c865005855253af4f68a497John McCall
2055f85e193739c953358c865005855253af4f68a497John McCall      default:
2056f85e193739c953358c865005855253af4f68a497John McCall        break;
2057f85e193739c953358c865005855253af4f68a497John McCall      }
2058f85e193739c953358c865005855253af4f68a497John McCall
2059f85e193739c953358c865005855253af4f68a497John McCall    // Skip __extension__.
2060f85e193739c953358c865005855253af4f68a497John McCall    } else if (const UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
2061f85e193739c953358c865005855253af4f68a497John McCall      if (op->getOpcode() == UO_Extension) {
2062f85e193739c953358c865005855253af4f68a497John McCall        e = op->getSubExpr();
2063f85e193739c953358c865005855253af4f68a497John McCall        continue;
2064f85e193739c953358c865005855253af4f68a497John McCall      }
2065f85e193739c953358c865005855253af4f68a497John McCall
2066f85e193739c953358c865005855253af4f68a497John McCall    // For calls and message sends, use the retained-call logic.
2067f85e193739c953358c865005855253af4f68a497John McCall    // Delegate inits are a special case in that they're the only
2068f85e193739c953358c865005855253af4f68a497John McCall    // returns-retained expression that *isn't* surrounded by
2069f85e193739c953358c865005855253af4f68a497John McCall    // a consume.
2070f85e193739c953358c865005855253af4f68a497John McCall    } else if (isa<CallExpr>(e) ||
2071f85e193739c953358c865005855253af4f68a497John McCall               (isa<ObjCMessageExpr>(e) &&
2072f85e193739c953358c865005855253af4f68a497John McCall                !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
2073f85e193739c953358c865005855253af4f68a497John McCall      llvm::Value *result = emitARCRetainCall(CGF, e);
2074f85e193739c953358c865005855253af4f68a497John McCall      if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2075f85e193739c953358c865005855253af4f68a497John McCall      return TryEmitResult(result, true);
2076f85e193739c953358c865005855253af4f68a497John McCall    }
2077f85e193739c953358c865005855253af4f68a497John McCall
2078f85e193739c953358c865005855253af4f68a497John McCall    // Conservatively halt the search at any other expression kind.
2079f85e193739c953358c865005855253af4f68a497John McCall    break;
2080f85e193739c953358c865005855253af4f68a497John McCall  }
2081f85e193739c953358c865005855253af4f68a497John McCall
2082f85e193739c953358c865005855253af4f68a497John McCall  // We didn't find an obvious production, so emit what we've got and
2083f85e193739c953358c865005855253af4f68a497John McCall  // tell the caller that we didn't manage to retain.
2084f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = CGF.EmitScalarExpr(e);
2085f85e193739c953358c865005855253af4f68a497John McCall  if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2086f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult(result, false);
2087f85e193739c953358c865005855253af4f68a497John McCall}
2088f85e193739c953358c865005855253af4f68a497John McCall
2089f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2090f85e193739c953358c865005855253af4f68a497John McCall                                                LValue lvalue,
2091f85e193739c953358c865005855253af4f68a497John McCall                                                QualType type) {
2092f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainLoadOfScalar(CGF, lvalue, type);
2093f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2094f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2095f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetain(type, value);
2096f85e193739c953358c865005855253af4f68a497John McCall  return value;
2097f85e193739c953358c865005855253af4f68a497John McCall}
2098f85e193739c953358c865005855253af4f68a497John McCall
2099f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainScalarExpr - Semantically equivalent to
2100f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a
2101f85e193739c953358c865005855253af4f68a497John McCall/// best-effort attempt to peephole expressions that naturally produce
2102f85e193739c953358c865005855253af4f68a497John McCall/// retained objects.
2103f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
2104f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2105f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2106f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2107f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetain(e->getType(), value);
2108f85e193739c953358c865005855253af4f68a497John McCall  return value;
2109f85e193739c953358c865005855253af4f68a497John McCall}
2110f85e193739c953358c865005855253af4f68a497John McCall
2111f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
2112f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {
2113f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2114f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2115f85e193739c953358c865005855253af4f68a497John McCall  if (result.getInt())
2116f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCAutorelease(value);
2117f85e193739c953358c865005855253af4f68a497John McCall  else
2118f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetainAutorelease(e->getType(), value);
2119f85e193739c953358c865005855253af4f68a497John McCall  return value;
2120f85e193739c953358c865005855253af4f68a497John McCall}
2121f85e193739c953358c865005855253af4f68a497John McCall
2122f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2123f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
2124f85e193739c953358c865005855253af4f68a497John McCall                                    bool ignored) {
2125f85e193739c953358c865005855253af4f68a497John McCall  // Evaluate the RHS first.
2126f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS());
2127f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2128f85e193739c953358c865005855253af4f68a497John McCall
2129f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2130f85e193739c953358c865005855253af4f68a497John McCall
2131f85e193739c953358c865005855253af4f68a497John McCall  // If the RHS was emitted retained, expand this.
2132f85e193739c953358c865005855253af4f68a497John McCall  if (result.getInt()) {
2133f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *oldValue =
2134f85e193739c953358c865005855253af4f68a497John McCall      EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatileQualified(),
2135f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getAlignment(), e->getType(),
2136f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getTBAAInfo());
2137f85e193739c953358c865005855253af4f68a497John McCall    EmitStoreOfScalar(value, lvalue.getAddress(),
2138f85e193739c953358c865005855253af4f68a497John McCall                      lvalue.isVolatileQualified(), lvalue.getAlignment(),
2139f85e193739c953358c865005855253af4f68a497John McCall                      e->getType(), lvalue.getTBAAInfo());
2140f85e193739c953358c865005855253af4f68a497John McCall    EmitARCRelease(oldValue, /*precise*/ false);
2141f85e193739c953358c865005855253af4f68a497John McCall  } else {
2142545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    value = EmitARCStoreStrong(lvalue, value, ignored);
2143f85e193739c953358c865005855253af4f68a497John McCall  }
2144f85e193739c953358c865005855253af4f68a497John McCall
2145f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2146f85e193739c953358c865005855253af4f68a497John McCall}
2147f85e193739c953358c865005855253af4f68a497John McCall
2148f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2149f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) {
2150f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = EmitARCRetainAutoreleaseScalarExpr(e->getRHS());
2151f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2152f85e193739c953358c865005855253af4f68a497John McCall
2153f85e193739c953358c865005855253af4f68a497John McCall  EmitStoreOfScalar(value, lvalue.getAddress(),
2154f85e193739c953358c865005855253af4f68a497John McCall                    lvalue.isVolatileQualified(), lvalue.getAlignment(),
2155f85e193739c953358c865005855253af4f68a497John McCall                    e->getType(), lvalue.getTBAAInfo());
2156f85e193739c953358c865005855253af4f68a497John McCall
2157f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2158f85e193739c953358c865005855253af4f68a497John McCall}
2159f85e193739c953358c865005855253af4f68a497John McCall
2160f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolStmt(
2161f85e193739c953358c865005855253af4f68a497John McCall                                             const ObjCAutoreleasePoolStmt &ARPS) {
2162f85e193739c953358c865005855253af4f68a497John McCall  const Stmt *subStmt = ARPS.getSubStmt();
2163f85e193739c953358c865005855253af4f68a497John McCall  const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
2164f85e193739c953358c865005855253af4f68a497John McCall
2165f85e193739c953358c865005855253af4f68a497John McCall  CGDebugInfo *DI = getDebugInfo();
2166f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2167f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getLBracLoc());
2168f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionStart(Builder);
2169f85e193739c953358c865005855253af4f68a497John McCall  }
2170f85e193739c953358c865005855253af4f68a497John McCall
2171f85e193739c953358c865005855253af4f68a497John McCall  // Keep track of the current cleanup stack depth.
2172f85e193739c953358c865005855253af4f68a497John McCall  RunCleanupsScope Scope(*this);
21739f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (CGM.getCodeGenOpts().ObjCRuntimeHasARC) {
2174f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCAutoreleasePoolPush();
2175f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token);
2176f85e193739c953358c865005855253af4f68a497John McCall  } else {
2177f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCMRRAutoreleasePoolPush();
2178f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token);
2179f85e193739c953358c865005855253af4f68a497John McCall  }
2180f85e193739c953358c865005855253af4f68a497John McCall
2181f85e193739c953358c865005855253af4f68a497John McCall  for (CompoundStmt::const_body_iterator I = S.body_begin(),
2182f85e193739c953358c865005855253af4f68a497John McCall       E = S.body_end(); I != E; ++I)
2183f85e193739c953358c865005855253af4f68a497John McCall    EmitStmt(*I);
2184f85e193739c953358c865005855253af4f68a497John McCall
2185f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2186f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getRBracLoc());
2187f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionEnd(Builder);
2188f85e193739c953358c865005855253af4f68a497John McCall  }
2189f85e193739c953358c865005855253af4f68a497John McCall}
21900c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
21910c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
21920c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// make sure it survives garbage collection until this point.
21930c24c808e4dce43e88abf2d5f98546b901bd4315John McCallvoid CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
21940c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  // We just use an inline assembly.
21959cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *paramTypes[] = { VoidPtrTy };
21960c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::FunctionType *extenderType
21970c24c808e4dce43e88abf2d5f98546b901bd4315John McCall    = llvm::FunctionType::get(VoidTy, paramTypes, /*variadic*/ false);
21980c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::Value *extender
21990c24c808e4dce43e88abf2d5f98546b901bd4315John McCall    = llvm::InlineAsm::get(extenderType,
22000c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* assembly */ "",
22010c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* constraints */ "r",
22020c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* side effects */ true);
22030c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
22040c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  object = Builder.CreateBitCast(object, VoidPtrTy);
22050c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  Builder.CreateCall(extender, object)->setDoesNotThrow();
22060c24c808e4dce43e88abf2d5f98546b901bd4315John McCall}
22070c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
22082979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
2209