]> granicus.if.org Git - clang/commitdiff
Add special "property reference" CodeGen::LValue type for emitting
authorDaniel Dunbar <daniel@zuster.org>
Fri, 29 Aug 2008 08:11:39 +0000 (08:11 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 29 Aug 2008 08:11:39 +0000 (08:11 +0000)
Objective-C property references.
 - This handles property references "more correctly" but setters still
   don't work.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55534 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CGValue.h
lib/CodeGen/CodeGenFunction.h

index 0b4bf23a49741cab981980d15f432d5f32206a34..d3872c12dd0c4fc84c6d70a1354e1ea52f0677fc 100644 (file)
@@ -112,9 +112,7 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
   case Expr::ObjCIvarRefExprClass: 
     return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
   case Expr::ObjCPropertyRefExprClass:
-    // FIXME: Implement!
-    return EmitUnsupportedLValue(E, 
-                                 "l-value expression (Objective-C property)");
+    return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
     
   case Expr::UnaryOperatorClass: 
     return EmitUnaryOpLValue(cast<UnaryOperator>(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) {
index cee8852cdca8c6348cac490465c3b09c1a933f30..7334dd7e818065d75d0708c7801c6ebf563e478c 100644 (file)
@@ -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;
 }
index cec75dea9b58aa88af1a98c80b470e25b797a7d7..624b24aa75debd1798a5092510b760f753ae5fcc 100644 (file)
@@ -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() {}
index ba4ea0e6c8b53597e49266d8944f256f6e47b417..bc9a15fe9f77453c8e0201d4c8c713753012d370 100644 (file)
@@ -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
index 0178f8a3e3e14168913f68a1e2eb059ecd082a79..44d4cd251a10e05c9f857ee09e558dd0de4f74a2 100644 (file)
@@ -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);
 
 
   //===--------------------------------------------------------------------===//