Browse Source
Added custom Ast classes for Goto and Label statements that track the reference count of a label.
Added custom Ast classes for Goto and Label statements that track the reference count of a label.
Added an Ast transform to remove dead labels. (first Ast transform in program, I expect many more to come. Some stuff should be rewritten to use these explicit transforms)pull/1/head^2

6 changed files with 119 additions and 28 deletions
-
6Decompiler.csproj
-
29src/AstMetodBodyBuilder.cs
-
32src/ControlFlow/Node-Structure.cs
-
40src/MyAst/MyGotoStatement.cs
-
21src/MyAst/MyLabelStatement.cs
-
19src/Transforms/Ast/RemoveDeadLabels.cs
@ -0,0 +1,40 @@ |
|||
using System; |
|||
|
|||
using Ast = ICSharpCode.NRefactory.Ast; |
|||
using Decompiler.ControlFlow; |
|||
|
|||
namespace ICSharpCode.NRefactory.Ast |
|||
{ |
|||
public class MyGotoStatement: Ast.GotoStatement |
|||
{ |
|||
NodeLabel nodeLabel; |
|||
|
|||
public NodeLabel NodeLabel { |
|||
get { return nodeLabel; } |
|||
} |
|||
|
|||
public MyGotoStatement(NodeLabel nodeLabel): base(nodeLabel.Label) |
|||
{ |
|||
this.nodeLabel = nodeLabel; |
|||
|
|||
this.nodeLabel.ReferenceCount++; |
|||
} |
|||
|
|||
public static Ast.Statement Create(Node contextNode, Node targetNode) |
|||
{ |
|||
// Propagate target up to the top most scope
|
|||
while (targetNode.Parent != null && targetNode.Parent.HeadChild == targetNode) { |
|||
targetNode = targetNode.Parent; |
|||
} |
|||
// If branches to the start of encapsulating loop
|
|||
if (contextNode.Parent is Loop && targetNode == contextNode.Parent) { |
|||
return new Ast.ContinueStatement(); |
|||
} |
|||
// If branches outside the encapsulating loop
|
|||
if (contextNode.Parent is Loop && targetNode == contextNode.Parent.NextNode) { |
|||
return new Ast.BreakStatement(); |
|||
} |
|||
return new Ast.MyGotoStatement(targetNode.Label); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
using System; |
|||
|
|||
using Ast = ICSharpCode.NRefactory.Ast; |
|||
using Decompiler.ControlFlow; |
|||
|
|||
namespace ICSharpCode.NRefactory.Ast |
|||
{ |
|||
public class MyLabelStatement: Ast.LabelStatement |
|||
{ |
|||
NodeLabel nodeLabel; |
|||
|
|||
public NodeLabel NodeLabel { |
|||
get { return nodeLabel; } |
|||
} |
|||
|
|||
public MyLabelStatement(NodeLabel nodeLabel): base(nodeLabel.Label) |
|||
{ |
|||
this.nodeLabel = nodeLabel; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,19 @@ |
|||
using System; |
|||
|
|||
using ICSharpCode.NRefactory.Ast; |
|||
using ICSharpCode.NRefactory.Visitors; |
|||
|
|||
namespace Decompiler.Transforms.Ast |
|||
{ |
|||
public class RemoveDeadLabels: AbstractAstTransformer |
|||
{ |
|||
public override object VisitLabelStatement(LabelStatement labelStatement, object data) |
|||
{ |
|||
MyLabelStatement myLabel = (MyLabelStatement)labelStatement; |
|||
if (myLabel.NodeLabel.ReferenceCount == 0) { |
|||
RemoveCurrentNode(); |
|||
} |
|||
return null; |
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue