diff options
author | Chris Lattner <sabre@nondot.org> | 2007-06-02 03:19:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-06-02 03:19:07 +0000 |
commit | 3f3dbeedd391f10a410aa8fff5a9c95055ce214c (patch) | |
tree | 6987d1ac5f29af14a836b2faa2e7554c445b87d0 /clang/CodeGen/CGStmt.cpp | |
parent | adb6372aa58456513b3db54ed552aefb61b6d887 (diff) | |
download | bcm5719-llvm-3f3dbeedd391f10a410aa8fff5a9c95055ce214c.tar.gz bcm5719-llvm-3f3dbeedd391f10a410aa8fff5a9c95055ce214c.zip |
implement codegen support for return of void and simple scalars.
llvm-svn: 39547
Diffstat (limited to 'clang/CodeGen/CGStmt.cpp')
-rw-r--r-- | clang/CodeGen/CGStmt.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/clang/CodeGen/CGStmt.cpp b/clang/CodeGen/CGStmt.cpp index c8f02a12b98..0b30a99f3d2 100644 --- a/clang/CodeGen/CGStmt.cpp +++ b/clang/CodeGen/CGStmt.cpp @@ -43,6 +43,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break; case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break; case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break; + case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break; } } @@ -178,3 +179,36 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { EmitBlock(ContBlock); } +/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand +/// if the function returns void, or may be missing one if the function returns +/// non-void. Fun stuff :). +void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { + ExprResult RetVal; + + // Emit the result value, even if unused, to evalute the side effects. + const Expr *RV = S.getRetValue(); + if (RV) + RetVal = EmitExpr(RV); + + if (CurFuncDecl->getType()->isVoidType()) { + // If the function returns void, emit ret void, and ignore the retval. + Builder.CreateRetVoid(); + } else if (RV == 0) { + // "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 (RetVal.isScalar()) { + // FIXME: return should coerce its operand to the return type! + Builder.CreateRet(RetVal.getVal()); + } else { + assert(0 && "FIXME: aggregate return unimp"); + } + + // Emit a block after the branch so that dead code after a goto has some place + // to go. + Builder.SetInsertPoint(new BasicBlock("", CurFn)); +} + |