/* Command line option handling.
   Copyright (C) 2006-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "intl.h"
#include "coretypes.h"
#include "opts.h"
#include "options.h"
#include "diagnostic.h"
#include "spellcheck.h"

static void prune_options (struct cl_decoded_option **, unsigned int *);

/* An option that is undocumented, that takes a joined argument, and
   that doesn't fit any of the classes of uses (language/common,
   driver, target) is assumed to be a prefix used to catch
   e.g. negated options, and stop them from being further shortened to
   a prefix that could use the negated option as an argument.  For
   example, we want -gno-statement-frontiers to be taken as a negation
   of -gstatement-frontiers, but without catching the gno- prefix and
   signaling it's to be used for option remapping, it would end up
   backtracked to g with no-statemnet-frontiers as the debug level.  */

static bool
remapping_prefix_p (const struct cl_option *opt)
{
  return opt->flags & CL_UNDOCUMENTED
    && opt->flags & CL_JOINED
    && !(opt->flags & (CL_DRIVER | CL_TARGET | CL_COMMON | CL_LANG_ALL));
}

/* Perform a binary search to find which option the command-line INPUT
   matches.  Returns its index in the option array, and
   OPT_SPECIAL_unknown on failure.

   This routine is quite subtle.  A normal binary search is not good
   enough because some options can be suffixed with an argument, and
   multiple sub-matches can occur, e.g. input of "-pedantic" matching
   the initial substring of "-pedantic-errors".

   A more complicated example is -gstabs.  It should match "-g" with
   an argument of "stabs".  Suppose, however, that the number and list
   of switches are such that the binary search tests "-gen-decls"
   before having tested "-g".  This doesn't match, and as "-gen-decls"
   is less than "-gstabs", it will become the lower bound of the
   binary search range, and "-g" will never be seen.  To resolve this
   issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member,
   to "-g" so that failed searches that end between "-gen-decls" and
   the lexicographically subsequent switch know to go back and see if
   "-g" causes a match (which it does in this example).

   This search is done in such a way that the longest match for the
   front end in question wins.  If there is no match for the current
   front end, the longest match for a different front end is returned
   (or N_OPTS if none) and the caller emits an error message.  */
size_t
find_opt (const char *input, unsigned int lang_mask)
{
  size_t mn, mn_orig, mx, md, opt_len;
  size_t match_wrong_lang;
  int comp;

  mn = 0;
  mx = cl_options_count;

  /* Find mn such this lexicographical inequality holds:
     cl_options[mn] <= input < cl_options[mn + 1].  */
  while (mx - mn > 1)
    {
      md = (mn + mx) / 2;
      opt_len = cl_options[md].opt_len;
      comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);

      if (comp < 0)
	mx = md;
      else
	mn = md;
    }

  mn_orig = mn;

  /* This is the switch that is the best match but for a different
     front end, or OPT_SPECIAL_unknown if there is no match at all.  */
  match_wrong_lang = OPT_SPECIAL_unknown;

  /* Backtrace the chain of possible matches, returning the longest
     one, if any, that fits best.  With current GCC switches, this
     loop executes at most twice.  */
  do
    {
      const struct cl_option *opt = &cl_options[mn];

      /* Is the input either an exact match or a prefix that takes a
	 joined argument?  */
      if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
	  && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
	{
	  /* If language is OK, return it.  */
	  if (opt->flags & lang_mask)
	    return mn;

	  if (remapping_prefix_p (opt))
	    return OPT_SPECIAL_unknown;

	  /* If we haven't remembered a prior match, remember this
	     one.  Any prior match is necessarily better.  */
	  if (match_wrong_lang == OPT_SPECIAL_unknown)
	    match_wrong_lang = mn;
	}

      /* Try the next possibility.  This is cl_options_count if there
	 are no more.  */
      mn = opt->back_chain;
    }
  while (mn != cl_options_count);

  if (match_wrong_lang == OPT_SPECIAL_unknown && input[0] == '-')
    {
      /* Long options, starting "--", may be abbreviated if the
	 abbreviation is unambiguous.  This only applies to options
	 not taking a joined argument, and abbreviations of "--option"
	 are permitted even if there is a variant "--option=".  */
      size_t mnc = mn_orig + 1;
      size_t cmp_len = strlen (input);
      while (mnc < cl_options_count
	     && strncmp (input, cl_options[mnc].opt_text + 1, cmp_len) == 0)
	{
	  /* Option matching this abbreviation.  OK if it is the first
	     match and that does not take a joined argument, or the
	     second match, taking a joined argument and with only '='
	     added to the first match; otherwise considered
	     ambiguous.  */
	  if (mnc == mn_orig + 1
	      && !(cl_options[mnc].flags & CL_JOINED))
	    match_wrong_lang = mnc;
	  else if (mnc == mn_orig + 2
		   && match_wrong_lang == mn_orig + 1
		   && (cl_options[mnc].flags & CL_JOINED)
		   && (cl_options[mnc].opt_len
		       == cl_options[mn_orig + 1].opt_len + 1)
		   && strncmp (cl_options[mnc].opt_text + 1,
			       cl_options[mn_orig + 1].opt_text + 1,
			       cl_options[mn_orig + 1].opt_len) == 0)
	    ; /* OK, as long as there are no more matches.  */
	  else
	    return OPT_SPECIAL_unknown;
	  mnc++;
	}
    }

  /* Return the best wrong match, or OPT_SPECIAL_unknown if none.  */
  return match_wrong_lang;
}

/* If ARG is a non-negative decimal or hexadecimal integer representable
   in HOST_WIDE_INT return its value, otherwise return -1.  If ERR is not
   null set *ERR to zero on success or to EINVAL or to the value of errno
   otherwise.  */

HOST_WIDE_INT
integral_argument (const char *arg, int *err, bool byte_size_suffix)
{
  if (!err)
    err = &errno;

  if (!ISDIGIT (*arg))
    {
      *err = EINVAL;
      return -1;
    }

  *err = 0;
  errno = 0;

  char *end = NULL;
  unsigned HOST_WIDE_INT unit = 1;
  unsigned HOST_WIDE_INT value = strtoull (arg, &end, 10);

  /* If the value is too large to be represented use the maximum
     representable value that strtoull sets VALUE to (setting
     errno to ERANGE).  */

  if (end && *end)
    {
      if (!byte_size_suffix)
	{
	  errno = 0;
	  value = strtoull (arg, &end, 0);
	  if (*end)
	    {
	      if (errno)
		*err = errno;
	      else
		*err = EINVAL;
	      return -1;
	    }

	  return value;
	}

      /* Numeric option arguments are at most INT_MAX.  Make it
	 possible to specify a larger value by accepting common
	 suffixes.  */
      if (!strcmp (end, "kB"))
	unit = 1000;
      else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
	unit = 1024;
      else if (!strcmp (end, "MB"))
	unit = HOST_WIDE_INT_UC (1000) * 1000;
      else if (!strcasecmp (end, "MiB"))
	unit = HOST_WIDE_INT_UC (1024) * 1024;
      else if (!strcasecmp (end, "GB"))
	unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
      else if (!strcasecmp (end, "GiB"))
	unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
      else if (!strcasecmp (end, "TB"))
	unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
      else if (!strcasecmp (end, "TiB"))
	unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
      else if (!strcasecmp (end, "PB"))
	unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
      else if (!strcasecmp (end, "PiB"))
	unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
      else if (!strcasecmp (end, "EB"))
	unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
	  * 1000;
      else if (!strcasecmp (end, "EiB"))
	unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
	  * 1024;
      else
	{
	  /* This could mean an unknown suffix or a bad prefix, like
	     "+-1".  */
	  *err = EINVAL;
	  return -1;
	}
    }

  if (unit)
    {
      unsigned HOST_WIDE_INT prod = value * unit;
      value = prod < value ? HOST_WIDE_INT_M1U : prod;
    }

  return value;
}

/* Return whether OPTION is OK for the language given by
   LANG_MASK.  */
static bool
option_ok_for_language (const struct cl_option *option,
			unsigned int lang_mask)
{
  if (!(option->flags & lang_mask))
    return false;
  else if ((option->flags & CL_TARGET)
	   && (option->flags & (CL_LANG_ALL | CL_DRIVER))
	   && !(option->flags & (lang_mask & ~CL_COMMON & ~CL_TARGET)))
    /* Complain for target flag language mismatches if any languages
       are specified.  */
    return false;
  return true;
}

/* Return whether ENUM_ARG is OK for the language given by
   LANG_MASK.  */

static bool
enum_arg_ok_for_language (const struct cl_enum_arg *enum_arg,
			  unsigned int lang_mask)
{
  return (lang_mask & CL_DRIVER) || !(enum_arg->flags & CL_ENUM_DRIVER_ONLY);
}

/* Look up ARG in ENUM_ARGS for language LANG_MASK, returning true and
   storing the value in *VALUE if found, and returning false without
   modifying *VALUE if not found.  */

static bool
enum_arg_to_value (const struct cl_enum_arg *enum_args,
		   const char *arg, HOST_WIDE_INT *value,
		   unsigned int lang_mask)
{
  unsigned int i;

  for (i = 0; enum_args[i].arg != NULL; i++)
    if (strcmp (arg, enum_args[i].arg) == 0
	&& enum_arg_ok_for_language (&enum_args[i], lang_mask))
      {
	*value = enum_args[i].value;
	return true;
      }

  return false;
}

/* Look up ARG in the enum used by option OPT_INDEX for language
   LANG_MASK, returning true and storing the value in *VALUE if found,
   and returning false without modifying *VALUE if not found.  */

bool
opt_enum_arg_to_value (size_t opt_index, const char *arg,
		       int *value, unsigned int lang_mask)
{
  const struct cl_option *option = &cl_options[opt_index];

  gcc_assert (option->var_type == CLVC_ENUM);

  HOST_WIDE_INT wideval;
  if (enum_arg_to_value (cl_enums[option->var_enum].values, arg,
			 &wideval, lang_mask))
    {
      *value = wideval;
      return true;
    }

  return false;
}

/* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the
   corresponding string in *ARGP, returning true if the found string
   was marked as canonical, false otherwise.  If VALUE is not found
   (which may be the case for uninitialized values if the relevant
   option has not been passed), set *ARGP to NULL and return
   false.  */

bool
enum_value_to_arg (const struct cl_enum_arg *enum_args,
		   const char **argp, int value, unsigned int lang_mask)
{
  unsigned int i;

  for (i = 0; enum_args[i].arg != NULL; i++)
    if (enum_args[i].value == value
	&& (enum_args[i].flags & CL_ENUM_CANONICAL)
	&& enum_arg_ok_for_language (&enum_args[i], lang_mask))
      {
	*argp = enum_args[i].arg;
	return true;
      }

  for (i = 0; enum_args[i].arg != NULL; i++)
    if (enum_args[i].value == value
	&& enum_arg_ok_for_language (&enum_args[i], lang_mask))
      {
	*argp = enum_args[i].arg;
	return false;
      }

  *argp = NULL;
  return false;
}

/* Fill in the canonical option part of *DECODED with an option
   described by OPT_INDEX, ARG and VALUE.  */

static void
generate_canonical_option (size_t opt_index, const char *arg,
			   HOST_WIDE_INT value,
			   struct cl_decoded_option *decoded)
{
  const struct cl_option *option = &cl_options[opt_index];
  const char *opt_text = option->opt_text;

  if (value == 0
      && !option->cl_reject_negative
      && (opt_text[1] == 'W' || opt_text[1] == 'f'
	  || opt_text[1] == 'g' || opt_text[1] == 'm'))
    {
      char *t = XOBNEWVEC (&opts_obstack, char, option->opt_len + 5);
      t[0] = '-';
      t[1] = opt_text[1];
      t[2] = 'n';
      t[3] = 'o';
      t[4] = '-';
      memcpy (t + 5, opt_text + 2, option->opt_len);
      opt_text = t;
    }

  decoded->canonical_option[2] = NULL;
  decoded->canonical_option[3] = NULL;

  if (arg)
    {
      if ((option->flags & CL_SEPARATE)
	  && !option->cl_separate_alias)
	{
	  decoded->canonical_option[0] = opt_text;
	  decoded->canonical_option[1] = arg;
	  decoded->canonical_option_num_elements = 2;
	}
      else
	{
	  gcc_assert (option->flags & CL_JOINED);
	  decoded->canonical_option[0] = opts_concat (opt_text, arg, NULL);
	  decoded->canonical_option[1] = NULL;
	  decoded->canonical_option_num_elements = 1;
	}
    }
  else
    {
      decoded->canonical_option[0] = opt_text;
      decoded->canonical_option[1] = NULL;
      decoded->canonical_option_num_elements = 1;
    }
}

/* Structure describing mappings from options on the command line to
   options to look up with find_opt.  */
struct option_map
{
  /* Prefix of the option on the command line.  */
  const char *opt0;
  /* If two argv elements are considered to be merged into one option,
     prefix for the second element, otherwise NULL.  */
  const char *opt1;
  /* The new prefix to map to.  */
  const char *new_prefix;
  /* Whether at least one character is needed following opt1 or opt0
     for this mapping to be used.  (--optimize= is valid for -O, but
     --warn- is not valid for -W.)  */
  bool another_char_needed;
  /* Whether the original option is a negated form of the option
     resulting from this map.  */
  bool negated;
};
static const struct option_map option_map[] =
  {
    { "-Wno-", NULL, "-W", false, true },
    { "-fno-", NULL, "-f", false, true },
    { "-gno-", NULL, "-g", false, true },
    { "-mno-", NULL, "-m", false, true },
    { "--debug=", NULL, "-g", false, false },
    { "--machine-", NULL, "-m", true, false },
    { "--machine-no-", NULL, "-m", false, true },
    { "--machine=", NULL, "-m", false, false },
    { "--machine=no-", NULL, "-m", false, true },
    { "--machine", "", "-m", false, false },
    { "--machine", "no-", "-m", false, true },
    { "--optimize=", NULL, "-O", false, false },
    { "--std=", NULL, "-std=", false, false },
    { "--std", "", "-std=", false, false },
    { "--warn-", NULL, "-W", true, false },
    { "--warn-no-", NULL, "-W", false, true },
    { "--", NULL, "-f", true, false },
    { "--no-", NULL, "-f", false, true }
  };

/* Helper function for gcc.cc's driver::suggest_option, for populating the
   vec of suggestions for misspelled options.

   option_map above provides various prefixes for spelling command-line
   options, which decode_cmdline_option uses to map spellings of options
   to specific options.  We want to do the reverse: to find all the ways
   that a user could validly spell an option.

   Given valid OPT_TEXT (with a leading dash) for OPTION, add it and all
   of its valid variant spellings to CANDIDATES, each without a leading
   dash.

   For example, given "-Wabi-tag", the following are added to CANDIDATES:
     "Wabi-tag"
     "Wno-abi-tag"
     "-warn-abi-tag"
     "-warn-no-abi-tag".

   The added strings must be freed using free.  */

void
add_misspelling_candidates (auto_vec<char *> *candidates,
			    const struct cl_option *option,
			    const char *opt_text)
{
  gcc_assert (candidates);
  gcc_assert (option);
  gcc_assert (opt_text);
  if (remapping_prefix_p (option))
    return;
  candidates->safe_push (xstrdup (opt_text + 1));
  for (unsigned i = 0; i < ARRAY_SIZE (option_map); i++)
    {
      const char *opt0 = option_map[i].opt0;
      const char *new_prefix = option_map[i].new_prefix;
      size_t new_prefix_len = strlen (new_prefix);

      if (option->cl_reject_negative && option_map[i].negated)
	continue;

      if (strncmp (opt_text, new_prefix, new_prefix_len) == 0)
	{
	  char *alternative = concat (opt0 + 1, opt_text + new_prefix_len,
				      NULL);
	  candidates->safe_push (alternative);
	}
    }

  /* For all params (e.g. --param=key=value),
     include also '--param key=value'.  */
  const char *prefix = "--param=";
  if (strstr (opt_text, prefix) == opt_text)
    {
      char *param = xstrdup (opt_text + 1);
      gcc_assert (param[6] == '=');
      param[6] = ' ';
      candidates->safe_push (param);
    }
}

/* Decode the switch beginning at ARGV for the language indicated by
   LANG_MASK (including CL_COMMON and CL_TARGET if applicable), into
   the structure *DECODED.  Returns the number of switches
   consumed.  */

static unsigned int
decode_cmdline_option (const char *const *argv, unsigned int lang_mask,
		       struct cl_decoded_option *decoded)
{
  size_t opt_index;
  const char *arg = 0;
  HOST_WIDE_INT value = 1;
  unsigned int result = 1, i, extra_args, separate_args = 0;
  int adjust_len = 0;
  size_t total_len;
  char *p;
  const struct cl_option *option;
  int errors = 0;
  const char *warn_message = NULL;
  bool separate_arg_flag;
  bool joined_arg_flag;
  bool have_separate_arg = false;

  extra_args = 0;

  const char *opt_value = argv[0] + 1;
  opt_index = find_opt (opt_value, lang_mask);
  i = 0;
  while (opt_index == OPT_SPECIAL_unknown
	 && i < ARRAY_SIZE (option_map))
    {
      const char *opt0 = option_map[i].opt0;
      const char *opt1 = option_map[i].opt1;
      const char *new_prefix = option_map[i].new_prefix;
      bool another_char_needed = option_map[i].another_char_needed;
      size_t opt0_len = strlen (opt0);
      size_t opt1_len = (opt1 == NULL ? 0 : strlen (opt1));
      size_t optn_len = (opt1 == NULL ? opt0_len : opt1_len);
      size_t new_prefix_len = strlen (new_prefix);

      extra_args = (opt1 == NULL ? 0 : 1);
      value = !option_map[i].negated;

      if (strncmp (argv[0], opt0, opt0_len) == 0
	  && (opt1 == NULL
	      || (argv[1] != NULL && strncmp (argv[1], opt1, opt1_len) == 0))
	  && (!another_char_needed
	      || argv[extra_args][optn_len] != 0))
	{
	  size_t arglen = strlen (argv[extra_args]);
	  char *dup;

	  adjust_len = (int) optn_len - (int) new_prefix_len;
	  dup = XNEWVEC (char, arglen + 1 - adjust_len);
	  memcpy (dup, new_prefix, new_prefix_len);
	  memcpy (dup + new_prefix_len, argv[extra_args] + optn_len,
		  arglen - optn_len + 1);
	  opt_index = find_opt (dup + 1, lang_mask);
	  free (dup);
	}
      i++;
    }

  if (opt_index == OPT_SPECIAL_unknown)
    {
      arg = argv[0];
      extra_args = 0;
      value = 1;
      goto done;
    }

  option = &cl_options[opt_index];

  /* Reject negative form of switches that don't take negatives as
     unrecognized.  */
  if (!value && option->cl_reject_negative)
    {
      opt_index = OPT_SPECIAL_unknown;
      errors |= CL_ERR_NEGATIVE;
      arg = argv[0];
      goto done;
    }

  /* Clear the initial value for size options (it will be overwritten
     later based on the Init(value) specification in the opt file.  */
  if (option->var_type == CLVC_SIZE)
    value = 0;

  result = extra_args + 1;
  warn_message = option->warn_message;

  /* Check to see if the option is disabled for this configuration.  */
  if (option->cl_disabled)
    errors |= CL_ERR_DISABLED;

  /* Determine whether there may be a separate argument based on
     whether this option is being processed for the driver, and, if
     so, how many such arguments.  */
  separate_arg_flag = ((option->flags & CL_SEPARATE)
		       && !(option->cl_no_driver_arg
			    && (lang_mask & CL_DRIVER)));
  separate_args = (separate_arg_flag
		   ? option->cl_separate_nargs + 1
		   : 0);
  joined_arg_flag = (option->flags & CL_JOINED) != 0;

  /* Sort out any argument the switch takes.  */
  if (joined_arg_flag)
    {
      /* Have arg point to the original switch.  This is because
	 some code, such as disable_builtin_function, expects its
	 argument to be persistent until the program exits.  */
      arg = argv[extra_args] + cl_options[opt_index].opt_len + 1 + adjust_len;

      if (*arg == '\0' && !option->cl_missing_ok)
	{
	  if (separate_arg_flag)
	    {
	      arg = argv[extra_args + 1];
	      result = extra_args + 2;
	      if (arg == NULL)
		result = extra_args + 1;
	      else
		have_separate_arg = true;
	    }
	  else
	    /* Missing argument.  */
	    arg = NULL;
	}
    }
  else if (separate_arg_flag)
    {
      arg = argv[extra_args + 1];
      for (i = 0; i < separate_args; i++)
	if (argv[extra_args + 1 + i] == NULL)
	  {
	    errors |= CL_ERR_MISSING_ARG;
	    break;
	  }
      result = extra_args + 1 + i;
      if (arg != NULL)
	have_separate_arg = true;
    }

  if (arg == NULL && (separate_arg_flag || joined_arg_flag))
    errors |= CL_ERR_MISSING_ARG;

  /* Is this option an alias (or an ignored option, marked as an alias
     of OPT_SPECIAL_ignore)?  */
  if (option->alias_target != N_OPTS
      && (!option->cl_separate_alias || have_separate_arg))
    {
      size_t new_opt_index = option->alias_target;

      if (new_opt_index == OPT_SPECIAL_ignore
	  || new_opt_index == OPT_SPECIAL_warn_removed)
	{
	  gcc_assert (option->alias_arg == NULL);
	  gcc_assert (option->neg_alias_arg == NULL);
	  opt_index = new_opt_index;
	  arg = NULL;
	}
      else
	{
	  const struct cl_option *new_option = &cl_options[new_opt_index];

	  /* The new option must not be an alias itself.  */
	  gcc_assert (new_option->alias_target == N_OPTS
		      || new_option->cl_separate_alias);

	  if (option->neg_alias_arg)
	    {
	      gcc_assert (option->alias_arg != NULL);
	      gcc_assert (arg == NULL);
	      gcc_assert (!option->cl_negative_alias);
	      if (value)
		arg = option->alias_arg;
	      else
		arg = option->neg_alias_arg;
	      value = 1;
	    }
	  else if (option->alias_arg)
	    {
	      gcc_assert (value == 1);
	      gcc_assert (arg == NULL);
	      gcc_assert (!option->cl_negative_alias);
	      arg = option->alias_arg;
	    }

	  if (option->cl_negative_alias)
	    value = !value;

	  opt_index = new_opt_index;
	  option = new_option;

	  if (value == 0)
	    gcc_assert (!option->cl_reject_negative);

	  /* Recompute what arguments are allowed.  */
	  separate_arg_flag = ((option->flags & CL_SEPARATE)
			       && !(option->cl_no_driver_arg
				    && (lang_mask & CL_DRIVER)));
	  joined_arg_flag = (option->flags & CL_JOINED) != 0;

	  if (separate_args > 1 || option->cl_separate_nargs)
	    gcc_assert (separate_args
			== (unsigned int) option->cl_separate_nargs + 1);

	  if (!(errors & CL_ERR_MISSING_ARG))
	    {
	      if (separate_arg_flag || joined_arg_flag)
		{
		  if (option->cl_missing_ok && arg == NULL)
		    arg = "";
		  gcc_assert (arg != NULL);
		}
	      else
		gcc_assert (arg == NULL);
	    }

	  /* Recheck for warnings and disabled options.  */
	  if (option->warn_message)
	    {
	      gcc_assert (warn_message == NULL);
	      warn_message = option->warn_message;
	    }
	  if (option->cl_disabled)
	    errors |= CL_ERR_DISABLED;
	}
    }

  /* Check if this is a switch for a different front end.  */
  if (!option_ok_for_language (option, lang_mask))
    errors |= CL_ERR_WRONG_LANG;
  else if (strcmp (option->opt_text, "-Werror=") == 0
	   && strchr (opt_value, ',') == NULL)
    {
      /* Verify that -Werror argument is a valid warning
	 for a language.  */
      char *werror_arg = xstrdup (opt_value + 6);
      werror_arg[0] = 'W';

      size_t warning_index = find_opt (werror_arg, lang_mask);
      free (werror_arg);
      if (warning_index != OPT_SPECIAL_unknown)
	{
	  const struct cl_option *warning_option
	    = &cl_options[warning_index];
	  if (!option_ok_for_language (warning_option, lang_mask))
	    errors |= CL_ERR_WRONG_LANG;
	}
    }

  /* Convert the argument to lowercase if appropriate.  */
  if (arg && option->cl_tolower)
    {
      size_t j;
      size_t len = strlen (arg);
      char *arg_lower = XOBNEWVEC (&opts_obstack, char, len + 1);

      for (j = 0; j < len; j++)
	arg_lower[j] = TOLOWER ((unsigned char) arg[j]);
      arg_lower[len] = 0;
      arg = arg_lower;
    }

  /* If the switch takes an integer argument, convert it.  */
  if (arg && (option->cl_uinteger || option->cl_host_wide_int))
    {
      int error = 0;
      value = *arg ? integral_argument (arg, &error, option->cl_byte_size) : 0;
      if (error)
	errors |= CL_ERR_UINT_ARG;

      /* Reject value out of a range.  */
      if (option->range_max != -1
	  && (value < option->range_min || value > option->range_max))
	errors |= CL_ERR_INT_RANGE_ARG;
    }

  /* If the switch takes an enumerated argument, convert it.  */
  if (arg && (option->var_type == CLVC_ENUM))
    {
      const struct cl_enum *e = &cl_enums[option->var_enum];

      gcc_assert (value == 1);
      if (enum_arg_to_value (e->values, arg, &value, lang_mask))
	{
	  const char *carg = NULL;

	  if (enum_value_to_arg (e->values, &carg, value, lang_mask))
	    arg = carg;
	  gcc_assert (carg != NULL);
	}
      else
	errors |= CL_ERR_ENUM_ARG;
    }

 done:
  decoded->opt_index = opt_index;
  decoded->arg = arg;
  decoded->value = value;
  decoded->errors = errors;
  decoded->warn_message = warn_message;

  if (opt_index == OPT_SPECIAL_unknown)
    gcc_assert (result == 1);

  gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option));
  decoded->canonical_option_num_elements = result;
  total_len = 0;
  for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++)
    {
      if (i < result)
	{
	  size_t len;
	  if (opt_index == OPT_SPECIAL_unknown)
	    decoded->canonical_option[i] = argv[i];
	  else
	    decoded->canonical_option[i] = NULL;
	  len = strlen (argv[i]);
	  /* If the argument is an empty string, we will print it as "" in
	     orig_option_with_args_text.  */
	  total_len += (len != 0 ? len : 2) + 1;
	}
      else
	decoded->canonical_option[i] = NULL;
    }
  if (opt_index != OPT_SPECIAL_unknown && opt_index != OPT_SPECIAL_ignore
      && opt_index != OPT_SPECIAL_warn_removed)
    {
      generate_canonical_option (opt_index, arg, value, decoded);
      if (separate_args > 1)
	{
	  for (i = 0; i < separate_args; i++)
	    {
	      if (argv[extra_args + 1 + i] == NULL)
		  break;
	      else
		decoded->canonical_option[1 + i] = argv[extra_args + 1 + i];
	    }
	  gcc_assert (result == 1 + i);
	  decoded->canonical_option_num_elements = result;
	}
    }
  decoded->orig_option_with_args_text
    = p = XOBNEWVEC (&opts_obstack, char, total_len);
  for (i = 0; i < result; i++)
    {
      size_t len = strlen (argv[i]);

      /* Print the empty string verbally.  */
      if (len == 0)
	{
	  *p++ = '"';
	  *p++ = '"';
	}
      else
	memcpy (p, argv[i], len);
      p += len;
      if (i == result - 1)
	*p++ = 0;
      else
	*p++ = ' ';
    }

  return result;
}

/* Obstack for option strings.  */

struct obstack opts_obstack;

/* Like libiberty concat, but allocate using opts_obstack.  */

char *
opts_concat (const char *first, ...)
{
  char *newstr, *end;
  size_t length = 0;
  const char *arg;
  va_list ap;

  /* First compute the size of the result and get sufficient memory.  */
  va_start (ap, first);
  for (arg = first; arg; arg = va_arg (ap, const char *))
    length += strlen (arg);
  newstr = XOBNEWVEC (&opts_obstack, char, length + 1);
  va_end (ap);

  /* Now copy the individual pieces to the result string. */
  va_start (ap, first);
  for (arg = first, end = newstr; arg; arg = va_arg (ap, const char *))
    {
      length = strlen (arg);
      memcpy (end, arg, length);
      end += length;
    }
  *end = '\0';
  va_end (ap);
  return newstr;
}

/* Decode command-line options (ARGC and ARGV being the arguments of
   main) into an array, setting *DECODED_OPTIONS to a pointer to that
   array and *DECODED_OPTIONS_COUNT to the number of entries in the
   array.  The first entry in the array is always one for the program
   name (OPT_SPECIAL_program_name).  LANG_MASK indicates the language
   flags applicable for decoding (including CL_COMMON and CL_TARGET if
   those options should be considered applicable).  Do not produce any
   diagnostics or set state outside of these variables.  */

void
decode_cmdline_options_to_array (unsigned int argc, const char **argv, 
				 unsigned int lang_mask,
				 struct cl_decoded_option **decoded_options,
				 unsigned int *decoded_options_count)
{
  unsigned int n, i;
  struct cl_decoded_option *opt_array;
  unsigned int num_decoded_options;

  int opt_array_len = argc;
  opt_array = XNEWVEC (struct cl_decoded_option, opt_array_len);

  opt_array[0].opt_index = OPT_SPECIAL_program_name;
  opt_array[0].warn_message = NULL;
  opt_array[0].arg = argv[0];
  opt_array[0].orig_option_with_args_text = argv[0];
  opt_array[0].canonical_option_num_elements = 1;
  opt_array[0].canonical_option[0] = argv[0];
  opt_array[0].canonical_option[1] = NULL;
  opt_array[0].canonical_option[2] = NULL;
  opt_array[0].canonical_option[3] = NULL;
  opt_array[0].value = 1;
  opt_array[0].errors = 0;
  num_decoded_options = 1;

  for (i = 1; i < argc; i += n)
    {
      const char *opt = argv[i];

      /* Interpret "-" or a non-switch as a file name.  */
      if (opt[0] != '-' || opt[1] == '\0')
	{
	  generate_option_input_file (opt, &opt_array[num_decoded_options]);
	  num_decoded_options++;
	  n = 1;
	  continue;
	}

      /* Interpret "--param" "key=name" as "--param=key=name".  */
      const char *needle = "--param";
      if (i + 1 < argc && strcmp (opt, needle) == 0)
	{
	  const char *replacement
	    = opts_concat (needle, "=", argv[i + 1], NULL);
	  argv[++i] = replacement;
	}

      /* Expand -fdiagnostics-plain-output to its constituents.  This needs
	 to happen here so that prune_options can handle -fdiagnostics-color
	 specially.  */
      if (!strcmp (opt, "-fdiagnostics-plain-output"))
	{
	  /* If you have changed the default diagnostics output, and this new
	     output is not appropriately "plain" (e.g., the change needs to be
	     undone in order for the testsuite to work properly), then please do
	     the following:
		 1.  Add the necessary option to undo the new behavior to
		     the array below.
		 2.  Update the documentation for -fdiagnostics-plain-output
		     in invoke.texi.  */
	  const char *const expanded_args[] = {
	    "-fno-diagnostics-show-caret",
	    "-fno-diagnostics-show-line-numbers",
	    "-fdiagnostics-color=never",
	    "-fdiagnostics-urls=never",
	    "-fdiagnostics-path-format=separate-events",
	  };
	  const int num_expanded = ARRAY_SIZE (expanded_args);
	  opt_array_len += num_expanded - 1;
	  opt_array = XRESIZEVEC (struct cl_decoded_option,
				  opt_array, opt_array_len);
	  for (int j = 0, nj; j < num_expanded; j += nj)
	    {
	      nj = decode_cmdline_option (expanded_args + j, lang_mask,
					  &opt_array[num_decoded_options]);
	      num_decoded_options++;
	    }

	  n = 1;
	  continue;
	}

      n = decode_cmdline_option (argv + i, lang_mask,
				 &opt_array[num_decoded_options]);
      num_decoded_options++;
    }

  *decoded_options = opt_array;
  *decoded_options_count = num_decoded_options;
  prune_options (decoded_options, decoded_options_count);
}

/* Return true if NEXT_OPT_IDX cancels OPT_IDX.  Return false if the
   next one is the same as ORIG_NEXT_OPT_IDX.  */

static bool
cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
{
  /* An option can be canceled by the same option or an option with
     Negative.  */
  if (cl_options [next_opt_idx].neg_index == opt_idx)
    return true;

  if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
    return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
			  orig_next_opt_idx);

  return false;
}

/* Filter out options canceled by the ones after them.  */

static void
prune_options (struct cl_decoded_option **decoded_options,
	       unsigned int *decoded_options_count)
{
  unsigned int old_decoded_options_count = *decoded_options_count;
  struct cl_decoded_option *old_decoded_options = *decoded_options;
  unsigned int new_decoded_options_count;
  struct cl_decoded_option *new_decoded_options
    = XNEWVEC (struct cl_decoded_option, old_decoded_options_count);
  unsigned int i;
  const struct cl_option *option;
  unsigned int fdiagnostics_color_idx = 0;

  /* Remove arguments which are negated by others after them.  */
  new_decoded_options_count = 0;
  for (i = 0; i < old_decoded_options_count; i++)
    {
      unsigned int j, opt_idx, next_opt_idx;

      if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG)
	goto keep;

      opt_idx = old_decoded_options[i].opt_index;
      switch (opt_idx)
	{
	case OPT_SPECIAL_unknown:
	case OPT_SPECIAL_ignore:
	case OPT_SPECIAL_warn_removed:
	case OPT_SPECIAL_program_name:
	case OPT_SPECIAL_input_file:
	  goto keep;

	/* Do not save OPT_fdiagnostics_color_, just remember the last one.  */
	case OPT_fdiagnostics_color_:
	  fdiagnostics_color_idx = i;
	  continue;

	default:
	  gcc_assert (opt_idx < cl_options_count);
	  option = &cl_options[opt_idx];
	  if (option->neg_index < 0)
	    goto keep;

	  /* Skip joined switches.  */
	  if ((option->flags & CL_JOINED)
	      && (!option->cl_reject_negative
		  || (unsigned int) option->neg_index != opt_idx))
	    goto keep;

	  for (j = i + 1; j < old_decoded_options_count; j++)
	    {
	      if (old_decoded_options[j].errors & ~CL_ERR_WRONG_LANG)
		continue;
	      next_opt_idx = old_decoded_options[j].opt_index;
	      if (next_opt_idx >= cl_options_count)
		continue;
	      if (cl_options[next_opt_idx].neg_index < 0)
		continue;
	      if ((cl_options[next_opt_idx].flags & CL_JOINED)
		  && (!cl_options[next_opt_idx].cl_reject_negative
		      || ((unsigned int) cl_options[next_opt_idx].neg_index
			  != next_opt_idx)))
		continue;
	      if (cancel_option (opt_idx, next_opt_idx, next_opt_idx))
		break;
	    }
	  if (j == old_decoded_options_count)
	    {
keep:
	      new_decoded_options[new_decoded_options_count]
		= old_decoded_options[i];
	      new_decoded_options_count++;
	    }
	  break;
	}
    }

  if (fdiagnostics_color_idx >= 1)
    {
      /* We put the last -fdiagnostics-color= at the first position
	 after argv[0] so it can take effect immediately.  */
      memmove (new_decoded_options + 2, new_decoded_options + 1,
	       sizeof (struct cl_decoded_option) 
	       * (new_decoded_options_count - 1));
      new_decoded_options[1] = old_decoded_options[fdiagnostics_color_idx];
      new_decoded_options_count++;
    }

  free (old_decoded_options);
  new_decoded_options = XRESIZEVEC (struct cl_decoded_option,
				    new_decoded_options,
				    new_decoded_options_count);
  *decoded_options = new_decoded_options;
  *decoded_options_count = new_decoded_options_count;
}

/* Handle option DECODED for the language indicated by LANG_MASK,
   using the handlers in HANDLERS and setting fields in OPTS and
   OPTS_SET.  KIND is the diagnostic_t if this is a diagnostics
   option, DK_UNSPECIFIED otherwise, and LOC is the location of the
   option for options from the source file, UNKNOWN_LOCATION
   otherwise.  GENERATED_P is true for an option generated as part of
   processing another option or otherwise generated internally, false
   for one explicitly passed by the user.  control_warning_option
   generated options are considered explicitly passed by the user.
   Returns false if the switch was invalid.  DC is the diagnostic
   context for options affecting diagnostics state, or NULL.  */

static bool
handle_option (struct gcc_options *opts,
	       struct gcc_options *opts_set,
	       const struct cl_decoded_option *decoded,
	       unsigned int lang_mask, int kind, location_t loc,
	       const struct cl_option_handlers *handlers,
	       bool generated_p, diagnostic_context *dc)
{
  size_t opt_index = decoded->opt_index;
  const char *arg = decoded->arg;
  HOST_WIDE_INT value = decoded->value;
  const struct cl_option *option = &cl_options[opt_index];
  void *flag_var = option_flag_var (opt_index, opts);
  size_t i;

  if (flag_var)
    set_option (opts, (generated_p ? NULL : opts_set),
		opt_index, value, arg, kind, loc, dc);

  for (i = 0; i < handlers->num_handlers; i++)
    if (option->flags & handlers->handlers[i].mask)
      {
	if (!handlers->handlers[i].handler (opts, opts_set, decoded,
					    lang_mask, kind, loc,
					    handlers, dc,
					    handlers->target_option_override_hook))
	  return false;
      }
  
  return true;
}

/* Like handle_option, but OPT_INDEX, ARG and VALUE describe the
   option instead of DECODED.  This is used for callbacks when one
   option implies another instead of an option being decoded from the
   command line.  */

bool
handle_generated_option (struct gcc_options *opts,
			 struct gcc_options *opts_set,
			 size_t opt_index, const char *arg, HOST_WIDE_INT value,
			 unsigned int lang_mask, int kind, location_t loc,
			 const struct cl_option_handlers *handlers,
			 bool generated_p, diagnostic_context *dc)
{
  struct cl_decoded_option decoded;

  generate_option (opt_index, arg, value, lang_mask, &decoded);
  return handle_option (opts, opts_set, &decoded, lang_mask, kind, loc,
			handlers, generated_p, dc);
}

/* Fill in *DECODED with an option described by OPT_INDEX, ARG and
   VALUE for a front end using LANG_MASK.  This is used when the
   compiler generates options internally.  */

void
generate_option (size_t opt_index, const char *arg, HOST_WIDE_INT value,
		 unsigned int lang_mask, struct cl_decoded_option *decoded)
{
  const struct cl_option *option = &cl_options[opt_index];

  decoded->opt_index = opt_index;
  decoded->warn_message = NULL;
  decoded->arg = arg;
  decoded->value = value;
  decoded->errors = (option_ok_for_language (option, lang_mask)
		     ? 0
		     : CL_ERR_WRONG_LANG);

  generate_canonical_option (opt_index, arg, value, decoded);
  switch (decoded->canonical_option_num_elements)
    {
    case 1:
      decoded->orig_option_with_args_text = decoded->canonical_option[0];
      break;

    case 2:
      decoded->orig_option_with_args_text
	= opts_concat (decoded->canonical_option[0], " ",
		       decoded->canonical_option[1], NULL);
      break;

    default:
      gcc_unreachable ();
    }
}

/* Fill in *DECODED with an option for input file FILE.  */

void
generate_option_input_file (const char *file,
			    struct cl_decoded_option *decoded)
{
  decoded->opt_index = OPT_SPECIAL_input_file;
  decoded->warn_message = NULL;
  decoded->arg = file;
  decoded->orig_option_with_args_text = file;
  decoded->canonical_option_num_elements = 1;
  decoded->canonical_option[0] = file;
  decoded->canonical_option[1] = NULL;
  decoded->canonical_option[2] = NULL;
  decoded->canonical_option[3] = NULL;
  decoded->value = 1;
  decoded->errors = 0;
}

/* Helper function for listing valid choices and hint for misspelled
   value.  CANDIDATES is a vector containing all valid strings,
   STR is set to a heap allocated string that contains all those
   strings concatenated, separated by spaces, and the return value
   is the closest string from those to ARG, or NULL if nothing is
   close enough.  Callers should XDELETEVEC (STR) after using it
   to avoid memory leaks.  */

const char *
candidates_list_and_hint (const char *arg, char *&str,
			  const auto_vec <const char *> &candidates)
{
  size_t len = 0;
  int i;
  const char *candidate;
  char *p;

  FOR_EACH_VEC_ELT (candidates, i, candidate)
    len += strlen (candidate) + 1;

  str = p = XNEWVEC (char, len);
  FOR_EACH_VEC_ELT (candidates, i, candidate)
    {
      len = strlen (candidate);
      memcpy (p, candidate, len);
      p[len] = ' ';
      p += len + 1;
    }
  p[-1] = '\0';
  return find_closest_string (arg, &candidates);
}

/* Perform diagnostics for read_cmdline_option and control_warning_option
   functions.  Returns true if an error has been diagnosed.
   LOC and LANG_MASK arguments like in read_cmdline_option.
   OPTION is the option to report diagnostics for, OPT the name
   of the option as text, ARG the argument of the option (for joined
   options), ERRORS is bitmask of CL_ERR_* values.  */

static bool
cmdline_handle_error (location_t loc, const struct cl_option *option,
		      const char *opt, const char *arg, int errors,
		      unsigned int lang_mask)
{
  if (errors & CL_ERR_DISABLED)
    {
      error_at (loc, "command-line option %qs"
		     " is not supported by this configuration", opt);
      return true;
    }

  if (errors & CL_ERR_MISSING_ARG)
    {
      if (option->missing_argument_error)
	error_at (loc, option->missing_argument_error, opt);
      else
	error_at (loc, "missing argument to %qs", opt);
      return true;
    }

  if (errors & CL_ERR_UINT_ARG)
    {
      if (option->cl_byte_size)
	error_at (loc, "argument to %qs should be a non-negative integer "
		  "optionally followed by a size unit",
		  option->opt_text);
      else
	error_at (loc, "argument to %qs should be a non-negative integer",
		  option->opt_text);
      return true;
    }

  if (errors & CL_ERR_INT_RANGE_ARG)
    {
      error_at (loc, "argument to %qs is not between %d and %d",
		option->opt_text, option->range_min, option->range_max);
      return true;
    }

  if (errors & CL_ERR_ENUM_ARG)
    {
      const struct cl_enum *e = &cl_enums[option->var_enum];
      unsigned int i;
      char *s;

      auto_diagnostic_group d;
      if (e->unknown_error)
	error_at (loc, e->unknown_error, arg);
      else
	error_at (loc, "unrecognized argument in option %qs", opt);

      auto_vec <const char *> candidates;
      for (i = 0; e->values[i].arg != NULL; i++)
	{
	  if (!enum_arg_ok_for_language (&e->values[i], lang_mask))
	    continue;
	  candidates.safe_push (e->values[i].arg);
	}
      const char *hint = candidates_list_and_hint (arg, s, candidates);
      if (hint)
	inform (loc, "valid arguments to %qs are: %s; did you mean %qs?",
		option->opt_text, s, hint);
      else
	inform (loc, "valid arguments to %qs are: %s", option->opt_text, s);
      XDELETEVEC (s);

      return true;
    }

  return false;
}

/* Handle the switch DECODED (location LOC) for the language indicated
   by LANG_MASK, using the handlers in *HANDLERS and setting fields in
   OPTS and OPTS_SET and using diagnostic context DC (if not NULL) for
   diagnostic options.  */

void
read_cmdline_option (struct gcc_options *opts,
		     struct gcc_options *opts_set,
		     struct cl_decoded_option *decoded,
		     location_t loc,
		     unsigned int lang_mask,
		     const struct cl_option_handlers *handlers,
		     diagnostic_context *dc)
{
  const struct cl_option *option;
  const char *opt = decoded->orig_option_with_args_text;

  if (decoded->warn_message)
    warning_at (loc, 0, decoded->warn_message, opt);

  if (decoded->opt_index == OPT_SPECIAL_unknown)
    {
      if (handlers->unknown_option_callback (decoded))
	error_at (loc, "unrecognized command-line option %qs", decoded->arg);
      return;
    }

  if (decoded->opt_index == OPT_SPECIAL_ignore)
    return;

  if (decoded->opt_index == OPT_SPECIAL_warn_removed)
    {
      /* Warn only about positive ignored options.  */
      if (decoded->value)
	warning_at (loc, 0, "switch %qs is no longer supported", opt);
      return;
    }

  option = &cl_options[decoded->opt_index];

  if (decoded->errors
      && cmdline_handle_error (loc, option, opt, decoded->arg,
			       decoded->errors, lang_mask))
    return;

  if (decoded->errors & CL_ERR_WRONG_LANG)
    {
      handlers->wrong_lang_callback (decoded, lang_mask);
      return;
    }

  gcc_assert (!decoded->errors);

  if (!handle_option (opts, opts_set, decoded, lang_mask, DK_UNSPECIFIED,
		      loc, handlers, false, dc))
    error_at (loc, "unrecognized command-line option %qs", opt);
}

/* Set any field in OPTS, and OPTS_SET if not NULL, for option
   OPT_INDEX according to VALUE and ARG, diagnostic kind KIND,
   location LOC, using diagnostic context DC if not NULL for
   diagnostic classification.  */

void
set_option (struct gcc_options *opts, struct gcc_options *opts_set,
	    int opt_index, HOST_WIDE_INT value, const char *arg, int kind,
	    location_t loc, diagnostic_context *dc)
{
  const struct cl_option *option = &cl_options[opt_index];
  void *flag_var = option_flag_var (opt_index, opts);
  void *set_flag_var = NULL;

  if (!flag_var)
    return;

  if ((diagnostic_t) kind != DK_UNSPECIFIED && dc != NULL)
    diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);

  if (opts_set != NULL)
    set_flag_var = option_flag_var (opt_index, opts_set);

  switch (option->var_type)
    {
    case CLVC_INTEGER:
	if (option->cl_host_wide_int)
	  {
	    *(HOST_WIDE_INT *) flag_var = value;
	    if (set_flag_var)
	      *(HOST_WIDE_INT *) set_flag_var = 1;
	  }
	else
	  {
	    if (value > INT_MAX)
	      error_at (loc, "argument to %qs is bigger than %d",
			option->opt_text, INT_MAX);
	    else
	      {
		*(int *) flag_var = value;
		if (set_flag_var)
		  *(int *) set_flag_var = 1;
	      }
	  }

	break;

    case CLVC_SIZE:
	if (option->cl_host_wide_int)
	  {
	    *(HOST_WIDE_INT *) flag_var = value;
	    if (set_flag_var)
	      *(HOST_WIDE_INT *) set_flag_var = value;
	  }
	else
	  {
	    *(int *) flag_var = value;
	    if (set_flag_var)
	      *(int *) set_flag_var = value;
	  }

	break;

    case CLVC_EQUAL:
	if (option->cl_host_wide_int)
	  {
	    *(HOST_WIDE_INT *) flag_var = (value
					   ? option->var_value
					   : !option->var_value);
	    if (set_flag_var)
	      *(HOST_WIDE_INT *) set_flag_var = 1;
	  }
	else
	  {
	    *(int *) flag_var = (value
				 ? option->var_value
				 : !option->var_value);
	    if (set_flag_var)
	      *(int *) set_flag_var = 1;
	  }
	break;

    case CLVC_BIT_CLEAR:
    case CLVC_BIT_SET:
	if ((value != 0) == (option->var_type == CLVC_BIT_SET))
	  {
	    if (option->cl_host_wide_int) 
	      *(HOST_WIDE_INT *) flag_var |= option->var_value;
	    else 
	      *(int *) flag_var |= option->var_value;
	  }
	else
	  {
	    if (option->cl_host_wide_int) 
	      *(HOST_WIDE_INT *) flag_var &= ~option->var_value;
	    else 
	      *(int *) flag_var &= ~option->var_value;
	  }
	if (set_flag_var)
	  {
	    if (option->cl_host_wide_int) 
	      *(HOST_WIDE_INT *) set_flag_var |= option->var_value;
	    else
	      *(int *) set_flag_var |= option->var_value;
	  }
	break;

    case CLVC_STRING:
	*(const char **) flag_var = arg;
	if (set_flag_var)
	  *(const char **) set_flag_var = "";
	break;

    case CLVC_ENUM:
      {
	const struct cl_enum *e = &cl_enums[option->var_enum];

	e->set (flag_var, value);
	if (set_flag_var)
	  e->set (set_flag_var, 1);
      }
      break;

    case CLVC_DEFER:
	{
	  vec<cl_deferred_option> *v
	    = (vec<cl_deferred_option> *) *(void **) flag_var;
	  cl_deferred_option p = {opt_index, arg, value};
	  if (!v)
	    v = XCNEW (vec<cl_deferred_option>);
	  v->safe_push (p);
	  *(void **) flag_var = v;
	  if (set_flag_var)
	    *(void **) set_flag_var = v;
	}
	break;
    }
}

/* Return the address of the flag variable for option OPT_INDEX in
   options structure OPTS, or NULL if there is no flag variable.  */

void *
option_flag_var (int opt_index, struct gcc_options *opts)
{
  const struct cl_option *option = &cl_options[opt_index];

  if (option->flag_var_offset == (unsigned short) -1)
    return NULL;
  return (void *)(((char *) opts) + option->flag_var_offset);
}

/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
   or -1 if it isn't a simple on-off switch
   (or if the value is unknown, typically set later in target).  */

int
option_enabled (int opt_idx, unsigned lang_mask, void *opts)
{
  const struct cl_option *option = &(cl_options[opt_idx]);

  /* A language-specific option can only be considered enabled when it's
     valid for the current language.  */
  if (!(option->flags & CL_COMMON)
      && (option->flags & CL_LANG_ALL)
      && !(option->flags & lang_mask))
    return 0;

  struct gcc_options *optsg = (struct gcc_options *) opts;
  void *flag_var = option_flag_var (opt_idx, optsg);

  if (flag_var)
    switch (option->var_type)
      {
      case CLVC_INTEGER:
	if (option->cl_host_wide_int)
	  {
	    HOST_WIDE_INT v = *(HOST_WIDE_INT *) flag_var;
	    return v != 0 ? (v < 0 ? -1 : 1) : 0;
	  }
	else
	  {
	    int v = *(int *) flag_var;
	    return v != 0 ? (v < 0 ? -1 : 1) : 0;
	  }

      case CLVC_EQUAL:
	if (option->cl_host_wide_int) 
	  return *(HOST_WIDE_INT *) flag_var == option->var_value;
	else
	  return *(int *) flag_var == option->var_value;

      case CLVC_BIT_CLEAR:
	if (option->cl_host_wide_int) 
	  return (*(HOST_WIDE_INT *) flag_var & option->var_value) == 0;
	else
	  return (*(int *) flag_var & option->var_value) == 0;

      case CLVC_BIT_SET:
	if (option->cl_host_wide_int) 
	  return (*(HOST_WIDE_INT *) flag_var & option->var_value) != 0;
	else 
	  return (*(int *) flag_var & option->var_value) != 0;

      case CLVC_SIZE:
	if (option->cl_host_wide_int)
	  return *(HOST_WIDE_INT *) flag_var != -1;
	else
	  return *(int *) flag_var != -1;

      case CLVC_STRING:
      case CLVC_ENUM:
      case CLVC_DEFER:
	break;
      }
  return -1;
}

/* Fill STATE with the current state of option OPTION in OPTS.  Return
   true if there is some state to store.  */

bool
get_option_state (struct gcc_options *opts, int option,
		  struct cl_option_state *state)
{
  void *flag_var = option_flag_var (option, opts);

  if (flag_var == 0)
    return false;

  switch (cl_options[option].var_type)
    {
    case CLVC_INTEGER:
    case CLVC_EQUAL:
    case CLVC_SIZE:
      state->data = flag_var;
      state->size = (cl_options[option].cl_host_wide_int
		     ? sizeof (HOST_WIDE_INT)
		     : sizeof (int));
      break;

    case CLVC_BIT_CLEAR:
    case CLVC_BIT_SET:
      state->ch = option_enabled (option, -1, opts);
      state->data = &state->ch;
      state->size = 1;
      break;

    case CLVC_STRING:
      state->data = *(const char **) flag_var;
      if (state->data == 0)
	state->data = "";
      state->size = strlen ((const char *) state->data) + 1;
      break;

    case CLVC_ENUM:
      state->data = flag_var;
      state->size = cl_enums[cl_options[option].var_enum].var_size;
      break;

    case CLVC_DEFER:
      return false;
    }
  return true;
}

/* Set a warning option OPT_INDEX (language mask LANG_MASK, option
   handlers HANDLERS) to have diagnostic kind KIND for option
   structures OPTS and OPTS_SET and diagnostic context DC (possibly
   NULL), at location LOC (UNKNOWN_LOCATION for -Werror=).  ARG is the
   argument of the option for joined options, or NULL otherwise.  If IMPLY,
   the warning option in question is implied at this point.  This is
   used by -Werror= and #pragma GCC diagnostic.  */

void
control_warning_option (unsigned int opt_index, int kind, const char *arg,
			bool imply, location_t loc, unsigned int lang_mask,
			const struct cl_option_handlers *handlers,
			struct gcc_options *opts,
			struct gcc_options *opts_set,
			diagnostic_context *dc)
{
  if (cl_options[opt_index].alias_target != N_OPTS)
    {
      gcc_assert (!cl_options[opt_index].cl_separate_alias
		  && !cl_options[opt_index].cl_negative_alias);
      if (cl_options[opt_index].alias_arg)
	arg = cl_options[opt_index].alias_arg;
      opt_index = cl_options[opt_index].alias_target;
    }
  if (opt_index == OPT_SPECIAL_ignore || opt_index == OPT_SPECIAL_warn_removed)
    return;
  if (dc)
    diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
  if (imply)
    {
      const struct cl_option *option = &cl_options[opt_index];

      /* -Werror=foo implies -Wfoo.  */
      if (option->var_type == CLVC_INTEGER
	  || option->var_type == CLVC_ENUM
	  || option->var_type == CLVC_SIZE)
	{
	  HOST_WIDE_INT value = 1;

	  if (arg && *arg == '\0' && !option->cl_missing_ok)
	    arg = NULL;

	  if ((option->flags & CL_JOINED) && arg == NULL)
	    {
	      cmdline_handle_error (loc, option, option->opt_text, arg,
				    CL_ERR_MISSING_ARG, lang_mask);
	      return;
	    }

	  /* If the switch takes an integer argument, convert it.  */
	  if (arg && (option->cl_uinteger || option->cl_host_wide_int))
	    {
	      int error = 0;
	      value = *arg ? integral_argument (arg, &error,
						option->cl_byte_size) : 0;
	      if (error)
		{
		  cmdline_handle_error (loc, option, option->opt_text, arg,
					CL_ERR_UINT_ARG, lang_mask);
		  return;
		}
	    }

	  /* If the switch takes an enumerated argument, convert it.  */
	  if (arg && option->var_type == CLVC_ENUM)
	    {
	      const struct cl_enum *e = &cl_enums[option->var_enum];

	      if (enum_arg_to_value (e->values, arg, &value, lang_mask))
		{
		  const char *carg = NULL;

		  if (enum_value_to_arg (e->values, &carg, value, lang_mask))
		    arg = carg;
		  gcc_assert (carg != NULL);
		}
	      else
		{
		  cmdline_handle_error (loc, option, option->opt_text, arg,
					CL_ERR_ENUM_ARG, lang_mask);
		  return;
		}
	    }

	  handle_generated_option (opts, opts_set,
				   opt_index, arg, value, lang_mask,
				   kind, loc, handlers, false, dc);
	}
    }
}

/* Parse options in COLLECT_GCC_OPTIONS and push them on ARGV_OBSTACK.
   Store number of arguments into ARGC_P.  */

void
parse_options_from_collect_gcc_options (const char *collect_gcc_options,
					obstack *argv_obstack,
					int *argc_p)
{
  char *argv_storage = xstrdup (collect_gcc_options);
  int j, k;

  for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
    {
      if (argv_storage[j] == '\'')
	{
	  obstack_ptr_grow (argv_obstack, &argv_storage[k]);
	  ++j;
	  do
	    {
	      if (argv_storage[j] == '\0')
		fatal_error (input_location,
			     "malformed %<COLLECT_GCC_OPTIONS%>");
	      else if (startswith (&argv_storage[j], "'\\''"))
		{
		  argv_storage[k++] = '\'';
		  j += 4;
		}
	      else if (argv_storage[j] == '\'')
		break;
	      else
		argv_storage[k++] = argv_storage[j++];
	    }
	  while (1);
	  argv_storage[k++] = '\0';
	}
    }

  obstack_ptr_grow (argv_obstack, NULL);
  *argc_p = obstack_object_size (argv_obstack) / sizeof (void *) - 1;
}

/* Prepend -Xassembler for each option in COLLECT_AS_OPTIONS,
   and push on O.  */

void prepend_xassembler_to_collect_as_options (const char *collect_as_options,
					       obstack *o)
{
  obstack opts_obstack;
  int opts_count;

  obstack_init (&opts_obstack);
  parse_options_from_collect_gcc_options (collect_as_options,
					  &opts_obstack, &opts_count);
  const char **assembler_opts = XOBFINISH (&opts_obstack, const char **);

  for (int i = 0; i < opts_count; i++)
    {
      obstack_grow (o, " '-Xassembler' ",
		    strlen (" '-Xassembler' "));
      const char *opt = assembler_opts[i];
      obstack_1grow (o, '\'');
      obstack_grow (o, opt, strlen (opt));
      obstack_1grow (o, '\'');
    }
}
