public static bool AllPathsReturn(BoundBlockStatement body) { var graph = Create(body); if (!graph.End.Incoming.Any()) { return(false); } foreach (var branch in graph.End.Incoming) { if (!branch.From.Statements.Any()) { return(false); } var last = branch.From.Statements.Last(); if (last.Kind != BoundNodeKind.ReturnStatement) { return(false); } } return(true); }
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.NopStatement: case BoundNodeKind.VariableDeclaration: case BoundNodeKind.ExpressionStatement: _statements.Add(statement); break; default: throw new Exception($"Unexpected statement: {statement.Kind}"); } } EndBlock(); return(_blocks.ToList()); }
protected virtual BoundStatement RewriteBlockStatement(BoundBlockStatement node) { ImmutableArray <BoundStatement> .Builder builder = null; for (var 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 (var 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 static ControlFlowGraph Create(BoundBlockStatement body) { var blocks = AtomicBlockBuilder.Build(body); var graph = ControlFlowGraphBuilder.Build(blocks); return(graph); }
public static ControlFlowGraph Create(BoundBlockStatement body) { var basicBlockBuilder = new BasicBlockBuilder(); var blocks = basicBlockBuilder.Build(body); var graphBuilder = new GraphBuilder(); return(graphBuilder.Build(blocks)); }
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); }
private static void WriteBlockStatement(BoundBlockStatement node, IndentedTextWriter writer) { writer.WritePunctuation(SyntaxKind.OpenBraceToken); writer.WriteLine(); writer.Indent++; foreach (var statement in node.Statements) { statement.WriteTo(writer); } writer.Indent--; writer.WritePunctuation(SyntaxKind.CloseBraceToken); writer.WriteLine(); }
private static void WriteBlockStatement(BoundBlockStatement node, IndentedTextWriter writer) { writer.WritePunctuation("{"); writer.WriteLine(); writer.Indent++; foreach (var s in node.Statements) { s.WriteTo(writer); } writer.Indent--; writer.WritePunctuation("}"); writer.WriteLine(); }
private List <AtomicBlock> BuildInternal(BoundBlockStatement block) { foreach (var statement in block.Statements) { switch (statement.Kind) { case BoundNodeKind.ConditionalGotoStatement: case BoundNodeKind.GotoStatement: case BoundNodeKind.ReturnStatement: statements.Add(statement); StartBlock(); break; case BoundNodeKind.ExpressionStatement: case BoundNodeKind.VariableDeclarationStatement: statements.Add(statement); break; case BoundNodeKind.LabelStatement: StartBlock(); statements.Add(statement); break; case BoundNodeKind.ConditionalStatement: case BoundNodeKind.ForToStatement: case BoundNodeKind.WhileStatement: throw new Exception($"Statement kind '{statement.Kind}' should be lowered out already"); case BoundNodeKind.ErrorStatement: case BoundNodeKind.BlockStatement: default: throw new Exception($"Unexpected statement kind '{statement.Kind}'"); } } EndBlock(); return(blocks); }
public BoundProgram(ImmutableArray <Diagnostic> diagnostics, ImmutableDictionary <FunctionSymbol, BoundBlockStatement> functions, BoundBlockStatement statement) { Diagnostics = diagnostics; Functions = functions; Statement = statement; }
public static List <AtomicBlock> Build(BoundBlockStatement block) { var builder = new AtomicBlockBuilder(); return(builder.BuildInternal(block)); }