diff options
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 26 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 45 | ||||
-rw-r--r-- | lib/CodeGen/CGValue.h | 22 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 5 | ||||
-rw-r--r-- | test/CodeGenObjC/implicit-property.m | 16 |
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; +} + |