[svn r332] Fix codegen for continue within switch.

This commit is contained in:
Christian Kamm
2008-06-28 18:37:27 +02:00
parent ad65788592
commit 7dd287be94
3 changed files with 16 additions and 5 deletions

View File

@@ -36,13 +36,14 @@ IRLoopScope::IRLoopScope()
{
}
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;
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -45,9 +45,12 @@ struct IRLoopScope : IRScope
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

View File

@@ -458,8 +458,15 @@ void ContinueStatement::toIR(IRState* p)
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 @@ void SwitchStatement::toIR(IRState* p)
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();