CGObjC.cpp revision e66f4e3e3ae9d7d11b0c302211066fad69228aba
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)
8619cd87eb5fb3c197e631ce08fd52c446c4d4e8f1Daniel Dunbar    EmitCallArg(*i, Args);
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);
1094111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
1104111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1114111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Create a marker to make it easy to insert allocas into the entryblock
1124111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // later.  Don't create this with the builder, because we don't want it
1134111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // folded.
1144111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
1154111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
1164111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner                                         EntryBB);
1174111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1184111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  FnRetTy = OMD->getResultType();
1194111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  CurFuncDecl = OMD;
1204111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1214111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  Builder.SetInsertPoint(EntryBB);
1224111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1234111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Emit allocs for param decls.  Give the LLVM Argument nodes names.
1244111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  llvm::Function::arg_iterator AI = CurFn->arg_begin();
1254111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
126b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  // Name the struct return argument.
1274111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  if (hasAggregateLLVMType(OMD->getResultType())) {
128b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar    AI->setName("agg.result");
1294111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    ++AI;
1304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
131b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
1324111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  // Add implicit parameters to the decl map.
133b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  EmitParmDecl(*OMD->getSelfDecl(), AI);
134b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  ++AI;
135b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
136b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  EmitParmDecl(*OMD->getCmdDecl(), AI);
1374111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  ++AI;
1384111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
1394111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  for (unsigned i = 0, e = OMD->getNumParams(); i != e; ++i, ++AI) {
1404111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    assert(AI != CurFn->arg_end() && "Argument mismatch!");
1414111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner    EmitParmDecl(*OMD->getParamDecl(i), AI);
1424111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  }
143b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  assert(AI == CurFn->arg_end() && "Argument mismatch");
144af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
145af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
146af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// Generate an Objective-C method.  An Objective-C method is a C function with
147af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// its pointer, name, and types registered in the class struture.
148af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
149af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  StartObjCMethod(OMD);
150af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  EmitStmt(OMD->getBody());
151af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
152af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const CompoundStmt *S = dyn_cast<CompoundStmt>(OMD->getBody());
153af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  if (S) {
154af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    FinishFunction(S->getRBracLoc());
155af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  } else {
156af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar    FinishFunction();
157af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  }
158af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
159af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
160af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// FIXME: I wasn't sure about the synthesis approach. If we end up
161af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// generating an AST for the whole body we can just fall back to
162af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar// having a GenerateFunction which takes the body Stmt.
163af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
164af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCGetter - Generate an Objective-C property getter
165af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl
166af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl.
167af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) {
168af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
169af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
170af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate getter (empty method)");
171af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: This is rather murky, we create this here since they will
172af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // not have been created by Sema for us.
173af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  OMD->createImplicitParams(getContext());
174af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  StartObjCMethod(OMD);
175af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
176af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: What about nonatomic?
177af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  SourceLocation Loc = PD->getLocation();
178af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ValueDecl *Self = OMD->getSelfDecl();
179af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
180af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  DeclRefExpr Base(Self, Self->getType(), Loc);
181af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
182af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar                          true, true);
183af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ReturnStmt Return(Loc, &IvarRef);
184af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  EmitStmt(&Return);
185af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
186af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
187af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar}
188af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
189af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// GenerateObjCSetter - Generate an Objective-C property setter
190af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// function. The given Decl must be either an ObjCCategoryImplDecl
191af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar/// or an ObjCImplementationDecl.
192af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbarvoid CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) {
193af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
194af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
195af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  assert(OMD && "Invalid call to generate setter (empty method)");
196af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: This is rather murky, we create this here since they will
197af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // not have been created by Sema for us.
198af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  OMD->createImplicitParams(getContext());
199af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  StartObjCMethod(OMD);
200af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
201af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  switch (PD->getSetterKind()) {
202af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  case ObjCPropertyDecl::Assign: break;
203af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  case ObjCPropertyDecl::Copy:
204af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C setter with 'copy'");
205af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      break;
206af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  case ObjCPropertyDecl::Retain:
207af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      CGM.ErrorUnsupported(PID, "Obj-C setter with 'retain'");
208af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar      break;
209af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  }
210b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar
211af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  // FIXME: What about nonatomic?
212af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  SourceLocation Loc = PD->getLocation();
213af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ValueDecl *Self = OMD->getSelfDecl();
214af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
215af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  DeclRefExpr Base(Self, Self->getType(), Loc);
216af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ParmVarDecl *ArgDecl = OMD->getParamDecl(0);
217af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
218af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base,
219af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar                          true, true);
220af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
221af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar                        Ivar->getType(), Loc);
222af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  EmitStmt(&Assign);
223af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar
224af05bb9073319d8381b71c4325188853fd4b8ed6Daniel Dunbar  FinishFunction();
2254111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
2264111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
227b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbarllvm::Value *CodeGenFunction::LoadObjCSelf(void) {
228b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
229b7ec246872b412f0e7bb9e93eacfd78cfa6adfb3Daniel Dunbar  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
2304111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner}
2314111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner
2329c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel DunbarRValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) {
2339c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  // Determine getter selector.
2349c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  Selector S;
235e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
236e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    S = E->getGetterMethod()->getSelector();
2379c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  } else {
238e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    S = E->getProperty()->getGetterName();
2399c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar  }
2409c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
2417f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  return CGM.getObjCRuntime().
2427f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar    GenerateMessageSend(*this, E->getType(), S,
2437f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                        EmitScalarExpr(E->getBase()),
2447f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                        false, CallArgList());
2459c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar}
2469c3fc703b29a31d40bcf5027dbb4784dd393804eDaniel Dunbar
24785c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbarvoid CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E,
24885c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar                                          RValue Src) {
2497f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  Selector S;
250e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar  if (E->getKind() == ObjCPropertyRefExpr::MethodRef) {
251e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    ObjCMethodDecl *Setter = E->getSetterMethod();
252e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar
253e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    if (Setter) {
254e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      S = Setter->getSelector();
255e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    } else {
256e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      // FIXME: This should be diagnosed by sema.
257e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      SourceRange Range = E->getSourceRange();
258e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      CGM.getDiags().Report(getContext().getFullLoc(E->getLocStart()),
259e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar                            diag::err_typecheck_assign_const, 0, 0,
260e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar                            &Range, 1);
261e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar      return;
262e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    }
2637f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  } else {
264e66f4e3e3ae9d7d11b0c302211066fad69228abaDaniel Dunbar    S = E->getProperty()->getSetterName();
2657f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  }
2667f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar
2677f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  CallArgList Args;
2687f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  EmitCallArg(Src, E->getType(), Args);
2697f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar  CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
2707f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                           EmitScalarExpr(E->getBase()),
2717f8ea5c5b3a6a4332a841eefdd86b0726722ea7bDaniel Dunbar                                           false, Args);
27285c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar}
27385c59edda02df48fae8dc85049743319bc6e7e89Daniel Dunbar
2743d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlssonvoid CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
2753d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson{
276f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *DeclAddress;
277f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ElementTy;
278f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
279f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
280f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    EmitStmt(SD);
281f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
282f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    ElementTy = cast<ValueDecl>(SD->getDecl())->getType();
283f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    DeclAddress = LocalDeclMap[SD->getDecl()];
284f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  } else {
285f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    ElementTy = cast<Expr>(S.getElement())->getType();
286f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    DeclAddress = 0;
287f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
288f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
289f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fast enumeration state.
290f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType StateTy = getContext().getObjCFastEnumerationStateType();
291f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertType(StateTy),
292f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                                "state.ptr");
293f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3);
2942abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitMemSetToZero(StatePtr, StateTy);
295f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
296f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Number of elements in the items array.
2972abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  static const unsigned NumItems = 16;
298f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
299f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Get selector
300f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::SmallVector<IdentifierInfo*, 3> II;
301f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  II.push_back(&CGM.getContext().Idents.get("countByEnumeratingWithState"));
302f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  II.push_back(&CGM.getContext().Idents.get("objects"));
303f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  II.push_back(&CGM.getContext().Idents.get("count"));
304f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Selector FastEnumSel = CGM.getContext().Selectors.getSelector(II.size(),
305f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                                                &II[0]);
306f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
307f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  QualType ItemsTy =
308f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    getContext().getConstantArrayType(getContext().getObjCIdType(),
309f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      llvm::APInt(32, NumItems),
310f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ArrayType::Normal, 0);
311f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *ItemsPtr = CreateTempAlloca(ConvertType(ItemsTy), "items.ptr");
312f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
313f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Collection = EmitScalarExpr(S.getCollection());
314f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
315f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CallArgList Args;
316f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Args.push_back(std::make_pair(StatePtr,
317f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                getContext().getPointerType(StateTy)));
318f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
319f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Args.push_back(std::make_pair(ItemsPtr,
320f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                getContext().getPointerType(ItemsTy)));
321f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
322f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
323f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
324f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Args.push_back(std::make_pair(Count, getContext().UnsignedLongTy));
325f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
326f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  RValue CountRV =
327f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    CGM.getObjCRuntime().GenerateMessageSend(*this,
328f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
329f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
330f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             Collection, false, Args);
331f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
332f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *LimitPtr = CreateTempAlloca(UnsignedLongLTy, "limit.ptr");
333f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
334f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
335f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *NoElements = llvm::BasicBlock::Create("noelements");
3362abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *SetStartMutations =
3372abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    llvm::BasicBlock::Create("setstartmutations");
338f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
339f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Limit = Builder.CreateLoad(LimitPtr);
340f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy);
341f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
342f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
3432abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateCondBr(IsZero, NoElements, SetStartMutations);
344f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
3452abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitBlock(SetStartMutations);
3462abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3472abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StartMutationsPtr =
3482abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    CreateTempAlloca(UnsignedLongLTy);
3492abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3502abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StateMutationsPtrPtr =
3512abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
3522abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
3532abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                      "mutationsptr");
3542abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3552abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr,
3562abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                   "mutations");
3572abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3582abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateStore(StateMutations, StartMutationsPtr);
3592abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3602abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *LoopStart = llvm::BasicBlock::Create("loopstart");
361f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(LoopStart);
362f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
363f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr");
364f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(Zero, CounterPtr);
365f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
3662abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("loopbody");
367f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(LoopBody);
368f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
3692abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
3702abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations");
3712abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3722abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr,
3732abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                   "mutations");
3742abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations,
3752abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                     StartMutations,
3762abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                                                     "tobool");
3772abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3782abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3792abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *WasMutated = llvm::BasicBlock::Create("wasmutated");
3802abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::BasicBlock *WasNotMutated = llvm::BasicBlock::Create("wasnotmutated");
3812abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3822abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated);
3832abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3842abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitBlock(WasMutated);
3852abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  llvm::Value *V =
3862abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson    Builder.CreateBitCast(Collection,
3872abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          ConvertType(getContext().getObjCIdType()),
3882abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                          "tmp");
3892abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateCall(CGM.getObjCRuntime().EnumerationMutationFunction(),
3902abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson                     V);
3912abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
3922abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  EmitBlock(WasNotMutated);
3932abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson
394f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *StateItemsPtr =
395f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
396f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
397f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter");
398f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
399f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr,
400f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                                   "stateitems");
401f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
402f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *CurrentItemPtr =
403f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr");
404f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
405f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem");
406f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
407f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Cast the item to the right type.
408f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CurrentItem = Builder.CreateBitCast(CurrentItem,
409f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                      ConvertType(ElementTy), "tmp");
410f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
411f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  if (!DeclAddress) {
412f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
413f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
414f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // Set the value to null.
415f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStore(CurrentItem, LV.getAddress());
416f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  } else
417f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStore(CurrentItem, DeclAddress);
418f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
419f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Increment the counter.
420f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Counter = Builder.CreateAdd(Counter,
421f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                              llvm::ConstantInt::get(UnsignedLongLTy, 1));
422f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(Counter, CounterPtr);
423f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
424f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *LoopEnd = llvm::BasicBlock::Create("loopend");
425f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *AfterBody = llvm::BasicBlock::Create("afterbody");
426f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
427f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
428f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
429f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitStmt(S.getBody());
430f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
431f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  BreakContinueStack.pop_back();
432f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
433f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(AfterBody);
434f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
435f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::BasicBlock *FetchMore = llvm::BasicBlock::Create("fetchmore");
436f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
437f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless");
4382abd89c039e835e84519a4cd8a7495899a70153dAnders Carlsson  Builder.CreateCondBr(IsLess, LoopStart, FetchMore);
439f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
440f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // Fetch more elements.
441f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(FetchMore);
442f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
443f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  CountRV =
444f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    CGM.getObjCRuntime().GenerateMessageSend(*this,
445f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             getContext().UnsignedLongTy,
446f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             FastEnumSel,
447f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                                             Collection, false, Args);
448f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
449f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Limit = Builder.CreateLoad(LimitPtr);
450f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
451f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
452f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  Builder.CreateCondBr(IsZero, NoElements, LoopStart);
453f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
454f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  // No more elements.
455f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(NoElements);
456f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
457f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  if (!DeclAddress) {
458f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // If the element was not a declaration, set it to be null.
459f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
460f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
461f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
462f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    // Set the value to null.
463f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson    Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)),
464f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson                        LV.getAddress());
465f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  }
466f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson
467f484c31f4d6934f56070c2942d4dfdf3fee84074Anders Carlsson  EmitBlock(LoopEnd);
4683d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson}
4693d8400d9a61aa4b63ff35e5cede405b32a41425eAnders Carlsson
4702979ec73b4f974d85f2ce84167712177a44c6f09Ted KremenekCGObjCRuntime::~CGObjCRuntime() {}
471