From 9e22c0d317d0edfe9aaff6e1473b0029642aecca Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 29 Aug 2008 08:11:39 +0000 Subject: [PATCH] Add special "property reference" CodeGen::LValue type for emitting Objective-C property references. - This handles property references "more correctly" but setters still don't work. llvm-svn: 55534 --- clang/lib/CodeGen/CGExpr.cpp | 28 +++++++++++++++++++++++++--- clang/lib/CodeGen/CGExprScalar.cpp | 12 ++++++++---- clang/lib/CodeGen/CGObjC.cpp | 6 ++++++ clang/lib/CodeGen/CGValue.h | 26 ++++++++++++++++++++++++-- clang/lib/CodeGen/CodeGenFunction.h | 4 ++++ 5 files changed, 67 insertions(+), 9 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 0b4bf23a4974..d3872c12dd0c 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -112,9 +112,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { case Expr::ObjCIvarRefExprClass: return EmitObjCIvarRefLValue(cast(E)); case Expr::ObjCPropertyRefExprClass: - // FIXME: Implement! - return EmitUnsupportedLValue(E, - "l-value expression (Objective-C property)"); + return EmitObjCPropertyRefLValue(cast(E)); case Expr::UnaryOperatorClass: return EmitUnaryOpLValue(cast(E)); @@ -169,6 +167,9 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) { if (LV.isBitfield()) return EmitLoadOfBitfieldLValue(LV, ExprType); + if (LV.isPropertyRef()) + return EmitLoadOfPropertyRefLValue(LV, ExprType); + assert(0 && "Unknown LValue type!"); //an invalid RValue, but the assert will //ensure that this point is never reached @@ -238,6 +239,11 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV, return RValue::get(Val); } +RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV, + QualType ExprType) { + return EmitObjCPropertyGet(LV.getPropertyRefExpr()); +} + // 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, @@ -318,6 +324,9 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, if (Dst.isBitfield()) return EmitStoreThroughBitfieldLValue(Src, Dst, Ty); + if (Dst.isPropertyRef()) + return EmitStoreThroughPropertyRefLValue(Src, Dst, Ty); + assert(0 && "Unknown LValue type"); } @@ -407,6 +416,12 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, } } +void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src, + LValue Dst, + QualType Ty) { + EmitObjCPropertySet(Dst.getPropertyRefExpr(), Src); +} + void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst, QualType Ty) { @@ -792,6 +807,13 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { Field->getType().getCVRQualifiers()|CVRQualifiers); } +LValue +CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) { + // This is a special l-value that just issues sends when we load or + // store through it. + return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers()); +} + RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType FnType, CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd) { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index cee8852cdca8..7334dd7e8180 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -144,7 +144,7 @@ public: return EmitLoadOfLValue(E); } Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { - return CGF.EmitObjCPropertyGet(E).getScalarVal(); + return EmitLoadOfLValue(E); } Value *VisitObjCMessageExpr(ObjCMessageExpr *E) { return CGF.EmitObjCMessageExpr(E).getScalarVal(); @@ -783,11 +783,12 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E, // Store the result value into the LHS lvalue. CGF.EmitStoreThroughLValue(RValue::get(Result), LHSLV, LHSTy); - // For bitfields, we need the value in the bitfield + // For bitfields, we need the value in the bitfield. Note that + // property references do not reload their value (even though the + // setter may have changed it). // FIXME: This adds an extra bitfield load if (LHSLV.isBitfield()) Result = EmitLoadOfLValue(LHSLV, LHSTy); - return Result; } @@ -1000,10 +1001,13 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { // FIXME: Volatility! CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS, E->getType()); - // For bitfields, we need the value in the bitfield + // For bitfields, we need the value in the bitfield. Note that + // property references do not reload their value (even though the + // setter may have changed it). // FIXME: This adds an extra bitfield load if (LHS.isBitfield()) return EmitLoadOfLValue(LHS, E->getLHS()->getType()); + // Return the RHS. return RHS; } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index cec75dea9b58..624b24aa75de 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -14,6 +14,7 @@ #include "CGObjCRuntime.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" using namespace clang; @@ -238,4 +239,9 @@ RValue CodeGenFunction::EmitObjCPropertyGet(const ObjCPropertyRefExpr *E) { return EmitObjCMessageExpr(&GetExpr); } +void CodeGenFunction::EmitObjCPropertySet(const ObjCPropertyRefExpr *E, + RValue Src) { + ErrorUnsupported(E, "Objective-C property setter call"); +} + CGObjCRuntime::~CGObjCRuntime() {} diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h index ba4ea0e6c8b5..bc9a15fe9f77 100644 --- a/clang/lib/CodeGen/CGValue.h +++ b/clang/lib/CodeGen/CGValue.h @@ -18,6 +18,8 @@ #include "clang/AST/Type.h" namespace clang { + class ObjCPropertyRefExpr; + namespace CodeGen { /// RValue - This trivial value class is used to represent the result of an @@ -95,7 +97,9 @@ class LValue { Simple, // This is a normal l-value, use getAddress(). 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 + ExtVectorElt, // This is an extended vector subset, use getExtVectorComp + PropertyRef // This is an Objective-C property reference, use + // getPropertyRefExpr } LVType; llvm::Value *V; @@ -113,6 +117,9 @@ class LValue { unsigned short Size; bool IsSigned; } BitfieldData; + + // Obj-C property reference expression + const ObjCPropertyRefExpr *PropertyRefExpr; }; bool Volatile:1; @@ -130,7 +137,8 @@ public: bool isVectorElt() const { return LVType == VectorElt; } bool isBitfield() const { return LVType == BitField; } bool isExtVectorElt() const { return LVType == ExtVectorElt; } - + bool isPropertyRef() const { return LVType == PropertyRef; } + bool isVolatileQualified() const { return Volatile; } bool isRestrictQualified() const { return Restrict; } @@ -159,6 +167,11 @@ public: assert(isBitfield()); return BitfieldData.IsSigned; } + // property ref lvalue + const ObjCPropertyRefExpr *getPropertyRefExpr() const { + assert(isPropertyRef()); + return PropertyRefExpr; + } static LValue MakeAddr(llvm::Value *V, unsigned Qualifiers) { LValue R; @@ -200,6 +213,15 @@ public: SetQualifiers(Qualifiers,R); return R; } + + static LValue MakePropertyRef(const ObjCPropertyRefExpr *E, + unsigned Qualifiers) { + LValue R; + R.LVType = PropertyRef; + R.PropertyRefExpr = E; + SetQualifiers(Qualifiers,R); + return R; + } }; } // end namespace CodeGen diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 0178f8a3e3e1..44d4cd251a10 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -265,6 +265,7 @@ public: RValue EmitLoadOfLValue(LValue V, QualType LVType); RValue EmitLoadOfExtVectorElementLValue(LValue V, QualType LVType); RValue EmitLoadOfBitfieldLValue(LValue LV, QualType ExprType); + RValue EmitLoadOfPropertyRefLValue(LValue LV, QualType ExprType); /// EmitStoreThroughLValue - Store the specified rvalue into the specified @@ -274,6 +275,7 @@ public: void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst, QualType Ty); void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty); + void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst, QualType Ty); // Note: only availabe for agg return types LValue EmitCallExprLValue(const CallExpr *E); @@ -292,6 +294,7 @@ public: LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E); LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E); + LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E); //===--------------------------------------------------------------------===// // Scalar Expression Emission @@ -327,6 +330,7 @@ public: llvm::Value *EmitObjCSelectorExpr(const ObjCSelectorExpr *E); RValue EmitObjCMessageExpr(const ObjCMessageExpr *E); RValue EmitObjCPropertyGet(const ObjCPropertyRefExpr *E); + void EmitObjCPropertySet(const ObjCPropertyRefExpr *E, RValue Src); //===--------------------------------------------------------------------===//