aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGExpr.cpp26
-rw-r--r--lib/CodeGen/CGExprAgg.cpp9
-rw-r--r--lib/CodeGen/CGExprScalar.cpp3
-rw-r--r--lib/CodeGen/CGObjC.cpp45
-rw-r--r--lib/CodeGen/CGValue.h22
-rw-r--r--lib/CodeGen/CodeGenFunction.h5
-rw-r--r--test/CodeGenObjC/implicit-property.m16
7 files changed, 112 insertions, 14 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 4f2bd4871b..4ad698ad11 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -132,6 +132,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
case Expr::ObjCPropertyRefExprClass:
return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
+ case Expr::ObjCKVCRefExprClass:
+ return EmitObjCKVCRefLValue(cast<ObjCKVCRefExpr>(E));
case Expr::ObjCSuperExprClass:
return EmitObjCSuperExpr(cast<ObjCSuperExpr>(E));
@@ -199,6 +201,9 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
if (LV.isPropertyRef())
return EmitLoadOfPropertyRefLValue(LV, ExprType);
+ if (LV.isKVCRef())
+ return EmitLoadOfKVCRefLValue(LV, ExprType);
+
assert(0 && "Unknown LValue type!");
//an invalid RValue, but the assert will
//ensure that this point is never reached
@@ -274,6 +279,11 @@ RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
return EmitObjCPropertyGet(LV.getPropertyRefExpr());
}
+RValue CodeGenFunction::EmitLoadOfKVCRefLValue(LValue LV,
+ QualType ExprType) {
+ return EmitObjCPropertyGet(LV.getKVCRefExpr());
+}
+
// If this is a reference to a subset of the elements of a vector, either
// shuffle the input or extract/insert them as appropriate.
RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
@@ -357,6 +367,9 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
if (Dst.isPropertyRef())
return EmitStoreThroughPropertyRefLValue(Src, Dst, Ty);
+ if (Dst.isKVCRef())
+ return EmitStoreThroughKVCRefLValue(Src, Dst, Ty);
+
assert(0 && "Unknown LValue type");
}
@@ -491,6 +504,12 @@ void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
EmitObjCPropertySet(Dst.getPropertyRefExpr(), Src);
}
+void CodeGenFunction::EmitStoreThroughKVCRefLValue(RValue Src,
+ LValue Dst,
+ QualType Ty) {
+ EmitObjCPropertySet(Dst.getKVCRefExpr(), Src);
+}
+
void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
LValue Dst,
QualType Ty) {
@@ -973,6 +992,13 @@ CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers());
}
+LValue
+CodeGenFunction::EmitObjCKVCRefLValue(const ObjCKVCRefExpr *E) {
+ // This is a special l-value that just issues sends when we load or
+ // store through it.
+ return LValue::MakeKVCRef(E, E->getType().getCVRQualifiers());
+}
+
LValue
CodeGenFunction::EmitObjCSuperExpr(const ObjCSuperExpr *E) {
return EmitUnsupportedLValue(E, "use of super");
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 66f3feb8cc..a06d3b63c1 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -229,6 +229,15 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
CGF.EmitAggExpr(E->getRHS(), AggLoc, false);
CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(),
RValue::getAggregate(AggLoc));
+ }
+ else if (LHS.isKVCRef()) {
+ // FIXME: Volatility?
+ llvm::Value *AggLoc = DestPtr;
+ if (!AggLoc)
+ AggLoc = CGF.CreateTempAlloca(CGF.ConvertType(E->getRHS()->getType()));
+ CGF.EmitAggExpr(E->getRHS(), AggLoc, false);
+ CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(),
+ RValue::getAggregate(AggLoc));
} else {
// Codegen the RHS so that it stores directly into the LHS.
CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), false /*FIXME: VOLATILE LHS*/);
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index a8a40bef20..8c4303b467 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -145,6 +145,9 @@ public:
Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
return EmitLoadOfLValue(E);
}
+ Value *VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
+ return EmitLoadOfLValue(E);
+ }
Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
return CGF.EmitObjCMessageExpr(E).getScalarVal();
}
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 226ec9917c..efdb0db129 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -279,25 +279,46 @@ llvm::Value *CodeGenFunction::LoadObjCSelf() {
}
RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) {
+ // FIXME: Split it into two separate routines.
if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
Selector S = E->getProperty()->getGetterName();
-
return CGM.getObjCRuntime().
- GenerateMessageSend(*this, E->getType(), S,
- EmitScalarExpr(E->getBase()),
- false, CallArgList());
+ GenerateMessageSend(*this, Exp->getType(), S,
+ EmitScalarExpr(E->getBase()),
+ false, CallArgList());
+ }
+ else if (const ObjCKVCRefExpr *E = dyn_cast<ObjCKVCRefExpr>(Exp)) {
+ Selector S = E->getGetterMethod()->getSelector();
+ return CGM.getObjCRuntime().
+ GenerateMessageSend(*this, Exp->getType(), S,
+ EmitScalarExpr(E->getBase()),
+ false, CallArgList());
}
- assert (0);
+ else
+ assert (0 && "bad expression node in EmitObjCPropertyGet");
}
-void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E,
+void CodeGenFunction::EmitObjCPropertySet(const Expr *Exp,
RValue Src) {
- Selector S = E->getProperty()->getSetterName();
- CallArgList Args;
- Args.push_back(std::make_pair(Src, E->getType()));
- CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
- EmitScalarExpr(E->getBase()),
- false, Args);
+ // FIXME: Split it into two separate routines.
+ if (const ObjCPropertyRefExpr *E = dyn_cast<ObjCPropertyRefExpr>(Exp)) {
+ Selector S = E->getProperty()->getSetterName();
+ CallArgList Args;
+ Args.push_back(std::make_pair(Src, E->getType()));
+ CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+ EmitScalarExpr(E->getBase()),
+ false, Args);
+ }
+ else if (const ObjCKVCRefExpr *E = dyn_cast<ObjCKVCRefExpr>(Exp)) {
+ Selector S = E->getSetterMethod()->getSelector();
+ CallArgList Args;
+ Args.push_back(std::make_pair(Src, E->getType()));
+ CGM.getObjCRuntime().GenerateMessageSend(*this, getContext().VoidTy, S,
+ EmitScalarExpr(E->getBase()),
+ false, Args);
+ }
+ else
+ assert (0 && "bad expression node in EmitObjCPropertySet");
}
void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index 59cfc54c9d..f16bb0838f 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -24,6 +24,7 @@ namespace llvm {
namespace clang {
class ObjCPropertyRefExpr;
+ class ObjCKVCRefExpr;
namespace CodeGen {
@@ -103,8 +104,10 @@ class LValue {
VectorElt, // This is a vector element l-value (V[i]), use getVector*
BitField, // This is a bitfield l-value, use getBitfield*.
ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
- PropertyRef // This is an Objective-C property reference, use
+ PropertyRef, // This is an Objective-C property reference, use
// getPropertyRefExpr
+ KVCRef // This is an objective-c 'implicit' property ref,
+ // use getKVCRefExpr
} LVType;
enum ObjCType {
@@ -131,6 +134,8 @@ class LValue {
// Obj-C property reference expression
const ObjCPropertyRefExpr *PropertyRefExpr;
+ // ObjC 'implicit' property reference expression
+ const ObjCKVCRefExpr *KVCRefExpr;
};
bool Volatile:1;
@@ -160,6 +165,7 @@ public:
bool isBitfield() const { return LVType == BitField; }
bool isExtVectorElt() const { return LVType == ExtVectorElt; }
bool isPropertyRef() const { return LVType == PropertyRef; }
+ bool isKVCRef() const { return LVType == KVCRef; }
bool isVolatileQualified() const { return Volatile; }
bool isRestrictQualified() const { return Restrict; }
@@ -211,6 +217,12 @@ public:
return PropertyRefExpr;
}
+ // 'implicit' property ref lvalue
+ const ObjCKVCRefExpr *getKVCRefExpr() const {
+ assert(isKVCRef());
+ return KVCRefExpr;
+ }
+
static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers) {
LValue R;
R.LVType = Simple;
@@ -263,6 +275,14 @@ public:
SetQualifiers(Qualifiers,R);
return R;
}
+ static LValue MakeKVCRef(const ObjCKVCRefExpr *E,
+ unsigned Qualifiers) {
+ LValue R;
+ R.LVType = KVCRef;
+ R.KVCRefExpr = E;
+ SetQualifiers(Qualifiers,R);
+ return R;
+ }
};
} // end namespace CodeGen
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 56a6e16e9e..63af44f9cb 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -439,6 +439,7 @@ public:
RValue EmitLoadOfExtVectorElementLValue(LValue V, QualType LVType);
RValue EmitLoadOfBitfieldLValue(LValue LV, QualType ExprType);
RValue EmitLoadOfPropertyRefLValue(LValue LV, QualType ExprType);
+ RValue EmitLoadOfKVCRefLValue(LValue LV, QualType ExprType);
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
@@ -448,6 +449,7 @@ public:
void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst,
QualType Ty);
void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst, QualType Ty);
+ void EmitStoreThroughKVCRefLValue(RValue Src, LValue Dst, QualType Ty);
/// EmitStoreThroughLValue - Store Src into Dst with same
/// constraints as EmitStoreThroughLValue.
@@ -484,6 +486,7 @@ public:
LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E);
+ LValue EmitObjCKVCRefLValue(const ObjCKVCRefExpr *E);
LValue EmitObjCSuperExpr(const ObjCSuperExpr *E);
//===--------------------------------------------------------------------===//
@@ -525,7 +528,7 @@ public:
llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E);
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E);
RValue EmitObjCPropertyGet(const Expr *E);
- void EmitObjCPropertySet(const ObjCPropertyRefExpr *E, RValue Src);
+ void EmitObjCPropertySet(const Expr *E, RValue Src);
//===--------------------------------------------------------------------===//
diff --git a/test/CodeGenObjC/implicit-property.m b/test/CodeGenObjC/implicit-property.m
new file mode 100644
index 0000000000..11d2a5603b
--- /dev/null
+++ b/test/CodeGenObjC/implicit-property.m
@@ -0,0 +1,16 @@
+// RUN: clang -emit-llvm -triple=i686-apple-darwin8 -o %t %s
+// RUNX: clang -emit-llvm -o %t %s
+
+@interface A
+ -(void) setOk:(int)arg;
+ -(int) ok;
+
+ -(void) setX:(int)arg;
+ -(int) x;
+@end
+
+void f0(A *a) {
+ a.x = 1;
+ a.ok = a.x;
+}
+