summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-16 10:15:15 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-16 10:15:15 +0000
commite28aa11462a447d3a30e8a53a7058d1158e33e5f (patch)
treea8e55701ad8152ef11268c33109062e262817e2e /gcc
parent9a14ba4fd861436294514c3008d03f1f77de058a (diff)
downloadgcc-e28aa11462a447d3a30e8a53a7058d1158e33e5f.tar.gz
* common.opt: Add driver options.
(auxbase, auxbase-strip, quiet, version): Mark RejectDriver. * doc/options.texi (Driver, RejectDriver): Document. * gcc.c (pass_exit_codes, print_search_dirs, print_file_name, print_prog_name, print_multi_directory, print_sysroot, print_multi_os_directory, print_multi_lib, print_sysroot_headers_suffix, report_times, combine_flag, use_pipes, wrapper_string): Remove. (save_switch, driver_unknown_option_callback, driver_wrong_lang_callback, driver_post_handling_callback, driver_handle_option): New. (spec_lang, last_language_n_infiles): Make file-scope static instead of local to process_command. (process_command): Use decode_cmdline_options_to_array and read_cmdline_option for option processing. Compute have_c in prescan of decoded options. * opt-functions.awk (switch_flags): Handle Driver and RejectDriver. (var_type, var_type_struct): Handle Separate options as generating const char * variables. * opts-common.c (decode_cmdline_option): Expect CL_COMMON and CL_TARGET to be passed by caller if required. (decode_cmdline_options_to_array): Update comment. * opts.c (complain_wrong_lang): Handle options only valid for the driver. (decode_options): Update call to decode_cmdline_options_to_array. (print_filtered_help): Ignore driver-only options. (print_specific_help): Ignore CL_DRIVER. (common_handle_option): Don't call print_specific_help for CL_DRIVER. * opts.h (CL_DRIVER, CL_REJECT_DRIVER): Define. (CL_PARAMS, CL_WARNING, CL_OPTIMIZATION, CL_TARGET, CL_COMMON): Update values. c-family: * c.opt (MDX, MMDX, lang-asm): Mark RejectDriver. fortran: * lang.opt (MDX, MMDX): Mark RejectDriver. java: * lang.opt (MD_, MMD_, version): Mark RejectDriver. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163279 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog36
-rw-r--r--gcc/c-family/ChangeLog4
-rw-r--r--gcc/c-family/c.opt6
-rw-r--r--gcc/common.opt161
-rw-r--r--gcc/doc/options.texi8
-rw-r--r--gcc/fortran/ChangeLog4
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/gcc.c1043
-rw-r--r--gcc/java/ChangeLog4
-rw-r--r--gcc/java/lang.opt6
-rw-r--r--gcc/opt-functions.awk6
-rw-r--r--gcc/opts-common.c20
-rw-r--r--gcc/opts.c37
-rw-r--r--gcc/opts.h12
14 files changed, 740 insertions, 611 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 57df2abca9c..92ae2640778 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,39 @@
+2010-08-16 Joseph Myers <joseph@codesourcery.com>
+
+ * common.opt: Add driver options.
+ (auxbase, auxbase-strip, quiet, version): Mark RejectDriver.
+ * doc/options.texi (Driver, RejectDriver): Document.
+ * gcc.c (pass_exit_codes, print_search_dirs, print_file_name,
+ print_prog_name, print_multi_directory, print_sysroot,
+ print_multi_os_directory, print_multi_lib,
+ print_sysroot_headers_suffix, report_times, combine_flag,
+ use_pipes, wrapper_string): Remove.
+ (save_switch, driver_unknown_option_callback,
+ driver_wrong_lang_callback, driver_post_handling_callback,
+ driver_handle_option): New.
+ (spec_lang, last_language_n_infiles): Make file-scope static
+ instead of local to process_command.
+ (process_command): Use decode_cmdline_options_to_array and
+ read_cmdline_option for option processing. Compute have_c in
+ prescan of decoded options.
+ * opt-functions.awk (switch_flags): Handle Driver and
+ RejectDriver.
+ (var_type, var_type_struct): Handle Separate options as generating
+ const char * variables.
+ * opts-common.c (decode_cmdline_option): Expect CL_COMMON and
+ CL_TARGET to be passed by caller if required.
+ (decode_cmdline_options_to_array): Update comment.
+ * opts.c (complain_wrong_lang): Handle options only valid for the
+ driver.
+ (decode_options): Update call to decode_cmdline_options_to_array.
+ (print_filtered_help): Ignore driver-only options.
+ (print_specific_help): Ignore CL_DRIVER.
+ (common_handle_option): Don't call print_specific_help for
+ CL_DRIVER.
+ * opts.h (CL_DRIVER, CL_REJECT_DRIVER): Define.
+ (CL_PARAMS, CL_WARNING, CL_OPTIMIZATION, CL_TARGET, CL_COMMON):
+ Update values.
+
2010-08-16 Richard Guenther <rguenther@suse.de>
* tree-cfg.c (verify_types_in_gimple_reference): Verify
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 56aabb45665..80034e6d6ec 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,7 @@
+2010-08-16 Joseph Myers <joseph@codesourcery.com>
+
+ * c.opt (MDX, MMDX, lang-asm): Mark RejectDriver.
+
2010-08-12 Joseph Myers <joseph@codesourcery.com>
* c.opt (MD, MMD): Change to MDX and MMDX.
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 98569cbae12..d1aa10e1887 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -73,7 +73,7 @@ C ObjC C++ ObjC++
Generate make dependencies
MDX
-C ObjC C++ ObjC++ Separate MissingArgError(missing filename after %qs)
+C ObjC C++ ObjC++ RejectDriver Separate MissingArgError(missing filename after %qs)
-MD Generate make dependencies and compile
MF
@@ -89,7 +89,7 @@ C ObjC C++ ObjC++
Like -M but ignore system header files
MMDX
-C ObjC C++ ObjC++ Separate MissingArgError(missing filename after %qs)
+C ObjC C++ ObjC++ RejectDriver Separate MissingArgError(missing filename after %qs)
-MMD Like -MD but ignore system header files
MP
@@ -926,7 +926,7 @@ C ObjC C++ ObjC++ Joined Separate
-iwithprefixbefore <dir> Add <dir> to the end of the main include path
lang-asm
-C Undocumented
+C Undocumented RejectDriver
nostdinc
C ObjC C++ ObjC++
diff --git a/gcc/common.opt b/gcc/common.opt
index 1285ff037fb..96d0c9f3ec8 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -23,39 +23,51 @@
; Please try to keep this file in ASCII collating order.
+###
+Driver
+
-help
-Common
+Common Driver
Display this information
-help=
-Common Report Joined
+Common Driver Report Joined
--help=<class> Display descriptions of a specific class of options. <class> is one or more of optimizers, target, warnings, undocumented, params
-target-help
-Common
+Common Driver
Alias for --help=target
;; The following four entries are to work around the gcc driver
;; program's insatiable desire to turn options starting with a
;; double dash (--) into options starting with a dash f (-f).
fhelp
-Common Var(help_flag)
+Common Driver Var(help_flag)
fhelp=
-Common Joined
+Common Driver Joined
ftarget-help
-Common
+Common Driver
fversion
-Common
+Common Driver
-param
Common Separate
--param <param>=<value> Set parameter <param> to value. See below for a complete list of parameters
+-sysroot=
+Driver JoinedOrMissing
+
-version
-Common
+Common Driver
+
+B
+Driver Joined Separate
+
+E
+Driver
O
Common JoinedOrMissing Optimization
@@ -69,10 +81,22 @@ Ofast
Common Optimization
Optimize for speed disregarding exact standards compliance
+S
+Driver
+
W
Common RejectNegative Var(extra_warnings) Warning
This switch is deprecated; use -Wextra instead
+Wa,
+Driver JoinedOrMissing
+
+Wl,
+Driver JoinedOrMissing
+
+Wp,
+Driver JoinedOrMissing
+
Waggregate-return
Common Var(warn_aggregate_return) Warning
Warn about returning structures, unions or arrays
@@ -260,6 +284,15 @@ Wcoverage-mismatch
Common Var(warn_coverage_mismatch) Init(1) Warning
Warn in case profiles in -fprofile-use do not match
+Xassembler
+Driver Separate
+
+Xlinker
+Driver Separate
+
+Xpreprocessor
+Driver Separate
+
aux-info
Common Separate
-aux-info <file> Emit declaration information into <file>
@@ -268,10 +301,16 @@ aux-info=
Common Joined
auxbase
-Common Separate
+Common Separate RejectDriver
auxbase-strip
-Common Separate
+Common Separate RejectDriver
+
+combine
+Driver Var(combine_flag)
+
+c
+Driver
d
Common Joined
@@ -285,6 +324,15 @@ dumpdir
Common Separate
-dumpdir <dir> Set the directory name to be used for dumps
+dumpmachine
+Driver
+
+dumpspecs
+Driver
+
+dumpversion
+Driver
+
; The version of the C++ ABI in use. The following values are allowed:
;
; 0: The version of the ABI believed most conformant with the C++ ABI
@@ -410,12 +458,16 @@ fcommon
Common Report Var(flag_no_common,0) Optimization
Do not put uninitialized globals in the common section
+fcompare-debug
+Driver
+; Converted by the driver to -fcompare-debug= options.
+
fcompare-debug=
-Common JoinedOrMissing RejectNegative Var(flag_compare_debug_opt)
+Common Driver JoinedOrMissing RejectNegative Var(flag_compare_debug_opt)
-fcompare-debug[=<opts>] Compile with and without e.g. -gtoggle, and compare the final-insns dump
fcompare-debug-second
-Common RejectNegative Var(flag_compare_debug)
+Common Driver RejectNegative Var(flag_compare_debug)
Run only the second compilation of -fcompare-debug
fconserve-stack
@@ -1587,14 +1639,23 @@ iplugindir=
Common Joined Var(plugindir_string) Init(0)
-iplugindir=<dir> Set <dir> to be the default plugin directory
+l
+Driver Joined Separate
+
+no-canonical-prefixes
+Driver
+
o
-Common Joined Separate MissingArgError(missing filename after %qs)
+Common Driver Joined Separate MissingArgError(missing filename after %qs)
-o <file> Place output into <file>
p
Common Var(profile_flag)
Enable function profiling
+pass-exit-codes
+Driver Var(pass_exit_codes)
+
pedantic
Common Var(pedantic)
Issue warnings needed for strict compliance to the standard
@@ -1603,22 +1664,92 @@ pedantic-errors
Common
Like -pedantic but issue them as errors
+pipe
+Driver Var(use_pipes)
+
+print-file-name=
+Driver JoinedOrMissing Var(print_file_name)
+
+print-libgcc-file-name
+Driver
+
+print-multi-directory
+Driver Var(print_multi_directory)
+
+print-multi-lib
+Driver Var(print_multi_lib)
+
+print-multi-os-directory
+Driver Var(print_multi_os_directory)
+
+print-prog-name=
+Driver JoinedOrMissing Var(print_prog_name)
+
+print-search-dirs
+Driver Var(print_search_dirs)
+
+print-sysroot
+Driver Var(print_sysroot)
+
+print-sysroot-headers-suffix
+Driver Var(print_sysroot_headers_suffix)
+
quiet
-Common Var(quiet_flag)
+Common Var(quiet_flag) RejectDriver
Do not display functions compiled or elapsed time
+save-temps
+Driver
+
+save-temps=
+Driver Joined
+
+time
+Driver Var(report_times)
+
+time=
+Driver JoinedOrMissing
+
+v
+Driver
+
version
-Common Var(version_flag)
+Common Var(version_flag) RejectDriver
Display the compiler's version
w
Common Var(inhibit_warnings)
Suppress warnings
+wrapper
+Driver Separate Var(wrapper_string)
+
+x
+Driver Joined Separate
+
shared
Common RejectNegative Negative(pie)
Create a shared library
+shared-libgcc
+Driver
+
+specs
+Driver Separate
+
+specs=
+Driver Joined
+
+static-libgcc
+Driver
+
+static-libgfortran
+Driver
+; Documented for Fortran, but always accepted by driver.
+
+static-libstdc++
+Driver
+
pie
Common RejectNegative Negative(shared)
Create a position independent executable
diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi
index b14b2b497fa..fff148defad 100644
--- a/gcc/doc/options.texi
+++ b/gcc/doc/options.texi
@@ -102,6 +102,10 @@ The option is available for all languages and targets.
@item Target
The option is available for all languages but is target-specific.
+@item Driver
+The option is handled by the compiler driver using code not shared
+with the compilers proper (@file{cc1} etc.).
+
@item @var{language}
The option is available when compiling for the given language.
@@ -109,6 +113,10 @@ It is possible to specify several different languages for the same
option. Each @var{language} must have been declared by an earlier
@code{Language} record. @xref{Option file format}.
+@item RejectDriver
+The option is only handled by the compilers proper (@file{cc1} etc.)@:
+and should not be accepted by the driver.
+
@item RejectNegative
The option does not have a ``no-'' form. All options beginning with
``f'', ``W'' or ``m'' are assumed to have a ``no-'' form unless this
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index dbb06cfb19f..cf8eb49c0a4 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,7 @@
+2010-08-16 Joseph Myers <joseph@codesourcery.com>
+
+ * lang.opt (MDX, MMDX): Mark RejectDriver.
+
2010-08-15 Janus Weil <janus@gcc.gnu.org>
* trans-expr.c (gfc_trans_assign_vtab_procs): Clean up (we don't have
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 453a2413624..dea14511baa 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -61,7 +61,7 @@ Fortran
; Documented in C
MDX
-Fortran Separate
+Fortran Separate RejectDriver
; Documented in C
MF
@@ -77,7 +77,7 @@ Fortran
; Documented in C
MMDX
-Fortran Separate
+Fortran Separate RejectDriver
; Documented in C
MP
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 8aef83b82ef..f0a037c16b1 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -140,44 +140,9 @@ int is_cpp_driver;
/* Flag set to nonzero if an @file argument has been supplied to gcc. */
static bool at_file_supplied;
-/* Flag saying to pass the greatest exit code returned by a sub-process
- to the calling program. */
-static int pass_exit_codes;
-
/* Definition of string containing the arguments given to configure. */
#include "configargs.h"
-/* Flag saying to print the directories gcc will search through looking for
- programs, libraries, etc. */
-
-static int print_search_dirs;
-
-/* Flag saying to print the full filename of this file
- as found through our usual search mechanism. */
-
-static const char *print_file_name = NULL;
-
-/* As print_file_name, but search for executable file. */
-
-static const char *print_prog_name = NULL;
-
-/* Flag saying to print the relative path we'd use to
- find libgcc.a given the current compiler flags. */
-
-static int print_multi_directory;
-
-static int print_sysroot;
-
-/* Flag saying to print the relative path we'd use to
- find OS libraries given the current compiler flags. */
-
-static int print_multi_os_directory;
-
-/* Flag saying to print the list of subdirectories and
- compiler flags used to select them in a standard form. */
-
-static int print_multi_lib;
-
/* Flag saying to print the command line options understood by gcc and its
sub-processes. */
@@ -187,11 +152,6 @@ static int print_help_list;
static int print_version;
-/* Flag saying to print the sysroot suffix used for searching for
- headers. */
-
-static int print_sysroot_headers_suffix;
-
/* Flag indicating whether we should print the command and arguments */
static int verbose_flag;
@@ -207,11 +167,6 @@ static int verbose_only_flag;
static int print_subprocess_help;
-/* Flag indicating whether we should report subprocess execution times
- (if this is supported by the system - see pexecute.c). */
-
-static int report_times;
-
/* Whether we should report subprocess execution times to a file. */
FILE *report_times_to_file = NULL;
@@ -250,15 +205,6 @@ static enum save_temps {
static char *save_temps_prefix = 0;
static size_t save_temps_length = 0;
-/* Nonzero means pass multiple source files to the compiler at one time. */
-
-static int combine_flag = 0;
-
-/* Nonzero means use pipes to communicate between subprocesses.
- Overridden by either of the above two flags. */
-
-static int use_pipes;
-
/* The compiler version. */
static const char *compiler_version;
@@ -295,14 +241,6 @@ static struct obstack obstack;
static struct obstack collect_obstack;
-/* This is a list of a wrapper program and its arguments.
- e.g. wrapper_string of "strace,-c"
- will cause all programs to run as
- strace -c program arguments
- instead of just
- program arguments */
-static const char *wrapper_string;
-
/* Forward declaration for prototypes. */
struct path_prefix;
struct prefix_list;
@@ -3506,6 +3444,448 @@ alloc_switch (void)
}
}
+/* Save an option OPT with N_ARGS arguments in array ARGS, marking it
+ as validated if VALIDATED. */
+
+static void
+save_switch (const char *opt, size_t n_args, const char *const *args,
+ bool validated)
+{
+ alloc_switch ();
+ switches[n_switches].part1 = opt + 1;
+ if (n_args == 0)
+ switches[n_switches].args = 0;
+ else
+ {
+ switches[n_switches].args = XNEWVEC (const char *, n_args + 1);
+ memcpy (switches[n_switches].args, args, n_args * sizeof (const char *));
+ switches[n_switches].args[n_args] = NULL;
+ }
+
+ switches[n_switches].live_cond = 0;
+ switches[n_switches].validated = validated;
+ switches[n_switches].ordering = 0;
+ n_switches++;
+}
+
+/* Handle an option DECODED that is unknown to the option-processing
+ machinery, but may be known to specs. */
+
+static bool
+driver_unknown_option_callback (const struct cl_decoded_option *decoded)
+{
+ save_switch (decoded->canonical_option[0],
+ decoded->canonical_option_num_elements - 1,
+ &decoded->canonical_option[1], false);
+
+ return false;
+}
+
+/* Handle an option DECODED that is not marked as CL_DRIVER.
+ LANG_MASK will always be CL_DRIVER. */
+
+static void
+driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
+ unsigned int lang_mask ATTRIBUTE_UNUSED)
+{
+ /* At this point, non-driver options are accepted (and expected to
+ be passed down by specs) unless marked to be rejected by the
+ driver. Options to be rejected by the driver but accepted by the
+ compilers proper are treated just like completely unknown
+ options. */
+ const struct cl_option *option = &cl_options[decoded->opt_index];
+
+ if (option->flags & CL_REJECT_DRIVER)
+ error ("unrecognized command line option %qs",
+ decoded->orig_option_with_args_text);
+ else
+ driver_unknown_option_callback (decoded);
+}
+
+/* Note that an option (index OPT_INDEX, argument ARG, value VALUE)
+ has been successfully handled with a handler for mask MASK. */
+
+static void
+driver_post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
+ unsigned int mask ATTRIBUTE_UNUSED)
+{
+ /* Nothing to do here. */
+}
+
+static const char *spec_lang = 0;
+static int last_language_n_infiles;
+
+/* Handle a driver option; arguments and return value as for
+ handle_option. */
+
+static bool
+driver_handle_option (const struct cl_decoded_option *decoded,
+ unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
+ const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
+{
+ size_t opt_index = decoded->opt_index;
+ const char *arg = decoded->arg;
+ const char *compare_debug_replacement_opt;
+ int value = decoded->value;
+ bool validated = false;
+ bool do_save = true;
+
+ gcc_assert (kind == DK_UNSPECIFIED);
+
+ switch (opt_index)
+ {
+ case OPT_dumpspecs:
+ {
+ struct spec_list *sl;
+ init_spec ();
+ for (sl = specs; sl; sl = sl->next)
+ printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
+ if (link_command_spec)
+ printf ("*link_command:\n%s\n\n", link_command_spec);
+ exit (0);
+ }
+
+ case OPT_dumpversion:
+ printf ("%s\n", spec_version);
+ exit (0);
+
+ case OPT_dumpmachine:
+ printf ("%s\n", spec_machine);
+ exit (0);
+
+ case OPT_fversion:
+ /* translate_options () has turned --version into -fversion. */
+ print_version = 1;
+
+ /* CPP driver cannot obtain switch from cc1_options. */
+ if (is_cpp_driver)
+ add_preprocessor_option ("--version", strlen ("--version"));
+ add_assembler_option ("--version", strlen ("--version"));
+ add_linker_option ("--version", strlen ("--version"));
+ break;
+
+ case OPT_fhelp:
+ /* translate_options () has turned --help into -fhelp. */
+ print_help_list = 1;
+
+ /* CPP driver cannot obtain switch from cc1_options. */
+ if (is_cpp_driver)
+ add_preprocessor_option ("--help", 6);
+ add_assembler_option ("--help", 6);
+ add_linker_option ("--help", 6);
+ break;
+
+ case OPT_fhelp_:
+ /* translate_options () has turned --help into -fhelp. */
+ print_subprocess_help = 2;
+ break;
+
+ case OPT_ftarget_help:
+ /* translate_options() has turned --target-help into -ftarget-help. */
+ print_subprocess_help = 1;
+
+ /* CPP driver cannot obtain switch from cc1_options. */
+ if (is_cpp_driver)
+ add_preprocessor_option ("--target-help", 13);
+ add_assembler_option ("--target-help", 13);
+ add_linker_option ("--target-help", 13);
+ break;
+
+ case OPT_pass_exit_codes:
+ case OPT_print_search_dirs:
+ case OPT_print_file_name_:
+ case OPT_print_prog_name_:
+ case OPT_print_multi_lib:
+ case OPT_print_multi_directory:
+ case OPT_print_sysroot:
+ case OPT_print_multi_os_directory:
+ case OPT_print_sysroot_headers_suffix:
+ case OPT_time:
+ case OPT_wrapper:
+ /* These options set the variables specified in common.opt
+ automatically, and do not need to be saved for spec
+ processing. */
+ do_save = false;
+ break;
+
+ case OPT_print_libgcc_file_name:
+ print_file_name = "libgcc.a";
+ do_save = false;
+ break;
+
+ case OPT_fcompare_debug_second:
+ compare_debug_second = 1;
+ break;
+
+ case OPT_fcompare_debug:
+ switch (value)
+ {
+ case 0:
+ compare_debug_replacement_opt = "-fcompare-debug=";
+ arg = "";
+ goto compare_debug_with_arg;
+
+ case 1:
+ compare_debug_replacement_opt = "-fcompare-debug=-gtoggle";
+ arg = "-gtoggle";
+ goto compare_debug_with_arg;
+
+ default:
+ gcc_unreachable ();
+ }
+ break;
+
+ case OPT_fcompare_debug_:
+ compare_debug_replacement_opt = decoded->canonical_option[0];
+ compare_debug_with_arg:
+ gcc_assert (decoded->canonical_option_num_elements == 1);
+ gcc_assert (arg != NULL);
+ if (arg)
+ compare_debug = 1;
+ else
+ compare_debug = -1;
+ if (compare_debug < 0)
+ compare_debug_opt = NULL;
+ else
+ compare_debug_opt = arg;
+ save_switch (compare_debug_replacement_opt, 0, NULL, validated);
+ return true;
+
+ case OPT_Wa_:
+ {
+ int prev, j;
+ /* Pass the rest of this option to the assembler. */
+
+ /* Split the argument at commas. */
+ prev = 0;
+ for (j = 0; arg[j]; j++)
+ if (arg[j] == ',')
+ {
+ add_assembler_option (arg + prev, j - prev);
+ prev = j + 1;
+ }
+
+ /* Record the part after the last comma. */
+ add_assembler_option (arg + prev, j - prev);
+ }
+ do_save = false;
+ break;
+
+ case OPT_Wp_:
+ {
+ int prev, j;
+ /* Pass the rest of this option to the preprocessor. */
+
+ /* Split the argument at commas. */
+ prev = 0;
+ for (j = 0; arg[j]; j++)
+ if (arg[j] == ',')
+ {
+ add_preprocessor_option (arg + prev, j - prev);
+ prev = j + 1;
+ }
+
+ /* Record the part after the last comma. */
+ add_preprocessor_option (arg + prev, j - prev);
+ }
+ do_save = false;
+ break;
+
+ case OPT_Wl_:
+ {
+ int prev, j;
+ /* Split the argument at commas. */
+ prev = 0;
+ for (j = 0; arg[j]; j++)
+ if (arg[j] == ',')
+ {
+ add_infile (save_string (arg + prev, j - prev), "*");
+ prev = j + 1;
+ }
+ /* Record the part after the last comma. */
+ add_infile (arg + prev, "*");
+ }
+ do_save = false;
+ break;
+
+ case OPT_Xlinker:
+ add_infile (arg, "*");
+ do_save = false;
+ break;
+
+ case OPT_Xpreprocessor:
+ add_preprocessor_option (arg, strlen (arg));
+ do_save = false;
+ break;
+
+ case OPT_Xassembler:
+ add_assembler_option (arg, strlen (arg));
+ do_save = false;
+ break;
+
+ case OPT_l:
+ /* POSIX allows separation of -l and the lib arg; canonicalize
+ by concatenating -l with its arg */
+ add_infile (concat ("-l", arg, NULL), "*");
+ do_save = false;
+ break;
+
+ case OPT_save_temps:
+ save_temps_flag = SAVE_TEMPS_CWD;
+ validated = true;
+ break;
+
+ case OPT_save_temps_:
+ if (strcmp (arg, "cwd") == 0)
+ save_temps_flag = SAVE_TEMPS_CWD;
+ else if (strcmp (arg, "obj") == 0
+ || strcmp (arg, "object") == 0)
+ save_temps_flag = SAVE_TEMPS_OBJ;
+ else
+ fatal_error ("%qs is an unknown -save-temps option",
+ decoded->orig_option_with_args_text);
+ break;
+
+ case OPT_no_canonical_prefixes:
+ /* Already handled as a special case, so ignored here. */
+ do_save = false;
+ break;
+
+ case OPT_pipe:
+ validated = true;
+ /* Fall through. */
+ case OPT_combine:
+ /* These options set the variables specified in common.opt
+ automatically, but do need to be saved for spec
+ processing. */
+ break;
+
+ case OPT_specs:
+ case OPT_specs_:
+ {
+ struct user_specs *user = XNEW (struct user_specs);
+
+ user->next = (struct user_specs *) 0;
+ user->filename = arg;
+ if (user_specs_tail)
+ user_specs_tail->next = user;
+ else
+ user_specs_head = user;
+ user_specs_tail = user;
+ }
+ do_save = false;
+ break;
+
+ case OPT__sysroot_:
+ target_system_root = arg;
+ target_system_root_changed = 1;
+ do_save = false;
+ break;
+
+ case OPT_time_:
+ if (report_times_to_file)
+ fclose (report_times_to_file);
+ report_times_to_file = fopen (arg, "a");
+ do_save = false;
+ break;
+
+ case OPT____:
+ /* "-###"
+ This is similar to -v except that there is no execution
+ of the commands and the echoed arguments are quoted. It
+ is intended for use in shell scripts to capture the
+ driver-generated command line. */
+ verbose_only_flag++;
+ verbose_flag++;
+ do_save = false;
+ break;
+
+ case OPT_B:
+ {
+ size_t len = strlen (arg);
+
+ /* Catch the case where the user has forgotten to append a
+ directory separator to the path. Note, they may be using
+ -B to add an executable name prefix, eg "i386-elf-", in
+ order to distinguish between multiple installations of
+ GCC in the same directory. Hence we must check to see
+ if appending a directory separator actually makes a
+ valid directory name. */
+ if (!IS_DIR_SEPARATOR (arg[len - 1])
+ && is_directory (arg, false))
+ {
+ char *tmp = XNEWVEC (char, len + 2);
+ strcpy (tmp, arg);
+ tmp[len] = DIR_SEPARATOR;
+ tmp[++len] = 0;
+ arg = tmp;
+ }
+
+ add_prefix (&exec_prefixes, arg, NULL,
+ PREFIX_PRIORITY_B_OPT, 0, 0);
+ add_prefix (&startfile_prefixes, arg, NULL,
+ PREFIX_PRIORITY_B_OPT, 0, 0);
+ add_prefix (&include_prefixes, arg, NULL,
+ PREFIX_PRIORITY_B_OPT, 0, 0);
+ }
+ validated = true;
+ break;
+
+ case OPT_v: /* Print our subcommands and print versions. */
+ verbose_flag++;
+ break;
+
+ case OPT_x:
+ spec_lang = arg;
+ if (!strcmp (spec_lang, "none"))
+ /* Suppress the warning if -xnone comes after the last input
+ file, because alternate command interfaces like g++ might
+ find it useful to place -xnone after each input file. */
+ spec_lang = 0;
+ else
+ last_language_n_infiles = n_infiles;
+ do_save = false;
+ break;
+
+ case OPT_S:
+ case OPT_c:
+ case OPT_E:
+ /* have_c already set in a prescan above. */
+ break;
+
+ case OPT_o:
+ have_o = 1;
+#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
+ arg = convert_filename (arg, ! have_c, 0);
+#endif
+ /* Save the output name in case -save-temps=obj was used. */
+ save_temps_prefix = xstrdup (arg);
+ /* On some systems, ld cannot handle "-o" without a space. So
+ split the option from its argument. */
+ save_switch ("-o", 1, &arg, validated);
+ return true;
+
+ case OPT_static_libgcc:
+ case OPT_shared_libgcc:
+ case OPT_static_libgfortran:
+ case OPT_static_libstdc__:
+ /* These are always valid, since gcc.c itself understands the
+ first two, gfortranspec.c understands -static-libgfortran and
+ g++spec.c understands -static-libstdc++ */
+ validated = true;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (do_save)
+ save_switch (decoded->canonical_option[0],
+ decoded->canonical_option_num_elements - 1,
+ &decoded->canonical_option[1], validated);
+ return true;
+}
+
/* Create the vector `switches' and its contents.
Store its length in `n_switches'. */
@@ -3515,11 +3895,12 @@ process_command (int argc, const char **argv)
int i;
const char *temp;
char *temp1;
- const char *spec_lang = 0;
- int last_language_n_infiles;
const char *tooldir_prefix;
char *(*get_relative_prefix) (const char *, const char *,
const char *) = NULL;
+ struct cl_option_handlers handlers;
+ struct cl_decoded_option *decoded_options;
+ unsigned int decoded_options_count, j;
GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX");
@@ -3735,538 +4116,74 @@ process_command (int argc, const char **argv)
last_language_n_infiles = -1;
- for (i = 1; i < argc; i++)
- {
- const char *p = NULL;
- int c = 0;
-
- if (argv[i][0] == '-' && argv[i][1] != 0)
- {
- p = &argv[i][1];
- c = *p;
- }
-
- if (! strcmp (argv[i], "-dumpspecs"))
- {
- struct spec_list *sl;
- init_spec ();
- for (sl = specs; sl; sl = sl->next)
- printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec));
- if (link_command_spec)
- printf ("*link_command:\n%s\n\n", link_command_spec);
- exit (0);
- }
- else if (! strcmp (argv[i], "-dumpversion"))
- {
- printf ("%s\n", spec_version);
- exit (0);
- }
- else if (! strcmp (argv[i], "-dumpmachine"))
- {
- printf ("%s\n", spec_machine);
- exit (0);
- }
- else if (strcmp (argv[i], "-fversion") == 0)
- {
- /* translate_options () has turned --version into -fversion. */
- print_version = 1;
+ decode_cmdline_options_to_array (argc, argv, CL_DRIVER,
+ &decoded_options, &decoded_options_count);
- /* CPP driver cannot obtain switch from cc1_options. */
- if (is_cpp_driver)
- add_preprocessor_option ("--version", strlen ("--version"));
- add_assembler_option ("--version", strlen ("--version"));
- add_linker_option ("--version", strlen ("--version"));
+ handlers.unknown_option_callback = driver_unknown_option_callback;
+ handlers.wrong_lang_callback = driver_wrong_lang_callback;
+ handlers.post_handling_callback = driver_post_handling_callback;
+ handlers.num_handlers = 1;
+ handlers.handlers[0].handler = driver_handle_option;
+ handlers.handlers[0].mask = CL_DRIVER;
- goto normal_switch;
- }
- else if (strcmp (argv[i], "-fhelp") == 0)
- {
- /* translate_options () has turned --help into -fhelp. */
- print_help_list = 1;
-
- /* CPP driver cannot obtain switch from cc1_options. */
- if (is_cpp_driver)
- add_preprocessor_option ("--help", 6);
- add_assembler_option ("--help", 6);
- add_linker_option ("--help", 6);
-
- goto normal_switch;
- }
- else if (strncmp (argv[i], "-fhelp=", 7) == 0)
- {
- /* translate_options () has turned --help into -fhelp. */
- print_subprocess_help = 2;
-
- goto normal_switch;
- }
- else if (strcmp (argv[i], "-ftarget-help") == 0)
- {
- /* translate_options() has turned --target-help into -ftarget-help. */
- print_subprocess_help = 1;
-
- /* CPP driver cannot obtain switch from cc1_options. */
- if (is_cpp_driver)
- add_preprocessor_option ("--target-help", 13);
- add_assembler_option ("--target-help", 13);
- add_linker_option ("--target-help", 13);
-
- goto normal_switch;
- }
- else if (! strcmp (argv[i], "-pass-exit-codes"))
- {
- pass_exit_codes = 1;
- }
- else if (! strcmp (argv[i], "-print-search-dirs"))
- print_search_dirs = 1;
- else if (! strcmp (argv[i], "-print-libgcc-file-name"))
- print_file_name = "libgcc.a";
- else if (! strncmp (argv[i], "-print-file-name=", 17))
- print_file_name = argv[i] + 17;
- else if (! strncmp (argv[i], "-print-prog-name=", 17))
- print_prog_name = argv[i] + 17;
- else if (! strcmp (argv[i], "-print-multi-lib"))
- print_multi_lib = 1;
- else if (! strcmp (argv[i], "-print-multi-directory"))
- print_multi_directory = 1;
- else if (! strcmp (argv[i], "-print-sysroot"))
- print_sysroot = 1;
- else if (! strcmp (argv[i], "-print-multi-os-directory"))
- print_multi_os_directory = 1;
- else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
- print_sysroot_headers_suffix = 1;
- else if (! strcmp (argv[i], "-fcompare-debug-second"))
- {
- compare_debug_second = 1;
- goto normal_switch;
- }
- else if (! strcmp (argv[i], "-fno-compare-debug"))
- {
- argv[i] = "-fcompare-debug=";
- p = &argv[i][1];
- goto compare_debug_with_arg;
- }
- else if (! strcmp (argv[i], "-fcompare-debug"))
- {
- argv[i] = "-fcompare-debug=-gtoggle";
- p = &argv[i][1];
- goto compare_debug_with_arg;
- }
-#define OPT "-fcompare-debug="
- else if (! strncmp (argv[i], OPT, sizeof (OPT) - 1))
- {
- const char *opt;
- compare_debug_with_arg:
- opt = argv[i] + sizeof (OPT) - 1;
-#undef OPT
- if (*opt)
- compare_debug = 1;
- else
- compare_debug = -1;
- if (compare_debug < 0)
- compare_debug_opt = NULL;
- else
- compare_debug_opt = opt;
- goto normal_switch;
- }
- else if (! strncmp (argv[i], "-Wa,", 4))
- {
- int prev, j;
- /* Pass the rest of this option to the assembler. */
-
- /* Split the argument at commas. */
- prev = 4;
- for (j = 4; argv[i][j]; j++)
- if (argv[i][j] == ',')
- {
- add_assembler_option (argv[i] + prev, j - prev);
- prev = j + 1;
- }
-
- /* Record the part after the last comma. */
- add_assembler_option (argv[i] + prev, j - prev);
- }
- else if (! strncmp (argv[i], "-Wp,", 4))
- {
- int prev, j;
- /* Pass the rest of this option to the preprocessor. */
-
- /* Split the argument at commas. */
- prev = 4;
- for (j = 4; argv[i][j]; j++)
- if (argv[i][j] == ',')
- {
- add_preprocessor_option (argv[i] + prev, j - prev);
- prev = j + 1;
- }
-
- /* Record the part after the last comma. */
- add_preprocessor_option (argv[i] + prev, j - prev);
- }
- else if (strncmp (argv[i], "-Wl,", 4) == 0)
- {
- int prev, j;
- /* Split the argument at commas. */
- prev = 4;
- for (j = 4; argv[i][j]; j++)
- if (argv[i][j] == ',')
- {
- add_infile (save_string (argv[i] + prev, j - prev), "*");
- prev = j + 1;
- }
- /* Record the part after the last comma. */
- add_infile (argv[i] + prev, "*");
- }
- else if (strcmp (argv[i], "-Xlinker") == 0)
- {
- if (i + 1 == argc)
- fatal_error ("argument to %<-Xlinker%> is missing");
-
- add_infile (argv[i+1], "*");
- i++;
- }
- else if (strcmp (argv[i], "-Xpreprocessor") == 0)
- {
- if (i + 1 == argc)
- fatal_error ("argument to %<-Xpreprocessor%> is missing");
-
- add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
- i++;
- }
- else if (strcmp (argv[i], "-Xassembler") == 0)
- {
- if (i + 1 == argc)
- fatal_error ("argument to %<-Xassembler%> is missing");
-
- add_assembler_option (argv[i+1], strlen (argv[i+1]));
- i++;
- }
- else if (strcmp (argv[i], "-l") == 0)
- {
- if (i + 1 == argc)
- fatal_error ("argument to %<-l%> is missing");
-
- /* POSIX allows separation of -l and the lib arg;
- canonicalize by concatenating -l with its arg */
- add_infile (concat ("-l", argv[i + 1], NULL), "*");
- i++;
- }
- else if (strncmp (argv[i], "-l", 2) == 0)
- {
- add_infile (argv[i], "*");
- }
- else if (strcmp (argv[i], "-save-temps") == 0)
- {
- save_temps_flag = SAVE_TEMPS_CWD;
- goto normal_switch;
- }
- else if (strncmp (argv[i], "-save-temps=", 12) == 0)
- {
- if (strcmp (argv[i]+12, "cwd") == 0)
- save_temps_flag = SAVE_TEMPS_CWD;
- else if (strcmp (argv[i]+12, "obj") == 0
- || strcmp (argv[i]+12, "object") == 0)
- save_temps_flag = SAVE_TEMPS_OBJ;
- else
- fatal_error ("%qs is an unknown -save-temps option", argv[i]);
- goto normal_switch;
- }
- else if (strcmp (argv[i], "-no-canonical-prefixes") == 0)
- /* Already handled as a special case, so ignored here. */
- ;
- else if (strcmp (argv[i], "-combine") == 0)
- {
- combine_flag = 1;
- goto normal_switch;
- }
- else if (strcmp (argv[i], "-specs") == 0)
- {
- struct user_specs *user = XNEW (struct user_specs);
- if (++i >= argc)
- fatal_error ("argument to %<-specs%> is missing");
-
- user->next = (struct user_specs *) 0;
- user->filename = argv[i];
- if (user_specs_tail)
- user_specs_tail->next = user;
- else
- user_specs_head = user;
- user_specs_tail = user;
- }
- else if (strncmp (argv[i], "-specs=", 7) == 0)
- {
- struct user_specs *user = XNEW (struct user_specs);
- if (strlen (argv[i]) == 7)
- fatal_error ("argument to %<-specs=%> is missing");
-
- user->next = (struct user_specs *) 0;
- user->filename = argv[i] + 7;
- if (user_specs_tail)
- user_specs_tail->next = user;
- else
- user_specs_head = user;
- user_specs_tail = user;
- }
- else if (! strncmp (argv[i], "--sysroot=", strlen ("--sysroot=")))
- {
- target_system_root = argv[i] + strlen ("--sysroot=");
- target_system_root_changed = 1;
- }
- else if (strcmp (argv[i], "-time") == 0)
- report_times = 1;
- else if (strncmp (argv[i], "-time=", sizeof ("-time=") - 1) == 0)
- {
- if (report_times_to_file)
- fclose (report_times_to_file);
- report_times_to_file = fopen (argv[i] + sizeof ("-time=") - 1, "a");
- }
- else if (strcmp (argv[i], "-pipe") == 0)
- {
- /* -pipe has to go into the switches array as well as
- setting a flag. */
- use_pipes = 1;
- goto normal_switch;
- }
- else if (strcmp (argv[i], "-wrapper") == 0)
- {
- if (++i >= argc)
- fatal_error ("argument to %<-wrapper%> is missing");
-
- wrapper_string = argv[i];
- }
- else if (strcmp (argv[i], "-###") == 0)
+ for (j = 1; j < decoded_options_count; j++)
+ {
+ switch (decoded_options[j].opt_index)
{
- /* This is similar to -v except that there is no execution
- of the commands and the echoed arguments are quoted. It
- is intended for use in shell scripts to capture the
- driver-generated command line. */
- verbose_only_flag++;
- verbose_flag++;
+ case OPT_S:
+ case OPT_c:
+ case OPT_E:
+ have_c = 1;
+ break;
}
- else if (argv[i][0] == '-' && argv[i][1] != 0)
- {
- switch (c)
- {
- case 'B':
- {
- const char *value;
- int len;
-
- if (p[1] == 0 && i + 1 == argc)
- fatal_error ("argument to %<-B%> is missing");
- if (p[1] == 0)
- value = argv[i + 1];
- else
- value = p + 1;
-
- len = strlen (value);
-
- /* Catch the case where the user has forgotten to append a
- directory separator to the path. Note, they may be using
- -B to add an executable name prefix, eg "i386-elf-", in
- order to distinguish between multiple installations of
- GCC in the same directory. Hence we must check to see
- if appending a directory separator actually makes a
- valid directory name. */
- if (! IS_DIR_SEPARATOR (value [len - 1])
- && is_directory (value, false))
- {
- char *tmp = XNEWVEC (char, len + 2);
- strcpy (tmp, value);
- tmp[len] = DIR_SEPARATOR;
- tmp[++ len] = 0;
- value = tmp;
- }
-
- add_prefix (&exec_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, 0);
- add_prefix (&startfile_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, 0);
- add_prefix (&include_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, 0);
- }
- goto normal_switch;
-
- case 'v': /* Print our subcommands and print versions. */
- /* If they do anything other than exactly `-v', don't set
- verbose_flag; rather, continue on to give the error. */
- if (p[1] != 0)
- break;
- verbose_flag++;
- goto normal_switch;
-
- case 'x':
- if (p[1] == 0 && i + 1 == argc)
- fatal_error ("argument to %<-x%> is missing");
- if (p[1] == 0)
- spec_lang = argv[++i];
- else
- spec_lang = p + 1;
- if (! strcmp (spec_lang, "none"))
- /* Suppress the warning if -xnone comes after the last input
- file, because alternate command interfaces like g++ might
- find it useful to place -xnone after each input file. */
- spec_lang = 0;
- else
- last_language_n_infiles = n_infiles;
- break;
-
- case 'S':
- case 'c':
- case 'E':
- if (p[1] == 0)
- have_c = 1;
- goto normal_switch;
-
- case 'o':
- have_o = 1;
-#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
- if (! have_c)
- {
- int skip;
-
- /* Forward scan, just in case -S, -E or -c is specified
- after -o. */
- int j = i + 1;
- if (p[1] == 0)
- ++j;
- while (j < argc)
- {
- if (argv[j][0] == '-')
- {
- if (SWITCH_CURTAILS_COMPILATION (argv[j][1])
- && argv[j][2] == 0)
- {
- have_c = 1;
- break;
- }
- else if ((skip = SWITCH_TAKES_ARG (argv[j][1])))
- j += skip - (argv[j][2] != 0);
- else if ((skip = WORD_SWITCH_TAKES_ARG (argv[j] + 1)))
- j += skip;
- }
- j++;
- }
- }
-#endif
-#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX)
- if (p[1] == 0)
- argv[i + 1] = convert_filename (argv[i + 1], ! have_c, 0);
- else
- {
- argv[i] = convert_filename (argv[i], ! have_c, 0);
- p = &argv[i][1];
- }
-#endif
- /* Save the output name in case -save-temps=obj was used. */
- if ((p[1] == 0) && argv[i + 1])
- save_temps_prefix = xstrdup(argv[i + 1]);
- else
- save_temps_prefix = xstrdup(argv[i] + 1);
- goto normal_switch;
-
- default:
- normal_switch:
-
- alloc_switch ();
- switches[n_switches].part1 = p;
- /* Deal with option arguments in separate argv elements. */
- if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
- || WORD_SWITCH_TAKES_ARG (p))
- {
- int j = 0;
- int n_args = WORD_SWITCH_TAKES_ARG (p);
+ if (have_c)
+ break;
+ }
- if (n_args == 0)
- {
- /* Count only the option arguments in separate
- argv elements. */
- n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
- }
- if (i + n_args >= argc)
- fatal_error ("argument to %<-%s%> is missing", p);
- switches[n_switches].args
- = XNEWVEC (const char *, n_args + 1);
- while (j < n_args)
- switches[n_switches].args[j++] = argv[++i];
- /* Null-terminate the vector. */
- switches[n_switches].args[j] = 0;
- }
- else if (c == 'o')
- {
- /* On some systems, ld cannot handle "-o" without
- a space. So split the option from its argument. */
- char *part1 = XNEWVEC (char, 2);
- part1[0] = c;
- part1[1] = '\0';
-
- switches[n_switches].part1 = part1;
- switches[n_switches].args = XNEWVEC (const char *, 2);
- switches[n_switches].args[0] = xstrdup (p+1);
- switches[n_switches].args[1] = 0;
- }
- else
- switches[n_switches].args = 0;
-
- switches[n_switches].live_cond = 0;
- switches[n_switches].validated = 0;
- switches[n_switches].ordering = 0;
- /* These are always valid, since gcc.c itself understands the
- first four, gfortranspec.c understands -static-libgfortran
- and g++spec.c understands -static-libstdc++ */
- if (!strcmp (p, "save-temps")
- || !strcmp (p, "static-libgcc")
- || !strcmp (p, "shared-libgcc")
- || !strcmp (p, "pipe")
- || !strcmp (p, "static-libgfortran")
- || !strcmp (p, "static-libstdc++"))
- switches[n_switches].validated = 1;
- else
- {
- char ch = switches[n_switches].part1[0];
- if (ch == 'B')
- switches[n_switches].validated = 1;
- }
- n_switches++;
- }
- }
- else
+ for (j = 1; j < decoded_options_count; j++)
+ {
+ if (decoded_options[j].opt_index == OPT_SPECIAL_input_file)
{
- const char *p = strrchr (argv[i], '@');
+ const char *arg = decoded_options[j].arg;
+ const char *p = strrchr (arg, '@');
char *fname;
long offset;
int consumed;
#ifdef HAVE_TARGET_OBJECT_SUFFIX
- argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
+ arg = convert_filename (arg, 0, access (arg, F_OK));
#endif
/* For LTO static archive support we handle input file
specifications that are composed of a filename and
an offset like FNAME@OFFSET. */
if (p
- && p != argv[i]
+ && p != arg
&& sscanf (p, "@%li%n", &offset, &consumed) >= 1
&& strlen (p) == (unsigned int)consumed)
{
- fname = (char *)xmalloc (p - argv[i] + 1);
- memcpy (fname, argv[i], p - argv[i]);
- fname[p - argv[i]] = '\0';
+ fname = (char *)xmalloc (p - arg + 1);
+ memcpy (fname, arg, p - arg);
+ fname[p - arg] = '\0';
/* Only accept non-stdin and existing FNAME parts, otherwise
try with the full name. */
if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0)
{
free (fname);
- fname = xstrdup (argv[i]);
+ fname = xstrdup (arg);
}
}
else
- fname = xstrdup (argv[i]);
+ fname = xstrdup (arg);
if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
perror_with_name (fname);
else
- add_infile (argv[i], spec_lang);
+ add_infile (arg, spec_lang);
free (fname);
+ continue;
}
+
+ read_cmdline_option (decoded_options + j, CL_DRIVER, &handlers);
}
/* If -save-temps=obj and -o name, create the prefix to use for %b.
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 07674fb385f..d0da14b3b69 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,7 @@
+2010-08-16 Joseph Myers <joseph@codesourcery.com>
+
+ * lang.opt (MD_, MMD_, version): Mark RejectDriver.
+
2010-08-05 David Daney <ddaney@caviumnetworks.com>
* class.c (build_utf8_ref): Fix code formatting from previous commit.
diff --git a/gcc/java/lang.opt b/gcc/java/lang.opt
index 9e9a8cb5210..6dba0840a00 100644
--- a/gcc/java/lang.opt
+++ b/gcc/java/lang.opt
@@ -33,7 +33,7 @@ Java
; Documented for C
MD_
-Java Undocumented
+Java Undocumented RejectDriver
; Documented for C
MF
@@ -45,7 +45,7 @@ Java
; Documented for C
MMD_
-Java Undocumented
+Java Undocumented RejectDriver
; Documented for C
MP
@@ -209,7 +209,7 @@ Java Joined
Set the target VM version
version
-Java
+Java RejectDriver
;
; Warnings handled by ecj.
diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk
index 4eeb67bdbea..4ff4068cc0c 100644
--- a/gcc/opt-functions.awk
+++ b/gcc/opt-functions.awk
@@ -78,6 +78,8 @@ function switch_flags (flags)
result = result \
test_flag("Common", flags, " | CL_COMMON") \
test_flag("Target", flags, " | CL_TARGET") \
+ test_flag("Driver", flags, " | CL_DRIVER") \
+ test_flag("RejectDriver", flags, " | CL_REJECT_DRIVER") \
test_flag("Save", flags, " | CL_SAVE") \
test_flag("Joined", flags, " | CL_JOINED") \
test_flag("JoinedOrMissing", flags, " | CL_JOINED | CL_MISSING_OK") \
@@ -128,7 +130,7 @@ function static_var(name, flags)
# Return the type of variable that should be associated with the given flags.
function var_type(flags)
{
- if (!flag_set_p("Joined.*", flags))
+ if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags))
return "int "
else if (flag_set_p("UInteger", flags))
return "int "
@@ -143,7 +145,7 @@ function var_type_struct(flags)
{
if (flag_set_p("UInteger", flags))
return "int "
- else if (!flag_set_p("Joined.*", flags)) {
+ else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) {
if (flag_set_p(".*Mask.*", flags))
return "int "
else
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 6125dfae44d..f7c10407c38 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -128,8 +128,9 @@ integral_argument (const char *arg)
}
/* Decode the switch beginning at ARGV for the language indicated by
- LANG_MASK, into the structure *DECODED. Returns the number of
- switches consumed. */
+ 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 **argv, unsigned int lang_mask,
@@ -147,7 +148,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);
+ opt_index = find_opt (opt + 1, lang_mask);
if (opt_index == OPT_SPECIAL_unknown
&& (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
&& opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
@@ -161,7 +162,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
memcpy (dup + 2, opt + 5, len - 2 + 1);
opt = dup;
value = 0;
- opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
+ opt_index = find_opt (opt + 1, lang_mask);
}
if (opt_index == OPT_SPECIAL_unknown)
@@ -218,11 +219,11 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
}
/* Check if this is a switch for a different front end. */
- if (!(option->flags & (lang_mask | CL_COMMON | CL_TARGET)))
+ if (!(option->flags & lang_mask))
errors |= CL_ERR_WRONG_LANG;
else if ((option->flags & CL_TARGET)
- && (option->flags & CL_LANG_ALL)
- && !(option->flags & lang_mask))
+ && (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. */
errors |= CL_ERR_WRONG_LANG;
@@ -301,8 +302,9 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
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. */
+ 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,
diff --git a/gcc/opts.c b/gcc/opts.c
index 6e528058750..d04e81c6493 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -418,17 +418,27 @@ complain_wrong_lang (const struct cl_decoded_option *decoded,
{
const struct cl_option *option = &cl_options[decoded->opt_index];
const char *text = decoded->orig_option_with_args_text;
- char *ok_langs, *bad_lang;
+ char *ok_langs = NULL, *bad_lang = NULL;
+ unsigned int opt_flags = option->flags;
if (!lang_hooks.complain_wrong_lang_p (option))
return;
- ok_langs = write_langs (option->flags);
- bad_lang = write_langs (lang_mask);
-
- /* Eventually this should become a hard error IMO. */
- warning (0, "command line option \"%s\" is valid for %s but not for %s",
- text, ok_langs, bad_lang);
+ opt_flags &= ((1U << cl_lang_count) - 1) | CL_DRIVER;
+ if (opt_flags != CL_DRIVER)
+ ok_langs = write_langs (opt_flags);
+ if (lang_mask != CL_DRIVER)
+ bad_lang = write_langs (lang_mask);
+
+ if (opt_flags == CL_DRIVER)
+ error ("command line option %qs is valid for the driver but not for %s",
+ text, bad_lang);
+ else if (lang_mask == CL_DRIVER)
+ gcc_unreachable ();
+ else
+ /* Eventually this should become a hard error IMO. */
+ warning (0, "command line option %qs is valid for %s but not for %s",
+ text, ok_langs, bad_lang);
free (ok_langs);
free (bad_lang);
@@ -681,7 +691,8 @@ decode_options (unsigned int argc, const char **argv,
else
lang_mask = initial_lang_mask;
- decode_cmdline_options_to_array (argc, argv, lang_mask,
+ decode_cmdline_options_to_array (argc, argv,
+ lang_mask | CL_COMMON | CL_TARGET,
decoded_options, decoded_options_count);
if (first_time_p)
/* Perform language-specific options initialization. */
@@ -1193,6 +1204,12 @@ print_filtered_help (unsigned int include_flags,
if ((option->flags & exclude_flags) != 0)
continue;
+ /* The driver currently prints its own help text. */
+ if ((option->flags & CL_DRIVER) != 0
+ && (option->flags & (((1U << cl_lang_count) - 1)
+ | CL_COMMON | CL_TARGET)) == 0)
+ continue;
+
found = true;
/* Skip switches that have already been printed. */
if (printed[i])
@@ -1333,6 +1350,7 @@ print_specific_help (unsigned int include_flags,
switch (flag & include_flags)
{
case 0:
+ case CL_DRIVER:
break;
case CL_TARGET:
@@ -1436,7 +1454,8 @@ common_handle_option (const struct cl_decoded_option *decoded,
print_specific_help (0, undoc_mask, all_langs_mask);
/* Then display any remaining, non-language options. */
for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
- print_specific_help (i, undoc_mask, 0);
+ if (i != CL_DRIVER)
+ print_specific_help (i, undoc_mask, 0);
exit_after_options = true;
break;
}
diff --git a/gcc/opts.h b/gcc/opts.h
index d6412c3035d..18dfdc2a096 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -67,11 +67,12 @@ extern const unsigned int cl_options_count;
extern const char *const lang_names[];
extern const unsigned int cl_lang_count;
-#define CL_PARAMS (1 << 17) /* Fake entry. Used to display --param info with --help. */
-#define CL_WARNING (1 << 18) /* Enables an (optional) warning message. */
-#define CL_OPTIMIZATION (1 << 19) /* Enables an (optional) optimization. */
-#define CL_TARGET (1 << 20) /* Target-specific option. */
-#define CL_COMMON (1 << 21) /* Language-independent. */
+#define CL_PARAMS (1 << 15) /* Fake entry. Used to display --param info with --help. */
+#define CL_WARNING (1 << 16) /* Enables an (optional) warning message. */
+#define CL_OPTIMIZATION (1 << 17) /* Enables an (optional) optimization. */
+#define CL_DRIVER (1 << 18) /* Driver option. */
+#define CL_TARGET (1 << 19) /* Target-specific option. */
+#define CL_COMMON (1 << 20) /* Language-independent. */
#define CL_MIN_OPTION_CLASS CL_PARAMS
#define CL_MAX_OPTION_CLASS CL_COMMON
@@ -81,6 +82,7 @@ extern const unsigned int cl_lang_count;
This distinction is important because --help will not list options
which only have these higher bits set. */
+#define CL_REJECT_DRIVER (1 << 21) /* Reject this option in the driver. */
#define CL_SAVE (1 << 22) /* Target-specific option for attribute. */
#define CL_DISABLED (1 << 23) /* Disabled in this configuration. */
#define CL_REPORT (1 << 24) /* Report argument with -fverbose-asm */