public override bool Resolve (BlockContext ec)
{
Block variables_block = variable.local_info.Block;
copy = TemporaryVariableReference.Create (for_each.expr.Type, variables_block, loc);
copy.Resolve (ec);
int rank = length_exprs.Length;
Arguments list = new Arguments (rank);
for (int i = 0; i < rank; i++) {
var v = TemporaryVariableReference.Create (TypeManager.int32_type, variables_block, loc);
variables[i] = v;
counter[i] = new StatementExpression (new UnaryMutator (UnaryMutator.Mode.PostIncrement, v, loc));
counter[i].Resolve (ec);
if (rank == 1) {
length_exprs [i] = new MemberAccess (copy, "Length").Resolve (ec);
} else {
lengths[i] = TemporaryVariableReference.Create (TypeManager.int32_type, variables_block, loc);
lengths[i].Resolve (ec);
Arguments args = new Arguments (1);
args.Add (new Argument (new IntConstant (i, loc)));
length_exprs [i] = new Invocation (new MemberAccess (copy, "GetLength"), args).Resolve (ec);
}
list.Add (new Argument (v));
}
access = new ElementAccess (copy, list, loc).Resolve (ec);
if (access == null)
return false;
Expression var_type = for_each.type;
VarExpr ve = var_type as VarExpr;
if (ve != null) {
// Infer implicitly typed local variable from foreach array type
var_type = new TypeExpression (access.Type, ve.Location);
}
var_type = var_type.ResolveAsTypeTerminal (ec, false);
if (var_type == null)
return false;
conv = Convert.ExplicitConversion (ec, access, var_type.Type, loc);
if (conv == null)
return false;
bool ok = true;
ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
ec.CurrentBranching.CreateSibling ();
variable.local_info.Type = conv.Type;
variable.Resolve (ec);
ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc);
if (!statement.Resolve (ec))
ok = false;
ec.EndFlowBranching ();
// There's no direct control flow from the end of the embedded statement to the end of the loop
ec.CurrentBranching.CurrentUsageVector.Goto ();
ec.EndFlowBranching ();
return ok;
}