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 | c21cb44de28cde3eae6797e6ba0d35016d6d92fe (patch) | |
| tree | f7afaea3bb47f4ad4d3b7ef4a1938077a476f4da | |
| parent | 050379b8650cbbc69388b738fa768e6576ebfc13 (diff) | |
| download | bcm5719-llvm-c21cb44de28cde3eae6797e6ba0d35016d6d92fe.tar.gz bcm5719-llvm-c21cb44de28cde3eae6797e6ba0d35016d6d92fe.zip | |
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.
llvm-svn: 72159
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 33 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/references.cpp | 7 |
2 files changed, 25 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 0886ad040a4..0b7ad05b305 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/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/clang/test/CodeGenCXX/references.cpp b/clang/test/CodeGenCXX/references.cpp index 9b9e0f8623b..0124f695b3b 100644 --- a/clang/test/CodeGenCXX/references.cpp +++ b/clang/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()); } |

