Author: miguel
Date: 2007-02-17 20:26:03 -0500 (Sat, 17 Feb 2007)
New Revision: 73063

Modified:
   trunk/mcs/mcs/ChangeLog
   trunk/mcs/mcs/anonymous.cs
   trunk/mcs/mcs/assign.cs
   trunk/mcs/mcs/codegen.cs
   trunk/mcs/mcs/constant.cs
   trunk/mcs/mcs/ecore.cs
   trunk/mcs/mcs/expression.cs
   trunk/mcs/mcs/iterators.cs
   trunk/mcs/mcs/lambda.cs
   trunk/mcs/mcs/statement.cs
Log:
2007-02-17  Miguel de Icaza  <[EMAIL PROTECTED]>

        * lambda.cs: Only clone when we are probing, not on the final call
        (Compatible is the final call). 

        * statement.cs (CloneContext): Introduce class to provide block
        remapping during clone.

        All statements Clone themselves now.

        (Clone): special handling for blocks, when we clone a block, we
        register the block inside this routine, as children of the block
        might trigger a lookup. 
        
        * expression.cs: Add support for CloneContext in all expressions. 



Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog     2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/ChangeLog     2007-02-18 01:26:03 UTC (rev 73063)
@@ -1,3 +1,20 @@
+2007-02-17  Miguel de Icaza  <[EMAIL PROTECTED]>
+
+       * lambda.cs: Only clone when we are probing, not on the final call
+       (Compatible is the final call). 
+
+       * statement.cs (CloneContext): Introduce class to provide block
+       remapping during clone.
+
+       All statements Clone themselves now.
+
+       (Clone): special handling for blocks, when we clone a block, we
+       register the block inside this routine, as children of the block
+       might trigger a lookup. 
+       
+       * expression.cs: Add support for CloneContext in all expressions. 
+       
+
 2007-02-17  Marek Safar  <[EMAIL PROTECTED]>
  
        A fix for bug #80493

Modified: trunk/mcs/mcs/anonymous.cs
===================================================================
--- trunk/mcs/mcs/anonymous.cs  2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/anonymous.cs  2007-02-18 01:26:03 UTC (rev 73063)
@@ -1063,7 +1063,7 @@
                public ToplevelBlock Block;
                protected AnonymousMethod anonymous;
 
-               protected readonly Block container;
+               protected Block container;
                protected readonly GenericMethod generic;
 
                public Block Container {
@@ -1333,12 +1333,12 @@
                        get { return false; }
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        AnonymousMethodExpression target = 
(AnonymousMethodExpression) t;
 
-                       throw new Exception ("Must map the block");
-                       
+                       target.Block = (ToplevelBlock) clonectx.LookupBlock 
(Block);
+                       target.container = clonectx.LookupBlock (Block);
                        target.Parameters = Parameters.Clone ();
                }
        }

Modified: trunk/mcs/mcs/assign.cs
===================================================================
--- trunk/mcs/mcs/assign.cs     2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/assign.cs     2007-02-18 01:26:03 UTC (rev 73063)
@@ -583,12 +583,12 @@
                        Emit (ec, true);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Assign _target = (Assign) t;
 
-                       _target.target = target.Clone ();
-                       _target.source = source.Clone ();
+                       _target.target = target.Clone (clonectx);
+                       _target.source = source.Clone (clonectx);
                }
        }
 
@@ -676,11 +676,11 @@
                        return base.DoResolve (ec);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        CompoundAssign target = (CompoundAssign) t;
 
-                       target.original_source = original_source.Clone ();
+                       target.original_source = original_source.Clone 
(clonectx);
                }
        }
 }

Modified: trunk/mcs/mcs/codegen.cs
===================================================================
--- trunk/mcs/mcs/codegen.cs    2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/codegen.cs    2007-02-18 01:26:03 UTC (rev 73063)
@@ -15,7 +15,7 @@
 //
 // Only remove it if you need to debug locally on your tree.
 //
-#define PRODUCTION
+//#define PRODUCTION
 
 using System;
 using System.IO;

Modified: trunk/mcs/mcs/constant.cs
===================================================================
--- trunk/mcs/mcs/constant.cs   2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/constant.cs   2007-02-18 01:26:03 UTC (rev 73063)
@@ -217,7 +217,7 @@
                        get { return false; }
                }
 
-               protected override void CloneTo (Expression target)
+               protected override void CloneTo (CloneContext clonectx, 
Expression target)
                {
                        // CloneTo: Nothing, we do not keep any state on this 
expression
                }

Modified: trunk/mcs/mcs/ecore.cs
===================================================================
--- trunk/mcs/mcs/ecore.cs      2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/ecore.cs      2007-02-18 01:26:03 UTC (rev 73063)
@@ -1156,7 +1156,7 @@
                // Only expressions that are created for the parser need to 
implement
                // this.
                //
-               protected virtual void CloneTo (Expression target)
+               protected virtual void CloneTo (CloneContext clonectx, 
Expression target)
                {
                        throw new NotImplementedException (
                                String.Format (
@@ -1174,10 +1174,10 @@
                // compile the same code using different type values for the 
same
                // arguments to find the correct overload
                //
-               public Expression Clone ()
+               public Expression Clone (CloneContext clonectx)
                {
                        Expression cloned = (Expression) MemberwiseClone ();
-                       CloneTo (cloned);
+                       CloneTo (clonectx, cloned);
 
                        return cloned;
                }
@@ -1255,11 +1255,11 @@
                        return child.GetAttributableValue (valueType, out 
value);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        EmptyCast target = (EmptyCast) t;
 
-                       target.child = child.Clone ();
+                       target.child = child.Clone (clonectx);
                }
        }
 
@@ -2383,7 +2383,7 @@
                        return Name;
                }
 
-               protected override void CloneTo (Expression target)
+               protected override void CloneTo (CloneContext clonectx, 
Expression target)
                {
                        // CloneTo: Nothing, we do not keep any state on this 
expression
                }
@@ -2610,6 +2610,11 @@
                public override string FullName {
                        get { return name; }
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Expression target)
+               {
+                       // CloneTo: Nothing, we do not keep any state on this 
expression
+               }
        }
 
        /// <summary>

Modified: trunk/mcs/mcs/expression.cs
===================================================================
--- trunk/mcs/mcs/expression.cs 2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/expression.cs 2007-02-18 01:26:03 UTC (rev 73063)
@@ -115,11 +115,11 @@
                        }
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        ParenthesizedExpression target = 
(ParenthesizedExpression) t;
 
-                       target.Expr = Expr.Clone ();
+                       target.Expr = Expr.Clone (clonectx);
                }
        }
        
@@ -667,11 +667,11 @@
                        return "Unary (" + Oper + ", " + Expr + ")";
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Unary target = (Unary) t;
 
-                       target.Expr = Expr.Clone ();
+                       target.Expr = Expr.Clone (clonectx);
                }
        }
 
@@ -1039,11 +1039,11 @@
                        EmitCode (ec, false);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        UnaryMutator target = (UnaryMutator) t;
 
-                       target.expr = expr.Clone ();
+                       target.expr = expr.Clone (clonectx);
                }
        }
 
@@ -1090,12 +1090,12 @@
                        return this;
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Probe target = (Probe) t;
 
-                       target.expr = expr.Clone ();
-                       target.ProbeType = ProbeType.Clone ();
+                       target.expr = expr.Clone (clonectx);
+                       target.ProbeType = ProbeType.Clone (clonectx);
                }
 
        }
@@ -1416,12 +1416,12 @@
                        throw new Exception ("Should not happen");
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Cast target = (Cast) t;
 
-                       target.target_type = target_type.Clone ();
-                       target.expr = expr.Clone ();
+                       target.target_type = target_type.Clone (clonectx);
+                       target.expr = expr.Clone (clonectx);
                }
        }
 
@@ -2821,12 +2821,12 @@
                        ig.Emit (opcode);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Binary target = (Binary) t;
 
-                       target.left = left.Clone ();
-                       target.right = right.Clone ();
+                       target.left = left.Clone (clonectx);
+                       target.right = right.Clone (clonectx);
                }
        }
 
@@ -3379,13 +3379,13 @@
                        ig.MarkLabel (end_target);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Conditional target = (Conditional) t;
 
-                       target.expr = expr.Clone ();
-                       target.trueExpr = trueExpr.Clone ();
-                       target.falseExpr = falseExpr.Clone ();
+                       target.expr = expr.Clone (clonectx);
+                       target.trueExpr = trueExpr.Clone (clonectx);
+                       target.falseExpr = falseExpr.Clone (clonectx);
                }
        }
 
@@ -3495,7 +3495,7 @@
        /// </summary>
        public class LocalVariableReference : VariableReference, IVariable {
                public readonly string Name;
-               public readonly Block Block;
+               public Block Block;
                public LocalInfo local_info;
                bool is_readonly;
                Variable variable;
@@ -3641,13 +3641,11 @@
                        return String.Format ("{0} ({1}:{2})", GetType (), 
Name, loc);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
-                       //
-                       // We need an infrastructure in CloneTo that can be 
used remap
-                       // old block pointers to new block pointers
-                       //
-                       throw new Exception ("Do something about the block we 
point to");
+                       LocalVariableReference target = 
(LocalVariableReference) t;
+                       
+                       target.Block = clonectx.LookupBlock (Block);
                }
        }
 
@@ -3774,7 +3772,6 @@
                        if (!am.IsIterator && block.Toplevel.IsLocalParameter 
(name))
                                return true;
 
-                       RootScopeInfo host = null;
                        ToplevelBlock toplevel = block.Toplevel;
                        while (toplevel != null) {
                                if (toplevel.IsLocalParameter (name))
@@ -3972,9 +3969,9 @@
                                ml.AddressOf (ec, mode);
                }
 
-               public Argument Clone ()
+               public Argument Clone (CloneContext clonectx)
                {
-                       return new Argument (Expr.Clone (), ArgType);
+                       return new Argument (Expr.Clone (clonectx), ArgType);
                }
        }
 
@@ -4827,17 +4824,17 @@
                        }
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Invocation target = (Invocation) t;
 
                        if (Arguments != null){
                                target.Arguments = new ArrayList ();
                                foreach (Argument a in Arguments)
-                                       target.Arguments.Add (a.Clone ());
+                                       target.Arguments.Add (a.Clone 
(clonectx));
                        }
 
-                       expr = expr.Clone ();
+                       expr = expr.Clone (clonectx);
                }
        }
 
@@ -4939,12 +4936,12 @@
                        throw new Exception ("Cannot happen");
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        InvocationOrCast target = (InvocationOrCast) t;
 
-                       target.expr = expr.Clone ();
-                       target.argument = argument.Clone ();
+                       target.expr = expr.Clone (clonectx);
+                       target.argument = argument.Clone (clonectx);
                }
        }
 
@@ -5337,15 +5334,15 @@
                        ((IMemoryLocation) value_target).AddressOf (ec, Mode);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        New target = (New) t;
 
-                       target.RequestedType = RequestedType.Clone ();
+                       target.RequestedType = RequestedType.Clone (clonectx);
                        if (Arguments != null){
                                target.Arguments = new ArrayList ();
                                foreach (Argument a in Arguments){
-                                       target.Arguments.Add (a.Clone ());
+                                       target.Arguments.Add (a.Clone 
(clonectx));
                                }
                        }
                }
@@ -6060,19 +6057,19 @@
                        return true;
                }
                
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        ArrayCreation target = (ArrayCreation) t;
 
-                       target.requested_base_type = requested_base_type.Clone 
();
+                       target.requested_base_type = requested_base_type.Clone 
(clonectx);
                        target.arguments = new ArrayList ();
                        foreach (Argument a in arguments)
-                               target.arguments.Add (a.Clone ());
+                               target.arguments.Add (a.Clone (clonectx));
 
                        if (initializers != null){
                                target.initializers = new ArrayList ();
                                foreach (Expression initializer in initializers)
-                                       target.initializers.Add 
(initializer.Clone ());
+                                       target.initializers.Add 
(initializer.Clone (clonectx));
                        }
                }
        }
@@ -6281,11 +6278,11 @@
                        }
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        This target = (This) t;
 
-                       throw new Exception ("Must do block remapping");
+                       target.block = clonectx.LookupBlock (block);
                }
        }
 
@@ -6319,7 +6316,7 @@
                        ec.ig.Emit (OpCodes.Arglist);
                }
 
-               protected override void CloneTo (Expression target)
+               protected override void CloneTo (CloneContext clonectx, 
Expression target)
                {
                        // nothing.
                }
@@ -6366,13 +6363,13 @@
                                arg.Emit (ec);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        Arglist target = (Arglist) t;
 
                        target.Arguments = new Argument [Arguments.Length];
                        for (int i = 0; i < Arguments.Length; i++)
-                               target.Arguments [i] = Arguments [i].Clone ();
+                               target.Arguments [i] = Arguments [i].Clone 
(clonectx);
                }
        }
 
@@ -6469,11 +6466,11 @@
                        }
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        TypeOf target = (TypeOf) t;
 
-                       target.QueriedType = QueriedType.Clone ();
+                       target.QueriedType = QueriedType.Clone (clonectx);
                }
        }
 
@@ -6561,11 +6558,11 @@
                                IntConstant.EmitInt (ec.ig, size);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        SizeOf target = (SizeOf) t;
 
-                       target.QueriedType = QueriedType.Clone ();
+                       target.QueriedType = QueriedType.Clone (clonectx);
                }
        }
 
@@ -6651,7 +6648,7 @@
                        return ToString ();
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        // Nothing 
                }
@@ -6937,11 +6934,11 @@
                        return expr.GetSignatureForError () + "." + Identifier;
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        MemberAccess target = (MemberAccess) t;
 
-                       target.expr = expr.Clone ();
+                       target.expr = expr.Clone (clonectx);
                }
        }
 
@@ -6986,11 +6983,11 @@
                                Expr.EmitBranchable (ec, target, onTrue);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        CheckedExpr target = (CheckedExpr) t;
 
-                       target.Expr = Expr.Clone ();
+                       target.Expr = Expr.Clone (clonectx);
                }
        }
 
@@ -7035,11 +7032,11 @@
                                Expr.EmitBranchable (ec, target, onTrue);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        UnCheckedExpr target = (UnCheckedExpr) t;
 
-                       target.Expr = Expr.Clone ();
+                       target.Expr = Expr.Clone (clonectx);
                }
        }
 
@@ -7173,14 +7170,14 @@
                        throw new Exception ("Should never be reached");
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        ElementAccess target = (ElementAccess) t;
 
-                       target.Expr = Expr.Clone ();
+                       target.Expr = Expr.Clone (clonectx);
                        target.Arguments = new ArrayList ();
                        foreach (Argument a in Arguments)
-                               target.Arguments.Add (a.Clone ());
+                               target.Arguments.Add (a.Clone (clonectx));
                }
        }
 
@@ -7917,17 +7914,17 @@
                        return instance_expr.GetSignatureForError () + 
".this[...]";
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        IndexerAccess target = (IndexerAccess) t;
 
                        if (arguments != null){
                                target.arguments = new ArrayList ();
                                foreach (Argument a in arguments)
-                                       target.arguments.Add (a.Clone ());
+                                       target.arguments.Add (a.Clone 
(clonectx));
                        }
                        if (instance_expr != null)
-                               target.instance_expr = instance_expr.Clone ();
+                               target.instance_expr = instance_expr.Clone 
(clonectx);
                }
        }
 
@@ -8042,7 +8039,7 @@
                        throw new Exception ("Should never be called"); 
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        BaseAccess target = (BaseAccess) t;
 
@@ -8280,11 +8277,11 @@
                        return left.GetSignatureForError () + dim;
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        ComposedCast target = (ComposedCast) t;
 
-                       target.left = left.Clone ();
+                       target.left = left.Clone (clonectx);
                }
        }
 
@@ -8439,11 +8436,11 @@
                        ig.Emit (OpCodes.Localloc);
                }
 
-               protected override void CloneTo (Expression t)
+               protected override void CloneTo (CloneContext clonectx, 
Expression t)
                {
                        StackAlloc target = (StackAlloc) t;
-                       target.count = count.Clone ();
-                       target.t = t.Clone ();
+                       target.count = count.Clone (clonectx);
+                       target.t = t.Clone (clonectx);
                }
        }
 }

Modified: trunk/mcs/mcs/iterators.cs
===================================================================
--- trunk/mcs/mcs/iterators.cs  2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/iterators.cs  2007-02-18 01:26:03 UTC (rev 73063)
@@ -100,6 +100,13 @@
                {
                        ec.CurrentIterator.MarkYield (ec, expr, finally_blocks);
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Yield target = (Yield) t;
+
+                       target.expr = expr.Clone (clonectx);
+               }
        }
 
        public class YieldBreak : Statement {

Modified: trunk/mcs/mcs/lambda.cs
===================================================================
--- trunk/mcs/mcs/lambda.cs     2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/lambda.cs     2007-02-18 01:26:03 UTC (rev 73063)
@@ -63,7 +63,11 @@
 
                        try {
                                Report.DisableErrors ();
-                               result = Compatible (ec, delegate_type) != null;
+                               result = DoCompatibleTest (ec, delegate_type, 
true) != null;
+                               if (result)
+                                       Console.WriteLine ("INFO: 
Lambda.Compatible Passed for {0}", delegate_type);
+                               else
+                                       Console.WriteLine ("INFO: 
Lambda.Compatible Failed for {0}", delegate_type);
                        } finally {
                                Report.EnableErrors ();
                        }
@@ -80,19 +84,10 @@
                //
                public override Expression Compatible (EmitContext ec, Type 
delegate_type)
                {
-                       Expression result;
-                       
-                       result = DoCompatibleTest (ec, delegate_type);
-
-                       if (result == null)
-                               Console.WriteLine ("INFO: Lambda.Compatible 
Failed for {0}", delegate_type);
-                       else
-                               Console.WriteLine ("INFO: Lambda.Compatible 
Passed for {0}", delegate_type);
-                       
-                       return result;
+                       return DoCompatibleTest (ec, delegate_type, false);
                }
 
-               Expression DoCompatibleTest (EmitContext ec, Type delegate_type)
+               Expression DoCompatibleTest (EmitContext ec, Type 
delegate_type, bool clone)
                {
                        if (anonymous != null)
                                return anonymous.AnonymousDelegate;
@@ -148,7 +143,7 @@
                        // to be the delegate type return type.
                        //
 
-                       ToplevelBlock b = (ToplevelBlock) Block.Clone ();
+                       ToplevelBlock b = clone ? (ToplevelBlock) 
Block.PerformClone () : Block;
                        
                        anonymous = new AnonymousMethod (
                                Parent != null ? Parent.AnonymousMethod : null, 
RootScope, Host,
@@ -224,11 +219,11 @@
                        ec.ig.Emit (OpCodes.Ret);
                }
 
-               protected override void CloneTo (Statement t)
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
                {
                        ContextualReturn cr = (ContextualReturn) t;
 
-                       cr.Expr = Expr.Clone ();
+                       cr.Expr = Expr.Clone (clonectx);
                }
        }
 }

Modified: trunk/mcs/mcs/statement.cs
===================================================================
--- trunk/mcs/mcs/statement.cs  2007-02-17 19:44:06 UTC (rev 73062)
+++ trunk/mcs/mcs/statement.cs  2007-02-18 01:26:03 UTC (rev 73063)
@@ -91,19 +91,82 @@
                // This routine must be overrided in derived classes and make 
copies
                // of all the data that might be modified if resolved
                // 
-               protected virtual void CloneTo (Statement target)
+               protected virtual void CloneTo (CloneContext clonectx, 
Statement target)
                {
                        throw new Exception (String.Format ("Statement.CloneTo 
not implemented for {0}", this.GetType ()));
                }
                
-               public Statement Clone ()
+               public Statement Clone (CloneContext clonectx)
                {
                        Statement s = (Statement) this.MemberwiseClone ();
-                       CloneTo (s);
+                       if (s is Block)
+                               clonectx.AddBlockMap ((Block) this, (Block) s);
+                       
+                       CloneTo (clonectx, s);
                        return s;
                }
+
+               public Statement PerformClone ()
+               {
+                       CloneContext clonectx = new CloneContext ();
+
+                       return Clone (clonectx);
+               }
+
        }
 
+       //
+       // This class is used during the Statement.Clone operation
+       // to remap objects that have been cloned.
+       //
+       // Since blocks are cloned by Block.Clone, we need a way for
+       // expressions that must reference the block to be cloned
+       // pointing to the new cloned block.
+       //
+       public class CloneContext {
+               Hashtable block_map = new Hashtable ();
+               Hashtable variable_map;
+               
+               public void AddBlockMap (Block from, Block to)
+               {
+                       if (block_map.Contains (from))
+                               return;
+                       block_map [from] = to;
+               }
+               
+               public Block LookupBlock (Block from)
+               {
+                       Block result = (Block) block_map [from];
+
+                       if (result == null){
+                               result = (Block) from.Clone (this);
+                               block_map [from] = result;
+                       }
+
+                       return result;
+               }
+
+               public void AddVariableMap (LocalInfo from, LocalInfo to)
+               {
+                       if (variable_map == null)
+                               variable_map = new Hashtable ();
+                       
+                       if (variable_map.Contains (from))
+                               return;
+                       variable_map [from] = to;
+               }
+               
+               public LocalInfo LookupVariable (LocalInfo from)
+               {
+                       LocalInfo result = (LocalInfo) variable_map [from];
+
+                       if (result == null)
+                               throw new Exception ("LookupVariable: looking 
up a variable that has not been registered yet");
+
+                       return result;
+               }
+       }
+       
        public sealed class EmptyStatement : Statement {
                
                private EmptyStatement () {}
@@ -255,11 +318,20 @@
                                ig.MarkLabel (false_target);
                        }
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       If target = (If) t;
+
+                       target.expr = expr.Clone (clonectx);
+                       target.TrueStatement = TrueStatement.Clone (clonectx);
+                       target.FalseStatement = FalseStatement.Clone (clonectx);
+               }
        }
 
        public class Do : Statement {
                public Expression expr;
-               public readonly Statement  EmbeddedStatement;
+               public Statement  EmbeddedStatement;
                bool infinite;
                
                public Do (Statement statement, Expression boolExpr, Location l)
@@ -332,11 +404,19 @@
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Do target = (Do) t;
+
+                       target.EmbeddedStatement = EmbeddedStatement.Clone 
(clonectx);
+                       target.expr = expr.Clone (clonectx);
+               }
        }
 
        public class While : Statement {
                public Expression expr;
-               public readonly Statement Statement;
+               public Statement Statement;
                bool infinite, empty;
                
                public While (Expression boolExpr, Statement statement, 
Location l)
@@ -429,13 +509,21 @@
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       While target = (While) t;
+
+                       target.expr = expr.Clone (clonectx);
+                       target.Statement = Statement.Clone (clonectx);
+               }
        }
 
        public class For : Statement {
                Expression Test;
-               readonly Statement InitStatement;
-               readonly Statement Increment;
-               public readonly Statement Statement;
+               Statement InitStatement;
+               Statement Increment;
+               public Statement Statement;
                bool infinite, empty;
                
                public For (Statement initStatement,
@@ -558,6 +646,19 @@
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       For target = (For) t;
+
+                       if (InitStatement != null)
+                               target.InitStatement = InitStatement.Clone 
(clonectx);
+                       if (Test != null)
+                               target.Test = Test.Clone (clonectx);
+                       if (Increment != null)
+                               target.Increment = Increment.Clone (clonectx);
+                       target.Statement = Statement.Clone (clonectx);
+               }
        }
        
        public class StatementExpression : Statement {
@@ -586,11 +687,11 @@
                        return "StatementExpression (" + expr + ")";
                }
 
-               protected override void CloneTo (Statement t)
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
                {
                        StatementExpression target = (StatementExpression) t;
 
-                       target.expr = (ExpressionStatement) expr.Clone ();
+                       target.expr = (ExpressionStatement) expr.Clone 
(clonectx);
                }
        }
 
@@ -670,11 +771,11 @@
                                ec.ig.Emit (OpCodes.Ret);
                }
 
-               protected override void CloneTo (Statement t)
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
                {
                        Return target = (Return) t;
 
-                       target.Expr = Expr.Clone ();
+                       target.Expr = Expr.Clone (clonectx);
                }
        }
 
@@ -882,6 +983,14 @@
                {
                        ec.ig.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       GotoCase target = (GotoCase) t;
+
+                       target.expr = expr.Clone (clonectx);
+                       target.sl = sl.Clone (clonectx);
+               }
        }
        
        public class Throw : Statement {
@@ -945,6 +1054,13 @@
                                ec.ig.Emit (OpCodes.Throw);
                        }
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Throw target = (Throw) t;
+
+                       target.expr = expr.Clone (clonectx);
+               }
        }
 
        public class Break : Statement {
@@ -1289,8 +1405,14 @@
                                ec.ig.Emit (OpCodes.Ldloca, builder);
                        }
                }
+
+               public LocalInfo Clone (CloneContext clonectx)
+               {
+                       // Only this kind is created by the parser.
+                       return new LocalInfo (Type.Clone (clonectx), Name, 
clonectx.LookupBlock (Block), Location);
+               }
        }
-               
+
        /// <summary>
        ///   Block represents a C# block.
        /// </summary>
@@ -1874,8 +1996,9 @@
 
                public VariableMap ParameterMap {
                        get {
-                               if ((flags & Flags.VariablesInitialized) == 0)
+                               if ((flags & Flags.VariablesInitialized) == 0){
                                        throw new Exception ("Variables have 
not been initialized yet");
+                               }
 
                                return param_map;
                        }
@@ -2304,22 +2427,39 @@
                        return String.Format ("{0} ({1}:{2})", GetType (),ID, 
StartLocation);
                }
 
-               protected override void CloneTo (Statement t)
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
                {
                        Block target = (Block) t;
 
+                       if (Parent != null)
+                               target.Parent = clonectx.LookupBlock (Parent);
+                       
                        target.statements = new ArrayList ();
-                       foreach (Statement s in statements)
-                               target.statements.Add (s.Clone ());
-
                        if (target.children != null){
                                target.children = new ArrayList ();
-                               foreach (Block b in children)
-                                       target.children.Add (b.Clone ());
+                               foreach (Block b in children){
+                                       Block newblock = (Block) b.Clone 
(clonectx);
+
+                                       target.children.Add (newblock);
+                               }
+                               
                        }
 
+                       foreach (Statement s in statements)
+                               target.statements.Add (s.Clone (clonectx));
+
+                       if (variables != null){
+                               target.variables = new Hashtable ();
+
+                               foreach (DictionaryEntry de in variables){
+                                       LocalInfo newlocal = ((LocalInfo) 
de.Value).Clone (clonectx);
+                                       target.variables [de.Key] = newlocal;
+                                       clonectx.AddVariableMap ((LocalInfo) 
de.Value, newlocal);
+                               }
+                       }
+
                        //
-                       // TODO: labels, switch_block, variables, constants 
(?), anonymous_children
+                       // TODO: labels, switch_block, constants (?), 
anonymous_children
                        //
                }
        }
@@ -2670,7 +2810,6 @@
                                              root_scope, anonymous_container 
!= null ?
                                              anonymous_container.Scope : null);
                }
-
        }
        
        public class SwitchLabel {
@@ -2774,6 +2913,11 @@
                        Report.SymbolRelatedToPreviousError (collisionWith.loc, 
null);
                        Report.Error (152, loc, "The label `case {0}:' already 
occurs in this switch statement", label);
                }
+
+               public SwitchLabel Clone (CloneContext clonectx)
+               {
+                       return new SwitchLabel (label.Clone (clonectx), loc);
+               }
        }
 
        public class SwitchSection {
@@ -2786,10 +2930,20 @@
                        Labels = labels;
                        Block = block;
                }
+
+               public SwitchSection Clone (CloneContext clonectx)
+               {
+                       ArrayList cloned_labels = new ArrayList ();
+
+                       foreach (SwitchLabel sl in cloned_labels)
+                               cloned_labels.Add (sl.Clone (clonectx));
+                       
+                       return new SwitchSection (cloned_labels, 
clonectx.LookupBlock (Block));
+               }
        }
        
        public class Switch : Statement {
-               public readonly ArrayList Sections;
+               public ArrayList Sections;
                public Expression Expr;
 
                /// <summary>
@@ -3509,6 +3663,17 @@
                        ec.LoopEnd = old_end;
                        ec.Switch = old_switch;
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Switch target = (Switch) t;
+
+                       target.Expr = Expr.Clone (clonectx);
+                       target.Sections = new ArrayList ();
+                       foreach (SwitchSection ss in Sections){
+                               target.Sections.Add (ss.Clone (clonectx));
+                       }
+               }
        }
 
        public abstract class ExceptionStatement : Statement
@@ -3615,10 +3780,18 @@
                        temp.Emit (ec);
                        ec.ig.Emit (OpCodes.Call, 
TypeManager.void_monitor_exit_object);
                }
+               
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Lock target = (Lock) t;
+
+                       target.expr = expr.Clone (clonectx);
+                       target.Statement = Statement.Clone (clonectx);
+               }
        }
 
        public class Unchecked : Statement {
-               public readonly Block Block;
+               public Block Block;
                
                public Unchecked (Block b)
                {
@@ -3637,10 +3810,17 @@
                        using (ec.With (EmitContext.Flags.AllCheckStateFlags, 
false))
                                Block.Emit (ec);
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Unchecked target = (Unchecked) t;
+
+                       target.Block = clonectx.LookupBlock (Block);
+               }
        }
 
        public class Checked : Statement {
-               public readonly Block Block;
+               public Block Block;
                
                public Checked (Block b)
                {
@@ -3659,10 +3839,17 @@
                        using (ec.With (EmitContext.Flags.AllCheckStateFlags, 
true))
                                Block.Emit (ec);
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Checked target = (Checked) t;
+
+                       target.Block = clonectx.LookupBlock (Block);
+               }
        }
 
        public class Unsafe : Statement {
-               public readonly Block Block;
+               public Block Block;
 
                public Unsafe (Block b)
                {
@@ -3681,6 +3868,12 @@
                        using (ec.With (EmitContext.Flags.InUnsafe, true))
                                Block.Emit (ec);
                }
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Unsafe target = (Unsafe) t;
+
+                       target.Block = clonectx.LookupBlock (Block);
+               }
        }
 
        // 
@@ -3968,12 +4161,23 @@
                                data [i].EmitExit (ec);
                        }
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Fixed target = (Fixed) t;
+
+                       target.type = type.Clone (clonectx);
+                       target.declarators = new ArrayList ();
+                       foreach (LocalInfo var in declarators)
+                               target.declarators.Add (clonectx.LookupVariable 
(var));
+                       target.statement = statement.Clone (clonectx);
+               }
        }
        
        public class Catch : Statement {
                public readonly string Name;
-               public readonly Block  Block;
-               public readonly Block  VarBlock;
+               public Block  Block;
+               public Block  VarBlock;
 
                Expression type_expr;
                Type type;
@@ -4059,12 +4263,21 @@
                                return true;
                        }
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Catch target = (Catch) t;
+
+                       target.type_expr = type_expr.Clone (clonectx);
+                       target.Block = clonectx.LookupBlock (Block);
+                       target.VarBlock = clonectx.LookupBlock (VarBlock);
+               }
        }
 
        public class Try : ExceptionStatement {
-               public readonly Block Fini, Block;
-               public readonly ArrayList Specific;
-               public readonly Catch General;
+               public Block Fini, Block;
+               public ArrayList Specific;
+               public Catch General;
 
                bool need_exc_block;
                
@@ -4223,6 +4436,22 @@
                                return General != null || Specific.Count > 0;
                        }
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Try target = (Try) t;
+
+                       target.Block = clonectx.LookupBlock (Block);
+                       if (Fini != null)
+                               target.Fini = clonectx.LookupBlock (Fini);
+                       if (General != null)
+                               target.General = (Catch) General.Clone 
(clonectx);
+                       if (Specific != null){
+                               target.Specific = new ArrayList ();
+                               foreach (Catch c in Specific)
+                                       target.Specific.Add (c.Clone 
(clonectx));
+                       }
+               }
        }
 
        public class Using : ExceptionStatement {
@@ -4529,6 +4758,18 @@
                        else if (expression_or_block is Expression)
                                EmitExpressionFinally (ec);
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Using target = (Using) t;
+
+                       if (expression_or_block is Expression)
+                               target.expression_or_block = ((Expression) 
expression_or_block).Clone (clonectx);
+                       else
+                               target.expression_or_block = ((Statement) 
expression_or_block).Clone (clonectx);
+                       
+                       target.Statement = Statement.Clone (clonectx);
+               }
        }
 
        /// <summary>
@@ -5223,5 +5464,15 @@
                                statement.Emit (ec);
                        }
                }
+
+               protected override void CloneTo (CloneContext clonectx, 
Statement t)
+               {
+                       Foreach target = (Foreach) t;
+
+                       target.type = type.Clone (clonectx);
+                       target.variable = variable.Clone (clonectx);
+                       target.expr = expr.Clone (clonectx);
+                       target.statement = statement.Clone (clonectx);
+               }
        }
 }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to