+2002-07-03 Miguel de Icaza <miguel@ximian.com>
+
+ * statement.cs (While, For, Do): These loops can exit through a
+ Break statement, use this information to tell whether the
+ statement is the last piece of code.
+
+ (Break): Flag that we break.
+
+ * codegen.cs (EmitContexts): New `Breaks' state variable.
+
2002-07-03 Martin Baulig <martin@gnome.org>
* class.cs (TypeContainer.MethodModifiersValid): Allow override
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
ec.LoopBegin = ig.DefineLabel ();
ec.LoopEnd = ig.DefineLabel ();
ec.InLoop = true;
ig.MarkLabel (loop);
+ ec.Breaks = false;
EmbeddedStatement.Emit (ec);
+ bool breaks = ec.Breaks;
ig.MarkLabel (ec.LoopBegin);
//
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+ ec.Breaks = old_breaks;
//
// Inform whether we are infinite or not
BoolConstant bc = (BoolConstant) expr;
if (bc.Value == true)
- return true;
+ return breaks == false;
}
return false;
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
Label while_loop = ig.DefineLabel ();
bool ret;
Warning_DeadCodeFound (Statement.loc);
ret = false;
} else {
+ bool breaks;
+
+ ec.Breaks = false;
Statement.Emit (ec);
+ breaks = ec.Breaks;
ig.Emit (OpCodes.Br, ec.LoopBegin);
//
- // Inform that we are infinite (ie, `we return')
+ // Inform that we are infinite (ie, `we return'), only
+ // if we do not `break' inside the code.
//
- ret = true;
+ ret = breaks == false;
}
ig.MarkLabel (ec.LoopEnd);
} else {
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
+ ec.Breaks = old_breaks;
return ret;
}
Label old_begin = ec.LoopBegin;
Label old_end = ec.LoopEnd;
bool old_inloop = ec.InLoop;
+ bool old_breaks = ec.Breaks;
Label loop = ig.DefineLabel ();
if (InitStatement != null)
//
if (Test != null)
EmitBoolExpression (ec, Test, ec.LoopEnd, false);
-
+
+ ec.Breaks = false;
Statement.Emit (ec);
+ bool breaks = ec.Breaks;
+
ig.MarkLabel (ec.LoopBegin);
if (!(Increment is EmptyStatement))
Increment.Emit (ec);
ec.LoopBegin = old_begin;
ec.LoopEnd = old_end;
ec.InLoop = old_inloop;
-
+ ec.Breaks = old_breaks;
+
//
// Inform whether we are infinite or not
//
BoolConstant bc = (BoolConstant) Test;
if (bc.Value)
- return true;
+ return breaks == false;
}
return false;
} else
Report.Error (139, loc, "No enclosing loop or switch to continue to");
return false;
}
-
+
+ ec.Breaks = true;
ig.Emit (OpCodes.Br, ec.LoopEnd);
return false;