CGObjC.cpp revision 198893
1//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Objective-C code as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CGObjCRuntime.h"
15#include "CodeGenFunction.h"
16#include "CodeGenModule.h"
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/DeclObjC.h"
19#include "clang/AST/StmtObjC.h"
20#include "clang/Basic/Diagnostic.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/Target/TargetData.h"
23using namespace clang;
24using namespace CodeGen;
25
26/// Emits an instance of NSConstantString representing the object.
27llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
28{
29  llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(E);
30  // FIXME: This bitcast should just be made an invariant on the Runtime.
31  return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
32}
33
34/// Emit a selector.
35llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
36  // Untyped selector.
37  // Note that this implementation allows for non-constant strings to be passed
38  // as arguments to @selector().  Currently, the only thing preventing this
39  // behaviour is the type checking in the front end.
40  return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
41}
42
43llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
44  // FIXME: This should pass the Decl not the name.
45  return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol());
46}
47
48
49RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
50  // Only the lookup mechanism and first two arguments of the method
51  // implementation vary between runtimes.  We can get the receiver and
52  // arguments in generic code.
53
54  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
55  const Expr *ReceiverExpr = E->getReceiver();
56  bool isSuperMessage = false;
57  bool isClassMessage = false;
58  // Find the receiver
59  llvm::Value *Receiver;
60  if (!ReceiverExpr) {
61    const ObjCInterfaceDecl *OID = E->getClassInfo().first;
62
63    // Very special case, super send in class method. The receiver is
64    // self (the class object) and the send uses super semantics.
65    if (!OID) {
66      assert(E->getClassName()->isStr("super") &&
67             "Unexpected missing class interface in message send.");
68      isSuperMessage = true;
69      Receiver = LoadObjCSelf();
70    } else {
71      Receiver = Runtime.GetClass(Builder, OID);
72    }
73
74    isClassMessage = true;
75  } else if (isa<ObjCSuperExpr>(E->getReceiver())) {
76    isSuperMessage = true;
77    Receiver = LoadObjCSelf();
78  } else {
79    Receiver = EmitScalarExpr(E->getReceiver());
80  }
81
82  CallArgList Args;
83  EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end());
84
85  if (isSuperMessage) {
86    // super is only valid in an Objective-C method
87    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
88    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
89    return Runtime.GenerateMessageSendSuper(*this, E->getType(),
90                                            E->getSelector(),
91                                            OMD->getClassInterface(),
92                                            isCategoryImpl,
93                                            Receiver,
94                                            isClassMessage,
95                                            Args,
96                                            E->getMethodDecl());
97  }
98
99  return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
100                                     Receiver, isClassMessage, Args,
101                                     E->getMethodDecl());
102}
103
104/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
105/// the LLVM function and sets the other context used by
106/// CodeGenFunction.
107void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
108                                      const ObjCContainerDecl *CD) {
109  FunctionArgList Args;
110  llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
111
112  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
113  CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
114
115  Args.push_back(std::make_pair(OMD->getSelfDecl(),
116                                OMD->getSelfDecl()->getType()));
117  Args.push_back(std::make_pair(OMD->getCmdDecl(),
118                                OMD->getCmdDecl()->getType()));
119
120  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
121       E = OMD->param_end(); PI != E; ++PI)
122    Args.push_back(std::make_pair(*PI, (*PI)->getType()));
123
124  StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocEnd());
125}
126
127/// Generate an Objective-C method.  An Objective-C method is a C function with
128/// its pointer, name, and types registered in the class struture.
129void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
130  // Check if we should generate debug info for this method.
131  if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
132    DebugInfo = CGM.getDebugInfo();
133  StartObjCMethod(OMD, OMD->getClassInterface());
134  EmitStmt(OMD->getBody());
135  FinishFunction(OMD->getBodyRBrace());
136}
137
138// FIXME: I wasn't sure about the synthesis approach. If we end up generating an
139// AST for the whole body we can just fall back to having a GenerateFunction
140// which takes the body Stmt.
141
142/// GenerateObjCGetter - Generate an Objective-C property getter
143/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
144/// is illegal within a category.
145void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
146                                         const ObjCPropertyImplDecl *PID) {
147  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
148  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
149  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
150  assert(OMD && "Invalid call to generate getter (empty method)");
151  // FIXME: This is rather murky, we create this here since they will not have
152  // been created by Sema for us.
153  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
154  StartObjCMethod(OMD, IMP->getClassInterface());
155
156  // Determine if we should use an objc_getProperty call for
157  // this. Non-atomic properties are directly evaluated.
158  // atomic 'copy' and 'retain' properties are also directly
159  // evaluated in gc-only mode.
160  if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
161      !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
162      (PD->getSetterKind() == ObjCPropertyDecl::Copy ||
163       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
164    llvm::Value *GetPropertyFn =
165      CGM.getObjCRuntime().GetPropertyGetFunction();
166
167    if (!GetPropertyFn) {
168      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
169      FinishFunction();
170      return;
171    }
172
173    // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
174    // FIXME: Can't this be simpler? This might even be worse than the
175    // corresponding gcc code.
176    CodeGenTypes &Types = CGM.getTypes();
177    ValueDecl *Cmd = OMD->getCmdDecl();
178    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
179    QualType IdTy = getContext().getObjCIdType();
180    llvm::Value *SelfAsId =
181      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
182    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
183    llvm::Value *True =
184      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
185    CallArgList Args;
186    Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
187    Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
188    Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
189    Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
190    // FIXME: We shouldn't need to get the function info here, the
191    // runtime already should have computed it to build the function.
192    RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args),
193                         GetPropertyFn, Args);
194    // We need to fix the type here. Ivars with copy & retain are
195    // always objects so we don't need to worry about complex or
196    // aggregates.
197    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
198                                           Types.ConvertType(PD->getType())));
199    EmitReturnOfRValue(RV, PD->getType());
200  } else {
201    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
202    if (hasAggregateLLVMType(Ivar->getType())) {
203      EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType());
204    } else {
205      CodeGenTypes &Types = CGM.getTypes();
206      RValue RV = EmitLoadOfLValue(LV, Ivar->getType());
207      RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
208                       Types.ConvertType(PD->getType())));
209      EmitReturnOfRValue(RV, PD->getType());
210    }
211  }
212
213  FinishFunction();
214}
215
216/// GenerateObjCSetter - Generate an Objective-C property setter
217/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
218/// is illegal within a category.
219void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
220                                         const ObjCPropertyImplDecl *PID) {
221  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
222  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
223  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
224  assert(OMD && "Invalid call to generate setter (empty method)");
225  // FIXME: This is rather murky, we create this here since they will not have
226  // been created by Sema for us.
227  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
228  StartObjCMethod(OMD, IMP->getClassInterface());
229
230  bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
231  bool IsAtomic =
232    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
233
234  // Determine if we should use an objc_setProperty call for
235  // this. Properties with 'copy' semantics always use it, as do
236  // non-atomic properties with 'release' semantics as long as we are
237  // not in gc-only mode.
238  if (IsCopy ||
239      (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
240       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
241    llvm::Value *SetPropertyFn =
242      CGM.getObjCRuntime().GetPropertySetFunction();
243
244    if (!SetPropertyFn) {
245      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
246      FinishFunction();
247      return;
248    }
249
250    // Emit objc_setProperty((id) self, _cmd, offset, arg,
251    //                       <is-atomic>, <is-copy>).
252    // FIXME: Can't this be simpler? This might even be worse than the
253    // corresponding gcc code.
254    CodeGenTypes &Types = CGM.getTypes();
255    ValueDecl *Cmd = OMD->getCmdDecl();
256    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
257    QualType IdTy = getContext().getObjCIdType();
258    llvm::Value *SelfAsId =
259      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
260    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
261    llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
262    llvm::Value *ArgAsId =
263      Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
264                            Types.ConvertType(IdTy));
265    llvm::Value *True =
266      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
267    llvm::Value *False =
268      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
269    CallArgList Args;
270    Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
271    Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
272    Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
273    Args.push_back(std::make_pair(RValue::get(ArgAsId), IdTy));
274    Args.push_back(std::make_pair(RValue::get(IsAtomic ? True : False),
275                                  getContext().BoolTy));
276    Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False),
277                                  getContext().BoolTy));
278    // FIXME: We shouldn't need to get the function info here, the runtime
279    // already should have computed it to build the function.
280    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args),
281             SetPropertyFn, Args);
282  } else {
283    // FIXME: Find a clean way to avoid AST node creation.
284    SourceLocation Loc = PD->getLocation();
285    ValueDecl *Self = OMD->getSelfDecl();
286    ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
287    DeclRefExpr Base(Self, Self->getType(), Loc);
288    ParmVarDecl *ArgDecl = *OMD->param_begin();
289    DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
290    ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true);
291
292    // The property type can differ from the ivar type in some situations with
293    // Objective-C pointer types, we can always bit cast the RHS in these cases.
294    if (getContext().getCanonicalType(Ivar->getType()) !=
295        getContext().getCanonicalType(ArgDecl->getType())) {
296      ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg,
297                                 false);
298      BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign,
299                            Ivar->getType(), Loc);
300      EmitStmt(&Assign);
301    } else {
302      BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
303                            Ivar->getType(), Loc);
304      EmitStmt(&Assign);
305    }
306  }
307
308  FinishFunction();
309}
310
311llvm::Value *CodeGenFunction::LoadObjCSelf() {
312  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
313  // See if we need to lazily forward self inside a block literal.
314  BlockForwardSelf();
315  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
316}
317
318QualType CodeGenFunction::TypeOfSelfObject() {
319  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
320  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
321  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
322    getContext().getCanonicalType(selfDecl->getType()));
323  return PTy->getPointeeType();
324}
325
326RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,
327                                                 const Selector &S) {
328  llvm::Value *Receiver = LoadObjCSelf();
329  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
330  bool isClassMessage = OMD->isClassMethod();
331  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
332  return CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
333                                                       Exp->getType(),
334                                                       S,
335                                                       OMD->getClassInterface(),
336                                                       isCategoryImpl,
337                                                       Receiver,
338                                                       isClassMessage,
339                                                       CallArgList());
340
341}
342
343RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
344  Exp = Exp->IgnoreParens();
345  // FIXME: Split it into two separate routines.
346  if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
347    Selector S = E->getProperty()->getGetterName();
348    if (isa<ObjCSuperExpr>(E->getBase()))
349      return EmitObjCSuperPropertyGet(E, S);
350    return CGM.getObjCRuntime().
351             GenerateMessageSend(*this, Exp->getType(), S,
352                                 EmitScalarExpr(E->getBase()),
353                                 false, CallArgList());
354  } else {
355    const ObjCImplicitSetterGetterRefExpr *KE =
356      cast<ObjCImplicitSetterGetterRefExpr>(Exp);
357    Selector S = KE->getGetterMethod()->getSelector();
358    llvm::Value *Receiver;
359    if (KE->getInterfaceDecl()) {
360      const ObjCInterfaceDecl *OID = KE->getInterfaceDecl();
361      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
362    } else if (isa<ObjCSuperExpr>(KE->getBase()))
363      return EmitObjCSuperPropertyGet(KE, S);
364    else
365      Receiver = EmitScalarExpr(KE->getBase());
366    return CGM.getObjCRuntime().
367             GenerateMessageSend(*this, Exp->getType(), S,
368                                 Receiver,
369                                 KE->getInterfaceDecl() != 0, CallArgList());
370  }
371}
372
373void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp,
374                                               const Selector &S,
375                                               RValue Src) {
376  CallArgList Args;
377  llvm::Value *Receiver = LoadObjCSelf();
378  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
379  bool isClassMessage = OMD->isClassMethod();
380  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
381  Args.push_back(std::make_pair(Src, Exp->getType()));
382  CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
383                                                Exp->getType(),
384                                                S,
385                                                OMD->getClassInterface(),
386                                                isCategoryImpl,
387                                                Receiver,
388                                                isClassMessage,
389                                                Args);
390  return;
391}
392
393void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
394                                          RValue Src) {
395  // FIXME: Split it into two separate routines.
396  if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
397    Selector S = E->getProperty()->getSetterName();
398    if (isa<ObjCSuperExpr>(E->getBase())) {
399      EmitObjCSuperPropertySet(E, S, Src);
400      return;
401    }
402    CallArgList Args;
403    Args.push_back(std::make_pair(Src, E->getType()));
404    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
405                                             EmitScalarExpr(E->getBase()),
406                                             false, Args);
407  } else if (const ObjCImplicitSetterGetterRefExpr *E =
408               dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
409    Selector S = E->getSetterMethod()->getSelector();
410    CallArgList Args;
411    llvm::Value *Receiver;
412    if (E->getInterfaceDecl()) {
413      const ObjCInterfaceDecl *OID = E->getInterfaceDecl();
414      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
415    } else if (isa<ObjCSuperExpr>(E->getBase())) {
416      EmitObjCSuperPropertySet(E, S, Src);
417      return;
418    } else
419      Receiver = EmitScalarExpr(E->getBase());
420    Args.push_back(std::make_pair(Src, E->getType()));
421    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
422                                             Receiver,
423                                             E->getInterfaceDecl() != 0, Args);
424  } else
425    assert (0 && "bad expression node in EmitObjCPropertySet");
426}
427
428void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
429  llvm::Constant *EnumerationMutationFn =
430    CGM.getObjCRuntime().EnumerationMutationFunction();
431  llvm::Value *DeclAddress;
432  QualType ElementTy;
433
434  if (!EnumerationMutationFn) {
435    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
436    return;
437  }
438
439  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
440    EmitStmt(SD);
441    assert(HaveInsertPoint() && "DeclStmt destroyed insert point!");
442    const Decl* D = SD->getSingleDecl();
443    ElementTy = cast<ValueDecl>(D)->getType();
444    DeclAddress = LocalDeclMap[D];
445  } else {
446    ElementTy = cast<Expr>(S.getElement())->getType();
447    DeclAddress = 0;
448  }
449
450  // Fast enumeration state.
451  QualType StateTy = getContext().getObjCFastEnumerationStateType();
452  llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertType(StateTy),
453                                                "state.ptr");
454  StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3);
455  EmitMemSetToZero(StatePtr, StateTy);
456
457  // Number of elements in the items array.
458  static const unsigned NumItems = 16;
459
460  // Get selector
461  llvm::SmallVector<IdentifierInfo*, 3> II;
462  II.push_back(&CGM.getContext().Idents.get("countByEnumeratingWithState"));
463  II.push_back(&CGM.getContext().Idents.get("objects"));
464  II.push_back(&CGM.getContext().Idents.get("count"));
465  Selector FastEnumSel = CGM.getContext().Selectors.getSelector(II.size(),
466                                                                &II[0]);
467
468  QualType ItemsTy =
469    getContext().getConstantArrayType(getContext().getObjCIdType(),
470                                      llvm::APInt(32, NumItems),
471                                      ArrayType::Normal, 0);
472  llvm::Value *ItemsPtr = CreateTempAlloca(ConvertType(ItemsTy), "items.ptr");
473
474  llvm::Value *Collection = EmitScalarExpr(S.getCollection());
475
476  CallArgList Args;
477  Args.push_back(std::make_pair(RValue::get(StatePtr),
478                                getContext().getPointerType(StateTy)));
479
480  Args.push_back(std::make_pair(RValue::get(ItemsPtr),
481                                getContext().getPointerType(ItemsTy)));
482
483  const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
484  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
485  Args.push_back(std::make_pair(RValue::get(Count),
486                                getContext().UnsignedLongTy));
487
488  RValue CountRV =
489    CGM.getObjCRuntime().GenerateMessageSend(*this,
490                                             getContext().UnsignedLongTy,
491                                             FastEnumSel,
492                                             Collection, false, Args);
493
494  llvm::Value *LimitPtr = CreateTempAlloca(UnsignedLongLTy, "limit.ptr");
495  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
496
497  llvm::BasicBlock *NoElements = createBasicBlock("noelements");
498  llvm::BasicBlock *SetStartMutations = createBasicBlock("setstartmutations");
499
500  llvm::Value *Limit = Builder.CreateLoad(LimitPtr);
501  llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy);
502
503  llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
504  Builder.CreateCondBr(IsZero, NoElements, SetStartMutations);
505
506  EmitBlock(SetStartMutations);
507
508  llvm::Value *StartMutationsPtr =
509    CreateTempAlloca(UnsignedLongLTy);
510
511  llvm::Value *StateMutationsPtrPtr =
512    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
513  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
514                                                      "mutationsptr");
515
516  llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr,
517                                                   "mutations");
518
519  Builder.CreateStore(StateMutations, StartMutationsPtr);
520
521  llvm::BasicBlock *LoopStart = createBasicBlock("loopstart");
522  EmitBlock(LoopStart);
523
524  llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr");
525  Builder.CreateStore(Zero, CounterPtr);
526
527  llvm::BasicBlock *LoopBody = createBasicBlock("loopbody");
528  EmitBlock(LoopBody);
529
530  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
531  StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations");
532
533  llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr,
534                                                   "mutations");
535  llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations,
536                                                     StartMutations,
537                                                     "tobool");
538
539
540  llvm::BasicBlock *WasMutated = createBasicBlock("wasmutated");
541  llvm::BasicBlock *WasNotMutated = createBasicBlock("wasnotmutated");
542
543  Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated);
544
545  EmitBlock(WasMutated);
546  llvm::Value *V =
547    Builder.CreateBitCast(Collection,
548                          ConvertType(getContext().getObjCIdType()),
549                          "tmp");
550  CallArgList Args2;
551  Args2.push_back(std::make_pair(RValue::get(V),
552                                getContext().getObjCIdType()));
553  // FIXME: We shouldn't need to get the function info here, the runtime already
554  // should have computed it to build the function.
555  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2),
556           EnumerationMutationFn, Args2);
557
558  EmitBlock(WasNotMutated);
559
560  llvm::Value *StateItemsPtr =
561    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
562
563  llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter");
564
565  llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr,
566                                                   "stateitems");
567
568  llvm::Value *CurrentItemPtr =
569    Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr");
570
571  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem");
572
573  // Cast the item to the right type.
574  CurrentItem = Builder.CreateBitCast(CurrentItem,
575                                      ConvertType(ElementTy), "tmp");
576
577  if (!DeclAddress) {
578    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
579
580    // Set the value to null.
581    Builder.CreateStore(CurrentItem, LV.getAddress());
582  } else
583    Builder.CreateStore(CurrentItem, DeclAddress);
584
585  // Increment the counter.
586  Counter = Builder.CreateAdd(Counter,
587                              llvm::ConstantInt::get(UnsignedLongLTy, 1));
588  Builder.CreateStore(Counter, CounterPtr);
589
590  llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
591  llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
592
593  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
594
595  EmitStmt(S.getBody());
596
597  BreakContinueStack.pop_back();
598
599  EmitBlock(AfterBody);
600
601  llvm::BasicBlock *FetchMore = createBasicBlock("fetchmore");
602
603  Counter = Builder.CreateLoad(CounterPtr);
604  Limit = Builder.CreateLoad(LimitPtr);
605  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless");
606  Builder.CreateCondBr(IsLess, LoopBody, FetchMore);
607
608  // Fetch more elements.
609  EmitBlock(FetchMore);
610
611  CountRV =
612    CGM.getObjCRuntime().GenerateMessageSend(*this,
613                                             getContext().UnsignedLongTy,
614                                             FastEnumSel,
615                                             Collection, false, Args);
616  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
617  Limit = Builder.CreateLoad(LimitPtr);
618
619  IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
620  Builder.CreateCondBr(IsZero, NoElements, LoopStart);
621
622  // No more elements.
623  EmitBlock(NoElements);
624
625  if (!DeclAddress) {
626    // If the element was not a declaration, set it to be null.
627
628    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
629
630    // Set the value to null.
631    Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)),
632                        LV.getAddress());
633  }
634
635  EmitBlock(LoopEnd);
636}
637
638void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
639  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
640}
641
642void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
643  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
644}
645
646void CodeGenFunction::EmitObjCAtSynchronizedStmt(
647                                              const ObjCAtSynchronizedStmt &S) {
648  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
649}
650
651CGObjCRuntime::~CGObjCRuntime() {}
652