diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 31 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 11 |
4 files changed, 36 insertions, 18 deletions
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 36f974a3132..643ef91c891 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -358,7 +358,9 @@ ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { CodeGenFunction::StmtExprEvaluation eval(CGF); - return CGF.EmitCompoundStmt(*E->getSubStmt(), true).getComplexVal(); + llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true); + assert(RetAlloca && "Expected complex return value"); + return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType())); } /// EmitComplexToComplexCast - Emit a cast from complex value Val to DestType. diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index c1c252d12b7..7fb8e87cbd3 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1442,8 +1442,12 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { Value *ScalarExprEmitter::VisitStmtExpr(const StmtExpr *E) { CodeGenFunction::StmtExprEvaluation eval(CGF); - return CGF.EmitCompoundStmt(*E->getSubStmt(), !E->getType()->isVoidType()) - .getScalarVal(); + llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), + !E->getType()->isVoidType()); + if (!RetAlloca) + return 0; + return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType())); + } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 0db31ac49c1..f104acb1990 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -196,8 +196,8 @@ bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) { /// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true, /// this captures the expression result of the last sub-statement and returns it /// (for use by the statement expression extension). -RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, - AggValueSlot AggSlot) { +llvm::Value* CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, + AggValueSlot AggSlot) { PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(), "LLVM IR generation of compound statement ('{}')"); @@ -207,17 +207,17 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, return EmitCompoundStmtWithoutScope(S, GetLast, AggSlot); } -RValue CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast, - AggValueSlot AggSlot) { +llvm::Value* +CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, + bool GetLast, + AggValueSlot AggSlot) { for (CompoundStmt::const_body_iterator I = S.body_begin(), E = S.body_end()-GetLast; I != E; ++I) EmitStmt(*I); - RValue RV; - if (!GetLast) - RV = RValue::get(0); - else { + llvm::Value *RetAlloca = 0; + if (GetLast) { // We have to special case labels here. They are statements, but when put // at the end of a statement expression, they yield the value of their // subexpression. Handle this by walking through all labels we encounter, @@ -230,10 +230,21 @@ RValue CodeGenFunction::EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool EnsureInsertPoint(); - RV = EmitAnyExpr(cast<Expr>(LastStmt), AggSlot); + QualType ExprTy = cast<Expr>(LastStmt)->getType(); + if (hasAggregateEvaluationKind(ExprTy)) { + EmitAggExpr(cast<Expr>(LastStmt), AggSlot); + } else { + // We can't return an RValue here because there might be cleanups at + // the end of the StmtExpr. Because of that, we have to emit the result + // here into a temporary alloca. + RetAlloca = CreateMemTemp(ExprTy); + EmitAnyExprToMem(cast<Expr>(LastStmt), RetAlloca, Qualifiers(), + /*IsInit*/false); + } + } - return RV; + return RetAlloca; } void CodeGenFunction::SimplifyForwardingBlocks(llvm::BasicBlock *BB) { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 41228fa8083..81b5d05cf65 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1767,11 +1767,12 @@ public: /// \return True if the statement was handled. bool EmitSimpleStmt(const Stmt *S); - RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, - AggValueSlot AVS = AggValueSlot::ignored()); - RValue EmitCompoundStmtWithoutScope(const CompoundStmt &S, - bool GetLast = false, AggValueSlot AVS = - AggValueSlot::ignored()); + llvm::Value *EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false, + AggValueSlot AVS = AggValueSlot::ignored()); + llvm::Value *EmitCompoundStmtWithoutScope(const CompoundStmt &S, + bool GetLast = false, + AggValueSlot AVS = + AggValueSlot::ignored()); /// EmitLabel - Emit the block for the given label. It is legal to call this /// function even if there is no current insertion point. |