CGObjC.cpp revision ad346f4f678ab1c3222425641d851dc63e9dfa1a
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) {
36f85e193739c953358c865005855253af4f68a497John McCall  const 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
83ef072fd2f3347cfd857d6eb787b245b950771430John McCallRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
84ef072fd2f3347cfd857d6eb787b245b950771430John McCall                                            ReturnValueSlot Return) {
858fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Only the lookup mechanism and first two arguments of the method
868fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // implementation vary between runtimes.  We can get the receiver and
878fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // arguments in generic code.
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89f85e193739c953358c865005855253af4f68a497John McCall  bool isDelegateInit = E->isDelegateInitCall();
90f85e193739c953358c865005855253af4f68a497John McCall
91f85e193739c953358c865005855253af4f68a497John McCall  // We don't retain the receiver in delegate init calls, and this is
92f85e193739c953358c865005855253af4f68a497John McCall  // safe because the receiver value is always loaded from 'self',
93f85e193739c953358c865005855253af4f68a497John McCall  // which we zero out.  We don't want to Block_copy block receivers,
94f85e193739c953358c865005855253af4f68a497John McCall  // though.
95f85e193739c953358c865005855253af4f68a497John McCall  bool retainSelf =
96f85e193739c953358c865005855253af4f68a497John McCall    (!isDelegateInit &&
97f85e193739c953358c865005855253af4f68a497John McCall     CGM.getLangOptions().ObjCAutoRefCount &&
98f85e193739c953358c865005855253af4f68a497John McCall     E->getMethodDecl() &&
99f85e193739c953358c865005855253af4f68a497John McCall     E->getMethodDecl()->hasAttr<NSConsumesSelfAttr>());
100f85e193739c953358c865005855253af4f68a497John McCall
101208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
1028fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  bool isSuperMessage = false;
103f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  bool isClassMessage = false;
104c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall  ObjCInterfaceDecl *OID = 0;
1058fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Find the receiver
106926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  QualType ReceiverType;
1070b647a6ea18151149d624ab373e6fe0e819e4a9aDaniel Dunbar  llvm::Value *Receiver = 0;
10804badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  switch (E->getReceiverKind()) {
10904badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::Instance:
110926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getInstanceReceiver()->getType();
111f85e193739c953358c865005855253af4f68a497John McCall    if (retainSelf) {
112f85e193739c953358c865005855253af4f68a497John McCall      TryEmitResult ter = tryEmitARCRetainScalarExpr(*this,
113f85e193739c953358c865005855253af4f68a497John McCall                                                   E->getInstanceReceiver());
114f85e193739c953358c865005855253af4f68a497John McCall      Receiver = ter.getPointer();
115f85e193739c953358c865005855253af4f68a497John McCall      if (!ter.getInt())
116f85e193739c953358c865005855253af4f68a497John McCall        Receiver = EmitARCRetainNonBlock(Receiver);
117f85e193739c953358c865005855253af4f68a497John McCall    } else
118f85e193739c953358c865005855253af4f68a497John McCall      Receiver = EmitScalarExpr(E->getInstanceReceiver());
11904badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
12104badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::Class: {
122926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getClassReceiver();
123926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    const ObjCObjectType *ObjTy = ReceiverType->getAs<ObjCObjectType>();
1243031c63f7b5b09d5f64609fa7a1922a05b520fa7John McCall    assert(ObjTy && "Invalid Objective-C class message send");
1253031c63f7b5b09d5f64609fa7a1922a05b520fa7John McCall    OID = ObjTy->getInterface();
1263031c63f7b5b09d5f64609fa7a1922a05b520fa7John McCall    assert(OID && "Invalid Objective-C class message send");
127c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall    Receiver = Runtime.GetClass(Builder, OID);
128f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    isClassMessage = true;
129f85e193739c953358c865005855253af4f68a497John McCall
130f85e193739c953358c865005855253af4f68a497John McCall    if (retainSelf)
131f85e193739c953358c865005855253af4f68a497John McCall      Receiver = EmitARCRetainNonBlock(Receiver);
13204badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
13304badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  }
13404badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor
13504badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::SuperInstance:
136926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getSuperType();
13704badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    Receiver = LoadObjCSelf();
1388fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    isSuperMessage = true;
139f85e193739c953358c865005855253af4f68a497John McCall
140f85e193739c953358c865005855253af4f68a497John McCall    if (retainSelf)
141f85e193739c953358c865005855253af4f68a497John McCall      Receiver = EmitARCRetainNonBlock(Receiver);
14204badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
14304badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor
14404badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor  case ObjCMessageExpr::SuperClass:
145926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    ReceiverType = E->getSuperType();
1468fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    Receiver = LoadObjCSelf();
14704badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    isSuperMessage = true;
14804badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    isClassMessage = true;
149f85e193739c953358c865005855253af4f68a497John McCall
150f85e193739c953358c865005855253af4f68a497John McCall    if (retainSelf)
151f85e193739c953358c865005855253af4f68a497John McCall      Receiver = EmitARCRetainNonBlock(Receiver);
15204badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor    break;
1538fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
1548fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
155f85e193739c953358c865005855253af4f68a497John McCall  QualType ResultType =
156f85e193739c953358c865005855253af4f68a497John McCall    E->getMethodDecl() ? E->getMethodDecl()->getResultType() : E->getType();
157f85e193739c953358c865005855253af4f68a497John McCall
15819cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  CallArgList Args;
159131038e2125d98f1be0d9cb62561a7cede41bb44Anders Carlsson  EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end());
1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
161f85e193739c953358c865005855253af4f68a497John McCall  // For delegate init calls in ARC, do an unsafe store of null into
162f85e193739c953358c865005855253af4f68a497John McCall  // self.  This represents the call taking direct ownership of that
163f85e193739c953358c865005855253af4f68a497John McCall  // value.  We have to do this after emitting the other call
164f85e193739c953358c865005855253af4f68a497John McCall  // arguments because they might also reference self, but we don't
165f85e193739c953358c865005855253af4f68a497John McCall  // have to worry about any of them modifying self because that would
166f85e193739c953358c865005855253af4f68a497John McCall  // be an undefined read and write of an object in unordered
167f85e193739c953358c865005855253af4f68a497John McCall  // expressions.
168f85e193739c953358c865005855253af4f68a497John McCall  if (isDelegateInit) {
169f85e193739c953358c865005855253af4f68a497John McCall    assert(getLangOptions().ObjCAutoRefCount &&
170f85e193739c953358c865005855253af4f68a497John McCall           "delegate init calls should only be marked in ARC");
171f85e193739c953358c865005855253af4f68a497John McCall
172f85e193739c953358c865005855253af4f68a497John McCall    // Do an unsafe store of null into self.
173f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *selfAddr =
174f85e193739c953358c865005855253af4f68a497John McCall      LocalDeclMap[cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()];
175f85e193739c953358c865005855253af4f68a497John McCall    assert(selfAddr && "no self entry for a delegate init call?");
176f85e193739c953358c865005855253af4f68a497John McCall
177f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(getNullForVariable(selfAddr), selfAddr);
178f85e193739c953358c865005855253af4f68a497John McCall  }
1797e70fb217dcdf96faf34df3e197c3831c86f8089Anders Carlsson
180926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  RValue result;
1818fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  if (isSuperMessage) {
1829384c768e93f270118a30ce96546083a666da284Chris Lattner    // super is only valid in an Objective-C method
1839384c768e93f270118a30ce96546083a666da284Chris Lattner    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
1847ce77920a35060f1c8dd72e541e42ce296ccd168Fariborz Jahanian    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
185926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    result = Runtime.GenerateMessageSendSuper(*this, Return, ResultType,
186926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              E->getSelector(),
187926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              OMD->getClassInterface(),
188926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              isCategoryImpl,
189926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              Receiver,
190926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              isClassMessage,
191926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              Args,
192926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                              E->getMethodDecl());
193926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  } else {
194926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    result = Runtime.GenerateMessageSend(*this, Return, ResultType,
195926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                         E->getSelector(),
196926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                         Receiver, Args, OID,
197926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                         E->getMethodDecl());
1988fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
199f85e193739c953358c865005855253af4f68a497John McCall
200f85e193739c953358c865005855253af4f68a497John McCall  // For delegate init calls in ARC, implicitly store the result of
201f85e193739c953358c865005855253af4f68a497John McCall  // the call back into self.  This takes ownership of the value.
202f85e193739c953358c865005855253af4f68a497John McCall  if (isDelegateInit) {
203f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *selfAddr =
204f85e193739c953358c865005855253af4f68a497John McCall      LocalDeclMap[cast<ObjCMethodDecl>(CurCodeDecl)->getSelfDecl()];
205f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *newSelf = result.getScalarVal();
206f85e193739c953358c865005855253af4f68a497John McCall
207f85e193739c953358c865005855253af4f68a497John McCall    // The delegate return type isn't necessarily a matching type; in
208f85e193739c953358c865005855253af4f68a497John McCall    // fact, it's quite likely to be 'id'.
209f85e193739c953358c865005855253af4f68a497John McCall    const llvm::Type *selfTy =
210f85e193739c953358c865005855253af4f68a497John McCall      cast<llvm::PointerType>(selfAddr->getType())->getElementType();
211f85e193739c953358c865005855253af4f68a497John McCall    newSelf = Builder.CreateBitCast(newSelf, selfTy);
212f85e193739c953358c865005855253af4f68a497John McCall
213f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(newSelf, selfAddr);
214f85e193739c953358c865005855253af4f68a497John McCall  }
215f85e193739c953358c865005855253af4f68a497John McCall
216926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return AdjustRelatedResultType(*this, E, E->getMethodDecl(), result);
2175508518a2702b00be3b15a26d772bde968972f54Anders Carlsson}
2185508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
219f85e193739c953358c865005855253af4f68a497John McCallnamespace {
220f85e193739c953358c865005855253af4f68a497John McCallstruct FinishARCDealloc : EHScopeStack::Cleanup {
221ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall  void Emit(CodeGenFunction &CGF, Flags flags) {
222f85e193739c953358c865005855253af4f68a497John McCall    const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CGF.CurCodeDecl);
223f85e193739c953358c865005855253af4f68a497John McCall    const ObjCImplementationDecl *impl
224f85e193739c953358c865005855253af4f68a497John McCall      = cast<ObjCImplementationDecl>(method->getDeclContext());
225f85e193739c953358c865005855253af4f68a497John McCall    const ObjCInterfaceDecl *iface = impl->getClassInterface();
226f85e193739c953358c865005855253af4f68a497John McCall    if (!iface->getSuperClass()) return;
227f85e193739c953358c865005855253af4f68a497John McCall
228f85e193739c953358c865005855253af4f68a497John McCall    // Call [super dealloc] if we have a superclass.
229f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *self = CGF.LoadObjCSelf();
230f85e193739c953358c865005855253af4f68a497John McCall
231f85e193739c953358c865005855253af4f68a497John McCall    CallArgList args;
232f85e193739c953358c865005855253af4f68a497John McCall    CGF.CGM.getObjCRuntime().GenerateMessageSendSuper(CGF, ReturnValueSlot(),
233f85e193739c953358c865005855253af4f68a497John McCall                                                      CGF.getContext().VoidTy,
234f85e193739c953358c865005855253af4f68a497John McCall                                                      method->getSelector(),
235f85e193739c953358c865005855253af4f68a497John McCall                                                      iface,
236f85e193739c953358c865005855253af4f68a497John McCall                                                      /*is category*/ false,
237f85e193739c953358c865005855253af4f68a497John McCall                                                      self,
238f85e193739c953358c865005855253af4f68a497John McCall                                                      /*is class msg*/ false,
239f85e193739c953358c865005855253af4f68a497John McCall                                                      args,
240f85e193739c953358c865005855253af4f68a497John McCall                                                      method);
241f85e193739c953358c865005855253af4f68a497John McCall  }
242f85e193739c953358c865005855253af4f68a497John McCall};
243f85e193739c953358c865005855253af4f68a497John McCall}
244f85e193739c953358c865005855253af4f68a497John McCall
245af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
246af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// the LLVM function and sets the other context used by
247af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// CodeGenFunction.
248679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanianvoid CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
2498d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel                                      const ObjCContainerDecl *CD,
2508d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel                                      SourceLocation StartLoc) {
251d26bc76c98006609002d9930f8840490e88ac5b5John McCall  FunctionArgList args;
2524800ea6ff8017cf803c32a5fd63b94c0614014e3Devang Patel  // Check if we should generate debug info for this method.
253aa11289f754d220c9c155b68a4f84cdcfcefef6aDevang Patel  if (CGM.getModuleDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
254aa11289f754d220c9c155b68a4f84cdcfcefef6aDevang Patel    DebugInfo = CGM.getModuleDebugInfo();
2554800ea6ff8017cf803c32a5fd63b94c0614014e3Devang Patel
256679a502d462ef819e6175b58e255ca3f3391e7cfFariborz Jahanian  llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
257f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar
2580e4f40e1bbc4dce16bbb9870300a435419f1b3d5Daniel Dunbar  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
2590e4f40e1bbc4dce16bbb9870300a435419f1b3d5Daniel Dunbar  CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
2604111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
261d26bc76c98006609002d9930f8840490e88ac5b5John McCall  args.push_back(OMD->getSelfDecl());
262d26bc76c98006609002d9930f8840490e88ac5b5John McCall  args.push_back(OMD->getCmdDecl());
2634111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
26489951a86b594513c2a013532ed45d197413b1087Chris Lattner  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
26589951a86b594513c2a013532ed45d197413b1087Chris Lattner       E = OMD->param_end(); PI != E; ++PI)
266d26bc76c98006609002d9930f8840490e88ac5b5John McCall    args.push_back(*PI);
267b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
26814110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne  CurGD = OMD;
26914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne
2708d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartFunction(OMD, OMD->getResultType(), Fn, FI, args, StartLoc);
271f85e193739c953358c865005855253af4f68a497John McCall
272f85e193739c953358c865005855253af4f68a497John McCall  // In ARC, certain methods get an extra cleanup.
273f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount &&
274f85e193739c953358c865005855253af4f68a497John McCall      OMD->isInstanceMethod() &&
275f85e193739c953358c865005855253af4f68a497John McCall      OMD->getSelector().isUnarySelector()) {
276f85e193739c953358c865005855253af4f68a497John McCall    const IdentifierInfo *ident =
277f85e193739c953358c865005855253af4f68a497John McCall      OMD->getSelector().getIdentifierInfoForSlot(0);
278f85e193739c953358c865005855253af4f68a497John McCall    if (ident->isStr("dealloc"))
279f85e193739c953358c865005855253af4f68a497John McCall      EHStack.pushCleanup<FinishARCDealloc>(getARCCleanupKind());
280f85e193739c953358c865005855253af4f68a497John McCall  }
281af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
282af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
283f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
284f85e193739c953358c865005855253af4f68a497John McCall                                              LValue lvalue, QualType type);
285f85e193739c953358c865005855253af4f68a497John McCall
2862846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanianvoid CodeGenFunction::GenerateObjCGetterBody(ObjCIvarDecl *Ivar,
2872846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                             bool IsAtomic, bool IsStrong) {
2882846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
2892846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                Ivar, 0);
2902846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *GetCopyStructFn =
2912846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CGM.getObjCRuntime().GetGetStructFunction();
2922846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CodeGenTypes &Types = CGM.getTypes();
2932846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // objc_copyStruct (ReturnValue, &structIvar,
2942846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  //                  sizeof (Type of Ivar), isAtomic, false);
2952846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CallArgList Args;
2960774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  RValue RV = RValue::get(Builder.CreateBitCast(ReturnValue, VoidPtrTy));
29704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
2980774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  RV = RValue::get(Builder.CreateBitCast(LV.getAddress(), VoidPtrTy));
29904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
3002846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // sizeof (Type of Ivar)
3012846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CharUnits Size =  getContext().getTypeSizeInChars(Ivar->getType());
3022846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *SizeVal =
3030774cb84719f2aea3016493a2bbd9a02aa3e0541John McCall  llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy),
3042846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         Size.getQuantity());
30504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(SizeVal), getContext().LongTy);
3062846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *isAtomic =
3072846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
3082846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         IsAtomic ? 1 : 0);
30904c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(isAtomic), getContext().BoolTy);
3102846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *hasStrong =
3112846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
3122846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         IsStrong ? 1 : 0);
31304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(hasStrong), getContext().BoolTy);
3142846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
3152846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                 FunctionType::ExtInfo()),
3162846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian           GetCopyStructFn, ReturnValueSlot(), Args);
3172846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian}
3182846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian
319af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method.  An Objective-C method is a C function with
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// its pointer, name, and types registered in the class struture.
321af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
3228d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, OMD->getClassInterface(), OMD->getLocStart());
3236fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis  EmitStmt(OMD->getBody());
3246fb0aee4f9dc261bbec72e1283ad8dc0557a6d96Argyrios Kyrtzidis  FinishFunction(OMD->getBodyRBrace());
325af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
326af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
327f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump// FIXME: I wasn't sure about the synthesis approach. If we end up generating an
328f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump// AST for the whole body we can just fall back to having a GenerateFunction
329f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump// which takes the body Stmt.
330af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
331af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter
332489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
333489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// is illegal within a category.
334fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanianvoid CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
335fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian                                         const ObjCPropertyImplDecl *PID) {
336c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
337af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
33815bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  bool IsAtomic =
33915bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
340af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
341af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate getter (empty method)");
3428d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
34315bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian
344c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  // Determine if we should use an objc_getProperty call for
345447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian  // this. Non-atomic properties are directly evaluated.
346447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian  // atomic 'copy' and 'retain' properties are also directly
347447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian  // evaluated in gc-only mode.
348c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
34915bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian      IsAtomic &&
350447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian      (PD->getSetterKind() == ObjCPropertyDecl::Copy ||
351447d7aeb9499d7ade42be7d63fa03b37b1d2fc09Fariborz Jahanian       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *GetPropertyFn =
353c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      CGM.getObjCRuntime().GetPropertyGetFunction();
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
355c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    if (!GetPropertyFn) {
356c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
357c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      FinishFunction();
358c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      return;
359c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    }
360c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
361c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
362c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // FIXME: Can't this be simpler? This might even be worse than the
363c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // corresponding gcc code.
364c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CodeGenTypes &Types = CGM.getTypes();
365c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    ValueDecl *Cmd = OMD->getCmdDecl();
366c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
367c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    QualType IdTy = getContext().getObjCIdType();
3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *SelfAsId =
369c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
370fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
371c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    llvm::Value *True =
3724a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
373c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CallArgList Args;
37404c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(SelfAsId), IdTy);
37504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(CmdVal), Cmd->getType());
37604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(Offset), getContext().getPointerDiffType());
37704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(True), getContext().BoolTy);
378e4be5a66072f7c7618071284c8d2a9c6d8e691cfDaniel Dunbar    // FIXME: We shouldn't need to get the function info here, the
379e4be5a66072f7c7618071284c8d2a9c6d8e691cfDaniel Dunbar    // runtime already should have computed it to build the function.
38004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args,
381264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                               FunctionType::ExtInfo()),
382f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson                         GetPropertyFn, ReturnValueSlot(), Args);
383c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // We need to fix the type here. Ivars with copy & retain are
384c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // always objects so we don't need to worry about complex or
385c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    // aggregates.
3861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
387c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar                                           Types.ConvertType(PD->getType())));
388c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    EmitReturnOfRValue(RV, PD->getType());
389f85e193739c953358c865005855253af4f68a497John McCall
390f85e193739c953358c865005855253af4f68a497John McCall    // objc_getProperty does an autorelease, so we should suppress ours.
391f85e193739c953358c865005855253af4f68a497John McCall    AutoreleaseResult = false;
392c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  } else {
3932846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    const llvm::Triple &Triple = getContext().Target.getTriple();
3942846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    QualType IVART = Ivar->getType();
3952846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    if (IsAtomic &&
3962846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        IVART->isScalarType() &&
3972846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (Triple.getArch() == llvm::Triple::arm ||
3982846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian         Triple.getArch() == llvm::Triple::thumb) &&
3992846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (getContext().getTypeSizeInChars(IVART)
4002846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian         > CharUnits::fromQuantity(4)) &&
4012846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        CGM.getObjCRuntime().GetGetStructFunction()) {
4022846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      GenerateObjCGetterBody(Ivar, true, false);
4032846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    }
4041d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
4051d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
4061d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86 &&
4071d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
4081d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(4)) &&
4091d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
4101d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCGetterBody(Ivar, true, false);
4111d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
4121d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
4131d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
4141d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86_64 &&
4151d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
4161d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(8)) &&
4171d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
4181d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCGetterBody(Ivar, true, false);
4191d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
4202846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    else if (IVART->isAnyComplexType()) {
42197a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
42297a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian                                    Ivar, 0);
4231b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian      ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(),
4241b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian                                               LV.isVolatileQualified());
4251b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian      StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
4261b23fe61cf4437668280212d0ad6cb7196f51529Fariborz Jahanian    }
4272846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    else if (hasAggregateLLVMType(IVART)) {
42815bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian      bool IsStrong = false;
4295fb6509b402d052aa661b15bfa5b71b7cdd7d0e9Fariborz Jahanian      if ((IsStrong = IvarTypeWithAggrGCObjects(IVART))
4300b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian          && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
4318fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall          && CGM.getObjCRuntime().GetGetStructFunction()) {
4322846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        GenerateObjCGetterBody(Ivar, IsAtomic, IsStrong);
4330b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian      }
43497a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian      else {
43501cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian        const CXXRecordDecl *classDecl = IVART->getAsCXXRecordDecl();
43601cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian
43701cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian        if (PID->getGetterCXXConstructor() &&
438023df37c27ee8035664fb62f206ca58f4e2a169dSean Hunt            classDecl && !classDecl->hasTrivialDefaultConstructor()) {
43997a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian          ReturnStmt *Stmt =
44097a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian            new (getContext()) ReturnStmt(SourceLocation(),
4415077c3876beeaed32280af88244e8050078619a8Douglas Gregor                                          PID->getGetterCXXConstructor(),
4425077c3876beeaed32280af88244e8050078619a8Douglas Gregor                                          0);
44397a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian          EmitReturnStmt(*Stmt);
4441d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian        } else if (IsAtomic &&
4451d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   !IVART->isAnyComplexType() &&
4461d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   Triple.getArch() == llvm::Triple::x86 &&
4471d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   (getContext().getTypeSizeInChars(IVART)
4481d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                    > CharUnits::fromQuantity(4)) &&
4491d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                   CGM.getObjCRuntime().GetGetStructFunction()) {
4501d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          GenerateObjCGetterBody(Ivar, true, false);
4511d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian        }
4521d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian        else if (IsAtomic &&
4531d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 !IVART->isAnyComplexType() &&
4541d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 Triple.getArch() == llvm::Triple::x86_64 &&
4551d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 (getContext().getTypeSizeInChars(IVART)
4561d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                  > CharUnits::fromQuantity(8)) &&
4571d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian                 CGM.getObjCRuntime().GetGetStructFunction()) {
4581d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          GenerateObjCGetterBody(Ivar, true, false);
45997a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian        }
46097a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian        else {
46197a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian          LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
46297a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian                                        Ivar, 0);
4632846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian          EmitAggregateCopy(ReturnValue, LV.getAddress(), IVART);
46497a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian        }
46597a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian      }
4662846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    }
4672846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    else {
4682846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),
469545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall                                      Ivar, 0);
470f85e193739c953358c865005855253af4f68a497John McCall        QualType propType = PD->getType();
471f85e193739c953358c865005855253af4f68a497John McCall
472f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *value;
473f85e193739c953358c865005855253af4f68a497John McCall        if (propType->isReferenceType()) {
474f85e193739c953358c865005855253af4f68a497John McCall          value = LV.getAddress();
475f85e193739c953358c865005855253af4f68a497John McCall        } else {
476f85e193739c953358c865005855253af4f68a497John McCall          // In ARC, we want to emit this retained.
477f85e193739c953358c865005855253af4f68a497John McCall          if (getLangOptions().ObjCAutoRefCount &&
478f85e193739c953358c865005855253af4f68a497John McCall              PD->getType()->isObjCRetainableType())
479f85e193739c953358c865005855253af4f68a497John McCall            value = emitARCRetainLoadOfScalar(*this, LV, IVART);
480f85e193739c953358c865005855253af4f68a497John McCall          else
481545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall            value = EmitLoadOfLValue(LV).getScalarVal();
482f85e193739c953358c865005855253af4f68a497John McCall
483f85e193739c953358c865005855253af4f68a497John McCall          value = Builder.CreateBitCast(value, ConvertType(propType));
48414086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian        }
485f85e193739c953358c865005855253af4f68a497John McCall
486f85e193739c953358c865005855253af4f68a497John McCall        EmitReturnOfRValue(RValue::get(value), propType);
487ed1d29d62595a83ccf6ef23eb2759d355206df2eFariborz Jahanian    }
488c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
489af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
490af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
491af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
492af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
4932846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanianvoid CodeGenFunction::GenerateObjCAtomicSetterBody(ObjCMethodDecl *OMD,
4942846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                                   ObjCIvarDecl *Ivar) {
4952846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // objc_copyStruct (&structIvar, &Arg,
4962846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  //                  sizeof (struct something), true, false);
4972846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *GetCopyStructFn =
4982846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CGM.getObjCRuntime().GetSetStructFunction();
4992846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CodeGenTypes &Types = CGM.getTypes();
5002846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CallArgList Args;
5012846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
5022846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  RValue RV =
5032846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    RValue::get(Builder.CreateBitCast(LV.getAddress(),
5042846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                Types.ConvertType(getContext().VoidPtrTy)));
50504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
5062846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
5072846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *ArgAsPtrTy =
5082846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  Builder.CreateBitCast(Arg,
5092846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                      Types.ConvertType(getContext().VoidPtrTy));
5102846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  RV = RValue::get(ArgAsPtrTy);
51104c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RV, getContext().VoidPtrTy);
5122846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  // sizeof (Type of Ivar)
5132846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  CharUnits Size =  getContext().getTypeSizeInChars(Ivar->getType());
5142846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *SizeVal =
5152846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy),
5162846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                         Size.getQuantity());
51704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(SizeVal), getContext().LongTy);
5182846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *True =
5192846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
52004c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(True), getContext().BoolTy);
5212846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::Value *False =
5222846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
52304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(False), getContext().BoolTy);
5242846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian  EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
5252846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                 FunctionType::ExtInfo()),
5262846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian           GetCopyStructFn, ReturnValueSlot(), Args);
5272846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian}
5282846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian
52901cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanianstatic bool
53001cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz JahanianIvarAssignHasTrvialAssignment(const ObjCPropertyImplDecl *PID,
53101cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian                              QualType IvarT) {
53201cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  bool HasTrvialAssignment = true;
53301cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  if (PID->getSetterCXXAssignment()) {
53401cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian    const CXXRecordDecl *classDecl = IvarT->getAsCXXRecordDecl();
53501cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian    HasTrvialAssignment =
53601cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian      (!classDecl || classDecl->hasTrivialCopyAssignment());
53701cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  }
53801cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian  return HasTrvialAssignment;
53901cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian}
54001cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian
541af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCSetter - Generate an Objective-C property setter
542489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
543489034cf8bde09360e0089f401b2929597b125d8Steve Naroff/// is illegal within a category.
544fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanianvoid CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
545fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian                                         const ObjCPropertyImplDecl *PID) {
54686957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
547af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
548af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
549af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate setter (empty method)");
5508d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
5511d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian  const llvm::Triple &Triple = getContext().Target.getTriple();
5521d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian  QualType IVART = Ivar->getType();
55386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
5541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool IsAtomic =
55586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
55686957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar
55786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // Determine if we should use an objc_setProperty call for
55886957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // this. Properties with 'copy' semantics always use it, as do
55986957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // non-atomic properties with 'release' semantics as long as we are
56086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  // not in gc-only mode.
56186957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  if (IsCopy ||
56286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
56386957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
5641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *SetPropertyFn =
56586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      CGM.getObjCRuntime().GetPropertySetFunction();
5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
56786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    if (!SetPropertyFn) {
56886957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
56986957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      FinishFunction();
57086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      return;
57186957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    }
5721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // Emit objc_setProperty((id) self, _cmd, offset, arg,
57486957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    //                       <is-atomic>, <is-copy>).
57586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    // FIXME: Can't this be simpler? This might even be worse than the
57686957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    // corresponding gcc code.
57786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    CodeGenTypes &Types = CGM.getTypes();
57886957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    ValueDecl *Cmd = OMD->getCmdDecl();
57986957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
58086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    QualType IdTy = getContext().getObjCIdType();
5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *SelfAsId =
58286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
583fef30b55230064d334a669a065a1c9acdb87cdfeFariborz Jahanian    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
58489951a86b594513c2a013532ed45d197413b1087Chris Lattner    llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
5851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    llvm::Value *ArgAsId =
58686957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar      Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
58786957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar                            Types.ConvertType(IdTy));
58886957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    llvm::Value *True =
5894a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
59086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    llvm::Value *False =
5914a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
59286957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar    CallArgList Args;
59304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(SelfAsId), IdTy);
59404c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(CmdVal), Cmd->getType());
59504c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(Offset), getContext().getPointerDiffType());
59604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(ArgAsId), IdTy);
59704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(IsAtomic ? True : False),  getContext().BoolTy);
59804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman    Args.add(RValue::get(IsCopy ? True : False), getContext().BoolTy);
599f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // FIXME: We shouldn't need to get the function info here, the runtime
600f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump    // already should have computed it to build the function.
60104a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
602264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                   FunctionType::ExtInfo()),
603264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola             SetPropertyFn,
604f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson             ReturnValueSlot(), Args);
6051d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian  } else if (IsAtomic && hasAggregateLLVMType(IVART) &&
6061d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             !IVART->isAnyComplexType() &&
60701cb307f0b84a368cdbc0738d6680aab8ed7423fFariborz Jahanian             IvarAssignHasTrvialAssignment(PID, IVART) &&
6081d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             ((Triple.getArch() == llvm::Triple::x86 &&
6091d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              (getContext().getTypeSizeInChars(IVART)
6101d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian               > CharUnits::fromQuantity(4))) ||
6111d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              (Triple.getArch() == llvm::Triple::x86_64 &&
6121d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              (getContext().getTypeSizeInChars(IVART)
6131d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian               > CharUnits::fromQuantity(8))))
6148fac25d33b13e25f512dd921d4d5a4b565f5d175David Chisnall             && CGM.getObjCRuntime().GetSetStructFunction()) {
6151d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          // objc_copyStruct (&structIvar, &Arg,
6161d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian          //                  sizeof (struct something), true, false);
6172846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    GenerateObjCAtomicSetterBody(OMD, Ivar);
61897a73cd8e2b81f5aed9f59e07e7787e3fd3b8d00Fariborz Jahanian  } else if (PID->getSetterCXXAssignment()) {
6192a41637a995affa1563f4d82a8b026e326a2faa0John McCall    EmitIgnoredExpr(PID->getSetterCXXAssignment());
62086957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  } else {
6212846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    if (IsAtomic &&
6222846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        IVART->isScalarType() &&
6232846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (Triple.getArch() == llvm::Triple::arm ||
6242846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian         Triple.getArch() == llvm::Triple::thumb) &&
6252846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        (getContext().getTypeSizeInChars(IVART)
6262846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian          > CharUnits::fromQuantity(4)) &&
6272846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        CGM.getObjCRuntime().GetGetStructFunction()) {
6282846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      GenerateObjCAtomicSetterBody(OMD, Ivar);
6291d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
6301d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
6311d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
6321d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86 &&
6331d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
6341d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(4)) &&
6351d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
6361d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCAtomicSetterBody(OMD, Ivar);
6371d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    }
6381d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian    else if (IsAtomic &&
6391d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
6401d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             Triple.getArch() == llvm::Triple::x86_64 &&
6411d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             (getContext().getTypeSizeInChars(IVART)
6421d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian              > CharUnits::fromQuantity(8)) &&
6431d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian             CGM.getObjCRuntime().GetGetStructFunction()) {
6441d3a61a5ab0952ebf1f829bd2e48bc09bb332189Fariborz Jahanian      GenerateObjCAtomicSetterBody(OMD, Ivar);
6452846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    }
6462846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian    else {
6472846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      // FIXME: Find a clean way to avoid AST node creation.
6488d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel      SourceLocation Loc = PID->getLocStart();
6492846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ValueDecl *Self = OMD->getSelfDecl();
6502846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
6512846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      DeclRefExpr Base(Self, Self->getType(), VK_RValue, Loc);
6522846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ParmVarDecl *ArgDecl = *OMD->param_begin();
65314086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian      QualType T = ArgDecl->getType();
65414086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian      if (T->isReferenceType())
65514086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian        T = cast<ReferenceType>(T)->getPointeeType();
65614086764e340267e17803d0f8243070ffae2c76eFariborz Jahanian      DeclRefExpr Arg(ArgDecl, T, VK_LValue, Loc);
6572846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true);
65845e8423d7dcea657c14c55347e8a30ac904d7501Daniel Dunbar
6592846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      // The property type can differ from the ivar type in some situations with
6602846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      // Objective-C pointer types, we can always bit cast the RHS in these cases.
6612846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      if (getContext().getCanonicalType(Ivar->getType()) !=
6622846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian          getContext().getCanonicalType(ArgDecl->getType())) {
6632846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        ImplicitCastExpr ArgCasted(ImplicitCastExpr::OnStack,
6642846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                   Ivar->getType(), CK_BitCast, &Arg,
6652846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                                   VK_RValue);
6662846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        BinaryOperator Assign(&IvarRef, &ArgCasted, BO_Assign,
6672846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                              Ivar->getType(), VK_RValue, OK_Ordinary, Loc);
6682846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        EmitStmt(&Assign);
6692846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      } else {
6702846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        BinaryOperator Assign(&IvarRef, &Arg, BO_Assign,
6712846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian                              Ivar->getType(), VK_RValue, OK_Ordinary, Loc);
6722846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian        EmitStmt(&Assign);
6732846b97965e980ad2e7c8d444b82cc21d733a699Fariborz Jahanian      }
67445e8423d7dcea657c14c55347e8a30ac904d7501Daniel Dunbar    }
67586957eb200492e95a09bce1b2c76f66345468f84Daniel Dunbar  }
676af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
677af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
6784111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
6794111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
680e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallnamespace {
6819928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  struct DestroyIvar : EHScopeStack::Cleanup {
6829928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  private:
6839928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    llvm::Value *addr;
684e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    const ObjCIvarDecl *ivar;
6859928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer &destroyer;
6869928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    bool useEHCleanupForArray;
6879928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  public:
6889928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    DestroyIvar(llvm::Value *addr, const ObjCIvarDecl *ivar,
6899928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                CodeGenFunction::Destroyer *destroyer,
6909928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                bool useEHCleanupForArray)
6919928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      : addr(addr), ivar(ivar), destroyer(*destroyer),
6929928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        useEHCleanupForArray(useEHCleanupForArray) {}
693e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
694ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
6959928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      LValue lvalue
6969928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall        = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0);
6979928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      CGF.emitDestroy(lvalue.getAddress(), ivar->getType(), destroyer,
698ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall                      flags.isForNormalCleanup() && useEHCleanupForArray);
699e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
700e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  };
701e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
702e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
7039928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall/// Like CodeGenFunction::destroyARCStrong, but do it with a call.
7049928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCallstatic void destroyARCStrongWithStore(CodeGenFunction &CGF,
7059928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      llvm::Value *addr,
7069928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                      QualType type) {
7079928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  llvm::Value *null = getNullForVariable(addr);
7089928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall  CGF.EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
7099928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall}
710f85e193739c953358c865005855253af4f68a497John McCall
711e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCallstatic void emitCXXDestructMethod(CodeGenFunction &CGF,
712e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall                                  ObjCImplementationDecl *impl) {
713e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  CodeGenFunction::RunCleanupsScope scope(CGF);
714e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
715e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  llvm::Value *self = CGF.LoadObjCSelf();
716e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
717e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  ObjCInterfaceDecl *iface
718e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    = const_cast<ObjCInterfaceDecl*>(impl->getClassInterface());
719e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
720e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall       ivar; ivar = ivar->getNextIvar()) {
721e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    QualType type = ivar->getType();
722e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
723e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    // Check whether the ivar is a destructible type.
7249928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    QualType::DestructionKind dtorKind = type.isDestructedType();
7259928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (!dtorKind) continue;
7269928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7279928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CodeGenFunction::Destroyer *destroyer = 0;
7289928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7299928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Use a call to objc_storeStrong to destroy strong ivars, for the
7309928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // general benefit of the tools.
7319928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    if (dtorKind == QualType::DK_objc_strong_lifetime) {
7329928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &destroyARCStrongWithStore;
7339928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7349928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    // Otherwise use the default for the destruction kind.
7359928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    } else {
7369928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall      destroyer = &CGF.getDestroyer(dtorKind);
737e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    }
7389928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7399928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CleanupKind cleanupKind = CGF.getCleanupKind(dtorKind);
7409928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall
7419928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall    CGF.EHStack.pushCleanup<DestroyIvar>(cleanupKind, self, ivar, destroyer,
7429928c4805aa8d5fabd488d0d0c5aeb64fd50f0e3John McCall                                         cleanupKind & EHCleanup);
743e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  }
744e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
745e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
746e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall}
747e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
748109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanianvoid CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
749109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 ObjCMethodDecl *MD,
750109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian                                                 bool ctor) {
751109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
7528d3f8979e46f9d0b8735566eabe471db0e1e0e53Devang Patel  StartObjCMethod(MD, IMP->getClassInterface(), MD->getLocStart());
753e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
754e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_construct.
755109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  if (ctor) {
756f85e193739c953358c865005855253af4f68a497John McCall    // Suppress the final autorelease in ARC.
757f85e193739c953358c865005855253af4f68a497John McCall    AutoreleaseResult = false;
758f85e193739c953358c865005855253af4f68a497John McCall
759e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    llvm::SmallVector<CXXCtorInitializer *, 8> IvarInitializers;
760e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
761e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall           E = IMP->init_end(); B != E; ++B) {
762e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall      CXXCtorInitializer *IvarInit = (*B);
76300eb3f9c5b33e3d99aee1f8b75dd9c9678fdd66bFrancois Pichet      FieldDecl *Field = IvarInit->getAnyMember();
764109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
7659b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian      LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
7669b4d4fc49f30f1caa35d680702f1921afad81971Fariborz Jahanian                                    LoadObjCSelf(), Ivar, 0);
767558d2abc7f9fd6801cc7677200992313ae90b5d8John McCall      EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, true));
768109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    }
769109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    // constructor returns 'self'.
770109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    CodeGenTypes &Types = CGM.getTypes();
771109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    QualType IdTy(CGM.getContext().getObjCIdType());
772109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    llvm::Value *SelfAsId =
773109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
774109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
775e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall
776e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall  // Emit .cxx_destruct.
777bc397cf90355f17c974b0bdf3960e8fb38caf5d6Chandler Carruth  } else {
778e81ac69c5da9fadfac33ee76e98d5fb558c4e389John McCall    emitCXXDestructMethod(*this, IMP);
779109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  }
780109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian  FinishFunction();
781109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian}
782109dfc6ca6652f60c55ed0f2631aebf323d0200dFariborz Jahanian
7830b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanianbool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
7840b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
7850b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  it++; it++;
7860b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  const ABIArgInfo &AI = it->info;
7870b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  // FIXME. Is this sufficient check?
7880b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian  return (AI.getKind() == ABIArgInfo::Indirect);
7890b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian}
7900b2bd47151ee9205ad6c66d1ffb921918106088aFariborz Jahanian
79115bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanianbool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
79215bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
79315bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return false;
79415bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
79515bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian    return FDTTy->getDecl()->hasObjectMember();
79615bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian  return false;
79715bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian}
79815bd58842adaa4f8cca4e58047ed18e033858d9bFariborz Jahanian
799c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf() {
800b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
801b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
8024111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
8034111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
80445012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz JahanianQualType CodeGenFunction::TypeOfSelfObject() {
80545012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
80645012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
80714108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
80814108da7f7fc059772711e4ffee1322a27b152a7Steve Naroff    getContext().getCanonicalType(selfDecl->getType()));
80945012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian  return PTy->getPointeeType();
81045012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian}
81145012a7ef5abf1042c893f3f2fa5c23cb5485ea9Fariborz Jahanian
812e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallLValue
813e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallCodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
814e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // This is a special l-value that just issues sends when we load or
815e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // store through it.
816e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
817e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // For certain base kinds, we need to emit the base immediately.
818e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Base;
819e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  if (E->isSuperReceiver())
820e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = LoadObjCSelf();
821e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else if (E->isClassReceiver())
822e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver());
823e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  else
824e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    Base = EmitScalarExpr(E->getBase());
825e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return LValue::MakePropertyRef(E, Base);
826e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall}
827e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
828e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCallstatic RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
829e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       ReturnValueSlot Return,
830e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       QualType ResultType,
831e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       Selector S,
832e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       llvm::Value *Receiver,
833e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                       const CallArgList &CallArgs) {
834e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl);
835f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isClassMessage = OMD->isClassMethod();
836f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
837e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  return CGF.CGM.getObjCRuntime()
838e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                .GenerateMessageSendSuper(CGF, Return, ResultType,
839e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          S, OMD->getClassInterface(),
840e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isCategoryImpl, Receiver,
841e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                          isClassMessage, CallArgs);
842f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian}
843f469557743f77918d2ca8226e2ee2888998ffd4aFariborz Jahanian
844119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallRValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
845119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                    ReturnValueSlot Return) {
846119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr();
84768af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ResultType = E->getGetterResultType();
84812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S;
849926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  const ObjCMethodDecl *method;
85012f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isExplicitProperty()) {
85112f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    const ObjCPropertyDecl *Property = E->getExplicitProperty();
85212f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    S = Property->getGetterName();
853926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = Property->getGetterMethodDecl();
854b3589f44c5d295cd41de2c83f3475116835eeebdMike Stump  } else {
855926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    method = E->getImplicitPropertyGetter();
856926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    S = method->getSelector();
8575daf570d0ce027e18ed5f9d66e6b2a14a40b720dFariborz Jahanian  }
85812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
859e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = LV.getPropertyRefBaseAddr();
860e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
861f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount) {
862f85e193739c953358c865005855253af4f68a497John McCall    QualType receiverType;
863f85e193739c953358c865005855253af4f68a497John McCall    if (E->isSuperReceiver())
864f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getSuperReceiverType();
865f85e193739c953358c865005855253af4f68a497John McCall    else if (E->isClassReceiver())
866f85e193739c953358c865005855253af4f68a497John McCall      receiverType = getContext().getObjCClassType();
867f85e193739c953358c865005855253af4f68a497John McCall    else
868f85e193739c953358c865005855253af4f68a497John McCall      receiverType = E->getBase()->getType();
869f85e193739c953358c865005855253af4f68a497John McCall  }
870f85e193739c953358c865005855253af4f68a497John McCall
871e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  // Accesses to 'super' follow a different code path.
87212f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver())
873926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor    return AdjustRelatedResultType(*this, E, method,
874926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                   GenerateMessageSendSuper(*this, Return,
875926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            ResultType,
876926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            S, Receiver,
877926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor                                                            CallArgList()));
878119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
879119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
880926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor  return AdjustRelatedResultType(*this, E, method,
881f85e193739c953358c865005855253af4f68a497John McCall          CGM.getObjCRuntime().
882f85e193739c953358c865005855253af4f68a497John McCall             GenerateMessageSend(*this, Return, ResultType, S,
883f85e193739c953358c865005855253af4f68a497John McCall                                 Receiver, CallArgList(), ReceiverClass));
8849c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar}
8859c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
886119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCallvoid CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
887119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall                                                        LValue Dst) {
888119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr();
88912f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  Selector S = E->getSetterSelector();
89068af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian  QualType ArgType = E->getSetterArgType();
89168af13f3ca39947e3f285f864fe3b76640fddf69Fariborz Jahanian
892b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // FIXME. Other than scalars, AST is not adequate for setter and
893b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  // getter type mismatches which require conversion.
894b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  if (Src.isScalar()) {
895b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    llvm::Value *SrcVal = Src.getScalarVal();
896b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    QualType DstType = getContext().getCanonicalType(ArgType);
897b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    const llvm::Type *DstTy = ConvertType(DstType);
898b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian    if (SrcVal->getType() != DstTy)
899b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian      Src =
900b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian        RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType));
901b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian  }
902b19c76e857d21b722d0a207cb45b26d7cb20a73fFariborz Jahanian
903e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  CallArgList Args;
90404c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(Src, ArgType);
905e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
906e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  llvm::Value *Receiver = Dst.getPropertyRefBaseAddr();
907e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall  QualType ResultType = getContext().VoidTy;
908e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall
90912f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  if (E->isSuperReceiver()) {
910e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall    GenerateMessageSendSuper(*this, ReturnValueSlot(),
911e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                             ResultType, S, Receiver, Args);
91212f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall    return;
91312f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  }
91412f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
915119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall  const ObjCInterfaceDecl *ReceiverClass
916119a1c6c4029d30cae7b31a2826aa0ff70d01668John McCall    = (E->isClassReceiver() ? E->getClassReceiver() : 0);
91712f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall
91812f78a6741a4cb3d904340f8d3d2714568b50e7aJohn McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
919e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ResultType, S, Receiver, Args,
920e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4John McCall                                           ReceiverClass);
92185c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar}
92285c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar
92374391b48b4791cded373683a3baf67314f358d50Chris Lattnervoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
9241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Constant *EnumerationMutationFn =
925c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.getObjCRuntime().EnumerationMutationFunction();
9261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
927c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  if (!EnumerationMutationFn) {
928c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
929c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar    return;
930c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar  }
931c1cf4a579f8a0a77719deedc1b8f850b77d36ecfDaniel Dunbar
932bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  CGDebugInfo *DI = getDebugInfo();
933bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
934bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getBegin());
935bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionStart(Builder);
936bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
937bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
9389d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  // The local variable comes into scope immediately.
9399d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  AutoVarEmission variable = AutoVarEmission::invalid();
9409d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
9419d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel    variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl()));
9429d99f2db9bccc1664d6bbf1fc5346bab293ec0c3Devang Patel
943d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
944d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
9451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
946f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fast enumeration state.
947f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType StateTy = getContext().getObjCFastEnumerationStateType();
948195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
9491884eb0b5c55edda4893ddec45e7dbad79758782Anders Carlsson  EmitNullInitialization(StatePtr, StateTy);
9501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
951f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Number of elements in the items array.
9522abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  static const unsigned NumItems = 16;
9531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
954d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the countByEnumeratingWithState:objects:count: selector.
955ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  IdentifierInfo *II[] = {
956ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
957ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("objects"),
958ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    &CGM.getContext().Idents.get("count")
959ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  };
960ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer  Selector FastEnumSel =
961ad4688669579d5d7b025137a095be66936d7ea31Benjamin Kramer    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
962f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
963f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ItemsTy =
964f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    getContext().getConstantArrayType(getContext().getObjCIdType(),
9651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                      llvm::APInt(32, NumItems),
966f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ArrayType::Normal, 0);
967195337d2e5d4625ae9dc1328c7cdbc7115b0261bDaniel Dunbar  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
9681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
969d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Emit the collection pointer.
970f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Collection = EmitScalarExpr(S.getCollection());
9711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
972d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Send it our message:
973f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CallArgList Args;
974d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
975d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The first argument is a temporary of the enumeration-state type.
97604c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(StatePtr), getContext().getPointerType(StateTy));
9771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
978d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The second argument is a temporary array with space for NumItems
979d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointers.  We'll actually be loading elements from the array
980d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // pointer written into the control state; this buffer is so that
981d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // collections that *aren't* backed by arrays can still queue up
982d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // batches of elements.
98304c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy));
9841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
985d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The third argument is the capacity of that temporary array.
986f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
9874a28d5deeba33722aa009eab488591fb9055cc7eOwen Anderson  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
98804c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args.add(RValue::get(Count), getContext().UnsignedLongTy);
9891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
990d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start the enumeration.
9911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  RValue CountRV =
992ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
993f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
994f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
995c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
996f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
997d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The initial number of objects that were returned in the buffer.
998d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialBufferLimit = CountRV.getScalarVal();
9991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1000d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
1001d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
1002f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1003d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
1004f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1005d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If the limit pointer was zero to begin with, the collection is
1006d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // empty; skip all this.
1007d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
1008d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopInitBB);
10091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1010d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, initialize the loop.
1011d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopInitBB);
10121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1013d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Save the initial mutations value.  This is the value at an
1014d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // address that was written into the state object by
1015d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // countByEnumeratingWithState:objects:count:.
10161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtrPtr =
10172abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
10181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
10192abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                      "mutationsptr");
10201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1021d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *initialMutations =
1022d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations");
10231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1024d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Start looping.  This is the point we return to whenever we have a
1025d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // fresh, non-empty batch of objects.
1026d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
1027d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(LoopBodyBB);
10281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1029d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current index into the buffer.
1030bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
1031d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, LoopInitBB);
1032f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1033d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // The current buffer size.
1034bbf3bacb3e0c1ebb3e8a4a8b1330404a7e379315Jay Foad  llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
1035d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(initialBufferLimit, LoopInitBB);
1036f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1037d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether the mutations value has changed from where it was
1038d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // at start.  StateMutationsPtr should actually be invariant between
1039d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes.
10402abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
1041d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *currentMutations
1042d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateLoad(StateMutationsPtr, "statemutations");
10431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1044d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
1045361cf980a7d976ef11a37b49567412b6b63a89d7Dan Gohman  llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
10461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1047d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
1048d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       WasNotMutatedBB, WasMutatedBB);
10491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1050d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If so, call the enumeration-mutation function.
1051d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasMutatedBB);
10522abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *V =
10531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    Builder.CreateBitCast(Collection,
10542abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          ConvertType(getContext().getObjCIdType()),
10552abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          "tmp");
10562b2105e92fc77016992dae3f117f526e73af5ea9Daniel Dunbar  CallArgList Args2;
105704c9a49ee251424b11d7c4e8b1c23637684cecb6Eli Friedman  Args2.add(RValue::get(V), getContext().getObjCIdType());
1058f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // FIXME: We shouldn't need to get the function info here, the runtime already
1059f5408fe484495ee4efbdd709c8a2c2fdbbbdb328Mike Stump  // should have computed it to build the function.
106004a67a6aa3dfdc92d57f7f8d93ba397348c868a4John McCall  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
1061264ba48dc98f3f843935a485d5b086f7e0fdc4f1Rafael Espindola                                          FunctionType::ExtInfo()),
1062f3c47c9525153aea2de0ec4bd615b9cf2d81c103Anders Carlsson           EnumerationMutationFn, ReturnValueSlot(), Args2);
10631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1064d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, or if the mutation function returns, just continue.
1065d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(WasNotMutatedBB);
10661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1067d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Initialize the element variable.
1068d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  RunCleanupsScope elementVariableScope(*this);
106957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  bool elementIsVariable;
1070d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  LValue elementLValue;
1071d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  QualType elementType;
1072d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
107357b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    // Initialize the variable, in case it's a __block variable or something.
107457b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarInit(variable);
1075f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
107657b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
1077d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
1078d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                        VK_LValue, SourceLocation());
1079d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(&tempDRE);
1080d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = D->getType();
108157b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = true;
10827acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall
10837acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    if (D->isARCPseudoStrong())
10847acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall      elementLValue.getQuals().setObjCLifetime(Qualifiers::OCL_ExplicitNone);
1085d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  } else {
1086d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = LValue(); // suppress warning
1087d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementType = cast<Expr>(S.getElement())->getType();
108857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    elementIsVariable = false;
1089d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
1090d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  const llvm::Type *convertedElementType = ConvertType(elementType);
1091f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1092d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the buffer out of the enumeration state.
1093d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // TODO: this pointer should actually be invariant between
1094d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // refreshes, which would help us do certain loop optimizations.
1095d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *StateItemsPtr =
1096d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
1097d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *EnumStateItems =
1098d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateLoad(StateItemsPtr, "stateitems");
1099f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1100d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Fetch the value at the current index from the buffer.
11011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::Value *CurrentItemPtr =
1102d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr");
1103d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr);
11041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1105d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Cast that value to the right type.
1106d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
1107d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                                      "currentitem");
11081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1109d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Make sure we have an l-value.  Yes, this gets evaluated every
1110d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // time through the loop.
11117acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  if (!elementIsVariable) {
1112d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1113545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue);
11147acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  } else {
11157acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall    EmitScalarInit(CurrentItem, elementLValue);
11167acddacc921cd0b3f813443a8641eeddb82dfbd4John McCall  }
11171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
111857b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // If we do have an element variable, this assignment is the end of
111957b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  // its initialization.
112057b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (elementIsVariable)
112157b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall    EmitAutoVarCleanups(variable);
112257b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall
1123d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Perform the loop body, setting up break and continue labels.
1124e4b6d342c29d5cb9d311756100df1603810fa892Anders Carlsson  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
1125d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  {
1126d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    RunCleanupsScope Scope(*this);
1127d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    EmitStmt(S.getBody());
1128d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  }
1129f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.pop_back();
11301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1131d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Destroy the element variable now.
1132d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  elementVariableScope.ForceCleanup();
1133d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1134d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Check whether there are more elements.
1135ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(AfterBody.getBlock());
11361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1137d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
1138d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1139d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // First we check in the local buffer.
1140d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *indexPlusOne
1141d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
1142d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1143d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we haven't overrun the buffer yet, we can continue.
1144d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
1145d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       LoopBodyBB, FetchMoreBB);
1146f0906c4edb37b20141428ca77fa7dfd00b976eafFariborz Jahanian
1147d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(indexPlusOne, AfterBody.getBlock());
1148d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(count, AfterBody.getBlock());
1149f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1150d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // Otherwise, we have to fetch more elements.
1151d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(FetchMoreBB);
11521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
11531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CountRV =
1154ef072fd2f3347cfd857d6eb787b245b950771430John McCall    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1155f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
11561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                             FastEnumSel,
1157c6cd5fd3eae71f8841504a396563343cfaaf503eDavid Chisnall                                             Collection, Args);
11581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1159d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // If we got a zero count, we're done.
1160d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  llvm::Value *refetchCount = CountRV.getScalarVal();
1161d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1162d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  // (note that the message send might split FetchMoreBB)
1163d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  index->addIncoming(zero, Builder.GetInsertBlock());
1164d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  count->addIncoming(refetchCount, Builder.GetInsertBlock());
1165d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall
1166d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
1167d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall                       EmptyBB, LoopBodyBB);
11681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1169f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // No more elements.
1170d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall  EmitBlock(EmptyBB);
1171f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
117257b3b6a60856eaec30fd876a8a3face8f7e3ad7bJohn McCall  if (!elementIsVariable) {
1173f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // If the element was not a declaration, set it to be null.
1174f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1175d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
1176d88687fc8b3b6e0bce1f7cb83d347ef009ab5480John McCall    elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1177545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    EmitStoreThroughLValue(RValue::get(null), elementLValue);
1178f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
1179f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
1180bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  if (DI) {
1181bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->setLocation(S.getSourceRange().getEnd());
1182bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel    DI->EmitRegionEnd(Builder);
1183bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel  }
1184bcbd03ac0ac0890a436e1a179d3a285e914d41faDevang Patel
1185ff8e11579fc904aa4032d90d2be6ce1ac5fc9fe1John McCall  EmitBlock(LoopEnd.getBlock());
11863d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
11873d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
11881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
1189f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitTryStmt(*this, S);
119064d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
119164d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
11921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpvoid CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
119364d5d6c5903157c521af496479d06dc26032d718Anders Carlsson  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
119464d5d6c5903157c521af496479d06dc26032d718Anders Carlsson}
119564d5d6c5903157c521af496479d06dc26032d718Anders Carlsson
119610cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattnervoid CodeGenFunction::EmitObjCAtSynchronizedStmt(
11971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              const ObjCAtSynchronizedStmt &S) {
1198f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
119910cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner}
120010cac6f7115b59a466bb8d2d51cdddeb38aadc37Chris Lattner
1201f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code for a CK_ObjCProduceObject.  Just does a
1202f85e193739c953358c865005855253af4f68a497John McCall/// primitive retain.
1203f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCProduceObject(QualType type,
1204f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *value) {
1205f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetain(type, value);
1206f85e193739c953358c865005855253af4f68a497John McCall}
1207f85e193739c953358c865005855253af4f68a497John McCall
1208f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1209f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCRelease : EHScopeStack::Cleanup {
1210f85e193739c953358c865005855253af4f68a497John McCall    CallObjCRelease(QualType type, llvm::Value *ptr, llvm::Value *condition)
1211f85e193739c953358c865005855253af4f68a497John McCall      : type(type), ptr(ptr), condition(condition) {}
1212f85e193739c953358c865005855253af4f68a497John McCall    QualType type;
1213f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *ptr;
1214f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *condition;
1215f85e193739c953358c865005855253af4f68a497John McCall
1216ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1217f85e193739c953358c865005855253af4f68a497John McCall      llvm::Value *object;
1218f85e193739c953358c865005855253af4f68a497John McCall
1219f85e193739c953358c865005855253af4f68a497John McCall      // If we're in a conditional branch, we had to stash away in an
1220f85e193739c953358c865005855253af4f68a497John McCall      // alloca the pointer to be released.
1221f85e193739c953358c865005855253af4f68a497John McCall      llvm::BasicBlock *cont = 0;
1222f85e193739c953358c865005855253af4f68a497John McCall      if (condition) {
1223f85e193739c953358c865005855253af4f68a497John McCall        llvm::BasicBlock *release = CGF.createBasicBlock("release.yes");
1224f85e193739c953358c865005855253af4f68a497John McCall        cont = CGF.createBasicBlock("release.cont");
1225f85e193739c953358c865005855253af4f68a497John McCall
1226f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *cond = CGF.Builder.CreateLoad(condition);
1227f85e193739c953358c865005855253af4f68a497John McCall        CGF.Builder.CreateCondBr(cond, release, cont);
1228f85e193739c953358c865005855253af4f68a497John McCall        CGF.EmitBlock(release);
1229f85e193739c953358c865005855253af4f68a497John McCall        object = CGF.Builder.CreateLoad(ptr);
1230f85e193739c953358c865005855253af4f68a497John McCall      } else {
1231f85e193739c953358c865005855253af4f68a497John McCall        object = ptr;
1232f85e193739c953358c865005855253af4f68a497John McCall      }
1233f85e193739c953358c865005855253af4f68a497John McCall
1234f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitARCRelease(object, /*precise*/ true);
1235f85e193739c953358c865005855253af4f68a497John McCall
1236f85e193739c953358c865005855253af4f68a497John McCall      if (cont) CGF.EmitBlock(cont);
1237f85e193739c953358c865005855253af4f68a497John McCall    }
1238f85e193739c953358c865005855253af4f68a497John McCall  };
1239f85e193739c953358c865005855253af4f68a497John McCall}
1240f85e193739c953358c865005855253af4f68a497John McCall
1241f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code for a CK_ObjCConsumeObject.  Does a primitive
1242f85e193739c953358c865005855253af4f68a497John McCall/// release at the end of the full-expression.
1243f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCConsumeObject(QualType type,
1244f85e193739c953358c865005855253af4f68a497John McCall                                                    llvm::Value *object) {
1245f85e193739c953358c865005855253af4f68a497John McCall  // If we're in a conditional branch, we need to make the cleanup
1246f85e193739c953358c865005855253af4f68a497John McCall  // conditional.  FIXME: this really needs to be supported by the
1247f85e193739c953358c865005855253af4f68a497John McCall  // environment.
1248f85e193739c953358c865005855253af4f68a497John McCall  llvm::AllocaInst *cond;
1249f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *ptr;
1250f85e193739c953358c865005855253af4f68a497John McCall  if (isInConditionalBranch()) {
1251f85e193739c953358c865005855253af4f68a497John McCall    cond = CreateTempAlloca(Builder.getInt1Ty(), "release.cond");
1252f85e193739c953358c865005855253af4f68a497John McCall    ptr = CreateTempAlloca(object->getType(), "release.value");
1253f85e193739c953358c865005855253af4f68a497John McCall
1254f85e193739c953358c865005855253af4f68a497John McCall    // The alloca is false until we get here.
1255f85e193739c953358c865005855253af4f68a497John McCall    // FIXME: er. doesn't this need to be set at the start of the condition?
1256f85e193739c953358c865005855253af4f68a497John McCall    InitTempAlloca(cond, Builder.getFalse());
1257f85e193739c953358c865005855253af4f68a497John McCall
1258f85e193739c953358c865005855253af4f68a497John McCall    // Then it turns true.
1259f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(Builder.getTrue(), cond);
1260f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(object, ptr);
1261f85e193739c953358c865005855253af4f68a497John McCall  } else {
1262f85e193739c953358c865005855253af4f68a497John McCall    cond = 0;
1263f85e193739c953358c865005855253af4f68a497John McCall    ptr = object;
1264f85e193739c953358c865005855253af4f68a497John McCall  }
1265f85e193739c953358c865005855253af4f68a497John McCall
1266f85e193739c953358c865005855253af4f68a497John McCall  EHStack.pushCleanup<CallObjCRelease>(getARCCleanupKind(), type, ptr, cond);
1267f85e193739c953358c865005855253af4f68a497John McCall  return object;
1268f85e193739c953358c865005855253af4f68a497John McCall}
1269f85e193739c953358c865005855253af4f68a497John McCall
1270f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCExtendObjectLifetime(QualType type,
1271f85e193739c953358c865005855253af4f68a497John McCall                                                           llvm::Value *value) {
1272f85e193739c953358c865005855253af4f68a497John McCall  return EmitARCRetainAutorelease(type, value);
1273f85e193739c953358c865005855253af4f68a497John McCall}
1274f85e193739c953358c865005855253af4f68a497John McCall
1275f85e193739c953358c865005855253af4f68a497John McCall
1276f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
1277f85e193739c953358c865005855253af4f68a497John McCall                                                const llvm::FunctionType *type,
1278f85e193739c953358c865005855253af4f68a497John McCall                                                llvm::StringRef fnName) {
1279f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *fn = CGM.CreateRuntimeFunction(type, fnName);
1280f85e193739c953358c865005855253af4f68a497John McCall
1281f85e193739c953358c865005855253af4f68a497John McCall  // In -fobjc-no-arc-runtime, emit weak references to the runtime
1282f85e193739c953358c865005855253af4f68a497John McCall  // support library.
12839f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (!CGM.getCodeGenOpts().ObjCRuntimeHasARC)
1284f85e193739c953358c865005855253af4f68a497John McCall    if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
1285f85e193739c953358c865005855253af4f68a497John McCall      f->setLinkage(llvm::Function::ExternalWeakLinkage);
1286f85e193739c953358c865005855253af4f68a497John McCall
1287f85e193739c953358c865005855253af4f68a497John McCall  return fn;
1288f85e193739c953358c865005855253af4f68a497John McCall}
1289f85e193739c953358c865005855253af4f68a497John McCall
1290f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the signature
1291f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8*)
1292f85e193739c953358c865005855253af4f68a497John McCall/// where a null input causes a no-op and returns null.
1293f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCValueOperation(CodeGenFunction &CGF,
1294f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1295f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
1296f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::StringRef fnName) {
1297f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1298f85e193739c953358c865005855253af4f68a497John McCall
1299f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13009cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrTy);
1301f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType =
1302f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1303f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1304f85e193739c953358c865005855253af4f68a497John McCall  }
1305f85e193739c953358c865005855253af4f68a497John McCall
1306f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
1307f85e193739c953358c865005855253af4f68a497John McCall  const llvm::Type *origType = value->getType();
1308f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1309f85e193739c953358c865005855253af4f68a497John McCall
1310f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1311f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, value);
1312f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1313f85e193739c953358c865005855253af4f68a497John McCall
1314f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to the original type.
1315f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(call, origType);
1316f85e193739c953358c865005855253af4f68a497John McCall}
1317f85e193739c953358c865005855253af4f68a497John McCall
1318f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1319f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**)
1320f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCLoadOperation(CodeGenFunction &CGF,
1321f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Value *addr,
1322f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::Constant *&fn,
1323f85e193739c953358c865005855253af4f68a497John McCall                                         llvm::StringRef fnName) {
1324f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, CGF.Int8PtrPtrTy);
1326f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType =
1327f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(CGF.Int8PtrTy, args, false);
1328f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1329f85e193739c953358c865005855253af4f68a497John McCall  }
1330f85e193739c953358c865005855253af4f68a497John McCall
1331f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
1332f85e193739c953358c865005855253af4f68a497John McCall  const llvm::Type *origType = addr->getType();
1333f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1334f85e193739c953358c865005855253af4f68a497John McCall
1335f85e193739c953358c865005855253af4f68a497John McCall  // Call the function.
1336f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = CGF.Builder.CreateCall(fn, addr);
1337f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1338f85e193739c953358c865005855253af4f68a497John McCall
1339f85e193739c953358c865005855253af4f68a497John McCall  // Cast the result back to a dereference of the original type.
1340f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = call;
1341f85e193739c953358c865005855253af4f68a497John McCall  if (origType != CGF.Int8PtrPtrTy)
1342f85e193739c953358c865005855253af4f68a497John McCall    result = CGF.Builder.CreateBitCast(result,
1343f85e193739c953358c865005855253af4f68a497John McCall                        cast<llvm::PointerType>(origType)->getElementType());
1344f85e193739c953358c865005855253af4f68a497John McCall
1345f85e193739c953358c865005855253af4f68a497John McCall  return result;
1346f85e193739c953358c865005855253af4f68a497John McCall}
1347f85e193739c953358c865005855253af4f68a497John McCall
1348f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1349f85e193739c953358c865005855253af4f68a497John McCall///   i8* (i8**, i8*)
1350f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCStoreOperation(CodeGenFunction &CGF,
1351f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *addr,
1352f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Value *value,
1353f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::Constant *&fn,
1354f85e193739c953358c865005855253af4f68a497John McCall                                          llvm::StringRef fnName,
1355f85e193739c953358c865005855253af4f68a497John McCall                                          bool ignored) {
1356f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1357f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1358f85e193739c953358c865005855253af4f68a497John McCall
1359f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13609cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2);
1361f85e193739c953358c865005855253af4f68a497John McCall    argTypes[0] = CGF.Int8PtrPtrTy;
1362f85e193739c953358c865005855253af4f68a497John McCall    argTypes[1] = CGF.Int8PtrTy;
1363f85e193739c953358c865005855253af4f68a497John McCall
1364f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType
1365f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Int8PtrTy, argTypes, false);
1366f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1367f85e193739c953358c865005855253af4f68a497John McCall  }
1368f85e193739c953358c865005855253af4f68a497John McCall
1369f85e193739c953358c865005855253af4f68a497John McCall  const llvm::Type *origType = value->getType();
1370f85e193739c953358c865005855253af4f68a497John McCall
1371f85e193739c953358c865005855253af4f68a497John McCall  addr = CGF.Builder.CreateBitCast(addr, CGF.Int8PtrPtrTy);
1372f85e193739c953358c865005855253af4f68a497John McCall  value = CGF.Builder.CreateBitCast(value, CGF.Int8PtrTy);
1373f85e193739c953358c865005855253af4f68a497John McCall
1374f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, addr, value);
1375f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1376f85e193739c953358c865005855253af4f68a497John McCall
1377f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1378f85e193739c953358c865005855253af4f68a497John McCall
1379f85e193739c953358c865005855253af4f68a497John McCall  return CGF.Builder.CreateBitCast(result, origType);
1380f85e193739c953358c865005855253af4f68a497John McCall}
1381f85e193739c953358c865005855253af4f68a497John McCall
1382f85e193739c953358c865005855253af4f68a497John McCall/// Perform an operation having the following signature:
1383f85e193739c953358c865005855253af4f68a497John McCall///   void (i8**, i8**)
1384f85e193739c953358c865005855253af4f68a497John McCallstatic void emitARCCopyOperation(CodeGenFunction &CGF,
1385f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *dst,
1386f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Value *src,
1387f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::Constant *&fn,
1388f85e193739c953358c865005855253af4f68a497John McCall                                 llvm::StringRef fnName) {
1389f85e193739c953358c865005855253af4f68a497John McCall  assert(dst->getType() == src->getType());
1390f85e193739c953358c865005855253af4f68a497John McCall
1391f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
13929cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> argTypes(2, CGF.Int8PtrPtrTy);
1393f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType
1394f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(CGF.Builder.getVoidTy(), argTypes, false);
1395f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGF.CGM, fnType, fnName);
1396f85e193739c953358c865005855253af4f68a497John McCall  }
1397f85e193739c953358c865005855253af4f68a497John McCall
1398f85e193739c953358c865005855253af4f68a497John McCall  dst = CGF.Builder.CreateBitCast(dst, CGF.Int8PtrPtrTy);
1399f85e193739c953358c865005855253af4f68a497John McCall  src = CGF.Builder.CreateBitCast(src, CGF.Int8PtrPtrTy);
1400f85e193739c953358c865005855253af4f68a497John McCall
1401f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *result = CGF.Builder.CreateCall2(fn, dst, src);
1402f85e193739c953358c865005855253af4f68a497John McCall  result->setDoesNotThrow();
1403f85e193739c953358c865005855253af4f68a497John McCall}
1404f85e193739c953358c865005855253af4f68a497John McCall
1405f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a retain.  Based on the type, calls one of:
1406f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1407f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1408f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetain(QualType type, llvm::Value *value) {
1409f85e193739c953358c865005855253af4f68a497John McCall  if (type->isBlockPointerType())
1410f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainBlock(value);
1411f85e193739c953358c865005855253af4f68a497John McCall  else
1412f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainNonBlock(value);
1413f85e193739c953358c865005855253af4f68a497John McCall}
1414f85e193739c953358c865005855253af4f68a497John McCall
1415f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object, with normal retain semantics.
1416f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retain(i8* %value)
1417f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainNonBlock(llvm::Value *value) {
1418f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1419f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retain,
1420f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retain");
1421f85e193739c953358c865005855253af4f68a497John McCall}
1422f85e193739c953358c865005855253af4f68a497John McCall
1423f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given block, with _Block_copy semantics.
1424f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainBlock(i8* %value)
1425f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainBlock(llvm::Value *value) {
1426f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1427f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainBlock,
1428f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainBlock");
1429f85e193739c953358c865005855253af4f68a497John McCall}
1430f85e193739c953358c865005855253af4f68a497John McCall
1431f85e193739c953358c865005855253af4f68a497John McCall/// Retain the given object which is the result of a function call.
1432f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleasedReturnValue(i8* %value)
1433f85e193739c953358c865005855253af4f68a497John McCall///
1434f85e193739c953358c865005855253af4f68a497John McCall/// Yes, this function name is one character away from a different
1435f85e193739c953358c865005855253af4f68a497John McCall/// call with completely different semantics.
1436f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1437f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
1438f85e193739c953358c865005855253af4f68a497John McCall  // Fetch the void(void) inline asm which marks that we're going to
1439f85e193739c953358c865005855253af4f68a497John McCall  // retain the autoreleased return value.
1440f85e193739c953358c865005855253af4f68a497John McCall  llvm::InlineAsm *&marker
1441f85e193739c953358c865005855253af4f68a497John McCall    = CGM.getARCEntrypoints().retainAutoreleasedReturnValueMarker;
1442f85e193739c953358c865005855253af4f68a497John McCall  if (!marker) {
1443f85e193739c953358c865005855253af4f68a497John McCall    llvm::StringRef assembly
1444f85e193739c953358c865005855253af4f68a497John McCall      = CGM.getTargetCodeGenInfo()
1445f85e193739c953358c865005855253af4f68a497John McCall           .getARCRetainAutoreleasedReturnValueMarker();
1446f85e193739c953358c865005855253af4f68a497John McCall
1447f85e193739c953358c865005855253af4f68a497John McCall    // If we have an empty assembly string, there's nothing to do.
1448f85e193739c953358c865005855253af4f68a497John McCall    if (assembly.empty()) {
1449f85e193739c953358c865005855253af4f68a497John McCall
1450f85e193739c953358c865005855253af4f68a497John McCall    // Otherwise, at -O0, build an inline asm that we're going to call
1451f85e193739c953358c865005855253af4f68a497John McCall    // in a moment.
1452f85e193739c953358c865005855253af4f68a497John McCall    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
1453f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType *type =
1454f85e193739c953358c865005855253af4f68a497John McCall        llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
1455f85e193739c953358c865005855253af4f68a497John McCall                                /*variadic*/ false);
1456f85e193739c953358c865005855253af4f68a497John McCall
1457f85e193739c953358c865005855253af4f68a497John McCall      marker = llvm::InlineAsm::get(type, assembly, "", /*sideeffects*/ true);
1458f85e193739c953358c865005855253af4f68a497John McCall
1459f85e193739c953358c865005855253af4f68a497John McCall    // If we're at -O1 and above, we don't want to litter the code
1460f85e193739c953358c865005855253af4f68a497John McCall    // with this marker yet, so leave a breadcrumb for the ARC
1461f85e193739c953358c865005855253af4f68a497John McCall    // optimizer to pick up.
1462f85e193739c953358c865005855253af4f68a497John McCall    } else {
1463f85e193739c953358c865005855253af4f68a497John McCall      llvm::NamedMDNode *metadata =
1464f85e193739c953358c865005855253af4f68a497John McCall        CGM.getModule().getOrInsertNamedMetadata(
1465f85e193739c953358c865005855253af4f68a497John McCall                            "clang.arc.retainAutoreleasedReturnValueMarker");
1466f85e193739c953358c865005855253af4f68a497John McCall      assert(metadata->getNumOperands() <= 1);
1467f85e193739c953358c865005855253af4f68a497John McCall      if (metadata->getNumOperands() == 0) {
1468f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *string = llvm::MDString::get(getLLVMContext(), assembly);
1469f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *args[] = { string };
1470f85e193739c953358c865005855253af4f68a497John McCall        metadata->addOperand(llvm::MDNode::get(getLLVMContext(), args));
1471f85e193739c953358c865005855253af4f68a497John McCall      }
1472f85e193739c953358c865005855253af4f68a497John McCall    }
1473f85e193739c953358c865005855253af4f68a497John McCall  }
1474f85e193739c953358c865005855253af4f68a497John McCall
1475f85e193739c953358c865005855253af4f68a497John McCall  // Call the marker asm if we made one, which we do only at -O0.
1476f85e193739c953358c865005855253af4f68a497John McCall  if (marker) Builder.CreateCall(marker);
1477f85e193739c953358c865005855253af4f68a497John McCall
1478f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1479f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleasedReturnValue,
1480f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleasedReturnValue");
1481f85e193739c953358c865005855253af4f68a497John McCall}
1482f85e193739c953358c865005855253af4f68a497John McCall
1483f85e193739c953358c865005855253af4f68a497John McCall/// Release the given object.
1484f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_release(i8* %value)
1485f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCRelease(llvm::Value *value, bool precise) {
1486f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return;
1487f85e193739c953358c865005855253af4f68a497John McCall
1488f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_release;
1489f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
14909cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
1491f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType =
1492f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1493f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_release");
1494f85e193739c953358c865005855253af4f68a497John McCall  }
1495f85e193739c953358c865005855253af4f68a497John McCall
1496f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id'.
1497f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1498f85e193739c953358c865005855253af4f68a497John McCall
1499f85e193739c953358c865005855253af4f68a497John McCall  // Call objc_release.
1500f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1501f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1502f85e193739c953358c865005855253af4f68a497John McCall
1503f85e193739c953358c865005855253af4f68a497John McCall  if (!precise) {
1504f85e193739c953358c865005855253af4f68a497John McCall    llvm::SmallVector<llvm::Value*,1> args;
1505f85e193739c953358c865005855253af4f68a497John McCall    call->setMetadata("clang.imprecise_release",
1506f85e193739c953358c865005855253af4f68a497John McCall                      llvm::MDNode::get(Builder.getContext(), args));
1507f85e193739c953358c865005855253af4f68a497John McCall  }
1508f85e193739c953358c865005855253af4f68a497John McCall}
1509f85e193739c953358c865005855253af4f68a497John McCall
1510f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Always calls this:
1511f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1512f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrongCall(llvm::Value *addr,
1513f85e193739c953358c865005855253af4f68a497John McCall                                                     llvm::Value *value,
1514f85e193739c953358c865005855253af4f68a497John McCall                                                     bool ignored) {
1515f85e193739c953358c865005855253af4f68a497John McCall  assert(cast<llvm::PointerType>(addr->getType())->getElementType()
1516f85e193739c953358c865005855253af4f68a497John McCall           == value->getType());
1517f85e193739c953358c865005855253af4f68a497John McCall
1518f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_storeStrong;
1519f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
15209cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    llvm::Type *argTypes[] = { Int8PtrPtrTy, Int8PtrTy };
1521f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType
1522f85e193739c953358c865005855253af4f68a497John McCall      = llvm::FunctionType::get(Builder.getVoidTy(), argTypes, false);
1523f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_storeStrong");
1524f85e193739c953358c865005855253af4f68a497John McCall  }
1525f85e193739c953358c865005855253af4f68a497John McCall
1526f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1527f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *castValue = Builder.CreateBitCast(value, Int8PtrTy);
1528f85e193739c953358c865005855253af4f68a497John McCall
1529f85e193739c953358c865005855253af4f68a497John McCall  Builder.CreateCall2(fn, addr, castValue)->setDoesNotThrow();
1530f85e193739c953358c865005855253af4f68a497John McCall
1531f85e193739c953358c865005855253af4f68a497John McCall  if (ignored) return 0;
1532f85e193739c953358c865005855253af4f68a497John McCall  return value;
1533f85e193739c953358c865005855253af4f68a497John McCall}
1534f85e193739c953358c865005855253af4f68a497John McCall
1535f85e193739c953358c865005855253af4f68a497John McCall/// Store into a strong object.  Sometimes calls this:
1536f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_storeStrong(i8** %addr, i8* %value)
1537f85e193739c953358c865005855253af4f68a497John McCall/// Other times, breaks it down into components.
1538545d996ec5a3113f046944f11b27cc2d6cb055b4John McCallllvm::Value *CodeGenFunction::EmitARCStoreStrong(LValue dst,
1539f85e193739c953358c865005855253af4f68a497John McCall                                                 llvm::Value *newValue,
1540f85e193739c953358c865005855253af4f68a497John McCall                                                 bool ignored) {
1541545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  QualType type = dst.getType();
1542f85e193739c953358c865005855253af4f68a497John McCall  bool isBlock = type->isBlockPointerType();
1543f85e193739c953358c865005855253af4f68a497John McCall
1544f85e193739c953358c865005855253af4f68a497John McCall  // Use a store barrier at -O0 unless this is a block type or the
1545f85e193739c953358c865005855253af4f68a497John McCall  // lvalue is inadequately aligned.
1546f85e193739c953358c865005855253af4f68a497John McCall  if (shouldUseFusedARCCalls() &&
1547f85e193739c953358c865005855253af4f68a497John McCall      !isBlock &&
1548f85e193739c953358c865005855253af4f68a497John McCall      !(dst.getAlignment() && dst.getAlignment() < PointerAlignInBytes)) {
1549f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCStoreStrongCall(dst.getAddress(), newValue, ignored);
1550f85e193739c953358c865005855253af4f68a497John McCall  }
1551f85e193739c953358c865005855253af4f68a497John McCall
1552f85e193739c953358c865005855253af4f68a497John McCall  // Otherwise, split it out.
1553f85e193739c953358c865005855253af4f68a497John McCall
1554f85e193739c953358c865005855253af4f68a497John McCall  // Retain the new value.
1555f85e193739c953358c865005855253af4f68a497John McCall  newValue = EmitARCRetain(type, newValue);
1556f85e193739c953358c865005855253af4f68a497John McCall
1557f85e193739c953358c865005855253af4f68a497John McCall  // Read the old value.
1558545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  llvm::Value *oldValue = EmitLoadOfScalar(dst);
1559f85e193739c953358c865005855253af4f68a497John McCall
1560f85e193739c953358c865005855253af4f68a497John McCall  // Store.  We do this before the release so that any deallocs won't
1561f85e193739c953358c865005855253af4f68a497John McCall  // see the old value.
1562545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall  EmitStoreOfScalar(newValue, dst);
1563f85e193739c953358c865005855253af4f68a497John McCall
1564f85e193739c953358c865005855253af4f68a497John McCall  // Finally, release the old value.
1565f85e193739c953358c865005855253af4f68a497John McCall  EmitARCRelease(oldValue, /*precise*/ false);
1566f85e193739c953358c865005855253af4f68a497John McCall
1567f85e193739c953358c865005855253af4f68a497John McCall  return newValue;
1568f85e193739c953358c865005855253af4f68a497John McCall}
1569f85e193739c953358c865005855253af4f68a497John McCall
1570f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1571f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %value)
1572f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCAutorelease(llvm::Value *value) {
1573f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1574f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_autorelease,
1575f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autorelease");
1576f85e193739c953358c865005855253af4f68a497John McCall}
1577f85e193739c953358c865005855253af4f68a497John McCall
1578f85e193739c953358c865005855253af4f68a497John McCall/// Autorelease the given object.
1579f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleaseReturnValue(i8* %value)
1580f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1581f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCAutoreleaseReturnValue(llvm::Value *value) {
1582f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1583f85e193739c953358c865005855253af4f68a497John McCall                            CGM.getARCEntrypoints().objc_autoreleaseReturnValue,
1584f85e193739c953358c865005855253af4f68a497John McCall                               "objc_autoreleaseReturnValue");
1585f85e193739c953358c865005855253af4f68a497John McCall}
1586f85e193739c953358c865005855253af4f68a497John McCall
1587f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1588f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutoreleaseReturnValue(i8* %value)
1589f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1590f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseReturnValue(llvm::Value *value) {
1591f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1592f85e193739c953358c865005855253af4f68a497John McCall                     CGM.getARCEntrypoints().objc_retainAutoreleaseReturnValue,
1593f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutoreleaseReturnValue");
1594f85e193739c953358c865005855253af4f68a497John McCall}
1595f85e193739c953358c865005855253af4f68a497John McCall
1596f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1597f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1598f85e193739c953358c865005855253af4f68a497John McCall/// or
1599f85e193739c953358c865005855253af4f68a497John McCall///   %retain = call i8* @objc_retainBlock(i8* %value)
1600f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autorelease(i8* %retain)
1601f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainAutorelease(QualType type,
1602f85e193739c953358c865005855253af4f68a497John McCall                                                       llvm::Value *value) {
1603f85e193739c953358c865005855253af4f68a497John McCall  if (!type->isBlockPointerType())
1604f85e193739c953358c865005855253af4f68a497John McCall    return EmitARCRetainAutoreleaseNonBlock(value);
1605f85e193739c953358c865005855253af4f68a497John McCall
1606f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value)) return value;
1607f85e193739c953358c865005855253af4f68a497John McCall
1608f85e193739c953358c865005855253af4f68a497John McCall  const llvm::Type *origType = value->getType();
1609f85e193739c953358c865005855253af4f68a497John McCall  value = Builder.CreateBitCast(value, Int8PtrTy);
1610f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCRetainBlock(value);
1611f85e193739c953358c865005855253af4f68a497John McCall  value = EmitARCAutorelease(value);
1612f85e193739c953358c865005855253af4f68a497John McCall  return Builder.CreateBitCast(value, origType);
1613f85e193739c953358c865005855253af4f68a497John McCall}
1614f85e193739c953358c865005855253af4f68a497John McCall
1615f85e193739c953358c865005855253af4f68a497John McCall/// Do a fused retain/autorelease of the given object.
1616f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_retainAutorelease(i8* %value)
1617f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
1618f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseNonBlock(llvm::Value *value) {
1619f85e193739c953358c865005855253af4f68a497John McCall  return emitARCValueOperation(*this, value,
1620f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_retainAutorelease,
1621f85e193739c953358c865005855253af4f68a497John McCall                               "objc_retainAutorelease");
1622f85e193739c953358c865005855253af4f68a497John McCall}
1623f85e193739c953358c865005855253af4f68a497John McCall
1624f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeak(i8** %addr)
1625f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_autorelease(objc_loadWeakRetained(addr)).
1626f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeak(llvm::Value *addr) {
1627f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1628f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeak,
1629f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeak");
1630f85e193739c953358c865005855253af4f68a497John McCall}
1631f85e193739c953358c865005855253af4f68a497John McCall
1632f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_loadWeakRetained(i8** %addr)
1633f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCLoadWeakRetained(llvm::Value *addr) {
1634f85e193739c953358c865005855253af4f68a497John McCall  return emitARCLoadOperation(*this, addr,
1635f85e193739c953358c865005855253af4f68a497John McCall                              CGM.getARCEntrypoints().objc_loadWeakRetained,
1636f85e193739c953358c865005855253af4f68a497John McCall                              "objc_loadWeakRetained");
1637f85e193739c953358c865005855253af4f68a497John McCall}
1638f85e193739c953358c865005855253af4f68a497John McCall
1639f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_storeWeak(i8** %addr, i8* %value)
1640f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.
1641f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCStoreWeak(llvm::Value *addr,
1642f85e193739c953358c865005855253af4f68a497John McCall                                               llvm::Value *value,
1643f85e193739c953358c865005855253af4f68a497John McCall                                               bool ignored) {
1644f85e193739c953358c865005855253af4f68a497John McCall  return emitARCStoreOperation(*this, addr, value,
1645f85e193739c953358c865005855253af4f68a497John McCall                               CGM.getARCEntrypoints().objc_storeWeak,
1646f85e193739c953358c865005855253af4f68a497John McCall                               "objc_storeWeak", ignored);
1647f85e193739c953358c865005855253af4f68a497John McCall}
1648f85e193739c953358c865005855253af4f68a497John McCall
1649f85e193739c953358c865005855253af4f68a497John McCall/// i8* @objc_initWeak(i8** %addr, i8* %value)
1650f85e193739c953358c865005855253af4f68a497John McCall/// Returns %value.  %addr is known to not have a current weak entry.
1651f85e193739c953358c865005855253af4f68a497John McCall/// Essentially equivalent to:
1652f85e193739c953358c865005855253af4f68a497John McCall///   *addr = nil; objc_storeWeak(addr, value);
1653f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCInitWeak(llvm::Value *addr, llvm::Value *value) {
1654f85e193739c953358c865005855253af4f68a497John McCall  // If we're initializing to null, just write null to memory; no need
1655f85e193739c953358c865005855253af4f68a497John McCall  // to get the runtime involved.  But don't do this if optimization
1656f85e193739c953358c865005855253af4f68a497John McCall  // is enabled, because accounting for this would make the optimizer
1657f85e193739c953358c865005855253af4f68a497John McCall  // much more complicated.
1658f85e193739c953358c865005855253af4f68a497John McCall  if (isa<llvm::ConstantPointerNull>(value) &&
1659f85e193739c953358c865005855253af4f68a497John McCall      CGM.getCodeGenOpts().OptimizationLevel == 0) {
1660f85e193739c953358c865005855253af4f68a497John McCall    Builder.CreateStore(value, addr);
1661f85e193739c953358c865005855253af4f68a497John McCall    return;
1662f85e193739c953358c865005855253af4f68a497John McCall  }
1663f85e193739c953358c865005855253af4f68a497John McCall
1664f85e193739c953358c865005855253af4f68a497John McCall  emitARCStoreOperation(*this, addr, value,
1665f85e193739c953358c865005855253af4f68a497John McCall                        CGM.getARCEntrypoints().objc_initWeak,
1666f85e193739c953358c865005855253af4f68a497John McCall                        "objc_initWeak", /*ignored*/ true);
1667f85e193739c953358c865005855253af4f68a497John McCall}
1668f85e193739c953358c865005855253af4f68a497John McCall
1669f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_destroyWeak(i8** %addr)
1670f85e193739c953358c865005855253af4f68a497John McCall/// Essentially objc_storeWeak(addr, nil).
1671f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCDestroyWeak(llvm::Value *addr) {
1672f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getARCEntrypoints().objc_destroyWeak;
1673f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
16749cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrPtrTy);
1675f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType =
1676f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1677f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_destroyWeak");
1678f85e193739c953358c865005855253af4f68a497John McCall  }
1679f85e193739c953358c865005855253af4f68a497John McCall
1680f85e193739c953358c865005855253af4f68a497John McCall  // Cast the argument to 'id*'.
1681f85e193739c953358c865005855253af4f68a497John McCall  addr = Builder.CreateBitCast(addr, Int8PtrPtrTy);
1682f85e193739c953358c865005855253af4f68a497John McCall
1683f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, addr);
1684f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1685f85e193739c953358c865005855253af4f68a497John McCall}
1686f85e193739c953358c865005855253af4f68a497John McCall
1687f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_moveWeak(i8** %dest, i8** %src)
1688f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Leaves %src pointing to nothing.
1689f85e193739c953358c865005855253af4f68a497John McCall/// Essentially (objc_copyWeak(dest, src), objc_destroyWeak(src)).
1690f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCMoveWeak(llvm::Value *dst, llvm::Value *src) {
1691f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1692f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_moveWeak,
1693f85e193739c953358c865005855253af4f68a497John McCall                       "objc_moveWeak");
1694f85e193739c953358c865005855253af4f68a497John McCall}
1695f85e193739c953358c865005855253af4f68a497John McCall
1696f85e193739c953358c865005855253af4f68a497John McCall/// void @objc_copyWeak(i8** %dest, i8** %src)
1697f85e193739c953358c865005855253af4f68a497John McCall/// Disregards the current value in %dest.  Essentially
1698f85e193739c953358c865005855253af4f68a497John McCall///   objc_release(objc_initWeak(dest, objc_readWeakRetained(src)))
1699f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitARCCopyWeak(llvm::Value *dst, llvm::Value *src) {
1700f85e193739c953358c865005855253af4f68a497John McCall  emitARCCopyOperation(*this, dst, src,
1701f85e193739c953358c865005855253af4f68a497John McCall                       CGM.getARCEntrypoints().objc_copyWeak,
1702f85e193739c953358c865005855253af4f68a497John McCall                       "objc_copyWeak");
1703f85e193739c953358c865005855253af4f68a497John McCall}
1704f85e193739c953358c865005855253af4f68a497John McCall
1705f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a objc_autoreleasepool_push.
1706f85e193739c953358c865005855253af4f68a497John McCall///   call i8* @objc_autoreleasePoolPush(void)
1707f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCAutoreleasePoolPush() {
1708f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPush;
1709f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
1710f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType =
1711f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Int8PtrTy, false);
1712f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPush");
1713f85e193739c953358c865005855253af4f68a497John McCall  }
1714f85e193739c953358c865005855253af4f68a497John McCall
1715f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn);
1716f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1717f85e193739c953358c865005855253af4f68a497John McCall
1718f85e193739c953358c865005855253af4f68a497John McCall  return call;
1719f85e193739c953358c865005855253af4f68a497John McCall}
1720f85e193739c953358c865005855253af4f68a497John McCall
1721f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1722f85e193739c953358c865005855253af4f68a497John McCall///   call void @objc_autoreleasePoolPop(i8* %ptr)
1723f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolPop(llvm::Value *value) {
1724f85e193739c953358c865005855253af4f68a497John McCall  assert(value->getType() == Int8PtrTy);
1725f85e193739c953358c865005855253af4f68a497John McCall
1726f85e193739c953358c865005855253af4f68a497John McCall  llvm::Constant *&fn = CGM.getRREntrypoints().objc_autoreleasePoolPop;
1727f85e193739c953358c865005855253af4f68a497John McCall  if (!fn) {
17289cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    std::vector<llvm::Type*> args(1, Int8PtrTy);
1729f85e193739c953358c865005855253af4f68a497John McCall    const llvm::FunctionType *fnType =
1730f85e193739c953358c865005855253af4f68a497John McCall      llvm::FunctionType::get(Builder.getVoidTy(), args, false);
1731f85e193739c953358c865005855253af4f68a497John McCall
1732f85e193739c953358c865005855253af4f68a497John McCall    // We don't want to use a weak import here; instead we should not
1733f85e193739c953358c865005855253af4f68a497John McCall    // fall into this path.
1734f85e193739c953358c865005855253af4f68a497John McCall    fn = createARCRuntimeFunction(CGM, fnType, "objc_autoreleasePoolPop");
1735f85e193739c953358c865005855253af4f68a497John McCall  }
1736f85e193739c953358c865005855253af4f68a497John McCall
1737f85e193739c953358c865005855253af4f68a497John McCall  llvm::CallInst *call = Builder.CreateCall(fn, value);
1738f85e193739c953358c865005855253af4f68a497John McCall  call->setDoesNotThrow();
1739f85e193739c953358c865005855253af4f68a497John McCall}
1740f85e193739c953358c865005855253af4f68a497John McCall
1741f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do an MRR version objc_autoreleasepool_push.
1742f85e193739c953358c865005855253af4f68a497John McCall/// Which is: [[NSAutoreleasePool alloc] init];
1743f85e193739c953358c865005855253af4f68a497John McCall/// Where alloc is declared as: + (id) alloc; in NSAutoreleasePool class.
1744f85e193739c953358c865005855253af4f68a497John McCall/// init is declared as: - (id) init; in its NSObject super class.
1745f85e193739c953358c865005855253af4f68a497John McCall///
1746f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitObjCMRRAutoreleasePoolPush() {
1747f85e193739c953358c865005855253af4f68a497John McCall  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
1748f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *Receiver = Runtime.EmitNSAutoreleasePoolClassRef(Builder);
1749f85e193739c953358c865005855253af4f68a497John McCall  // [NSAutoreleasePool alloc]
1750f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("alloc");
1751f85e193739c953358c865005855253af4f68a497John McCall  Selector AllocSel = getContext().Selectors.getSelector(0, &II);
1752f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1753f85e193739c953358c865005855253af4f68a497John McCall  RValue AllocRV =
1754f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1755f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1756f85e193739c953358c865005855253af4f68a497John McCall                                AllocSel, Receiver, Args);
1757f85e193739c953358c865005855253af4f68a497John McCall
1758f85e193739c953358c865005855253af4f68a497John McCall  // [Receiver init]
1759f85e193739c953358c865005855253af4f68a497John McCall  Receiver = AllocRV.getScalarVal();
1760f85e193739c953358c865005855253af4f68a497John McCall  II = &CGM.getContext().Idents.get("init");
1761f85e193739c953358c865005855253af4f68a497John McCall  Selector InitSel = getContext().Selectors.getSelector(0, &II);
1762f85e193739c953358c865005855253af4f68a497John McCall  RValue InitRV =
1763f85e193739c953358c865005855253af4f68a497John McCall    Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
1764f85e193739c953358c865005855253af4f68a497John McCall                                getContext().getObjCIdType(),
1765f85e193739c953358c865005855253af4f68a497John McCall                                InitSel, Receiver, Args);
1766f85e193739c953358c865005855253af4f68a497John McCall  return InitRV.getScalarVal();
1767f85e193739c953358c865005855253af4f68a497John McCall}
1768f85e193739c953358c865005855253af4f68a497John McCall
1769f85e193739c953358c865005855253af4f68a497John McCall/// Produce the code to do a primitive release.
1770f85e193739c953358c865005855253af4f68a497John McCall/// [tmp drain];
1771f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCMRRAutoreleasePoolPop(llvm::Value *Arg) {
1772f85e193739c953358c865005855253af4f68a497John McCall  IdentifierInfo *II = &CGM.getContext().Idents.get("drain");
1773f85e193739c953358c865005855253af4f68a497John McCall  Selector DrainSel = getContext().Selectors.getSelector(0, &II);
1774f85e193739c953358c865005855253af4f68a497John McCall  CallArgList Args;
1775f85e193739c953358c865005855253af4f68a497John McCall  CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1776f85e193739c953358c865005855253af4f68a497John McCall                              getContext().VoidTy, DrainSel, Arg, Args);
1777f85e193739c953358c865005855253af4f68a497John McCall}
1778f85e193739c953358c865005855253af4f68a497John McCall
1779bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
1780bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              llvm::Value *addr,
1781bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                              QualType type) {
1782bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1783bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ true);
1784bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1785bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1786bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
1787bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                llvm::Value *addr,
1788bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                                QualType type) {
1789bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
1790bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCRelease(ptr, /*precise*/ false);
1791bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1792bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1793bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCallvoid CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
1794bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     llvm::Value *addr,
1795bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall                                     QualType type) {
1796bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall  CGF.EmitARCDestroyWeak(addr);
1797bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall}
1798bdc4d80956c83a486e58d3df6bb524a1f66ff574John McCall
1799f85e193739c953358c865005855253af4f68a497John McCallnamespace {
1800f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCAutoreleasePoolObject : EHScopeStack::Cleanup {
1801f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1802f85e193739c953358c865005855253af4f68a497John McCall
1803f85e193739c953358c865005855253af4f68a497John McCall    CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1804f85e193739c953358c865005855253af4f68a497John McCall
1805ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1806f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCAutoreleasePoolPop(Token);
1807f85e193739c953358c865005855253af4f68a497John McCall    }
1808f85e193739c953358c865005855253af4f68a497John McCall  };
1809f85e193739c953358c865005855253af4f68a497John McCall  struct CallObjCMRRAutoreleasePoolObject : EHScopeStack::Cleanup {
1810f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *Token;
1811f85e193739c953358c865005855253af4f68a497John McCall
1812f85e193739c953358c865005855253af4f68a497John McCall    CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
1813f85e193739c953358c865005855253af4f68a497John McCall
1814ad346f4f678ab1c3222425641d851dc63e9dfa1aJohn McCall    void Emit(CodeGenFunction &CGF, Flags flags) {
1815f85e193739c953358c865005855253af4f68a497John McCall      CGF.EmitObjCMRRAutoreleasePoolPop(Token);
1816f85e193739c953358c865005855253af4f68a497John McCall    }
1817f85e193739c953358c865005855253af4f68a497John McCall  };
1818f85e193739c953358c865005855253af4f68a497John McCall}
1819f85e193739c953358c865005855253af4f68a497John McCall
1820f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
1821f85e193739c953358c865005855253af4f68a497John McCall  if (CGM.getLangOptions().ObjCAutoRefCount)
1822f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr);
1823f85e193739c953358c865005855253af4f68a497John McCall  else
1824f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr);
1825f85e193739c953358c865005855253af4f68a497John McCall}
1826f85e193739c953358c865005855253af4f68a497John McCall
1827f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1828f85e193739c953358c865005855253af4f68a497John McCall                                                  LValue lvalue,
1829f85e193739c953358c865005855253af4f68a497John McCall                                                  QualType type) {
1830f85e193739c953358c865005855253af4f68a497John McCall  switch (type.getObjCLifetime()) {
1831f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_None:
1832f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_ExplicitNone:
1833f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Strong:
1834f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Autoreleasing:
1835545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    return TryEmitResult(CGF.EmitLoadOfLValue(lvalue).getScalarVal(),
1836f85e193739c953358c865005855253af4f68a497John McCall                         false);
1837f85e193739c953358c865005855253af4f68a497John McCall
1838f85e193739c953358c865005855253af4f68a497John McCall  case Qualifiers::OCL_Weak:
1839f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitARCLoadWeakRetained(lvalue.getAddress()),
1840f85e193739c953358c865005855253af4f68a497John McCall                         true);
1841f85e193739c953358c865005855253af4f68a497John McCall  }
1842f85e193739c953358c865005855253af4f68a497John McCall
1843f85e193739c953358c865005855253af4f68a497John McCall  llvm_unreachable("impossible lifetime!");
1844f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult();
1845f85e193739c953358c865005855253af4f68a497John McCall}
1846f85e193739c953358c865005855253af4f68a497John McCall
1847f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult tryEmitARCRetainLoadOfScalar(CodeGenFunction &CGF,
1848f85e193739c953358c865005855253af4f68a497John McCall                                                  const Expr *e) {
1849f85e193739c953358c865005855253af4f68a497John McCall  e = e->IgnoreParens();
1850f85e193739c953358c865005855253af4f68a497John McCall  QualType type = e->getType();
1851f85e193739c953358c865005855253af4f68a497John McCall
1852f85e193739c953358c865005855253af4f68a497John McCall  // As a very special optimization, in ARC++, if the l-value is the
1853f85e193739c953358c865005855253af4f68a497John McCall  // result of a non-volatile assignment, do a simple retain of the
1854f85e193739c953358c865005855253af4f68a497John McCall  // result of the call to objc_storeWeak instead of reloading.
1855f85e193739c953358c865005855253af4f68a497John McCall  if (CGF.getLangOptions().CPlusPlus &&
1856f85e193739c953358c865005855253af4f68a497John McCall      !type.isVolatileQualified() &&
1857f85e193739c953358c865005855253af4f68a497John McCall      type.getObjCLifetime() == Qualifiers::OCL_Weak &&
1858f85e193739c953358c865005855253af4f68a497John McCall      isa<BinaryOperator>(e) &&
1859f85e193739c953358c865005855253af4f68a497John McCall      cast<BinaryOperator>(e)->getOpcode() == BO_Assign)
1860f85e193739c953358c865005855253af4f68a497John McCall    return TryEmitResult(CGF.EmitScalarExpr(e), false);
1861f85e193739c953358c865005855253af4f68a497John McCall
1862f85e193739c953358c865005855253af4f68a497John McCall  return tryEmitARCRetainLoadOfScalar(CGF, CGF.EmitLValue(e), type);
1863f85e193739c953358c865005855253af4f68a497John McCall}
1864f85e193739c953358c865005855253af4f68a497John McCall
1865f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1866f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value);
1867f85e193739c953358c865005855253af4f68a497John McCall
1868f85e193739c953358c865005855253af4f68a497John McCall/// Given that the given expression is some sort of call (which does
1869f85e193739c953358c865005855253af4f68a497John McCall/// not return retained), emit a retain following it.
1870f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainCall(CodeGenFunction &CGF, const Expr *e) {
1871f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = CGF.EmitScalarExpr(e);
1872f85e193739c953358c865005855253af4f68a497John McCall  return emitARCRetainAfterCall(CGF, value);
1873f85e193739c953358c865005855253af4f68a497John McCall}
1874f85e193739c953358c865005855253af4f68a497John McCall
1875f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainAfterCall(CodeGenFunction &CGF,
1876f85e193739c953358c865005855253af4f68a497John McCall                                           llvm::Value *value) {
1877f85e193739c953358c865005855253af4f68a497John McCall  if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(value)) {
1878f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
1879f85e193739c953358c865005855253af4f68a497John McCall
1880f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain immediately following the call.
1881f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(call->getParent(),
1882f85e193739c953358c865005855253af4f68a497John McCall                               ++llvm::BasicBlock::iterator(call));
1883f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
1884f85e193739c953358c865005855253af4f68a497John McCall
1885f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
1886f85e193739c953358c865005855253af4f68a497John McCall    return value;
1887f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::InvokeInst *invoke = dyn_cast<llvm::InvokeInst>(value)) {
1888f85e193739c953358c865005855253af4f68a497John McCall    CGBuilderTy::InsertPoint ip = CGF.Builder.saveIP();
1889f85e193739c953358c865005855253af4f68a497John McCall
1890f85e193739c953358c865005855253af4f68a497John McCall    // Place the retain at the beginning of the normal destination block.
1891f85e193739c953358c865005855253af4f68a497John McCall    llvm::BasicBlock *BB = invoke->getNormalDest();
1892f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.SetInsertPoint(BB, BB->begin());
1893f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetainAutoreleasedReturnValue(value);
1894f85e193739c953358c865005855253af4f68a497John McCall
1895f85e193739c953358c865005855253af4f68a497John McCall    CGF.Builder.restoreIP(ip);
1896f85e193739c953358c865005855253af4f68a497John McCall    return value;
1897f85e193739c953358c865005855253af4f68a497John McCall
1898f85e193739c953358c865005855253af4f68a497John McCall  // Bitcasts can arise because of related-result returns.  Rewrite
1899f85e193739c953358c865005855253af4f68a497John McCall  // the operand.
1900f85e193739c953358c865005855253af4f68a497John McCall  } else if (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(value)) {
1901f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *operand = bitcast->getOperand(0);
1902f85e193739c953358c865005855253af4f68a497John McCall    operand = emitARCRetainAfterCall(CGF, operand);
1903f85e193739c953358c865005855253af4f68a497John McCall    bitcast->setOperand(0, operand);
1904f85e193739c953358c865005855253af4f68a497John McCall    return bitcast;
1905f85e193739c953358c865005855253af4f68a497John McCall
1906f85e193739c953358c865005855253af4f68a497John McCall  // Generic fall-back case.
1907f85e193739c953358c865005855253af4f68a497John McCall  } else {
1908f85e193739c953358c865005855253af4f68a497John McCall    // Retain using the non-block variant: we never need to do a copy
1909f85e193739c953358c865005855253af4f68a497John McCall    // of a block that's been returned to us.
1910f85e193739c953358c865005855253af4f68a497John McCall    return CGF.EmitARCRetainNonBlock(value);
1911f85e193739c953358c865005855253af4f68a497John McCall  }
1912f85e193739c953358c865005855253af4f68a497John McCall}
1913f85e193739c953358c865005855253af4f68a497John McCall
1914f85e193739c953358c865005855253af4f68a497John McCallstatic TryEmitResult
1915f85e193739c953358c865005855253af4f68a497John McCalltryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
1916f85e193739c953358c865005855253af4f68a497John McCall  // The desired result type, if it differs from the type of the
1917f85e193739c953358c865005855253af4f68a497John McCall  // ultimate opaque expression.
1918f85e193739c953358c865005855253af4f68a497John McCall  const llvm::Type *resultType = 0;
1919f85e193739c953358c865005855253af4f68a497John McCall
1920d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // If we're loading retained from a __strong xvalue, we can avoid
1921d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // an extra retain/release pair by zeroing out the source of this
1922d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  // "move" operation.
1923df7b091c58ccdb402a32bfbde9c506074dba5f3dJohn McCall  if (e->isXValue() && !e->getType().isConstQualified() &&
1924d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      e->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
1925d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Emit the lvalue
1926d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    LValue lv = CGF.EmitLValue(e);
1927d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1928d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Load the object pointer and cast it to the appropriate type.
1929d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    QualType exprType = e->getType();
1930545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    llvm::Value *result = CGF.EmitLoadOfLValue(lv).getScalarVal();
1931d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1932d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    if (resultType)
1933d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      result = CGF.Builder.CreateBitCast(result, resultType);
1934d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1935d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    // Set the source pointer to NULL.
1936d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    llvm::Value *null
1937d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor      = llvm::ConstantPointerNull::get(
1938d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor                            cast<llvm::PointerType>(CGF.ConvertType(exprType)));
1939545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    CGF.EmitStoreOfScalar(null, lv);
1940d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1941d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor    return TryEmitResult(result, true);
1942d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor  }
1943d1bd98a2c239d2a730b07f7c1b2c8c8718eaeac8Douglas Gregor
1944f85e193739c953358c865005855253af4f68a497John McCall  while (true) {
1945f85e193739c953358c865005855253af4f68a497John McCall    e = e->IgnoreParens();
1946f85e193739c953358c865005855253af4f68a497John McCall
1947f85e193739c953358c865005855253af4f68a497John McCall    // There's a break at the end of this if-chain;  anything
1948f85e193739c953358c865005855253af4f68a497John McCall    // that wants to keep looping has to explicitly continue.
1949f85e193739c953358c865005855253af4f68a497John McCall    if (const CastExpr *ce = dyn_cast<CastExpr>(e)) {
1950f85e193739c953358c865005855253af4f68a497John McCall      switch (ce->getCastKind()) {
1951f85e193739c953358c865005855253af4f68a497John McCall      // No-op casts don't change the type, so we just ignore them.
1952f85e193739c953358c865005855253af4f68a497John McCall      case CK_NoOp:
1953f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
1954f85e193739c953358c865005855253af4f68a497John McCall        continue;
1955f85e193739c953358c865005855253af4f68a497John McCall
1956f85e193739c953358c865005855253af4f68a497John McCall      case CK_LValueToRValue: {
1957f85e193739c953358c865005855253af4f68a497John McCall        TryEmitResult loadResult
1958f85e193739c953358c865005855253af4f68a497John McCall          = tryEmitARCRetainLoadOfScalar(CGF, ce->getSubExpr());
1959f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) {
1960f85e193739c953358c865005855253af4f68a497John McCall          llvm::Value *value = loadResult.getPointer();
1961f85e193739c953358c865005855253af4f68a497John McCall          value = CGF.Builder.CreateBitCast(value, resultType);
1962f85e193739c953358c865005855253af4f68a497John McCall          loadResult.setPointer(value);
1963f85e193739c953358c865005855253af4f68a497John McCall        }
1964f85e193739c953358c865005855253af4f68a497John McCall        return loadResult;
1965f85e193739c953358c865005855253af4f68a497John McCall      }
1966f85e193739c953358c865005855253af4f68a497John McCall
1967f85e193739c953358c865005855253af4f68a497John McCall      // These casts can change the type, so remember that and
1968f85e193739c953358c865005855253af4f68a497John McCall      // soldier on.  We only need to remember the outermost such
1969f85e193739c953358c865005855253af4f68a497John McCall      // cast, though.
1970f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToObjCPointerCast:
1971f85e193739c953358c865005855253af4f68a497John McCall      case CK_AnyPointerToBlockPointerCast:
1972f85e193739c953358c865005855253af4f68a497John McCall      case CK_BitCast:
1973f85e193739c953358c865005855253af4f68a497John McCall        if (!resultType)
1974f85e193739c953358c865005855253af4f68a497John McCall          resultType = CGF.ConvertType(ce->getType());
1975f85e193739c953358c865005855253af4f68a497John McCall        e = ce->getSubExpr();
1976f85e193739c953358c865005855253af4f68a497John McCall        assert(e->getType()->hasPointerRepresentation());
1977f85e193739c953358c865005855253af4f68a497John McCall        continue;
1978f85e193739c953358c865005855253af4f68a497John McCall
1979f85e193739c953358c865005855253af4f68a497John McCall      // For consumptions, just emit the subexpression and thus elide
1980f85e193739c953358c865005855253af4f68a497John McCall      // the retain/release pair.
1981f85e193739c953358c865005855253af4f68a497John McCall      case CK_ObjCConsumeObject: {
1982f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = CGF.EmitScalarExpr(ce->getSubExpr());
1983f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
1984f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
1985f85e193739c953358c865005855253af4f68a497John McCall      }
1986f85e193739c953358c865005855253af4f68a497John McCall
19877e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // For reclaims, emit the subexpression as a retained call and
19887e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      // skip the consumption.
19897e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      case CK_ObjCReclaimReturnedObject: {
19907e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce->getSubExpr());
19917e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
19927e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall        return TryEmitResult(result, true);
19937e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall      }
19947e5e5f4cc36fe50f46ad76dca7a266434c94f475John McCall
1995f85e193739c953358c865005855253af4f68a497John McCall      case CK_GetObjCProperty: {
1996f85e193739c953358c865005855253af4f68a497John McCall        llvm::Value *result = emitARCRetainCall(CGF, ce);
1997f85e193739c953358c865005855253af4f68a497John McCall        if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
1998f85e193739c953358c865005855253af4f68a497John McCall        return TryEmitResult(result, true);
1999f85e193739c953358c865005855253af4f68a497John McCall      }
2000f85e193739c953358c865005855253af4f68a497John McCall
2001f85e193739c953358c865005855253af4f68a497John McCall      default:
2002f85e193739c953358c865005855253af4f68a497John McCall        break;
2003f85e193739c953358c865005855253af4f68a497John McCall      }
2004f85e193739c953358c865005855253af4f68a497John McCall
2005f85e193739c953358c865005855253af4f68a497John McCall    // Skip __extension__.
2006f85e193739c953358c865005855253af4f68a497John McCall    } else if (const UnaryOperator *op = dyn_cast<UnaryOperator>(e)) {
2007f85e193739c953358c865005855253af4f68a497John McCall      if (op->getOpcode() == UO_Extension) {
2008f85e193739c953358c865005855253af4f68a497John McCall        e = op->getSubExpr();
2009f85e193739c953358c865005855253af4f68a497John McCall        continue;
2010f85e193739c953358c865005855253af4f68a497John McCall      }
2011f85e193739c953358c865005855253af4f68a497John McCall
2012f85e193739c953358c865005855253af4f68a497John McCall    // For calls and message sends, use the retained-call logic.
2013f85e193739c953358c865005855253af4f68a497John McCall    // Delegate inits are a special case in that they're the only
2014f85e193739c953358c865005855253af4f68a497John McCall    // returns-retained expression that *isn't* surrounded by
2015f85e193739c953358c865005855253af4f68a497John McCall    // a consume.
2016f85e193739c953358c865005855253af4f68a497John McCall    } else if (isa<CallExpr>(e) ||
2017f85e193739c953358c865005855253af4f68a497John McCall               (isa<ObjCMessageExpr>(e) &&
2018f85e193739c953358c865005855253af4f68a497John McCall                !cast<ObjCMessageExpr>(e)->isDelegateInitCall())) {
2019f85e193739c953358c865005855253af4f68a497John McCall      llvm::Value *result = emitARCRetainCall(CGF, e);
2020f85e193739c953358c865005855253af4f68a497John McCall      if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2021f85e193739c953358c865005855253af4f68a497John McCall      return TryEmitResult(result, true);
2022f85e193739c953358c865005855253af4f68a497John McCall    }
2023f85e193739c953358c865005855253af4f68a497John McCall
2024f85e193739c953358c865005855253af4f68a497John McCall    // Conservatively halt the search at any other expression kind.
2025f85e193739c953358c865005855253af4f68a497John McCall    break;
2026f85e193739c953358c865005855253af4f68a497John McCall  }
2027f85e193739c953358c865005855253af4f68a497John McCall
2028f85e193739c953358c865005855253af4f68a497John McCall  // We didn't find an obvious production, so emit what we've got and
2029f85e193739c953358c865005855253af4f68a497John McCall  // tell the caller that we didn't manage to retain.
2030f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *result = CGF.EmitScalarExpr(e);
2031f85e193739c953358c865005855253af4f68a497John McCall  if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
2032f85e193739c953358c865005855253af4f68a497John McCall  return TryEmitResult(result, false);
2033f85e193739c953358c865005855253af4f68a497John McCall}
2034f85e193739c953358c865005855253af4f68a497John McCall
2035f85e193739c953358c865005855253af4f68a497John McCallstatic llvm::Value *emitARCRetainLoadOfScalar(CodeGenFunction &CGF,
2036f85e193739c953358c865005855253af4f68a497John McCall                                                LValue lvalue,
2037f85e193739c953358c865005855253af4f68a497John McCall                                                QualType type) {
2038f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainLoadOfScalar(CGF, lvalue, type);
2039f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2040f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2041f85e193739c953358c865005855253af4f68a497John McCall    value = CGF.EmitARCRetain(type, value);
2042f85e193739c953358c865005855253af4f68a497John McCall  return value;
2043f85e193739c953358c865005855253af4f68a497John McCall}
2044f85e193739c953358c865005855253af4f68a497John McCall
2045f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainScalarExpr - Semantically equivalent to
2046f85e193739c953358c865005855253af4f68a497John McCall/// EmitARCRetainObject(e->getType(), EmitScalarExpr(e)), but making a
2047f85e193739c953358c865005855253af4f68a497John McCall/// best-effort attempt to peephole expressions that naturally produce
2048f85e193739c953358c865005855253af4f68a497John McCall/// retained objects.
2049f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *CodeGenFunction::EmitARCRetainScalarExpr(const Expr *e) {
2050f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2051f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2052f85e193739c953358c865005855253af4f68a497John McCall  if (!result.getInt())
2053f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetain(e->getType(), value);
2054f85e193739c953358c865005855253af4f68a497John McCall  return value;
2055f85e193739c953358c865005855253af4f68a497John McCall}
2056f85e193739c953358c865005855253af4f68a497John McCall
2057f85e193739c953358c865005855253af4f68a497John McCallllvm::Value *
2058f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCRetainAutoreleaseScalarExpr(const Expr *e) {
2059f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e);
2060f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2061f85e193739c953358c865005855253af4f68a497John McCall  if (result.getInt())
2062f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCAutorelease(value);
2063f85e193739c953358c865005855253af4f68a497John McCall  else
2064f85e193739c953358c865005855253af4f68a497John McCall    value = EmitARCRetainAutorelease(e->getType(), value);
2065f85e193739c953358c865005855253af4f68a497John McCall  return value;
2066f85e193739c953358c865005855253af4f68a497John McCall}
2067f85e193739c953358c865005855253af4f68a497John McCall
2068f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2069f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreStrong(const BinaryOperator *e,
2070f85e193739c953358c865005855253af4f68a497John McCall                                    bool ignored) {
2071f85e193739c953358c865005855253af4f68a497John McCall  // Evaluate the RHS first.
2072f85e193739c953358c865005855253af4f68a497John McCall  TryEmitResult result = tryEmitARCRetainScalarExpr(*this, e->getRHS());
2073f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = result.getPointer();
2074f85e193739c953358c865005855253af4f68a497John McCall
2075f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2076f85e193739c953358c865005855253af4f68a497John McCall
2077f85e193739c953358c865005855253af4f68a497John McCall  // If the RHS was emitted retained, expand this.
2078f85e193739c953358c865005855253af4f68a497John McCall  if (result.getInt()) {
2079f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *oldValue =
2080f85e193739c953358c865005855253af4f68a497John McCall      EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatileQualified(),
2081f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getAlignment(), e->getType(),
2082f85e193739c953358c865005855253af4f68a497John McCall                       lvalue.getTBAAInfo());
2083f85e193739c953358c865005855253af4f68a497John McCall    EmitStoreOfScalar(value, lvalue.getAddress(),
2084f85e193739c953358c865005855253af4f68a497John McCall                      lvalue.isVolatileQualified(), lvalue.getAlignment(),
2085f85e193739c953358c865005855253af4f68a497John McCall                      e->getType(), lvalue.getTBAAInfo());
2086f85e193739c953358c865005855253af4f68a497John McCall    EmitARCRelease(oldValue, /*precise*/ false);
2087f85e193739c953358c865005855253af4f68a497John McCall  } else {
2088545d996ec5a3113f046944f11b27cc2d6cb055b4John McCall    value = EmitARCStoreStrong(lvalue, value, ignored);
2089f85e193739c953358c865005855253af4f68a497John McCall  }
2090f85e193739c953358c865005855253af4f68a497John McCall
2091f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2092f85e193739c953358c865005855253af4f68a497John McCall}
2093f85e193739c953358c865005855253af4f68a497John McCall
2094f85e193739c953358c865005855253af4f68a497John McCallstd::pair<LValue,llvm::Value*>
2095f85e193739c953358c865005855253af4f68a497John McCallCodeGenFunction::EmitARCStoreAutoreleasing(const BinaryOperator *e) {
2096f85e193739c953358c865005855253af4f68a497John McCall  llvm::Value *value = EmitARCRetainAutoreleaseScalarExpr(e->getRHS());
2097f85e193739c953358c865005855253af4f68a497John McCall  LValue lvalue = EmitLValue(e->getLHS());
2098f85e193739c953358c865005855253af4f68a497John McCall
2099f85e193739c953358c865005855253af4f68a497John McCall  EmitStoreOfScalar(value, lvalue.getAddress(),
2100f85e193739c953358c865005855253af4f68a497John McCall                    lvalue.isVolatileQualified(), lvalue.getAlignment(),
2101f85e193739c953358c865005855253af4f68a497John McCall                    e->getType(), lvalue.getTBAAInfo());
2102f85e193739c953358c865005855253af4f68a497John McCall
2103f85e193739c953358c865005855253af4f68a497John McCall  return std::pair<LValue,llvm::Value*>(lvalue, value);
2104f85e193739c953358c865005855253af4f68a497John McCall}
2105f85e193739c953358c865005855253af4f68a497John McCall
2106f85e193739c953358c865005855253af4f68a497John McCallvoid CodeGenFunction::EmitObjCAutoreleasePoolStmt(
2107f85e193739c953358c865005855253af4f68a497John McCall                                             const ObjCAutoreleasePoolStmt &ARPS) {
2108f85e193739c953358c865005855253af4f68a497John McCall  const Stmt *subStmt = ARPS.getSubStmt();
2109f85e193739c953358c865005855253af4f68a497John McCall  const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
2110f85e193739c953358c865005855253af4f68a497John McCall
2111f85e193739c953358c865005855253af4f68a497John McCall  CGDebugInfo *DI = getDebugInfo();
2112f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2113f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getLBracLoc());
2114f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionStart(Builder);
2115f85e193739c953358c865005855253af4f68a497John McCall  }
2116f85e193739c953358c865005855253af4f68a497John McCall
2117f85e193739c953358c865005855253af4f68a497John McCall  // Keep track of the current cleanup stack depth.
2118f85e193739c953358c865005855253af4f68a497John McCall  RunCleanupsScope Scope(*this);
21199f084a3166b684573ba49df28fc5792bc37d92e1John McCall  if (CGM.getCodeGenOpts().ObjCRuntimeHasARC) {
2120f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCAutoreleasePoolPush();
2121f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token);
2122f85e193739c953358c865005855253af4f68a497John McCall  } else {
2123f85e193739c953358c865005855253af4f68a497John McCall    llvm::Value *token = EmitObjCMRRAutoreleasePoolPush();
2124f85e193739c953358c865005855253af4f68a497John McCall    EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token);
2125f85e193739c953358c865005855253af4f68a497John McCall  }
2126f85e193739c953358c865005855253af4f68a497John McCall
2127f85e193739c953358c865005855253af4f68a497John McCall  for (CompoundStmt::const_body_iterator I = S.body_begin(),
2128f85e193739c953358c865005855253af4f68a497John McCall       E = S.body_end(); I != E; ++I)
2129f85e193739c953358c865005855253af4f68a497John McCall    EmitStmt(*I);
2130f85e193739c953358c865005855253af4f68a497John McCall
2131f85e193739c953358c865005855253af4f68a497John McCall  if (DI) {
2132f85e193739c953358c865005855253af4f68a497John McCall    DI->setLocation(S.getRBracLoc());
2133f85e193739c953358c865005855253af4f68a497John McCall    DI->EmitRegionEnd(Builder);
2134f85e193739c953358c865005855253af4f68a497John McCall  }
2135f85e193739c953358c865005855253af4f68a497John McCall}
21360c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
21370c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// EmitExtendGCLifetime - Given a pointer to an Objective-C object,
21380c24c808e4dce43e88abf2d5f98546b901bd4315John McCall/// make sure it survives garbage collection until this point.
21390c24c808e4dce43e88abf2d5f98546b901bd4315John McCallvoid CodeGenFunction::EmitExtendGCLifetime(llvm::Value *object) {
21400c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  // We just use an inline assembly.
21419cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::Type *paramTypes[] = { VoidPtrTy };
21420c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::FunctionType *extenderType
21430c24c808e4dce43e88abf2d5f98546b901bd4315John McCall    = llvm::FunctionType::get(VoidTy, paramTypes, /*variadic*/ false);
21440c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  llvm::Value *extender
21450c24c808e4dce43e88abf2d5f98546b901bd4315John McCall    = llvm::InlineAsm::get(extenderType,
21460c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* assembly */ "",
21470c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* constraints */ "r",
21480c24c808e4dce43e88abf2d5f98546b901bd4315John McCall                           /* side effects */ true);
21490c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
21500c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  object = Builder.CreateBitCast(object, VoidPtrTy);
21510c24c808e4dce43e88abf2d5f98546b901bd4315John McCall  Builder.CreateCall(extender, object)->setDoesNotThrow();
21520c24c808e4dce43e88abf2d5f98546b901bd4315John McCall}
21530c24c808e4dce43e88abf2d5f98546b901bd4315John McCall
21542979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
2155