Rip the ObjCPropertyRef l-value kind out of IR-generation.

llvm-svn: 143908
This commit is contained in:
John McCall 2011-11-07 03:59:57 +00:00
parent 8c045bcf9d
commit c109a259d2
7 changed files with 23 additions and 258 deletions

View File

@ -239,19 +239,10 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
InitializedDecl);
}
if (const ObjCPropertyRefExpr *PRE =
dyn_cast<ObjCPropertyRefExpr>(E->IgnoreParenImpCasts()))
if (PRE->getGetterResultType()->isReferenceType())
E = PRE;
RValue RV;
if (E->isGLValue()) {
// Emit the expression as an lvalue.
LValue LV = CGF.EmitLValue(E);
if (LV.isPropertyRef()) {
RV = CGF.EmitLoadOfPropertyRefLValue(LV);
return RV.getScalarVal();
}
if (LV.isSimple())
return LV.getAddress();
@ -644,6 +635,9 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
switch (E->getStmtClass()) {
default: return EmitUnsupportedLValue(E, "l-value expression");
case Expr::ObjCPropertyRefExprClass:
llvm_unreachable("cannot emit a property reference directly");
case Expr::ObjCSelectorExprClass:
return EmitObjCSelectorLValue(cast<ObjCSelectorExpr>(E));
case Expr::ObjCIsaExprClass:
@ -696,8 +690,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
return EmitObjCMessageExprLValue(cast<ObjCMessageExpr>(E));
case Expr::ObjCIvarRefExprClass:
return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
case Expr::ObjCPropertyRefExprClass:
return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
case Expr::StmtExprClass:
return EmitStmtExprLValue(cast<StmtExpr>(E));
case Expr::UnaryOperatorClass:
@ -835,11 +827,8 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV) {
if (LV.isExtVectorElt())
return EmitLoadOfExtVectorElementLValue(LV);
if (LV.isBitField())
return EmitLoadOfBitfieldLValue(LV);
assert(LV.isPropertyRef() && "Unknown LValue type!");
return EmitLoadOfPropertyRefLValue(LV);
assert(LV.isBitField() && "Unknown LValue type!");
return EmitLoadOfBitfieldLValue(LV);
}
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {
@ -968,11 +957,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst) {
if (Dst.isExtVectorElt())
return EmitStoreThroughExtVectorComponentLValue(Src, Dst);
if (Dst.isBitField())
return EmitStoreThroughBitfieldLValue(Src, Dst);
assert(Dst.isPropertyRef() && "Unknown LValue type");
return EmitStoreThroughPropertyRefLValue(Src, Dst);
assert(Dst.isBitField() && "Unknown LValue type");
return EmitStoreThroughBitfieldLValue(Src, Dst);
}
// There's special magic for assigning into an ARC-qualified l-value.
@ -2024,20 +2010,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
case CK_Dependent:
llvm_unreachable("dependent cast kind in IR gen!");
case CK_GetObjCProperty: {
LValue LV = EmitLValue(E->getSubExpr());
assert(LV.isPropertyRef());
RValue RV = EmitLoadOfPropertyRefLValue(LV);
// Property is an aggregate r-value.
if (RV.isAggregate()) {
return MakeAddrLValue(RV.getAggregateAddr(), E->getType());
}
// Implicit property returns an l-value.
assert(RV.isScalar());
return MakeAddrLValue(RV.getScalarVal(), E->getSubExpr()->getType());
}
case CK_GetObjCProperty: llvm_unreachable("GetObjCProperty");
case CK_NoOp:
case CK_LValueToRValue:

View File

@ -131,7 +131,6 @@ public:
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
EmitAggLoadOfLValue(E);
}
void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
void VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
void VisitChooseExpr(const ChooseExpr *CE);
@ -334,14 +333,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
"should have been unpacked before we got here");
}
case CK_GetObjCProperty: {
LValue LV =
CGF.EmitObjCPropertyRefLValue(E->getSubExpr()->getObjCProperty());
assert(LV.isPropertyRef());
RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV, getReturnValueSlot());
EmitMoveFromReturnSlot(E, RV);
break;
}
case CK_GetObjCProperty: llvm_unreachable("GetObjCProperty!");
case CK_LValueToRValue: // hope for downstream optimization
case CK_NoOp:
@ -414,11 +406,6 @@ void AggExprEmitter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
EmitMoveFromReturnSlot(E, RV);
}
void AggExprEmitter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
llvm_unreachable("direct property access not surrounded by "
"lvalue-to-rvalue cast");
}
void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
CGF.EmitIgnoredExpr(E->getLHS());
Visit(E->getRHS());
@ -466,29 +453,13 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
LValue LHS = CGF.EmitLValue(E->getLHS());
// We have to special case property setters, otherwise we must have
// a simple lvalue (no aggregates inside vectors, bitfields).
if (LHS.isPropertyRef()) {
const ObjCPropertyRefExpr *RE = LHS.getPropertyRefExpr();
QualType ArgType = RE->getSetterArgType();
RValue Src;
if (ArgType->isReferenceType())
Src = CGF.EmitReferenceBindingToExpr(E->getRHS(), 0);
else {
AggValueSlot Slot = EnsureSlot(E->getRHS()->getType());
CGF.EmitAggExpr(E->getRHS(), Slot);
Src = Slot.asRValue();
}
CGF.EmitStoreThroughPropertyRefLValue(Src, LHS);
} else {
// Codegen the RHS so that it stores directly into the LHS.
AggValueSlot LHSSlot =
AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
needsGC(E->getLHS()->getType()),
AggValueSlot::IsAliased);
CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
EmitFinalDestCopy(E, LHS, true);
}
// Codegen the RHS so that it stores directly into the LHS.
AggValueSlot LHSSlot =
AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
needsGC(E->getLHS()->getType()),
AggValueSlot::IsAliased);
CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
EmitFinalDestCopy(E, LHS, true);
}
void AggExprEmitter::

View File

@ -64,11 +64,8 @@ public:
}
ComplexPairTy EmitLoadOfLValue(LValue LV) {
if (LV.isSimple())
return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
assert(LV.isPropertyRef() && "Unknown LValue type!");
return CGF.EmitLoadOfPropertyRefLValue(LV).getComplexVal();
assert(LV.isSimple() && "complex l-value must be simple");
return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
}
/// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
@ -78,11 +75,8 @@ public:
/// EmitStoreThroughLValue - Given an l-value of complex type, store
/// a complex number into it.
void EmitStoreThroughLValue(ComplexPairTy Val, LValue LV) {
if (LV.isSimple())
return EmitStoreOfComplex(Val, LV.getAddress(), LV.isVolatileQualified());
assert(LV.isPropertyRef() && "Unknown LValue type!");
CGF.EmitStoreThroughPropertyRefLValue(RValue::getComplex(Val), LV);
assert(LV.isSimple() && "complex l-value must be simple");
return EmitStoreOfComplex(Val, LV.getAddress(), LV.isVolatileQualified());
}
/// EmitStoreOfComplex - Store the specified real/imag parts into the
@ -122,10 +116,6 @@ public:
ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
return EmitLoadOfLValue(E);
}
ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
assert(E->getObjectKind() == OK_Ordinary);
return EmitLoadOfLValue(E);
}
ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
return CGF.EmitObjCMessageExpr(E).getComplexVal();
}
@ -365,12 +355,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
QualType DestTy) {
switch (CK) {
case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
case CK_GetObjCProperty: {
LValue LV = CGF.EmitObjCPropertyRefLValue(Op->getObjCProperty());
assert(LV.isPropertyRef() && "Unknown LValue type!");
return CGF.EmitLoadOfPropertyRefLValue(LV).getComplexVal();
}
case CK_GetObjCProperty: llvm_unreachable("GetObjCProperty!");
case CK_NoOp:
case CK_LValueToRValue:
@ -638,10 +623,6 @@ EmitCompoundAssign(const CompoundAssignOperator *E,
if (!CGF.getContext().getLangOptions().CPlusPlus)
return Val;
// Objective-C property assignment never reloads the value following a store.
if (LV.isPropertyRef())
return Val;
// If the lvalue is non-volatile, return the computed value of the assignment.
if (!LV.isVolatileQualified())
return Val;
@ -677,10 +658,6 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
if (!CGF.getContext().getLangOptions().CPlusPlus)
return Val;
// Objective-C property assignment never reloads the value following a store.
if (LV.isPropertyRef())
return Val;
// If the lvalue is non-volatile, return the computed value of the assignment.
if (!LV.isVolatileQualified())
return Val;

View File

@ -244,11 +244,6 @@ public:
Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
return EmitLoadOfLValue(E);
}
Value *VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
assert(E->getObjectKind() == OK_Ordinary &&
"reached property reference without lvalue-to-rvalue");
return EmitLoadOfLValue(E);
}
Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
if (E->getMethodDecl() &&
E->getMethodDecl()->getResultType()->isReferenceType())
@ -1051,6 +1046,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
// are in the same order as in the CastKind enum.
switch (Kind) {
case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
case CK_GetObjCProperty: llvm_unreachable("GetObjCProperty!");
case CK_LValueBitCast:
case CK_ObjCObjectLValueCast: {
@ -1170,14 +1166,6 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
llvm_unreachable("scalar cast to non-scalar value");
break;
case CK_GetObjCProperty: {
assert(E->isGLValue() && E->getObjectKind() == OK_ObjCProperty &&
"CK_GetObjCProperty for non-lvalue or non-ObjCProperty");
LValue LV = CGF.EmitObjCPropertyRefLValue(E->getObjCProperty());
RValue RV = CGF.EmitLoadOfPropertyRefLValue(LV);
return RV.getScalarVal();
}
case CK_LValueToRValue:
assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));
assert(E->isGLValue() && "lvalue-to-rvalue applied to r-value!");
@ -1716,10 +1704,6 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
if (!CGF.getContext().getLangOptions().CPlusPlus)
return RHS;
// Objective-C property assignment never reloads the value following a store.
if (LHS.isPropertyRef())
return RHS;
// If the lvalue is non-volatile, return the computed value of the assignment.
if (!LHS.isVolatileQualified())
return RHS;
@ -2342,10 +2326,6 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) {
if (!CGF.getContext().getLangOptions().CPlusPlus)
return RHS;
// Objective-C property assignment never reloads the value following a store.
if (LHS.isPropertyRef())
return RHS;
// If the lvalue is non-volatile, return the computed value of the assignment.
if (!LHS.isVolatileQualified())
return RHS;

View File

@ -1087,22 +1087,6 @@ QualType CodeGenFunction::TypeOfSelfObject() {
return PTy->getPointeeType();
}
LValue
CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
// This is a special l-value that just issues sends when we load or
// store through it.
// For certain base kinds, we need to emit the base immediately.
llvm::Value *Base;
if (E->isSuperReceiver())
Base = LoadObjCSelf();
else if (E->isClassReceiver())
Base = CGM.getObjCRuntime().GetClass(Builder, E->getClassReceiver());
else
Base = EmitScalarExpr(E->getBase());
return LValue::MakePropertyRef(E, Base);
}
static RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
ReturnValueSlot Return,
QualType ResultType,
@ -1119,85 +1103,6 @@ static RValue GenerateMessageSendSuper(CodeGenFunction &CGF,
isClassMessage, CallArgs);
}
RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
ReturnValueSlot Return) {
const ObjCPropertyRefExpr *E = LV.getPropertyRefExpr();
QualType ResultType = E->getGetterResultType();
Selector S;
const ObjCMethodDecl *method;
if (E->isExplicitProperty()) {
const ObjCPropertyDecl *Property = E->getExplicitProperty();
S = Property->getGetterName();
method = Property->getGetterMethodDecl();
} else {
method = E->getImplicitPropertyGetter();
S = method->getSelector();
}
llvm::Value *Receiver = LV.getPropertyRefBaseAddr();
if (CGM.getLangOptions().ObjCAutoRefCount) {
QualType receiverType;
if (E->isSuperReceiver())
receiverType = E->getSuperReceiverType();
else if (E->isClassReceiver())
receiverType = getContext().getObjCClassType();
else
receiverType = E->getBase()->getType();
}
// Accesses to 'super' follow a different code path.
if (E->isSuperReceiver())
return AdjustRelatedResultType(*this, E, method,
GenerateMessageSendSuper(*this, Return,
ResultType,
S, Receiver,
CallArgList()));
const ObjCInterfaceDecl *ReceiverClass
= (E->isClassReceiver() ? E->getClassReceiver() : 0);
return AdjustRelatedResultType(*this, E, method,
CGM.getObjCRuntime().
GenerateMessageSend(*this, Return, ResultType, S,
Receiver, CallArgList(), ReceiverClass));
}
void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
LValue Dst) {
const ObjCPropertyRefExpr *E = Dst.getPropertyRefExpr();
Selector S = E->getSetterSelector();
QualType ArgType = E->getSetterArgType();
// FIXME. Other than scalars, AST is not adequate for setter and
// getter type mismatches which require conversion.
if (Src.isScalar()) {
llvm::Value *SrcVal = Src.getScalarVal();
QualType DstType = getContext().getCanonicalType(ArgType);
llvm::Type *DstTy = ConvertType(DstType);
if (SrcVal->getType() != DstTy)
Src =
RValue::get(EmitScalarConversion(SrcVal, E->getType(), DstType));
}
CallArgList Args;
Args.add(Src, ArgType);
llvm::Value *Receiver = Dst.getPropertyRefBaseAddr();
QualType ResultType = getContext().VoidTy;
if (E->isSuperReceiver()) {
GenerateMessageSendSuper(*this, ReturnValueSlot(),
ResultType, S, Receiver, Args);
return;
}
const ObjCInterfaceDecl *ReceiverClass
= (E->isClassReceiver() ? E->getClassReceiver() : 0);
CGM.getObjCRuntime().GenerateMessageSend(*this, ReturnValueSlot(),
ResultType, S, Receiver, Args,
ReceiverClass);
}
void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){
llvm::Constant *EnumerationMutationFn =
CGM.getObjCRuntime().EnumerationMutationFunction();
@ -2382,12 +2287,6 @@ tryEmitARCRetainScalarExpr(CodeGenFunction &CGF, const Expr *e) {
return TryEmitResult(result, true);
}
case CK_GetObjCProperty: {
llvm::Value *result = emitARCRetainCall(CGF, ce);
if (resultType) result = CGF.Builder.CreateBitCast(result, resultType);
return TryEmitResult(result, true);
}
default:
break;
}

View File

@ -24,8 +24,6 @@ namespace llvm {
}
namespace clang {
class ObjCPropertyRefExpr;
namespace CodeGen {
class AggValueSlot;
class CGBitFieldInfo;
@ -106,9 +104,7 @@ 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
PropertyRef // This is an Objective-C property reference, use
// getPropertyRefExpr
ExtVectorElt // This is an extended vector subset, use getExtVectorComp
} LVType;
llvm::Value *V;
@ -122,9 +118,6 @@ class LValue {
// BitField start bit and size
const CGBitFieldInfo *BitFieldInfo;
// Obj-C property reference expression
const ObjCPropertyRefExpr *PropertyRefExpr;
};
QualType Type;
@ -176,7 +169,6 @@ 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 Quals.hasVolatile(); }
bool isRestrictQualified() const { return Quals.hasRestrict(); }
@ -257,16 +249,6 @@ public:
return *BitFieldInfo;
}
// property ref lvalue
llvm::Value *getPropertyRefBaseAddr() const {
assert(isPropertyRef());
return V;
}
const ObjCPropertyRefExpr *getPropertyRefExpr() const {
assert(isPropertyRef());
return PropertyRefExpr;
}
static LValue MakeAddr(llvm::Value *address, QualType type,
unsigned alignment, ASTContext &Context,
llvm::MDNode *TBAAInfo = 0) {
@ -316,19 +298,6 @@ public:
R.Initialize(type, type.getQualifiers());
return R;
}
// FIXME: It is probably bad that we aren't emitting the target when we build
// the lvalue. However, this complicates the code a bit, and I haven't figured
// out how to make it go wrong yet.
static LValue MakePropertyRef(const ObjCPropertyRefExpr *E,
llvm::Value *Base) {
LValue R;
R.LVType = PropertyRef;
R.V = Base;
R.PropertyRefExpr = E;
R.Initialize(QualType(), Qualifiers());
return R;
}
};
/// An aggregate value slot.

View File

@ -1994,15 +1994,12 @@ public:
RValue EmitLoadOfLValue(LValue V);
RValue EmitLoadOfExtVectorElementLValue(LValue V);
RValue EmitLoadOfBitfieldLValue(LValue LV);
RValue EmitLoadOfPropertyRefLValue(LValue LV,
ReturnValueSlot Return = ReturnValueSlot());
/// EmitStoreThroughLValue - Store the specified rvalue into the specified
/// lvalue, where both are guaranteed to the have the same type, and that type
/// is 'Ty'.
void EmitStoreThroughLValue(RValue Src, LValue Dst);
void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst);
/// EmitStoreThroughLValue - Store Src into Dst with same constraints as
/// EmitStoreThroughLValue.
@ -2075,7 +2072,6 @@ public:
LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E);
LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E);
LValue EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E);
LValue EmitStmtExprLValue(const StmtExpr *E);
LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E);