]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/CodeGen/CGObjC.cpp
Updaet clang to 92395.
[FreeBSD/FreeBSD.git] / lib / CodeGen / CGObjC.cpp
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"
23 using namespace clang;
24 using namespace CodeGen;
25
26 /// Emits an instance of NSConstantString representing the object.
27 llvm::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.
35 llvm::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
43 llvm::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
49 RValue 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.
107 void 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.
129 void 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.
145 void 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, ReturnValueSlot(), 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.
219 void 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), SetPropertyFn, 
281              ReturnValueSlot(), 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
311 llvm::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
318 QualType 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
326 RValue 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
343 RValue 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
373 void 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
393 void 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
428 void 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, ReturnValueSlot(), 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
638 void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
639   CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
640 }
641
642 void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
643   CGM.getObjCRuntime().EmitThrowStmt(*this, S);
644 }
645
646 void CodeGenFunction::EmitObjCAtSynchronizedStmt(
647                                               const ObjCAtSynchronizedStmt &S) {
648   CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
649 }
650
651 CGObjCRuntime::~CGObjCRuntime() {}