예제 #1
0
        void visit_subroutine(Subroutine m)
        {
            if (m.body == null)
            {
                return;
            }

            m.entry_block  = BasicBlock.entry();
            m.return_block = new BasicBlock();
            m.exit_block   = BasicBlock.exit();

            m.return_block.connect(m.exit_block);

            if (m is Method)
            {
                // ensure out parameters are defined at end of method
                foreach (var param in ((Method)m).get_parameters())
                {
                    if (param.direction == ParameterDirection.OUT)
                    {
                        var param_ma = MemberAccess.simple(param.name, param.source_reference);
                        param_ma.symbol_reference = param;
                        m.return_block.add_node(param_ma);
                    }
                }
            }

            current_block = new BasicBlock();
            m.entry_block.connect(current_block);
            current_block.add_node(m);

            jump_stack.Add(JumpTarget.return_target(m.return_block));
            jump_stack.Add(JumpTarget.exit_target(m.exit_block));

            m.accept_children(this);

            jump_stack.RemoveAt(jump_stack.Count - 1);

            if (current_block != null)
            {
                // end of method body reachable

                if (m.has_result)
                {
                    Report.error(m.source_reference, "missing return statement at end of subroutine body");
                    m.error = true;
                }

                current_block.connect(m.return_block);
            }

            analyze_body(m.entry_block);
        }