public override bool Resolve (BlockContext ec) { bool ok = true; ec.StartFlowBranching (this); if (!Block.Resolve (ec)) ok = false; TypeSpec[] prev_catches = new TypeSpec [Specific.Count]; int last_index = 0; foreach (Catch c in Specific){ ec.CurrentBranching.CreateSibling (c.Block, FlowBranching.SiblingType.Catch); if (!c.Resolve (ec)) { ok = false; continue; } TypeSpec resolved_type = c.CatchType; for (int ii = 0; ii < last_index; ++ii) { if (resolved_type == prev_catches[ii] || TypeSpec.IsBaseClass (resolved_type, prev_catches[ii], true)) { ec.Report.Error (160, c.loc, "A previous catch clause already catches all exceptions of this or a super type `{0}'", TypeManager.CSharpName (prev_catches [ii])); ok = false; } } prev_catches [last_index++] = resolved_type; } if (General != null) { if (CodeGen.Assembly.WrapNonExceptionThrows) { foreach (Catch c in Specific){ if (c.CatchType == TypeManager.exception_type && ec.Compiler.PredefinedAttributes.RuntimeCompatibility.IsDefined) { ec.Report.Warning (1058, 1, c.loc, "A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a `System.Runtime.CompilerServices.RuntimeWrappedException'"); } } } ec.CurrentBranching.CreateSibling (General.Block, FlowBranching.SiblingType.Catch); if (!General.Resolve (ec)) ok = false; } ec.EndFlowBranching (); // System.Reflection.Emit automatically emits a 'leave' at the end of a try/catch clause // So, ensure there's some IL code after this statement if (!inside_try_finally && !code_follows && ec.CurrentBranching.CurrentUsageVector.IsUnreachable) ec.NeedReturnLabel (); return ok; }
public sealed override bool Resolve (BlockContext ec) { if (!DoResolve (ec)) return false; unwind_protect = ec.CurrentBranching.AddReturnOrigin (ec.CurrentBranching.CurrentUsageVector, this); if (unwind_protect) ec.NeedReturnLabel (); ec.CurrentBranching.CurrentUsageVector.Goto (); return true; }
public override bool Resolve (BlockContext ec) { // System.Reflection.Emit automatically emits a 'leave' at the end of a try clause // So, ensure there's some IL code after this statement. if (!code_follows && resume_points == null && ec.CurrentBranching.CurrentUsageVector.IsUnreachable) ec.NeedReturnLabel (); iter = ec.CurrentIterator; return true; }