OSDN Git Service

gcc/
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 May 2006 14:27:18 +0000 (14:27 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 May 2006 14:27:18 +0000 (14:27 +0000)
2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>

PR driver/26885
* Makefile.in (GCC_OBJS): New.
(OBJS-common): Add opts-common.o.
(xgcc$(exeext)): Replace gcc.o with $(GCC_OBJS).
(cpp$(exeext)): Likewise.
(gcc.o): Also depend on opts.h.
(opts-common.o): New.

* common.opt (gcoff): Add Negative(gdwarf-2).
(gdwarf-2): Add Negative(gstabs).
(gstabs): Add Negative(gstabs+).
(gstabs+): Add Negative(gvms).
(gvms): Add Negative(gxcoff).
(gxcoff): Add Negative(gxcoff+).
(gxcoff+): Add Negative(gcoff).
* config/i386/i386.opt (m32): Add Negative(m64).
(m64): Add Negative(m32).

* doc/options.texi: Document the Negative option.

* gcc.c: Include "opts.h".
(main): Call prune_options after expandargv.

* optc-gen.awk: Generate common declarations for all flag
variables in options.c. Output the neg_index field.

* opts.c (find_opt): Moved to ...
* opts-common.c: Here. New file.

* opts.h (cl_option): Add a neg_index field.
(find_opt): New.
(prune_options): Likewise.

gcc/cp/

2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>

PR driver/26885
* Make-lang.in (GXX_OBJS): Replace gcc.o with $(GCC_OBJS).

gcc/fortran/

2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>

PR driver/26885
* Make-lang.in (GFORTRAN_D_OBJS): Replace gcc.o with
$(GCC_OBJS).

gcc/java/

2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>

PR driver/26885
* Make-lang.in ($(GCJ)$(exeext)): Replace gcc.o with
$(GCC_OBJS).

gcc/treelang/

2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>

PR driver/26885
* Make-lang.in (gtreelang$(exeext)): Replace gcc.o with
$(GCC_OBJS).

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113824 138bc75d-0d04-0410-961f-82ee72b054a4

18 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/common.opt
gcc/config/i386/i386.opt
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/doc/options.texi
gcc/fortran/ChangeLog
gcc/fortran/Make-lang.in
gcc/gcc.c
gcc/java/ChangeLog
gcc/java/Make-lang.in
gcc/optc-gen.awk
gcc/opts-common.c [new file with mode: 0644]
gcc/opts.c
gcc/opts.h
gcc/treelang/ChangeLog
gcc/treelang/Make-lang.in

index cee2e43..e5a5879 100644 (file)
@@ -1,3 +1,38 @@
+2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR driver/26885
+       * Makefile.in (GCC_OBJS): New.
+       (OBJS-common): Add opts-common.o.
+       (xgcc$(exeext)): Replace gcc.o with $(GCC_OBJS).
+       (cpp$(exeext)): Likewise.
+       (gcc.o): Also depend on opts.h.
+       (opts-common.o): New.
+
+       * common.opt (gcoff): Add Negative(gdwarf-2).
+       (gdwarf-2): Add Negative(gstabs).
+       (gstabs): Add Negative(gstabs+).
+       (gstabs+): Add Negative(gvms).
+       (gvms): Add Negative(gxcoff).
+       (gxcoff): Add Negative(gxcoff+).
+       (gxcoff+): Add Negative(gcoff).
+       * config/i386/i386.opt (m32): Add Negative(m64).
+       (m64): Add Negative(m32).
+
+       * doc/options.texi: Document the Negative option.
+
+       * gcc.c: Include "opts.h".
+       (main): Call prune_options after expandargv.
+
+       * optc-gen.awk: Generate common declarations for all flag
+       variables in options.c. Output the neg_index field.
+
+       * opts.c (find_opt): Moved to ...
+       * opts-common.c: Here. New file.
+
+       * opts.h (cl_option): Add a neg_index field.
+       (find_opt): New.
+       (prune_options): Likewise.
+
 2006-05-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/27573
index 93a5016..7b08929 100644 (file)
@@ -947,6 +947,9 @@ C_TARGET_OBJS=@c_target_objs@
 # Target specific, C++ specific object file
 CXX_TARGET_OBJS=@cxx_target_objs@
 
+# Object files for gcc driver.
+GCC_OBJS = gcc.o opts-common.o options.o
+
 # Language-specific object files for C and Objective C.
 C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
   c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
@@ -988,7 +991,7 @@ OBJS-common = \
  haifa-sched.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o insn-modes.o    \
  insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o      \
  integrate.o intl.o jump.o  langhooks.o lcm.o lists.o local-alloc.o       \
- mode-switching.o modulo-sched.o optabs.o options.o opts.o        \
+ mode-switching.o modulo-sched.o optabs.o options.o opts.o opts-common.o \
  params.o postreload.o postreload-gcse.o predict.o                        \
  insn-preds.o insn-automata.o pointer-set.o                               \
  print-rtl.o print-tree.o profile.o value-prof.o var-tracking.o                   \
@@ -1292,18 +1295,18 @@ libbackend.a: $(OBJS@onestep@)
 # We call this executable `xgcc' rather than `gcc'
 # to avoid confusion if the current directory is in the path
 # and CC is `gcc'.  It is renamed to `gcc' when it is installed.
-xgcc$(exeext): gcc.o gccspec.o version.o intl.o prefix.o \
+xgcc$(exeext): $(GCC_OBJS) gccspec.o version.o intl.o prefix.o \
    version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o gccspec.o intl.o \
-         prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
+       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) gccspec.o \
+         intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
 
 # cpp is to cpp0 as gcc is to cc1.
 # The only difference from xgcc is that it's linked with cppspec.o
 # instead of gccspec.o.
-cpp$(exeext): gcc.o cppspec.o version.o intl.o prefix.o \
+cpp$(exeext): $(GCC_OBJS) cppspec.o version.o intl.o prefix.o \
    version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o cppspec.o intl.o \
-         prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
+       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) cppspec.o \
+         intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
 
 # Create links to binutils, especially for in-tree builds, to make -B.
 # use them.  We need hard links so that directories can be shuffled
@@ -1700,7 +1703,7 @@ DRIVER_DEFINES = \
 
 gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h multilib.h \
     Makefile $(lang_specs_files) specs.h prefix.h $(GCC_H) $(FLAGS_H) \
-    configargs.h $(OBSTACK_H)
+    configargs.h $(OBSTACK_H) opts.h
        (SHLIB_LINK='$(SHLIB_LINK)' \
        SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
        $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
@@ -2117,6 +2120,8 @@ opts.o : opts.c opts.h options.h toplev.h $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(RTL_H) \
    output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
    $(FLAGS_H) $(PARAMS_H) tree-pass.h
+opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \
+   coretypes.h intl.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
index 9d9cbca..ab50569 100644 (file)
@@ -1088,11 +1088,11 @@ Common JoinedOrMissing
 Generate debug information in default format
 
 gcoff
-Common JoinedOrMissing
+Common JoinedOrMissing Negative(gdwarf-2)
 Generate debug information in COFF format
 
 gdwarf-2
-Common JoinedOrMissing
+Common JoinedOrMissing Negative(gstabs)
 Generate debug information in DWARF v2 format
 
 ggdb
@@ -1100,23 +1100,23 @@ Common JoinedOrMissing
 Generate debug information in default extended format
 
 gstabs
-Common JoinedOrMissing
+Common JoinedOrMissing Negative(gstabs+)
 Generate debug information in STABS format
 
 gstabs+
-Common JoinedOrMissing
+Common JoinedOrMissing Negative(gvms)
 Generate debug information in extended STABS format
 
 gvms
-Common JoinedOrMissing
+Common JoinedOrMissing Negative(gxcoff)
 Generate debug information in VMS format
 
 gxcoff
-Common JoinedOrMissing
+Common JoinedOrMissing Negative(gxcoff+)
 Generate debug information in XCOFF format
 
 gxcoff+
-Common JoinedOrMissing
+Common JoinedOrMissing Negative(gcoff)
 Generate debug information in extended XCOFF format
 
 o
index 9cd29b4..4d71492 100644 (file)
@@ -24,7 +24,7 @@ Target RejectNegative Report Mask(128BIT_LONG_DOUBLE)
 sizeof(long double) is 16
 
 m32
-Target RejectNegative Report InverseMask(64BIT)
+Target RejectNegative Negative(m64) Report InverseMask(64BIT)
 Generate 32bit i386 code
 
 m386
@@ -40,7 +40,7 @@ Target RejectNegative Undocumented
 ;; Deprecated
 
 m64
-Target RejectNegative Report Mask(64BIT)
+Target RejectNegative Negative(m32) Report Mask(64BIT)
 Generate 64bit x86-64 code
 
 m80387
index 42af5fd..698ae1a 100644 (file)
@@ -1,3 +1,8 @@
+2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR driver/26885
+       * Make-lang.in (GXX_OBJS): Replace gcc.o with $(GCC_OBJS).
+
 2006-05-15  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/27339
index 7b6268d..9bb1bb4 100644 (file)
@@ -60,7 +60,7 @@ g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) $(CON
                $(INCLUDES) $(srcdir)/cp/g++spec.c)
 
 # Create the compiler driver for g++.
-GXX_OBJS = gcc.o g++spec.o intl.o prefix.o version.o
+GXX_OBJS = $(GCC_OBJS) g++spec.o intl.o prefix.o version.o
 g++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
        $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
          $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
index b4ada5b..58791c7 100644 (file)
@@ -136,6 +136,13 @@ parser will set the variable to 1 when the positive form of the
 option is used and 0 when the ``no-'' form is used.
 
 @item
+If the option uses the @code{Negative} property, @var{var} is the
+the name of an option, with the leading ``-'' removed, which will be
+turned off when this option is turned on.  This chain action will
+propagate through the @code{Negative} property of the option to be
+turned off.
+
+@item
 If the option takes an argument and has the @code{UInteger} property,
 @var{var} is an integer variable that stores the value of the argument.
 
index 11b3b62..f07af3b 100644 (file)
@@ -1,3 +1,9 @@
+2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR driver/26885
+       * Make-lang.in (GFORTRAN_D_OBJS): Replace gcc.o with
+       $(GCC_OBJS).
+
 2006-05-15  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/25090
index ba9bfe8..dc771f9 100644 (file)
@@ -93,7 +93,7 @@ gfortranspec.o: $(srcdir)/fortran/gfortranspec.c $(SYSTEM_H) $(TM_H) $(GCC_H) $(
                $(INCLUDES) $(srcdir)/fortran/gfortranspec.c)
 
 # Create the compiler driver gfortran.
-GFORTRAN_D_OBJS = gcc.o gfortranspec.o version.o prefix.o intl.o
+GFORTRAN_D_OBJS = $(GCC_OBJS) gfortranspec.o version.o prefix.o intl.o
 gfortran$(exeext): $(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
        $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
          $(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
index 7e5733c..4c917aa 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -86,6 +86,7 @@ compilation is specified by a string called a "spec".  */
 #include "prefix.h"
 #include "gcc.h"
 #include "flags.h"
+#include "opts.h"
 
 /* By default there is no special suffix for target executables.  */
 /* FIXME: when autoconf is fixed, remove the host check - dj */
@@ -6098,6 +6099,8 @@ main (int argc, char **argv)
 
   expandargv (&argc, &argv);
 
+  prune_options (&argc, &argv);
+
 #ifdef GCC_DRIVER_HOST_INITIALIZATION
   /* Perform host dependent initialization when needed.  */
   GCC_DRIVER_HOST_INITIALIZATION;
index 783ba55..3d2e47c 100644 (file)
@@ -1,3 +1,9 @@
+2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR driver/26885
+       * Make-lang.in ($(GCJ)$(exeext)): Replace gcc.o with
+       $(GCC_OBJS).
+
 2006-05-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * Make-lang.in (java/decl.o): Add dependency on $(TARGET_H).
index dcb94d5..1a6d5be 100644 (file)
@@ -67,10 +67,10 @@ jvspec.o: $(srcdir)/java/jvspec.c $(SYSTEM_H) coretypes.h $(TM_H) \
                $(INCLUDES) $(srcdir)/java/jvspec.c $(OUTPUT_OPTION))
 
 # Create the compiler driver for $(GCJ).
-$(GCJ)$(exeext): gcc.o jvspec.o version.o \
+$(GCJ)$(exeext): $(GCC_OBJS) jvspec.o version.o \
           prefix.o intl.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
-       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o jvspec.o prefix.o intl.o \
-         version.o $(EXTRA_GCC_OBJS) $(LIBS)
+       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) jvspec.o \
+         prefix.o intl.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
 
 # Create a version of the $(GCJ) driver which calls the cross-compiler.
 $(GCJ)-cross$(exeext): $(GCJ)$(exeext)
index 065972b..da19917 100644 (file)
@@ -62,20 +62,27 @@ for (i = 1; i <= n_headers; i++)
 print "#include " quote "opts.h" quote
 print "#include " quote "intl.h" quote
 print ""
+print "int target_flags;"
+print ""
 
 for (i = 0; i < n_opts; i++) {
        name = var_name(flags[i]);
        if (name == "")
                continue;
 
-       if (flag_set_p("VarExists", flags[i]))
-               continue;
-
-       init = opt_args("Init", flags[i])
-       if (init != "")
-               init = " = " init;
-       else if (name in var_seen)
-               continue;
+       if (flag_set_p("VarExists", flags[i])) {
+               # Need it for the gcc driver.
+               if (name in var_seen)
+                       continue;
+               init = ""
+       }
+       else {
+               init = opt_args("Init", flags[i])
+               if (init != "")
+                       init = " = " init;
+               else if (name in var_seen)
+                       continue;
+       }
 
        print "/* Set by -" opts[i] "."
        print "   " help[i] "  */"
@@ -107,8 +114,21 @@ print "const unsigned int cl_options_count = N_OPTS;\n"
 
 print "const struct cl_option cl_options[] =\n{"
 
-for (i = 0; i < n_opts; i++)
+j = 0
+for (i = 0; i < n_opts; i++) {
        back_chain[i] = "N_OPTS";
+       indices[opts[i]] = j;
+       # Combine the flags of identical switches.  Switches
+       # appear many times if they are handled by many front
+       # ends, for example.
+       while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
+               flags[i + 1] = flags[i] " " flags[i + 1];
+               i++;
+               back_chain[i] = "N_OPTS";
+               indices[opts[i]] = j;
+       }
+       j++;
+}
 
 for (i = 0; i < n_opts; i++) {
        # Combine the flags of identical switches.  Switches
@@ -147,8 +167,21 @@ for (i = 0; i < n_opts; i++) {
        else
                hlp = quote help[i] quote;
 
-       printf("  { %c-%s%c,\n    %s,\n    %s, %u,\n",
-              quote, opts[i], quote, hlp, back_chain[i], len)
+       neg = opt_args("Negative", flags[i]);
+       if (neg != "")
+               idx = indices[neg]
+       else {
+               if (flag_set_p("RejectNegative", flags[i]))
+                       idx = -1;
+               else {
+                       if (opts[i] ~ "^[Wfm]")
+                               idx = indices[opts[i]];
+                       else
+                               idx = -1;
+               }
+       }
+       printf("  { %c-%s%c,\n    %s,\n    %s, %u, %d,\n",
+              quote, opts[i], quote, hlp, back_chain[i], len, idx)
        condition = opt_args("Condition", flags[i])
        cl_flags = switch_flags(flags[i])
        if (condition != "")
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
new file mode 100644 (file)
index 0000000..f3f6542
--- /dev/null
@@ -0,0 +1,233 @@
+/* Command line option handling.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "intl.h"
+#include "coretypes.h"
+#include "opts.h"
+
+/* Perform a binary search to find which option the command-line INPUT
+   matches.  Returns its index in the option array, and N_OPTS
+   (cl_options_count) on failure.
+
+   This routine is quite subtle.  A normal binary search is not good
+   enough because some options can be suffixed with an argument, and
+   multiple sub-matches can occur, e.g. input of "-pedantic" matching
+   the initial substring of "-pedantic-errors".
+
+   A more complicated example is -gstabs.  It should match "-g" with
+   an argument of "stabs".  Suppose, however, that the number and list
+   of switches are such that the binary search tests "-gen-decls"
+   before having tested "-g".  This doesn't match, and as "-gen-decls"
+   is less than "-gstabs", it will become the lower bound of the
+   binary search range, and "-g" will never be seen.  To resolve this
+   issue, opts.sh makes "-gen-decls" point, via the back_chain member,
+   to "-g" so that failed searches that end between "-gen-decls" and
+   the lexicographically subsequent switch know to go back and see if
+   "-g" causes a match (which it does in this example).
+
+   This search is done in such a way that the longest match for the
+   front end in question wins.  If there is no match for the current
+   front end, the longest match for a different front end is returned
+   (or N_OPTS if none) and the caller emits an error message.  */
+size_t
+find_opt (const char *input, int lang_mask)
+{
+  size_t mn, mx, md, opt_len;
+  size_t match_wrong_lang;
+  int comp;
+
+  mn = 0;
+  mx = cl_options_count;
+
+  /* Find mn such this lexicographical inequality holds:
+     cl_options[mn] <= input < cl_options[mn + 1].  */
+  while (mx - mn > 1)
+    {
+      md = (mn + mx) / 2;
+      opt_len = cl_options[md].opt_len;
+      comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
+
+      if (comp < 0)
+       mx = md;
+      else
+       mn = md;
+    }
+
+  /* This is the switch that is the best match but for a different
+     front end, or cl_options_count if there is no match at all.  */
+  match_wrong_lang = cl_options_count;
+
+  /* Backtrace the chain of possible matches, returning the longest
+     one, if any, that fits best.  With current GCC switches, this
+     loop executes at most twice.  */
+  do
+    {
+      const struct cl_option *opt = &cl_options[mn];
+
+      /* Is the input either an exact match or a prefix that takes a
+        joined argument?  */
+      if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
+         && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
+       {
+         /* If language is OK, return it.  */
+         if (opt->flags & lang_mask)
+           return mn;
+
+         /* If we haven't remembered a prior match, remember this
+            one.  Any prior match is necessarily better.  */
+         if (match_wrong_lang == cl_options_count)
+           match_wrong_lang = mn;
+       }
+
+      /* Try the next possibility.  This is cl_options_count if there
+        are no more.  */
+      mn = opt->back_chain;
+    }
+  while (mn != cl_options_count);
+
+  /* Return the best wrong match, or cl_options_count if none.  */
+  return match_wrong_lang;
+}
+
+/* Return true if NEXT_OPT_IDX cancels OPT_IDX.  Return false if the
+   next one is the same as ORIG_NEXT_OPT_IDX.  */
+
+static bool
+cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
+{
+  /* An option can be canceled by the same option or an option with
+     Negative.  */
+  if (cl_options [next_opt_idx].neg_index == opt_idx)
+    return true;
+
+  if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
+    return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
+                         orig_next_opt_idx);
+    
+  return false;
+}
+
+/* Filter out options canceled by the ones after them.  */
+
+void
+prune_options (int *argcp, char ***argvp)
+{
+  int argc = *argcp;
+  int *options = xmalloc (argc * sizeof (*options));
+  char **argv = xmalloc (argc * sizeof (char *));
+  int i, arg_count, need_prune = 0;
+  const struct cl_option *option;
+  size_t opt_index;
+
+  /* Scan all arguments.  */
+  for (i = 1; i < argc; i++)
+    {
+      int value = 1;
+      const char *opt = (*argvp) [i];
+
+      opt_index = find_opt (opt + 1, -1);
+      if (opt_index == cl_options_count
+         && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
+         && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+       {
+         char *dup;
+
+         /* Drop the "no-" from negative switches.  */
+         size_t len = strlen (opt) - 3;
+
+         dup = XNEWVEC (char, len + 1);
+         dup[0] = '-';
+         dup[1] = opt[1];
+         memcpy (dup + 2, opt + 5, len - 2 + 1);
+         opt = dup;
+         value = 0;
+         opt_index = find_opt (opt + 1, -1);
+         free (dup);
+       }
+
+      if (opt_index == cl_options_count)
+       {
+cont:
+         options [i] = 0;
+         continue;
+       }
+
+      option = &cl_options[opt_index];
+      if (option->neg_index < 0)
+       goto cont;
+
+      /* Reject negative form of switches that don't take negatives as
+        unrecognized.  */
+      if (!value && (option->flags & CL_REJECT_NEGATIVE))
+       goto cont;
+
+      options [i] = (int) opt_index;
+      need_prune |= options [i];
+    }
+
+  if (!need_prune)
+    goto done;
+
+  /* Remove arguments which are negated by others after them.  */
+  argv [0] = (*argvp) [0];
+  arg_count = 1;
+  for (i = 1; i < argc; i++)
+    {
+      int j, opt_idx;
+
+      opt_idx = options [i];
+      if (opt_idx)
+       {
+         int next_opt_idx;
+         for (j = i + 1; j < argc; j++)
+           {
+             next_opt_idx = options [j];
+             if (next_opt_idx
+                 && cancel_option (opt_idx, next_opt_idx,
+                                   next_opt_idx))
+               break;
+           }
+       }
+      else
+       goto keep;
+
+      if (j == argc)
+       {
+keep:
+         argv [arg_count] = (*argvp) [i];
+         arg_count++;
+       }
+    }
+
+  if (arg_count != argc)
+    {
+      *argcp = arg_count;
+      *argvp = argv;
+    }
+  else
+    {
+done:
+      free (argv);
+    }
+
+  free (options);
+}
index 00b9716..01ec30d 100644 (file)
@@ -105,7 +105,6 @@ static bool flag_peel_loops_set, flag_branch_probabilities_set;
 const char **in_fnames;
 unsigned num_in_fnames;
 
-static size_t find_opt (const char *, int);
 static int common_handle_option (size_t scode, const char *arg, int value,
                                 unsigned int lang_mask);
 static void handle_param (const char *);
@@ -124,90 +123,6 @@ static unsigned int print_switch (const char *text, unsigned int indent);
 static void set_debug_level (enum debug_info_type type, int extended,
                             const char *arg);
 
-/* Perform a binary search to find which option the command-line INPUT
-   matches.  Returns its index in the option array, and N_OPTS
-   (cl_options_count) on failure.
-
-   This routine is quite subtle.  A normal binary search is not good
-   enough because some options can be suffixed with an argument, and
-   multiple sub-matches can occur, e.g. input of "-pedantic" matching
-   the initial substring of "-pedantic-errors".
-
-   A more complicated example is -gstabs.  It should match "-g" with
-   an argument of "stabs".  Suppose, however, that the number and list
-   of switches are such that the binary search tests "-gen-decls"
-   before having tested "-g".  This doesn't match, and as "-gen-decls"
-   is less than "-gstabs", it will become the lower bound of the
-   binary search range, and "-g" will never be seen.  To resolve this
-   issue, opts.sh makes "-gen-decls" point, via the back_chain member,
-   to "-g" so that failed searches that end between "-gen-decls" and
-   the lexicographically subsequent switch know to go back and see if
-   "-g" causes a match (which it does in this example).
-
-   This search is done in such a way that the longest match for the
-   front end in question wins.  If there is no match for the current
-   front end, the longest match for a different front end is returned
-   (or N_OPTS if none) and the caller emits an error message.  */
-static size_t
-find_opt (const char *input, int lang_mask)
-{
-  size_t mn, mx, md, opt_len;
-  size_t match_wrong_lang;
-  int comp;
-
-  mn = 0;
-  mx = cl_options_count;
-
-  /* Find mn such this lexicographical inequality holds:
-     cl_options[mn] <= input < cl_options[mn + 1].  */
-  while (mx - mn > 1)
-    {
-      md = (mn + mx) / 2;
-      opt_len = cl_options[md].opt_len;
-      comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
-
-      if (comp < 0)
-       mx = md;
-      else
-       mn = md;
-    }
-
-  /* This is the switch that is the best match but for a different
-     front end, or cl_options_count if there is no match at all.  */
-  match_wrong_lang = cl_options_count;
-
-  /* Backtrace the chain of possible matches, returning the longest
-     one, if any, that fits best.  With current GCC switches, this
-     loop executes at most twice.  */
-  do
-    {
-      const struct cl_option *opt = &cl_options[mn];
-
-      /* Is the input either an exact match or a prefix that takes a
-        joined argument?  */
-      if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
-         && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
-       {
-         /* If language is OK, return it.  */
-         if (opt->flags & lang_mask)
-           return mn;
-
-         /* If we haven't remembered a prior match, remember this
-            one.  Any prior match is necessarily better.  */
-         if (match_wrong_lang == cl_options_count)
-           match_wrong_lang = mn;
-       }
-
-      /* Try the next possibility.  This is cl_options_count if there
-        are no more.  */
-      mn = opt->back_chain;
-    }
-  while (mn != cl_options_count);
-
-  /* Return the best wrong match, or cl_options_count if none.  */
-  return match_wrong_lang;
-}
-
 /* If ARG is a non-negative integer made up solely of digits, return its
    value, otherwise return -1.  */
 static int
index bfa9ccc..3af501f 100644 (file)
@@ -46,6 +46,7 @@ struct cl_option
   const char *help;
   unsigned short back_chain;
   unsigned char opt_len;
+  int neg_index;
   unsigned int flags;
   void *flag_var;
   enum cl_var_type var_type;
@@ -84,6 +85,8 @@ extern const char **in_fnames;
 
 extern unsigned num_in_fnames;
 
+size_t find_opt (const char *input, int lang_mask);
+extern void prune_options (int *argcp, char ***argvp);
 extern void decode_options (unsigned int argc, const char **argv);
 extern int option_enabled (int opt_idx);
 extern bool get_option_state (int, struct cl_option_state *);
index 71b444d..b4ee6d3 100644 (file)
@@ -1,3 +1,9 @@
+2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR driver/26885
+       * Make-lang.in (gtreelang$(exeext)): Replace gcc.o with
+       $(GCC_OBJS).
+
 2006-05-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * Make-lang.in (treelang/treetree.o): Add dependency on
index 2d91fd3..a0230d4 100644 (file)
@@ -87,10 +87,10 @@ tree1$(exeext): treelang/tree1.o treelang/treetree.o treelang/tree-convert.o \
        $(BACKEND) $(LIBS) attribs.o
 
 # Create the compiler driver treelang.
-gtreelang$(exeext): gcc.o version.o prefix.o intl.o $(EXTRA_GCC_OBJS) \
+gtreelang$(exeext): $(GCC_OBJS) version.o prefix.o intl.o $(EXTRA_GCC_OBJS) \
   $(LIBDEPS) treelang/spec.o
        $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ treelang/spec.o \
-         gcc.o version.o prefix.o intl.o $(EXTRA_GCC_OBJS) $(LIBS)
+         $(GCC_OBJS) version.o prefix.o intl.o $(EXTRA_GCC_OBJS) $(LIBS)