is_true_ret = ec.CurrentBranching.CurrentUsageVector.Reachability.IsUnreachable;
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Conditional);
+ ec.CurrentBranching.CreateSibling ();
if ((FalseStatement != null) && !FalseStatement.Resolve (ec))
ok = false;
ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
if (!infinite)
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Conditional);
+ ec.CurrentBranching.CreateSibling ();
if (!Statement.Resolve (ec))
ok = false;
if (Expr != null) {
Expr.Emit (ec);
- if (in_exc || !ec.IsLastStatement)
+ if (in_exc)
ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
}
if (in_exc) {
ec.NeedReturnLabel ();
ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
- } else if (ec.IsLastStatement) {
- // If we are the last statement in a top-level block, simply
- // emit a `ret'.
- ec.ig.Emit (OpCodes.Ret);
} else {
- // Otherwise, we always create a return label and jump to
- // it.
- ec.NeedReturnLabel ();
- ec.ig.Emit (OpCodes.Br, ec.ReturnLabel);
+ ec.ig.Emit (OpCodes.Ret);
}
}
}
public override bool Resolve (EmitContext ec)
{
- label = block.LookupLabel (target);
- if (label == null){
- Report.Error (
- 159, loc,
- "No such label `" + target + "' in this scope");
+ label = ec.CurrentBranching.LookupLabel (target, loc);
+ if (label == null)
return false;
- }
// If this is a forward goto.
if (!label.IsDefined)
if (VariableType == null)
VariableType = decl.ResolveType (Type, false, Location);
+ if (VariableType == TypeManager.void_type) {
+ Report.Error (1547, Location,
+ "Keyword 'void' cannot be used in this context");
+ return false;
+ }
+
if (VariableType == null)
return false;
return switch_block.AddLabel (name, target, loc);
Block cur = this;
- while (cur != null && cur.Implicit) {
- if (cur.LookupLabel (name) != null) {
+ while (cur != null) {
+ if (cur.DoLookupLabel (name) != null) {
Report.Error (
140, loc, "The label '{0}' is a duplicate",
name);
return false;
}
+ if (!Implicit)
+ break;
+
cur = cur.Parent;
}
while (cur != null) {
- if (cur.LookupLabel (name) != null) {
+ if (cur.DoLookupLabel (name) != null) {
Report.Error (
158, loc,
"The label '{0}' shadows another label " +
return false;
}
+ if (children != null) {
+ foreach (Block b in children) {
+ LabeledStatement s = b.DoLookupLabel (name);
+ if (s == null)
+ continue;
+
+ Report.Error (
+ 158, s.Location,
+ "The label '{0}' shadows another " +
+ "label by the same name in a " +
+ "containing scope.",
+ name);
+ return false;
+ }
+ }
+
+
cur = cur.Parent;
}
public LabeledStatement LookupLabel (string name)
{
- Hashtable l = new Hashtable ();
-
- return LookupLabel (name, l);
+ LabeledStatement s = DoLookupLabel (name);
+ if (s != null)
+ return s;
+
+ if (children == null)
+ return null;
+
+ foreach (Block child in children) {
+ if (!child.Implicit)
+ continue;
+
+ s = child.LookupLabel (name);
+ if (s != null)
+ return s;
+ }
+
+ return null;
}
- //
- // Lookups a label in the current block, parents and children.
- // It skips during child recurssion on `source'
- //
- LabeledStatement LookupLabel (string name, Hashtable seen)
+ LabeledStatement DoLookupLabel (string name)
{
if (switch_block != null)
- return switch_block.LookupLabel (name, seen);
+ return switch_block.LookupLabel (name);
- if (seen [this] != null)
- return null;
-
- seen [this] = this;
-
if (labels != null)
if (labels.Contains (name))
return ((LabeledStatement) labels [name]);
- if (children != null){
- foreach (Block b in children){
- LabeledStatement s = b.LookupLabel (name, seen);
- if (s != null)
- return s;
- }
- }
-
- if (Parent != null)
- return Parent.LookupLabel (name, seen);
-
return null;
}
return e != null;
}
- /// <summary>
- /// Use to fetch the statement associated with this label
- /// </summary>
- public Statement this [string name] {
- get {
- return (Statement) labels [name];
- }
- }
-
Parameters parameters = null;
public Parameters Parameters {
get {
Statement s = (Statement) statements [ix];
if (unreachable && !(s is LabeledStatement)) {
+ if (s == EmptyStatement.Value)
+ s.loc = EndLocation;
+
if (!s.ResolveUnreachable (ec, !warning_shown))
ok = false;
if (s != EmptyStatement.Value)
warning_shown = true;
+ else
+ s.loc = Location.Null;
statements [ix] = EmptyStatement.Value;
continue;
bool first = true;
foreach (SwitchSection ss in Sections){
if (!first)
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.SwitchSection);
+ ec.CurrentBranching.CreateSibling (
+ null, FlowBranching.SiblingType.SwitchSection);
else
first = false;
if (!got_default)
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.SwitchSection);
+ ec.CurrentBranching.CreateSibling (
+ null, FlowBranching.SiblingType.SwitchSection);
FlowBranching.Reachability reachability = ec.EndFlowBranching ();
ec.Switch = old_switch;
Report.Debug (1, "START OF CATCH BLOCKS", vector);
foreach (Catch c in Specific){
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Catch);
+ ec.CurrentBranching.CreateSibling (
+ c.Block, FlowBranching.SiblingType.Catch);
+
Report.Debug (1, "STARTED SIBLING FOR CATCH", ec.CurrentBranching);
if (c.Name != null) {
Report.Debug (1, "END OF CATCH BLOCKS", ec.CurrentBranching);
if (General != null){
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Catch);
+ ec.CurrentBranching.CreateSibling (
+ General.Block, FlowBranching.SiblingType.Catch);
+
Report.Debug (1, "STARTED SIBLING FOR GENERAL", ec.CurrentBranching);
if (!General.Resolve (ec))
if (Fini != null) {
if (ok)
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Finally);
+ ec.CurrentBranching.CreateSibling (
+ Fini, FlowBranching.SiblingType.Finally);
+
Report.Debug (1, "STARTED SIBLING FOR FINALLY", ec.CurrentBranching, vector);
if (!Fini.Resolve (ec))
converted_vars [i].Emit (ec);
ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
} else {
- Expression ml = Expression.MemberLookup(ec, typeof(IDisposable), var.Type, "Dispose", Mono.CSharp.Location.Null);
+ Expression ml = Expression.MemberLookup(ec, TypeManager.idisposable_type, var.Type, "Dispose", Mono.CSharp.Location.Null);
if (!(ml is MethodGroupExpr)) {
var.Emit (ec);
bool ok = true;
ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
- ec.CurrentBranching.CreateSibling (FlowBranching.SiblingType.Conditional);
+ ec.CurrentBranching.CreateSibling ();
//
//
if (expr is IMemoryLocation){
IMemoryLocation ml = (IMemoryLocation) expr;
- ml.AddressOf (ec, AddressOp.Load);
+ Expression ml1 = Expression.MemberLookup(ec, TypeManager.ienumerator_type, expr.Type, "GetEnumerator", Mono.CSharp.Location.Null);
+
+ if (!(ml1 is MethodGroupExpr)) {
+ expr.Emit(ec);
+ ec.ig.Emit(OpCodes.Box, expr.Type);
+ } else {
+ ml.AddressOf (ec, AddressOp.Load);
+ }
} else
throw new Exception ("Expr " + expr + " of type " + expr.Type +
" does not implement IMemoryLocation");
- ig.Emit (OpCodes.Call, hm.get_enumerator);
+ ig.Emit (OpCodes.Callvirt, hm.get_enumerator);
} else {
expr.Emit (ec);
ig.Emit (OpCodes.Callvirt, hm.get_enumerator);