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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55534 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Dunbar 2008-08-29 08:11:39 +00:00
Родитель d70900be3c
Коммит 85c59edda0
5 изменённых файлов: 67 добавлений и 9 удалений

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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() {}

Просмотреть файл

@ -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

Просмотреть файл

@ -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);
//===--------------------------------------------------------------------===//