diff options
author | Chris Lattner <sabre@nondot.org> | 2007-08-26 07:14:44 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-08-26 07:14:44 +0000 |
commit | 45067906adfdeb974c18a6194b8040dd83f8b5e8 (patch) | |
tree | 503d14085d5699a4f209e6adc84bdfbeb0d898ff /clang/CodeGen/CGStmt.cpp | |
parent | 44d3e74e2238942a188938634550b598c4742f96 (diff) | |
download | bcm5719-llvm-45067906adfdeb974c18a6194b8040dd83f8b5e8.tar.gz bcm5719-llvm-45067906adfdeb974c18a6194b8040dd83f8b5e8.zip |
Fix return of aggregate and return of complex.
llvm-svn: 41437
Diffstat (limited to 'clang/CodeGen/CGStmt.cpp')
-rw-r--r-- | clang/CodeGen/CGStmt.cpp | 27 |
1 files changed, 10 insertions, 17 deletions
diff --git a/clang/CodeGen/CGStmt.cpp b/clang/CodeGen/CGStmt.cpp index de50d71d9eb..014f0aa85b3 100644 --- a/clang/CodeGen/CGStmt.cpp +++ b/clang/CodeGen/CGStmt.cpp @@ -270,37 +270,30 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) { /// if the function returns void, or may be missing one if the function returns /// non-void. Fun stuff :). void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { - RValue RetVal; - // Emit the result value, even if unused, to evalute the side effects. const Expr *RV = S.getRetValue(); - // FIXME: Handle return of an aggregate! - if (RV) - // FIXME: This could be much better for return of aggregate: return inplace. - RetVal = EmitAnyExpr(RV); - else // Silence a bogus GCC warning. - RetVal = RValue::get(0); - + QualType FnRetTy = CurFuncDecl->getType().getCanonicalType(); FnRetTy = cast<FunctionType>(FnRetTy)->getResultType(); if (FnRetTy->isVoidType()) { - // If the function returns void, emit ret void, and ignore the retval. + // If the function returns void, emit ret void. Builder.CreateRetVoid(); } else if (RV == 0) { - // "return;" in a function that returns a value. + // Handle "return;" in a function that returns a value. const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType(); if (RetTy == llvm::Type::VoidTy) Builder.CreateRetVoid(); // struct return etc. else Builder.CreateRet(llvm::UndefValue::get(RetTy)); + } else if (!hasAggregateLLVMType(RV->getType())) { + Builder.CreateRet(EmitScalarExpr(RV)); + } else if (RV->getType()->isComplexType()) { + llvm::Value *SRetPtr = CurFn->arg_begin(); + EmitComplexExprIntoAddr(RV, SRetPtr); } else { - if (RetVal.isScalar()) { - Builder.CreateRet(RetVal.getVal()); - } else { - llvm::Value *SRetPtr = CurFn->arg_begin(); - EmitStoreThroughLValue(RetVal, LValue::MakeAddr(SRetPtr), FnRetTy); - } + llvm::Value *SRetPtr = CurFn->arg_begin(); + EmitAggExpr(RV, SRetPtr, false); } // Emit a block after the branch so that dead code after a return has some |