Cache only resolved types not expression to report correct error location. Fixes...
[mono.git] / mcs / mcs / statement.cs
index fd3133f9afeb7295da71cd4c9561acdd79dbbda4..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;
@@ -751,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
@@ -2583,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;
@@ -2608,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;
 
@@ -2625,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) {
@@ -2643,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;
                                                                }
@@ -3427,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;
@@ -3675,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;
                }
 
@@ -4174,7 +4212,11 @@ namespace Mono.CSharp {
                        if (case_default == null)
                                ec.CurrentBranching.CreateSibling (null, FlowBranching.SiblingType.SwitchSection);
 
-                       ec.EndFlowBranching ();
+                       if (ec.IsUnreachable)
+                               ec.KillFlowBranching ();
+                       else
+                               ec.EndFlowBranching ();
+
                        ec.Switch = old_switch;
 
                        //
@@ -4325,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);
@@ -5084,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)
                        {
                        }
@@ -5207,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