#  Copyright (C) 2013-2022 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any
# later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

# This Awk script takes passes.def and writes pass-instances.def,
# counting the instances of each kind of pass, adding an instance number
# to everywhere that NEXT_PASS is used.
# Also handle INSERT_PASS_AFTER, INSERT_PASS_BEFORE and REPLACE_PASS
# directives.
#
# For example, the single-instanced pass:
#     NEXT_PASS (pass_warn_unused_result);
# becomes this in the output:
#     NEXT_PASS (pass_warn_unused_result, 1);
#
# The various instances of
#   NEXT_PASS (pass_copy_prop);
# become:
#   NEXT_PASS (pass_copy_prop, 1);
# through:
#   NEXT_PASS (pass_copy_prop, 8);
# (currently there are 8 instances of that pass)
#
#     INSERT_PASS_AFTER (pass_copy_prop, 1, pass_stv);
# will insert
#     NEXT_PASS (pass_stv, 1);
# immediately after the NEXT_PASS (pass_copy_prop, 1) line,
# similarly INSERT_PASS_BEFORE inserts immediately before that line.
#     REPLACE_PASS (pass_copy_prop, 1, pass_stv, true);
# will replace NEXT_PASS (pass_copy_prop, 1) line with
#     NEXT_PASS (pass_stv, 1, true);
# line and renumber all higher pass_copy_prop instances if any.

# Usage: awk -f gen-pass-instances.awk passes.def

BEGIN {
  print "/* This file is auto-generated by gen-pass-instances.awk";
  print "   from passes.def.  */";
  lineno = 1;
}

function parse_line(line, fnname,	len_of_call, len_of_start,
					len_of_open, len_of_close,
					len_of_args, args_start_at,
					args_str, len_of_prefix,
					call_starts_at,
					postfix_starts_at)
{
  # Find call expression.
  call_starts_at = match(line, fnname " \\(.+\\)");
  if (call_starts_at == 0)
    return 0;

  # Length of the call expression.
  len_of_call = RLENGTH;

  len_of_start = length(fnname " (");
  len_of_open = length("(");
  len_of_close = length(")");

  # Find arguments
  len_of_args = len_of_call - (len_of_start + len_of_close);
  args_start_at = call_starts_at + len_of_start;
  args_str = substr(line, args_start_at, len_of_args);
  split(args_str, args, ",");

  # Find call expression prefix
  len_of_prefix = call_starts_at - 1;
  prefix = substr(line, 1, len_of_prefix);

  # Find call expression postfix
  postfix_starts_at = call_starts_at + len_of_call;
  postfix = substr(line, postfix_starts_at);
  return 1;
}

function adjust_linenos(above, increment,	p, i)
{
  for (p in pass_lines)
    if (pass_lines[p] >= above)
      pass_lines[p] += increment;
  if (increment > 0)
    for (i = lineno - 1; i >= above; i--)
      lines[i + increment] = lines[i];
  else
    for (i = above; i < lineno; i++)
      lines[i + increment] = lines[i];
  lineno += increment;
}

function insert_remove_pass(line, fnname,	arg3)
{
  parse_line($0, fnname);
  pass_name = args[1];
  if (pass_name == "PASS")
    return 1;
  pass_num = args[2] + 0;
  arg3 = args[3];
  sub(/^[ \t]*/, "", arg3);
  new_line = prefix "NEXT_PASS (" arg3;
  if (args[4])
    new_line = new_line "," args[4];
  new_line = new_line ")" postfix;
  if (!pass_lines[pass_name, pass_num])
    {
      print "ERROR: Can't locate instance of the pass mentioned in " fnname;
      return 1;
    }
  return 0;
}

function insert_pass(line, fnname, after,		num)
{
  if (insert_remove_pass(line, fnname))
    return;
  num = pass_lines[pass_name, pass_num];
  adjust_linenos(num + after, 1);
  pass_name = args[3];
  # Set pass_counts
  if (args[3] in pass_counts)
    pass_counts[pass_name]++;
  else
    pass_counts[pass_name] = 1;

  pass_lines[pass_name, pass_counts[pass_name]] = num + after;
  lines[num + after] = new_line;
}

function replace_pass(line, fnname,			num, i)
{
  if (insert_remove_pass(line, "REPLACE_PASS"))
    return;
  num = pass_lines[pass_name, pass_num];
  for (i = pass_counts[pass_name]; i > pass_num; i--)
    pass_lines[pass_name, i - 1] = pass_lines[pass_name, i];
  delete pass_lines[pass_name, pass_counts[pass_name]];
  if (pass_counts[pass_name] == 1)
    delete pass_counts[pass_name];
  else
    pass_counts[pass_name]--;

  pass_name = args[3];
  # Set pass_counts
  if (args[3] in pass_counts)
    pass_counts[pass_name]++;
  else
    pass_counts[pass_name] = 1;

  pass_lines[pass_name, pass_counts[pass_name]] = num;
  lines[num] = new_line;
}

/INSERT_PASS_AFTER \(.+\)/ {
  insert_pass($0, "INSERT_PASS_AFTER", 1);
  next;
}

/INSERT_PASS_BEFORE \(.+\)/ {
  insert_pass($0, "INSERT_PASS_BEFORE", 0);
  next;
}

/REPLACE_PASS \(.+\)/ {
  replace_pass($0, "REPLACE_PASS");
  next;
}

{
  ret = parse_line($0, "NEXT_PASS");
  if (ret)
    {
      pass_name = args[1];

      # Set pass_counts
      if (pass_name in pass_counts)
	pass_counts[pass_name]++;
      else
	pass_counts[pass_name] = 1;

      pass_lines[pass_name, pass_counts[pass_name]] = lineno;
    }
  lines[lineno++] = $0;
}

END {
  for (i = 1; i < lineno; i++)
    {
      ret = parse_line(lines[i], "NEXT_PASS");
      if (ret)
	{
	  # Set pass_name argument, an optional with_arg argument
	  pass_name = args[1];
	  with_arg = args[2];

	  # Set pass_final_counts
	  if (pass_name in pass_final_counts)
	    pass_final_counts[pass_name]++;
	  else
	    pass_final_counts[pass_name] = 1;

	  pass_num = pass_final_counts[pass_name];

	  # Print call expression with extra pass_num argument
	  printf "%s", prefix;
	  if (with_arg)
	    printf "NEXT_PASS_WITH_ARG";
	  else
	    printf "NEXT_PASS";
	  printf " (%s, %s", pass_name, pass_num;
	  if (with_arg)
	    printf ",%s", with_arg;
	  printf ")%s\n", postfix;
	}
      else
	print lines[i];
    }
}

# Local Variables:
# mode:awk
# c-basic-offset:8
# End:
