Browse Source

Add TryCatchHandler annotation to CatchClause

pull/1920/head
Siegfried Pammer 5 years ago
parent
commit
ba5c645257
  1. 33
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  2. 1
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  3. 6
      ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

33
ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

@ -289,6 +289,32 @@ namespace ICSharpCode.Decompiler.CSharp @@ -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<ILFunction>().FirstOrDefault();
AddToSequencePointRaw(function, new[] { catchClause.Annotation<TryCatchHandler>().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);
}
/// <summary>
/// Start a new C# statement = new sequence point.
/// </summary>
@ -318,6 +344,13 @@ namespace ICSharpCode.Decompiler.CSharp @@ -318,6 +344,13 @@ namespace ICSharpCode.Decompiler.CSharp
current = outerStates.Pop();
}
void AddToSequencePointRaw(ILFunction function, IEnumerable<Interval> ranges)
{
current.Intervals.AddRange(ranges);
Debug.Assert(current.Function == null || current.Function == function);
current.Function = function;
}
/// <summary>
/// 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).

1
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -363,6 +363,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -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));

6
ICSharpCode.Decompiler/IL/Transforms/ExpressionTransforms.cs

@ -692,7 +692,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -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);
}
/// <summary>
@ -709,7 +709,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -709,7 +709,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// }
/// }
/// </summary>
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 @@ -754,7 +754,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// </summary>
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;

Loading…
Cancel
Save