зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
d70900be3c
Коммит
85c59edda0
|
@ -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);
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
Загрузка…
Ссылка в новой задаче