CGObjC.cpp revision 46f45b9bec4a265ad8400a538e5ec3a5683617f1
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
142979ec73b4f974d85f2ce84167712177a44c6f09Ted Kremenek#include "CGObjCRuntime.h"
155508518a2702b00be3b15a26d772bde968972f54Anders Carlsson#include "CodeGenFunction.h"
165508518a2702b00be3b15a26d772bde968972f54Anders Carlsson#include "CodeGenModule.h"
1785c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar#include "clang/AST/ASTContext.h"
18c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/DeclObjC.h"
19e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar#include "clang/Basic/Diagnostic.h"
203d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson#include "llvm/ADT/STLExtras.h"
214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
225508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace clang;
235508518a2702b00be3b15a26d772bde968972f54Anders Carlssonusing namespace CodeGen;
245508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
258fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emits an instance of NSConstantString representing the object.
26bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbarllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) {
27bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  std::string String(E->getString()->getStrData(), E->getString()->getByteLength());
28bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(String);
29ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar  // FIXME: This bitcast should just be made an invariant on the Runtime.
30bbce49b9e5c6d7f05926b89f8e6fd235ae01c250Daniel Dunbar  return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
318fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
328fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
338fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner/// Emit a selector.
348fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattnerllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
358fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Untyped selector.
368fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Note that this implementation allows for non-constant strings to be passed
378fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // as arguments to @selector().  Currently, the only thing preventing this
388fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // behaviour is the type checking in the front end.
39208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar  return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
408fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner}
418fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
42ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbarllvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
43ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar  // FIXME: This should pass the Decl not the name.
44ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar  return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol());
45ed7c618f849e2541b1d0288c43154937652c5b15Daniel Dunbar}
468fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
478fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
488f2926b73ed635afecd020da787af6a837601a2bDaniel DunbarRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
498fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Only the lookup mechanism and first two arguments of the method
508fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // implementation vary between runtimes.  We can get the receiver and
518fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // arguments in generic code.
528fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
53208ff5e8a073de2a5d15cbe03cab8a4c0d935e28Daniel Dunbar  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
548fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  const Expr *ReceiverExpr = E->getReceiver();
558fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  bool isSuperMessage = false;
56f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar  bool isClassMessage = false;
578fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  // Find the receiver
588fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  llvm::Value *Receiver;
598fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  if (!ReceiverExpr) {
60ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar    const ObjCInterfaceDecl *OID = E->getClassInfo().first;
61ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar
62ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar    // Very special case, super send in class method. The receiver is
63ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar    // self (the class object) and the send uses super semantics.
64ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar    if (!OID) {
65ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar      assert(!strcmp(E->getClassName()->getName(), "super") &&
66ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar             "Unexpected missing class interface in message send.");
67ddb2a3d55a24a1dbdf9152621642d9a4b4fc2f61Daniel Dunbar      isSuperMessage = true;
68f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar      Receiver = LoadObjCSelf();
69f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    } else {
70f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar      Receiver = Runtime.GetClass(Builder, OID);
718fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    }
72f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar
73f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar    isClassMessage = true;
74d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner  } else if (const PredefinedExpr *PDE =
75d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner               dyn_cast<PredefinedExpr>(E->getReceiver())) {
76d9f6910f4ef37c0e8eeee2a01287d9572c3176efChris Lattner    assert(PDE->getIdentType() == PredefinedExpr::ObjCSuper);
778fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    isSuperMessage = true;
788fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner    Receiver = LoadObjCSelf();
798fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  } else {
802bedbf8549bb33293c6a53e5da6cbd8de290d014Daniel Dunbar    Receiver = EmitScalarExpr(E->getReceiver());
818fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
828fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner
8319cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  CallArgList Args;
8419cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar  for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
8519cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar       i != e; ++i)
8646f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar    Args.push_back(std::make_pair(EmitAnyExprToTemp(*i), (*i)->getType()));
8719cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar
888fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  if (isSuperMessage) {
899384c768e93f270118a30ce96546083a666da284Chris Lattner    // super is only valid in an Objective-C method
909384c768e93f270118a30ce96546083a666da284Chris Lattner    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
917f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar    return Runtime.GenerateMessageSendSuper(*this, E->getType(),
927f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                            E->getSelector(),
93f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                            OMD->getClassInterface(),
94f56f1913e91ad32bed52dd3f6afc26735d336584Daniel Dunbar                                            Receiver,
9519cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar                                            isClassMessage,
9619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar                                            Args);
978fdf32822be2238aa7db62d40e75b168b637ab7dChris Lattner  }
987f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
997f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                     Receiver, isClassMessage, Args);
1005508518a2702b00be3b15a26d772bde968972f54Anders Carlsson}
1015508518a2702b00be3b15a26d772bde968972f54Anders Carlsson
102af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
103af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// the LLVM function and sets the other context used by
104af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// CodeGenFunction.
105af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
106af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: This should really be merged with GenerateCode.
107af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) {
1087ded7f4983dc4a20561db7a8d02c6b2435030961Daniel Dunbar  CurFn = CGM.getObjCRuntime().GenerateMethod(OMD);
109f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar
110f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar  CGM.SetMethodAttributes(OMD, CurFn);
111f80519b919a348db004fba18530706314d1ebfb5Daniel Dunbar
1124111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
1134111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1144111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Create a marker to make it easy to insert allocas into the entryblock
1154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // later.  Don't create this with the builder, because we don't want it
1164111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // folded.
1174111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
1184111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
1194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                         EntryBB);
1204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  FnRetTy = OMD->getResultType();
1224111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  CurFuncDecl = OMD;
1234111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1244111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  Builder.SetInsertPoint(EntryBB);
1254111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1264111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Emit allocs for param decls.  Give the LLVM Argument nodes names.
1274111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Function::arg_iterator AI = CurFn->arg_begin();
1284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
129b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  // Name the struct return argument.
1304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  if (hasAggregateLLVMType(OMD->getResultType())) {
131b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar    AI->setName("agg.result");
1324111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    ++AI;
1334111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
134b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
1354111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Add implicit parameters to the decl map.
136b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  EmitParmDecl(*OMD->getSelfDecl(), AI);
137b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  ++AI;
138b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
139b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  EmitParmDecl(*OMD->getCmdDecl(), AI);
1404111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ++AI;
1414111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1424111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
1434111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    assert(AI != CurFn->arg_end() && "Argument mismatch!");
1444111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    EmitParmDecl(*OMD->getParamDecl(i), AI);
1454111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
146b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  assert(AI == CurFn->arg_end() && "Argument mismatch");
147af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
148af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
149af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method.  An Objective-C method is a C function with
150af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// its pointer, name, and types registered in the class struture.
151af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
152af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  StartObjCMethod(OMD);
153af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  EmitStmt(OMD->getBody());
154af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
155af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const CompoundStmt *S = dyn_cast<CompoundStmt>(OMD->getBody());
156af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  if (S) {
157af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    FinishFunction(S->getRBracLoc());
158af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  } else {
159af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    FinishFunction();
160af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  }
161af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
162af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
163af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: I wasn't sure about the synthesis approach. If we end up
164af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// generating an AST for the whole body we can just fall back to
165af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// having a GenerateFunction which takes the body Stmt.
166af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
167af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter
168af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl
169af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl.
170af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) {
171af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
172af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
173af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate getter (empty method)");
174af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: This is rather murky, we create this here since they will
175af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // not have been created by Sema for us.
176af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  OMD->createImplicitParams(getContext());
177af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  StartObjCMethod(OMD);
178af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
179af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: What about nonatomic?
180af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  SourceLocation Loc = PD->getLocation();
181af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ValueDecl *Self = OMD->getSelfDecl();
182af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
183af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  DeclRefExpr Base(Self, Self->getType(), Loc);
184af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
185af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar                          true, true);
186af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ReturnStmt Return(Loc, &IvarRef);
187af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  EmitStmt(&Return);
188af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
189af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
190af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
191af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
192af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCSetter - Generate an Objective-C property setter
193af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl
194af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl.
195af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) {
196af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
197af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
198af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate setter (empty method)");
199af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: This is rather murky, we create this here since they will
200af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // not have been created by Sema for us.
201af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  OMD->createImplicitParams(getContext());
202af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  StartObjCMethod(OMD);
203af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
204af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  switch (PD->getSetterKind()) {
205af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  case ObjCPropertyDecl::Assign: break;
206af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  case ObjCPropertyDecl::Copy:
207af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C setter with 'copy'");
208af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      break;
209af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  case ObjCPropertyDecl::Retain:
210af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C setter with 'retain'");
211af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      break;
212af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  }
213b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
214af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: What about nonatomic?
215af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  SourceLocation Loc = PD->getLocation();
216af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ValueDecl *Self = OMD->getSelfDecl();
217af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
218af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  DeclRefExpr Base(Self, Self->getType(), Loc);
219af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ParmVarDecl *ArgDecl = OMD->getParamDecl(0);
220af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
221af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
222af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar                          true, true);
223af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
224af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar                        Ivar->getType(), Loc);
225af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  EmitStmt(&Assign);
226af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
227af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
2284111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
2294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
230b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf(void) {
231b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
232b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
2334111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
2344111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
2359c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel DunbarRValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) {
2369c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  // Determine getter selector.
2379c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  Selector S;
238e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
239e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    S = E->getGetterMethod()->getSelector();
2409c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  } else {
241e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    S = E->getProperty()->getGetterName();
2429c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  }
2439c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
2447f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  return CGM.getObjCRuntime().
2457f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar    GenerateMessageSend(*this, E->getType(), S,
2467f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                        EmitScalarExpr(E->getBase()),
2477f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                        false, CallArgList());
2489c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar}
2499c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
25085c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbarvoid CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E,
25185c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar                                          RValue Src) {
2527f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  Selector S;
253e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
254e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    ObjCMethodDecl *Setter = E->getSetterMethod();
255e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar
256e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    if (Setter) {
257e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      S = Setter->getSelector();
258e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    } else {
259e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      // FIXME: This should be diagnosed by sema.
260e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      SourceRange Range = E->getSourceRange();
261e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()),
262e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar                            diag::err_typecheck_assign_const, 0, 0,
263e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar                            &Range, 1);
264e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      return;
265e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    }
2667f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  } else {
267e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    S = E->getProperty()->getSetterName();
2687f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  }
2697f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar
2707f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  CallArgList Args;
27146f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar  Args.push_back(std::make_pair(Src, E->getType()));
2727f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
2737f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                           EmitScalarExpr(E->getBase()),
2747f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                           false, Args);
27585c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar}
27685c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar
2773d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlssonvoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
2783d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson{
279f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *DeclAddress;
280f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ElementTy;
281f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
282f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
283f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    EmitStmt(SD);
284f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
285f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    ElementTy = cast<ValueDecl>(SD->getDecl())->getType();
286f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    DeclAddress = LocalDeclMap[SD->getDecl()];
287f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  } else {
288f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    ElementTy = cast<Expr>(S.getElement())->getType();
289f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    DeclAddress = 0;
290f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
291f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
292f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fast enumeration state.
293f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType StateTy = getContext().getObjCFastEnumerationStateType();
294f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertType(StateTy),
295f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                                "state.ptr");
296f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3);
2972abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitMemSetToZero(StatePtr, StateTy);
298f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
299f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Number of elements in the items array.
3002abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  static const unsigned NumItems = 16;
301f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
302f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Get selector
303f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::SmallVector<IdentifierInfo*, 3> II;
304f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  II.push_back(&CGM.getContext().Idents.get("countByEnumeratingWithState"));
305f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  II.push_back(&CGM.getContext().Idents.get("objects"));
306f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  II.push_back(&CGM.getContext().Idents.get("count"));
307f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Selector FastEnumSel = CGM.getContext().Selectors.getSelector(II.size(),
308f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                                                &II[0]);
309f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
310f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ItemsTy =
311f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    getContext().getConstantArrayType(getContext().getObjCIdType(),
312f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      llvm::APInt(32, NumItems),
313f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ArrayType::Normal, 0);
314f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *ItemsPtr = CreateTempAlloca(ConvertType(ItemsTy), "items.ptr");
315f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
316f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Collection = EmitScalarExpr(S.getCollection());
317f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
318f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CallArgList Args;
31946f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar  Args.push_back(std::make_pair(RValue::get(StatePtr),
320f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                getContext().getPointerType(StateTy)));
321f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
32246f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar  Args.push_back(std::make_pair(RValue::get(ItemsPtr),
323f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                getContext().getPointerType(ItemsTy)));
324f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
325f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
326f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
32746f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar  Args.push_back(std::make_pair(RValue::get(Count),
32846f45b9bec4a265ad8400a538e5ec3a5683617f1Daniel Dunbar                                getContext().UnsignedLongTy));
329f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
330f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  RValue CountRV =
331f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    CGM.getObjCRuntime().GenerateMessageSend(*this,
332f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
333f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
334f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             Collection, false, Args);
335f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
336f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *LimitPtr = CreateTempAlloca(UnsignedLongLTy, "limit.ptr");
337f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
338f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
339f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *NoElements = llvm::BasicBlock::Create("noelements");
3402abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *SetStartMutations =
3412abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    llvm::BasicBlock::Create("setstartmutations");
342f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
343f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Limit = Builder.CreateLoad(LimitPtr);
344f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy);
345f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
346f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
3472abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateCondBr(IsZero, NoElements, SetStartMutations);
348f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
3492abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitBlock(SetStartMutations);
3502abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3512abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StartMutationsPtr =
3522abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    CreateTempAlloca(UnsignedLongLTy);
3532abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3542abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StateMutationsPtrPtr =
3552abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
3562abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
3572abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                      "mutationsptr");
3582abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3592abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr,
3602abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                   "mutations");
3612abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3622abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateStore(StateMutations, StartMutationsPtr);
3632abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3642abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *LoopStart = llvm::BasicBlock::Create("loopstart");
365f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(LoopStart);
366f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
367f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr");
368f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(Zero, CounterPtr);
369f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
3702abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("loopbody");
371f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(LoopBody);
372f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
3732abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
3742abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations");
3752abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3762abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr,
3772abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                   "mutations");
3782abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations,
3792abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                     StartMutations,
3802abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                     "tobool");
3812abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3822abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3832abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *WasMutated = llvm::BasicBlock::Create("wasmutated");
3842abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *WasNotMutated = llvm::BasicBlock::Create("wasnotmutated");
3852abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3862abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated);
3872abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3882abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitBlock(WasMutated);
3892abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *V =
3902abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateBitCast(Collection,
3912abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          ConvertType(getContext().getObjCIdType()),
3922abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          "tmp");
3932abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateCall(CGM.getObjCRuntime().EnumerationMutationFunction(),
3942abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                     V);
3952abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3962abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitBlock(WasNotMutated);
3972abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
398f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *StateItemsPtr =
399f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
400f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
401f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter");
402f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
403f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr,
404f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                                   "stateitems");
405f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
406f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *CurrentItemPtr =
407f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr");
408f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
409f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem");
410f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
411f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Cast the item to the right type.
412f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CurrentItem = Builder.CreateBitCast(CurrentItem,
413f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ConvertType(ElementTy), "tmp");
414f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
415f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  if (!DeclAddress) {
416f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
417f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
418f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // Set the value to null.
419f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStore(CurrentItem, LV.getAddress());
420f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  } else
421f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStore(CurrentItem, DeclAddress);
422f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
423f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Increment the counter.
424f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Counter = Builder.CreateAdd(Counter,
425f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                              llvm::ConstantInt::get(UnsignedLongLTy, 1));
426f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(Counter, CounterPtr);
427f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
428f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *LoopEnd = llvm::BasicBlock::Create("loopend");
429f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *AfterBody = llvm::BasicBlock::Create("afterbody");
430f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
431f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
432f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
433f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitStmt(S.getBody());
434f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
435f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.pop_back();
436f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
437f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(AfterBody);
438f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
439f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *FetchMore = llvm::BasicBlock::Create("fetchmore");
440f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
441f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless");
442fe2b2c08984f861f82339138302689480c658ecdDaniel Dunbar  Builder.CreateCondBr(IsLess, LoopBody, FetchMore);
443f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
444f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fetch more elements.
445f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(FetchMore);
446f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
447f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CountRV =
448f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    CGM.getObjCRuntime().GenerateMessageSend(*this,
449f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
450f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
451f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             Collection, false, Args);
452f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
453f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Limit = Builder.CreateLoad(LimitPtr);
454f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
455f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
456f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateCondBr(IsZero, NoElements, LoopStart);
457f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
458f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // No more elements.
459f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(NoElements);
460f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
461f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  if (!DeclAddress) {
462f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // If the element was not a declaration, set it to be null.
463f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
464f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
465f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
466f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // Set the value to null.
467f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)),
468f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                        LV.getAddress());
469f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
470f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
471f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(LoopEnd);
4723d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
4733d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
4742979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
475