summaryrefslogtreecommitdiff
path: root/gcc/opts-common.c
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-20 21:02:46 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-20 21:02:46 +0000
commit615ef0bb3fc9c4ebb5349ae424373e14bd06b7ed (patch)
tree2c4f1fab67e1d031a842bdda5d4777aed748b3b5 /gcc/opts-common.c
parentcafb8a7729b9f3cde334d1890dff54478b0fb1dd (diff)
downloadgcc-615ef0bb3fc9c4ebb5349ae424373e14bd06b7ed.tar.gz
PR other/32998
* opth-gen.awk: Generate definitions of OPT_SPECIAL_unknown, OPT_SPECIAL_program_name and OPT_SPECIAL_input_file. * opts-common.c (find_opt): Return OPT_SPECIAL_unknown on failure. (decode_cmdline_option): Update for this return value. Set orig_option_with_args_text field. Set arg field for unknown options. Make static. (decode_cmdline_options_to_array): New. (prune_options): Update handling of find_opt return value. * opts.c (read_cmdline_option): Take decoded option. Return void. (read_cmdline_options): Take decoded options. (decode_options): Add parameters for decoded options. Use decode_cmdline_options_to_array. Use decoded options for -O scan. Use integral_argument for -O parameters. Update call to read_cmdline_options. (enable_warning_as_error): Update handling of find_opt return value. * opts.h: Update comment on unknown options. (struct cl_decoded_option): Update comments on opt_index and arg. Add orig_option_with_args_text. (decode_cmdline_option): Remove. (decode_cmdline_options_to_array): Declare. (decode_options): Update prototype. * toplev.c (save_argv): Remove. (save_decoded_options, save_decoded_options_count): New. (read_integral_parameter): Remove. (print_switch_values): Use decoded options. (toplev_main): Don't set save_argv. Update call to decode_options. * toplev.h (read_integral_parameter): Remove. * varasm.c (elf_record_gcc_switches): Don't handle holding back names. c-family: * c-common.c (parse_optimize_options): Update call to decode_options. fortran: * options.c (gfc_handle_option): Don't handle N_OPTS. testsuite: * gcc.dg/opts-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161053 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/opts-common.c')
-rw-r--r--gcc/opts-common.c97
1 files changed, 84 insertions, 13 deletions
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 513a766e520..cde8ccfe29b 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -25,8 +25,8 @@ along with GCC; see the file COPYING3. If not see
#include "options.h"
/* Perform a binary search to find which option the command-line INPUT
- matches. Returns its index in the option array, and N_OPTS
- (cl_options_count) on failure.
+ 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
@@ -73,8 +73,8 @@ find_opt (const char *input, int lang_mask)
}
/* This is the switch that is the best match but for a different
- front end, or cl_options_count if there is no match at all. */
- match_wrong_lang = cl_options_count;
+ 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
@@ -94,7 +94,7 @@ find_opt (const char *input, int lang_mask)
/* If we haven't remembered a prior match, remember this
one. Any prior match is necessarily better. */
- if (match_wrong_lang == cl_options_count)
+ if (match_wrong_lang == OPT_SPECIAL_unknown)
match_wrong_lang = mn;
}
@@ -104,7 +104,7 @@ find_opt (const char *input, int lang_mask)
}
while (mn != cl_options_count);
- /* Return the best wrong match, or cl_options_count if none. */
+ /* Return the best wrong match, or OPT_SPECIAL_unknown if none. */
return match_wrong_lang;
}
@@ -129,7 +129,7 @@ integral_argument (const char *arg)
LANG_MASK, into the structure *DECODED. Returns the number of
switches consumed. */
-unsigned int
+static unsigned int
decode_cmdline_option (const char **argv, unsigned int lang_mask,
struct cl_decoded_option *decoded)
{
@@ -144,7 +144,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
opt = argv[0];
opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
- if (opt_index == cl_options_count
+ if (opt_index == OPT_SPECIAL_unknown
&& (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
&& opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
{
@@ -160,8 +160,11 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
}
- if (opt_index == cl_options_count)
- goto done;
+ if (opt_index == OPT_SPECIAL_unknown)
+ {
+ arg = argv[0];
+ goto done;
+ }
option = &cl_options[opt_index];
@@ -169,7 +172,8 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
unrecognized. */
if (!value && (option->flags & CL_REJECT_NEGATIVE))
{
- opt_index = cl_options_count;
+ opt_index = OPT_SPECIAL_unknown;
+ arg = argv[0];
goto done;
}
@@ -237,9 +241,76 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
decoded->arg = arg;
decoded->value = value;
decoded->errors = errors;
+ switch (result)
+ {
+ case 1:
+ decoded->orig_option_with_args_text = argv[0];
+ break;
+ case 2:
+ decoded->orig_option_with_args_text = concat (argv[0], " ",
+ argv[1], NULL);
+ break;
+ default:
+ gcc_unreachable ();
+ }
return result;
}
+/* 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
+ applicable for decoding. 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;
+
+ opt_array = XNEWVEC (struct cl_decoded_option, argc);
+
+ opt_array[0].opt_index = OPT_SPECIAL_program_name;
+ opt_array[0].arg = argv[0];
+ opt_array[0].orig_option_with_args_text = argv[0];
+ 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')
+ {
+ opt_array[num_decoded_options].opt_index = OPT_SPECIAL_input_file;
+ opt_array[num_decoded_options].arg = opt;
+ opt_array[num_decoded_options].orig_option_with_args_text = opt;
+ opt_array[num_decoded_options].value = 1;
+ opt_array[num_decoded_options].errors = 0;
+ num_decoded_options++;
+ n = 1;
+ continue;
+ }
+
+ n = decode_cmdline_option (argv + i, lang_mask,
+ &opt_array[num_decoded_options]);
+ num_decoded_options++;
+ }
+
+ opt_array = XRESIZEVEC (struct cl_decoded_option, opt_array,
+ num_decoded_options);
+ *decoded_options = opt_array;
+ *decoded_options_count = num_decoded_options;
+}
+
/* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
next one is the same as ORIG_NEXT_OPT_IDX. */
@@ -281,7 +352,7 @@ prune_options (int *argcp, char ***argvp)
const char *opt = (*argvp) [i];
opt_index = find_opt (opt + 1, -1);
- if (opt_index == cl_options_count
+ if (opt_index == OPT_SPECIAL_unknown
&& (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
&& opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
{
@@ -300,7 +371,7 @@ prune_options (int *argcp, char ***argvp)
free (dup);
}
- if (opt_index == cl_options_count)
+ if (opt_index == OPT_SPECIAL_unknown)
{
cont:
options [i] = 0;