]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/CodeGen/CGObjC.cpp
MFC
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / 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 "CGDebugInfo.h"
15 #include "CGObjCRuntime.h"
16 #include "CodeGenFunction.h"
17 #include "CodeGenModule.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/DeclObjC.h"
20 #include "clang/AST/StmtObjC.h"
21 #include "clang/Basic/Diagnostic.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/Target/TargetData.h"
24 using namespace clang;
25 using namespace CodeGen;
26
27 /// Emits an instance of NSConstantString representing the object.
28 llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
29 {
30   llvm::Constant *C = 
31       CGM.getObjCRuntime().GenerateConstantString(E->getString());
32   // FIXME: This bitcast should just be made an invariant on the Runtime.
33   return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
34 }
35
36 /// Emit a selector.
37 llvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
38   // Untyped selector.
39   // Note that this implementation allows for non-constant strings to be passed
40   // as arguments to @selector().  Currently, the only thing preventing this
41   // behaviour is the type checking in the front end.
42   return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
43 }
44
45 llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
46   // FIXME: This should pass the Decl not the name.
47   return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol());
48 }
49
50
51 RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E,
52                                             ReturnValueSlot Return) {
53   // Only the lookup mechanism and first two arguments of the method
54   // implementation vary between runtimes.  We can get the receiver and
55   // arguments in generic code.
56
57   CGObjCRuntime &Runtime = CGM.getObjCRuntime();
58   bool isSuperMessage = false;
59   bool isClassMessage = false;
60   ObjCInterfaceDecl *OID = 0;
61   // Find the receiver
62   llvm::Value *Receiver = 0;
63   switch (E->getReceiverKind()) {
64   case ObjCMessageExpr::Instance:
65     Receiver = EmitScalarExpr(E->getInstanceReceiver());
66     break;
67
68   case ObjCMessageExpr::Class: {
69     const ObjCObjectType *ObjTy
70       = E->getClassReceiver()->getAs<ObjCObjectType>();
71     assert(ObjTy && "Invalid Objective-C class message send");
72     OID = ObjTy->getInterface();
73     assert(OID && "Invalid Objective-C class message send");
74     Receiver = Runtime.GetClass(Builder, OID);
75     isClassMessage = true;
76     break;
77   }
78
79   case ObjCMessageExpr::SuperInstance:
80     Receiver = LoadObjCSelf();
81     isSuperMessage = true;
82     break;
83
84   case ObjCMessageExpr::SuperClass:
85     Receiver = LoadObjCSelf();
86     isSuperMessage = true;
87     isClassMessage = true;
88     break;
89   }
90
91   CallArgList Args;
92   EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end());
93
94   QualType ResultType =
95     E->getMethodDecl() ? E->getMethodDecl()->getResultType() : E->getType();
96
97   if (isSuperMessage) {
98     // super is only valid in an Objective-C method
99     const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
100     bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
101     return Runtime.GenerateMessageSendSuper(*this, Return, ResultType,
102                                             E->getSelector(),
103                                             OMD->getClassInterface(),
104                                             isCategoryImpl,
105                                             Receiver,
106                                             isClassMessage,
107                                             Args,
108                                             E->getMethodDecl());
109   }
110
111   return Runtime.GenerateMessageSend(*this, Return, ResultType,
112                                      E->getSelector(),
113                                      Receiver, Args, OID,
114                                      E->getMethodDecl());
115 }
116
117 /// StartObjCMethod - Begin emission of an ObjCMethod. This generates
118 /// the LLVM function and sets the other context used by
119 /// CodeGenFunction.
120 void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
121                                       const ObjCContainerDecl *CD) {
122   FunctionArgList args;
123   // Check if we should generate debug info for this method.
124   if (CGM.getModuleDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
125     DebugInfo = CGM.getModuleDebugInfo();
126
127   llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
128
129   const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
130   CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
131
132   args.push_back(OMD->getSelfDecl());
133   args.push_back(OMD->getCmdDecl());
134
135   for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
136        E = OMD->param_end(); PI != E; ++PI)
137     args.push_back(*PI);
138
139   CurGD = OMD;
140
141   StartFunction(OMD, OMD->getResultType(), Fn, FI, args, OMD->getLocStart());
142 }
143
144 void CodeGenFunction::GenerateObjCGetterBody(ObjCIvarDecl *Ivar, 
145                                              bool IsAtomic, bool IsStrong) {
146   LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
147                                 Ivar, 0);
148   llvm::Value *GetCopyStructFn =
149   CGM.getObjCRuntime().GetGetStructFunction();
150   CodeGenTypes &Types = CGM.getTypes();
151   // objc_copyStruct (ReturnValue, &structIvar, 
152   //                  sizeof (Type of Ivar), isAtomic, false);
153   CallArgList Args;
154   RValue RV = RValue::get(Builder.CreateBitCast(ReturnValue,
155                                                 Types.ConvertType(getContext().VoidPtrTy)));
156   Args.add(RV, getContext().VoidPtrTy);
157   RV = RValue::get(Builder.CreateBitCast(LV.getAddress(),
158                                          Types.ConvertType(getContext().VoidPtrTy)));
159   Args.add(RV, getContext().VoidPtrTy);
160   // sizeof (Type of Ivar)
161   CharUnits Size =  getContext().getTypeSizeInChars(Ivar->getType());
162   llvm::Value *SizeVal =
163   llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), 
164                          Size.getQuantity());
165   Args.add(RValue::get(SizeVal), getContext().LongTy);
166   llvm::Value *isAtomic =
167   llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 
168                          IsAtomic ? 1 : 0);
169   Args.add(RValue::get(isAtomic), getContext().BoolTy);
170   llvm::Value *hasStrong =
171   llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 
172                          IsStrong ? 1 : 0);
173   Args.add(RValue::get(hasStrong), getContext().BoolTy);
174   EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
175                                  FunctionType::ExtInfo()),
176            GetCopyStructFn, ReturnValueSlot(), Args);
177 }
178
179 /// Generate an Objective-C method.  An Objective-C method is a C function with
180 /// its pointer, name, and types registered in the class struture.
181 void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
182   StartObjCMethod(OMD, OMD->getClassInterface());
183   EmitStmt(OMD->getBody());
184   FinishFunction(OMD->getBodyRBrace());
185 }
186
187 // FIXME: I wasn't sure about the synthesis approach. If we end up generating an
188 // AST for the whole body we can just fall back to having a GenerateFunction
189 // which takes the body Stmt.
190
191 /// GenerateObjCGetter - Generate an Objective-C property getter
192 /// function. The given Decl must be an ObjCImplementationDecl. @synthesize
193 /// is illegal within a category.
194 void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
195                                          const ObjCPropertyImplDecl *PID) {
196   ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
197   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
198   bool IsAtomic =
199     !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
200   ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
201   assert(OMD && "Invalid call to generate getter (empty method)");
202   StartObjCMethod(OMD, IMP->getClassInterface());
203   
204   // Determine if we should use an objc_getProperty call for
205   // this. Non-atomic properties are directly evaluated.
206   // atomic 'copy' and 'retain' properties are also directly
207   // evaluated in gc-only mode.
208   if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
209       IsAtomic &&
210       (PD->getSetterKind() == ObjCPropertyDecl::Copy ||
211        PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
212     llvm::Value *GetPropertyFn =
213       CGM.getObjCRuntime().GetPropertyGetFunction();
214
215     if (!GetPropertyFn) {
216       CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
217       FinishFunction();
218       return;
219     }
220
221     // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
222     // FIXME: Can't this be simpler? This might even be worse than the
223     // corresponding gcc code.
224     CodeGenTypes &Types = CGM.getTypes();
225     ValueDecl *Cmd = OMD->getCmdDecl();
226     llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
227     QualType IdTy = getContext().getObjCIdType();
228     llvm::Value *SelfAsId =
229       Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
230     llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
231     llvm::Value *True =
232       llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
233     CallArgList Args;
234     Args.add(RValue::get(SelfAsId), IdTy);
235     Args.add(RValue::get(CmdVal), Cmd->getType());
236     Args.add(RValue::get(Offset), getContext().getPointerDiffType());
237     Args.add(RValue::get(True), getContext().BoolTy);
238     // FIXME: We shouldn't need to get the function info here, the
239     // runtime already should have computed it to build the function.
240     RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args,
241                                                FunctionType::ExtInfo()),
242                          GetPropertyFn, ReturnValueSlot(), Args);
243     // We need to fix the type here. Ivars with copy & retain are
244     // always objects so we don't need to worry about complex or
245     // aggregates.
246     RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
247                                            Types.ConvertType(PD->getType())));
248     EmitReturnOfRValue(RV, PD->getType());
249   } else {
250     const llvm::Triple &Triple = getContext().Target.getTriple();
251     QualType IVART = Ivar->getType();
252     if (IsAtomic &&
253         IVART->isScalarType() &&
254         (Triple.getArch() == llvm::Triple::arm ||
255          Triple.getArch() == llvm::Triple::thumb) &&
256         (getContext().getTypeSizeInChars(IVART) 
257          > CharUnits::fromQuantity(4)) &&
258         CGM.getObjCRuntime().GetGetStructFunction()) {
259       GenerateObjCGetterBody(Ivar, true, false);
260     }
261     else if (IsAtomic &&
262              (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
263              Triple.getArch() == llvm::Triple::x86 &&
264              (getContext().getTypeSizeInChars(IVART) 
265               > CharUnits::fromQuantity(4)) &&
266              CGM.getObjCRuntime().GetGetStructFunction()) {
267       GenerateObjCGetterBody(Ivar, true, false);
268     }
269     else if (IsAtomic &&
270              (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
271              Triple.getArch() == llvm::Triple::x86_64 &&
272              (getContext().getTypeSizeInChars(IVART) 
273               > CharUnits::fromQuantity(8)) &&
274              CGM.getObjCRuntime().GetGetStructFunction()) {
275       GenerateObjCGetterBody(Ivar, true, false);
276     }
277     else if (IVART->isAnyComplexType()) {
278       LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
279                                     Ivar, 0);
280       ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(),
281                                                LV.isVolatileQualified());
282       StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
283     }
284     else if (hasAggregateLLVMType(IVART)) {
285       bool IsStrong = false;
286       if ((IsStrong = IvarTypeWithAggrGCObjects(IVART))
287           && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
288           && CGM.getObjCRuntime().GetGetStructFunction()) {
289         GenerateObjCGetterBody(Ivar, IsAtomic, IsStrong);
290       }
291       else {
292         const CXXRecordDecl *classDecl = IVART->getAsCXXRecordDecl();
293         
294         if (PID->getGetterCXXConstructor() &&
295             classDecl && !classDecl->hasTrivialConstructor()) {
296           ReturnStmt *Stmt = 
297             new (getContext()) ReturnStmt(SourceLocation(), 
298                                           PID->getGetterCXXConstructor(),
299                                           0);
300           EmitReturnStmt(*Stmt);
301         } else if (IsAtomic &&
302                    !IVART->isAnyComplexType() &&
303                    Triple.getArch() == llvm::Triple::x86 &&
304                    (getContext().getTypeSizeInChars(IVART) 
305                     > CharUnits::fromQuantity(4)) &&
306                    CGM.getObjCRuntime().GetGetStructFunction()) {
307           GenerateObjCGetterBody(Ivar, true, false);
308         }
309         else if (IsAtomic &&
310                  !IVART->isAnyComplexType() &&
311                  Triple.getArch() == llvm::Triple::x86_64 &&
312                  (getContext().getTypeSizeInChars(IVART) 
313                   > CharUnits::fromQuantity(8)) &&
314                  CGM.getObjCRuntime().GetGetStructFunction()) {
315           GenerateObjCGetterBody(Ivar, true, false);
316         }
317         else {
318           LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
319                                         Ivar, 0);
320           EmitAggregateCopy(ReturnValue, LV.getAddress(), IVART);
321         }
322       }
323     } 
324     else {
325         LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), 
326                                     Ivar, 0);
327         if (PD->getType()->isReferenceType()) {
328           RValue RV = RValue::get(LV.getAddress());
329           EmitReturnOfRValue(RV, PD->getType());
330         }
331         else {
332           CodeGenTypes &Types = CGM.getTypes();
333           RValue RV = EmitLoadOfLValue(LV, IVART);
334           RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
335                                                Types.ConvertType(PD->getType())));
336           EmitReturnOfRValue(RV, PD->getType());
337         }
338     }
339   }
340
341   FinishFunction();
342 }
343
344 void CodeGenFunction::GenerateObjCAtomicSetterBody(ObjCMethodDecl *OMD,
345                                                    ObjCIvarDecl *Ivar) {
346   // objc_copyStruct (&structIvar, &Arg, 
347   //                  sizeof (struct something), true, false);
348   llvm::Value *GetCopyStructFn =
349   CGM.getObjCRuntime().GetSetStructFunction();
350   CodeGenTypes &Types = CGM.getTypes();
351   CallArgList Args;
352   LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
353   RValue RV =
354     RValue::get(Builder.CreateBitCast(LV.getAddress(),
355                 Types.ConvertType(getContext().VoidPtrTy)));
356   Args.add(RV, getContext().VoidPtrTy);
357   llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
358   llvm::Value *ArgAsPtrTy =
359   Builder.CreateBitCast(Arg,
360                       Types.ConvertType(getContext().VoidPtrTy));
361   RV = RValue::get(ArgAsPtrTy);
362   Args.add(RV, getContext().VoidPtrTy);
363   // sizeof (Type of Ivar)
364   CharUnits Size =  getContext().getTypeSizeInChars(Ivar->getType());
365   llvm::Value *SizeVal =
366   llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), 
367                          Size.getQuantity());
368   Args.add(RValue::get(SizeVal), getContext().LongTy);
369   llvm::Value *True =
370   llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
371   Args.add(RValue::get(True), getContext().BoolTy);
372   llvm::Value *False =
373   llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
374   Args.add(RValue::get(False), getContext().BoolTy);
375   EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
376                                  FunctionType::ExtInfo()),
377            GetCopyStructFn, ReturnValueSlot(), Args);
378 }
379
380 static bool
381 IvarAssignHasTrvialAssignment(const ObjCPropertyImplDecl *PID,
382                               QualType IvarT) {
383   bool HasTrvialAssignment = true;
384   if (PID->getSetterCXXAssignment()) {
385     const CXXRecordDecl *classDecl = IvarT->getAsCXXRecordDecl();
386     HasTrvialAssignment = 
387       (!classDecl || classDecl->hasTrivialCopyAssignment());
388   }
389   return HasTrvialAssignment;
390 }
391
392 /// GenerateObjCSetter - Generate an Objective-C property setter
393 /// function. The given Decl must be an ObjCImplementationDecl. @synthesize
394 /// is illegal within a category.
395 void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
396                                          const ObjCPropertyImplDecl *PID) {
397   ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
398   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
399   ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
400   assert(OMD && "Invalid call to generate setter (empty method)");
401   StartObjCMethod(OMD, IMP->getClassInterface());
402   const llvm::Triple &Triple = getContext().Target.getTriple();
403   QualType IVART = Ivar->getType();
404   bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
405   bool IsAtomic =
406     !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
407
408   // Determine if we should use an objc_setProperty call for
409   // this. Properties with 'copy' semantics always use it, as do
410   // non-atomic properties with 'release' semantics as long as we are
411   // not in gc-only mode.
412   if (IsCopy ||
413       (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
414        PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
415     llvm::Value *SetPropertyFn =
416       CGM.getObjCRuntime().GetPropertySetFunction();
417
418     if (!SetPropertyFn) {
419       CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
420       FinishFunction();
421       return;
422     }
423
424     // Emit objc_setProperty((id) self, _cmd, offset, arg,
425     //                       <is-atomic>, <is-copy>).
426     // FIXME: Can't this be simpler? This might even be worse than the
427     // corresponding gcc code.
428     CodeGenTypes &Types = CGM.getTypes();
429     ValueDecl *Cmd = OMD->getCmdDecl();
430     llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
431     QualType IdTy = getContext().getObjCIdType();
432     llvm::Value *SelfAsId =
433       Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
434     llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
435     llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
436     llvm::Value *ArgAsId =
437       Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
438                             Types.ConvertType(IdTy));
439     llvm::Value *True =
440       llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
441     llvm::Value *False =
442       llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
443     CallArgList Args;
444     Args.add(RValue::get(SelfAsId), IdTy);
445     Args.add(RValue::get(CmdVal), Cmd->getType());
446     Args.add(RValue::get(Offset), getContext().getPointerDiffType());
447     Args.add(RValue::get(ArgAsId), IdTy);
448     Args.add(RValue::get(IsAtomic ? True : False),  getContext().BoolTy);
449     Args.add(RValue::get(IsCopy ? True : False), getContext().BoolTy);
450     // FIXME: We shouldn't need to get the function info here, the runtime
451     // already should have computed it to build the function.
452     EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
453                                    FunctionType::ExtInfo()),
454              SetPropertyFn,
455              ReturnValueSlot(), Args);
456   } else if (IsAtomic && hasAggregateLLVMType(IVART) &&
457              !IVART->isAnyComplexType() &&
458              IvarAssignHasTrvialAssignment(PID, IVART) &&
459              ((Triple.getArch() == llvm::Triple::x86 &&
460               (getContext().getTypeSizeInChars(IVART)
461                > CharUnits::fromQuantity(4))) ||
462               (Triple.getArch() == llvm::Triple::x86_64 &&
463               (getContext().getTypeSizeInChars(IVART)
464                > CharUnits::fromQuantity(8))))
465              && CGM.getObjCRuntime().GetSetStructFunction()) {
466           // objc_copyStruct (&structIvar, &Arg, 
467           //                  sizeof (struct something), true, false);
468     GenerateObjCAtomicSetterBody(OMD, Ivar);
469   } else if (PID->getSetterCXXAssignment()) {
470     EmitIgnoredExpr(PID->getSetterCXXAssignment());
471   } else {
472     if (IsAtomic &&
473         IVART->isScalarType() &&
474         (Triple.getArch() == llvm::Triple::arm ||
475          Triple.getArch() == llvm::Triple::thumb) &&
476         (getContext().getTypeSizeInChars(IVART)
477           > CharUnits::fromQuantity(4)) &&
478         CGM.getObjCRuntime().GetGetStructFunction()) {
479       GenerateObjCAtomicSetterBody(OMD, Ivar);
480     }
481     else if (IsAtomic &&
482              (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
483              Triple.getArch() == llvm::Triple::x86 &&
484              (getContext().getTypeSizeInChars(IVART)
485               > CharUnits::fromQuantity(4)) &&
486              CGM.getObjCRuntime().GetGetStructFunction()) {
487       GenerateObjCAtomicSetterBody(OMD, Ivar);
488     }
489     else if (IsAtomic &&
490              (IVART->isScalarType() && !IVART->isRealFloatingType()) &&
491              Triple.getArch() == llvm::Triple::x86_64 &&
492              (getContext().getTypeSizeInChars(IVART)
493               > CharUnits::fromQuantity(8)) &&
494              CGM.getObjCRuntime().GetGetStructFunction()) {
495       GenerateObjCAtomicSetterBody(OMD, Ivar);
496     }
497     else {
498       // FIXME: Find a clean way to avoid AST node creation.
499       SourceLocation Loc = PD->getLocation();
500       ValueDecl *Self = OMD->getSelfDecl();
501       ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
502       DeclRefExpr Base(Self, Self->getType(), VK_RValue, Loc);
503       ParmVarDecl *ArgDecl = *OMD->param_begin();
504       QualType T = ArgDecl->getType();
505       if (T->isReferenceType())
506         T = cast<ReferenceType>(T)->getPointeeType();
507       DeclRefExpr Arg(ArgDecl, T, VK_LValue, Loc);
508       ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true);
509     
510       // The property type can differ from the ivar type in some situations with
511       // Objective-C pointer types, we can always bit cast the RHS in these cases.
512       if (getContext().getCanonicalType(Ivar->getType()) !=
513           getContext().getCanonicalType(ArgDecl->getType())) {
514         ImplicitCastExpr ArgCasted(ImplicitCastExpr::OnStack,
515                                    Ivar->getType(), CK_BitCast, &Arg,
516                                    VK_RValue);
517         BinaryOperator Assign(&IvarRef, &ArgCasted, BO_Assign,
518                               Ivar->getType(), VK_RValue, OK_Ordinary, Loc);
519         EmitStmt(&Assign);
520       } else {
521         BinaryOperator Assign(&IvarRef, &Arg, BO_Assign,
522                               Ivar->getType(), VK_RValue, OK_Ordinary, Loc);
523         EmitStmt(&Assign);
524       }
525     }
526   }
527
528   FinishFunction();
529 }
530
531 // FIXME: these are stolen from CGClass.cpp, which is lame.
532 namespace {
533   struct CallArrayIvarDtor : EHScopeStack::Cleanup {
534     const ObjCIvarDecl *ivar;
535     llvm::Value *self;
536     CallArrayIvarDtor(const ObjCIvarDecl *ivar, llvm::Value *self)
537       : ivar(ivar), self(self) {}
538
539     void Emit(CodeGenFunction &CGF, bool IsForEH) {
540       LValue lvalue =
541         CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), self, ivar, 0);
542
543       QualType type = ivar->getType();
544       const ConstantArrayType *arrayType
545         = CGF.getContext().getAsConstantArrayType(type);
546       QualType baseType = CGF.getContext().getBaseElementType(arrayType);
547       const CXXRecordDecl *classDecl = baseType->getAsCXXRecordDecl();
548
549       llvm::Value *base
550         = CGF.Builder.CreateBitCast(lvalue.getAddress(),
551                                     CGF.ConvertType(baseType)->getPointerTo());
552       CGF.EmitCXXAggrDestructorCall(classDecl->getDestructor(),
553                                     arrayType, base);
554     }
555   };
556
557   struct CallIvarDtor : EHScopeStack::Cleanup {
558     const ObjCIvarDecl *ivar;
559     llvm::Value *self;
560     CallIvarDtor(const ObjCIvarDecl *ivar, llvm::Value *self)
561       : ivar(ivar), self(self) {}
562
563     void Emit(CodeGenFunction &CGF, bool IsForEH) {
564       LValue lvalue =
565         CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), self, ivar, 0);
566
567       QualType type = ivar->getType();
568       const CXXRecordDecl *classDecl = type->getAsCXXRecordDecl();
569
570       CGF.EmitCXXDestructorCall(classDecl->getDestructor(),
571                                 Dtor_Complete, /*ForVirtualBase=*/false,
572                                 lvalue.getAddress());
573     }
574   };
575 }
576
577 static void emitCXXDestructMethod(CodeGenFunction &CGF,
578                                   ObjCImplementationDecl *impl) {
579   CodeGenFunction::RunCleanupsScope scope(CGF);
580
581   llvm::Value *self = CGF.LoadObjCSelf();
582
583   ObjCInterfaceDecl *iface
584     = const_cast<ObjCInterfaceDecl*>(impl->getClassInterface());
585   for (ObjCIvarDecl *ivar = iface->all_declared_ivar_begin();
586        ivar; ivar = ivar->getNextIvar()) {
587     QualType type = ivar->getType();
588
589     // Drill down to the base element type.
590     QualType baseType = type;
591     const ConstantArrayType *arrayType = 
592       CGF.getContext().getAsConstantArrayType(baseType);
593     if (arrayType) baseType = CGF.getContext().getBaseElementType(arrayType);
594
595     // Check whether the ivar is a destructible type.
596     QualType::DestructionKind destructKind = baseType.isDestructedType();
597     assert(destructKind == type.isDestructedType());
598
599     switch (destructKind) {
600     case QualType::DK_none:
601       continue;
602
603     case QualType::DK_cxx_destructor:
604       if (arrayType)
605         CGF.EHStack.pushCleanup<CallArrayIvarDtor>(NormalAndEHCleanup,
606                                                    ivar, self);
607       else
608         CGF.EHStack.pushCleanup<CallIvarDtor>(NormalAndEHCleanup,
609                                               ivar, self);
610       break;
611     }
612   }
613
614   assert(scope.requiresCleanups() && "nothing to do in .cxx_destruct?");
615 }
616
617 void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
618                                                  ObjCMethodDecl *MD,
619                                                  bool ctor) {
620   MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
621   StartObjCMethod(MD, IMP->getClassInterface());
622
623   // Emit .cxx_construct.
624   if (ctor) {
625     llvm::SmallVector<CXXCtorInitializer *, 8> IvarInitializers;
626     for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
627            E = IMP->init_end(); B != E; ++B) {
628       CXXCtorInitializer *IvarInit = (*B);
629       FieldDecl *Field = IvarInit->getAnyMember();
630       ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
631       LValue LV = EmitLValueForIvar(TypeOfSelfObject(), 
632                                     LoadObjCSelf(), Ivar, 0);
633       EmitAggExpr(IvarInit->getInit(), AggValueSlot::forLValue(LV, true));
634     }
635     // constructor returns 'self'.
636     CodeGenTypes &Types = CGM.getTypes();
637     QualType IdTy(CGM.getContext().getObjCIdType());
638     llvm::Value *SelfAsId =
639       Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
640     EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
641
642   // Emit .cxx_destruct.
643   } else {
644     emitCXXDestructMethod(*this, IMP);
645   }
646   FinishFunction();
647 }
648
649 bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
650   CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
651   it++; it++;
652   const ABIArgInfo &AI = it->info;
653   // FIXME. Is this sufficient check?
654   return (AI.getKind() == ABIArgInfo::Indirect);
655 }
656
657 bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
658   if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
659     return false;
660   if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
661     return FDTTy->getDecl()->hasObjectMember();
662   return false;
663 }
664
665 llvm::Value *CodeGenFunction::LoadObjCSelf() {
666   const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
667   return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
668 }
669
670 QualType CodeGenFunction::TypeOfSelfObject() {
671   const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
672   ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
673   const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
674     getContext().getCanonicalType(selfDecl->getType()));
675   return PTy->getPointeeType();
676 }
677
678 LValue
679 CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
680   // This is a special l-value that just issues sends when we load or
681   // store through it.
682
683   // For certain base kinds, we need to emit the base immediately.
684   llvm::Value *Base;
685   if (E->isSuperReceiver())
686     Base = LoadObjCSelf();
687   else if (E->isClassReceiver())
688     Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver());
689   else
690     Base = EmitScalarExpr(E->getBase());
691   return LValue::MakePropertyRef(E, Base);
692 }
693
694 static RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
695                                        ReturnValueSlot Return,
696                                        QualType ResultType,
697                                        Selector S,
698                                        llvm::Value *Receiver,
699                                        const CallArgList &CallArgs) {
700   const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl);
701   bool isClassMessage = OMD->isClassMethod();
702   bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
703   return CGF.CGM.getObjCRuntime()
704                 .GenerateMessageSendSuper(CGF, Return, ResultType,
705                                           S, OMD->getClassInterface(),
706                                           isCategoryImpl, Receiver,
707                                           isClassMessage, CallArgs);
708 }
709
710 RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
711                                                     ReturnValueSlot Return) {
712   const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr();
713   QualType ResultType = E->getGetterResultType();
714   Selector S;
715   if (E->isExplicitProperty()) {
716     const ObjCPropertyDecl *Property = E->getExplicitProperty();
717     S = Property->getGetterName();
718   } else {
719     const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter();
720     S = Getter->getSelector();
721   }
722
723   llvm::Value *Receiver = LV.getPropertyRefBaseAddr();
724
725   // Accesses to 'super' follow a different code path.
726   if (E->isSuperReceiver())
727     return GenerateMessageSendSuper(*this, Return, ResultType,
728                                     S, Receiver, CallArgList());
729
730   const ObjCInterfaceDecl *ReceiverClass
731     = (E->isClassReceiver() ? E->getClassReceiver() : 0);
732   return CGM.getObjCRuntime().
733              GenerateMessageSend(*this, Return, ResultType, S,
734                                  Receiver, CallArgList(), ReceiverClass);
735 }
736
737 void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
738                                                         LValue Dst) {
739   const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr();
740   Selector S = E->getSetterSelector();
741   QualType ArgType = E->getSetterArgType();
742   
743   // FIXME. Other than scalars, AST is not adequate for setter and
744   // getter type mismatches which require conversion.
745   if (Src.isScalar()) {
746     llvm::Value *SrcVal = Src.getScalarVal();
747     QualType DstType = getContext().getCanonicalType(ArgType);
748     const llvm::Type *DstTy = ConvertType(DstType);
749     if (SrcVal->getType() != DstTy)
750       Src = 
751         RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType));
752   }
753   
754   CallArgList Args;
755   Args.add(Src, ArgType);
756
757   llvm::Value *Receiver = Dst.getPropertyRefBaseAddr();
758   QualType ResultType = getContext().VoidTy;
759
760   if (E->isSuperReceiver()) {
761     GenerateMessageSendSuper(*this, ReturnValueSlot(),
762                              ResultType, S, Receiver, Args);
763     return;
764   }
765
766   const ObjCInterfaceDecl *ReceiverClass
767     = (E->isClassReceiver() ? E->getClassReceiver() : 0);
768
769   CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
770                                            ResultType, S, Receiver, Args,
771                                            ReceiverClass);
772 }
773
774 void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
775   llvm::Constant *EnumerationMutationFn =
776     CGM.getObjCRuntime().EnumerationMutationFunction();
777
778   if (!EnumerationMutationFn) {
779     CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
780     return;
781   }
782
783   // The local variable comes into scope immediately.
784   AutoVarEmission variable = AutoVarEmission::invalid();
785   if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
786     variable = EmitAutoVarAlloca(*cast<VarDecl>(SD->getSingleDecl()));
787
788   CGDebugInfo *DI = getDebugInfo();
789   if (DI) {
790     DI->setLocation(S.getSourceRange().getBegin());
791     DI->EmitRegionStart(Builder);
792   }
793
794   JumpDest LoopEnd = getJumpDestInCurrentScope("forcoll.end");
795   JumpDest AfterBody = getJumpDestInCurrentScope("forcoll.next");
796
797   // Fast enumeration state.
798   QualType StateTy = getContext().getObjCFastEnumerationStateType();
799   llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
800   EmitNullInitialization(StatePtr, StateTy);
801
802   // Number of elements in the items array.
803   static const unsigned NumItems = 16;
804
805   // Fetch the countByEnumeratingWithState:objects:count: selector.
806   IdentifierInfo *II[] = {
807     &CGM.getContext().Idents.get("countByEnumeratingWithState"),
808     &CGM.getContext().Idents.get("objects"),
809     &CGM.getContext().Idents.get("count")
810   };
811   Selector FastEnumSel =
812     CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
813
814   QualType ItemsTy =
815     getContext().getConstantArrayType(getContext().getObjCIdType(),
816                                       llvm::APInt(32, NumItems),
817                                       ArrayType::Normal, 0);
818   llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
819
820   // Emit the collection pointer.
821   llvm::Value *Collection = EmitScalarExpr(S.getCollection());
822
823   // Send it our message:
824   CallArgList Args;
825
826   // The first argument is a temporary of the enumeration-state type.
827   Args.add(RValue::get(StatePtr), getContext().getPointerType(StateTy));
828
829   // The second argument is a temporary array with space for NumItems
830   // pointers.  We'll actually be loading elements from the array
831   // pointer written into the control state; this buffer is so that
832   // collections that *aren't* backed by arrays can still queue up
833   // batches of elements.
834   Args.add(RValue::get(ItemsPtr), getContext().getPointerType(ItemsTy));
835
836   // The third argument is the capacity of that temporary array.
837   const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
838   llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
839   Args.add(RValue::get(Count), getContext().UnsignedLongTy);
840
841   // Start the enumeration.
842   RValue CountRV =
843     CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
844                                              getContext().UnsignedLongTy,
845                                              FastEnumSel,
846                                              Collection, Args);
847
848   // The initial number of objects that were returned in the buffer.
849   llvm::Value *initialBufferLimit = CountRV.getScalarVal();
850
851   llvm::BasicBlock *EmptyBB = createBasicBlock("forcoll.empty");
852   llvm::BasicBlock *LoopInitBB = createBasicBlock("forcoll.loopinit");
853
854   llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
855
856   // If the limit pointer was zero to begin with, the collection is
857   // empty; skip all this.
858   Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
859                        EmptyBB, LoopInitBB);
860
861   // Otherwise, initialize the loop.
862   EmitBlock(LoopInitBB);
863
864   // Save the initial mutations value.  This is the value at an
865   // address that was written into the state object by
866   // countByEnumeratingWithState:objects:count:.
867   llvm::Value *StateMutationsPtrPtr =
868     Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
869   llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
870                                                       "mutationsptr");
871
872   llvm::Value *initialMutations =
873     Builder.CreateLoad(StateMutationsPtr, "forcoll.initial-mutations");
874
875   // Start looping.  This is the point we return to whenever we have a
876   // fresh, non-empty batch of objects.
877   llvm::BasicBlock *LoopBodyBB = createBasicBlock("forcoll.loopbody");
878   EmitBlock(LoopBodyBB);
879
880   // The current index into the buffer.
881   llvm::PHINode *index = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.index");
882   index->addIncoming(zero, LoopInitBB);
883
884   // The current buffer size.
885   llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
886   count->addIncoming(initialBufferLimit, LoopInitBB);
887
888   // Check whether the mutations value has changed from where it was
889   // at start.  StateMutationsPtr should actually be invariant between
890   // refreshes.
891   StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
892   llvm::Value *currentMutations
893     = Builder.CreateLoad(StateMutationsPtr, "statemutations");
894
895   llvm::BasicBlock *WasMutatedBB = createBasicBlock("forcoll.mutated");
896   llvm::BasicBlock *WasNotMutatedBB = createBasicBlock("forcoll.notmutated");
897
898   Builder.CreateCondBr(Builder.CreateICmpEQ(currentMutations, initialMutations),
899                        WasNotMutatedBB, WasMutatedBB);
900
901   // If so, call the enumeration-mutation function.
902   EmitBlock(WasMutatedBB);
903   llvm::Value *V =
904     Builder.CreateBitCast(Collection,
905                           ConvertType(getContext().getObjCIdType()),
906                           "tmp");
907   CallArgList Args2;
908   Args2.add(RValue::get(V), getContext().getObjCIdType());
909   // FIXME: We shouldn't need to get the function info here, the runtime already
910   // should have computed it to build the function.
911   EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
912                                           FunctionType::ExtInfo()),
913            EnumerationMutationFn, ReturnValueSlot(), Args2);
914
915   // Otherwise, or if the mutation function returns, just continue.
916   EmitBlock(WasNotMutatedBB);
917
918   // Initialize the element variable.
919   RunCleanupsScope elementVariableScope(*this);
920   bool elementIsVariable;
921   LValue elementLValue;
922   QualType elementType;
923   if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
924     // Initialize the variable, in case it's a __block variable or something.
925     EmitAutoVarInit(variable);
926
927     const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
928     DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
929                         VK_LValue, SourceLocation());
930     elementLValue = EmitLValue(&tempDRE);
931     elementType = D->getType();
932     elementIsVariable = true;
933   } else {
934     elementLValue = LValue(); // suppress warning
935     elementType = cast<Expr>(S.getElement())->getType();
936     elementIsVariable = false;
937   }
938   const llvm::Type *convertedElementType = ConvertType(elementType);
939
940   // Fetch the buffer out of the enumeration state.
941   // TODO: this pointer should actually be invariant between
942   // refreshes, which would help us do certain loop optimizations.
943   llvm::Value *StateItemsPtr =
944     Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
945   llvm::Value *EnumStateItems =
946     Builder.CreateLoad(StateItemsPtr, "stateitems");
947
948   // Fetch the value at the current index from the buffer.
949   llvm::Value *CurrentItemPtr =
950     Builder.CreateGEP(EnumStateItems, index, "currentitem.ptr");
951   llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr);
952
953   // Cast that value to the right type.
954   CurrentItem = Builder.CreateBitCast(CurrentItem, convertedElementType,
955                                       "currentitem");
956
957   // Make sure we have an l-value.  Yes, this gets evaluated every
958   // time through the loop.
959   if (!elementIsVariable)
960     elementLValue = EmitLValue(cast<Expr>(S.getElement()));
961
962   EmitStoreThroughLValue(RValue::get(CurrentItem), elementLValue, elementType);
963
964   // If we do have an element variable, this assignment is the end of
965   // its initialization.
966   if (elementIsVariable)
967     EmitAutoVarCleanups(variable);
968
969   // Perform the loop body, setting up break and continue labels.
970   BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
971   {
972     RunCleanupsScope Scope(*this);
973     EmitStmt(S.getBody());
974   }
975   BreakContinueStack.pop_back();
976
977   // Destroy the element variable now.
978   elementVariableScope.ForceCleanup();
979
980   // Check whether there are more elements.
981   EmitBlock(AfterBody.getBlock());
982
983   llvm::BasicBlock *FetchMoreBB = createBasicBlock("forcoll.refetch");
984
985   // First we check in the local buffer.
986   llvm::Value *indexPlusOne
987     = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
988
989   // If we haven't overrun the buffer yet, we can continue.
990   Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
991                        LoopBodyBB, FetchMoreBB);
992
993   index->addIncoming(indexPlusOne, AfterBody.getBlock());
994   count->addIncoming(count, AfterBody.getBlock());
995
996   // Otherwise, we have to fetch more elements.
997   EmitBlock(FetchMoreBB);
998
999   CountRV =
1000     CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
1001                                              getContext().UnsignedLongTy,
1002                                              FastEnumSel,
1003                                              Collection, Args);
1004
1005   // If we got a zero count, we're done.
1006   llvm::Value *refetchCount = CountRV.getScalarVal();
1007
1008   // (note that the message send might split FetchMoreBB)
1009   index->addIncoming(zero, Builder.GetInsertBlock());
1010   count->addIncoming(refetchCount, Builder.GetInsertBlock());
1011
1012   Builder.CreateCondBr(Builder.CreateICmpEQ(refetchCount, zero),
1013                        EmptyBB, LoopBodyBB);
1014
1015   // No more elements.
1016   EmitBlock(EmptyBB);
1017
1018   if (!elementIsVariable) {
1019     // If the element was not a declaration, set it to be null.
1020
1021     llvm::Value *null = llvm::Constant::getNullValue(convertedElementType);
1022     elementLValue = EmitLValue(cast<Expr>(S.getElement()));
1023     EmitStoreThroughLValue(RValue::get(null), elementLValue, elementType);
1024   }
1025
1026   if (DI) {
1027     DI->setLocation(S.getSourceRange().getEnd());
1028     DI->EmitRegionEnd(Builder);
1029   }
1030
1031   EmitBlock(LoopEnd.getBlock());
1032 }
1033
1034 void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
1035   CGM.getObjCRuntime().EmitTryStmt(*this, S);
1036 }
1037
1038 void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
1039   CGM.getObjCRuntime().EmitThrowStmt(*this, S);
1040 }
1041
1042 void CodeGenFunction::EmitObjCAtSynchronizedStmt(
1043                                               const ObjCAtSynchronizedStmt &S) {
1044   CGM.getObjCRuntime().EmitSynchronizedStmt(*this, S);
1045 }
1046
1047 CGObjCRuntime::~CGObjCRuntime() {}