public static bool AllPathsReturn(FunctionSymbol symbol, BoundBlockStatement body)
        {
            if (symbol.ReturnType == TypeSymbol.Void)
            {
                return(true);
            }
            if (!body.IsValid)
            {
                return(false);
            }

            var graph = Create(body);

            foreach (var toEnd in graph.End.Incoming)
            {
                if (!toEnd.From.Statements.Any())
                {
                    return(false);
                }
                if (toEnd.From.Statements.Last().Kind != BoundNodeKind.BoundReturnStatement)
                {
                    return(false);
                }
            }

            return(true);
        }
            public List <BasicBlock> Build(BoundBlockStatement boundBlock)
            {
                foreach (var statement in boundBlock.Statements)
                {
                    switch (statement.Kind)
                    {
                    case BoundNodeKind.BoundExpressionStatement:
                    case BoundNodeKind.BoundVariableDeclarationStatement:
                    case BoundNodeKind.BoundNopStatement:
                        statements.Add(statement);
                        break;

                    case BoundNodeKind.BoundLabelStatement:
                        EndBlock();
                        statements.Add(statement);
                        break;

                    case BoundNodeKind.BoundConditionalGotoStatement:
                    case BoundNodeKind.BoundGotoStatement:
                    case BoundNodeKind.BoundReturnStatement:
                        statements.Add(statement);
                        EndBlock();
                        break;

                    default: throw new Exception("Unexpected kind");
                    }
                }

                EndBlock();

                return(blocks);
            }
Exemple #3
0
        protected virtual BoundStatement RewriteBlockStatement(BoundBlockStatement node)
        {
            var builder = (ImmutableArray <BoundStatement> .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 is null)
                    {
                        builder = ImmutableArray.CreateBuilder <BoundStatement>(node.Statements.Length);

                        for (var j = 0; j < i; j++)
                        {
                            builder.Add(node.Statements[j]);
                        }
                    }
                }

                if (!(builder is null))
                {
                    builder.Add(newStatement);
                }
            }

            if (builder is null)
            {
                return(node);
            }

            return(new BoundBlockStatement(builder.MoveToImmutable(), node.IsValid));
        }
        internal static ControlFlowGraph Create(BoundBlockStatement body)
        {
            var basicBuilder = new BasicBlockBuilder();
            var blocks       = basicBuilder.Build(body);

            var graphBuilder = new GraphBuilder();

            return(graphBuilder.Build(blocks));
        }