CGObjC.cpp revision 207619
133965Sjdp//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
278828Sobrien//
360484Sobrien//                     The LLVM Compiler Infrastructure
433965Sjdp//
533965Sjdp// This file is distributed under the University of Illinois Open Source
633965Sjdp// License. See LICENSE.TXT for details.
733965Sjdp//
833965Sjdp//===----------------------------------------------------------------------===//
933965Sjdp//
1033965Sjdp// This contains code to emit Objective-C code as LLVM code.
1133965Sjdp//
1233965Sjdp//===----------------------------------------------------------------------===//
1333965Sjdp
1433965Sjdp#include "CGObjCRuntime.h"
1533965Sjdp#include "CodeGenFunction.h"
1633965Sjdp#include "CodeGenModule.h"
1733965Sjdp#include "clang/AST/ASTContext.h"
1877298Sobrien#include "clang/AST/DeclObjC.h"
1977298Sobrien#include "clang/AST/StmtObjC.h"
2077298Sobrien#include "clang/Basic/Diagnostic.h"
2133965Sjdp#include "llvm/ADT/STLExtras.h"
2233965Sjdp#include "llvm/Target/TargetData.h"
2333965Sjdpusing namespace clang;
2433965Sjdpusing namespace CodeGen;
2533965Sjdp
2633965Sjdp/// Emits an instance of NSConstantString representing the object.
2733965Sjdpllvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E)
2833965Sjdp{
2933965Sjdp  llvm::Constant *C =
3077298Sobrien      CGM.getObjCRuntime().GenerateConstantString(E->getString());
3133965Sjdp  // FIXME: This bitcast should just be made an invariant on the Runtime.
3233965Sjdp  return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
3333965Sjdp}
3433965Sjdp
3533965Sjdp/// Emit a selector.
3633965Sjdpllvm::Value *CodeGenFunction::EmitObjCSelectorExpr(const ObjCSelectorExpr *E) {
3777298Sobrien  // Untyped selector.
3833965Sjdp  // Note that this implementation allows for non-constant strings to be passed
3933965Sjdp  // as arguments to @selector().  Currently, the only thing preventing this
4077298Sobrien  // behaviour is the type checking in the front end.
4133965Sjdp  return CGM.getObjCRuntime().GetSelector(Builder, E->getSelector());
4233965Sjdp}
4377298Sobrien
4477298Sobrienllvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {
4533965Sjdp  // FIXME: This should pass the Decl not the name.
4633965Sjdp  return CGM.getObjCRuntime().GenerateProtocolRef(Builder, E->getProtocol());
4777298Sobrien}
4833965Sjdp
4933965Sjdp
5033965SjdpRValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
5177298Sobrien  // Only the lookup mechanism and first two arguments of the method
5233965Sjdp  // implementation vary between runtimes.  We can get the receiver and
5377298Sobrien  // arguments in generic code.
5433965Sjdp
5533965Sjdp  CGObjCRuntime &Runtime = CGM.getObjCRuntime();
5633965Sjdp  bool isSuperMessage = false;
5777298Sobrien  bool isClassMessage = false;
5833965Sjdp  ObjCInterfaceDecl *OID = 0;
5977298Sobrien  // Find the receiver
6033965Sjdp  llvm::Value *Receiver = 0;
6133965Sjdp  switch (E->getReceiverKind()) {
6233965Sjdp  case ObjCMessageExpr::Instance:
6333965Sjdp    Receiver = EmitScalarExpr(E->getInstanceReceiver());
6433965Sjdp    break;
6533965Sjdp
6633965Sjdp  case ObjCMessageExpr::Class: {
6733965Sjdp    const ObjCInterfaceType *IFace
6877298Sobrien      = E->getClassReceiver()->getAs<ObjCInterfaceType>();
6977298Sobrien    OID = IFace->getDecl();
7033965Sjdp    assert(IFace && "Invalid Objective-C class message send");
7177298Sobrien    Receiver = Runtime.GetClass(Builder, OID);
7233965Sjdp    isClassMessage = true;
7333965Sjdp    break;
7477298Sobrien  }
7577298Sobrien
7633965Sjdp  case ObjCMessageExpr::SuperInstance:
7733965Sjdp    Receiver = LoadObjCSelf();
7877298Sobrien    isSuperMessage = true;
7933965Sjdp    break;
8033965Sjdp
8133965Sjdp  case ObjCMessageExpr::SuperClass:
8277298Sobrien    Receiver = LoadObjCSelf();
8333965Sjdp    isSuperMessage = true;
8477298Sobrien    isClassMessage = true;
8533965Sjdp    break;
8633965Sjdp  }
8733965Sjdp
8877298Sobrien  CallArgList Args;
8933965Sjdp  EmitCallArgs(Args, E->getMethodDecl(), E->arg_begin(), E->arg_end());
9033965Sjdp
9177298Sobrien  if (isSuperMessage) {
9233965Sjdp    // super is only valid in an Objective-C method
9333965Sjdp    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
9433965Sjdp    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
9577298Sobrien    return Runtime.GenerateMessageSendSuper(*this, E->getType(),
9633965Sjdp                                            E->getSelector(),
9733965Sjdp                                            OMD->getClassInterface(),
9877298Sobrien                                            isCategoryImpl,
9933965Sjdp                                            Receiver,
10033965Sjdp                                            isClassMessage,
10133965Sjdp                                            Args,
10277298Sobrien                                            E->getMethodDecl());
10333965Sjdp  }
10433965Sjdp
10577298Sobrien  return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(),
10633965Sjdp                                     Receiver, Args, OID,
10733965Sjdp                                     E->getMethodDecl());
10833965Sjdp}
10977298Sobrien
11033965Sjdp/// StartObjCMethod - Begin emission of an ObjCMethod. This generates
11133965Sjdp/// the LLVM function and sets the other context used by
11277298Sobrien/// CodeGenFunction.
11333965Sjdpvoid CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
11433965Sjdp                                      const ObjCContainerDecl *CD) {
11533965Sjdp  FunctionArgList Args;
11633965Sjdp  // Check if we should generate debug info for this method.
11733965Sjdp  if (CGM.getDebugInfo() && !OMD->hasAttr<NoDebugAttr>())
11833965Sjdp    DebugInfo = CGM.getDebugInfo();
11933965Sjdp
12033965Sjdp  llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
12133965Sjdp
12233965Sjdp  const CGFunctionInfo &FI = CGM.getTypes().getFunctionInfo(OMD);
12333965Sjdp  CGM.SetInternalFunctionAttributes(OMD, Fn, FI);
12433965Sjdp
12533965Sjdp  Args.push_back(std::make_pair(OMD->getSelfDecl(),
12633965Sjdp                                OMD->getSelfDecl()->getType()));
12733965Sjdp  Args.push_back(std::make_pair(OMD->getCmdDecl(),
12833965Sjdp                                OMD->getCmdDecl()->getType()));
12933965Sjdp
13033965Sjdp  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
13133965Sjdp       E = OMD->param_end(); PI != E; ++PI)
13233965Sjdp    Args.push_back(std::make_pair(*PI, (*PI)->getType()));
13333965Sjdp
13433965Sjdp  StartFunction(OMD, OMD->getResultType(), Fn, Args, OMD->getLocStart());
13533965Sjdp}
13633965Sjdp
13733965Sjdp/// Generate an Objective-C method.  An Objective-C method is a C function with
13833965Sjdp/// its pointer, name, and types registered in the class struture.
13933965Sjdpvoid CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
14033965Sjdp  StartObjCMethod(OMD, OMD->getClassInterface());
14177298Sobrien  EmitStmt(OMD->getBody());
14233965Sjdp  FinishFunction(OMD->getBodyRBrace());
14333965Sjdp}
14433965Sjdp
14533965Sjdp// FIXME: I wasn't sure about the synthesis approach. If we end up generating an
14633965Sjdp// AST for the whole body we can just fall back to having a GenerateFunction
14733965Sjdp// which takes the body Stmt.
14833965Sjdp
14933965Sjdp/// GenerateObjCGetter - Generate an Objective-C property getter
15033965Sjdp/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
15133965Sjdp/// is illegal within a category.
15233965Sjdpvoid CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
15333965Sjdp                                         const ObjCPropertyImplDecl *PID) {
15433965Sjdp  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
15533965Sjdp  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
15633965Sjdp  bool IsAtomic =
15733965Sjdp    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
15833965Sjdp  ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
15933965Sjdp  assert(OMD && "Invalid call to generate getter (empty method)");
16060484Sobrien  // FIXME: This is rather murky, we create this here since they will not have
16160484Sobrien  // been created by Sema for us.
16260484Sobrien  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
16360484Sobrien  StartObjCMethod(OMD, IMP->getClassInterface());
16460484Sobrien
16560484Sobrien  // Determine if we should use an objc_getProperty call for
16660484Sobrien  // this. Non-atomic properties are directly evaluated.
16760484Sobrien  // atomic 'copy' and 'retain' properties are also directly
16860484Sobrien  // evaluated in gc-only mode.
16960484Sobrien  if (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
17060484Sobrien      IsAtomic &&
17133965Sjdp      (PD->getSetterKind() == ObjCPropertyDecl::Copy ||
17289857Sobrien       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
17389857Sobrien    llvm::Value *GetPropertyFn =
17489857Sobrien      CGM.getObjCRuntime().GetPropertyGetFunction();
17533965Sjdp
17689857Sobrien    if (!GetPropertyFn) {
17733965Sjdp      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
17833965Sjdp      FinishFunction();
17989857Sobrien      return;
18033965Sjdp    }
18133965Sjdp
18233965Sjdp    // Return (ivar-type) objc_getProperty((id) self, _cmd, offset, true).
18389857Sobrien    // FIXME: Can't this be simpler? This might even be worse than the
18489857Sobrien    // corresponding gcc code.
18589857Sobrien    CodeGenTypes &Types = CGM.getTypes();
18633965Sjdp    ValueDecl *Cmd = OMD->getCmdDecl();
18733965Sjdp    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
18877298Sobrien    QualType IdTy = getContext().getObjCIdType();
18933965Sjdp    llvm::Value *SelfAsId =
19033965Sjdp      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
19133965Sjdp    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
19233965Sjdp    llvm::Value *True =
19377298Sobrien      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
19477298Sobrien    CallArgList Args;
19533965Sjdp    Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
19633965Sjdp    Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
19733965Sjdp    Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
19833965Sjdp    Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
19933965Sjdp    // FIXME: We shouldn't need to get the function info here, the
20033965Sjdp    // runtime already should have computed it to build the function.
20133965Sjdp    RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args,
20233965Sjdp                                               FunctionType::ExtInfo()),
20333965Sjdp                         GetPropertyFn, ReturnValueSlot(), Args);
20477298Sobrien    // We need to fix the type here. Ivars with copy & retain are
20533965Sjdp    // always objects so we don't need to worry about complex or
20633965Sjdp    // aggregates.
20733965Sjdp    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
20833965Sjdp                                           Types.ConvertType(PD->getType())));
20977298Sobrien    EmitReturnOfRValue(RV, PD->getType());
21033965Sjdp  } else {
21133965Sjdp    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
21233965Sjdp    if (Ivar->getType()->isAnyComplexType()) {
21333965Sjdp      ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(),
21477298Sobrien                                               LV.isVolatileQualified());
21533965Sjdp      StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified());
21677298Sobrien    }
21777298Sobrien    else if (hasAggregateLLVMType(Ivar->getType())) {
21877298Sobrien      bool IsStrong = false;
21933965Sjdp      if ((IsAtomic || (IsStrong = IvarTypeWithAggrGCObjects(Ivar->getType())))
22033965Sjdp          && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect
22133965Sjdp          && CGM.getObjCRuntime().GetCopyStructFunction()) {
22277298Sobrien        llvm::Value *GetCopyStructFn =
22377298Sobrien          CGM.getObjCRuntime().GetCopyStructFunction();
22433965Sjdp        CodeGenTypes &Types = CGM.getTypes();
22560484Sobrien        // objc_copyStruct (ReturnValue, &structIvar,
22633965Sjdp        //                  sizeof (Type of Ivar), isAtomic, false);
22733965Sjdp        CallArgList Args;
22833965Sjdp        RValue RV = RValue::get(Builder.CreateBitCast(ReturnValue,
22977298Sobrien                                    Types.ConvertType(getContext().VoidPtrTy)));
23077298Sobrien        Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
23133965Sjdp        RV = RValue::get(Builder.CreateBitCast(LV.getAddress(),
23260484Sobrien                                    Types.ConvertType(getContext().VoidPtrTy)));
23333965Sjdp        Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
23433965Sjdp        // sizeof (Type of Ivar)
23533965Sjdp        uint64_t Size =  getContext().getTypeSize(Ivar->getType()) / 8;
23633965Sjdp        llvm::Value *SizeVal =
23733965Sjdp          llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), Size);
23877298Sobrien        Args.push_back(std::make_pair(RValue::get(SizeVal),
23933965Sjdp                                      getContext().LongTy));
24033965Sjdp        llvm::Value *isAtomic =
24177298Sobrien          llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
24277298Sobrien                                 IsAtomic ? 1 : 0);
24377298Sobrien        Args.push_back(std::make_pair(RValue::get(isAtomic),
24477298Sobrien                                      getContext().BoolTy));
24577298Sobrien        llvm::Value *hasStrong =
24677298Sobrien          llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy),
24777298Sobrien                                 IsStrong ? 1 : 0);
24877298Sobrien        Args.push_back(std::make_pair(RValue::get(hasStrong),
24977298Sobrien                                      getContext().BoolTy));
25077298Sobrien        EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
25177298Sobrien                                       FunctionType::ExtInfo()),
25277298Sobrien                 GetCopyStructFn, ReturnValueSlot(), Args);
25377298Sobrien      }
25477298Sobrien      else
25577298Sobrien        EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType());
25677298Sobrien    } else {
25733965Sjdp      CodeGenTypes &Types = CGM.getTypes();
25833965Sjdp      RValue RV = EmitLoadOfLValue(LV, Ivar->getType());
25933965Sjdp      RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
26033965Sjdp                       Types.ConvertType(PD->getType())));
26133965Sjdp      EmitReturnOfRValue(RV, PD->getType());
26233965Sjdp    }
26333965Sjdp  }
26433965Sjdp
26533965Sjdp  FinishFunction();
26633965Sjdp}
26733965Sjdp
26833965Sjdp/// GenerateObjCSetter - Generate an Objective-C property setter
26933965Sjdp/// function. The given Decl must be an ObjCImplementationDecl. @synthesize
27033965Sjdp/// is illegal within a category.
27133965Sjdpvoid CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
27233965Sjdp                                         const ObjCPropertyImplDecl *PID) {
27333965Sjdp  ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
27433965Sjdp  const ObjCPropertyDecl *PD = PID->getPropertyDecl();
27560484Sobrien  ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
27660484Sobrien  assert(OMD && "Invalid call to generate setter (empty method)");
27760484Sobrien  // FIXME: This is rather murky, we create this here since they will not have
27877298Sobrien  // been created by Sema for us.
27960484Sobrien  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
28077298Sobrien  StartObjCMethod(OMD, IMP->getClassInterface());
28160484Sobrien
28277298Sobrien  bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
28377298Sobrien  bool IsAtomic =
28460484Sobrien    !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);
28577298Sobrien
28677298Sobrien  // Determine if we should use an objc_setProperty call for
28760484Sobrien  // this. Properties with 'copy' semantics always use it, as do
28860484Sobrien  // non-atomic properties with 'release' semantics as long as we are
28960484Sobrien  // not in gc-only mode.
29077298Sobrien  if (IsCopy ||
29160484Sobrien      (CGM.getLangOptions().getGCMode() != LangOptions::GCOnly &&
29260484Sobrien       PD->getSetterKind() == ObjCPropertyDecl::Retain)) {
29360484Sobrien    llvm::Value *SetPropertyFn =
29460484Sobrien      CGM.getObjCRuntime().GetPropertySetFunction();
29560484Sobrien
29677298Sobrien    if (!SetPropertyFn) {
29760484Sobrien      CGM.ErrorUnsupported(PID, "Obj-C getter requiring atomic copy");
29860484Sobrien      FinishFunction();
29960484Sobrien      return;
30060484Sobrien    }
30160484Sobrien
30260484Sobrien    // Emit objc_setProperty((id) self, _cmd, offset, arg,
30377298Sobrien    //                       <is-atomic>, <is-copy>).
30477298Sobrien    // FIXME: Can't this be simpler? This might even be worse than the
30560484Sobrien    // corresponding gcc code.
30660484Sobrien    CodeGenTypes &Types = CGM.getTypes();
30760484Sobrien    ValueDecl *Cmd = OMD->getCmdDecl();
30860484Sobrien    llvm::Value *CmdVal = Builder.CreateLoad(LocalDeclMap[Cmd], "cmd");
30960484Sobrien    QualType IdTy = getContext().getObjCIdType();
31060484Sobrien    llvm::Value *SelfAsId =
311      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
312    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
313    llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
314    llvm::Value *ArgAsId =
315      Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
316                            Types.ConvertType(IdTy));
317    llvm::Value *True =
318      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
319    llvm::Value *False =
320      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
321    CallArgList Args;
322    Args.push_back(std::make_pair(RValue::get(SelfAsId), IdTy));
323    Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType()));
324    Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy));
325    Args.push_back(std::make_pair(RValue::get(ArgAsId), IdTy));
326    Args.push_back(std::make_pair(RValue::get(IsAtomic ? True : False),
327                                  getContext().BoolTy));
328    Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False),
329                                  getContext().BoolTy));
330    // FIXME: We shouldn't need to get the function info here, the runtime
331    // already should have computed it to build the function.
332    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
333                                   FunctionType::ExtInfo()),
334             SetPropertyFn,
335             ReturnValueSlot(), Args);
336  } else if (IsAtomic && hasAggregateLLVMType(Ivar->getType()) &&
337             !Ivar->getType()->isAnyComplexType() &&
338             IndirectObjCSetterArg(*CurFnInfo)
339             && CGM.getObjCRuntime().GetCopyStructFunction()) {
340    // objc_copyStruct (&structIvar, &Arg,
341    //                  sizeof (struct something), true, false);
342    llvm::Value *GetCopyStructFn =
343      CGM.getObjCRuntime().GetCopyStructFunction();
344    CodeGenTypes &Types = CGM.getTypes();
345    CallArgList Args;
346    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);
347    RValue RV = RValue::get(Builder.CreateBitCast(LV.getAddress(),
348                                    Types.ConvertType(getContext().VoidPtrTy)));
349    Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
350    llvm::Value *Arg = LocalDeclMap[*OMD->param_begin()];
351    llvm::Value *ArgAsPtrTy =
352      Builder.CreateBitCast(Arg,
353                            Types.ConvertType(getContext().VoidPtrTy));
354    RV = RValue::get(ArgAsPtrTy);
355    Args.push_back(std::make_pair(RV, getContext().VoidPtrTy));
356    // sizeof (Type of Ivar)
357    uint64_t Size =  getContext().getTypeSize(Ivar->getType()) / 8;
358    llvm::Value *SizeVal =
359      llvm::ConstantInt::get(Types.ConvertType(getContext().LongTy), Size);
360    Args.push_back(std::make_pair(RValue::get(SizeVal),
361                                  getContext().LongTy));
362    llvm::Value *True =
363      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 1);
364    Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy));
365    llvm::Value *False =
366      llvm::ConstantInt::get(Types.ConvertType(getContext().BoolTy), 0);
367    Args.push_back(std::make_pair(RValue::get(False), getContext().BoolTy));
368    EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,
369                                   FunctionType::ExtInfo()),
370             GetCopyStructFn, ReturnValueSlot(), Args);
371  } else {
372    // FIXME: Find a clean way to avoid AST node creation.
373    SourceLocation Loc = PD->getLocation();
374    ValueDecl *Self = OMD->getSelfDecl();
375    ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
376    DeclRefExpr Base(Self, Self->getType(), Loc);
377    ParmVarDecl *ArgDecl = *OMD->param_begin();
378    DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc);
379    ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true);
380
381    // The property type can differ from the ivar type in some situations with
382    // Objective-C pointer types, we can always bit cast the RHS in these cases.
383    if (getContext().getCanonicalType(Ivar->getType()) !=
384        getContext().getCanonicalType(ArgDecl->getType())) {
385      ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg,
386                                 CXXBaseSpecifierArray(), false);
387      BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign,
388                            Ivar->getType(), Loc);
389      EmitStmt(&Assign);
390    } else {
391      BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign,
392                            Ivar->getType(), Loc);
393      EmitStmt(&Assign);
394    }
395  }
396
397  FinishFunction();
398}
399
400void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,
401                                                 ObjCMethodDecl *MD,
402                                                 bool ctor) {
403  llvm::SmallVector<CXXBaseOrMemberInitializer *, 8> IvarInitializers;
404  MD->createImplicitParams(CGM.getContext(), IMP->getClassInterface());
405  StartObjCMethod(MD, IMP->getClassInterface());
406  for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
407       E = IMP->init_end(); B != E; ++B) {
408    CXXBaseOrMemberInitializer *Member = (*B);
409    IvarInitializers.push_back(Member);
410  }
411  if (ctor) {
412    for (unsigned I = 0, E = IvarInitializers.size(); I != E; ++I) {
413      CXXBaseOrMemberInitializer *IvarInit = IvarInitializers[I];
414      FieldDecl *Field = IvarInit->getMember();
415      QualType FieldType = Field->getType();
416      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
417      LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
418                                    LoadObjCSelf(), Ivar, 0);
419      EmitAggExpr(IvarInit->getInit(), LV.getAddress(),
420                  LV.isVolatileQualified(), false, true);
421    }
422    // constructor returns 'self'.
423    CodeGenTypes &Types = CGM.getTypes();
424    QualType IdTy(CGM.getContext().getObjCIdType());
425    llvm::Value *SelfAsId =
426      Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
427    EmitReturnOfRValue(RValue::get(SelfAsId), IdTy);
428  }
429  else {
430    // dtor
431    for (size_t i = IvarInitializers.size(); i > 0; --i) {
432      FieldDecl *Field = IvarInitializers[i - 1]->getMember();
433      QualType FieldType = Field->getType();
434      const ConstantArrayType *Array =
435        getContext().getAsConstantArrayType(FieldType);
436      if (Array)
437        FieldType = getContext().getBaseElementType(FieldType);
438
439      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
440      LValue LV = EmitLValueForIvar(TypeOfSelfObject(),
441                                    LoadObjCSelf(), Ivar, 0);
442      const RecordType *RT = FieldType->getAs<RecordType>();
443      CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
444      if (Array) {
445        const llvm::Type *BasePtr = ConvertType(FieldType);
446        BasePtr = llvm::PointerType::getUnqual(BasePtr);
447        llvm::Value *BaseAddrPtr =
448          Builder.CreateBitCast(LV.getAddress(), BasePtr);
449        EmitCXXAggrDestructorCall(FieldClassDecl->getDestructor(getContext()),
450                                  Array, BaseAddrPtr);
451      }
452      else
453        EmitCXXDestructorCall(FieldClassDecl->getDestructor(CGM.getContext()),
454                              Dtor_Complete, /*ForVirtualBase=*/false,
455                              LV.getAddress());
456    }
457  }
458  FinishFunction();
459}
460
461bool CodeGenFunction::IndirectObjCSetterArg(const CGFunctionInfo &FI) {
462  CGFunctionInfo::const_arg_iterator it = FI.arg_begin();
463  it++; it++;
464  const ABIArgInfo &AI = it->info;
465  // FIXME. Is this sufficient check?
466  return (AI.getKind() == ABIArgInfo::Indirect);
467}
468
469bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
470  if (CGM.getLangOptions().getGCMode() == LangOptions::NonGC)
471    return false;
472  if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
473    return FDTTy->getDecl()->hasObjectMember();
474  return false;
475}
476
477llvm::Value *CodeGenFunction::LoadObjCSelf() {
478  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
479  // See if we need to lazily forward self inside a block literal.
480  BlockForwardSelf();
481  return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
482}
483
484QualType CodeGenFunction::TypeOfSelfObject() {
485  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
486  ImplicitParamDecl *selfDecl = OMD->getSelfDecl();
487  const ObjCObjectPointerType *PTy = cast<ObjCObjectPointerType>(
488    getContext().getCanonicalType(selfDecl->getType()));
489  return PTy->getPointeeType();
490}
491
492RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,
493                                                 const Selector &S) {
494  llvm::Value *Receiver = LoadObjCSelf();
495  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
496  bool isClassMessage = OMD->isClassMethod();
497  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
498  return CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
499                                                       Exp->getType(),
500                                                       S,
501                                                       OMD->getClassInterface(),
502                                                       isCategoryImpl,
503                                                       Receiver,
504                                                       isClassMessage,
505                                                       CallArgList());
506
507}
508
509RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
510  Exp = Exp->IgnoreParens();
511  // FIXME: Split it into two separate routines.
512  if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
513    Selector S = E->getProperty()->getGetterName();
514    if (isa<ObjCSuperExpr>(E->getBase()))
515      return EmitObjCSuperPropertyGet(E, S);
516    return CGM.getObjCRuntime().
517             GenerateMessageSend(*this, Exp->getType(), S,
518                                 EmitScalarExpr(E->getBase()),
519                                 CallArgList());
520  } else {
521    const ObjCImplicitSetterGetterRefExpr *KE =
522      cast<ObjCImplicitSetterGetterRefExpr>(Exp);
523    Selector S = KE->getGetterMethod()->getSelector();
524    llvm::Value *Receiver;
525    if (KE->getInterfaceDecl()) {
526      const ObjCInterfaceDecl *OID = KE->getInterfaceDecl();
527      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
528    } else if (isa<ObjCSuperExpr>(KE->getBase()))
529      return EmitObjCSuperPropertyGet(KE, S);
530    else
531      Receiver = EmitScalarExpr(KE->getBase());
532    return CGM.getObjCRuntime().
533             GenerateMessageSend(*this, Exp->getType(), S,
534                                 Receiver,
535                                 CallArgList(), KE->getInterfaceDecl());
536  }
537}
538
539void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp,
540                                               const Selector &S,
541                                               RValue Src) {
542  CallArgList Args;
543  llvm::Value *Receiver = LoadObjCSelf();
544  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
545  bool isClassMessage = OMD->isClassMethod();
546  bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());
547  Args.push_back(std::make_pair(Src, Exp->getType()));
548  CGM.getObjCRuntime().GenerateMessageSendSuper(*this,
549                                                Exp->getType(),
550                                                S,
551                                                OMD->getClassInterface(),
552                                                isCategoryImpl,
553                                                Receiver,
554                                                isClassMessage,
555                                                Args);
556  return;
557}
558
559void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
560                                          RValue Src) {
561  // FIXME: Split it into two separate routines.
562  if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
563    Selector S = E->getProperty()->getSetterName();
564    if (isa<ObjCSuperExpr>(E->getBase())) {
565      EmitObjCSuperPropertySet(E, S, Src);
566      return;
567    }
568    CallArgList Args;
569    Args.push_back(std::make_pair(Src, E->getType()));
570    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
571                                             EmitScalarExpr(E->getBase()),
572                                             Args);
573  } else if (const ObjCImplicitSetterGetterRefExpr *E =
574               dyn_cast<ObjCImplicitSetterGetterRefExpr>(Exp)) {
575    Selector S = E->getSetterMethod()->getSelector();
576    CallArgList Args;
577    llvm::Value *Receiver;
578    if (E->getInterfaceDecl()) {
579      const ObjCInterfaceDecl *OID = E->getInterfaceDecl();
580      Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);
581    } else if (isa<ObjCSuperExpr>(E->getBase())) {
582      EmitObjCSuperPropertySet(E, S, Src);
583      return;
584    } else
585      Receiver = EmitScalarExpr(E->getBase());
586    Args.push_back(std::make_pair(Src, E->getType()));
587    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
588                                             Receiver,
589                                             Args, E->getInterfaceDecl());
590  } else
591    assert (0 && "bad expression node in EmitObjCPropertySet");
592}
593
594void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
595  llvm::Constant *EnumerationMutationFn =
596    CGM.getObjCRuntime().EnumerationMutationFunction();
597  llvm::Value *DeclAddress;
598  QualType ElementTy;
599
600  if (!EnumerationMutationFn) {
601    CGM.ErrorUnsupported(&S, "Obj-C fast enumeration for this runtime");
602    return;
603  }
604
605  if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
606    EmitStmt(SD);
607    assert(HaveInsertPoint() && "DeclStmt destroyed insert point!");
608    const Decl* D = SD->getSingleDecl();
609    ElementTy = cast<ValueDecl>(D)->getType();
610    DeclAddress = LocalDeclMap[D];
611  } else {
612    ElementTy = cast<Expr>(S.getElement())->getType();
613    DeclAddress = 0;
614  }
615
616  // Fast enumeration state.
617  QualType StateTy = getContext().getObjCFastEnumerationStateType();
618  llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr");
619  EmitMemSetToZero(StatePtr, StateTy);
620
621  // Number of elements in the items array.
622  static const unsigned NumItems = 16;
623
624  // Get selector
625  IdentifierInfo *II[] = {
626    &CGM.getContext().Idents.get("countByEnumeratingWithState"),
627    &CGM.getContext().Idents.get("objects"),
628    &CGM.getContext().Idents.get("count")
629  };
630  Selector FastEnumSel =
631    CGM.getContext().Selectors.getSelector(llvm::array_lengthof(II), &II[0]);
632
633  QualType ItemsTy =
634    getContext().getConstantArrayType(getContext().getObjCIdType(),
635                                      llvm::APInt(32, NumItems),
636                                      ArrayType::Normal, 0);
637  llvm::Value *ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
638
639  llvm::Value *Collection = EmitScalarExpr(S.getCollection());
640
641  CallArgList Args;
642  Args.push_back(std::make_pair(RValue::get(StatePtr),
643                                getContext().getPointerType(StateTy)));
644
645  Args.push_back(std::make_pair(RValue::get(ItemsPtr),
646                                getContext().getPointerType(ItemsTy)));
647
648  const llvm::Type *UnsignedLongLTy = ConvertType(getContext().UnsignedLongTy);
649  llvm::Constant *Count = llvm::ConstantInt::get(UnsignedLongLTy, NumItems);
650  Args.push_back(std::make_pair(RValue::get(Count),
651                                getContext().UnsignedLongTy));
652
653  RValue CountRV =
654    CGM.getObjCRuntime().GenerateMessageSend(*this,
655                                             getContext().UnsignedLongTy,
656                                             FastEnumSel,
657                                             Collection, Args);
658
659  llvm::Value *LimitPtr = CreateMemTemp(getContext().UnsignedLongTy,
660                                        "limit.ptr");
661  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
662
663  llvm::BasicBlock *NoElements = createBasicBlock("noelements");
664  llvm::BasicBlock *SetStartMutations = createBasicBlock("setstartmutations");
665
666  llvm::Value *Limit = Builder.CreateLoad(LimitPtr);
667  llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy);
668
669  llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
670  Builder.CreateCondBr(IsZero, NoElements, SetStartMutations);
671
672  EmitBlock(SetStartMutations);
673
674  llvm::Value *StartMutationsPtr = CreateMemTemp(getContext().UnsignedLongTy);
675
676  llvm::Value *StateMutationsPtrPtr =
677    Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr");
678  llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr,
679                                                      "mutationsptr");
680
681  llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr,
682                                                   "mutations");
683
684  Builder.CreateStore(StateMutations, StartMutationsPtr);
685
686  llvm::BasicBlock *LoopStart = createBasicBlock("loopstart");
687  EmitBlock(LoopStart);
688
689  llvm::Value *CounterPtr = CreateMemTemp(getContext().UnsignedLongTy,
690                                       "counter.ptr");
691  Builder.CreateStore(Zero, CounterPtr);
692
693  llvm::BasicBlock *LoopBody = createBasicBlock("loopbody");
694  EmitBlock(LoopBody);
695
696  StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr");
697  StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations");
698
699  llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr,
700                                                   "mutations");
701  llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations,
702                                                     StartMutations,
703                                                     "tobool");
704
705
706  llvm::BasicBlock *WasMutated = createBasicBlock("wasmutated");
707  llvm::BasicBlock *WasNotMutated = createBasicBlock("wasnotmutated");
708
709  Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated);
710
711  EmitBlock(WasMutated);
712  llvm::Value *V =
713    Builder.CreateBitCast(Collection,
714                          ConvertType(getContext().getObjCIdType()),
715                          "tmp");
716  CallArgList Args2;
717  Args2.push_back(std::make_pair(RValue::get(V),
718                                getContext().getObjCIdType()));
719  // FIXME: We shouldn't need to get the function info here, the runtime already
720  // should have computed it to build the function.
721  EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2,
722                                          FunctionType::ExtInfo()),
723           EnumerationMutationFn, ReturnValueSlot(), Args2);
724
725  EmitBlock(WasNotMutated);
726
727  llvm::Value *StateItemsPtr =
728    Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr");
729
730  llvm::Value *Counter = Builder.CreateLoad(CounterPtr, "counter");
731
732  llvm::Value *EnumStateItems = Builder.CreateLoad(StateItemsPtr,
733                                                   "stateitems");
734
735  llvm::Value *CurrentItemPtr =
736    Builder.CreateGEP(EnumStateItems, Counter, "currentitem.ptr");
737
738  llvm::Value *CurrentItem = Builder.CreateLoad(CurrentItemPtr, "currentitem");
739
740  // Cast the item to the right type.
741  CurrentItem = Builder.CreateBitCast(CurrentItem,
742                                      ConvertType(ElementTy), "tmp");
743
744  if (!DeclAddress) {
745    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
746
747    // Set the value to null.
748    Builder.CreateStore(CurrentItem, LV.getAddress());
749  } else
750    Builder.CreateStore(CurrentItem, DeclAddress);
751
752  // Increment the counter.
753  Counter = Builder.CreateAdd(Counter,
754                              llvm::ConstantInt::get(UnsignedLongLTy, 1));
755  Builder.CreateStore(Counter, CounterPtr);
756
757  llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
758  llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
759
760  BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
761
762  EmitStmt(S.getBody());
763
764  BreakContinueStack.pop_back();
765
766  EmitBlock(AfterBody);
767
768  llvm::BasicBlock *FetchMore = createBasicBlock("fetchmore");
769
770  Counter = Builder.CreateLoad(CounterPtr);
771  Limit = Builder.CreateLoad(LimitPtr);
772  llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless");
773  Builder.CreateCondBr(IsLess, LoopBody, FetchMore);
774
775  // Fetch more elements.
776  EmitBlock(FetchMore);
777
778  CountRV =
779    CGM.getObjCRuntime().GenerateMessageSend(*this,
780                                             getContext().UnsignedLongTy,
781                                             FastEnumSel,
782                                             Collection, Args);
783  Builder.CreateStore(CountRV.getScalarVal(), LimitPtr);
784  Limit = Builder.CreateLoad(LimitPtr);
785
786  IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero");
787  Builder.CreateCondBr(IsZero, NoElements, LoopStart);
788
789  // No more elements.
790  EmitBlock(NoElements);
791
792  if (!DeclAddress) {
793    // If the element was not a declaration, set it to be null.
794
795    LValue LV = EmitLValue(cast<Expr>(S.getElement()));
796
797    // Set the value to null.
798    Builder.CreateStore(llvm::Constant::getNullValue(ConvertType(ElementTy)),
799                        LV.getAddress());
800  }
801
802  EmitBlock(LoopEnd);
803}
804
805void CodeGenFunction::EmitObjCAtTryStmt(const ObjCAtTryStmt &S) {
806  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
807}
808
809void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) {
810  CGM.getObjCRuntime().EmitThrowStmt(*this, S);
811}
812
813void CodeGenFunction::EmitObjCAtSynchronizedStmt(
814                                              const ObjCAtSynchronizedStmt &S) {
815  CGM.getObjCRuntime().EmitTryOrSynchronizedStmt(*this, S);
816}
817
818CGObjCRuntime::~CGObjCRuntime() {}
819