diff options
author | John McCall <rjmccall@apple.com> | 2010-12-04 03:11:00 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-12-04 03:11:00 +0000 |
commit | e68b9842d2d6adc2c72c81c845a2c68e58d9d3a4 (patch) | |
tree | 64d7de04261b00bf4b4796366796afed3afb7e76 /lib/CodeGen/CGObjC.cpp | |
parent | 119a1c6c4029d30cae7b31a2826aa0ff70d01668 (diff) |
Test case for the l-value base only being evaluated once.
Also, move the l-value emission code into CGObjC.cpp and teach it, for
completeness, to store away self for a super send.
Also, inline the super cases for property gets and sets and make them
use the correct result type for implicit getter/setter calls.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120887 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 87 |
1 files changed, 43 insertions, 44 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 4b2b8612e7..a8acb2b72f 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -509,23 +509,36 @@ QualType CodeGenFunction::TypeOfSelfObject() { return PTy->getPointeeType(); } -RValue CodeGenFunction::EmitObjCSuperPropertyGet(const Expr *Exp, - const Selector &S, - ReturnValueSlot Return) { - llvm::Value *Receiver = LoadObjCSelf(); - const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); +LValue +CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) { + // This is a special l-value that just issues sends when we load or + // store through it. + + // For certain base kinds, we need to emit the base immediately. + llvm::Value *Base; + if (E->isSuperReceiver()) + Base = LoadObjCSelf(); + else if (E->isClassReceiver()) + Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver()); + else + Base = EmitScalarExpr(E->getBase()); + return LValue::MakePropertyRef(E, Base); +} + +static RValue GenerateMessageSendSuper(CodeGenFunction &CGF, + ReturnValueSlot Return, + QualType ResultType, + Selector S, + llvm::Value *Receiver, + const CallArgList &CallArgs) { + const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CGF.CurFuncDecl); bool isClassMessage = OMD->isClassMethod(); bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); - return CGM.getObjCRuntime().GenerateMessageSendSuper(*this, - Return, - Exp->getType(), - S, - OMD->getClassInterface(), - isCategoryImpl, - Receiver, - isClassMessage, - CallArgList()); - + return CGF.CGM.getObjCRuntime() + .GenerateMessageSendSuper(CGF, Return, ResultType, + S, OMD->getClassInterface(), + isCategoryImpl, Receiver, + isClassMessage, CallArgs); } RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV, @@ -543,10 +556,13 @@ RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV, ResultType = Getter->getResultType(); // with reference! } + llvm::Value *Receiver = LV.getPropertyRefBaseAddr(); + + // Accesses to 'super' follow a different code path. if (E->isSuperReceiver()) - return EmitObjCSuperPropertyGet(E, S, Return); + return GenerateMessageSendSuper(*this, Return, ResultType, + S, Receiver, CallArgList()); - llvm::Value *Receiver = LV.getPropertyRefBaseAddr(); const ObjCInterfaceDecl *ReceiverClass = (E->isClassReceiver() ? E->getClassReceiver() : 0); return CGM.getObjCRuntime(). @@ -554,27 +570,6 @@ RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV, Receiver, CallArgList(), ReceiverClass); } -void CodeGenFunction::EmitObjCSuperPropertySet(const Expr *Exp, - const Selector &S, - RValue Src) { - CallArgList Args; - llvm::Value *Receiver = LoadObjCSelf(); - const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl); - bool isClassMessage = OMD->isClassMethod(); - bool isCategoryImpl = isa<ObjCCategoryImplDecl>(OMD->getDeclContext()); - Args.push_back(std::make_pair(Src, Exp->getType())); - CGM.getObjCRuntime().GenerateMessageSendSuper(*this, - ReturnValueSlot(), - getContext().VoidTy, - S, - OMD->getClassInterface(), - isCategoryImpl, - Receiver, - isClassMessage, - Args); - return; -} - void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst) { const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr(); @@ -588,20 +583,24 @@ void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src, ArgType = E->getType(); } + CallArgList Args; + Args.push_back(std::make_pair(Src, ArgType)); + + llvm::Value *Receiver = Dst.getPropertyRefBaseAddr(); + QualType ResultType = getContext().VoidTy; + if (E->isSuperReceiver()) { - EmitObjCSuperPropertySet(E, S, Src); + GenerateMessageSendSuper(*this, ReturnValueSlot(), + ResultType, S, Receiver, Args); return; } - llvm::Value *Receiver = Dst.getPropertyRefBaseAddr(); const ObjCInterfaceDecl *ReceiverClass = (E->isClassReceiver() ? E->getClassReceiver() : 0); - CallArgList Args; - Args.push_back(std::make_pair(Src, ArgType)); CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(), - getContext().VoidTy, S, - Receiver, Args, ReceiverClass); + ResultType, S, Receiver, Args, + ReceiverClass); } void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ |