From 80e62c29fe21cd06c93eba6e72b7e32dca06fcf9 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 4 Sep 2008 03:20:13 +0000 Subject: [PATCH] Implement codegen of aggregates as lvalues in binary expressions, e.g. "(a = b).somefield". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55758 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExpr.cpp | 16 +++++++++++++++- lib/CodeGen/CodeGenFunction.h | 2 ++ test/CodeGen/struct.c | 25 ++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index e1893493b0..cc5e705c39 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -99,6 +99,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { switch (E->getStmtClass()) { default: return EmitUnsupportedLValue(E, "l-value expression"); + case Expr::BinaryOperatorClass: + return EmitBinaryOperatorLValue(cast(E)); case Expr::CallExprClass: return EmitCallExprLValue(cast(E)); case Expr::DeclRefExprClass: return EmitDeclRefLValue(cast(E)); case Expr::ParenExprClass:return EmitLValue(cast(E)->getSubExpr()); @@ -738,7 +740,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) { dyn_cast(DRExpr->getDecl())) if (unsigned builtinID = FDecl->getIdentifier()->getBuiltinID()) return EmitBuiltinExpr(builtinID, E); - + llvm::Value *Callee = EmitScalarExpr(E->getCallee()); return EmitCallExpr(Callee, E->getCallee()->getType(), E->arg_begin(), E->arg_end()); @@ -752,6 +754,18 @@ RValue CodeGenFunction::EmitCallExpr(Expr *FnExpr, return EmitCallExpr(Callee, FnExpr->getType(), ArgBeg, ArgEnd); } +LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) { + // Can only get l-value for binary operator expressions which are a + // simple assignment of aggregate type. + if (E->getOpcode() != BinaryOperator::Assign) + return EmitUnsupportedLValue(E, "binary l-value expression"); + + llvm::Value *Temp = CreateTempAlloca(ConvertType(E->getType())); + EmitAggExpr(E, Temp, false); + // FIXME: Are these qualifiers correct? + return LValue::MakeAddr(Temp, E->getType().getCVRQualifiers()); +} + LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) { // Can only get l-value for call expression returning aggregate type RValue RV = EmitCallExpr(E); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index e43b2d3961..853f445384 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -281,6 +281,8 @@ public: void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, QualType Ty); void EmitStoreThroughPropertyRefLValue(RValue Src, LValue Dst, QualType Ty); + // Note: only availabe for agg return types + LValue EmitBinaryOperatorLValue(const BinaryOperator *E); // Note: only availabe for agg return types LValue EmitCallExprLValue(const CallExpr *E); diff --git a/test/CodeGen/struct.c b/test/CodeGen/struct.c index 9af684b114..76d9b77274 100644 --- a/test/CodeGen/struct.c +++ b/test/CodeGen/struct.c @@ -69,7 +69,6 @@ typedef struct { int location; int length; } range; - extern range f6(); void f7() { @@ -166,3 +165,27 @@ struct __attribute__((packed)) S2839 { double a[19]; signed char b; } s2839[5]; struct __attribute__((packed)) SS { long double a; char b; } SS; + +/* As lvalue */ + +int f15() { + extern range f15_ext(); + return f15_ext().location; +} + +range f16() { + extern rangepair f16_ext(); + return f16_ext().range1; +} + +int f17() { + extern range f17_ext(); + range r; + return (r = f17_ext()).location; +} + +range f18() { + extern rangepair f18_ext(); + rangepair rp; + return (rp = f18_ext()).range1; +} -- 2.40.0