diff --git a/Decompiler.csproj b/Decompiler.csproj
index 0e5aa019b..b62aa1fa6 100644
--- a/Decompiler.csproj
+++ b/Decompiler.csproj
@@ -66,6 +66,7 @@
+
diff --git a/src/AstBuilder.cs b/src/AstBuilder.cs
index 36bedee71..94d86d32f 100644
--- a/src/AstBuilder.cs
+++ b/src/AstBuilder.cs
@@ -28,6 +28,8 @@ namespace Decompiler
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.SimplifyTypeReferences(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null);
+ astCompileUnit.AcceptVisitor(new Transforms.Ast.RestoreLoop(), null);
+ astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
astCompileUnit.AcceptVisitor(csOutVisitor, null);
diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs
index bb5cb9ff0..8cf8cc2f2 100644
--- a/src/AstMetodBodyBuilder.cs
+++ b/src/AstMetodBodyBuilder.cs
@@ -86,11 +86,11 @@ namespace Decompiler
} else if (node is Loop) {
Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement();
blockStatement.Children.AddRange(TransformNodes(node.Childs));
- yield return new Ast.DoLoopStatement(
- new Ast.PrimitiveExpression(true, true.ToString()),
- blockStatement,
- ConditionType.While,
- ConditionPosition.Start
+ yield return new Ast.ForStatement(
+ null,
+ null,
+ null,
+ blockStatement
);
} else if (node is Block) {
foreach(Ast.INode inode in TransformNodes(node.Childs)) {
diff --git a/src/Transforms/Ast/RemoveGotos.cs b/src/Transforms/Ast/RemoveGotos.cs
index cea72cfdb..1062f1bfb 100644
--- a/src/Transforms/Ast/RemoveGotos.cs
+++ b/src/Transforms/Ast/RemoveGotos.cs
@@ -13,13 +13,20 @@ namespace Decompiler.Transforms.Ast
// Remove redundant jump at the end of block
INode lastStmt = blockStatement.Children[blockStatement.Children.Count - 1];
- // End of loop
+ // End of while loop
if (lastStmt is ContinueStatement &&
blockStatement.Parent is DoLoopStatement)
{
blockStatement.Children.Remove(lastStmt);
return null;
}
+ // End of for loop
+ if (lastStmt is ContinueStatement &&
+ blockStatement.Parent is ForStatement)
+ {
+ blockStatement.Children.Remove(lastStmt);
+ return null;
+ }
// End of method
if (lastStmt is ReturnStatement &&
blockStatement.Parent is MethodDeclaration &&
diff --git a/src/Transforms/Ast/RestoreLoop.cs b/src/Transforms/Ast/RestoreLoop.cs
new file mode 100644
index 000000000..77f8a8c6e
--- /dev/null
+++ b/src/Transforms/Ast/RestoreLoop.cs
@@ -0,0 +1,38 @@
+using System;
+
+using Ast = ICSharpCode.NRefactory.Ast;
+using ICSharpCode.NRefactory.Ast;
+using ICSharpCode.NRefactory.Visitors;
+
+namespace Decompiler.Transforms.Ast
+{
+ public class RestoreLoop: AbstractAstTransformer
+ {
+ public override object VisitForStatement(ForStatement forStatement, object data)
+ {
+ base.VisitForStatement(forStatement, data);
+
+ if (forStatement.Condition.IsNull &&
+ forStatement.EmbeddedStatement.Children.Count >= 3)
+ {
+ IfElseStatement condition = forStatement.EmbeddedStatement.Children[0] as IfElseStatement;
+ BreakStatement breakStmt = forStatement.EmbeddedStatement.Children[1] as BreakStatement;
+ MyLabelStatement label = forStatement.EmbeddedStatement.Children[2] as MyLabelStatement;
+ if (condition != null &&
+ breakStmt != null &&
+ label != null &&
+ condition.TrueStatement.Count == 1)
+ {
+ MyGotoStatement gotoStmt = condition.TrueStatement[0] as MyGotoStatement;
+ if (gotoStmt != null && gotoStmt.NodeLabel == label.NodeLabel) {
+ forStatement.EmbeddedStatement.Children.RemoveAt(0);
+ forStatement.EmbeddedStatement.Children.RemoveAt(0);
+ gotoStmt.NodeLabel.ReferenceCount--;
+ forStatement.Condition = condition.Condition;
+ }
+ }
+ }
+ return null;
+ }
+ }
+}