diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 | 
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-27 15:17:06 +0000 | 
| commit | d7279c4c177bca357ef96ff1379fd9bc420bfe83 (patch) | |
| tree | 3558f327a6f9ab59c5d7a06528d84e1560445247 /lib/CodeGen/CGObjC.cpp | |
| parent | be17651f5cd2e94922c1b732bc8589e180698193 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/CGObjC.cpp')
| -rw-r--r-- | lib/CodeGen/CGObjC.cpp | 92 | 
1 files changed, 57 insertions, 35 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 8426f7105be4..7c842a94986c 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -47,7 +47,8 @@ llvm::Value *CodeGenFunction::EmitObjCProtocolExpr(const ObjCProtocolExpr *E) {  } -RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) { +RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E, +                                            ReturnValueSlot Return) {    // Only the lookup mechanism and first two arguments of the method    // implementation vary between runtimes.  We can get the receiver and    // arguments in generic code. @@ -64,10 +65,11 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {      break;    case ObjCMessageExpr::Class: { -    const ObjCInterfaceType *IFace -      = E->getClassReceiver()->getAs<ObjCInterfaceType>(); -    OID = IFace->getDecl(); -    assert(IFace && "Invalid Objective-C class message send"); +    const ObjCObjectType *ObjTy +      = E->getClassReceiver()->getAs<ObjCObjectType>(); +    assert(ObjTy && "Invalid Objective-C class message send"); +    OID = ObjTy->getInterface(); +    assert(OID && "Invalid Objective-C class message send");      Receiver = Runtime.GetClass(Builder, OID);      isClassMessage = true;      break; @@ -92,7 +94,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {      // super is only valid in an Objective-C method      const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);      bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); -    return Runtime.GenerateMessageSendSuper(*this, E->getType(), +    return Runtime.GenerateMessageSendSuper(*this, Return, E->getType(),                                              E->getSelector(),                                              OMD->getClassInterface(),                                              isCategoryImpl, @@ -102,7 +104,8 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {                                              E->getMethodDecl());    } -  return Runtime.GenerateMessageSend(*this, E->getType(), E->getSelector(), +  return Runtime.GenerateMessageSend(*this, Return, E->getType(), +                                     E->getSelector(),                                       Receiver, Args, OID,                                       E->getMethodDecl());  } @@ -157,9 +160,6 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,      !(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_nonatomic);    ObjCMethodDecl *OMD = PD->getGetterMethodDecl();    assert(OMD && "Invalid call to generate getter (empty method)"); -  // FIXME: This is rather murky, we create this here since they will not have -  // been created by Sema for us. -  OMD->createImplicitParams(getContext(), IMP->getClassInterface());    StartObjCMethod(OMD, IMP->getClassInterface());    // Determine if we should use an objc_getProperty call for @@ -208,8 +208,9 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,                                             Types.ConvertType(PD->getType())));      EmitReturnOfRValue(RV, PD->getType());    } else { -    LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(), Ivar, 0);      if (Ivar->getType()->isAnyComplexType()) { +      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),  +                                    Ivar, 0);        ComplexPairTy Pair = LoadComplexFromAddr(LV.getAddress(),                                                 LV.isVolatileQualified());        StoreComplexToAddr(Pair, ReturnValue, LV.isVolatileQualified()); @@ -219,6 +220,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,        if ((IsAtomic || (IsStrong = IvarTypeWithAggrGCObjects(Ivar->getType())))            && CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect            && CGM.getObjCRuntime().GetCopyStructFunction()) { +        LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),  +                                      Ivar, 0);          llvm::Value *GetCopyStructFn =            CGM.getObjCRuntime().GetCopyStructFunction();          CodeGenTypes &Types = CGM.getTypes(); @@ -251,9 +254,23 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,                                         FunctionType::ExtInfo()),                   GetCopyStructFn, ReturnValueSlot(), Args);        } -      else -        EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType()); +      else { +        if (PID->getGetterCXXConstructor()) { +          ReturnStmt *Stmt =  +            new (getContext()) ReturnStmt(SourceLocation(),  +                                          PID->getGetterCXXConstructor(), +                                          0); +          EmitReturnStmt(*Stmt); +        } +        else { +          LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),  +                                        Ivar, 0); +          EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType()); +        } +      }      } else { +      LValue LV = EmitLValueForIvar(TypeOfSelfObject(), LoadObjCSelf(),  +                                    Ivar, 0);        CodeGenTypes &Types = CGM.getTypes();        RValue RV = EmitLoadOfLValue(LV, Ivar->getType());        RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(), @@ -274,9 +291,6 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,    const ObjCPropertyDecl *PD = PID->getPropertyDecl();    ObjCMethodDecl *OMD = PD->getSetterMethodDecl();    assert(OMD && "Invalid call to generate setter (empty method)"); -  // FIXME: This is rather murky, we create this here since they will not have -  // been created by Sema for us. -  OMD->createImplicitParams(getContext(), IMP->getClassInterface());    StartObjCMethod(OMD, IMP->getClassInterface());    bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy; @@ -368,6 +382,10 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,      EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args,                                     FunctionType::ExtInfo()),               GetCopyStructFn, ReturnValueSlot(), Args); +  } else if (PID->getSetterCXXAssignment()) { +    EmitAnyExpr(PID->getSetterCXXAssignment(), (llvm::Value *)0, false, true, +                false); +                    } else {      // FIXME: Find a clean way to avoid AST node creation.      SourceLocation Loc = PD->getLocation(); @@ -425,8 +443,7 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,      llvm::Value *SelfAsId =        Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));      EmitReturnOfRValue(RValue::get(SelfAsId), IdTy); -  } -  else { +  } else {      // dtor      for (size_t i = IvarInitializers.size(); i > 0; --i) {        FieldDecl *Field = IvarInitializers[i - 1]->getMember(); @@ -442,7 +459,7 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,        const RecordType *RT = FieldType->getAs<RecordType>();        CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());        CXXDestructorDecl *Dtor = FieldClassDecl->getDestructor(getContext()); -      if (!Dtor->isTrivial()) +      if (!Dtor->isTrivial()) {          if (Array) {            const llvm::Type *BasePtr = ConvertType(FieldType);            BasePtr = llvm::PointerType::getUnqual(BasePtr); @@ -450,12 +467,13 @@ void CodeGenFunction::GenerateObjCCtorDtorMethod(ObjCImplementationDecl *IMP,              Builder.CreateBitCast(LV.getAddress(), BasePtr);            EmitCXXAggrDestructorCall(Dtor,                                      Array, BaseAddrPtr); -        } -        else  +        } else {            EmitCXXDestructorCall(Dtor,                                  Dtor_Complete, /*ForVirtualBase=*/false,                                  LV.getAddress()); -    }     +        } +      } +    }    }    FinishFunction();  } @@ -478,8 +496,6 @@ bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {  llvm::Value *CodeGenFunction::LoadObjCSelf() {    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); -  // See if we need to lazily forward self inside a block literal. -  BlockForwardSelf();    return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");  } @@ -492,12 +508,14 @@ QualType CodeGenFunction::TypeOfSelfObject() {  }  RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp, -                                                 const Selector &S) { +                                                 const Selector &S, +                                                 ReturnValueSlot Return) {    llvm::Value *Receiver = LoadObjCSelf();    const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);    bool isClassMessage = OMD->isClassMethod();    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());    return CGM.getObjCRuntime().GenerateMessageSendSuper(*this, +                                                       Return,                                                         Exp->getType(),                                                         S,                                                         OMD->getClassInterface(), @@ -508,15 +526,16 @@ RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp,  } -RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) { +RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp, +                                            ReturnValueSlot Return) {    Exp = Exp->IgnoreParens();    // FIXME: Split it into two separate routines.    if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {      Selector S = E->getProperty()->getGetterName();      if (isa<ObjCSuperExpr>(E->getBase())) -      return EmitObjCSuperPropertyGet(E, S); +      return EmitObjCSuperPropertyGet(E, S, Return);      return CGM.getObjCRuntime(). -             GenerateMessageSend(*this, Exp->getType(), S, +             GenerateMessageSend(*this, Return, Exp->getType(), S,                                   EmitScalarExpr(E->getBase()),                                   CallArgList());    } else { @@ -528,11 +547,11 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {        const ObjCInterfaceDecl *OID = KE->getInterfaceDecl();        Receiver = CGM.getObjCRuntime().GetClass(Builder, OID);      } else if (isa<ObjCSuperExpr>(KE->getBase())) -      return EmitObjCSuperPropertyGet(KE, S); +      return EmitObjCSuperPropertyGet(KE, S, Return);      else        Receiver = EmitScalarExpr(KE->getBase());      return CGM.getObjCRuntime(). -             GenerateMessageSend(*this, Exp->getType(), S, +             GenerateMessageSend(*this, Return, Exp->getType(), S,                                   Receiver,                                   CallArgList(), KE->getInterfaceDecl());    } @@ -548,6 +567,7 @@ void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp,    bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext());    Args.push_back(std::make_pair(Src, Exp->getType()));    CGM.getObjCRuntime().GenerateMessageSendSuper(*this, +                                                ReturnValueSlot(),                                                  Exp->getType(),                                                  S,                                                  OMD->getClassInterface(), @@ -569,7 +589,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,      }      CallArgList Args;      Args.push_back(std::make_pair(Src, E->getType())); -    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, +    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), +                                             getContext().VoidTy, S,                                               EmitScalarExpr(E->getBase()),                                               Args);    } else if (const ObjCImplicitSetterGetterRefExpr *E = @@ -586,7 +607,8 @@ void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,      } else        Receiver = EmitScalarExpr(E->getBase());      Args.push_back(std::make_pair(Src, E->getType())); -    CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S, +    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), +                                             getContext().VoidTy, S,                                               Receiver,                                               Args, E->getInterfaceDecl());    } else @@ -618,7 +640,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){    // Fast enumeration state.    QualType StateTy = getContext().getObjCFastEnumerationStateType();    llvm::Value *StatePtr = CreateMemTemp(StateTy, "state.ptr"); -  EmitMemSetToZero(StatePtr, StateTy); +  EmitNullInitialization(StatePtr, StateTy);    // Number of elements in the items array.    static const unsigned NumItems = 16; @@ -653,7 +675,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){                                  getContext().UnsignedLongTy));    RValue CountRV = -    CGM.getObjCRuntime().GenerateMessageSend(*this, +    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),                                               getContext().UnsignedLongTy,                                               FastEnumSel,                                               Collection, Args); @@ -778,7 +800,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){    EmitBlock(FetchMore);    CountRV = -    CGM.getObjCRuntime().GenerateMessageSend(*this, +    CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),                                               getContext().UnsignedLongTy,                                               FastEnumSel,                                               Collection, Args);  | 
