From patchwork Wed Aug 18 20:58:28 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 62089 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id EB127B70D3 for ; Thu, 19 Aug 2010 06:59:05 +1000 (EST) Received: (qmail 20727 invoked by alias); 18 Aug 2010 20:59:03 -0000 Received: (qmail 20329 invoked by uid 22791); 18 Aug 2010 20:58:45 -0000 X-SWARE-Spam-Status: No, hits=-0.3 required=5.0 tests=AWL, BAYES_50, TW_BG, TW_CP, TW_JC, TW_RG, TW_XJ, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 18 Aug 2010 20:58:32 +0000 Received: (qmail 18054 invoked from network); 18 Aug 2010 20:58:29 -0000 Received: from unknown (HELO digraph.polyomino.org.uk) (joseph@127.0.0.2) by mail.codesourcery.com with ESMTPA; 18 Aug 2010 20:58:29 -0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.69) (envelope-from ) id 1OlpiO-0001WE-1E; Wed, 18 Aug 2010 20:58:28 +0000 Date: Wed, 18 Aug 2010 20:58:28 +0000 (UTC) From: "Joseph S. Myers" To: gcc-patches@gcc.gnu.org, fortran@gcc.gnu.org, java-patches@gcc.gnu.org Subject: Make lang_specific_driver use cl_decoded_option structures Message-ID: MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch continues the transition to using central option-processing code everywhere by moving lang_specific_driver to working with cl_decoded_option structures rather than the argv array. In the process of so doing, various oddities in the code have been noted, and some fixed while others are left for discussion of the desired semantics and fixing by front-end maintainers. * The drivers had various different versions of logic to determine what is an option and what is an option argument, most of which could go wrong in some cases. This is fixed by using the central logic in opts-common.c (which in turn uses *SWITCH_TAKES_ARG for unknown options) to produce the cl_decoded_option structures. (The code for translating options in the driver, and do_self_spec, still need converting to use the central logic to eliminate the remaining possibilities for such inconsistencies.) Similarly, the drivers would inconsistently try to give errors for missing option arguments; this is now unambiguously the responsibility of the central option processing code (while the drivers just need to check for CL_ERR_MISSING_ARG in some cases to avoid dereferencing null pointers). * Some of the ad hoc checks for options taking arguments still handled the -b and -V options that were removed a while back. Similarly, the Fortran driver's option processing code handled those options. The -b and -V handling is removed. * The drivers would handle non-option arguments "", "-", other single-character arguments and longer non-option arguments in various ways inconsistent from driver to driver and between the different types of such arguments listed above. I have tried to keep the logic in question the same as before this patch, although probably it should be fixed for greater consistency (except where special handling for "-" as stdin is needed, which may just be in cppspec.c, by treating all these cases the same as longer non-options, I think). * Because of string comparison when the drivers checked for options such as "-lc" or "-lm" already being present, some drivers checking for such options would fail to detect what should be equivalent forms split into two arguments such as "-l c". Fixed by using cl_decoded_option structures. * The C++ driver checked for an option "-ObjC++". No such option exists; it would be passed through to cc1plus, which would then reject it. The code for this option is removed. * The Fortran code has an error "overflowed output arg list for %qs" that is a call to fatal_error but looks like it should be an internal_error instead since if it triggers there is a bug in the calculation of how large the new option list should be. The patch does not change this. (Actually, it would be better just to resize dynamically as needed rather than hardcoding a calculation of the maximum size that might be needed, and so eliminate this error completely. The same applies in other drivers) * The Fortran driver has another relic of code for the C++ +e option (recall that this was removed in 2.95 and I removed further relics in ). This is removed by this patch. * The Fortran driver had a comment saying "Also, if -v is specified, but no other options that do anything special (allowing -V version, etc.), remember to add special stuff to make gcc command actually invoke all the different phases of the compilation process so all the version numbers can be seen.". Apart from the reference to -V, there is nothing special in the Fortran code at all regarding the lack of other options with -v. * The Fortran driver has a comment about "-lg2c -lm" but it always appears to use -lgfortran, not -lg2c. Left unchanged. * There are various target macros (defaulted with #ifndef in individual driver files) to control the libraries for different languages etc. - MATH_LIBRARY is documented in tm.texi.in, but MATH_LIBRARY_PROFILE, LIBSTDCXX, LIBSTDCXX_PROFILE, LIBSTDCXX_STATIC and FORTRAN_LIBRARY are not. (No target actually has a non-default value of LIBSTDCXX_PROFILE or FORTRAN_LIBRARY, but by analogy with the others they should still be considered target macros.) Left unchanged. * The Java driver has its own support for @FILE files but expandargv has already been called by the time lang_specific_driver is reached so I think this is dead code. Left unchanged. * The Java driver handles various options that were not previously known to the other drivers: -classpath, -bootclasspath, -CLASSPATH, -encoding, -extdirs. I entered these in the .opt file, so now the generic driver will handle them as taking arguments - and then reject them later as not being processed by any spec if it wouldn't have accepted them anyway because of some spec that handled them. In general I think such a change is a good idea because differences between the drivers are bad - the existence of separate drivers is to some extent a workaround for the generic driver not being able to tell which runtime libraries are needed by the object files it is linking. It may however change behavior in corner cases, where -encoding or -extdirs were used as linker options to say that a symbol "ncoding" or "xtdirs" is the entry point. * The Java -d option - -d with a separate argument being an alias for -foutput-class-dir= - is problematic in that it is incompatible with the semantics of -d with a joined argument. For now I made translate_options handle it (for all languages); when translate_options becomes generic .opt alias machinery, that machinery will need to handle this special case of joined and separate arguments having different semantics. * Java -extdirs is also peculiar in that it is different from -fextdirs/--extdirs; -extdirs is processed by the driver only, not directly generating jc1 options, while -fextdirs is processed by jc1 only. This may not result in any semantic differences, but looks odd. * The Java driver handled "--syntax-only" and "--indirect-dispatch" but those would have been translated to the -f forms before lang_specific_driver is called; such handling is removed as useless. Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to commit? 2010-08-18 Joseph Myers * Makefile.in (gccspec.o, cppspec.o): Update dependencies. * common.opt (L, nodefaultlibs, nostdlib, pg, static): New options. * config/avr/avr.h (LIBSTDCXX): Remove initial "-l". * config/freebsd.h (MATH_LIBRARY_PROFILE): Remove initial "-l". * config/i386/djgpp.h (LIBSTDCXX): Remove initial "-l". * config/rs6000/aix.h (LIBSTDCXX_STATIC): Remove initial "-l". * config/s390/tpf.h (MATH_LIBRARY, LIBSTDCXX): Remove initial "-l". * cppspec.c: Include opts.h. (lang_specific_driver): Use cl_decoded_option structures. * doc/tm.texi.in (MATH_LIBRARY): Update documentation. * doc/tm.texi: Regenerate. * gcc.c (translate_options): Translate -d to -foutput-class-dir=. (driver_handle_option): Allow driver options needing no special processing. (process_command): Decode options before call to lang_specific_driver. Pass decoded options to lang_specific_driver. * gcc.h (lang_specific_driver): Update prototype. * gccspec.c: Include opts.h. (lang_specific_driver): Use cl_decoded_option structures. * opts-common.c (option_ok_for_language, generate_option, generate_option_input_file): New. (decode_cmdline_option): Use option_ok_for_language. (decode_cmdline_options_to_array): Use generate_option_input_file. (handle_generated_option): Use generate_option. * opts.h (generate_option, generate_option_input_file): Declare. cp: 2010-08-18 Joseph Myers * Make-lang.in (g++spec.o): Update dependencies. * g++spec.c: Include opts.h (MATH_LIBRARY, LIBSTDCXX): Remove initial "-l". (lang_specific_driver): Use cl_decoded_option structures. fortran: 2010-08-18 Joseph Myers * Make-lang.in (gfortranspec.o): Update dependencies. * gfortranspec.c: Include coretypes.h before gcc.h. Include opts.h. (MATH_LIBRARY, FORTRAN_LIBRARY): Remove initial "-l". (ADD_ARG_LIBGFORTRAN, Option, lookup_option): Remove. (g77_xargc): Make unsigned. (g77_xargv): Change to g77_x_decoded_options. (g77_newargc): Make unsigned. (g77_newargv): Change to g77_new_decoded_options. (strings_same, options_same): New. (append_arg): Use cl_decoded_option structures. (append_option): New. (add_arg_libgfortran): New. (lang_specific_driver): Use cl_decoded_option structures. java: 2010-08-18 Joseph Myers * Make-lang.in (jvspec.o): Update dependencies. * jvspec.c: Include opts.h. (PARAM_ARG): Remove. (find_spec_file): Do not add leading -specs=. (lang_specific_driver): Use cl_decoded_option structures. * lang.opt (C, CLASSPATH, D, bootclasspath, classpath, encoding, extdirs, fmain=, s-bc-abi): New options. Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi (revision 163280) +++ gcc/doc/tm.texi (working copy) @@ -10694,10 +10694,11 @@ for overlap with regards to asm-declared @defmac MATH_LIBRARY Define this macro as a C string constant for the linker argument to link -in the system math library, or @samp{""} if the target does not have a +in the system math library, minus the initial @samp{"-l"}, or +@samp{""} if the target does not have a separate math library. -You need only define this macro if the default of @samp{"-lm"} is wrong. +You need only define this macro if the default of @samp{"m"} is wrong. @end defmac @defmac LIBRARY_PATH_ENV Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in (revision 163280) +++ gcc/doc/tm.texi.in (working copy) @@ -10674,10 +10674,11 @@ for overlap with regards to asm-declared @defmac MATH_LIBRARY Define this macro as a C string constant for the linker argument to link -in the system math library, or @samp{""} if the target does not have a +in the system math library, minus the initial @samp{"-l"}, or +@samp{""} if the target does not have a separate math library. -You need only define this macro if the default of @samp{"-lm"} is wrong. +You need only define this macro if the default of @samp{"m"} is wrong. @end defmac @defmac LIBRARY_PATH_ENV Index: gcc/opts-common.c =================================================================== --- gcc/opts-common.c (revision 163280) +++ gcc/opts-common.c (working copy) @@ -127,6 +127,23 @@ integral_argument (const char *arg) return -1; } +/* 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; +} + /* 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 @@ -228,14 +245,8 @@ decode_cmdline_option (const char **argv } /* Check if this is a switch for a different front end. */ - if (!(option->flags & lang_mask)) + if (!option_ok_for_language (option, lang_mask)) errors |= CL_ERR_WRONG_LANG; - 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. */ - errors |= CL_ERR_WRONG_LANG; if (arg == NULL && (separate_arg_flag || joined_arg_flag)) errors |= CL_ERR_MISSING_ARG; @@ -346,16 +357,7 @@ decode_cmdline_options_to_array (unsigne /* 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].canonical_option_num_elements = 1; - opt_array[num_decoded_options].canonical_option[0] = opt; - opt_array[num_decoded_options].canonical_option[1] = NULL; - opt_array[num_decoded_options].canonical_option[2] = NULL; - opt_array[num_decoded_options].canonical_option[3] = NULL; - opt_array[num_decoded_options].value = 1; - opt_array[num_decoded_options].errors = 0; + generate_option_input_file (opt, &opt_array[num_decoded_options]); num_decoded_options++; n = 1; continue; @@ -550,45 +552,76 @@ handle_generated_option (size_t opt_inde unsigned int lang_mask, int kind, const struct cl_option_handlers *handlers) { - const struct cl_option *option = &cl_options[opt_index]; struct cl_decoded_option decoded; - decoded.opt_index = opt_index; - decoded.arg = arg; - decoded.canonical_option[2] = NULL; - decoded.canonical_option[3] = NULL; - decoded.value = value; - decoded.errors = 0; + generate_option (opt_index, arg, value, lang_mask, &decoded); + return handle_option (&decoded, lang_mask, kind, handlers); +} + +/* 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, 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->arg = arg; + decoded->canonical_option[2] = NULL; + decoded->canonical_option[3] = NULL; + decoded->value = value; + decoded->errors = (option_ok_for_language (option, lang_mask) + ? 0 + : CL_ERR_WRONG_LANG); if (arg) { if (option->flags & CL_SEPARATE) { - decoded.orig_option_with_args_text = concat (option->opt_text, " ", - arg, NULL); - decoded.canonical_option[0] = option->opt_text; - decoded.canonical_option[1] = arg; - decoded.canonical_option_num_elements = 2; + decoded->orig_option_with_args_text = concat (option->opt_text, " ", + arg, NULL); + decoded->canonical_option[0] = option->opt_text; + decoded->canonical_option[1] = arg; + decoded->canonical_option_num_elements = 2; } else { gcc_assert (option->flags & CL_JOINED); - decoded.orig_option_with_args_text = concat (option->opt_text, arg, - NULL); - decoded.canonical_option[0] = decoded.orig_option_with_args_text; - decoded.canonical_option[1] = NULL; - decoded.canonical_option_num_elements = 1; + decoded->orig_option_with_args_text = concat (option->opt_text, arg, + NULL); + decoded->canonical_option[0] = decoded->orig_option_with_args_text; + decoded->canonical_option[1] = NULL; + decoded->canonical_option_num_elements = 1; } } else { - decoded.orig_option_with_args_text = option->opt_text; - decoded.canonical_option[0] = option->opt_text; - decoded.canonical_option[1] = NULL; - decoded.canonical_option_num_elements = 1; + decoded->orig_option_with_args_text = option->opt_text; + decoded->canonical_option[0] = option->opt_text; + decoded->canonical_option[1] = NULL; + decoded->canonical_option_num_elements = 1; } +} - return handle_option (&decoded, lang_mask, kind, handlers); +/* 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->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; } /* Handle the switch DECODED for the language indicated by LANG_MASK, Index: gcc/java/Make-lang.in =================================================================== --- gcc/java/Make-lang.in (revision 163280) +++ gcc/java/Make-lang.in (working copy) @@ -57,7 +57,7 @@ JAVA_TARGET_INDEPENDENT_BIN_TOOLS = jcf- .PHONY: java jvspec.o: $(srcdir)/java/jvspec.c $(SYSTEM_H) coretypes.h $(TM_H) \ - $(GCC_H) $(CONFIG_H) java/jcf.h java/javaop.h + $(GCC_H) $(CONFIG_H) java/jcf.h java/javaop.h opts.h (SHLIB_LINK='$(SHLIB_LINK)'; \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \ $(INCLUDES) $(srcdir)/java/jvspec.c $(OUTPUT_OPTION)) Index: gcc/java/jvspec.c =================================================================== --- gcc/java/jvspec.c (revision 163280) +++ gcc/java/jvspec.c (working copy) @@ -29,14 +29,13 @@ The Free Software Foundation is independ #include "tm.h" #include "gcc.h" #include "jcf.h" +#include "opts.h" /* Name of spec file. */ #define SPEC_FILE "libgcj.spec" /* This bit is set if we saw a `-xfoo' language specification. */ #define LANGSPEC (1<<1) -/* True if this arg is a parameter to the previous option-taking arg. */ -#define PARAM_ARG (1<<2) /* True if this arg is a .java input file name. */ #define JAVA_FILE_ARG (1<<3) /* True if this arg is a .class input file name. */ @@ -88,17 +87,13 @@ static char * find_spec_file (const char *dir) { char *spec; - int x; struct stat sb; - spec = XNEWVEC (char, strlen (dir) + sizeof (SPEC_FILE) - + sizeof ("-specs=") + 4); - strcpy (spec, "-specs="); - x = strlen (spec); - strcat (spec, dir); + spec = XNEWVEC (char, strlen (dir) + sizeof (SPEC_FILE) + 4); + strcpy (spec, dir); strcat (spec, "/"); strcat (spec, SPEC_FILE); - if (! stat (spec + x, &sb)) + if (! stat (spec, &sb)) return spec; free (spec); return NULL; @@ -142,10 +137,11 @@ verify_class_name (const char *name) } void -lang_specific_driver (int *in_argc, const char *const **in_argv, +lang_specific_driver (struct cl_decoded_option **in_decoded_options, + unsigned int *in_decoded_options_count, int *in_added_libraries) { - int i, j; + unsigned int i, j; int saw_save_temps = 0; @@ -174,12 +170,8 @@ lang_specific_driver (int *in_argc, cons libraries. */ int added = 2; - /* Used to track options that take arguments, so we don't go wrapping - those with -xc++/-xnone. */ - const char *quote = NULL; - /* The new argument list will be contained in this. */ - const char **arglist; + struct cl_decoded_option *new_decoded_options; /* Nonzero if we saw a `-xfoo' language specification on the command line. Used to avoid adding our own -xc++ if the user @@ -203,16 +195,16 @@ lang_specific_driver (int *in_argc, cons int *args; /* The total number of arguments with the new stuff. */ - int argc; + unsigned int argc; /* The argument list. */ - const char *const *argv; + struct cl_decoded_option *decoded_options; /* The number of libraries added in. */ int added_libraries; /* The total number of arguments with the new stuff. */ - int num_args = 1; + unsigned int num_args = 1; /* Nonzero if linking is supposed to happen. */ int will_link = 1; @@ -226,182 +218,182 @@ lang_specific_driver (int *in_argc, cons /* If linking, nonzero if the BC-ABI is in use. */ int link_for_bc_abi = 0; - argc = *in_argc; - argv = *in_argv; + argc = *in_decoded_options_count; + decoded_options = *in_decoded_options; added_libraries = *in_added_libraries; args = XCNEWVEC (int, argc); for (i = 1; i < argc; i++) { - /* If the previous option took an argument, we swallow it here. */ - if (quote) + switch (decoded_options[i].opt_index) { - quote = NULL; - args[i] |= PARAM_ARG; - continue; - } - - /* We don't do this anymore, since we don't get them with minus - signs on them. */ - if (argv[i][0] == '\0' || argv[i][1] == '\0') - continue; + case OPT_nostdlib: + case OPT_nodefaultlibs: + library = 0; + break; + + case OPT_fmain_: + main_class_name = decoded_options[i].arg; + added--; + break; + + case OPT_fhelp: + want_spec_file = 0; + break; - if (argv[i][0] == '-') - { - if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0 - || strcmp (argv[i], "-nodefaultlibs") == 0)) - { - library = 0; - } - else if (strncmp (argv[i], "-fmain=", 7) == 0) - { - main_class_name = argv[i] + 7; - added--; - } - else if (strcmp (argv[i], "-fhelp") == 0) - want_spec_file = 0; - else if (strcmp (argv[i], "-v") == 0) - { - if (argc == 2) - { - /* If they only gave us `-v', don't try to link - in libgcj. */ - library = 0; - } - } - else if (strncmp (argv[i], "-x", 2) == 0) - saw_speclang = 1; - else if (strcmp (argv[i], "-C") == 0) - { - saw_C = 1; - want_spec_file = 0; - if (library != 0) - added -= 2; - library = 0; - will_link = 0; - } - else if (strncmp (argv[i], "-fcompile-resource=", 19) == 0) + case OPT_v: + if (argc == 2) { - saw_resource = 1; - want_spec_file = 0; - if (library != 0) - --added; + /* If they only gave us `-v', don't try to link + in libgcj. */ library = 0; - will_link = 0; - } - else if (argv[i][1] == 'D') - saw_D = 1; - else if (argv[i][1] == 'g') - saw_g = 1; - else if (argv[i][1] == 'O') - saw_O = 1; - else if ((argv[i][2] == '\0' - && strchr ("bBVDUoeTuIYmLiAI", argv[i][1]) != NULL) - || strcmp (argv[i], "-Tdata") == 0 - || strcmp (argv[i], "-MT") == 0 - || strcmp (argv[i], "-MF") == 0) - { - if (strcmp (argv[i], "-o") == 0) - saw_o = 1; - quote = argv[i]; - } - else if (strcmp (argv[i], "-classpath") == 0 - || strcmp (argv[i], "-bootclasspath") == 0 - || strcmp (argv[i], "-CLASSPATH") == 0 - || strcmp (argv[i], "-encoding") == 0 - || strcmp (argv[i], "-extdirs") == 0) - { - quote = argv[i]; - added -= 1; } - else if (library != 0 - && ((argv[i][2] == '\0' - && strchr ("cSEM", argv[i][1]) != NULL) - || strcmp (argv[i], "-MM") == 0)) - { - /* Don't specify libraries if we won't link, since that would - cause a warning. */ - library = 0; - added -= 2; + break; - /* Remember this so we can confirm -fmain option. */ - will_link = 0; - } - else if (strcmp (argv[i], "-d") == 0) - { - /* `-d' option is for javac compatibility. */ - quote = argv[i]; - added -= 1; - } - else if (strcmp (argv[i], "-fsyntax-only") == 0 - || strcmp (argv[i], "--syntax-only") == 0) - { - library = 0; - will_link = 0; + case OPT_x: + saw_speclang = 1; + break; + + case OPT_C: + saw_C = 1; + want_spec_file = 0; + if (library != 0) + added -= 2; + library = 0; + will_link = 0; + break; + + case OPT_fcompile_resource_: + saw_resource = 1; + want_spec_file = 0; + if (library != 0) + --added; + library = 0; + will_link = 0; + break; + + case OPT_D: + saw_D = 1; + break; + + case OPT_g: + case OPT_gcoff: + case OPT_gdwarf_: + case OPT_ggdb: + case OPT_gstabs: + case OPT_gstabs_: + case OPT_gvms: + case OPT_gxcoff: + case OPT_gxcoff_: + saw_g = 1; + break; + + case OPT_O: + case OPT_Os: + case OPT_Ofast: + saw_O = 1; + break; + + case OPT_o: + saw_o = 1; + break; + + case OPT_classpath: + case OPT_bootclasspath: + case OPT_CLASSPATH: + case OPT_encoding: + case OPT_extdirs: + added -= 1; + break; + + case OPT_c: + case OPT_S: + case OPT_E: + case OPT_M: + case OPT_MM: + /* Don't specify libraries if we won't link, since that would + cause a warning. */ + library = 0; + added -= 2; + + /* Remember this so we can confirm -fmain option. */ + will_link = 0; + break; + + case OPT_fsyntax_only: + library = 0; + will_link = 0; + continue; + + case OPT_save_temps: + saw_save_temps = 1; + break; + + case OPT_static_libgcc: + case OPT_static: + shared_libgcc = 0; + break; + + case OPT_findirect_dispatch: + link_for_bc_abi = 1; + break; + + case OPT_SPECIAL_input_file: + { + const char *arg = decoded_options[i].arg; + int len; + + /* We don't do this anymore, since we don't get them with minus + signs on them. */ + if (arg[0] == '\0' || arg[1] == '\0') continue; - } - else if (strcmp (argv[i], "-save-temps") == 0) - saw_save_temps = 1; - else if (strcmp (argv[i], "-static-libgcc") == 0 - || strcmp (argv[i], "-static") == 0) - shared_libgcc = 0; - else if (strcmp (argv[i], "-findirect-dispatch") == 0 - || strcmp (argv[i], "--indirect-dispatch") == 0) - { - link_for_bc_abi = 1; - } - else - /* Pass other options through. */ - continue; - } - else - { - int len; - if (saw_speclang) - { - saw_speclang = 0; - continue; - } + if (saw_speclang) + { + saw_speclang = 0; + continue; + } + + if (saw_resource) + { + args[i] |= RESOURCE_FILE_ARG; + added += 2; /* for -xjava and -xnone */ + } + + if (arg[0] == '@') + { + args[i] |= INDIRECT_FILE_ARG; + indirect_files_count++; + added += 2; /* for -xjava and -xnone */ + } + + len = strlen (arg); + if (len > 5 && strcmp (arg + len - 5, ".java") == 0) + { + args[i] |= JAVA_FILE_ARG; + java_files_count++; + } + if (len > 6 && strcmp (arg + len - 6, ".class") == 0) + { + args[i] |= CLASS_FILE_ARG; + class_files_count++; + } + if (len > 4 + && (strcmp (arg + len - 4, ".zip") == 0 + || strcmp (arg + len - 4, ".jar") == 0)) + { + args[i] |= ZIP_FILE_ARG; + zip_files_count++; + } + } - if (saw_resource) - { - args[i] |= RESOURCE_FILE_ARG; - added += 2; /* for -xjava and -xnone */ - } - - if (argv[i][0] == '@') - { - args[i] |= INDIRECT_FILE_ARG; - indirect_files_count++; - added += 2; /* for -xjava and -xnone */ - } - - len = strlen (argv[i]); - if (len > 5 && strcmp (argv[i] + len - 5, ".java") == 0) - { - args[i] |= JAVA_FILE_ARG; - java_files_count++; - } - if (len > 6 && strcmp (argv[i] + len - 6, ".class") == 0) - { - args[i] |= CLASS_FILE_ARG; - class_files_count++; - } - if (len > 4 - && (strcmp (argv[i] + len - 4, ".zip") == 0 - || strcmp (argv[i] + len - 4, ".jar") == 0)) - { - args[i] |= ZIP_FILE_ARG; - zip_files_count++; - } + default: + /* Pass other options through. */ + continue; } } - if (quote) - fatal_error ("argument to %qs missing", quote); - if (saw_D && ! main_class_name) fatal_error ("can't specify %<-D%> without %<--main%>"); @@ -475,112 +467,83 @@ lang_specific_driver (int *in_argc, cons num_args += link_for_bc_abi; - arglist = XNEWVEC (const char *, num_args + 1); + new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args); j = 0; - arglist[j++] = argv[0]; + new_decoded_options[j++] = decoded_options[0]; if (combine_inputs || indirect_files_count > 0) - arglist[j++] = "-ffilelist-file"; + generate_option (OPT_ffilelist_file, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); if (combine_inputs) { - arglist[j++] = "-xjava"; - arglist[j++] = filelist_filename; - arglist[j++] = "-xnone"; + generate_option (OPT_x, "java", 1, CL_DRIVER, + &new_decoded_options[j++]); + generate_option_input_file (filelist_filename, + &new_decoded_options[j++]); + generate_option (OPT_x, "none", 1, CL_DRIVER, + &new_decoded_options[j++]); } if (java_files_count > 0) - arglist[j++] = "-fsaw-java-file"; + generate_option (OPT_fsaw_java_file, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); jcf_path_init (); for (i = 1; i < argc; i++, j++) { - arglist[j] = argv[i]; + new_decoded_options[j] = decoded_options[i]; - if ((args[i] & PARAM_ARG)) + if (decoded_options[i].errors & CL_ERR_MISSING_ARG) continue; if ((args[i] & RESOURCE_FILE_ARG) != 0) { - arglist[j++] = "-xjava"; - arglist[j++] = argv[i]; - arglist[j] = "-xnone"; + generate_option (OPT_x, "java", 1, CL_DRIVER, + &new_decoded_options[j++]); + new_decoded_options[j++] = decoded_options[i]; + generate_option (OPT_x, "none", 1, CL_DRIVER, + &new_decoded_options[j]); } - if (argv[i][0] == '-' && argv[i][1] == 'I') - { - const char *arg; - if (argv[i][2] == '\0') - { - gcc_assert (i + 1 < argc && (args[i + 1] & PARAM_ARG) != 0); - arg = argv[i + 1]; - /* Drop the argument. */ - ++i; - } - else - arg = &argv[i][2]; - jcf_path_include_arg (arg); - --j; - continue; - } - if (! strcmp (argv[i], "-classpath") - || ! strcmp (argv[i], "-CLASSPATH")) - { - jcf_path_classpath_arg (argv[i + 1]); - ++i; - --j; - continue; - } - if (! strcmp (argv[i], "-bootclasspath")) - { - jcf_path_bootclasspath_arg (argv[i + 1]); - ++i; - --j; - continue; - } - if (! strncmp (argv[i], "-fCLASSPATH=", 12) - || ! strncmp (argv[i], "-fclasspath=", 12)) + switch (decoded_options[i].opt_index) { - const char *p = strchr (argv[i], '='); - jcf_path_classpath_arg (p + 1); + case OPT_I: + jcf_path_include_arg (decoded_options[i].arg); --j; continue; - } - if (! strncmp (argv[i], "-fbootclasspath=", 16)) - { - const char *p = strchr (argv[i], '='); - jcf_path_bootclasspath_arg (p + 1); + + case OPT_classpath: + case OPT_CLASSPATH: + case OPT_fCLASSPATH_: + case OPT_fclasspath_: + jcf_path_classpath_arg (decoded_options[i].arg); --j; continue; - } - if (! strcmp (argv[i], "-extdirs")) - { - jcf_path_extdirs_arg (argv[i + 1]); - ++i; + + case OPT_bootclasspath: + case OPT_fbootclasspath_: + jcf_path_bootclasspath_arg (decoded_options[i].arg); --j; continue; - } - if (strcmp (argv[i], "-encoding") == 0) - { - arglist[j] = concat ("-f", argv[i]+1, "=", argv[i+1], NULL); - i++; + case OPT_extdirs: + jcf_path_extdirs_arg (decoded_options[i].arg); + --j; continue; - } - if (strcmp (argv[i], "-d") == 0) - { - arglist[j] = concat ("-foutput-class-dir=", argv[i + 1], NULL); - ++i; + case OPT_encoding: + generate_option (OPT_fencoding_, decoded_options[i].arg, 1, + CL_DRIVER, &new_decoded_options[j]); continue; - } - if (spec_file == NULL && strncmp (argv[i], "-L", 2) == 0) - spec_file = find_spec_file (argv[i] + 2); + case OPT_L: + if (spec_file == NULL) + spec_file = find_spec_file (decoded_options[i].arg); + break; - if (strncmp (argv[i], "-fmain=", 7) == 0) - { + case OPT_fmain_: if (! will_link) fatal_error ("cannot specify % class when not linking"); --j; @@ -589,9 +552,13 @@ lang_specific_driver (int *in_argc, cons if ((args[i] & INDIRECT_FILE_ARG) != 0) { - arglist[j++] = "-xjava"; - arglist[j++] = argv[i]+1; /* Drop '@'. */ - arglist[j] = "-xnone"; + generate_option (OPT_x, "java", 1, CL_DRIVER, + &new_decoded_options[j++]); + /* Drop '@'. */ + generate_option_input_file (decoded_options[i].arg + 1, + &new_decoded_options[j++]); + generate_option (OPT_x, "none", 1, CL_DRIVER, + &new_decoded_options[j]); } if ((args[i] & (CLASS_FILE_ARG|ZIP_FILE_ARG)) && saw_C) @@ -603,7 +570,7 @@ lang_specific_driver (int *in_argc, cons if (combine_inputs && (args[i] & (CLASS_FILE_ARG|JAVA_FILE_ARG|ZIP_FILE_ARG)) != 0) { - fputs (argv[i], filelist_file); + fputs (decoded_options[i].arg, filelist_file); fputc ('\n', filelist_file); --j; continue; @@ -613,7 +580,8 @@ lang_specific_driver (int *in_argc, cons /* Handle classpath setting. We specify the bootclasspath since that requires the fewest changes to our existing code... */ jcf_path_seal (0); - arglist[j++] = jcf_path_compute ("-fbootclasspath="); + generate_option (OPT_fbootclasspath_, jcf_path_compute (""), 1, + CL_DRIVER, &new_decoded_options[j++]); if (combine_inputs) { @@ -623,33 +591,36 @@ lang_specific_driver (int *in_argc, cons /* If we saw no -O or -g option, default to -g1, for javac compatibility. */ if (saw_g + saw_O == 0) - arglist[j++] = "-g1"; + generate_option (OPT_g, "1", 1, CL_DRIVER, &new_decoded_options[j++]); /* Read the specs file corresponding to libgcj. If we didn't find the spec file on the -L path, then we hope it is somewhere in the standard install areas. */ if (want_spec_file) - arglist[j++] = spec_file == NULL ? "-specs=libgcj.spec" : spec_file; + generate_option (OPT_specs_, spec_file == NULL ? "libgcj.spec" : spec_file, + 1, CL_DRIVER, &new_decoded_options[j++]); if (saw_C) { - arglist[j++] = "-fsyntax-only"; - arglist[j++] = "-femit-class-files"; - arglist[j++] = "-S"; - arglist[j++] = "-o"; - arglist[j++] = "NONE"; + generate_option (OPT_fsyntax_only, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); + generate_option (OPT_femit_class_files, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); + generate_option (OPT_S, NULL, 1, CL_DRIVER, &new_decoded_options[j++]); + generate_option (OPT_o, "NONE", 1, CL_DRIVER, + &new_decoded_options[j++]); } if (shared_libgcc) - arglist[j++] = "-shared-libgcc"; + generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); if (link_for_bc_abi) - arglist[j++] = "-s-bc-abi"; - - arglist[j] = NULL; + generate_option (OPT_s_bc_abi, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); - *in_argc = j; - *in_argv = arglist; + *in_decoded_options_count = j; + *in_decoded_options = new_decoded_options; *in_added_libraries = added_libraries; } Index: gcc/java/lang.opt =================================================================== --- gcc/java/lang.opt (revision 163280) +++ gcc/java/lang.opt (working copy) @@ -1,5 +1,5 @@ ; Options for the Java front end. -; Copyright (C) 2003, 2005, 2007, 2009 Free Software Foundation, Inc. +; Copyright (C) 2003, 2005, 2007, 2009, 2010 Free Software Foundation, Inc. ; ; This file is part of GCC. ; @@ -24,6 +24,17 @@ Language Java +C +Driver +; Java driver option in fact distinct from C-family option with the same name. + +CLASSPATH +Driver Separate + +D +Driver Joined Separate +; Java driver option similar to C-family option. + I Java Joined Separate ; Documented for C @@ -76,6 +87,18 @@ Wredundant-modifiers Java Var(flag_redundant) Warn if modifiers are specified when not necessary +bootclasspath +Driver Separate + +classpath +Driver Separate + +encoding +Driver Separate + +extdirs +Driver Separate + fCLASSPATH= Java JoinedOrMissing RejectNegative --CLASSPATH Deprecated; use --classpath instead @@ -136,6 +159,9 @@ fextdirs= Java Joined RejectNegative --extdirs= Set the extension directory path +fmain= +Driver JoinedOrMissing RejectNegative + fsource-filename= Java Joined Undocumented @@ -208,6 +234,9 @@ ftarget= Java Joined Set the target VM version +s-bc-abi +Driver + version Java RejectDriver Index: gcc/cppspec.c =================================================================== --- gcc/cppspec.c (revision 163280) +++ gcc/cppspec.c (working copy) @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. #include "coretypes.h" #include "tm.h" #include "gcc.h" +#include "opts.h" /* The `cpp' executable installed in $(bindir) and $(cpp_install_dir) is a customized version of the gcc driver. It forces -E; -S and -c @@ -41,13 +42,14 @@ static const char *const known_suffixes[ NULL }; -/* Filter argc and argv before processing by the gcc driver proper. */ +/* Filter the command line before processing by the gcc driver proper. */ void -lang_specific_driver (int *in_argc, const char *const **in_argv, +lang_specific_driver (struct cl_decoded_option **in_decoded_options, + unsigned int *in_decoded_options_count, int *in_added_libraries ATTRIBUTE_UNUSED) { - int argc = *in_argc; - const char *const *argv = *in_argv; + struct cl_decoded_option *decoded_options = *in_decoded_options; + unsigned int argc = *in_decoded_options_count; /* Do we need to read stdin? */ int read_stdin = 1; @@ -60,16 +62,16 @@ lang_specific_driver (int *in_argc, cons /* Positions to insert -xc, -xassembler-with-cpp, and -o, if necessary. 0 means unnecessary. */ - int lang_c_here = 0; - int lang_S_here = 0; - int o_here = 0; + unsigned int lang_c_here = 0; + unsigned int lang_S_here = 0; + unsigned int o_here = 0; /* Do we need to fix up an input file with an unrecognized suffix? */ int need_fixups = 1; - int i, j, quote = 0; - const char **new_argv; - int new_argc; + unsigned int i, j; + struct cl_decoded_option *new_decoded_options; + unsigned int new_argc; extern int is_cpp_driver; is_cpp_driver = 1; @@ -79,117 +81,111 @@ lang_specific_driver (int *in_argc, cons the output file. If we see a third input file, barf. */ for (i = 1; i < argc; i++) { - if (quote == 1) + switch (decoded_options[i].opt_index) { - quote = 0; - continue; - } + case OPT_E: + need_E = 0; + break; + + case OPT_S: + case OPT_c: + fatal_error ("%qs is not a valid option to the preprocessor", + decoded_options[i].orig_option_with_args_text); + return; + + case OPT_x: + need_fixups = 0; + break; + + case OPT_SPECIAL_input_file: + { + const char *file = decoded_options[i].arg; - if (argv[i][0] == '-') - { - if (argv[i][1] == '\0') - read_stdin = 0; - else if (argv[i][2] == '\0') - { - if (argv[i][1] == 'E') - need_E = 0; - else if (argv[i][1] == 'S' || argv[i][1] == 'c') - { - fatal_error ("%qs is not a valid option to the " - "preprocessor", argv[i]); - return; - } - else if (argv[i][1] == 'x') - { - need_fixups = 0; - quote = 1; - } - else if (SWITCH_TAKES_ARG (argv[i][1])) - quote = 1; - } - else if (argv[i][1] == 'x') - need_fixups = 0; - else if (WORD_SWITCH_TAKES_ARG (&argv[i][1])) - quote = 1; - } - else /* not an option */ - { - seen_input++; - if (seen_input == 3) - { - fatal_error ("too many input files"); - return; - } - else if (seen_input == 2) - { - o_here = i; - } - else - { + if (strcmp (file, "-") == 0) read_stdin = 0; - if (need_fixups) - { - int l = strlen (argv[i]); - int known = 0; - const char *const *suff; - - for (suff = known_suffixes; *suff; suff++) - if (!strcmp (*suff, &argv[i][l - strlen(*suff)])) + else + { + seen_input++; + if (seen_input == 3) + { + fatal_error ("too many input files"); + return; + } + else if (seen_input == 2) + { + o_here = i; + } + else + { + read_stdin = 0; + if (need_fixups) { - known = 1; - break; + int l = strlen (file); + int known = 0; + const char *const *suff; + + for (suff = known_suffixes; *suff; suff++) + if (!strcmp (*suff, &file[l - strlen(*suff)])) + { + known = 1; + break; + } + + if (! known) + { + /* .s files are a special case; we have to + treat them like .S files so + -D__ASSEMBLER__ will be in effect. */ + if (!strcmp (".s", &file[l - 2])) + lang_S_here = i; + else + lang_c_here = i; + } } - - if (! known) - { - /* .s files are a special case; we have to treat - them like .S files so -D__ASSEMBLER__ will be - in effect. */ - if (!strcmp (".s", &argv[i][l - 2])) - lang_S_here = i; - else - lang_c_here = i; - } - } - } + } + } + } + break; } } /* If we don't need to edit the command line, we can bail early. */ - new_argc = argc + need_E + read_stdin - + !!o_here + !!lang_c_here + !!lang_S_here; + new_argc = argc + need_E + read_stdin + !!lang_c_here + !!lang_S_here; - if (new_argc == argc) + if (new_argc == argc && !o_here) return; - /* One more slot for a terminating null. */ - new_argv = XNEWVEC (const char *, new_argc + 1); + new_decoded_options = XNEWVEC (struct cl_decoded_option, new_argc); - new_argv[0] = argv[0]; + new_decoded_options[0] = new_decoded_options[0]; j = 1; if (need_E) - new_argv[j++] = "-E"; + generate_option (OPT_E, NULL, 1, CL_DRIVER, &new_decoded_options[j++]); for (i = 1; i < argc; i++, j++) { if (i == lang_c_here) - new_argv[j++] = "-xc"; + generate_option (OPT_x, "c", 1, CL_DRIVER, &new_decoded_options[j++]); else if (i == lang_S_here) - new_argv[j++] = "-xassembler-with-cpp"; + generate_option (OPT_x, "assembler-with-cpp", 1, CL_DRIVER, + &new_decoded_options[j++]); else if (i == o_here) - new_argv[j++] = "-o"; + { + generate_option (OPT_o, decoded_options[i].arg, 1, CL_DRIVER, + &new_decoded_options[j]); + continue; + } - new_argv[j] = argv[i]; + new_decoded_options[j] = decoded_options[i]; } if (read_stdin) - new_argv[j++] = "-"; + generate_option_input_file ("-", &new_decoded_options[j++]); - new_argv[j] = NULL; - *in_argc = new_argc; - *in_argv = new_argv; + *in_decoded_options_count = new_argc; + *in_decoded_options = new_decoded_options; } /* Called before linking. Returns 0 on success and -1 on failure. */ Index: gcc/gcc.c =================================================================== --- gcc/gcc.c (revision 163280) +++ gcc/gcc.c (working copy) @@ -1367,6 +1367,16 @@ translate_options (int *argcp, const cha if (nskip + i > argc) nskip = argc - i; + /* Convert -d with a separate argument to + -foutput-class-dir= for Java. */ + if (c == 'd' && p[1] == 0 && argv[i + 1] != NULL) + { + newv[newindex++] = concat ("-foutput-class-dir=", argv[i + 1], + NULL); + nskip = 0; + i += 2; + } + while (nskip > 0) { newv[newindex++] = argv[i++]; @@ -3847,12 +3857,6 @@ driver_handle_option (const struct cl_de 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) @@ -3876,7 +3880,10 @@ driver_handle_option (const struct cl_de break; default: - gcc_unreachable (); + /* Various driver options need no special processing at this + point, having been handled in a prescan above or being + handled by specs. */ + break; } if (do_save) @@ -3981,10 +3988,11 @@ process_command (int argc, const char ** is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX or an automatically created GCC_EXEC_PREFIX from argv[0]. */ + decode_cmdline_options_to_array (argc, argv, CL_DRIVER, + &decoded_options, &decoded_options_count); + /* Do language-specific adjustment/addition of flags. */ - lang_specific_driver (&argc, - CONST_CAST2 (const char *const **, const char ***, - &argv), + lang_specific_driver (&decoded_options, &decoded_options_count, &added_libraries); if (gcc_exec_prefix) @@ -4116,9 +4124,6 @@ process_command (int argc, const char ** last_language_n_infiles = -1; - decode_cmdline_options_to_array (argc, argv, CL_DRIVER, - &decoded_options, &decoded_options_count); - handlers.unknown_option_callback = driver_unknown_option_callback; handlers.wrong_lang_callback = driver_wrong_lang_callback; handlers.post_handling_callback = driver_post_handling_callback; Index: gcc/gcc.h =================================================================== --- gcc/gcc.h (revision 163280) +++ gcc/gcc.h (working copy) @@ -41,7 +41,8 @@ extern void set_input (const char *); /* Spec files linked with gcc.c must provide definitions for these. */ /* Called before processing to change/add/remove arguments. */ -extern void lang_specific_driver (int *, const char *const **, int *); +extern void lang_specific_driver (struct cl_decoded_option **, + unsigned int *, int *); /* Called before linking. Returns 0 on success and -1 on failure. */ extern int lang_specific_pre_link (void); Index: gcc/cp/Make-lang.in =================================================================== --- gcc/cp/Make-lang.in (revision 163280) +++ gcc/cp/Make-lang.in (working copy) @@ -53,7 +53,8 @@ c++: cc1plus$(exeext) # Tell GNU make to ignore these if they exist. .PHONY: c++ -g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) $(CONFIG_H) +g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) \ + $(CONFIG_H) opts.h (SHLIB_LINK='$(SHLIB_LINK)'; \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \ $(INCLUDES) $(srcdir)/cp/g++spec.c) Index: gcc/cp/g++spec.c =================================================================== --- gcc/cp/g++spec.c (revision 163280) +++ gcc/cp/g++spec.c (working copy) @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. #include "coretypes.h" #include "tm.h" #include "gcc.h" +#include "opts.h" /* This bit is set if we saw a `-xfoo' language specification. */ #define LANGSPEC (1<<1) @@ -34,14 +35,14 @@ along with GCC; see the file COPYING3. #define SKIPOPT (1<<4) #ifndef MATH_LIBRARY -#define MATH_LIBRARY "-lm" +#define MATH_LIBRARY "m" #endif #ifndef MATH_LIBRARY_PROFILE #define MATH_LIBRARY_PROFILE MATH_LIBRARY #endif #ifndef LIBSTDCXX -#define LIBSTDCXX "-lstdc++" +#define LIBSTDCXX "stdc++" #endif #ifndef LIBSTDCXX_PROFILE #define LIBSTDCXX_PROFILE LIBSTDCXX @@ -51,10 +52,11 @@ along with GCC; see the file COPYING3. #endif void -lang_specific_driver (int *in_argc, const char *const **in_argv, +lang_specific_driver (struct cl_decoded_option **in_decoded_options, + unsigned int *in_decoded_options_count, int *in_added_libraries) { - int i, j; + unsigned int i, j; /* If nonzero, the user gave us the `-p' or `-pg' flag. */ int saw_profile_flag = 0; @@ -71,12 +73,8 @@ lang_specific_driver (int *in_argc, cons -xc++/-xnone. */ int added = 0; - /* Used to track options that take arguments, so we don't go wrapping - those with -xc++/-xnone. */ - const char *quote = NULL; - /* The new argument list will be contained in this. */ - const char **arglist; + struct cl_decoded_option *new_decoded_options; /* Nonzero if we saw a `-xfoo' language specification on the command line. Used to avoid adding our own -xc++ if the user @@ -84,10 +82,10 @@ lang_specific_driver (int *in_argc, cons int saw_speclang = 0; /* "-lm" or "-lmath" if it appears on the command line. */ - const char *saw_math = 0; + const struct cl_decoded_option *saw_math = NULL; /* "-lc" if it appears on the command line. */ - const char *saw_libc = 0; + const struct cl_decoded_option *saw_libc = NULL; /* An array used to flag each argument that needs a bit set for LANGSPEC, MATHLIB, or WITHLIBC. */ @@ -103,220 +101,206 @@ lang_specific_driver (int *in_argc, cons int shared_libgcc = 1; /* The total number of arguments with the new stuff. */ - int argc; + unsigned int argc; /* The argument list. */ - const char *const *argv; + struct cl_decoded_option *decoded_options; /* The number of libraries added in. */ int added_libraries; /* The total number of arguments with the new stuff. */ - int num_args = 1; + unsigned int num_args = 1; - argc = *in_argc; - argv = *in_argv; + argc = *in_decoded_options_count; + decoded_options = *in_decoded_options; added_libraries = *in_added_libraries; args = XCNEWVEC (int, argc); for (i = 1; i < argc; i++) { - /* If the previous option took an argument, we swallow it here. */ - if (quote) - { - quote = NULL; - continue; - } + const char *arg = decoded_options[i].arg; + if (decoded_options[i].errors & CL_ERR_MISSING_ARG) + continue; /* Avoid examining arguments of options missing them. */ - /* We don't do this anymore, since we don't get them with minus - signs on them. */ - if (argv[i][0] == '\0' || argv[i][1] == '\0') - continue; - - if (argv[i][0] == '-') + switch (decoded_options[i].opt_index) { - if (strcmp (argv[i], "-nostdlib") == 0 - || strcmp (argv[i], "-nodefaultlibs") == 0) - { - library = -1; - } - else if (strcmp (argv[i], MATH_LIBRARY) == 0) + case OPT_nostdlib: + case OPT_nodefaultlibs: + library = -1; + break; + + case OPT_l: + if (strcmp (arg, MATH_LIBRARY) == 0) { args[i] |= MATHLIB; need_math = 0; } - else if (strcmp (argv[i], "-lc") == 0) + else if (strcmp (arg, "c") == 0) args[i] |= WITHLIBC; - else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0) - saw_profile_flag++; - else if (strncmp (argv[i], "-x", 2) == 0) - { - const char * arg; - if (argv[i][2] != '\0') - arg = argv[i]+2; - else if ((argv[i+1]) != NULL) - /* We need to swallow arg on next loop. */ - quote = arg = argv[i+1]; - else /* Error condition, message will be printed later. */ - arg = ""; - if (library == 0 - && (strcmp (arg, "c++") == 0 - || strcmp (arg, "c++-cpp-output") == 0 - || strcmp (arg, "objective-c++") == 0 - || strcmp (arg, "objective-c++-cpp-output") == 0)) - library = 1; + else + /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */ + library = (library == 0) ? 1 : library; + break; + + case OPT_pg: + case OPT_p: + saw_profile_flag++; + break; + + case OPT_x: + if (library == 0 + && (strcmp (arg, "c++") == 0 + || strcmp (arg, "c++-cpp-output") == 0 + || strcmp (arg, "objective-c++") == 0 + || strcmp (arg, "objective-c++-cpp-output") == 0)) + library = 1; - saw_speclang = 1; - } - else if (strcmp (argv[i], "-ObjC++") == 0) - { - if (library == 0) - library = 1; - saw_speclang = 1; - } + saw_speclang = 1; + break; + + case OPT_Xlinker: + case OPT_Wl_: /* Arguments that go directly to the linker might be .o files, or something, and so might cause libstdc++ to be needed. */ - else if (strcmp (argv[i], "-Xlinker") == 0) - { - quote = argv[i]; - if (library == 0) - library = 1; - } - else if (strncmp (argv[i], "-Wl,", 4) == 0) - library = (library == 0) ? 1 : library; - /* Unrecognized libraries (e.g. -lfoo) may require libstdc++. */ - else if (strncmp (argv[i], "-l", 2) == 0) - library = (library == 0) ? 1 : library; - else if (((argv[i][2] == '\0' - && strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL) - || strcmp (argv[i], "-Tdata") == 0)) - quote = argv[i]; - else if ((argv[i][2] == '\0' - && strchr ("cSEM", argv[i][1]) != NULL) - || strcmp (argv[i], "-MM") == 0 - || strcmp (argv[i], "-fsyntax-only") == 0) - { - /* Don't specify libraries if we won't link, since that would - cause a warning. */ - library = -1; - } - else if (strcmp (argv[i], "-static") == 0) - static_link = 1; - else if (strcmp (argv[i], "-static-libgcc") == 0) - shared_libgcc = 0; - else if (strcmp (argv[i], "-static-libstdc++") == 0) - { - library = library >= 0 ? 2 : library; - args[i] |= SKIPOPT; - } - else if (DEFAULT_WORD_SWITCH_TAKES_ARG (&argv[i][1])) - i++; - else - /* Pass other options through. */ - continue; - } - else - { - int len; + if (library == 0) + library = 1; + break; - if (saw_speclang) - { - saw_speclang = 0; + case OPT_c: + case OPT_S: + case OPT_E: + case OPT_M: + case OPT_MM: + case OPT_fsyntax_only: + /* Don't specify libraries if we won't link, since that would + cause a warning. */ + library = -1; + break; + + case OPT_static: + static_link = 1; + break; + + case OPT_static_libgcc: + shared_libgcc = 0; + break; + + case OPT_static_libstdc__: + library = library >= 0 ? 2 : library; + args[i] |= SKIPOPT; + break; + + case OPT_SPECIAL_input_file: + { + int len; + + /* We don't do this anymore, since we don't get them with minus + signs on them. */ + if (arg[0] == '\0' || arg[1] == '\0') continue; - } - /* If the filename ends in .[chi], put options around it. - But not if a specified -x option is currently active. */ - len = strlen (argv[i]); - if (len > 2 - && (argv[i][len - 1] == 'c' - || argv[i][len - 1] == 'i' - || argv[i][len - 1] == 'h') - && argv[i][len - 2] == '.') - { - args[i] |= LANGSPEC; - added += 2; - } - - /* If we don't know that this is a header file, we might - need to be linking in the libraries. */ - if (library == 0) - { - if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0) - && (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".hpp") != 0) - && (len <= 3 || strcmp (argv[i] + (len - 3), ".hp") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".hxx") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".h++") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".HPP") != 0) - && (len <= 4 || strcmp (argv[i] + (len - 4), ".tcc") != 0) - && (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0)) - library = 1; - } + if (saw_speclang) + { + saw_speclang = 0; + continue; + } + + /* If the filename ends in .[chi], put options around it. + But not if a specified -x option is currently active. */ + len = strlen (arg); + if (len > 2 + && (arg[len - 1] == 'c' + || arg[len - 1] == 'i' + || arg[len - 1] == 'h') + && arg[len - 2] == '.') + { + args[i] |= LANGSPEC; + added += 2; + } + + /* If we don't know that this is a header file, we might + need to be linking in the libraries. */ + if (library == 0) + { + if ((len <= 2 || strcmp (arg + (len - 2), ".H") != 0) + && (len <= 2 || strcmp (arg + (len - 2), ".h") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".hpp") != 0) + && (len <= 3 || strcmp (arg + (len - 3), ".hp") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".hxx") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".h++") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".HPP") != 0) + && (len <= 4 || strcmp (arg + (len - 4), ".tcc") != 0) + && (len <= 3 || strcmp (arg + (len - 3), ".hh") != 0)) + library = 1; + } + } + break; } } - if (quote) - fatal_error ("argument to %qs missing", quote); - /* There's no point adding -shared-libgcc if we don't have a shared libgcc. */ #ifndef ENABLE_SHARED_LIBGCC shared_libgcc = 0; #endif - /* Make sure to have room for the trailing NULL argument. - Add one for shared_libgcc or extra static library. */ - num_args = argc + added + need_math + (library > 0) * 4 + 2; - arglist = XNEWVEC (const char *, num_args); + /* Add one for shared_libgcc or extra static library. */ + num_args = argc + added + need_math + (library > 0) * 4 + 1; + new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args); i = 0; j = 0; /* Copy the 0th argument, i.e., the name of the program itself. */ - arglist[i++] = argv[j++]; + new_decoded_options[j++] = decoded_options[i++]; /* NOTE: We start at 1 now, not 0. */ while (i < argc) { - arglist[j] = argv[i]; + new_decoded_options[j] = decoded_options[i]; /* Make sure -lstdc++ is before the math library, since libstdc++ itself uses those math routines. */ if (!saw_math && (args[i] & MATHLIB) && library > 0) { --j; - saw_math = argv[i]; + saw_math = &decoded_options[i]; } if (!saw_libc && (args[i] & WITHLIBC) && library > 0) { --j; - saw_libc = argv[i]; + saw_libc = &decoded_options[i]; } /* Wrap foo.[chi] files in a language specification to force the gcc compiler driver to run cc1plus on them. */ if (args[i] & LANGSPEC) { - int len = strlen (argv[i]); - switch (argv[i][len - 1]) + const char *arg = decoded_options[i].arg; + int len = strlen (arg); + switch (arg[len - 1]) { case 'c': - arglist[j++] = "-xc++"; + generate_option (OPT_x, "c++", 1, CL_DRIVER, + &new_decoded_options[j++]); break; case 'i': - arglist[j++] = "-xc++-cpp-output"; + generate_option (OPT_x, "c++-cpp-output", 1, CL_DRIVER, + &new_decoded_options[j++]); break; case 'h': - arglist[j++] = "-xc++-header"; + generate_option (OPT_x, "c++-header", 1, CL_DRIVER, + &new_decoded_options[j++]); break; default: gcc_unreachable (); } - arglist[j++] = argv[i]; - arglist[j] = "-xnone"; + new_decoded_options[j++] = decoded_options[i]; + generate_option (OPT_x, "none", 1, CL_DRIVER, + &new_decoded_options[j]); } if ((args[i] & SKIPOPT) != 0) @@ -332,48 +316,51 @@ lang_specific_driver (int *in_argc, cons #ifdef HAVE_LD_STATIC_DYNAMIC if (library > 1 && !static_link) { - arglist[j] = "-Wl,-Bstatic"; + generate_option (OPT_Wl_, "-Bstatic", 1, CL_DRIVER, + &new_decoded_options[j]); j++; } #endif - arglist[j] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX; - if (arglist[j][0] != '-' || arglist[j][1] == 'l') - added_libraries++; + generate_option (OPT_l, + saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX, 1, + CL_DRIVER, &new_decoded_options[j]); + added_libraries++; j++; /* Add target-dependent static library, if necessary. */ if ((static_link || library > 1) && LIBSTDCXX_STATIC != NULL) { - arglist[j] = LIBSTDCXX_STATIC; - if (arglist[j][0] != '-' || arglist[j][1] == 'l') - added_libraries++; + generate_option (OPT_l, LIBSTDCXX_STATIC, 1, + CL_DRIVER, &new_decoded_options[j]); + added_libraries++; j++; } #ifdef HAVE_LD_STATIC_DYNAMIC if (library > 1 && !static_link) { - arglist[j] = "-Wl,-Bdynamic"; + generate_option (OPT_Wl_, "-Bdynamic", 1, CL_DRIVER, + &new_decoded_options[j]); j++; } #endif } if (saw_math) - arglist[j++] = saw_math; + new_decoded_options[j++] = *saw_math; else if (library > 0 && need_math) { - arglist[j] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY; - if (arglist[j][0] != '-' || arglist[j][1] == 'l') - added_libraries++; + generate_option (OPT_l, + saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY, + 1, CL_DRIVER, &new_decoded_options[j]); + added_libraries++; j++; } if (saw_libc) - arglist[j++] = saw_libc; + new_decoded_options[j++] = *saw_libc; if (shared_libgcc && !static_link) - arglist[j++] = "-shared-libgcc"; - - arglist[j] = NULL; + generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER, + &new_decoded_options[j++]); - *in_argc = j; - *in_argv = arglist; + *in_decoded_options_count = j; + *in_decoded_options = new_decoded_options; *in_added_libraries = added_libraries; } Index: gcc/opts.h =================================================================== --- gcc/opts.h (revision 163280) +++ gcc/opts.h (working copy) @@ -208,6 +208,11 @@ bool handle_option (const struct cl_deco bool handle_generated_option (size_t opt_index, const char *arg, int value, unsigned int lang_mask, int kind, const struct cl_option_handlers *handlers); +void generate_option (size_t opt_index, const char *arg, int value, + unsigned int lang_mask, + struct cl_decoded_option *decoded); +void generate_option_input_file (const char *file, + struct cl_decoded_option *decoded); extern void read_cmdline_option (struct cl_decoded_option *decoded, unsigned int lang_mask, const struct cl_option_handlers *handlers); Index: gcc/fortran/Make-lang.in =================================================================== --- gcc/fortran/Make-lang.in (revision 163280) +++ gcc/fortran/Make-lang.in (working copy) @@ -78,7 +78,7 @@ fortran: f951$(exeext) .PHONY: fortran gfortranspec.o: $(srcdir)/fortran/gfortranspec.c $(SYSTEM_H) $(TM_H) $(GCC_H) \ - $(CONFIG_H) coretypes.h intl.h + $(CONFIG_H) coretypes.h intl.h opts.h (SHLIB_LINK='$(SHLIB_LINK)'; \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \ $(INCLUDES) $(srcdir)/fortran/gfortranspec.c) Index: gcc/fortran/gfortranspec.c =================================================================== --- gcc/fortran/gfortranspec.c (revision 163280) +++ gcc/fortran/gfortranspec.c (working copy) @@ -48,149 +48,62 @@ along with GCC; see the file COPYING3. #include "config.h" #include "system.h" +#include "coretypes.h" #include "gcc.h" +#include "opts.h" -#include "coretypes.h" #include "tm.h" #include "intl.h" #ifndef MATH_LIBRARY -#define MATH_LIBRARY "-lm" +#define MATH_LIBRARY "m" #endif #ifndef FORTRAN_LIBRARY -#define FORTRAN_LIBRARY "-lgfortran" -#endif - -#ifdef HAVE_LD_STATIC_DYNAMIC -#define ADD_ARG_LIBGFORTRAN(arg) \ - { \ - if (static_lib && !static_linking) \ - append_arg ("-Wl,-Bstatic"); \ - append_arg (arg); \ - if (static_lib && !static_linking) \ - append_arg ("-Wl,-Bdynamic"); \ - } -#else -#define ADD_ARG_LIBGFORTRAN(arg) append_arg (arg); +#define FORTRAN_LIBRARY "gfortran" #endif - -/* Options this driver needs to recognize, not just know how to - skip over. */ -typedef enum -{ - OPTION_b, /* Aka --prefix. */ - OPTION_B, /* Aka --target. */ - OPTION_c, /* Aka --compile. */ - OPTION_E, /* Aka --preprocess. */ - OPTION_help, /* --help. */ - OPTION_i, /* -imacros, -include, -include-*. */ - OPTION_l, - OPTION_L, /* Aka --library-directory. */ - OPTION_nostdlib, /* Aka --no-standard-libraries, or - -nodefaultlibs. */ - OPTION_o, /* Aka --output. */ - OPTION_S, /* Aka --assemble. */ - OPTION_static, /* -static. */ - OPTION_static_libgfortran, /* -static-libgfortran. */ - OPTION_syntax_only, /* -fsyntax-only. */ - OPTION_v, /* Aka --verbose. */ - OPTION_version, /* --version. */ - OPTION_V, /* Aka --use-version. */ - OPTION_x, /* Aka --language. */ - OPTION_ /* Unrecognized or unimportant. */ -} -Option; - /* The original argument list and related info is copied here. */ -static int g77_xargc; -static const char *const *g77_xargv; -static void lookup_option (Option *, int *, const char **, const char *); -static void append_arg (const char *); +static unsigned int g77_xargc; +static const struct cl_decoded_option *g77_x_decoded_options; +static void append_arg (const struct cl_decoded_option *); /* The new argument list will be built here. */ -static int g77_newargc; -static const char **g77_newargv; - -/* Assumes text[0] == '-'. Returns number of argv items that belong to - (and follow) this one, an option id for options important to the - caller, and a pointer to the first char of the arg, if embedded (else - returns NULL, meaning no arg or it's the next argv). +static unsigned int g77_newargc; +static struct cl_decoded_option *g77_new_decoded_options; - Note that this also assumes gcc.c's pass converting long options - to short ones, where available, has already been run. */ +/* Return whether strings S1 and S2 are both NULL or both the same + string. */ -static void -lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text) +static bool +strings_same (const char *s1, const char *s2) { - Option opt = OPTION_; - int skip; - const char *arg = NULL; - - if ((skip = SWITCH_TAKES_ARG (text[1]))) - skip -= (text[2] != '\0'); /* See gcc.c. */ - - if (text[1] == 'B') - opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2; - else if (text[1] == 'b') - opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2; - else if ((text[1] == 'c') && (text[2] == '\0')) - opt = OPTION_c, skip = 0; - else if ((text[1] == 'E') && (text[2] == '\0')) - opt = OPTION_E, skip = 0; - else if (text[1] == 'i') - opt = OPTION_i, skip = 0; - else if (text[1] == 'l') - opt = OPTION_l; - else if (text[1] == 'L') - opt = OPTION_L, arg = text + 2; - else if (text[1] == 'o') - opt = OPTION_o; - else if ((text[1] == 'S') && (text[2] == '\0')) - opt = OPTION_S, skip = 0; - else if (text[1] == 'V') - opt = OPTION_V, skip = (text[2] == '\0'); - else if ((text[1] == 'v') && (text[2] == '\0')) - opt = OPTION_v, skip = 0; - else if (text[1] == 'x') - opt = OPTION_x, arg = text + 2; - else if (text[1] == 'J') - ; - else - { - if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0) /* See gcc.c. */ - ; - else if (!strcmp (text, "-fhelp")) /* Really --help!! */ - opt = OPTION_help; - else if (!strcmp (text, "-nostdlib") - || !strcmp (text, "-nodefaultlibs")) - opt = OPTION_nostdlib; - else if (!strcmp (text, "-fsyntax-only")) - opt = OPTION_syntax_only; - else if (!strcmp (text, "-static-libgfortran")) - opt = OPTION_static_libgfortran; - else if (!strcmp (text, "-static")) - opt = OPTION_static; - else if (!strcmp (text, "-fversion")) /* Really --version!! */ - opt = OPTION_version; - else if (!strcmp (text, "-Xlinker") || !strcmp (text, "-specs")) - skip = 1; - else - skip = 0; - } + return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0); +} - if (xopt != NULL) - *xopt = opt; - if (xskip != NULL) - *xskip = skip; - if (xarg != NULL) - { - if ((arg != NULL) && (arg[0] == '\0')) - *xarg = NULL; - else - *xarg = arg; - } +/* Return whether decoded option structures OPT1 and OPT2 are the + same. */ + +static bool +options_same (const struct cl_decoded_option *opt1, + const struct cl_decoded_option *opt2) +{ + return (opt1->opt_index == opt2->opt_index + && strings_same (opt1->arg, opt2->arg) + && strings_same (opt1->orig_option_with_args_text, + opt2->orig_option_with_args_text) + && strings_same (opt1->canonical_option[0], + opt2->canonical_option[0]) + && strings_same (opt1->canonical_option[1], + opt2->canonical_option[1]) + && strings_same (opt1->canonical_option[2], + opt2->canonical_option[2]) + && strings_same (opt1->canonical_option[3], + opt2->canonical_option[3]) + && (opt1->canonical_option_num_elements + == opt2->canonical_option_num_elements) + && opt1->value == opt2->value + && opt1->errors == opt2->errors); } /* Append another argument to the list being built. As long as it is @@ -198,52 +111,78 @@ lookup_option (Option *xopt, int *xskip, the new arg count. Otherwise allocate a new list, etc. */ static void -append_arg (const char *arg) +append_arg (const struct cl_decoded_option *arg) { - static int newargsize; + static unsigned int newargsize; #if 0 fprintf (stderr, "`%s'\n", arg); #endif - if (g77_newargv == g77_xargv + if (g77_new_decoded_options == g77_x_decoded_options && g77_newargc < g77_xargc - && (arg == g77_xargv[g77_newargc] - || !strcmp (arg, g77_xargv[g77_newargc]))) + && options_same (arg, &g77_x_decoded_options[g77_newargc])) { ++g77_newargc; return; /* Nothing new here. */ } - if (g77_newargv == g77_xargv) + if (g77_new_decoded_options == g77_x_decoded_options) { /* Make new arglist. */ - int i; + unsigned int i; newargsize = (g77_xargc << 2) + 20; /* This should handle all. */ - g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *)); + g77_new_decoded_options = XNEWVEC (struct cl_decoded_option, newargsize); /* Copy what has been done so far. */ for (i = 0; i < g77_newargc; ++i) - g77_newargv[i] = g77_xargv[i]; + g77_new_decoded_options[i] = g77_x_decoded_options[i]; } if (g77_newargc == newargsize) - fatal_error ("overflowed output arg list for %qs", arg); + fatal_error ("overflowed output arg list for %qs", + arg->orig_option_with_args_text); + + g77_new_decoded_options[g77_newargc++] = *arg; +} - g77_newargv[g77_newargc++] = arg; +/* Append an option described by OPT_INDEX, ARG and VALUE to the list + being built. */ +static void +append_option (size_t opt_index, const char *arg, int value) +{ + struct cl_decoded_option decoded; + + generate_option (opt_index, arg, value, CL_DRIVER, &decoded); + append_arg (&decoded); +} + +/* Append a libgfortran argument to the list being built. If + FORCE_STATIC, ensure the library is linked statically. */ + +static void +add_arg_libgfortran (bool force_static ATTRIBUTE_UNUSED) +{ +#ifdef HAVE_LD_STATIC_DYNAMIC + if (force_static) + append_option (OPT_Wl_, "-Bstatic", 1); +#endif + append_option (OPT_l, FORTRAN_LIBRARY, 1); +#ifdef HAVE_LD_STATIC_DYNAMIC + if (force_static) + append_option (OPT_Wl_, "-Bdynamic", 1); +#endif } void -lang_specific_driver (int *in_argc, const char *const **in_argv, +lang_specific_driver (struct cl_decoded_option **in_decoded_options, + unsigned int *in_decoded_options_count, int *in_added_libraries ATTRIBUTE_UNUSED) { - int argc = *in_argc; - const char *const *argv = *in_argv; - int i; + unsigned int argc = *in_decoded_options_count; + struct cl_decoded_option *decoded_options = *in_decoded_options; + unsigned int i; int verbose = 0; - Option opt; - int skip; - const char *arg; /* This will be NULL if we encounter a situation where we should not link in libf2c. */ @@ -261,13 +200,11 @@ lang_specific_driver (int *in_argc, cons /* By default, we throw on the math library if we have one. */ int need_math = (MATH_LIBRARY[0] != '\0'); -#ifdef HAVE_LD_STATIC_DYNAMIC /* Whether we should link a static libgfortran. */ int static_lib = 0; /* Whether we need to link statically. */ int static_linking = 0; -#endif /* The number of input and output files in the incoming arg list. */ int n_infiles = 0; @@ -276,91 +213,65 @@ lang_specific_driver (int *in_argc, cons #if 0 fprintf (stderr, "Incoming:"); for (i = 0; i < argc; i++) - fprintf (stderr, " %s", argv[i]); + fprintf (stderr, " %s", decoded_options[i].orig_option_with_args_text); fprintf (stderr, "\n"); #endif g77_xargc = argc; - g77_xargv = argv; + g77_x_decoded_options = decoded_options; g77_newargc = 0; - g77_newargv = CONST_CAST2 (const char **, const char *const *, argv); + g77_new_decoded_options = decoded_options; /* First pass through arglist. If -nostdlib or a "turn-off-linking" option is anywhere in the command line, don't do any library-option processing (except - relating to -x). Also, if -v is specified, but no other options - that do anything special (allowing -V version, etc.), remember - to add special stuff to make gcc command actually invoke all - the different phases of the compilation process so all the version - numbers can be seen. - - Also, here is where all problems with missing arguments to options - are caught. If this loop is exited normally, it means all options - have the appropriate number of arguments as far as the rest of this - program is concerned. */ + relating to -x). */ for (i = 1; i < argc; ++i) { - if ((argv[i][0] == '+') && (argv[i][1] == 'e')) - { - continue; - } - - if ((argv[i][0] != '-') || (argv[i][1] == '\0')) + switch (decoded_options[i].opt_index) { + case OPT_SPECIAL_input_file: ++n_infiles; continue; - } - - lookup_option (&opt, &skip, NULL, argv[i]); - switch (opt) - { - case OPTION_nostdlib: - case OPTION_c: - case OPTION_S: - case OPTION_syntax_only: - case OPTION_E: + case OPT_nostdlib: + case OPT_nodefaultlibs: + case OPT_c: + case OPT_S: + case OPT_fsyntax_only: + case OPT_E: /* These options disable linking entirely or linking of the standard libraries. */ library = 0; break; - case OPTION_static_libgfortran: + case OPT_static_libgfortran: #ifdef HAVE_LD_STATIC_DYNAMIC static_lib = 1; #endif break; - case OPTION_static: + case OPT_static: #ifdef HAVE_LD_STATIC_DYNAMIC static_linking = 1; #endif break; - case OPTION_l: + case OPT_l: ++n_infiles; break; - case OPTION_o: + case OPT_o: ++n_outfiles; break; - case OPTION_v: + case OPT_v: verbose = 1; break; - case OPTION_b: - case OPTION_B: - case OPTION_L: - case OPTION_i: - case OPTION_V: - /* These options are useful in conjunction with -v to get - appropriate version info. */ - break; - - case OPTION_version: + case OPT_fversion: printf ("GNU Fortran %s%s\n", pkgversion_string, version_string); printf ("Copyright %s 2010 Free Software Foundation, Inc.\n\n", _("(C)")); @@ -371,7 +282,7 @@ For more information about these matters exit (0); break; - case OPTION_help: + case OPT_fhelp: /* Let gcc.c handle this, as it has a really cool facility for handling --help and --verbose --help. */ return; @@ -379,14 +290,6 @@ For more information about these matters default: break; } - - /* This is the one place we check for missing arguments in the - program. */ - - if (i + skip < argc) - i += skip; - else - fatal_error ("argument to %qs missing", argv[i]); } if ((n_outfiles != 0) && (n_infiles == 0)) @@ -398,50 +301,50 @@ For more information about these matters /* Second pass through arglist, transforming arguments as appropriate. */ - append_arg (argv[0]); /* Start with command name, of course. */ + append_arg (&decoded_options[0]); /* Start with command name, of course. */ for (i = 1; i < argc; ++i) { - if (argv[i][0] == '\0') + if (decoded_options[i].errors & CL_ERR_MISSING_ARG) + { + append_arg (&decoded_options[i]); + continue; + } + + if (decoded_options[i].opt_index == OPT_SPECIAL_input_file + && decoded_options[i].arg[0] == '\0') { - append_arg (argv[i]); /* Interesting. Just append as is. */ + /* Interesting. Just append as is. */ + append_arg (&decoded_options[i]); continue; } - if ((argv[i][0] == '-') && (argv[i][1] != 'l')) + if (decoded_options[i].opt_index != OPT_l + && (decoded_options[i].opt_index != OPT_SPECIAL_input_file + || strcmp (decoded_options[i].arg, "-") == 0)) { /* Not a filename or library. */ if (saw_library == 1 && need_math) /* -l. */ - append_arg (MATH_LIBRARY); + append_option (OPT_l, MATH_LIBRARY, 1); saw_library = 0; - lookup_option (&opt, &skip, &arg, argv[i]); - - if (argv[i][1] == '\0') + if (decoded_options[i].opt_index == OPT_SPECIAL_input_file) { - append_arg (argv[i]); /* "-" == Standard input. */ + append_arg (&decoded_options[i]); /* "-" == Standard input. */ continue; } - if (opt == OPTION_x) + if (decoded_options[i].opt_index == OPT_x) { /* Track input language. */ - const char *lang; - - if (arg == NULL) - lang = argv[i + 1]; - else - lang = arg; + const char *lang = decoded_options[i].arg; saw_speclang = (strcmp (lang, "none") != 0); } - append_arg (argv[i]); - - for (; skip != 0; --skip) - append_arg (argv[++i]); + append_arg (&decoded_options[i]); continue; } @@ -452,29 +355,29 @@ For more information about these matters saw_library = 0; /* -xfoo currently active. */ else { /* -lfoo or filename. */ - if (strcmp (argv[i], MATH_LIBRARY) == 0) + if (decoded_options[i].opt_index == OPT_l + && strcmp (decoded_options[i].arg, MATH_LIBRARY) == 0) { if (saw_library == 1) saw_library = 2; /* -l -lm. */ else - { - ADD_ARG_LIBGFORTRAN (FORTRAN_LIBRARY); - } + add_arg_libgfortran (static_lib && !static_linking); } - else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0) + else if (decoded_options[i].opt_index == OPT_l + && strcmp (decoded_options[i].arg, FORTRAN_LIBRARY) == 0) { saw_library = 1; /* -l. */ - ADD_ARG_LIBGFORTRAN (argv[i]); + add_arg_libgfortran (static_lib && !static_linking); continue; } else { /* Other library, or filename. */ if (saw_library == 1 && need_math) - append_arg (MATH_LIBRARY); + append_option (OPT_l, MATH_LIBRARY, 1); saw_library = 0; } } - append_arg (argv[i]); + append_arg (&decoded_options[i]); } /* Append `-lg2c -lm' as necessary. */ @@ -482,17 +385,17 @@ For more information about these matters if (library) { /* Doing a link and no -nostdlib. */ if (saw_speclang) - append_arg ("-xnone"); + append_option (OPT_x, "none", 1); switch (saw_library) { case 0: - ADD_ARG_LIBGFORTRAN (library); + add_arg_libgfortran (static_lib && !static_linking); /* Fall through. */ case 1: if (need_math) - append_arg (MATH_LIBRARY); + append_option (OPT_l, MATH_LIBRARY, 1); default: break; } @@ -501,30 +404,30 @@ For more information about these matters #ifdef ENABLE_SHARED_LIBGCC if (library) { - int i; + unsigned int i; for (i = 1; i < g77_newargc; i++) - if (g77_newargv[i][0] == '-') - if (strcmp (g77_newargv[i], "-static-libgcc") == 0 - || strcmp (g77_newargv[i], "-static") == 0) - break; + if (g77_new_decoded_options[i].opt_index == OPT_static_libgcc + || g77_new_decoded_options[i].opt_index == OPT_static) + break; if (i == g77_newargc) - append_arg ("-shared-libgcc"); + append_option (OPT_shared_libgcc, NULL, 1); } #endif - if (verbose && g77_newargv != g77_xargv) + if (verbose && g77_new_decoded_options != g77_x_decoded_options) { fprintf (stderr, _("Driving:")); for (i = 0; i < g77_newargc; i++) - fprintf (stderr, " %s", g77_newargv[i]); + fprintf (stderr, " %s", + g77_new_decoded_options[i].orig_option_with_args_text); fprintf (stderr, "\n"); } - *in_argc = g77_newargc; - *in_argv = g77_newargv; + *in_decoded_options_count = g77_newargc; + *in_decoded_options = g77_new_decoded_options; } Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 163280) +++ gcc/common.opt (working copy) @@ -69,6 +69,9 @@ Driver Joined Separate E Driver +L +Driver Joined Separate + O Common JoinedOrMissing Optimization -O Set optimization level to @@ -1645,6 +1648,12 @@ Driver Joined Separate no-canonical-prefixes Driver +nodefaultlibs +Driver + +nostdlib +Driver + o Common Driver Joined Separate MissingArgError(missing filename after %qs) -o Place output into @@ -1664,6 +1673,9 @@ pedantic-errors Common Like -pedantic but issue them as errors +pg +Driver + pipe Driver Var(use_pipes) @@ -1740,6 +1752,9 @@ Driver Separate specs= Driver Joined +static +Driver + static-libgcc Driver Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 163280) +++ gcc/Makefile.in (working copy) @@ -2197,13 +2197,15 @@ gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) cor $(DRIVER_DEFINES) \ -c $(srcdir)/gcc.c $(OUTPUT_OPTION)) -gccspec.o: gccspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) +gccspec.o: gccspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) \ + opts.h (SHLIB_LINK='$(SHLIB_LINK)'; \ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \ $(DRIVER_DEFINES) \ -c $(srcdir)/gccspec.c $(OUTPUT_OPTION)) -cppspec.o: cppspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) +cppspec.o: cppspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) \ + opts.h specs.h : s-specs ; @true s-specs : Makefile Index: gcc/gccspec.c =================================================================== --- gcc/gccspec.c (revision 163280) +++ gcc/gccspec.c (working copy) @@ -1,5 +1,5 @@ /* Specific flags and argument handling of the C front-end. - Copyright (C) 1999, 2001, 2003, 2007 Free Software Foundation, Inc. + Copyright (C) 1999, 2001, 2003, 2007, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -22,75 +22,77 @@ along with GCC; see the file COPYING3. #include "coretypes.h" #include "tm.h" #include "gcc.h" +#include "opts.h" -/* Filter argc and argv before processing by the gcc driver proper. */ +/* Filter command line before processing by the gcc driver proper. */ void -lang_specific_driver (int *in_argc ATTRIBUTE_UNUSED, - const char *const **in_argv ATTRIBUTE_UNUSED, +lang_specific_driver (struct cl_decoded_option **in_decoded_options ATTRIBUTE_UNUSED, + unsigned int *in_decoded_options_count ATTRIBUTE_UNUSED, int *in_added_libraries ATTRIBUTE_UNUSED) { /* Systems which use the NeXT runtime by default should arrange for the shared libgcc to be used when -fgnu-runtime is passed through specs. */ #if defined(ENABLE_SHARED_LIBGCC) && ! defined(NEXT_OBJC_RUNTIME) - int i; + unsigned int i; /* The new argument list will be contained in this. */ - const char **arglist; + struct cl_decoded_option *new_decoded_options; /* True if we should add -shared-libgcc to the command-line. */ int shared_libgcc = 0; /* The total number of arguments with the new stuff. */ - int argc; + unsigned int argc; /* The argument list. */ - const char *const *argv; + struct cl_decoded_option *decoded_options; - argc = *in_argc; - argv = *in_argv; + argc = *in_decoded_options_count; + decoded_options = *in_decoded_options; for (i = 1; i < argc; i++) { - if (argv[i][0] == '-') + switch (decoded_options[i].opt_index) { - if (strcmp (argv[i], "-static-libgcc") == 0 - || strcmp (argv[i], "-static") == 0) - return; - } - else - { - int len; - - /* If the filename ends in .m or .mi, we are compiling ObjC - and want to pass -shared-libgcc. */ - len = strlen (argv[i]); - if ((len > 2 && argv[i][len - 2] == '.' && argv[i][len - 1] == 'm') - || (len > 3 && argv[i][len - 3] == '.' && argv[i][len - 2] == 'm' - && argv[i][len - 1] == 'i')) - shared_libgcc = 1; + case OPT_static_libgcc: + case OPT_static: + return; + + case OPT_SPECIAL_input_file: + { + const char *file = decoded_options[i].arg; + int len; + + /* If the filename ends in .m or .mi, we are compiling + ObjC and want to pass -shared-libgcc. */ + len = strlen (file); + if ((len > 2 && file[len - 2] == '.' && file[len - 1] == 'm') + || (len > 3 && file[len - 3] == '.' && file[len - 2] == 'm' + && file[len - 1] == 'i')) + shared_libgcc = 1; + } + break; } } if (shared_libgcc) { - /* Make sure to have room for the trailing NULL argument. */ - arglist = XNEWVEC (const char *, argc + 2); + new_decoded_options = XNEWVEC (struct cl_decoded_option, argc + 1); i = 0; do { - arglist[i] = argv[i]; + new_decoded_options[i] = decoded_options[i]; i++; } while (i < argc); - arglist[i++] = "-shared-libgcc"; - - arglist[i] = NULL; + generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER, + &new_decoded_options[i++]); - *in_argc = i; - *in_argv = arglist; + *in_decoded_options_count = i; + *in_decoded_options = new_decoded_options; } #endif } Index: gcc/config/s390/tpf.h =================================================================== --- gcc/config/s390/tpf.h (revision 163280) +++ gcc/config/s390/tpf.h (working copy) @@ -1,5 +1,6 @@ /* Definitions for target OS TPF for GNU compiler, for IBM S/390 hardware - Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2009, + 2010 Free Software Foundation, Inc. Contributed by P.J. Darcy (darcypj@us.ibm.com), Hartmut Penner (hpenner@de.ibm.com), and Ulrich Weigand (uweigand@de.ibm.com). @@ -124,6 +125,6 @@ along with GCC; see the file COPYING3. #define MD_UNWIND_SUPPORT "config/s390/tpf-unwind.h" /* IBM copies these libraries over with these names. */ -#define MATH_LIBRARY "-lCLBM" -#define LIBSTDCXX "-lCPP1" +#define MATH_LIBRARY "CLBM" +#define LIBSTDCXX "CPP1" #endif /* ! _TPF_H */ Index: gcc/config/i386/djgpp.h =================================================================== --- gcc/config/i386/djgpp.h (revision 163280) +++ gcc/config/i386/djgpp.h (working copy) @@ -1,6 +1,6 @@ /* Configuration for an i386 running MS-DOS with DJGPP. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, - 2007 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, + 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -166,7 +166,7 @@ along with GCC; see the file COPYING3. #define PTRDIFF_TYPE "int" /* Used to be defined in xm-djgpp.h, but moved here for cross-compilers. */ -#define LIBSTDCXX "-lstdcxx" +#define LIBSTDCXX "stdcxx" #define TARGET_VERSION fprintf (stderr, " (80386, MS-DOS DJGPP)"); Index: gcc/config/avr/avr.h =================================================================== --- gcc/config/avr/avr.h (revision 163280) +++ gcc/config/avr/avr.h (working copy) @@ -780,7 +780,7 @@ mmcu=*:-mmcu=%*}" #define LIB_SPEC \ "%{!mmcu=at90s1*:%{!mmcu=attiny11:%{!mmcu=attiny12:%{!mmcu=attiny15:%{!mmcu=attiny28: -lc }}}}}" -#define LIBSTDCXX "-lgcc" +#define LIBSTDCXX "gcc" /* No libstdc++ for now. Empty string doesn't work. */ #define LIBGCC_SPEC \ Index: gcc/config/rs6000/aix.h =================================================================== --- gcc/config/rs6000/aix.h (revision 163280) +++ gcc/config/rs6000/aix.h (working copy) @@ -156,7 +156,7 @@ %{p:-L%R/lib/profiled -L%R/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc" /* Static linking with shared libstdc++ requires libsupc++ as well. */ -#define LIBSTDCXX_STATIC "-lsupc++" +#define LIBSTDCXX_STATIC "supc++" /* This now supports a natural alignment mode. */ /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */ Index: gcc/config/freebsd.h =================================================================== --- gcc/config/freebsd.h (revision 163280) +++ gcc/config/freebsd.h (working copy) @@ -1,5 +1,6 @@ /* Base configuration file for all FreeBSD targets. - Copyright (C) 1999, 2000, 2001, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2007, 2008, 2009, + 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -76,7 +77,7 @@ along with GCC; see the file COPYING3. #undef WINT_TYPE #define WINT_TYPE "int" -#define MATH_LIBRARY_PROFILE "-lm_p" +#define MATH_LIBRARY_PROFILE "m_p" /* Code generation parameters. */