diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-05-20 02:31:19 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-05-20 02:31:19 +0000 |
commit | 5df0d426026b3820b5f0b13a8d4e60e9373d8d9d (patch) | |
tree | f4dd5b306631dea44438835da905f81cfec3bf4b | |
parent | a1f3dba77b7418575c1ff539ffa74ebaa068280c (diff) |
Handle the remaining unhandled cases in EmitReferenceBindingToExpr.
It would be nice if someone could write an ObjC++ testcase for the case
of passing a property returning a struct to a function taking a const
reference.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72159 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 33 | ||||
-rw-r--r-- | test/CodeGenCXX/references.cpp | 7 |
2 files changed, 25 insertions, 15 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0886ad040a..0b7ad05b30 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -72,28 +72,31 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E, llvm::Value *AggLoc, RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E, QualType DestType) { - if (E->isLvalue(getContext()) == Expr::LV_Valid && !E->getBitField()) { + RValue Val; + if (E->isLvalue(getContext()) == Expr::LV_Valid) { // Emit the expr as an lvalue. LValue LV = EmitLValue(E); - return RValue::get(LV.getAddress()); + if (LV.isSimple()) + return RValue::get(LV.getAddress()); + Val = EmitLoadOfLValue(LV, E->getType()); + } else { + Val = EmitAnyExprToTemp(E); } - - if (!hasAggregateLLVMType(E->getType())) { - // Create a temporary variable that we can bind the reference to. - llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(E->getType()), - "reftmp"); - EmitStoreOfScalar(EmitScalarExpr(E), Temp, false, E->getType()); - return RValue::get(Temp); - } else if (E->getType()->isAnyComplexType()) { + + if (Val.isAggregate()) { + Val = RValue::get(Val.getAggregateAddr()); + } else { // Create a temporary variable that we can bind the reference to. llvm::Value *Temp = CreateTempAlloca(ConvertTypeForMem(E->getType()), "reftmp"); - EmitComplexExprIntoAddr(E, Temp, false); - return RValue::get(Temp); + if (Val.isScalar()) + EmitStoreOfScalar(Val.getScalarVal(), Temp, false, E->getType()); + else + StoreComplexToAddr(Val.getComplexVal(), Temp, false); + Val = RValue::get(Temp); } - - CGM.ErrorUnsupported(E, "reference binding"); - return GetUndefRValue(DestType); + + return Val; } diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp index 9b9e0f8623..0124f695b3 100644 --- a/test/CodeGenCXX/references.cpp +++ b/test/CodeGenCXX/references.cpp @@ -24,6 +24,8 @@ void f(const int&); void f(const _Complex int&); void f(const C&); +C structfunc(); + void test_bool() { bool a = true; f(a); @@ -39,6 +41,9 @@ void test_scalar() { f(s.bitfield); f(10); + + __attribute((vector_size(16))) typedef int vec4; + f((vec4){1,2,3,4}[0]); } void test_complex() { @@ -51,5 +56,7 @@ void test_complex() { void test_aggregate() { C c; f(c); + + f(structfunc()); } |