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 | 0692a32a3e97f74728cdaba8ba7986702b693faf (patch) | |
tree | 8076aeed5ba2bf8a4117f18215adf6f34050ea6f /clang/lib/CodeGen/CGObjC.cpp | |
parent | 87408b61af2c3ecd584b8ddd5ee0d25f9e6519b3 (diff) | |
download | bcm5719-llvm-0692a32a3e97f74728cdaba8ba7986702b693faf.tar.gz bcm5719-llvm-0692a32a3e97f74728cdaba8ba7986702b693faf.zip |
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.
llvm-svn: 120887
Diffstat (limited to 'clang/lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 87 |
1 files changed, 43 insertions, 44 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 4b2b8612e70..a8acb2b72ff 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/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){ |