CGObjC.cpp revision 6c11f0b3106263600af2ea0438ebb372821514aa
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
338af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method.  An Objective-C method is a C function with
3391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// its pointer, name, and types registered in the class struture.
340af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
3418d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, OMD->getClassInterface(), OMD->getLocStart());
3426fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis  EmitStmt(OMD->getBody());
3436fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis  FinishFunction(OMD->getBodyRBrace());
344af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
345af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
34641bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall/// emitStructGetterCall - Call the runtime function to load a property
34741bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall/// into the return value slot.
34841bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCallstatic void emitStructGetterCall(CodeGenFunction &CGF, ObjCIvarDecl *ivar,
34941bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall                                 bool isAtomic, bool hasStrong) {
35041bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  ASTContext &Context = CGF.getContext();
35141bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
35241bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  llvm::Value *src =
35341bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall    CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), CGF.LoadObjCSelf(),
35441bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall                          ivar, 0).getAddress();
35541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
35641bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  // objc_copyStruct (ReturnValue, &structIvar,
35741bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  //                  sizeof (Type of Ivar), isAtomic, false);
35841bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  CallArgList args;
35941bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
36041bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  llvm::Value *dest = CGF.Builder.CreateBitCast(CGF.ReturnValue, CGF.VoidPtrTy);
36141bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(dest), Context.VoidPtrTy);
36241bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
36341bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  src = CGF.Builder.CreateBitCast(src, CGF.VoidPtrTy);
36441bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(src), Context.VoidPtrTy);
36541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
36641bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  CharUnits size = CGF.getContext().getTypeSizeInChars(ivar->getType());
36741bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(CGF.CGM.getSize(size)), Context.getSizeType());
36841bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(CGF.Builder.getInt1(isAtomic)), Context.BoolTy);
36941bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(CGF.Builder.getInt1(hasStrong)), Context.BoolTy);
37041bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
37141bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  llvm::Value *fn = CGF.CGM.getObjCRuntime().GetGetStructFunction();
37241bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  CGF.EmitCall(CGF.getTypes().getFunctionInfo(Context.VoidTy, args,
37341bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall                                              FunctionType::ExtInfo()),
37441bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall               fn, ReturnValueSlot(), args);
37541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall}
37641bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
3771e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall/// Determine whether the given architecture supports unaligned atomic
3781e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall/// accesses.  They don't have to be fast, just faster than a function
3791e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall/// call and a mutex.
3801e1f4871535f2cadcbf8c9af8cc48a2213192320John McCallstatic bool hasUnalignedAtomics(llvm::Triple::ArchType arch) {
3811e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  return (arch == llvm::Triple::x86 || arch == llvm::Triple::x86_64);
3821e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall}
3831e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
3841e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall/// Return the maximum size that permits atomic accesses for the given
3851e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall/// architecture.
3861e1f4871535f2cadcbf8c9af8cc48a2213192320John McCallstatic CharUnits getMaxAtomicAccessSize(CodeGenModule &CGM,
3871e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                                        llvm::Triple::ArchType arch) {
3881e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // ARM has 8-byte atomic accesses, but it's not clear whether we
3891e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // want to rely on them here.
3901e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
3911e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // In the default case, just assume that any size up to a pointer is
3921e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // fine given adequate alignment.
3931e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  return CharUnits::fromQuantity(CGM.PointerSizeInBytes);
3941e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall}
3951e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
3961e1f4871535f2cadcbf8c9af8cc48a2213192320John McCallnamespace {
3971e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  class PropertyImplStrategy {
3981e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  public:
3991e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    enum StrategyKind {
4001e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// The 'native' strategy is to use the architecture's provided
4011e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// reads and writes.
4021e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      Native,
4031e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4041e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// Use objc_setProperty and objc_getProperty.
4051e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      GetSetProperty,
4061e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4071e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// Use objc_setProperty for the setter, but use expression
4081e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// evaluation for the getter.
4091e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      SetPropertyAndExpressionGet,
4101e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4111e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// Use objc_copyStruct.
4121e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      CopyStruct,
4131e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4141e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// The 'expression' strategy is to emit normal assignment or
4151e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      /// lvalue-to-rvalue expressions.
4161e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      Expression
4171e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    };
4181e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4191e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    StrategyKind getKind() const { return StrategyKind(Kind); }
4201e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4211e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    bool hasStrongMember() const { return HasStrong; }
4221e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    bool isAtomic() const { return IsAtomic; }
4231e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    bool isCopy() const { return IsCopy; }
4241e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4251e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    CharUnits getIvarSize() const { return IvarSize; }
4261e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    CharUnits getIvarAlignment() const { return IvarAlignment; }
4271e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4281e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    PropertyImplStrategy(CodeGenModule &CGM,
4291e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                         const ObjCPropertyImplDecl *propImpl);
4301e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4311e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  private:
4321e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    unsigned Kind : 8;
4331e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    unsigned IsAtomic : 1;
4341e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    unsigned IsCopy : 1;
4351e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    unsigned HasStrong : 1;
4361e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4371e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    CharUnits IvarSize;
4381e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    CharUnits IvarAlignment;
4391e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  };
4401e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall}
4411e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4421e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall/// Pick an implementation strategy for the the given property synthesis.
4431e1f4871535f2cadcbf8c9af8cc48a2213192320John McCallPropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
4441e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                                     const ObjCPropertyImplDecl *propImpl) {
4451e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
4461e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  ObjCPropertyDecl::PropertyAttributeKind attrs = prop->getPropertyAttributes();
4471e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4481e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  IsCopy = (attrs & ObjCPropertyDecl::OBJC_PR_copy);
4491e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  IsAtomic = !(attrs & ObjCPropertyDecl::OBJC_PR_nonatomic);
4501e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  HasStrong = false; // doesn't matter here.
4511e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4521e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Evaluate the ivar's size and alignment.
4531e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
4541e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  QualType ivarType = ivar->getType();
4551e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  llvm::tie(IvarSize, IvarAlignment)
4561e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    = CGM.getContext().getTypeInfoInChars(ivarType);
4571e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4581e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // If we have a copy property, we always have to use getProperty/setProperty.
4591e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (IsCopy) {
4601e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    Kind = GetSetProperty;
4611e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
4621e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
4631e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4641e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Handle retain/strong.
4651e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (attrs & (ObjCPropertyDecl::OBJC_PR_retain
4661e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall               | ObjCPropertyDecl::OBJC_PR_strong)) {
4671e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // In GC-only, there's nothing special that needs to be done.
4681e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    if (CGM.getLangOptions().getGCMode() == LangOptions::GCOnly) {
4691e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      // fallthrough
4701e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4711e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // In ARC, if the property is non-atomic, use expression emission,
4721e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // which translates to objc_storeStrong.  This isn't required, but
4731e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // it's slightly nicer.
4741e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    } else if (CGM.getLangOptions().ObjCAutoRefCount && !IsAtomic) {
4751e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      Kind = Expression;
4761e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      return;
4771e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4781e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Otherwise, we need to at least use setProperty.  However, if
4791e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // the property isn't atomic, we can use normal expression
4801e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // emission for the getter.
4811e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    } else if (!IsAtomic) {
4821e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      Kind = SetPropertyAndExpressionGet;
4831e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      return;
4841e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4851e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Otherwise, we have to use both setProperty and getProperty.
4861e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    } else {
4871e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      Kind = GetSetProperty;
4881e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      return;
4891e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    }
4901e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
4911e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4921e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // If we're not atomic, just use expression accesses.
4931e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (!IsAtomic) {
4941e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    Kind = Expression;
4951e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
4961e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
4971e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
4985889c60d19101156a3a54b8c49bcc60a12cc1fdbJohn McCall  // Properties on bitfield ivars need to be emitted using expression
4995889c60d19101156a3a54b8c49bcc60a12cc1fdbJohn McCall  // accesses even if they're nominally atomic.
5005889c60d19101156a3a54b8c49bcc60a12cc1fdbJohn McCall  if (ivar->isBitField()) {
5015889c60d19101156a3a54b8c49bcc60a12cc1fdbJohn McCall    Kind = Expression;
5025889c60d19101156a3a54b8c49bcc60a12cc1fdbJohn McCall    return;
5035889c60d19101156a3a54b8c49bcc60a12cc1fdbJohn McCall  }
5045889c60d19101156a3a54b8c49bcc60a12cc1fdbJohn McCall
5051e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // GC-qualified or ARC-qualified ivars need to be emitted as
5061e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // expressions.  This actually works out to being atomic anyway,
5071e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // except for ARC __strong, but that should trigger the above code.
5081e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (ivarType.hasNonTrivialObjCLifetime() ||
5091e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      (CGM.getLangOptions().getGCMode() &&
5101e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall       CGM.getContext().getObjCGCAttrKind(ivarType))) {
5111e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    Kind = Expression;
5121e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
5131e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
5141e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5151e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Compute whether the ivar has strong members.
5161e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (CGM.getLangOptions().getGCMode())
5171e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    if (const RecordType *recordType = ivarType->getAs<RecordType>())
5181e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      HasStrong = recordType->getDecl()->hasObjectMember();
5191e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5201e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // We can never access structs with object members with a native
5211e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // access, because we need to use write barriers.  This is what
5221e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // objc_copyStruct is for.
5231e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (HasStrong) {
5241e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    Kind = CopyStruct;
5251e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
5261e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
5271e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5281e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Otherwise, this is target-dependent and based on the size and
5291e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // alignment of the ivar.
5301e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  llvm::Triple::ArchType arch =
5311e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    CGM.getContext().getTargetInfo().getTriple().getArch();
5321e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5331e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Most architectures require memory to fit within a single cache
5341e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // line, so the alignment has to be at least the size of the access.
5351e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Otherwise we have to grab a lock.
5361e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (IvarAlignment < IvarSize && !hasUnalignedAtomics(arch)) {
5371e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    Kind = CopyStruct;
5381e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
5391e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
5401e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5411e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // If the ivar's size exceeds the architecture's maximum atomic
5421e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // access size, we have to use CopyStruct.
5431e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (IvarSize > getMaxAtomicAccessSize(CGM, arch)) {
5441e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    Kind = CopyStruct;
5451e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
5461e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
5471e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5481e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Otherwise, we can use native loads and stores.
5491e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  Kind = Native;
5501e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall}
551af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
552af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter
553489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
554489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// is illegal within a category.
555fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanianvoid CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
556fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian                                         const ObjCPropertyImplDecl *PID) {
557af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
558af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
559af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate getter (empty method)");
5608d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
5611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5621e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  generateObjCGetterBody(IMP, PID);
5631e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5641e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  FinishFunction();
5651e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall}
5661e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5676c11f0b3106263600af2ea0438ebb372821514aaJohn McCallstatic bool hasTrivialGetExpr(const ObjCPropertyImplDecl *propImpl) {
5686c11f0b3106263600af2ea0438ebb372821514aaJohn McCall  const Expr *getter = propImpl->getGetterCXXConstructor();
5691e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (!getter) return true;
5701e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5711e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Sema only makes only of these when the ivar has a C++ class type,
5721e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // so the form is pretty constrained.
5731e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5746c11f0b3106263600af2ea0438ebb372821514aaJohn McCall  // If the property has a reference type, we might just be binding a
5756c11f0b3106263600af2ea0438ebb372821514aaJohn McCall  // reference, in which case the result will be a gl-value.  We should
5766c11f0b3106263600af2ea0438ebb372821514aaJohn McCall  // treat this as a non-trivial operation.
5776c11f0b3106263600af2ea0438ebb372821514aaJohn McCall  if (getter->isGLValue())
5786c11f0b3106263600af2ea0438ebb372821514aaJohn McCall    return false;
5796c11f0b3106263600af2ea0438ebb372821514aaJohn McCall
5801e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // If we selected a trivial copy-constructor, we're okay.
5811e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (const CXXConstructExpr *construct = dyn_cast<CXXConstructExpr>(getter))
5821e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return (construct->getConstructor()->isTrivial());
5831e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5841e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // The constructor might require cleanups (in which case it's never
5851e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // trivial).
5861e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  assert(isa<ExprWithCleanups>(getter));
5871e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  return false;
5881e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall}
5891e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
5901e1f4871535f2cadcbf8c9af8cc48a2213192320John McCallvoid
5911e1f4871535f2cadcbf8c9af8cc48a2213192320John McCallCodeGenFunction::generateObjCGetterBody(const ObjCImplementationDecl *classImpl,
5921e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                                        const ObjCPropertyImplDecl *propImpl) {
5931e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // If there's a non-trivial 'get' expression, we just have to emit that.
5941e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (!hasTrivialGetExpr(propImpl)) {
5951e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    ReturnStmt ret(SourceLocation(), propImpl->getGetterCXXConstructor(),
5961e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                   /*nrvo*/ 0);
5971e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    EmitReturnStmt(ret);
5981e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
5991e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
6001e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6011e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
6021e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  QualType propType = prop->getType();
6031e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  ObjCMethodDecl *getterMethod = prop->getGetterMethodDecl();
6041e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6051e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
6061e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6071e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Pick an implementation strategy.
6081e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  PropertyImplStrategy strategy(CGM, propImpl);
6091e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  switch (strategy.getKind()) {
6101e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::Native: {
6111e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0);
6121e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6131e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Currently, all atomic accesses have to be through integer
6141e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // types, so there's no point in trying to pick a prettier type.
6151e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Type *bitcastType =
6161e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      llvm::Type::getIntNTy(getLLVMContext(),
6171e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                            getContext().toBits(strategy.getIvarSize()));
6181e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    bitcastType = bitcastType->getPointerTo(); // addrspace 0 okay
6191e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6201e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Perform an atomic load.  This does not impose ordering constraints.
6211e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *ivarAddr = LV.getAddress();
6221e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    ivarAddr = Builder.CreateBitCast(ivarAddr, bitcastType);
6231e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::LoadInst *load = Builder.CreateLoad(ivarAddr, "load");
6241e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    load->setAlignment(strategy.getIvarAlignment().getQuantity());
6251e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    load->setAtomic(llvm::Unordered);
6261e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6271e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Store that value into the return address.  Doing this with a
6281e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // bitcast is likely to produce some pretty ugly IR, but it's not
6291e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // the *most* terrible thing in the world.
6301e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    Builder.CreateStore(load, Builder.CreateBitCast(ReturnValue, bitcastType));
6311e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6321e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Make sure we don't do an autorelease.
6331e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    AutoreleaseResult = false;
6341e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
6351e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
6361e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6371e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::GetSetProperty: {
6381e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *getPropertyFn =
6391e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      CGM.getObjCRuntime().GetPropertyGetFunction();
6401e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    if (!getPropertyFn) {
6411e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      CGM.ErrorUnsupported(propImpl, "Obj-C getter requiring atomic copy");
642c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      return;
643c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    }
644c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
645c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
646c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // FIXME: Can't this be simpler? This might even be worse than the
647c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // corresponding gcc code.
6481e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *cmd =
6491e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      Builder.CreateLoad(LocalDeclMap[getterMethod->getCmdDecl()], "cmd");
6501e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *self = Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
6511e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *ivarOffset =
6521e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      EmitIvarOffset(classImpl->getClassInterface(), ivar);
6531e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6541e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    CallArgList args;
6551e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    args.add(RValue::get(self), getContext().getObjCIdType());
6561e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    args.add(RValue::get(cmd), getContext().getObjCSelType());
6571e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
6581e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6591e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    assert(strategy.isAtomic());
6601e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    args.add(RValue::get(Builder.getTrue()), getContext().BoolTy);
6611e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
662e4be5a66072f7c7618071284c8d2a9c6d8e691cfDaniel Dunbar    // FIXME: We shouldn't need to get the function info here, the
663e4be5a66072f7c7618071284c8d2a9c6d8e691cfDaniel Dunbar    // runtime already should have computed it to build the function.
6641e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    RValue RV = EmitCall(getTypes().getFunctionInfo(propType, args,
66541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall                                                    FunctionType::ExtInfo()),
6661e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                         getPropertyFn, ReturnValueSlot(), args);
6671e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
668c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // We need to fix the type here. Ivars with copy & retain are
669c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // always objects so we don't need to worry about complex or
670c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // aggregates.
6711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
6721e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                                           getTypes().ConvertType(propType)));
6731e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6741e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    EmitReturnOfRValue(RV, propType);
675f85e193739c953358c865005855253af4f68a497John McCall
676f85e193739c953358c865005855253af4f68a497John McCall    // objc_getProperty does an autorelease, so we should suppress ours.
677f85e193739c953358c865005855253af4f68a497John McCall    AutoreleaseResult = false;
6781e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6791e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
6801e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
6811e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6821e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::CopyStruct:
6831e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    emitStructGetterCall(*this, ivar, strategy.isAtomic(),
6841e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                         strategy.hasStrongMember());
6851e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
6861e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6871e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::Expression:
6881e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::SetPropertyAndExpressionGet: {
6891e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, 0);
6901e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
6911e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    QualType ivarType = ivar->getType();
6921e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    if (ivarType->isAnyComplexType()) {
6931e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      ComplexPairTy pair = LoadComplexFromAddr(LV.getAddress(),
6941b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian                                               LV.isVolatileQualified());
6951e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      StoreComplexToAddr(pair, ReturnValue, LV.isVolatileQualified());
6961e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    } else if (hasAggregateLLVMType(ivarType)) {
6971e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      // The return value slot is guaranteed to not be aliased, but
6981e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      // that's not necessarily the same as "on the stack", so
6991e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      // we still potentially need objc_memmove_collectable.
7001e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType);
701ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall    } else {
702ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      llvm::Value *value;
703ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      if (propType->isReferenceType()) {
704ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        value = LV.getAddress();
705ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      } else {
706ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        // We want to load and autoreleaseReturnValue ARC __weak ivars.
707ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        if (LV.getQuals().getObjCLifetime() == Qualifiers::OCL_Weak) {
7081e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall          value = emitARCRetainLoadOfScalar(*this, LV, ivarType);
709ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall
710ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        // Otherwise we want to do a simple load, suppressing the
711ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        // final autorelease.
712f85e193739c953358c865005855253af4f68a497John McCall        } else {
713ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall          value = EmitLoadOfLValue(LV).getScalarVal();
714ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall          AutoreleaseResult = false;
71514086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian        }
716f85e193739c953358c865005855253af4f68a497John McCall
717ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall        value = Builder.CreateBitCast(value, ConvertType(propType));
718ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      }
719ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall
720ba3dd902d1cde09776a50c1adf2cd40bf0a15a7fJohn McCall      EmitReturnOfRValue(RValue::get(value), propType);
721ed1d29d62595a83ccf6ef23eb2759d355206df2eFariborz Jahanian    }
7221e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
723c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
724af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
7251e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
7261e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  llvm_unreachable("bad @property implementation strategy!");
727af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
728af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
72941bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall/// emitStructSetterCall - Call the runtime function to store the value
73041bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall/// from the first formal parameter into the given ivar.
73141bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCallstatic void emitStructSetterCall(CodeGenFunction &CGF, ObjCMethodDecl *OMD,
73241bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall                                 ObjCIvarDecl *ivar) {
7332846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // objc_copyStruct (&structIvar, &Arg,
7342846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  //                  sizeof (struct something), true, false);
735bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall  CallArgList args;
736bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall
737bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall  // The first argument is the address of the ivar.
73841bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  llvm::Value *ivarAddr = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(),
73941bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall                                                CGF.LoadObjCSelf(), ivar, 0)
74041bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall    .getAddress();
74141bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  ivarAddr = CGF.Builder.CreateBitCast(ivarAddr, CGF.Int8PtrTy);
74241bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(ivarAddr), CGF.getContext().VoidPtrTy);
743bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall
744bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall  // The second argument is the address of the parameter variable.
74541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  ParmVarDecl *argVar = *OMD->param_begin();
74641bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  DeclRefExpr argRef(argVar, argVar->getType(), VK_LValue, SourceLocation());
74741bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
74841bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
74941bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(argAddr), CGF.getContext().VoidPtrTy);
750bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall
751bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall  // The third argument is the sizeof the type.
752bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall  llvm::Value *size =
75341bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall    CGF.CGM.getSize(CGF.getContext().getTypeSizeInChars(ivar->getType()));
75441bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(size), CGF.getContext().getSizeType());
75541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall
75641bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  // The fourth argument is the 'isAtomic' flag.
75741bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(CGF.Builder.getTrue()), CGF.getContext().BoolTy);
758bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall
75941bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  // The fifth argument is the 'hasStrong' flag.
76041bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  // FIXME: should this really always be false?
76141bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  args.add(RValue::get(CGF.Builder.getFalse()), CGF.getContext().BoolTy);
762bbb253c307bc98fea5af9c9e59003e1c0da4cdc2John McCall
76341bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  llvm::Value *copyStructFn = CGF.CGM.getObjCRuntime().GetSetStructFunction();
76441bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall  CGF.EmitCall(CGF.getTypes().getFunctionInfo(CGF.getContext().VoidTy, args,
76541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall                                              FunctionType::ExtInfo()),
76641bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall               copyStructFn, ReturnValueSlot(), args);
7672846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian}
7682846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian
7691e1f4871535f2cadcbf8c9af8cc48a2213192320John McCallstatic bool hasTrivialSetExpr(const ObjCPropertyImplDecl *PID) {
7701e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  Expr *setter = PID->getSetterCXXAssignment();
7711e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (!setter) return true;
7721e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
7731e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // Sema only makes only of these when the ivar has a C++ class type,
7741e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // so the form is pretty constrained.
77571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
77671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // An operator call is trivial if the function it calls is trivial.
7771e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // This also implies that there's nothing non-trivial going on with
7781e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // the arguments, because operator= can only be trivial if it's a
7791e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // synthesized assignment operator and therefore both parameters are
7801e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  // references.
7811e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (CallExpr *call = dyn_cast<CallExpr>(setter)) {
78271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (const FunctionDecl *callee
78371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall          = dyn_cast_or_null<FunctionDecl>(call->getCalleeDecl()))
78471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      if (callee->isTrivial())
78571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall        return true;
78671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return false;
78701cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  }
78871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
7891e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  assert(isa<ExprWithCleanups>(setter));
79071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  return false;
79171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall}
79286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar
79371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallvoid
79471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallCodeGenFunction::generateObjCSetterBody(const ObjCImplementationDecl *classImpl,
79571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                        const ObjCPropertyImplDecl *propImpl) {
79671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Just use the setter expression if Sema gave us one and it's
79771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // non-trivial.  There's no way to do this atomically.
7981e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  if (!hasTrivialSetExpr(propImpl)) {
79971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    EmitStmt(propImpl->getSetterCXXAssignment());
80071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return;
80171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  }
80271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
80371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  const ObjCPropertyDecl *prop = propImpl->getPropertyDecl();
80471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
80571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCMethodDecl *setterMethod = prop->getSetterMethodDecl();
80671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
8071e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  PropertyImplStrategy strategy(CGM, propImpl);
8081e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  switch (strategy.getKind()) {
8091e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::Native: {
8101e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *argAddr = LocalDeclMap[*setterMethod->param_begin()];
81171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
8121e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    LValue ivarLValue =
8131e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), ivar, /*quals*/ 0);
8141e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *ivarAddr = ivarLValue.getAddress();
8151e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
8161e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Currently, all atomic accesses have to be through integer
8171e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // types, so there's no point in trying to pick a prettier type.
8181e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Type *bitcastType =
8191e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall      llvm::Type::getIntNTy(getLLVMContext(),
8201e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall                            getContext().toBits(strategy.getIvarSize()));
8211e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    bitcastType = bitcastType->getPointerTo(); // addrspace 0 okay
8221e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
8231e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Cast both arguments to the chosen operation type.
8241e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    argAddr = Builder.CreateBitCast(argAddr, bitcastType);
8251e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    ivarAddr = Builder.CreateBitCast(ivarAddr, bitcastType);
82671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
8271e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // This bitcast load is likely to cause some nasty IR.
8281e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::Value *load = Builder.CreateLoad(argAddr);
8291e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
8301e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    // Perform an atomic store.  There are no memory ordering requirements.
8311e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    llvm::StoreInst *store = Builder.CreateStore(load, ivarAddr);
8321e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    store->setAlignment(strategy.getIvarAlignment().getQuantity());
8331e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    store->setAtomic(llvm::Unordered);
8341e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    return;
8351e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  }
8361e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
8371e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::GetSetProperty:
8381e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::SetPropertyAndExpressionGet: {
83971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *setPropertyFn =
84071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      CGM.getObjCRuntime().GetPropertySetFunction();
84171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (!setPropertyFn) {
84271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      CGM.ErrorUnsupported(propImpl, "Obj-C setter requiring atomic copy");
84386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      return;
84486957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    }
8451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
8461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Emit objc_setProperty((id) self, _cmd, offset, arg,
84786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    //                       <is-atomic>, <is-copy>).
84871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *cmd =
84971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      Builder.CreateLoad(LocalDeclMap[setterMethod->getCmdDecl()]);
85071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *self =
85171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      Builder.CreateBitCast(LoadObjCSelf(), VoidPtrTy);
85271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *ivarOffset =
85371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      EmitIvarOffset(classImpl->getClassInterface(), ivar);
85471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    llvm::Value *arg = LocalDeclMap[*setterMethod->param_begin()];
85571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    arg = Builder.CreateBitCast(Builder.CreateLoad(arg, "arg"), VoidPtrTy);
85671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
85771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    CallArgList args;
85871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(self), getContext().getObjCIdType());
85971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(cmd), getContext().getObjCSelType());
86071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(ivarOffset), getContext().getPointerDiffType());
86171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    args.add(RValue::get(arg), getContext().getObjCIdType());
8621e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    args.add(RValue::get(Builder.getInt1(strategy.isAtomic())),
8631e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall             getContext().BoolTy);
8641e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    args.add(RValue::get(Builder.getInt1(strategy.isCopy())),
8651e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall             getContext().BoolTy);
866f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // FIXME: We shouldn't need to get the function info here, the runtime
867f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // already should have computed it to build the function.
86871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    EmitCall(getTypes().getFunctionInfo(getContext().VoidTy, args,
86971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                        FunctionType::ExtInfo()),
87071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall             setPropertyFn, ReturnValueSlot(), args);
87171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return;
87271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  }
87371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
8741e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::CopyStruct:
87541bdde9e961c4d96a94148f20f0b18397f4358ddJohn McCall    emitStructSetterCall(*this, setterMethod, ivar);
87671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    return;
8771e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall
8781e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall  case PropertyImplStrategy::Expression:
8791e1f4871535f2cadcbf8c9af8cc48a2213192320John McCall    break;
88071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  }
88171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
88271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Otherwise, fake up some ASTs and emit a normal assignment.
88371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ValueDecl *selfDecl = setterMethod->getSelfDecl();
88471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  DeclRefExpr self(selfDecl, selfDecl->getType(), VK_LValue, SourceLocation());
88571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
88671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                            selfDecl->getType(), CK_LValueToRValue, &self,
88771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                            VK_RValue);
88871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCIvarRefExpr ivarRef(ivar, ivar->getType().getNonReferenceType(),
88971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                          SourceLocation(), &selfLoad, true, true);
89071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
89171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ParmVarDecl *argDecl = *setterMethod->param_begin();
89271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  QualType argType = argDecl->getType().getNonReferenceType();
89371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  DeclRefExpr arg(argDecl, argType, VK_LValue, SourceLocation());
89471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
89571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           argType.getUnqualifiedType(), CK_LValueToRValue,
89671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           &arg, VK_RValue);
89745e8423d7dcea657c14c55347e8a30ac904d7501Daniel Dunbar
89871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // The property type can differ from the ivar type in some situations with
89971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // Objective-C pointer types, we can always bit cast the RHS in these cases.
90071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  // The following absurdity is just to ensure well-formed IR.
90171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  CastKind argCK = CK_NoOp;
90271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (ivarRef.getType()->isObjCObjectPointerType()) {
90371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    if (argLoad.getType()->isObjCObjectPointerType())
90471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_BitCast;
90571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    else if (argLoad.getType()->isBlockPointerType())
90671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_BlockPointerToObjCPointerCast;
90771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    else
90871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_CPointerToObjCPointerCast;
90971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  } else if (ivarRef.getType()->isBlockPointerType()) {
91071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall     if (argLoad.getType()->isBlockPointerType())
91171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_BitCast;
91271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    else
91371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall      argCK = CK_AnyPointerToBlockPointerCast;
91471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  } else if (ivarRef.getType()->isPointerType()) {
91571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    argCK = CK_BitCast;
91686957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  }
91771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ImplicitCastExpr argCast(ImplicitCastExpr::OnStack,
91871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           ivarRef.getType(), argCK, &argLoad,
91971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                           VK_RValue);
92071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  Expr *finalArg = &argLoad;
92171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  if (!getContext().hasSameUnqualifiedType(ivarRef.getType(),
92271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                           argLoad.getType()))
92371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall    finalArg = &argCast;
92471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
92571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
92671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  BinaryOperator assign(&ivarRef, finalArg, BO_Assign,
92771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                        ivarRef.getType(), VK_RValue, OK_Ordinary,
92871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                        SourceLocation());
92971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  EmitStmt(&assign);
93071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall}
93171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
93271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall/// GenerateObjCSetter - Generate an Objective-C property setter
93371c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
93471c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall/// is illegal within a category.
93571c758d3f4ecc8b511e6ae4a7210486aa994c182John McCallvoid CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
93671c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall                                         const ObjCPropertyImplDecl *PID) {
93771c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
93871c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
93971c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  assert(OMD && "Invalid call to generate setter (empty method)");
94071c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
94171c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall
94271c758d3f4ecc8b511e6ae4a7210486aa994c182John McCall  generateObjCSetterBody(IMP, PID);
943af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
944af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
9454111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
9464111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
947e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallnamespace {
9489928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  struct DestroyIvar : EHScopeStack::Cleanup {
9499928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  private:
9509928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    llvm::Value *addr;
951e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    const ObjCIvarDecl *ivar;
9529928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer &destroyer;
9539928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    bool useEHCleanupForArray;
9549928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  public:
9559928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
9569928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                CodeGenFunction::Destroyer *destroyer,
9579928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                bool useEHCleanupForArray)
9589928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      : addr(addr), ivar(ivar), destroyer(*destroyer),
9599928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        useEHCleanupForArray(useEHCleanupForArray) {}
960e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
961ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
9629928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      LValue lvalue
9639928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0);
9649928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      CGF.emitDestroy(lvalue.getAddress(), ivar->getType(), destroyer,
965ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall                      flags.isForNormalCleanup() && useEHCleanupForArray);
966e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
967e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  };
968e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
969e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
9709928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall/// Like CodeGenFunction::destroyARCStrong, but do it with a call.
9719928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCallstatic void destroyARCStrongWithStore(CodeGenFunction &CGF,
9729928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      llvm::Value *addr,
9739928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      QualType type) {
9749928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  llvm::Value *null = getNullForVariable(addr);
9759928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  CGF.EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
9769928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall}
977f85e193739c953358c865005855253af4f68a497John McCall
978e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallstatic void emitCXXDestructMethod(CodeGenFunction &CGF,
979e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall                                  ObjCImplementationDecl *impl) {
980e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  CodeGenFunction::RunCleanupsScope scope(CGF);
981e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
982e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  llvm::Value *self = CGF.LoadObjCSelf();
983e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
984db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  const ObjCInterfaceDecl *iface = impl->getClassInterface();
985db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose  for (const ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
986e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall       ivar; ivar = ivar->getNextIvar()) {
987e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    QualType type = ivar->getType();
988e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
989e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    // Check whether the ivar is a destructible type.
9909928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    QualType::DestructionKind dtorKind = type.isDestructedType();
9919928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (!dtorKind) continue;
9929928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
9939928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer *destroyer = 0;
9949928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
9959928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Use a call to objc_storeStrong to destroy strong ivars, for the
9969928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // general benefit of the tools.
9979928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (dtorKind == QualType::DK_objc_strong_lifetime) {
9989928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &destroyARCStrongWithStore;
9999928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
10009928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Otherwise use the default for the destruction kind.
10019928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    } else {
10029928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &CGF.getDestroyer(dtorKind);
1003e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
10049928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
10059928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind);
10069928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
10079928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CGF.EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
10089928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                         cleanupKind & EHCleanup);
1009e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  }
1010e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
1011e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
1012e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
1013e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
1014109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanianvoid CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
1015109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 ObjCMethodDecl *MD,
1016109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 bool ctor) {
1017109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
10188d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(MD, IMP->getClassInterface(), MD->getLocStart());
1019e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
1020e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_construct.
1021109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  if (ctor) {
1022f85e193739c953358c865005855253af4f68a497John McCall    // Suppress the final autorelease in ARC.
1023f85e193739c953358c865005855253af4f68a497John McCall    AutoreleaseResult = false;
1024f85e193739c953358c865005855253af4f68a497John McCall
10255f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<CXXCtorInitializer *, 8> IvarInitializers;
1026e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
1027e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall           E = IMP->init_end(); B != E; ++B) {
1028e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall      CXXCtorInitializer *IvarInit = (*B);
102900eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet      FieldDecl *Field = IvarInit->getAnyMember();
1030109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
10319b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian      LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
10329b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian                                    LoadObjCSelf(), Ivar, 0);
10337c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall      EmitAggExpr(IvarInit->getInit(),
10347c2349be2d11143a2e59a167fd43362a3bf4585eJohn McCall                  AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed,
1035410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall                                          AggValueSlot::DoesNotNeedGCBarriers,
1036410ffb2bc5f072d58a73c14560345bcf77dec1ccJohn McCall                                          AggValueSlot::IsNotAliased));
1037109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    }
1038109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    // constructor returns 'self'.
1039109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    CodeGenTypes &Types = CGM.getTypes();
1040109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    QualType IdTy(CGM.getContext().getObjCIdType());
1041109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    llvm::Value *SelfAsId =
1042109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
1043109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
1044e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
1045e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_destruct.
1046bc397cf90355f17c974b0bdf3960e8fb38caf5d6Chandler Carruth  } else {
1047e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    emitCXXDestructMethod(*this, IMP);
1048109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  }
1049109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  FinishFunction();
1050109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian}
1051109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian
10520b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanianbool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
10530b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
10540b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  it++; it++;
10550b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  const ABIArgInfo &AI = it->info;
10560b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  // FIXME. Is this sufficient check?
10570b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  return (AI.getKind() == ABIArgInfo::Indirect);
10580b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian}
10590b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian
106015bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanianbool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
106115bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
106215bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return false;
106315bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
106415bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return FDTTy->getDecl()->hasObjectMember();
106515bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  return false;
106615bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian}
106715bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian
1068c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf() {
1069b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
1070b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
10714111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
10724111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
107345012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz JahanianQualType CodeGenFunction::TypeOfSelfObject() {
107445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
107545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
107614108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
107714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    getContext().getCanonicalType(selfDecl->getType()));
107845012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  return PTy->getPointeeType();
107945012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian}
108045012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
1081e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallLValue
1082e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallCodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
1083e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // This is a special l-value that just issues sends when we load or
1084e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // store through it.
1085e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
1086e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // For certain base kinds, we need to emit the base immediately.
1087e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Base;
1088e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  if (E->isSuperReceiver())
1089e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = LoadObjCSelf();
1090e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else if (E->isClassReceiver())
1091e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver());
1092e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else
1093e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = EmitScalarExpr(E->getBase());
1094e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return LValue::MakePropertyRef(E, Base);
1095e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall}
1096e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
1097e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallstatic RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
1098e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       ReturnValueSlot Return,
1099e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       QualType ResultType,
1100e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       Selector S,
1101e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       llvm::Value *Receiver,
1102e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       const CallArgList &CallArgs) {
1103e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl);
1104f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isClassMessage = OMD->isClassMethod();
1105f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
1106e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return CGF.CGM.getObjCRuntime()
1107e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                .GenerateMessageSendSuper(CGF, Return, ResultType,
1108e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          S, OMD->getClassInterface(),
1109e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isCategoryImpl, Receiver,
1110e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isClassMessage, CallArgs);
1111f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian}
1112f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian
1113119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallRValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
1114119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                    ReturnValueSlot Return) {
1115119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr();
111668af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ResultType = E->getGetterResultType();
111712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S;
1118926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  const ObjCMethodDecl *method;
111912f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isExplicitProperty()) {
112012f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    const ObjCPropertyDecl *Property = E->getExplicitProperty();
112112f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    S = Property->getGetterName();
1122926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = Property->getGetterMethodDecl();
1123b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
1124926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = E->getImplicitPropertyGetter();
1125926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    S = method->getSelector();
11265daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian  }
112712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
1128e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = LV.getPropertyRefBaseAddr();
1129e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
1130f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount) {
1131f85e193739c953358c865005855253af4f68a497John McCall    QualType receiverType;
1132f85e193739c953358c865005855253af4f68a497John McCall    if (E->isSuperReceiver())
1133f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getSuperReceiverType();
1134f85e193739c953358c865005855253af4f68a497John McCall    else if (E->isClassReceiver())
1135f85e193739c953358c865005855253af4f68a497John McCall      receiverType = getContext().getObjCClassType();
1136f85e193739c953358c865005855253af4f68a497John McCall    else
1137f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getBase()->getType();
1138f85e193739c953358c865005855253af4f68a497John McCall  }
1139f85e193739c953358c865005855253af4f68a497John McCall
1140e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // Accesses to 'super' follow a different code path.
114112f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver())
1142926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return AdjustRelatedResultType(*this, E, method,
1143926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                   GenerateMessageSendSuper(*this, Return,
1144926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            ResultType,
1145926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            S, Receiver,
1146926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            CallArgList()));
1147119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
1148119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
1149926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return AdjustRelatedResultType(*this, E, method,
1150f85e193739c953358c865005855253af4f68a497John McCall          CGM.getObjCRuntime().
1151f85e193739c953358c865005855253af4f68a497John McCall             GenerateMessageSend(*this, Return, ResultType, S,
1152f85e193739c953358c865005855253af4f68a497John McCall                                 Receiver, CallArgList(), ReceiverClass));
11539c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar}
11549c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
1155119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallvoid CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
1156119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                        LValue Dst) {
1157119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr();
115812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S = E->getSetterSelector();
115968af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ArgType = E->getSetterArgType();
116068af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian
1161b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // FIXME. Other than scalars, AST is not adequate for setter and
1162b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // getter type mismatches which require conversion.
1163b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  if (Src.isScalar()) {
1164b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    llvm::Value *SrcVal = Src.getScalarVal();
1165b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    QualType DstType = getContext().getCanonicalType(ArgType);
11662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::Type *DstTy = ConvertType(DstType);
1167b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    if (SrcVal->getType() != DstTy)
1168b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian      Src =
1169b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian        RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType));
1170b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  }
1171b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian
1172e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  CallArgList Args;
117304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(Src, ArgType);
1174e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
1175e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = Dst.getPropertyRefBaseAddr();
1176e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  QualType ResultType = getContext().VoidTy;
1177e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
117812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver()) {
1179e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    GenerateMessageSendSuper(*this, ReturnValueSlot(),
1180e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                             ResultType, S, Receiver, Args);
118112f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    return;
118212f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  }
118312f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
1184119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
1185119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
118612f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
118712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1188e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ResultType, S, Receiver, Args,
1189e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ReceiverClass);
119085c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar}
119185c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar
119274391b48b4791cded373683a3baf67314f358d50Chris Lattnervoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
11931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Constant *EnumerationMutationFn =
1194c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.getObjCRuntime().EnumerationMutationFunction();
11951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1196c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  if (!EnumerationMutationFn) {
1197c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
1198c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    return;
1199c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
1200c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
1201bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  CGDebugInfo *DI = getDebugInfo();
1202bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
1203bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getBegin());
1204bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionStart(Builder);
1205bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
1206bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
12079d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  // The local variable comes into scope immediately.
12089d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  AutoVarEmission variable = AutoVarEmission::invalid();
12099d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
12109d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel    variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl()));
12119d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel
1212d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
12131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1214f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fast enumeration state.
12150815b579b31cb3129f732bb7ea36fd6ba6949e98Douglas Gregor  QualType StateTy = CGM.getObjCFastEnumerationStateType();
1216195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
12171884eb0b5c55edda4893ddec45e7dbad79758782Anders Carlsson  EmitNullInitialization(StatePtr, StateTy);
12181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1219f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Number of elements in the items array.
12202abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  static const unsigned NumItems = 16;
12211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1222d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the countByEnumeratingWithState:objects:count: selector.
1223ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  IdentifierInfo *II[] = {
1224ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
1225ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("objects"),
1226ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("count")
1227ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  };
1228ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  Selector FastEnumSel =
1229ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
1230f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1231f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ItemsTy =
1232f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    getContext().getConstantArrayType(getContext().getObjCIdType(),
12331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      llvm::APInt(32, NumItems),
1234f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ArrayType::Normal, 0);
1235195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
12361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1237990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Emit the collection pointer.  In ARC, we do a retain.
1238990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  llvm::Value *Collection;
1239990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (getLangOptions().ObjCAutoRefCount) {
1240990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    Collection = EmitARCRetainScalarExpr(S.getCollection());
1241990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1242990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    // Enter a cleanup to do the release.
1243990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    EmitObjCConsumeObject(S.getCollection()->getType(), Collection);
1244990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  } else {
1245990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    Collection = EmitScalarExpr(S.getCollection());
1246990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
12471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12484b302d32378b364703b212834f908762e570c29cJohn McCall  // The 'continue' label needs to appear within the cleanup for the
12494b302d32378b364703b212834f908762e570c29cJohn McCall  // collection object.
12504b302d32378b364703b212834f908762e570c29cJohn McCall  JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
12514b302d32378b364703b212834f908762e570c29cJohn McCall
1252d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Send it our message:
1253f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CallArgList Args;
1254d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1255d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The first argument is a temporary of the enumeration-state type.
125604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(StatePtr), getContext().getPointerType(StateTy));
12571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1258d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The second argument is a temporary array with space for NumItems
1259d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointers.  We'll actually be loading elements from the array
1260d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointer written into the control state; this buffer is so that
1261d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // collections that *aren't* backed by arrays can still queue up
1262d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // batches of elements.
126304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy));
12641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1265d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The third argument is the capacity of that temporary array.
12662acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
12674a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
126804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(Count), getContext().UnsignedLongTy);
12691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1270d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start the enumeration.
12711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  RValue CountRV =
1272ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1273f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
1274f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
1275c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
1276f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1277d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The initial number of objects that were returned in the buffer.
1278d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialBufferLimit = CountRV.getScalarVal();
12791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1280d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1281d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1282f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1283d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
1284f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1285d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If the limit pointer was zero to begin with, the collection is
1286d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // empty; skip all this.
1287d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
1288d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopInitBB);
12891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1290d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, initialize the loop.
1291d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopInitBB);
12921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1293d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Save the initial mutations value.  This is the value at an
1294d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // address that was written into the state object by
1295d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // countByEnumeratingWithState:objects:count:.
12961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtrPtr =
12972abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
12981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
12992abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                      "mutationsptr");
13001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1301d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialMutations =
1302d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations");
13031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1304d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start looping.  This is the point we return to whenever we have a
1305d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // fresh, non-empty batch of objects.
1306d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1307d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopBodyBB);
13081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1309d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current index into the buffer.
1310bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
1311d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, LoopInitBB);
1312f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1313d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current buffer size.
1314bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
1315d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(initialBufferLimit, LoopInitBB);
1316f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1317d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether the mutations value has changed from where it was
1318d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // at start.  StateMutationsPtr should actually be invariant between
1319d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes.
13202abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1321d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *currentMutations
1322d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateLoad(StateMutationsPtr, "statemutations");
13231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1324d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1325361cf980a7d976ef11a37b49567412b6b63a89d7Dan Gohman  llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
13261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1327d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1328d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       WasNotMutatedBB, WasMutatedBB);
13291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1330d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If so, call the enumeration-mutation function.
1331d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasMutatedBB);
13322abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *V =
13331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Builder.CreateBitCast(Collection,
13342abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          ConvertType(getContext().getObjCIdType()),
13352abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          "tmp");
13362b2105e92fc77016992dae3f117f526e73af5ea9Daniel Dunbar  CallArgList Args2;
133704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args2.add(RValue::get(V), getContext().getObjCIdType());
1338f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to get the function info here, the runtime already
1339f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // should have computed it to build the function.
134004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
1341264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                          FunctionType::ExtInfo()),
1342f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson           EnumerationMutationFn, ReturnValueSlot(), Args2);
13431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1344d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, or if the mutation function returns, just continue.
1345d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasNotMutatedBB);
13461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1347d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Initialize the element variable.
1348d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  RunCleanupsScope elementVariableScope(*this);
134957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  bool elementIsVariable;
1350d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  LValue elementLValue;
1351d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  QualType elementType;
1352d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
135357b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    // Initialize the variable, in case it's a __block variable or something.
135457b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarInit(variable);
1355f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
135657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
1357d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
1358d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                        VK_LValue, SourceLocation());
1359d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(&tempDRE);
1360d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = D->getType();
136157b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = true;
13627acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall
13637acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    if (D->isARCPseudoStrong())
13647acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall      elementLValue.getQuals().setObjCLifetime(Qualifiers::OCL_ExplicitNone);
1365d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  } else {
1366d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = LValue(); // suppress warning
1367d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = cast<Expr>(S.getElement())->getType();
136857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = false;
1369d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
13702acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *convertedElementType = ConvertType(elementType);
1371f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1372d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the buffer out of the enumeration state.
1373d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // TODO: this pointer should actually be invariant between
1374d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes, which would help us do certain loop optimizations.
1375d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *StateItemsPtr =
1376d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
1377d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *EnumStateItems =
1378d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateItemsPtr, "stateitems");
1379f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1380d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the value at the current index from the buffer.
13811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *CurrentItemPtr =
1382d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr");
1383d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr);
13841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1385d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Cast that value to the right type.
1386d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
1387d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                                      "currentitem");
13881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1389d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Make sure we have an l-value.  Yes, this gets evaluated every
1390d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // time through the loop.
13917acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  if (!elementIsVariable) {
1392d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1393545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue);
13947acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  } else {
13957acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    EmitScalarInit(CurrentItem, elementLValue);
13967acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  }
13971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
139857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // If we do have an element variable, this assignment is the end of
139957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // its initialization.
140057b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (elementIsVariable)
140157b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarCleanups(variable);
140257b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall
1403d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Perform the loop body, setting up break and continue labels.
1404e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
1405d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  {
1406d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    RunCleanupsScope Scope(*this);
1407d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    EmitStmt(S.getBody());
1408d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
1409f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.pop_back();
14101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1411d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Destroy the element variable now.
1412d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  elementVariableScope.ForceCleanup();
1413d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1414d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether there are more elements.
1415ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(AfterBody.getBlock());
14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1417d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
1418d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1419d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // First we check in the local buffer.
1420d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *indexPlusOne
1421d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
1422d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1423d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we haven't overrun the buffer yet, we can continue.
1424d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
1425d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       LoopBodyBB, FetchMoreBB);
1426f0906c4edb37b20141428ca77fa7dfd00b976eafFariborz Jahanian
1427d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(indexPlusOne, AfterBody.getBlock());
1428d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(count, AfterBody.getBlock());
1429f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1430d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, we have to fetch more elements.
1431d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(FetchMoreBB);
14321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CountRV =
1434ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1435f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
14361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             FastEnumSel,
1437c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
14381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1439d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we got a zero count, we're done.
1440d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *refetchCount = CountRV.getScalarVal();
1441d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1442d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // (note that the message send might split FetchMoreBB)
1443d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, Builder.GetInsertBlock());
1444d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(refetchCount, Builder.GetInsertBlock());
1445d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1446d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
1447d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopBodyBB);
14481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1449f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // No more elements.
1450d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(EmptyBB);
1451f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
145257b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (!elementIsVariable) {
1453f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // If the element was not a declaration, set it to be null.
1454f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1455d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
1456d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1457545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(null), elementLValue);
1458f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
1459f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1460bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
1461bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getEnd());
1462bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionEnd(Builder);
1463bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
1464bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
1465990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Leave the cleanup we entered in ARC.
1466990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (getLangOptions().ObjCAutoRefCount)
1467990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    PopCleanupBlock();
1468990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
1469ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(LoopEnd.getBlock());
14703d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
14713d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
14721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
1473f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitTryStmt(*this, S);
147464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
147564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
14761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
147764d5d6c5903157c521af496479d06dc26032d718Anders Carlsson  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
147864d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
147964d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
148010cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattnervoid CodeGenFunction::EmitObjCAtSynchronizedStmt(
14811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              const ObjCAtSynchronizedStmt &S) {
1482f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
148310cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner}
148410cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner
148533e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall/// Produce the code for a CK_ARCProduceObject.  Just does a
1486f85e193739c953358c865005855253af4f68a497John McCall/// primitive retain.
1487f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCProduceObject(QualType type,
1488f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *value) {
1489f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetain(type, value);
1490f85e193739c953358c865005855253af4f68a497John McCall}
1491f85e193739c953358c865005855253af4f68a497John McCall
1492f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1493f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCRelease : EHScopeStack::Cleanup {
1494bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall    CallObjCRelease(llvm::Value *object) : object(object) {}
1495bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall    llvm::Value *object;
1496f85e193739c953358c865005855253af4f68a497John McCall
1497ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1498f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitARCRelease(object, /*precise*/ true);
1499f85e193739c953358c865005855253af4f68a497John McCall    }
1500f85e193739c953358c865005855253af4f68a497John McCall  };
1501f85e193739c953358c865005855253af4f68a497John McCall}
1502f85e193739c953358c865005855253af4f68a497John McCall
150333e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall/// Produce the code for a CK_ARCConsumeObject.  Does a primitive
1504f85e193739c953358c865005855253af4f68a497John McCall/// release at the end of the full-expression.
1505f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
1506f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *object) {
1507f85e193739c953358c865005855253af4f68a497John McCall  // If we're in a conditional branch, we need to make the cleanup
1508bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall  // conditional.
1509bddfd87863bac7aa17d226cdfb228f49b30dd5f2John McCall  pushFullExprCleanup<CallObjCRelease>(getARCCleanupKind(), object);
1510f85e193739c953358c865005855253af4f68a497John McCall  return object;
1511f85e193739c953358c865005855253af4f68a497John McCall}
1512f85e193739c953358c865005855253af4f68a497John McCall
1513f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
1514f85e193739c953358c865005855253af4f68a497John McCall                                                           llvm::Value *value) {
1515f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetainAutorelease(type, value);
1516f85e193739c953358c865005855253af4f68a497John McCall}
1517f85e193739c953358c865005855253af4f68a497John McCall
1518f85e193739c953358c865005855253af4f68a497John McCall
1519f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
15202acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner                                                llvm::FunctionType *type,
15215f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                                StringRef fnName) {
1522f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
1523f85e193739c953358c865005855253af4f68a497John McCall
1524f85e193739c953358c865005855253af4f68a497John McCall  // In -fobjc-no-arc-runtime, emit weak references to the runtime
1525f85e193739c953358c865005855253af4f68a497John McCall  // support library.
15269f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (!CGM.getCodeGenOpts().ObjCRuntimeHasARC)
1527f85e193739c953358c865005855253af4f68a497John McCall    if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
1528f85e193739c953358c865005855253af4f68a497John McCall      f->setLinkage(llvm::Function::ExternalWeakLinkage);
1529f85e193739c953358c865005855253af4f68a497John McCall
1530f85e193739c953358c865005855253af4f68a497John McCall  return fn;
1531f85e193739c953358c865005855253af4f68a497John McCall}
1532f85e193739c953358c865005855253af4f68a497John McCall
1533f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the signature
1534f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8*)
1535f85e193739c953358c865005855253af4f68a497John McCall/// where a null input causes a no-op and returns null.
1536f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
1537f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1538f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
15395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName) {
1540f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1541f85e193739c953358c865005855253af4f68a497John McCall
1542f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15439cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrTy);
15442acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1545f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1546f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1547f85e193739c953358c865005855253af4f68a497John McCall  }
1548f85e193739c953358c865005855253af4f68a497John McCall
1549f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
15502acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1551f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1552f85e193739c953358c865005855253af4f68a497John McCall
1553f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1554f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, value);
1555f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1556f85e193739c953358c865005855253af4f68a497John McCall
1557f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to the original type.
1558f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(call, origType);
1559f85e193739c953358c865005855253af4f68a497John McCall}
1560f85e193739c953358c865005855253af4f68a497John McCall
1561f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1562f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**)
1563f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
1564f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Value *addr,
1565f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Constant *&fn,
15665f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                         StringRef fnName) {
1567f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15689cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrPtrTy);
15692acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1570f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1571f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1572f85e193739c953358c865005855253af4f68a497John McCall  }
1573f85e193739c953358c865005855253af4f68a497John McCall
1574f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
15752acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = addr->getType();
1576f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1577f85e193739c953358c865005855253af4f68a497John McCall
1578f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1579f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, addr);
1580f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1581f85e193739c953358c865005855253af4f68a497John McCall
1582f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to a dereference of the original type.
1583f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = call;
1584f85e193739c953358c865005855253af4f68a497John McCall  if (origType != CGF.Int8PtrPtrTy)
1585f85e193739c953358c865005855253af4f68a497John McCall    result = CGF.Builder.CreateBitCast(result,
1586f85e193739c953358c865005855253af4f68a497John McCall                        cast<llvm::PointerType>(origType)->getElementType());
1587f85e193739c953358c865005855253af4f68a497John McCall
1588f85e193739c953358c865005855253af4f68a497John McCall  return result;
1589f85e193739c953358c865005855253af4f68a497John McCall}
1590f85e193739c953358c865005855253af4f68a497John McCall
1591f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1592f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**, i8*)
1593f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
1594f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *addr,
1595f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1596f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
15975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                          StringRef fnName,
1598f85e193739c953358c865005855253af4f68a497John McCall                                          bool ignored) {
1599f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1600f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1601f85e193739c953358c865005855253af4f68a497John McCall
1602f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
16039cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2);
1604f85e193739c953358c865005855253af4f68a497John McCall    argTypes[0] = CGF.Int8PtrPtrTy;
1605f85e193739c953358c865005855253af4f68a497John McCall    argTypes[1] = CGF.Int8PtrTy;
1606f85e193739c953358c865005855253af4f68a497John McCall
16072acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1608f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false);
1609f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1610f85e193739c953358c865005855253af4f68a497John McCall  }
1611f85e193739c953358c865005855253af4f68a497John McCall
16122acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1613f85e193739c953358c865005855253af4f68a497John McCall
1614f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1615f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1616f85e193739c953358c865005855253af4f68a497John McCall
1617f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, addr, value);
1618f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1619f85e193739c953358c865005855253af4f68a497John McCall
1620f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1621f85e193739c953358c865005855253af4f68a497John McCall
1622f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(result, origType);
1623f85e193739c953358c865005855253af4f68a497John McCall}
1624f85e193739c953358c865005855253af4f68a497John McCall
1625f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1626f85e193739c953358c865005855253af4f68a497John McCall///   void (i8**, i8**)
1627f85e193739c953358c865005855253af4f68a497John McCallstatic void emitARCCopyOperation(CodeGenFunction &CGF,
1628f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *dst,
1629f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *src,
1630f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Constant *&fn,
16315f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                 StringRef fnName) {
1632f85e193739c953358c865005855253af4f68a497John McCall  assert(dst->getType() == src->getType());
1633f85e193739c953358c865005855253af4f68a497John McCall
1634f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
16359cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2, CGF.Int8PtrPtrTy);
16362acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1637f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false);
1638f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1639f85e193739c953358c865005855253af4f68a497John McCall  }
1640f85e193739c953358c865005855253af4f68a497John McCall
1641f85e193739c953358c865005855253af4f68a497John McCall  dst = CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy);
1642f85e193739c953358c865005855253af4f68a497John McCall  src = CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy);
1643f85e193739c953358c865005855253af4f68a497John McCall
1644f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, dst, src);
1645f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1646f85e193739c953358c865005855253af4f68a497John McCall}
1647f85e193739c953358c865005855253af4f68a497John McCall
1648f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a retain.  Based on the type, calls one of:
1649f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1650f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1651f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {
1652f85e193739c953358c865005855253af4f68a497John McCall  if (type->isBlockPointerType())
1653f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainBlock(value);
1654f85e193739c953358c865005855253af4f68a497John McCall  else
1655f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainNonBlock(value);
1656f85e193739c953358c865005855253af4f68a497John McCall}
1657f85e193739c953358c865005855253af4f68a497John McCall
1658f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object, with normal retain semantics.
1659f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1660f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) {
1661f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1662f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retain,
1663f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retain");
1664f85e193739c953358c865005855253af4f68a497John McCall}
1665f85e193739c953358c865005855253af4f68a497John McCall
1666f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given block, with _Block_copy semantics.
1667f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1668f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value) {
1669f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1670f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainBlock,
1671f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainBlock");
1672f85e193739c953358c865005855253af4f68a497John McCall}
1673f85e193739c953358c865005855253af4f68a497John McCall
1674f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object which is the result of a function call.
1675f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleasedReturnValue(i8* %value)
1676f85e193739c953358c865005855253af4f68a497John McCall///
1677f85e193739c953358c865005855253af4f68a497John McCall/// Yes, this function name is one character away from a different
1678f85e193739c953358c865005855253af4f68a497John McCall/// call with completely different semantics.
1679f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1680f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
1681f85e193739c953358c865005855253af4f68a497John McCall  // Fetch the void(void) inline asm which marks that we're going to
1682f85e193739c953358c865005855253af4f68a497John McCall  // retain the autoreleased return value.
1683f85e193739c953358c865005855253af4f68a497John McCall  llvm::InlineAsm *&marker
1684f85e193739c953358c865005855253af4f68a497John McCall    = CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker;
1685f85e193739c953358c865005855253af4f68a497John McCall  if (!marker) {
16865f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    StringRef assembly
1687f85e193739c953358c865005855253af4f68a497John McCall      = CGM.getTargetCodeGenInfo()
1688f85e193739c953358c865005855253af4f68a497John McCall           .getARCRetainAutoreleasedReturnValueMarker();
1689f85e193739c953358c865005855253af4f68a497John McCall
1690f85e193739c953358c865005855253af4f68a497John McCall    // If we have an empty assembly string, there's nothing to do.
1691f85e193739c953358c865005855253af4f68a497John McCall    if (assembly.empty()) {
1692f85e193739c953358c865005855253af4f68a497John McCall
1693f85e193739c953358c865005855253af4f68a497John McCall    // Otherwise, at -O0, build an inline asm that we're going to call
1694f85e193739c953358c865005855253af4f68a497John McCall    // in a moment.
1695f85e193739c953358c865005855253af4f68a497John McCall    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1696f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType *type =
1697f85e193739c953358c865005855253af4f68a497John McCall        llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
1698f85e193739c953358c865005855253af4f68a497John McCall                                /*variadic*/ false);
1699f85e193739c953358c865005855253af4f68a497John McCall
1700f85e193739c953358c865005855253af4f68a497John McCall      marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true);
1701f85e193739c953358c865005855253af4f68a497John McCall
1702f85e193739c953358c865005855253af4f68a497John McCall    // If we're at -O1 and above, we don't want to litter the code
1703f85e193739c953358c865005855253af4f68a497John McCall    // with this marker yet, so leave a breadcrumb for the ARC
1704f85e193739c953358c865005855253af4f68a497John McCall    // optimizer to pick up.
1705f85e193739c953358c865005855253af4f68a497John McCall    } else {
1706f85e193739c953358c865005855253af4f68a497John McCall      llvm::NamedMDNode *metadata =
1707f85e193739c953358c865005855253af4f68a497John McCall        CGM.getModule().getOrInsertNamedMetadata(
1708f85e193739c953358c865005855253af4f68a497John McCall                            "clang.arc.retainAutoreleasedReturnValueMarker");
1709f85e193739c953358c865005855253af4f68a497John McCall      assert(metadata->getNumOperands() <= 1);
1710f85e193739c953358c865005855253af4f68a497John McCall      if (metadata->getNumOperands() == 0) {
1711f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *string = llvm::MDString::get(getLLVMContext(), assembly);
1712da549e8995c447542d5631b8b67fcc3a9582797aJay Foad        metadata->addOperand(llvm::MDNode::get(getLLVMContext(), string));
1713f85e193739c953358c865005855253af4f68a497John McCall      }
1714f85e193739c953358c865005855253af4f68a497John McCall    }
1715f85e193739c953358c865005855253af4f68a497John McCall  }
1716f85e193739c953358c865005855253af4f68a497John McCall
1717f85e193739c953358c865005855253af4f68a497John McCall  // Call the marker asm if we made one, which we do only at -O0.
1718f85e193739c953358c865005855253af4f68a497John McCall  if (marker) Builder.CreateCall(marker);
1719f85e193739c953358c865005855253af4f68a497John McCall
1720f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1721f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleasedReturnValue,
1722f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleasedReturnValue");
1723f85e193739c953358c865005855253af4f68a497John McCall}
1724f85e193739c953358c865005855253af4f68a497John McCall
1725f85e193739c953358c865005855253af4f68a497John McCall/// Release the given object.
1726f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_release(i8* %value)
1727f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCRelease(llvm::Value *value, bool precise) {
1728f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return;
1729f85e193739c953358c865005855253af4f68a497John McCall
1730f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_release;
1731f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17329cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
17332acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1734f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1735f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_release");
1736f85e193739c953358c865005855253af4f68a497John McCall  }
1737f85e193739c953358c865005855253af4f68a497John McCall
1738f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
1739f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1740f85e193739c953358c865005855253af4f68a497John McCall
1741f85e193739c953358c865005855253af4f68a497John McCall  // Call objc_release.
1742f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1743f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1744f85e193739c953358c865005855253af4f68a497John McCall
1745f85e193739c953358c865005855253af4f68a497John McCall  if (!precise) {
17465f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    SmallVector<llvm::Value*,1> args;
1747f85e193739c953358c865005855253af4f68a497John McCall    call->setMetadata("clang.imprecise_release",
1748f85e193739c953358c865005855253af4f68a497John McCall                      llvm::MDNode::get(Builder.getContext(), args));
1749f85e193739c953358c865005855253af4f68a497John McCall  }
1750f85e193739c953358c865005855253af4f68a497John McCall}
1751f85e193739c953358c865005855253af4f68a497John McCall
1752f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Always calls this:
1753f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1754f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr,
1755f85e193739c953358c865005855253af4f68a497John McCall                                                     llvm::Value *value,
1756f85e193739c953358c865005855253af4f68a497John McCall                                                     bool ignored) {
1757f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1758f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1759f85e193739c953358c865005855253af4f68a497John McCall
1760f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_storeStrong;
1761f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17629cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy };
17632acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType
1764f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false);
1765f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong");
1766f85e193739c953358c865005855253af4f68a497John McCall  }
1767f85e193739c953358c865005855253af4f68a497John McCall
1768f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1769f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *castValue = Builder.CreateBitCast(value, Int8PtrTy);
1770f85e193739c953358c865005855253af4f68a497John McCall
1771f85e193739c953358c865005855253af4f68a497John McCall  Builder.CreateCall2(fn, addr, castValue)->setDoesNotThrow();
1772f85e193739c953358c865005855253af4f68a497John McCall
1773f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1774f85e193739c953358c865005855253af4f68a497John McCall  return value;
1775f85e193739c953358c865005855253af4f68a497John McCall}
1776f85e193739c953358c865005855253af4f68a497John McCall
1777f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Sometimes calls this:
1778f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1779f85e193739c953358c865005855253af4f68a497John McCall/// Other times, breaks it down into components.
1780545d996ec5a3113f046944f11b27cc2d6cb055b4John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
1781f85e193739c953358c865005855253af4f68a497John McCall                                                 llvm::Value *newValue,
1782f85e193739c953358c865005855253af4f68a497John McCall                                                 bool ignored) {
1783545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  QualType type = dst.getType();
1784f85e193739c953358c865005855253af4f68a497John McCall  bool isBlock = type->isBlockPointerType();
1785f85e193739c953358c865005855253af4f68a497John McCall
1786f85e193739c953358c865005855253af4f68a497John McCall  // Use a store barrier at -O0 unless this is a block type or the
1787f85e193739c953358c865005855253af4f68a497John McCall  // lvalue is inadequately aligned.
1788f85e193739c953358c865005855253af4f68a497John McCall  if (shouldUseFusedARCCalls() &&
1789f85e193739c953358c865005855253af4f68a497John McCall      !isBlock &&
1790f85e193739c953358c865005855253af4f68a497John McCall      !(dst.getAlignment() && dst.getAlignment() < PointerAlignInBytes)) {
1791f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCStoreStrongCall(dst.getAddress(), newValue, ignored);
1792f85e193739c953358c865005855253af4f68a497John McCall  }
1793f85e193739c953358c865005855253af4f68a497John McCall
1794f85e193739c953358c865005855253af4f68a497John McCall  // Otherwise, split it out.
1795f85e193739c953358c865005855253af4f68a497John McCall
1796f85e193739c953358c865005855253af4f68a497John McCall  // Retain the new value.
1797f85e193739c953358c865005855253af4f68a497John McCall  newValue = EmitARCRetain(type, newValue);
1798f85e193739c953358c865005855253af4f68a497John McCall
1799f85e193739c953358c865005855253af4f68a497John McCall  // Read the old value.
1800545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  llvm::Value *oldValue = EmitLoadOfScalar(dst);
1801f85e193739c953358c865005855253af4f68a497John McCall
1802f85e193739c953358c865005855253af4f68a497John McCall  // Store.  We do this before the release so that any deallocs won't
1803f85e193739c953358c865005855253af4f68a497John McCall  // see the old value.
1804545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  EmitStoreOfScalar(newValue, dst);
1805f85e193739c953358c865005855253af4f68a497John McCall
1806f85e193739c953358c865005855253af4f68a497John McCall  // Finally, release the old value.
1807f85e193739c953358c865005855253af4f68a497John McCall  EmitARCRelease(oldValue, /*precise*/ false);
1808f85e193739c953358c865005855253af4f68a497John McCall
1809f85e193739c953358c865005855253af4f68a497John McCall  return newValue;
1810f85e193739c953358c865005855253af4f68a497John McCall}
1811f85e193739c953358c865005855253af4f68a497John McCall
1812f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1813f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %value)
1814f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) {
1815f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1816f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_autorelease,
1817f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autorelease");
1818f85e193739c953358c865005855253af4f68a497John McCall}
1819f85e193739c953358c865005855253af4f68a497John McCall
1820f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1821f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleaseReturnValue(i8* %value)
1822f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1823f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
1824f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1825f85e193739c953358c865005855253af4f68a497John McCall                            CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
1826f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autoreleaseReturnValue");
1827f85e193739c953358c865005855253af4f68a497John McCall}
1828f85e193739c953358c865005855253af4f68a497John McCall
1829f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1830f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleaseReturnValue(i8* %value)
1831f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1832f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
1833f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1834f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
1835f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleaseReturnValue");
1836f85e193739c953358c865005855253af4f68a497John McCall}
1837f85e193739c953358c865005855253af4f68a497John McCall
1838f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1839f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1840f85e193739c953358c865005855253af4f68a497John McCall/// or
1841f85e193739c953358c865005855253af4f68a497John McCall///   %retain = call i8* @objc_retainBlock(i8* %value)
1842f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %retain)
1843f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
1844f85e193739c953358c865005855253af4f68a497John McCall                                                       llvm::Value *value) {
1845f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isBlockPointerType())
1846f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainAutoreleaseNonBlock(value);
1847f85e193739c953358c865005855253af4f68a497John McCall
1848f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1849f85e193739c953358c865005855253af4f68a497John McCall
18502acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *origType = value->getType();
1851f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1852f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCRetainBlock(value);
1853f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCAutorelease(value);
1854f85e193739c953358c865005855253af4f68a497John McCall  return Builder.CreateBitCast(value, origType);
1855f85e193739c953358c865005855253af4f68a497John McCall}
1856f85e193739c953358c865005855253af4f68a497John McCall
1857f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1858f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1859f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1860f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) {
1861f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1862f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainAutorelease,
1863f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutorelease");
1864f85e193739c953358c865005855253af4f68a497John McCall}
1865f85e193739c953358c865005855253af4f68a497John McCall
1866f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeak(i8** %addr)
1867f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_autorelease(objc_loadWeakRetained(addr)).
1868f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeak(llvm::Value *addr) {
1869f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1870f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeak,
1871f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeak");
1872f85e193739c953358c865005855253af4f68a497John McCall}
1873f85e193739c953358c865005855253af4f68a497John McCall
1874f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeakRetained(i8** %addr)
1875f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(llvm::Value *addr) {
1876f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1877f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeakRetained,
1878f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeakRetained");
1879f85e193739c953358c865005855253af4f68a497John McCall}
1880f85e193739c953358c865005855253af4f68a497John McCall
1881f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_storeWeak(i8** %addr, i8* %value)
1882f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.
1883f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreWeak(llvm::Value *addr,
1884f85e193739c953358c865005855253af4f68a497John McCall                                               llvm::Value *value,
1885f85e193739c953358c865005855253af4f68a497John McCall                                               bool ignored) {
1886f85e193739c953358c865005855253af4f68a497John McCall  return emitARCStoreOperation(*this, addr, value,
1887f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_storeWeak,
1888f85e193739c953358c865005855253af4f68a497John McCall                               "objc_storeWeak", ignored);
1889f85e193739c953358c865005855253af4f68a497John McCall}
1890f85e193739c953358c865005855253af4f68a497John McCall
1891f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_initWeak(i8** %addr, i8* %value)
1892f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.  %addr is known to not have a current weak entry.
1893f85e193739c953358c865005855253af4f68a497John McCall/// Essentially equivalent to:
1894f85e193739c953358c865005855253af4f68a497John McCall///   *addr = nil; objc_storeWeak(addr, value);
1895f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCInitWeak(llvm::Value *addr, llvm::Value *value) {
1896f85e193739c953358c865005855253af4f68a497John McCall  // If we're initializing to null, just write null to memory; no need
1897f85e193739c953358c865005855253af4f68a497John McCall  // to get the runtime involved.  But don't do this if optimization
1898f85e193739c953358c865005855253af4f68a497John McCall  // is enabled, because accounting for this would make the optimizer
1899f85e193739c953358c865005855253af4f68a497John McCall  // much more complicated.
1900f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value) &&
1901f85e193739c953358c865005855253af4f68a497John McCall      CGM.getCodeGenOpts().OptimizationLevel == 0) {
1902f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(value, addr);
1903f85e193739c953358c865005855253af4f68a497John McCall    return;
1904f85e193739c953358c865005855253af4f68a497John McCall  }
1905f85e193739c953358c865005855253af4f68a497John McCall
1906f85e193739c953358c865005855253af4f68a497John McCall  emitARCStoreOperation(*this, addr, value,
1907f85e193739c953358c865005855253af4f68a497John McCall                        CGM.getARCEntrypoints().objc_initWeak,
1908f85e193739c953358c865005855253af4f68a497John McCall                        "objc_initWeak", /*ignored*/ true);
1909f85e193739c953358c865005855253af4f68a497John McCall}
1910f85e193739c953358c865005855253af4f68a497John McCall
1911f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_destroyWeak(i8** %addr)
1912f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_storeWeak(addr, nil).
1913f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCDestroyWeak(llvm::Value *addr) {
1914f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_destroyWeak;
1915f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
19169cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrPtrTy);
19172acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1918f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1919f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak");
1920f85e193739c953358c865005855253af4f68a497John McCall  }
1921f85e193739c953358c865005855253af4f68a497John McCall
1922f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
1923f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1924f85e193739c953358c865005855253af4f68a497John McCall
1925f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, addr);
1926f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1927f85e193739c953358c865005855253af4f68a497John McCall}
1928f85e193739c953358c865005855253af4f68a497John McCall
1929f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_moveWeak(i8** %dest, i8** %src)
1930f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Leaves %src pointing to nothing.
1931f85e193739c953358c865005855253af4f68a497John McCall/// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)).
1932f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src) {
1933f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1934f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_moveWeak,
1935f85e193739c953358c865005855253af4f68a497John McCall                       "objc_moveWeak");
1936f85e193739c953358c865005855253af4f68a497John McCall}
1937f85e193739c953358c865005855253af4f68a497John McCall
1938f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_copyWeak(i8** %dest, i8** %src)
1939f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Essentially
1940f85e193739c953358c865005855253af4f68a497John McCall///   objc_release(objc_initWeak(dest, objc_readWeakRetained(src)))
1941f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCCopyWeak(llvm::Value *dst, llvm::Value *src) {
1942f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1943f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_copyWeak,
1944f85e193739c953358c865005855253af4f68a497John McCall                       "objc_copyWeak");
1945f85e193739c953358c865005855253af4f68a497John McCall}
1946f85e193739c953358c865005855253af4f68a497John McCall
1947f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a objc_autoreleasepool_push.
1948f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleasePoolPush(void)
1949f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
1950f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPush;
1951f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
19522acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1953f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Int8PtrTy, false);
1954f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush");
1955f85e193739c953358c865005855253af4f68a497John McCall  }
1956f85e193739c953358c865005855253af4f68a497John McCall
1957f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn);
1958f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1959f85e193739c953358c865005855253af4f68a497John McCall
1960f85e193739c953358c865005855253af4f68a497John McCall  return call;
1961f85e193739c953358c865005855253af4f68a497John McCall}
1962f85e193739c953358c865005855253af4f68a497John McCall
1963f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1964f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_autoreleasePoolPop(i8* %ptr)
1965f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
1966f85e193739c953358c865005855253af4f68a497John McCall  assert(value->getType() == Int8PtrTy);
1967f85e193739c953358c865005855253af4f68a497John McCall
1968f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPop;
1969f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
19709cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
19712acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner    llvm::FunctionType *fnType =
1972f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1973f85e193739c953358c865005855253af4f68a497John McCall
1974f85e193739c953358c865005855253af4f68a497John McCall    // We don't want to use a weak import here; instead we should not
1975f85e193739c953358c865005855253af4f68a497John McCall    // fall into this path.
1976f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop");
1977f85e193739c953358c865005855253af4f68a497John McCall  }
1978f85e193739c953358c865005855253af4f68a497John McCall
1979f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1980f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1981f85e193739c953358c865005855253af4f68a497John McCall}
1982f85e193739c953358c865005855253af4f68a497John McCall
1983f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do an MRR version objc_autoreleasepool_push.
1984f85e193739c953358c865005855253af4f68a497John McCall/// Which is: [[NSAutoreleasePool alloc] init];
1985f85e193739c953358c865005855253af4f68a497John McCall/// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class.
1986f85e193739c953358c865005855253af4f68a497John McCall/// init is declared as: - (id) init; in its NSObject super class.
1987f85e193739c953358c865005855253af4f68a497John McCall///
1988f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() {
1989f85e193739c953358c865005855253af4f68a497John McCall  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
1990f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(Builder);
1991f85e193739c953358c865005855253af4f68a497John McCall  // [NSAutoreleasePool alloc]
1992f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");
1993f85e193739c953358c865005855253af4f68a497John McCall  Selector AllocSel = getContext().Selectors.getSelector(0, &II);
1994f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1995f85e193739c953358c865005855253af4f68a497John McCall  RValue AllocRV =
1996f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1997f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1998f85e193739c953358c865005855253af4f68a497John McCall                                AllocSel, Receiver, Args);
1999f85e193739c953358c865005855253af4f68a497John McCall
2000f85e193739c953358c865005855253af4f68a497John McCall  // [Receiver init]
2001f85e193739c953358c865005855253af4f68a497John McCall  Receiver = AllocRV.getScalarVal();
2002f85e193739c953358c865005855253af4f68a497John McCall  II = &CGM.getContext().Idents.get("init");
2003f85e193739c953358c865005855253af4f68a497John McCall  Selector InitSel = getContext().Selectors.getSelector(0, &II);
2004f85e193739c953358c865005855253af4f68a497John McCall  RValue InitRV =
2005f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
2006f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
2007f85e193739c953358c865005855253af4f68a497John McCall                                InitSel, Receiver, Args);
2008f85e193739c953358c865005855253af4f68a497John McCall  return InitRV.getScalarVal();
2009f85e193739c953358c865005855253af4f68a497John McCall}
2010f85e193739c953358c865005855253af4f68a497John McCall
2011f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
2012f85e193739c953358c865005855253af4f68a497John McCall/// [tmp drain];
2013f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) {
2014f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("drain");
2015f85e193739c953358c865005855253af4f68a497John McCall  Selector DrainSel = getContext().Selectors.getSelector(0, &II);
2016f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
2017f85e193739c953358c865005855253af4f68a497John McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
2018f85e193739c953358c865005855253af4f68a497John McCall                              getContext().VoidTy, DrainSel, Arg, Args);
2019f85e193739c953358c865005855253af4f68a497John McCall}
2020f85e193739c953358c865005855253af4f68a497John McCall
2021bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
2022bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              llvm::Value *addr,
2023bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              QualType type) {
2024bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
2025bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ true);
2026bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
2027bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
2028bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
2029bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                llvm::Value *addr,
2030bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                QualType type) {
2031bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
2032bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ false);
2033bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
2034bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
2035bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
2036bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     llvm::Value *addr,
2037bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     QualType type) {
2038bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCDestroyWeak(addr);
2039bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
2040bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
2041f85e193739c953358c865005855253af4f68a497John McCallnamespace {
2042f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCAutoreleasePoolObject : EHScopeStack::Cleanup {
2043f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
2044f85e193739c953358c865005855253af4f68a497John McCall
2045f85e193739c953358c865005855253af4f68a497John McCall    CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2046f85e193739c953358c865005855253af4f68a497John McCall
2047ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
2048f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCAutoreleasePoolPop(Token);
2049f85e193739c953358c865005855253af4f68a497John McCall    }
2050f85e193739c953358c865005855253af4f68a497John McCall  };
2051f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCMRRAutoreleasePoolObject : EHScopeStack::Cleanup {
2052f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
2053f85e193739c953358c865005855253af4f68a497John McCall
2054f85e193739c953358c865005855253af4f68a497John McCall    CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
2055f85e193739c953358c865005855253af4f68a497John McCall
2056ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
2057f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCMRRAutoreleasePoolPop(Token);
2058f85e193739c953358c865005855253af4f68a497John McCall    }
2059f85e193739c953358c865005855253af4f68a497John McCall  };
2060f85e193739c953358c865005855253af4f68a497John McCall}
2061f85e193739c953358c865005855253af4f68a497John McCall
2062f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
2063f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount)
2064f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr);
2065f85e193739c953358c865005855253af4f68a497John McCall  else
2066f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr);
2067f85e193739c953358c865005855253af4f68a497John McCall}
2068f85e193739c953358c865005855253af4f68a497John McCall
2069f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2070f85e193739c953358c865005855253af4f68a497John McCall                                                  LValue lvalue,
2071f85e193739c953358c865005855253af4f68a497John McCall                                                  QualType type) {
2072f85e193739c953358c865005855253af4f68a497John McCall  switch (type.getObjCLifetime()) {
2073f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
2074f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
2075f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong:
2076f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
2077545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue).getScalarVal(),
2078f85e193739c953358c865005855253af4f68a497John McCall                         false);
2079f85e193739c953358c865005855253af4f68a497John McCall
2080f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:
2081f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitARCLoadWeakRetained(lvalue.getAddress()),
2082f85e193739c953358c865005855253af4f68a497John McCall                         true);
2083f85e193739c953358c865005855253af4f68a497John McCall  }
2084f85e193739c953358c865005855253af4f68a497John McCall
2085f85e193739c953358c865005855253af4f68a497John McCall  llvm_unreachable("impossible lifetime!");
2086f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult();
2087f85e193739c953358c865005855253af4f68a497John McCall}
2088f85e193739c953358c865005855253af4f68a497John McCall
2089f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2090f85e193739c953358c865005855253af4f68a497John McCall                                                  const Expr *e) {
2091f85e193739c953358c865005855253af4f68a497John McCall  e = e->IgnoreParens();
2092f85e193739c953358c865005855253af4f68a497John McCall  QualType type = e->getType();
2093f85e193739c953358c865005855253af4f68a497John McCall
20942148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  // If we're loading retained from a __strong xvalue, we can avoid
20952148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  // an extra retain/release pair by zeroing out the source of this
20962148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  // "move" operation.
20972148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  if (e->isXValue() &&
20982148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall      !type.isConstQualified() &&
20992148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall      type.getObjCLifetime() == Qualifiers::OCL_Strong) {
21002148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    // Emit the lvalue.
21012148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    LValue lv = CGF.EmitLValue(e);
21022148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
21032148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    // Load the object pointer.
21042148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal();
21052148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
21062148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    // Set the source pointer to NULL.
21072148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    CGF.EmitStoreOfScalar(getNullForVariable(lv.getAddress()), lv);
21082148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
21092148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall    return TryEmitResult(result, true);
21102148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall  }
21112148011bffc011f8e5f5b6dc1e312fa4afbc10a9John McCall
2112f85e193739c953358c865005855253af4f68a497John McCall  // As a very special optimization, in ARC++, if the l-value is the
2113f85e193739c953358c865005855253af4f68a497John McCall  // result of a non-volatile assignment, do a simple retain of the
2114f85e193739c953358c865005855253af4f68a497John McCall  // result of the call to objc_storeWeak instead of reloading.
2115f85e193739c953358c865005855253af4f68a497John McCall  if (CGF.getLangOptions().CPlusPlus &&
2116f85e193739c953358c865005855253af4f68a497John McCall      !type.isVolatileQualified() &&
2117f85e193739c953358c865005855253af4f68a497John McCall      type.getObjCLifetime() == Qualifiers::OCL_Weak &&
2118f85e193739c953358c865005855253af4f68a497John McCall      isa<BinaryOperator>(e) &&
2119f85e193739c953358c865005855253af4f68a497John McCall      cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
2120f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitScalarExpr(e), false);
2121f85e193739c953358c865005855253af4f68a497John McCall
2122f85e193739c953358c865005855253af4f68a497John McCall  return tryEmitARCRetainLoadOfScalar(CGF, CGF.EmitLValue(e), type);
2123f85e193739c953358c865005855253af4f68a497John McCall}
2124f85e193739c953358c865005855253af4f68a497John McCall
2125f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
2126f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value);
2127f85e193739c953358c865005855253af4f68a497John McCall
2128f85e193739c953358c865005855253af4f68a497John McCall/// Given that the given expression is some sort of call (which does
2129f85e193739c953358c865005855253af4f68a497John McCall/// not return retained), emit a retain following it.
2130f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainCall(CodeGenFunction &CGF, const Expr *e) {
2131f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = CGF.EmitScalarExpr(e);
2132f85e193739c953358c865005855253af4f68a497John McCall  return emitARCRetainAfterCall(CGF, value);
2133f85e193739c953358c865005855253af4f68a497John McCall}
2134f85e193739c953358c865005855253af4f68a497John McCall
2135f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
2136f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value) {
2137f85e193739c953358c865005855253af4f68a497John McCall  if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
2138f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
2139f85e193739c953358c865005855253af4f68a497John McCall
2140f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain immediately following the call.
2141f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(call->getParent(),
2142f85e193739c953358c865005855253af4f68a497John McCall                               ++llvm::BasicBlock::iterator(call));
2143f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
2144f85e193739c953358c865005855253af4f68a497John McCall
2145f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
2146f85e193739c953358c865005855253af4f68a497John McCall    return value;
2147f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
2148f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
2149f85e193739c953358c865005855253af4f68a497John McCall
2150f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain at the beginning of the normal destination block.
2151f85e193739c953358c865005855253af4f68a497John McCall    llvm::BasicBlock *BB = invoke->getNormalDest();
2152f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(BB, BB->begin());
2153f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
2154f85e193739c953358c865005855253af4f68a497John McCall
2155f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
2156f85e193739c953358c865005855253af4f68a497John McCall    return value;
2157f85e193739c953358c865005855253af4f68a497John McCall
2158f85e193739c953358c865005855253af4f68a497John McCall  // Bitcasts can arise because of related-result returns.  Rewrite
2159f85e193739c953358c865005855253af4f68a497John McCall  // the operand.
2160f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
2161f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *operand = bitcast->getOperand(0);
2162f85e193739c953358c865005855253af4f68a497John McCall    operand = emitARCRetainAfterCall(CGF, operand);
2163f85e193739c953358c865005855253af4f68a497John McCall    bitcast->setOperand(0, operand);
2164f85e193739c953358c865005855253af4f68a497John McCall    return bitcast;
2165f85e193739c953358c865005855253af4f68a497John McCall
2166f85e193739c953358c865005855253af4f68a497John McCall  // Generic fall-back case.
2167f85e193739c953358c865005855253af4f68a497John McCall  } else {
2168f85e193739c953358c865005855253af4f68a497John McCall    // Retain using the non-block variant: we never need to do a copy
2169f85e193739c953358c865005855253af4f68a497John McCall    // of a block that's been returned to us.
2170f85e193739c953358c865005855253af4f68a497John McCall    return CGF.EmitARCRetainNonBlock(value);
2171f85e193739c953358c865005855253af4f68a497John McCall  }
2172f85e193739c953358c865005855253af4f68a497John McCall}
2173f85e193739c953358c865005855253af4f68a497John McCall
2174dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall/// Determine whether it might be important to emit a separate
2175dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall/// objc_retain_block on the result of the given expression, or
2176dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall/// whether it's okay to just emit it in a +1 context.
2177dc05b11c67331016473fbc7909827b1b89c9616bJohn McCallstatic bool shouldEmitSeparateBlockRetain(const Expr *e) {
2178dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  assert(e->getType()->isBlockPointerType());
2179dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  e = e->IgnoreParens();
2180dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2181dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  // For future goodness, emit block expressions directly in +1
2182dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  // contexts if we can.
2183dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  if (isa<BlockExpr>(e))
2184dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    return false;
2185dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2186dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  if (const CastExpr *cast = dyn_cast<CastExpr>(e)) {
2187dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    switch (cast->getCastKind()) {
2188dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    // Emitting these operations in +1 contexts is goodness.
2189dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_LValueToRValue:
219033e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    case CK_ARCReclaimReturnedObject:
219133e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    case CK_ARCConsumeObject:
219233e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall    case CK_ARCProduceObject:
2193dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      return false;
2194dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2195dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    // These operations preserve a block type.
2196dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_NoOp:
2197dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_BitCast:
2198dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      return shouldEmitSeparateBlockRetain(cast->getSubExpr());
2199dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2200dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    // These operations are known to be bad (or haven't been considered).
2201dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    case CK_AnyPointerToBlockPointerCast:
2202dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    default:
2203dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      return true;
2204dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall    }
2205dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  }
2206dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2207dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall  return true;
2208dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall}
2209dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2210f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult
2211f85e193739c953358c865005855253af4f68a497John McCalltryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
2212990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  // Look through cleanups.
2213990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  if (const ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(e)) {
2214990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    CodeGenFunction::RunCleanupsScope scope(CGF);
2215990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall    return tryEmitARCRetainScalarExpr(CGF, cleanups->getSubExpr());
2216990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall  }
2217990567cb60e8530ba01b41d4e056e32b44b95ec0John McCall
2218f85e193739c953358c865005855253af4f68a497John McCall  // The desired result type, if it differs from the type of the
2219f85e193739c953358c865005855253af4f68a497John McCall  // ultimate opaque expression.
22202acc6e3feda5e4f7d9009bdcf8b1cd777fecfe2dChris Lattner  llvm::Type *resultType = 0;
2221f85e193739c953358c865005855253af4f68a497John McCall
2222f85e193739c953358c865005855253af4f68a497John McCall  while (true) {
2223f85e193739c953358c865005855253af4f68a497John McCall    e = e->IgnoreParens();
2224f85e193739c953358c865005855253af4f68a497John McCall
2225f85e193739c953358c865005855253af4f68a497John McCall    // There's a break at the end of this if-chain;  anything
2226f85e193739c953358c865005855253af4f68a497John McCall    // that wants to keep looping has to explicitly continue.
2227f85e193739c953358c865005855253af4f68a497John McCall    if (const CastExpr *ce = dyn_cast<CastExpr>(e)) {
2228f85e193739c953358c865005855253af4f68a497John McCall      switch (ce->getCastKind()) {
2229f85e193739c953358c865005855253af4f68a497John McCall      // No-op casts don't change the type, so we just ignore them.
2230f85e193739c953358c865005855253af4f68a497John McCall      case CK_NoOp:
2231f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
2232f85e193739c953358c865005855253af4f68a497John McCall        continue;
2233f85e193739c953358c865005855253af4f68a497John McCall
2234f85e193739c953358c865005855253af4f68a497John McCall      case CK_LValueToRValue: {
2235f85e193739c953358c865005855253af4f68a497John McCall        TryEmitResult loadResult
2236f85e193739c953358c865005855253af4f68a497John McCall          = tryEmitARCRetainLoadOfScalar(CGF, ce->getSubExpr());
2237f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) {
2238f85e193739c953358c865005855253af4f68a497John McCall          llvm::Value *value = loadResult.getPointer();
2239f85e193739c953358c865005855253af4f68a497John McCall          value = CGF.Builder.CreateBitCast(value, resultType);
2240f85e193739c953358c865005855253af4f68a497John McCall          loadResult.setPointer(value);
2241f85e193739c953358c865005855253af4f68a497John McCall        }
2242f85e193739c953358c865005855253af4f68a497John McCall        return loadResult;
2243f85e193739c953358c865005855253af4f68a497John McCall      }
2244f85e193739c953358c865005855253af4f68a497John McCall
2245f85e193739c953358c865005855253af4f68a497John McCall      // These casts can change the type, so remember that and
2246f85e193739c953358c865005855253af4f68a497John McCall      // soldier on.  We only need to remember the outermost such
2247f85e193739c953358c865005855253af4f68a497John McCall      // cast, though.
22481d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      case CK_CPointerToObjCPointerCast:
22491d9b3b25f7ac0d0195bba6b507a684fe5e7943eeJohn McCall      case CK_BlockPointerToObjCPointerCast:
2250f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToBlockPointerCast:
2251f85e193739c953358c865005855253af4f68a497John McCall      case CK_BitCast:
2252f85e193739c953358c865005855253af4f68a497John McCall        if (!resultType)
2253f85e193739c953358c865005855253af4f68a497John McCall          resultType = CGF.ConvertType(ce->getType());
2254f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
2255f85e193739c953358c865005855253af4f68a497John McCall        assert(e->getType()->hasPointerRepresentation());
2256f85e193739c953358c865005855253af4f68a497John McCall        continue;
2257f85e193739c953358c865005855253af4f68a497John McCall
2258f85e193739c953358c865005855253af4f68a497John McCall      // For consumptions, just emit the subexpression and thus elide
2259f85e193739c953358c865005855253af4f68a497John McCall      // the retain/release pair.
226033e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      case CK_ARCConsumeObject: {
2261f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = CGF.EmitScalarExpr(ce->getSubExpr());
2262f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2263f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2264f85e193739c953358c865005855253af4f68a497John McCall      }
2265f85e193739c953358c865005855253af4f68a497John McCall
2266dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      // Block extends are net +0.  Naively, we could just recurse on
2267dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      // the subexpression, but actually we need to ensure that the
2268dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      // value is copied as a block, so there's a little filter here.
226933e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      case CK_ARCExtendBlockObject: {
2270dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        llvm::Value *result; // will be a +0 value
2271dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2272dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // If we can't safely assume the sub-expression will produce a
2273dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // block-copied value, emit the sub-expression at +0.
2274dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        if (shouldEmitSeparateBlockRetain(ce->getSubExpr())) {
2275dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          result = CGF.EmitScalarExpr(ce->getSubExpr());
2276dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2277dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // Otherwise, try to emit the sub-expression at +1 recursively.
2278dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        } else {
2279dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          TryEmitResult subresult
2280dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall            = tryEmitARCRetainScalarExpr(CGF, ce->getSubExpr());
2281dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          result = subresult.getPointer();
2282dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2283dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          // If that produced a retained value, just use that,
2284dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          // possibly casting down.
2285dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          if (subresult.getInt()) {
2286dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall            if (resultType)
2287dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall              result = CGF.Builder.CreateBitCast(result, resultType);
2288dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall            return TryEmitResult(result, true);
2289dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          }
2290dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2291dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall          // Otherwise it's +0.
2292dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        }
2293dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
2294dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        // Retain the object as a block, then cast down.
2295dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        result = CGF.EmitARCRetainBlock(result);
2296dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2297dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall        return TryEmitResult(result, true);
2298dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall      }
2299dc05b11c67331016473fbc7909827b1b89c9616bJohn McCall
23007e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // For reclaims, emit the subexpression as a retained call and
23017e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // skip the consumption.
230233e56f3273457bfa22c7c50bc46cf5a18216863dJohn McCall      case CK_ARCReclaimReturnedObject: {
23037e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce->getSubExpr());
23047e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
23057e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        return TryEmitResult(result, true);
23067e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      }
23077e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall
2308f85e193739c953358c865005855253af4f68a497John McCall      case CK_GetObjCProperty: {
2309f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce);
2310f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2311f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
2312f85e193739c953358c865005855253af4f68a497John McCall      }
2313f85e193739c953358c865005855253af4f68a497John McCall
2314f85e193739c953358c865005855253af4f68a497John McCall      default:
2315f85e193739c953358c865005855253af4f68a497John McCall        break;
2316f85e193739c953358c865005855253af4f68a497John McCall      }
2317f85e193739c953358c865005855253af4f68a497John McCall
2318f85e193739c953358c865005855253af4f68a497John McCall    // Skip __extension__.
2319f85e193739c953358c865005855253af4f68a497John McCall    } else if (const UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
2320f85e193739c953358c865005855253af4f68a497John McCall      if (op->getOpcode() == UO_Extension) {
2321f85e193739c953358c865005855253af4f68a497John McCall        e = op->getSubExpr();
2322f85e193739c953358c865005855253af4f68a497John McCall        continue;
2323f85e193739c953358c865005855253af4f68a497John McCall      }
2324f85e193739c953358c865005855253af4f68a497John McCall
2325f85e193739c953358c865005855253af4f68a497John McCall    // For calls and message sends, use the retained-call logic.
2326f85e193739c953358c865005855253af4f68a497John McCall    // Delegate inits are a special case in that they're the only
2327f85e193739c953358c865005855253af4f68a497John McCall    // returns-retained expression that *isn't* surrounded by
2328f85e193739c953358c865005855253af4f68a497John McCall    // a consume.
2329f85e193739c953358c865005855253af4f68a497John McCall    } else if (isa<CallExpr>(e) ||
2330f85e193739c953358c865005855253af4f68a497John McCall               (isa<ObjCMessageExpr>(e) &&
2331f85e193739c953358c865005855253af4f68a497John McCall                !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
2332f85e193739c953358c865005855253af4f68a497John McCall      llvm::Value *result = emitARCRetainCall(CGF, e);
2333f85e193739c953358c865005855253af4f68a497John McCall      if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2334f85e193739c953358c865005855253af4f68a497John McCall      return TryEmitResult(result, true);
2335f85e193739c953358c865005855253af4f68a497John McCall    }
2336f85e193739c953358c865005855253af4f68a497John McCall
2337f85e193739c953358c865005855253af4f68a497John McCall    // Conservatively halt the search at any other expression kind.
2338f85e193739c953358c865005855253af4f68a497John McCall    break;
2339f85e193739c953358c865005855253af4f68a497John McCall  }
2340f85e193739c953358c865005855253af4f68a497John McCall
2341f85e193739c953358c865005855253af4f68a497John McCall  // We didn't find an obvious production, so emit what we've got and
2342f85e193739c953358c865005855253af4f68a497John McCall  // tell the caller that we didn't manage to retain.
2343f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = CGF.EmitScalarExpr(e);
2344f85e193739c953358c865005855253af4f68a497John McCall  if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2345f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult(result, false);
2346f85e193739c953358c865005855253af4f68a497John McCall}
2347f85e193739c953358c865005855253af4f68a497John McCall
2348f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2349f85e193739c953358c865005855253af4f68a497John McCall                                                LValue lvalue,
2350f85e193739c953358c865005855253af4f68a497John McCall                                                QualType type) {
2351f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainLoadOfScalar(CGF, lvalue, type);
2352f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2353f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2354f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetain(type, value);
2355f85e193739c953358c865005855253af4f68a497John McCall  return value;
2356f85e193739c953358c865005855253af4f68a497John McCall}
2357f85e193739c953358c865005855253af4f68a497John McCall
2358f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainScalarExpr - Semantically equivalent to
2359f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a
2360f85e193739c953358c865005855253af4f68a497John McCall/// best-effort attempt to peephole expressions that naturally produce
2361f85e193739c953358c865005855253af4f68a497John McCall/// retained objects.
2362f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
2363f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2364f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2365f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2366f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetain(e->getType(), value);
2367f85e193739c953358c865005855253af4f68a497John McCall  return value;
2368f85e193739c953358c865005855253af4f68a497John McCall}
2369f85e193739c953358c865005855253af4f68a497John McCall
2370f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
2371f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {
2372f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2373f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2374f85e193739c953358c865005855253af4f68a497John McCall  if (result.getInt())
2375f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCAutorelease(value);
2376f85e193739c953358c865005855253af4f68a497John McCall  else
2377f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetainAutorelease(e->getType(), value);
2378f85e193739c953358c865005855253af4f68a497John McCall  return value;
2379f85e193739c953358c865005855253af4f68a497John McCall}
2380f85e193739c953358c865005855253af4f68a497John McCall
2381f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2382f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
2383f85e193739c953358c865005855253af4f68a497John McCall                                    bool ignored) {
2384f85e193739c953358c865005855253af4f68a497John McCall  // Evaluate the RHS first.
2385f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS());
2386f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2387f85e193739c953358c865005855253af4f68a497John McCall
2388fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  bool hasImmediateRetain = result.getInt();
2389fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall
2390fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // If we didn't emit a retained object, and the l-value is of block
2391fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // type, then we need to emit the block-retain immediately in case
2392fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  // it invalidates the l-value.
2393fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  if (!hasImmediateRetain && e->getType()->isBlockPointerType()) {
2394fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall    value = EmitARCRetainBlock(value);
2395fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall    hasImmediateRetain = true;
2396fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  }
2397fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall
2398f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2399f85e193739c953358c865005855253af4f68a497John McCall
2400f85e193739c953358c865005855253af4f68a497John McCall  // If the RHS was emitted retained, expand this.
2401fb7208119a60f68c87e7d4b6e4b87371871abb49John McCall  if (hasImmediateRetain) {
2402f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *oldValue =
2403f85e193739c953358c865005855253af4f68a497John McCall      EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatileQualified(),
2404f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getAlignment(), e->getType(),
2405f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getTBAAInfo());
2406f85e193739c953358c865005855253af4f68a497John McCall    EmitStoreOfScalar(value, lvalue.getAddress(),
2407f85e193739c953358c865005855253af4f68a497John McCall                      lvalue.isVolatileQualified(), lvalue.getAlignment(),
2408f85e193739c953358c865005855253af4f68a497John McCall                      e->getType(), lvalue.getTBAAInfo());
2409f85e193739c953358c865005855253af4f68a497John McCall    EmitARCRelease(oldValue, /*precise*/ false);
2410f85e193739c953358c865005855253af4f68a497John McCall  } else {
2411545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    value = EmitARCStoreStrong(lvalue, value, ignored);
2412f85e193739c953358c865005855253af4f68a497John McCall  }
2413f85e193739c953358c865005855253af4f68a497John McCall
2414f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2415f85e193739c953358c865005855253af4f68a497John McCall}
2416f85e193739c953358c865005855253af4f68a497John McCall
2417f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2418f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) {
2419f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = EmitARCRetainAutoreleaseScalarExpr(e->getRHS());
2420f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2421f85e193739c953358c865005855253af4f68a497John McCall
2422f85e193739c953358c865005855253af4f68a497John McCall  EmitStoreOfScalar(value, lvalue.getAddress(),
2423f85e193739c953358c865005855253af4f68a497John McCall                    lvalue.isVolatileQualified(), lvalue.getAlignment(),
2424f85e193739c953358c865005855253af4f68a497John McCall                    e->getType(), lvalue.getTBAAInfo());
2425f85e193739c953358c865005855253af4f68a497John McCall
2426f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2427f85e193739c953358c865005855253af4f68a497John McCall}
2428f85e193739c953358c865005855253af4f68a497John McCall
2429f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolStmt(
2430f85e193739c953358c865005855253af4f68a497John McCall                                             const ObjCAutoreleasePoolStmt &ARPS) {
2431f85e193739c953358c865005855253af4f68a497John McCall  const Stmt *subStmt = ARPS.getSubStmt();
2432f85e193739c953358c865005855253af4f68a497John McCall  const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
2433f85e193739c953358c865005855253af4f68a497John McCall
2434f85e193739c953358c865005855253af4f68a497John McCall  CGDebugInfo *DI = getDebugInfo();
2435f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2436f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getLBracLoc());
2437f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionStart(Builder);
2438f85e193739c953358c865005855253af4f68a497John McCall  }
2439f85e193739c953358c865005855253af4f68a497John McCall
2440f85e193739c953358c865005855253af4f68a497John McCall  // Keep track of the current cleanup stack depth.
2441f85e193739c953358c865005855253af4f68a497John McCall  RunCleanupsScope Scope(*this);
24429f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (CGM.getCodeGenOpts().ObjCRuntimeHasARC) {
2443f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCAutoreleasePoolPush();
2444f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token);
2445f85e193739c953358c865005855253af4f68a497John McCall  } else {
2446f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCMRRAutoreleasePoolPush();
2447f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token);
2448f85e193739c953358c865005855253af4f68a497John McCall  }
2449f85e193739c953358c865005855253af4f68a497John McCall
2450f85e193739c953358c865005855253af4f68a497John McCall  for (CompoundStmt::const_body_iterator I = S.body_begin(),
2451f85e193739c953358c865005855253af4f68a497John McCall       E = S.body_end(); I != E; ++I)
2452f85e193739c953358c865005855253af4f68a497John McCall    EmitStmt(*I);
2453f85e193739c953358c865005855253af4f68a497John McCall
2454f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2455f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getRBracLoc());
2456f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionEnd(Builder);
2457f85e193739c953358c865005855253af4f68a497John McCall  }
2458f85e193739c953358c865005855253af4f68a497John McCall}
24590c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
24600c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
24610c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// make sure it survives garbage collection until this point.
24620c24c808e4dce43e88abf2d5f98546b901bd4315John McCallvoid CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
24630c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  // We just use an inline assembly.
24640c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::FunctionType *extenderType
2465da549e8995c447542d5631b8b67fcc3a9582797aJay Foad    = llvm::FunctionType::get(VoidTy, VoidPtrTy, /*variadic*/ false);
24660c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::Value *extender
24670c24c808e4dce43e88abf2d5f98546b901bd4315John McCall    = llvm::InlineAsm::get(extenderType,
24680c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* assembly */ "",
24690c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* constraints */ "r",
24700c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* side effects */ true);
24710c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
24720c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  object = Builder.CreateBitCast(object, VoidPtrTy);
24730c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  Builder.CreateCall(extender, object)->setDoesNotThrow();
24740c24c808e4dce43e88abf2d5f98546b901bd4315John McCall}
24750c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
24762979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
2477