changeset 311:9967a3270837 trunk

[svn r332] Fix codegen for continue within switch.
author ChristianK
date Sat, 28 Jun 2008 18:37:27 +0200
parents d20cf0dec9c1
children 553f844ae5b9
files gen/irstate.cpp gen/irstate.h gen/statements.cpp
diffstat 3 files changed, 16 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/gen/irstate.cpp	Sat Jun 28 11:50:28 2008 +0200
+++ b/gen/irstate.cpp	Sat Jun 28 18:37:27 2008 +0200
@@ -36,13 +36,14 @@
 {
 }
 
-IRLoopScope::IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e)
+IRLoopScope::IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e, bool isSwitch)
 {
     begin = b;
     end = e;
     //builder.SetInsertPoint(b);
     this->s = s;
     this->enclosinghandler = enclosinghandler;
+    this->isSwitch = isSwitch;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/irstate.h	Sat Jun 28 11:50:28 2008 +0200
+++ b/gen/irstate.h	Sat Jun 28 18:37:27 2008 +0200
@@ -45,9 +45,12 @@
     Statement* s;
     // the try of a TryFinally that encloses the loop
     EnclosingHandler* enclosinghandler;
+    // if it is a switch, we are a possible target for break
+    // but not for continue
+    bool isSwitch;
 
     IRLoopScope();
-    IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e);
+    IRLoopScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* b, llvm::BasicBlock* e, bool isSwitch = false);
 };
 
 struct IRBuilderHelper
--- a/gen/statements.cpp	Sat Jun 28 11:50:28 2008 +0200
+++ b/gen/statements.cpp	Sat Jun 28 18:37:27 2008 +0200
@@ -458,8 +458,15 @@
         assert(0);
     }
     else {
-        DtoEnclosingHandlers(enclosinghandler, gIR->loopbbs.back().enclosinghandler);
-        llvm::BranchInst::Create(gIR->loopbbs.back().begin, gIR->scopebb());
+        // can't 'continue' within switch, so omit them
+        IRState::LoopScopeVec::reverse_iterator it;
+        for(it = gIR->loopbbs.rbegin(); it != gIR->loopbbs.rend(); ++it) {
+            if(!it->isSwitch) {
+                break;
+            }
+        }
+        DtoEnclosingHandlers(enclosinghandler, it->enclosinghandler);
+        llvm::BranchInst::Create(it->begin, gIR->scopebb());
     }
 }
 
@@ -757,7 +764,7 @@
     assert(body);
 
     p->scope() = IRScope(bodybb, endbb);
-    p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb));
+    p->loopbbs.push_back(IRLoopScope(this,enclosinghandler,p->scopebb(),endbb,true));
     body->toIR(p);
     p->loopbbs.pop_back();