diff --git a/Decompiler.csproj b/Decompiler.csproj
index eda362fbd..8cb0cef3c 100644
--- a/Decompiler.csproj
+++ b/Decompiler.csproj
@@ -55,6 +55,7 @@
+
@@ -63,6 +64,7 @@
+
MainForm.cs
diff --git a/Decompiler.sln b/Decompiler.sln
index ae4af9b72..d0132cdfb 100644
--- a/Decompiler.sln
+++ b/Decompiler.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
-# SharpDevelop 3.0.0.2909
+# SharpDevelop 3.0.0.2914
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decompiler", "Decompiler.csproj", "{EE3A3C1A-F9C3-4C75-853D-A9476E518C3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "lib\cecil-0.6\src\Mono.Cecil\Mono.Cecil.csproj", "{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}"
diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs
index 0e5659825..6232f642b 100644
--- a/src/AstMetodBodyBuilder.cs
+++ b/src/AstMetodBodyBuilder.cs
@@ -18,16 +18,16 @@ namespace Decompiler
static Dictionary localVarTypes = new Dictionary();
static Dictionary localVarDefined = new Dictionary();
- public static BlockStatement CreateMetodBody(MethodDefinition methodDef)
+ public static MyBlockStatement CreateMetodBody(MethodDefinition methodDef)
{
AstMetodBodyBuilder builder = new AstMetodBodyBuilder();
builder.methodDef = methodDef;
return builder.CreateMetodBody();
}
- public BlockStatement CreateMetodBody()
+ public MyBlockStatement CreateMetodBody()
{
- Ast.BlockStatement astBlock = new Ast.BlockStatement();
+ Ast.MyBlockStatement astBlock = new Ast.MyBlockStatement();
methodDef.Body.Simplify();
@@ -50,6 +50,7 @@ namespace Decompiler
astBlock.Children.AddRange(TransformNodes(bodyGraph.Childs));
+ astBlock.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null);
astBlock.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
return astBlock;
@@ -78,15 +79,15 @@ namespace Decompiler
}
Node fallThroughNode = ((BasicBlock)node).FallThroughBasicBlock;
// If there is default branch and it is not the following node
- if (fallThroughNode != null && fallThroughNode != node.NextNode) {
+ if (fallThroughNode != null) {
yield return Ast.MyGotoStatement.Create(node, fallThroughNode);
}
} else if (node is AcyclicGraph) {
- Ast.BlockStatement blockStatement = new Ast.BlockStatement();
+ Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement();
blockStatement.Children.AddRange(TransformNodes(node.Childs));
yield return blockStatement;
} else if (node is Loop) {
- Ast.BlockStatement blockStatement = new Ast.BlockStatement();
+ Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement();
blockStatement.Children.AddRange(TransformNodes(node.Childs));
yield return new Ast.DoLoopStatement(
new Ast.PrimitiveExpression(true, true.ToString()),
@@ -112,14 +113,14 @@ namespace Decompiler
// Swap the method bodies
ifElseStmt.Condition = new Ast.UnaryOperatorExpression(new Ast.ParenthesizedExpression(ifElseStmt.Condition), UnaryOperatorType.Not);
- Ast.BlockStatement trueBlock = new Ast.BlockStatement();
+ Ast.MyBlockStatement trueBlock = new Ast.MyBlockStatement();
// The block entry code
trueBlock.Children.Add(Ast.MyGotoStatement.Create(node, conditionalNode.Condition.FallThroughBasicBlock));
// Sugested content
trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody));
ifElseStmt.TrueStatement.Add(trueBlock);
- Ast.BlockStatement falseBlock = new Ast.BlockStatement();
+ Ast.MyBlockStatement falseBlock = new Ast.MyBlockStatement();
// The block entry code
falseBlock.Children.Add(oldTrueBody);
// Sugested content
diff --git a/src/MyAst/MyBlockStatement.cs b/src/MyAst/MyBlockStatement.cs
new file mode 100644
index 000000000..64d5145ee
--- /dev/null
+++ b/src/MyAst/MyBlockStatement.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+
+using Ast = ICSharpCode.NRefactory.Ast;
+using Decompiler.ControlFlow;
+
+namespace ICSharpCode.NRefactory.Ast
+{
+ public class MyBlockStatement: BlockStatement
+ {
+ ChildrenCollection wrapper;
+
+ public class ChildrenCollection: System.Collections.ObjectModel.Collection
+ {
+ MyBlockStatement myStmt;
+
+ public void AddRange(IEnumerable items)
+ {
+ foreach(INode node in items) {
+ Add(node);
+ }
+ }
+
+ protected override void InsertItem(int index, INode item)
+ {
+ item.Parent = myStmt;
+ base.InsertItem(index, item);
+ }
+
+ protected override void SetItem(int index, INode item)
+ {
+ item.Parent = myStmt;
+ base.SetItem(index, item);
+ }
+
+ public ChildrenCollection(MyBlockStatement myStmt, IList nodes): base(nodes)
+ {
+ this.myStmt = myStmt;
+ }
+ }
+
+ public new ChildrenCollection Children {
+ get {
+ return wrapper;
+ }
+ }
+
+ public MyBlockStatement()
+ {
+ this.wrapper = new ChildrenCollection(this, base.Children);
+ }
+ }
+}
diff --git a/src/Transforms/Ast/RemoveGotos.cs b/src/Transforms/Ast/RemoveGotos.cs
new file mode 100644
index 000000000..7290b36eb
--- /dev/null
+++ b/src/Transforms/Ast/RemoveGotos.cs
@@ -0,0 +1,26 @@
+using System;
+
+using ICSharpCode.NRefactory.Ast;
+using ICSharpCode.NRefactory.Visitors;
+
+namespace Decompiler.Transforms.Ast
+{
+ public class RemoveGotos: AbstractAstTransformer
+ {
+ public override object VisitGotoStatement(GotoStatement gotoStatement, object data)
+ {
+ MyGotoStatement myGoto = (MyGotoStatement)gotoStatement;
+ if (gotoStatement.Parent == null) return null;
+ int index = gotoStatement.Parent.Children.IndexOf(gotoStatement);
+ if (index + 1 < gotoStatement.Parent.Children.Count) {
+ INode nextStmt = gotoStatement.Parent.Children[index + 1];
+ MyLabelStatement myLabel = nextStmt as MyLabelStatement;
+ if (myLabel != null && myLabel.NodeLabel == myGoto.NodeLabel) {
+ myGoto.NodeLabel.ReferenceCount--;
+ RemoveCurrentNode();
+ }
+ }
+ return null;
+ }
+ }
+}