Cache only resolved types not expression to report correct error location. Fixes...
[mono.git] / mcs / mcs / statement.cs
index 4bd207aa00f0f72729c019c4458dfeec50794d6a..871a798571ae873aa2f5c1cb7aea2160ea00bedf 100644 (file)
@@ -28,7 +28,7 @@ namespace Mono.CSharp {
                /// <summary>
                ///   Resolves the statement, true means that all sub-statements
                ///   did resolve ok.
-               //  </summary>
+               ///  </summary>
                public virtual bool Resolve (BlockContext bc)
                {
                        return true;
@@ -412,8 +412,9 @@ namespace Mono.CSharp {
                                                return false;
                                        empty = true;
                                        return true;
-                               } else
-                                       infinite = true;
+                               }
+
+                               infinite = true;
                        }
 
                        ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
@@ -548,8 +549,9 @@ namespace Mono.CSharp {
                                                        return false;
                                                empty = true;
                                                return true;
-                                       } else
-                                               infinite = true;
+                                       }
+
+                                       infinite = true;
                                }
                        } else
                                infinite = true;
@@ -702,7 +704,7 @@ namespace Mono.CSharp {
 
        public class StatementErrorExpression : Statement
        {
-               readonly Expression expr;
+               Expression expr;
 
                public StatementErrorExpression (Expression expr)
                {
@@ -729,7 +731,9 @@ namespace Mono.CSharp {
 
                protected override void CloneTo (CloneContext clonectx, Statement target)
                {
-                       throw new NotImplementedException ();
+                       var t = (StatementErrorExpression) target;
+
+                       t.expr = expr.Clone (clonectx);
                }
                
                public override object Accept (StructuralVisitor visitor)
@@ -747,7 +751,7 @@ namespace Mono.CSharp {
 
                public StatementList (Statement first, Statement second)
                {
-                       statements = new List<Statement> () { first, second };
+                       statements = new List<Statement> { first, second };
                }
 
                #region Properties
@@ -2579,7 +2583,8 @@ namespace Mono.CSharp {
                                        }
 
                                        if (b.Explicit == b.Explicit.ParametersBlock && b.Explicit.ParametersBlock.StateMachine != null) {
-                                               storey.HoistedThis = b.Explicit.ParametersBlock.StateMachine.HoistedThis;
+                                               if (storey.HoistedThis == null)
+                                                       storey.HoistedThis = b.Explicit.ParametersBlock.StateMachine.HoistedThis;
 
                                                if (storey.HoistedThis != null)
                                                        break;
@@ -2604,11 +2609,33 @@ namespace Mono.CSharp {
                                                        continue;
 
                                                if (storey.HoistedThis == null) {
-                                                       storey.AddCapturedThisField (ec);
+                                                       storey.AddCapturedThisField (ec, null);
                                                }
 
                                                for (ExplicitBlock b = ref_block; b.AnonymousMethodStorey != storey; b = b.Parent.Explicit) {
+                                                       ParametersBlock pb;
+
                                                        if (b.AnonymousMethodStorey != null) {
+                                                               //
+                                                               // Don't add storey cross reference for `this' when the storey ends up not
+                                                               // beeing attached to any parent
+                                                               //
+                                                               if (b.ParametersBlock.StateMachine == null) {
+                                                                       AnonymousMethodStorey s = null;
+                                                                       for (Block ab = b.AnonymousMethodStorey.OriginalSourceBlock.Parent; ab != null; ab = ab.Parent) {
+                                                                               s = ab.Explicit.AnonymousMethodStorey;
+                                                                               if (s != null)
+                                                                                       break;
+                                                                       }
+
+                                                                       // Needs to be in sync with AnonymousMethodBody::DoCreateMethodHost
+                                                                       if (s == null) {
+                                                                               var parent = storey == null || storey.Kind == MemberKind.Struct ? null : storey;
+                                                                               b.AnonymousMethodStorey.AddCapturedThisField (ec, parent);
+                                                                               break;
+                                                                       }
+                                                               }
+
                                                                b.AnonymousMethodStorey.AddParentStoreyReference (ec, storey);
                                                                b.AnonymousMethodStorey.HoistedThis = storey.HoistedThis;
 
@@ -2621,14 +2648,14 @@ namespace Mono.CSharp {
                                                                b = b.ParametersBlock;
                                                        }
 
-                                                       var pb = b as ParametersBlock;
+                                                       pb = b as ParametersBlock;
                                                        if (pb != null && pb.StateMachine != null) {
                                                                if (pb.StateMachine == storey)
                                                                        break;
 
                                                                //
-                                                               // If we are state machine with no parent we can hook into we don't
-                                                               // add reference but capture this directly
+                                                               // If we are state machine with no parent. We can hook into parent without additional
+                                                               // reference and capture this directly
                                                                //
                                                                ExplicitBlock parent_storey_block = pb;
                                                                while (parent_storey_block.Parent != null) {
@@ -2639,7 +2666,7 @@ namespace Mono.CSharp {
                                                                }
 
                                                                if (parent_storey_block.AnonymousMethodStorey == null) {
-                                                                       pb.StateMachine.AddCapturedThisField (ec);
+                                                                       pb.StateMachine.AddCapturedThisField (ec, null);
                                                                        b.HasCapturedThis = true;
                                                                        continue;
                                                                }
@@ -2984,7 +3011,7 @@ namespace Mono.CSharp {
                public override Expression CreateExpressionTree (ResolveContext ec)
                {
                        if (statements.Count == 1) {
-                               Expression expr = ((Statement) statements[0]).CreateExpressionTree (ec);
+                               Expression expr = statements[0].CreateExpressionTree (ec);
                                if (scope_initializers != null)
                                        expr = new BlockScopeExpression (expr, this);
 
@@ -3075,7 +3102,7 @@ namespace Mono.CSharp {
                                        unreachable = top_level.End ();
                                }
                        } catch (Exception e) {
-                               if (e is CompletionResult || rc.Report.IsDisabled || e is FatalException)
+                               if (e is CompletionResult || rc.Report.IsDisabled || e is FatalException || rc.Report.Printer is NullReportPrinter)
                                        throw;
 
                                if (rc.CurrentBlock != null) {
@@ -3423,8 +3450,23 @@ namespace Mono.CSharp {
                        int count = parameters.Count;
                        Arguments args = new Arguments (count);
                        for (int i = 0; i < count; ++i) {
-                               var arg_expr = GetParameterReference (i, parameter_info[i].Location);
-                               args.Add (new Argument (arg_expr));
+                               var pi = parameter_info[i];
+                               var arg_expr = GetParameterReference (i, pi.Location);
+
+                               Argument.AType atype_modifier;
+                               switch (pi.Parameter.ParameterModifier & Parameter.Modifier.RefOutMask) {
+                               case Parameter.Modifier.REF:
+                                       atype_modifier = Argument.AType.Ref;
+                                       break;
+                               case Parameter.Modifier.OUT:
+                                       atype_modifier = Argument.AType.Out;
+                                       break;
+                               default:
+                                       atype_modifier = 0;
+                                       break;
+                               }
+
+                               args.Add (new Argument (arg_expr, atype_modifier));
                        }
 
                        return args;
@@ -3671,7 +3713,7 @@ namespace Mono.CSharp {
                                return true;
                        }
 
-                       converted = c.ImplicitConversionRequired (rc, rc.Switch.SwitchType, loc);
+                       converted = c.ImplicitConversionRequired (rc, rc.Switch.SwitchType);
                        return converted != null;
                }
 
@@ -4168,9 +4210,13 @@ namespace Mono.CSharp {
                        var ok = block.Resolve (ec);
 
                        if (case_default == null)
-                               ec.CurrentBranching.CurrentUsageVector.ResetBarrier ();
+                               ec.CurrentBranching.CreateSibling (null, FlowBranching.SiblingType.SwitchSection);
+
+                       if (ec.IsUnreachable)
+                               ec.KillFlowBranching ();
+                       else
+                               ec.EndFlowBranching ();
 
-                       ec.EndFlowBranching ();
                        ec.Switch = old_switch;
 
                        //
@@ -4321,7 +4367,9 @@ namespace Mono.CSharp {
 
                                if (!unreachable_reported) {
                                        unreachable_reported = true;
-                                       bc.Report.Warning (162, 2, s.loc, "Unreachable code detected");
+                                       if (!bc.IsUnreachable) {
+                                               bc.Report.Warning (162, 2, s.loc, "Unreachable code detected");
+                                       }
                                }
 
                                block.Statements[i] = new EmptyStatement (s.loc);
@@ -5080,7 +5128,7 @@ namespace Mono.CSharp {
                {
                        LocalVariable pinned_string;
 
-                       public StringEmitter (Expression expr, LocalVariable li, Location loc)
+                       public StringEmitter (Expression expr, LocalVariable li)
                                : base (expr, li)
                        {
                        }
@@ -5203,7 +5251,7 @@ namespace Mono.CSharp {
                                // Case 2: string
                                //
                                if (initializer.Type.BuiltinType == BuiltinTypeSpec.Type.String) {
-                                       return new StringEmitter (initializer, li, loc).Resolve (bc);
+                                       return new StringEmitter (initializer, li).Resolve (bc);
                                }
 
                                // Case 3: fixed buffer
@@ -5495,7 +5543,7 @@ namespace Mono.CSharp {
                {
                        TryFinally target = (TryFinally) t;
 
-                       target.stmt = (Statement) stmt.Clone (clonectx);
+                       target.stmt = stmt.Clone (clonectx);
                        if (fini != null)
                                target.fini = clonectx.LookupBlock (fini);
                }
@@ -6446,14 +6494,20 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       variable.CreateBuilder (ec);
-
                        Label old_begin = ec.LoopBegin, old_end = ec.LoopEnd;
                        ec.LoopBegin = ec.DefineLabel ();
                        ec.LoopEnd = ec.DefineLabel ();
 
+                       if (!(statement is Block))
+                               ec.BeginCompilerScope ();
+
+                       variable.CreateBuilder (ec);
+
                        statement.Emit (ec);
 
+                       if (!(statement is Block))
+                               ec.EndScope ();
+
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }