protected virtual BoundStatement RewriteBlockStatement(BoundBlockStatement node) { ImmutableArray <BoundStatement> .Builder builder = null; for (int i = 0; i < node.Statements.Length; i++) { var oldStatement = node.Statements[i]; var newStatement = RewriteStatement(oldStatement); if (newStatement != oldStatement) { if (builder == null) { builder = ImmutableArray.CreateBuilder <BoundStatement>(node.Statements.Length); for (int j = 0; j < i; j++) { builder.Add(node.Statements[j]); } } } if (builder != null) { builder.Add(newStatement); } } if (builder == null) { return(node); } return(new BoundBlockStatement(builder.MoveToImmutable())); }
public List <BasicBlock> Build(BoundBlockStatement block) { foreach (var statement in block.Statements) { switch (statement.Kind) { case BoundNodeKind.LabelStatement: StartBlock(); _statements.Add(statement); break; case BoundNodeKind.GotoStatement: case BoundNodeKind.ConditionalGotoStatement: case BoundNodeKind.ReturnStatement: _statements.Add(statement); StartBlock(); break; case BoundNodeKind.ExpressionStatement: case BoundNodeKind.VariableDeclaration: _statements.Add(statement); break; default: throw new Exception($"Unexpected statement: {statement.Kind}."); } } EndBlock(); return(_blocks.ToList()); }
public static ControlFlowGraph Create(BoundBlockStatement body) { var basicBlockBuilder = new BasicBlockBuilder(); var blocks = basicBlockBuilder.Build(body); var graphBuilder = new GraphBuilder(); return(graphBuilder.Build(blocks)); }
private static void WriteBlockStatement(BoundBlockStatement node, IndentedTextWriter writer) { writer.WritePunctuation(SyntaxKind.OpenBraceToken); writer.WriteLine(); writer.Indent++; foreach (var s in node.Statements) { s.WriteTo(writer); } writer.Indent--; writer.WritePunctuation(SyntaxKind.CloseBraceToken); writer.WriteLine(); }
public static bool AllPathsReturn(BoundBlockStatement body) { var graph = Create(body); foreach (var branch in graph.End.Incoming) { var lastStatement = branch.From.Statements.LastOrDefault(); if (lastStatement == null || lastStatement.Kind != BoundNodeKind.ReturnStatement) { return(false); } } return(true); }