From patchwork Wed Jun 23 20:26:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 56712 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 79F46B6EF7 for ; Thu, 24 Jun 2010 06:27:23 +1000 (EST) Received: (qmail 24070 invoked by alias); 23 Jun 2010 20:27:18 -0000 Received: (qmail 24013 invoked by uid 22791); 23 Jun 2010 20:27:01 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL, BAYES_40, TW_CP, TW_RG, 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, 23 Jun 2010 20:26:51 +0000 Received: (qmail 14206 invoked from network); 23 Jun 2010 20:26:48 -0000 Received: from unknown (HELO digraph.polyomino.org.uk) (joseph@127.0.0.2) by mail.codesourcery.com with ESMTPA; 23 Jun 2010 20:26:48 -0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.69) (envelope-from ) id 1ORWX1-00069Q-Jm; Wed, 23 Jun 2010 20:26:47 +0000 Date: Wed, 23 Jun 2010 20:26:47 +0000 (UTC) From: "Joseph S. Myers" To: gcc-patches@gcc.gnu.org cc: fortran@gcc.gnu.org Subject: Make opts-common.c handle unknown options using SWITCH_TAKES_ARG etc. 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 is relative to a tree with , and applied. The first of these patches needs C++ and Ada pieces approved; the second needs C++ pieces approved; the third needs approval for everything except c-family, Fortran and Java pieces. The driver handles some options solely on the basis of specs and the target macros SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG with no more structured information about these options. Although I plan to move to .opt files having structured information about all options for all targets (since some such unstructured specs-only options are used in multilib selection, so such changes are required when multilib selection ceases to be textually based), an intermediate stage involved in reaching that point incrementally will have the driver using shared option processing code for some purposes but still passing through specs-only options for use in existing specs-processing code. Thus the shared option processing code should be able to handle unknown options using SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG, until more structured information eliminates those macros, and this patch implements this. (Right now it should only have any effect when cc1 etc. are called directly, since it does nothing for options known to the core compiler and the other options should not get passed through to the core compiler.) One complication is that SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG can specify options taking more than one argument, a concept not yet known to the .opt machinery. Thus, some common options code is adjusted to handle such options to the extent of storing multiple argv elements appropriately in the decoded option structure. Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to commit? 2010-06-23 Joseph Myers * config/darwin-driver.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Remove. * cppspec.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Remove. * defaults.h (DEFAULT_SWITCH_TAKES_ARG, DEFAULT_WORD_SWITCH_TAKES_ARG): Move from gcc.h. (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Move default definitions from gcc.c. * gcc.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Move to defaults.h. * gcc.h (DEFAULT_SWITCH_TAKES_ARG, DEFAULT_WORD_SWITCH_TAKES_ARG): Move to defaults.h. * opts-common.c: Include tm.h. (decode_cmdline_option): Use SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG to count arguments to unknown options. Handle more than one argument. Set canonical_option_num_elements. (decode_cmdline_options_to_array): Set canonical_option_num_elements and trailing elements of canonical_option. * opts.h (struct cl_decoded_option): Allow four elements in canonical_option. Add field canonical_option_num_elements. * Makefile.in (opts-common.o): Update dependencies. ada: 2010-06-23 Joseph Myers * gcc-interface/misc.c (gnat_init_options): Ignore erroneous options. Check canonical_option_num_elements on options copied. fortran: 2010-06-23 Joseph Myers * gfortranspec.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Remove. diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/Makefile.in gcc-mainline/gcc/Makefile.in --- gcc-mainline-opt3/gcc/Makefile.in 2010-06-22 15:24:00.000000000 -0700 +++ gcc-mainline/gcc/Makefile.in 2010-06-23 08:44:22.000000000 -0700 @@ -2796,7 +2796,7 @@ opts.o : opts.c opts.h options.h $(TOPLE $(FLAGS_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) debug.h \ $(PLUGIN_H) $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h intl.h $(DIAGNOSTIC_H) + coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H) targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(TOPLEV_H) \ $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/ada/gcc-interface/misc.c gcc-mainline/gcc/ada/gcc-interface/misc.c --- gcc-mainline-opt3/gcc/ada/gcc-interface/misc.c 2010-06-22 16:02:04.000000000 -0700 +++ gcc-mainline/gcc/ada/gcc-interface/misc.c 2010-06-23 07:46:46.000000000 -0700 @@ -303,8 +303,13 @@ gnat_init_options (unsigned int decoded_ save_argc = 0; for (i = 0; i < decoded_options_count; i++) { + if (decoded_options[i].errors + || decoded_options[i].opt_index == OPT_SPECIAL_unknown) + continue; + gcc_assert (decoded_options[i].canonical_option_num_elements >= 1 + && decoded_options[i].canonical_option_num_elements <= 2); save_argv[save_argc++] = decoded_options[i].canonical_option[0]; - if (decoded_options[i].canonical_option[1] != NULL) + if (decoded_options[i].canonical_option_num_elements >= 2) save_argv[save_argc++] = decoded_options[i].canonical_option[1]; } save_argv[save_argc] = NULL; diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/config/darwin-driver.c gcc-mainline/gcc/config/darwin-driver.c --- gcc-mainline-opt3/gcc/config/darwin-driver.c 2010-06-04 06:35:13.000000000 -0700 +++ gcc-mainline/gcc/config/darwin-driver.c 2010-06-23 08:24:32.000000000 -0700 @@ -27,14 +27,6 @@ along with GCC; see the file COPYING3. #include #include "xregex.h" -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - /* When running on a Darwin system and using that system's headers and libraries, default the -mmacosx-version-min flag to be the version of the system on which the compiler is running. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/cppspec.c gcc-mainline/gcc/cppspec.c --- gcc-mainline-opt3/gcc/cppspec.c 2010-06-04 06:40:58.000000000 -0700 +++ gcc-mainline/gcc/cppspec.c 2010-06-23 08:24:05.000000000 -0700 @@ -30,14 +30,6 @@ along with GCC; see the file COPYING3. assume the user knows what they're doing. If no explicit input is mentioned, it will read stdin. */ -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - /* Suffixes for known sorts of input files. Note that we do not list files which are normally considered to have been preprocessed already, since the user's expectation is that `cpp' always preprocesses. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/defaults.h gcc-mainline/gcc/defaults.h --- gcc-mainline-opt3/gcc/defaults.h 2010-06-11 02:16:45.000000000 -0700 +++ gcc-mainline/gcc/defaults.h 2010-06-23 08:24:12.000000000 -0700 @@ -32,6 +32,38 @@ see the files COPYING3 and COPYING.RUNTI #define GET_ENVIRONMENT(VALUE, NAME) do { (VALUE) = getenv (NAME); } while (0) #endif +/* This defines which switch letters take arguments. */ + +#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \ + ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ + || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ + || (CHAR) == 'I' || (CHAR) == 'J' || (CHAR) == 'm' \ + || (CHAR) == 'x' || (CHAR) == 'L' || (CHAR) == 'A' \ + || (CHAR) == 'B' ) + +/* This defines which multi-letter switches take arguments. */ + +#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ + (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ + || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ + || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ + || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ + || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ + || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \ + || !strcmp (STR, "isysroot") \ + || !strcmp (STR, "-param") || !strcmp (STR, "specs") \ + || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ") \ + || !strcmp (STR, "fintrinsic-modules-path") \ + || !strcmp (STR, "dumpbase") || !strcmp (STR, "dumpdir")) + +#ifndef SWITCH_TAKES_ARG +#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG (CHAR) +#endif + +#ifndef WORD_SWITCH_TAKES_ARG +#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) +#endif + /* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable or function named NAME. LABELNO is an integer which is different for each call. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/fortran/gfortranspec.c gcc-mainline/gcc/fortran/gfortranspec.c --- gcc-mainline-opt3/gcc/fortran/gfortranspec.c 2010-06-16 09:07:30.000000000 -0700 +++ gcc-mainline/gcc/fortran/gfortranspec.c 2010-06-23 08:25:11.000000000 -0700 @@ -113,22 +113,6 @@ static void append_arg (const char *); static int g77_newargc; static const char **g77_newargv; -/* --- This comes from gcc.c (2.8.1) verbatim: */ - -/* This defines which switch letters take arguments. */ - -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -/* This defines which multi-letter switches take arguments. */ - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - -/* --- End of verbatim. */ - /* 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 diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/gcc.c gcc-mainline/gcc/gcc.c --- gcc-mainline-opt3/gcc/gcc.c 2010-06-07 02:48:58.000000000 -0700 +++ gcc-mainline/gcc/gcc.c 2010-06-23 08:22:19.000000000 -0700 @@ -975,13 +975,6 @@ struct user_specs static struct user_specs *user_specs_head, *user_specs_tail; -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif #ifdef HAVE_TARGET_EXECUTABLE_SUFFIX /* This defines which switches stop a full compilation. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/gcc.h gcc-mainline/gcc/gcc.h --- gcc-mainline-opt3/gcc/gcc.h 2010-05-28 12:31:35.000000000 -0700 +++ gcc-mainline/gcc/gcc.h 2010-06-23 08:21:07.000000000 -0700 @@ -32,31 +32,6 @@ struct spec_function const char *(*func) (int, const char **); }; -/* This defines which switch letters take arguments. */ - -#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \ - ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ - || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ - || (CHAR) == 'I' || (CHAR) == 'J' || (CHAR) == 'm' \ - || (CHAR) == 'x' || (CHAR) == 'L' || (CHAR) == 'A' \ - || (CHAR) == 'B' ) - -/* This defines which multi-letter switches take arguments. */ - -#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ - (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ - || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ - || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ - || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ - || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ - || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \ - || !strcmp (STR, "isysroot") \ - || !strcmp (STR, "-param") || !strcmp (STR, "specs") \ - || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ") \ - || !strcmp (STR, "fintrinsic-modules-path") \ - || !strcmp (STR, "dumpbase") || !strcmp (STR, "dumpdir")) - - /* These are exported by gcc.c. */ extern int do_spec (const char *); extern void record_temp_file (const char *, int, int); diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/opts-common.c gcc-mainline/gcc/opts-common.c --- gcc-mainline-opt3/gcc/opts-common.c 2010-06-22 15:23:48.000000000 -0700 +++ gcc-mainline/gcc/opts-common.c 2010-06-23 11:44:40.000000000 -0700 @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. #include "opts.h" #include "options.h" #include "diagnostic.h" +#include "tm.h" /* For SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG. */ /* Perform a binary search to find which option the command-line INPUT matches. Returns its index in the option array, and @@ -138,7 +139,9 @@ decode_cmdline_option (const char **argv const char *opt, *arg = 0; char *dup = 0; int value = 1; - unsigned int result = 1; + unsigned int result = 1, i; + size_t total_len; + char *p; const struct cl_option *option; int errors = 0; @@ -242,22 +245,54 @@ decode_cmdline_option (const char **argv decoded->arg = arg; decoded->value = value; decoded->errors = errors; - switch (result) + + if (opt_index == OPT_SPECIAL_unknown) { - case 1: - decoded->orig_option_with_args_text = argv[0]; - decoded->canonical_option[0] = argv[0]; - decoded->canonical_option[1] = NULL; - break; - case 2: - decoded->orig_option_with_args_text = concat (argv[0], " ", - argv[1], NULL); - decoded->canonical_option[0] = argv[0]; - decoded->canonical_option[1] = argv[1]; - break; - default: - gcc_unreachable (); + /* Skip the correct number of arguments for options handled + through specs. */ + const char *popt = argv[0] + 1; + int c = *popt; + + gcc_assert (result == 1); + if (SWITCH_TAKES_ARG (c) > (popt[1] != 0)) + result += SWITCH_TAKES_ARG (c) - (popt[1] != 0); + else if (WORD_SWITCH_TAKES_ARG (popt)) + result += WORD_SWITCH_TAKES_ARG (popt); + if (result > 1) + for (i = 1; i < result; i++) + if (argv[i] == NULL) + { + result = i; + break; + } } + + gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option)); + decoded->canonical_option_num_elements = result; + total_len = 0; + for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++) + { + if (i < result) + { + decoded->canonical_option[i] = argv[i]; + total_len += strlen (argv[i]) + 1; + } + else + decoded->canonical_option[i] = NULL; + } + decoded->orig_option_with_args_text = p = XNEWVEC (char, total_len); + for (i = 0; i < result; i++) + { + size_t len = strlen (argv[i]); + + memcpy (p, argv[i], len); + p += len; + if (i == result - 1) + *p++ = 0; + else + *p++ = ' '; + } + return result; } @@ -284,8 +319,11 @@ decode_cmdline_options_to_array (unsigne opt_array[0].opt_index = OPT_SPECIAL_program_name; opt_array[0].arg = argv[0]; opt_array[0].orig_option_with_args_text = argv[0]; + opt_array[0].canonical_option_num_elements = 1; opt_array[0].canonical_option[0] = argv[0]; opt_array[0].canonical_option[1] = NULL; + opt_array[0].canonical_option[2] = NULL; + opt_array[0].canonical_option[3] = NULL; opt_array[0].value = 1; opt_array[0].errors = 0; num_decoded_options = 1; @@ -300,8 +338,11 @@ decode_cmdline_options_to_array (unsigne 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; num_decoded_options++; diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/opts.h gcc-mainline/gcc/opts.h --- gcc-mainline-opt3/gcc/opts.h 2010-06-22 15:15:44.000000000 -0700 +++ gcc-mainline/gcc/opts.h 2010-06-23 07:30:21.000000000 -0700 @@ -121,10 +121,12 @@ struct cl_decoded_option /* The canonical form of the option and its argument, for when it is necessary to reconstruct argv elements (in particular, for processing specs and passing options to subprocesses from the - driver). The first element of this array is non-NULL; the second - is NULL if the canonical form uses only one argv element, - non-NULL otherwise. */ - const char *canonical_option[2]; + driver). */ + const char *canonical_option[4]; + + /* The number of elements in the canonical form of the option and + arguments; always at least 1. */ + size_t canonical_option_num_elements; /* For a boolean option, 1 for the true case and 0 for the "no-" case. For an unsigned integer option, the value of the