aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjC.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-12-04 03:11:00 +0000
committerJohn McCall <rjmccall@apple.com>2010-12-04 03:11:00 +0000
commite68b9842d2d6adc2c72c81c845a2c68e58d9d3a4 (patch)
tree64d7de04261b00bf4b4796366796afed3afb7e76 /lib/CodeGen/CGObjC.cpp
parent119a1c6c4029d30cae7b31a2826aa0ff70d01668 (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.cpp87
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){