diff --git a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index b7e0d9a0f..51332c5f5 100644 --- a/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -151,12 +151,20 @@ namespace Decompiler */ } else if (node is ILCondition) { ILCondition conditionalNode = (ILCondition)node; - // Swap bodies - yield return new Ast.IfElseStatement { - Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, MakeBranchCondition(conditionalNode.Condition)), - TrueStatement = TransformBlock(conditionalNode.FalseBlock), - FalseStatement = TransformBlock(conditionalNode.TrueBlock) - }; + if (conditionalNode.FalseBlock.Body.Any()) { + // Swap bodies + yield return new Ast.IfElseStatement { + Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, MakeBranchCondition(conditionalNode.Condition)), + TrueStatement = TransformBlock(conditionalNode.FalseBlock), + FalseStatement = TransformBlock(conditionalNode.TrueBlock) + }; + } else { + yield return new Ast.IfElseStatement { + Condition = MakeBranchCondition(conditionalNode.Condition), + TrueStatement = TransformBlock(conditionalNode.TrueBlock), + FalseStatement = TransformBlock(conditionalNode.FalseBlock) + }; + } } else if (node is ILTryCatchBlock) { ILTryCatchBlock tryCatchNode = ((ILTryCatchBlock)node); List catchClauses = new List(); diff --git a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs index c3e3e7e1b..8ac3f29f3 100644 --- a/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs +++ b/ICSharpCode.Decompiler/ILAst/ILAstOptimizer.cs @@ -14,18 +14,20 @@ namespace Decompiler.ControlFlow public void Optimize(ILBlock method) { - var blocks = method.GetSelfAndChildrenRecursive().ToList(); + foreach(ILBlock block in method.GetSelfAndChildrenRecursive().ToList()) { + SplitToMovableBlocks(block); + } - foreach(ILBlock block in blocks) { + foreach(ILBlock block in method.GetSelfAndChildrenRecursive().Where(b => !(b is ILMoveableBlock)).ToList()) { ControlFlowGraph graph; - - SplitToMovableBlocks(block); - graph = BuildGraph(block.Body, block.EntryPoint); graph.ComputeDominance(); graph.ComputeDominanceFrontier(); block.Body = FindLoops(new HashSet(graph.Nodes.Skip(3)), graph.EntryPoint); - + } + + foreach(ILBlock block in method.GetSelfAndChildrenRecursive().Where(b => !(b is ILMoveableBlock)).ToList()) { + ControlFlowGraph graph; graph = BuildGraph(block.Body, block.EntryPoint); graph.ComputeDominance(); graph.ComputeDominanceFrontier(); @@ -153,7 +155,7 @@ namespace Decompiler.ControlFlow return new ControlFlowGraph(cfNodes.ToArray()); } - static List FindLoops(HashSet nodes, ControlFlowNode entryPoint) + List FindLoops(HashSet nodes, ControlFlowNode entryPoint) { List result = new List(); @@ -171,7 +173,9 @@ namespace Decompiler.ControlFlow // Move the content into loop block nodes.ExceptWith(loopContents); - result.Add(new ILLoop() { ContentBlock = new ILBlock(FindLoops(loopContents, node)) }); + ILLabel entryLabel = new ILLabel() { Name = "Loop_" + (nextBlockIndex++) }; + ((ILBlock)node.UserData).Body.Insert(0, entryLabel); + result.Add(new ILLoop() { ContentBlock = new ILBlock(FindLoops(loopContents, node)) { EntryPoint = entryLabel } }); } // Using the dominator tree should ensure we find the the widest loop first