diff --git a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs index 7c7be5344..37589c1c4 100644 --- a/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs @@ -289,6 +289,32 @@ namespace ICSharpCode.Decompiler.CSharp VisitAsSequencePoint(fixedStatement.EmbeddedStatement); } + public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement) + { + VisitAsSequencePoint(tryCatchStatement.TryBlock); + foreach (var c in tryCatchStatement.CatchClauses) { + VisitAsSequencePoint(c); + } + VisitAsSequencePoint(tryCatchStatement.FinallyBlock); + } + + public override void VisitCatchClause(CatchClause catchClause) + { + if (catchClause.Condition.IsNull) { + StartSequencePoint(catchClause.CatchToken); + var function = catchClause.Ancestors.OfType().FirstOrDefault(); + AddToSequencePointRaw(function, new[] { catchClause.Annotation().ExceptionSpecifierILRange }); + EndSequencePoint(catchClause.CatchToken.StartLocation, catchClause.RParToken.IsNull ? catchClause.CatchToken.EndLocation : catchClause.RParToken.EndLocation); + } else { + StartSequencePoint(catchClause.WhenToken); + AddToSequencePoint(catchClause.Condition); + EndSequencePoint(catchClause.WhenToken.StartLocation, catchClause.CondRParToken.EndLocation); + } + StartSequencePoint(catchClause); + catchClause.Body.AcceptVisitor(this); + EndSequencePoint(catchClause.StartLocation, catchClause.EndLocation); + } + /// /// Start a new C# statement = new sequence point. /// @@ -318,6 +344,13 @@ namespace ICSharpCode.Decompiler.CSharp current = outerStates.Pop(); } + void AddToSequencePointRaw(ILFunction function, IEnumerable ranges) + { + current.Intervals.AddRange(ranges); + Debug.Assert(current.Function == null || current.Function == function); + current.Function = function; + } + /// /// Add the ILAst instruction associated with the AstNode to the sequence point. /// Also add all its ILAst sub-instructions (unless they were already added to another sequence point). diff --git a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs index ae6eb6c7d..488311f88 100644 --- a/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/StatementBuilder.cs @@ -363,6 +363,7 @@ namespace ICSharpCode.Decompiler.CSharp tryCatch.TryBlock = ConvertAsBlock(inst.TryBlock); foreach (var handler in inst.Handlers) { var catchClause = new CatchClause(); + catchClause.AddAnnotation(handler); var v = handler.Variable; if (v != null) { catchClause.AddAnnotation(new ILVariableResolveResult(v, v.Type)); diff --git a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs index 061ee7721..7d9d411f1 100644 --- a/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs +++ b/ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs @@ -692,7 +692,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms TransformCatchWhen(inst, filterContainer.EntryPoint); } if (inst.Body is BlockContainer catchContainer) - TransformCatchVariable(inst, catchContainer.EntryPoint); + TransformCatchVariable(inst, catchContainer.EntryPoint, isCatchBlock: true); } /// @@ -709,7 +709,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// } /// } /// - void TransformCatchVariable(TryCatchHandler handler, Block entryPoint) + void TransformCatchVariable(TryCatchHandler handler, Block entryPoint, bool isCatchBlock) { if (!handler.Variable.IsSingleDefinition || handler.Variable.LoadCount != 1) return; // handle.Variable already has non-trivial uses @@ -754,7 +754,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms /// void TransformCatchWhen(TryCatchHandler handler, Block entryPoint) { - TransformCatchVariable(handler, entryPoint); + TransformCatchVariable(handler, entryPoint, isCatchBlock: false); if (entryPoint.Instructions.Count == 1 && entryPoint.Instructions[0].MatchLeave(out _, out var condition)) { context.Step("TransformCatchWhen", entryPoint.Instructions[0]); handler.Filter = condition;