summaryrefslogtreecommitdiffstats
path: root/clang/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-06-05 03:59:43 +0000
committerChris Lattner <sabre@nondot.org>2007-06-05 03:59:43 +0000
commit946aa31f026f29f41394c3e8776fcaf8f67d984c (patch)
tree6760c9f7d21543fb7530fb88a79789901b15664e /clang/CodeGen/CGStmt.cpp
parent71b59a9a294117e53143640ceba780cabca0297b (diff)
downloadbcm5719-llvm-946aa31f026f29f41394c3e8776fcaf8f67d984c.tar.gz
bcm5719-llvm-946aa31f026f29f41394c3e8776fcaf8f67d984c.zip
implement codegen of while stmts and lvalue evaluation of paren exprs :)
llvm-svn: 39582
Diffstat (limited to 'clang/CodeGen/CGStmt.cpp')
-rw-r--r--clang/CodeGen/CGStmt.cpp50
1 files changed, 46 insertions, 4 deletions
diff --git a/clang/CodeGen/CGStmt.cpp b/clang/CodeGen/CGStmt.cpp
index 6332f3ecd5f..88041b575e5 100644
--- a/clang/CodeGen/CGStmt.cpp
+++ b/clang/CodeGen/CGStmt.cpp
@@ -42,7 +42,10 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
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::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
+
case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
}
@@ -92,13 +95,12 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// Emit the if condition.
- ExprResult CondVal = EmitExpr(S.getCond());
- QualType CondTy = S.getCond()->getType().getCanonicalType();
+ QualType CondTy;
+ ExprResult CondVal = EmitExprWithUsualUnaryConversions(S.getCond(), CondTy);
// C99 6.8.4.1: The first substatement is executed if the expression compares
// unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal =
- EvaluateScalarValueToBool(CondVal, S.getCond()->getType());
+ llvm::Value *BoolCondVal = EvaluateScalarValueToBool(CondVal, CondTy);
BasicBlock *ContBlock = new BasicBlock("ifend");
BasicBlock *ThenBlock = new BasicBlock("ifthen");
@@ -126,6 +128,46 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
EmitBlock(ContBlock);
}
+void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
+ // FIXME: Handle continue/break.
+
+ // Emit the header for the loop, insert it, which will create an uncond br to
+ // it.
+ BasicBlock *LoopHeader = new BasicBlock("whilecond");
+ EmitBlock(LoopHeader);
+
+ // Evaluate the conditional in the while header. C99 6.8.5.1: The evaluation
+ // of the controlling expression takes place before each execution of the loop
+ // body.
+ QualType CondTy;
+ ExprResult CondVal = EmitExprWithUsualUnaryConversions(S.getCond(), CondTy);
+
+ // C99 6.8.5p2: The first substatement is executed if the expression compares
+ // unequal to 0. The condition must be a scalar type.
+ llvm::Value *BoolCondVal = EvaluateScalarValueToBool(CondVal, CondTy);
+
+ // TODO: while(1) is common, avoid extra exit blocks, etc.
+
+ // Create an exit block for when the condition fails, create a block for the
+ // body of the loop.
+ BasicBlock *ExitBlock = new BasicBlock("whileexit");
+ BasicBlock *LoopBody = new BasicBlock("whilebody");
+
+ // As long as the condition is true, go to the loop body.
+ Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
+
+ // Emit the loop body.
+ EmitBlock(LoopBody);
+ EmitStmt(S.getBody());
+
+ // Cycle to the condition.
+ Builder.CreateBr(LoopHeader);
+
+ // Emit the exit block.
+ EmitBlock(ExitBlock);
+}
+
+
/// 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 :).
OpenPOWER on IntegriCloud