diff options
author | Anders Carlsson <andersca@mac.com> | 2010-01-31 18:34:51 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-01-31 18:34:51 +0000 |
commit | 3aba09376c5f49c4c8d176109ea4835bc2c528ee (patch) | |
tree | 9327456a19ee39fa56e2de8df8f77f2313b6f8b7 | |
parent | 093802675b1548f2a5f44c29938d65cce00d58bb (diff) |
Start creating CXXBindReferenceExpr nodes when binding complex types to references.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94964 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 22 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 22 |
5 files changed, 50 insertions, 3 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index d3a41d62a7..e1fe0d29a2 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -802,6 +802,9 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, } RValue CodeGenFunction::EmitCallArg(const Expr *E, QualType ArgType) { + if (const CXXBindReferenceExpr *BE = dyn_cast<CXXBindReferenceExpr>(E)) + return RValue::get(EmitCXXBindReferenceExpr(BE)); + if (ArgType->isReferenceType()) return EmitReferenceBindingToExpr(E, ArgType); diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 51e194da34..6ba537e528 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -507,6 +507,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { Builder.CreateCall4(CGM.getMemCpyFn(), Loc, SrcPtr, SizeVal, AlignVal); } + } else if (const CXXBindReferenceExpr *BE = + dyn_cast<CXXBindReferenceExpr>(Init)) { + llvm::Value *V = EmitCXXBindReferenceExpr(BE); + EmitStoreOfScalar(V, Loc, /*Volatile=*/false, Ty); } else if (Ty->isReferenceType()) { RValue RV = EmitReferenceBindingToExpr(Init, Ty, /*IsInitializer=*/true); EmitStoreOfScalar(RV.getScalarVal(), Loc, false, Ty); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 605f77975f..c0dd68bc70 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -92,9 +92,31 @@ RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E, IsInitializer); } +llvm::Value * +CodeGenFunction::EmitCXXBindReferenceExpr(const CXXBindReferenceExpr *E) { + QualType T = E->getType(); + assert(T->isAnyComplexType() && "FIXME: Unhandled bind expression!"); + + const Expr *SubExpr = E->getSubExpr(); + + if (!E->requiresTemporaryCopy()) + return EmitLValue(SubExpr).getAddress(); + + llvm::Value *Value = CreateTempAlloca(ConvertTypeForMem(T), "reftmp"); + + if (T->isAnyComplexType()) + EmitComplexExprIntoAddr(SubExpr, Value, /*DestIsVolatile=*/false); + else + assert(false && "Unhandled bind expression"); + + return Value; +} + RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E, QualType DestType, bool IsInitializer) { + assert(!E->getType()->isAnyComplexType() && + "Should not use this function for complex types!"); bool ShouldDestroyTemporaries = false; unsigned OldNumLiveTemporaries = 0; diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 7a8da0c95b..69b2fa222c 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1116,6 +1116,8 @@ public: RValue EmitReferenceBindingToExpr(const Expr* E, QualType DestType, bool IsInitializer = false); + llvm::Value *EmitCXXBindReferenceExpr(const CXXBindReferenceExpr *E); + //===--------------------------------------------------------------------===// // Expression Emission //===--------------------------------------------------------------------===// diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a9adb70050..db888a62a4 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3297,15 +3297,31 @@ InitializationSequence::Perform(Sema &S, // Check exception specifications if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType)) return S.ExprError(); + + // FIXME: We should do this for all types. + if (DestType->isAnyComplexType()) { + CurInit = + S.Owned(CXXBindReferenceExpr::Create(S.Context, + CurInit.takeAs<Expr>(), + /*ExtendsLifetime=*/false, + /*RequiresTemporaryCopy=*/false)); + } + break; - + case SK_BindReferenceToTemporary: // Check exception specifications if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType)) return S.ExprError(); - // FIXME: At present, we have no AST to describe when we need to make a - // temporary to bind a reference to. We should. + // FIXME: We should do this for all types. + if (DestType->isAnyComplexType()) { + CurInit = + S.Owned(CXXBindReferenceExpr::Create(S.Context, + CurInit.takeAs<Expr>(), + /*ExtendsLifetime=*/false, + /*RequiresTemporaryCopy=*/true)); + } break; case SK_UserConversion: { |