/// <summary>
/// Resolves the statement, true means that all sub-statements
/// did resolve ok.
- // </summary>
+ /// </summary>
public virtual bool Resolve (BlockContext bc)
{
return true;
return false;
empty = true;
return true;
- } else
- infinite = true;
+ }
+
+ infinite = true;
}
ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
return false;
empty = true;
return true;
- } else
- infinite = true;
+ }
+
+ infinite = true;
}
} else
infinite = true;
public class StatementErrorExpression : Statement
{
- readonly Expression expr;
+ Expression expr;
public StatementErrorExpression (Expression expr)
{
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)
public StatementList (Statement first, Statement second)
{
- statements = new List<Statement> () { first, second };
+ statements = new List<Statement> { first, second };
}
#region Properties
}
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;
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;
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) {
}
if (parent_storey_block.AnonymousMethodStorey == null) {
- pb.StateMachine.AddCapturedThisField (ec);
+ pb.StateMachine.AddCapturedThisField (ec, null);
b.HasCapturedThis = true;
continue;
}
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);
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) {
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;
return true;
}
- converted = c.ImplicitConversionRequired (rc, rc.Switch.SwitchType, loc);
+ converted = c.ImplicitConversionRequired (rc, rc.Switch.SwitchType);
return converted != null;
}
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;
//
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);
{
LocalVariable pinned_string;
- public StringEmitter (Expression expr, LocalVariable li, Location loc)
+ public StringEmitter (Expression expr, LocalVariable li)
: base (expr, li)
{
}
// 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
{
TryFinally target = (TryFinally) t;
- target.stmt = (Statement) stmt.Clone (clonectx);
+ target.stmt = stmt.Clone (clonectx);
if (fini != null)
target.fini = clonectx.LookupBlock (fini);
}
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;
}