summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-06-02 03:19:07 +0000
committerChris Lattner <sabre@nondot.org>2007-06-02 03:19:07 +0000
commit3f3dbeedd391f10a410aa8fff5a9c95055ce214c (patch)
tree6987d1ac5f29af14a836b2faa2e7554c445b87d0 /clang/CodeGen/CGStmt.cpp
parentadb6372aa58456513b3db54ed552aefb61b6d887 (diff)
downloadbcm5719-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.cpp34
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));
+}
+
OpenPOWER on IntegriCloud