Reinstate the scalar-cast-to-const-reference improvements, this time
with the proper spelling of "non-class prvalue". Silly me, I think
class rvalues were xvalues rather than prvalues!
Hah hah hah.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108443 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 43bab9f..fa5ac8f 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1749,8 +1749,48 @@
/// cast from scalar to union.
LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
switch (E->getCastKind()) {
- default:
+ case CastExpr::CK_ToVoid:
return EmitUnsupportedLValue(E, "unexpected cast lvalue");
+
+ case CastExpr::CK_NoOp:
+ if (E->getSubExpr()->Classify(getContext()).getKind()
+ != Expr::Classification::CL_PRValue) {
+ LValue LV = EmitLValue(E->getSubExpr());
+ if (LV.isPropertyRef()) {
+ QualType QT = E->getSubExpr()->getType();
+ RValue RV = EmitLoadOfPropertyRefLValue(LV, QT);
+ assert(!RV.isScalar() && "EmitCastLValue-scalar cast of property ref");
+ llvm::Value *V = RV.getAggregateAddr();
+ return LValue::MakeAddr(V, MakeQualifiers(QT));
+ }
+ return LV;
+ }
+ // Fall through to synthesize a temporary.
+
+ case CastExpr::CK_Unknown:
+ case CastExpr::CK_BitCast:
+ case CastExpr::CK_ArrayToPointerDecay:
+ case CastExpr::CK_FunctionToPointerDecay:
+ case CastExpr::CK_NullToMemberPointer:
+ case CastExpr::CK_IntegralToPointer:
+ case CastExpr::CK_PointerToIntegral:
+ case CastExpr::CK_VectorSplat:
+ case CastExpr::CK_IntegralCast:
+ case CastExpr::CK_IntegralToFloating:
+ case CastExpr::CK_FloatingToIntegral:
+ case CastExpr::CK_FloatingCast:
+ case CastExpr::CK_DerivedToBaseMemberPointer:
+ case CastExpr::CK_BaseToDerivedMemberPointer:
+ case CastExpr::CK_MemberPointerToBoolean:
+ case CastExpr::CK_AnyPointerToBlockPointerCast: {
+ // These casts only produce lvalues when we're binding a reference to a
+ // temporary realized from a (converted) pure rvalue. Emit the expression
+ // as a value, copy it into a temporary, and return an lvalue referring to
+ // that temporary.
+ llvm::Value *V = CreateMemTemp(E->getType(), "ref.temp");
+ EmitAnyExprToMem(E, V, false, false);
+ return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
+ }
case CastExpr::CK_Dynamic: {
LValue LV = EmitLValue(E->getSubExpr());
@@ -1760,17 +1800,6 @@
MakeQualifiers(E->getType()));
}
- case CastExpr::CK_NoOp: {
- LValue LV = EmitLValue(E->getSubExpr());
- if (LV.isPropertyRef()) {
- QualType QT = E->getSubExpr()->getType();
- RValue RV = EmitLoadOfPropertyRefLValue(LV, QT);
- assert(!RV.isScalar() && "EmitCastLValue - scalar cast of property ref");
- llvm::Value *V = RV.getAggregateAddr();
- return LValue::MakeAddr(V, MakeQualifiers(QT));
- }
- return LV;
- }
case CastExpr::CK_ConstructorConversion:
case CastExpr::CK_UserDefinedConversion:
case CastExpr::CK_AnyPointerToObjCPointerCast:
@@ -1826,6 +1855,8 @@
return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
}
}
+
+ llvm_unreachable("Unhandled lvalue cast kind?");
}
LValue CodeGenFunction::EmitNullInitializationLValue(