2002-07-03 Miguel de Icaza <miguel@ximian.com>
authorMiguel de Icaza <miguel@gnome.org>
Wed, 3 Jul 2002 21:47:08 +0000 (21:47 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Wed, 3 Jul 2002 21:47:08 +0000 (21:47 -0000)
* 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.

svn path=/trunk/mcs/; revision=5583

mcs/mcs/ChangeLog
mcs/mcs/codegen.cs
mcs/mcs/statement.cs

index e983603f3d86aa4f2951a1742fcc5d3b6cff3867..e63893fa25d576df49cfc26a373208b7e1dcf534 100755 (executable)
@@ -1,3 +1,13 @@
+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
index 819acf29363f2db6f70ccfcc0163a8337a4b55e8..70eea2e8f0f4472a3c513085853b144566267024 100755 (executable)
@@ -268,6 +268,11 @@ namespace Mono.CSharp {
                ///  Whether we are inside an unsafe block
                /// </summary>
                public bool InUnsafe;
+
+               /// <summary>
+               ///   Whether we break from a loop or not
+               /// </summary>
+               public bool Breaks;
                
                /// <summary>
                ///   Location for this EmitContext
index dfc04ad87b219cbf3658f4161964c57a19bdb579..c7ef137b709788bd3863ca9705490ffdf1a34cc6 100755 (executable)
@@ -230,13 +230,16 @@ namespace Mono.CSharp {
                        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);
 
                        //
@@ -255,6 +258,7 @@ namespace Mono.CSharp {
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                        ec.InLoop = old_inloop;
+                       ec.Breaks = old_breaks;
 
                        //
                        // Inform whether we are infinite or not
@@ -263,7 +267,7 @@ namespace Mono.CSharp {
                                BoolConstant bc = (BoolConstant) expr;
 
                                if (bc.Value == true)
-                                       return true;
+                                       return breaks == false;
                        }
                        
                        return false;
@@ -296,6 +300,7 @@ namespace Mono.CSharp {
                        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;
                        
@@ -317,13 +322,18 @@ namespace Mono.CSharp {
                                        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 {
@@ -340,6 +350,7 @@ namespace Mono.CSharp {
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                        ec.InLoop = old_inloop;
+                       ec.Breaks = old_breaks;
 
                        return ret;
                }
@@ -393,6 +404,7 @@ namespace Mono.CSharp {
                        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)
@@ -411,8 +423,11 @@ namespace Mono.CSharp {
                        //
                        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);
@@ -422,7 +437,8 @@ namespace Mono.CSharp {
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                        ec.InLoop = old_inloop;
-
+                       ec.Breaks = old_breaks;
+                       
                        //
                        // Inform whether we are infinite or not
                        //
@@ -431,7 +447,7 @@ namespace Mono.CSharp {
                                        BoolConstant bc = (BoolConstant) Test;
 
                                        if (bc.Value)
-                                               return true;
+                                               return breaks == false;
                                }
                                return false;
                        } else
@@ -739,7 +755,8 @@ namespace Mono.CSharp {
                                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;