aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2006-05-16 14:27:18 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2006-05-16 07:27:18 -0700
commit14c7833ccd0392c40505c4f707abc7ef64af7972 (patch)
treef010ca26f2ca6b7e3f6a1baeeac28d996a541357 /gcc
parentb570947c8ad996f00aaa621a9e3dee997baa2e2e (diff)
downloadgcc-14c7833ccd0392c40505c4f707abc7ef64af7972.zip
gcc-14c7833ccd0392c40505c4f707abc7ef64af7972.tar.gz
gcc-14c7833ccd0392c40505c4f707abc7ef64af7972.tar.bz2
re PR target/26885 (-m64 -m32 no longer creates 32-bit object)
gcc/ 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). From-SVN: r113824
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog35
-rw-r--r--gcc/Makefile.in21
-rw-r--r--gcc/common.opt14
-rw-r--r--gcc/config/i386/i386.opt4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/Make-lang.in2
-rw-r--r--gcc/doc/options.texi7
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/Make-lang.in2
-rw-r--r--gcc/gcc.c3
-rw-r--r--gcc/java/ChangeLog6
-rw-r--r--gcc/java/Make-lang.in6
-rw-r--r--gcc/optc-gen.awk55
-rw-r--r--gcc/opts-common.c233
-rw-r--r--gcc/opts.c85
-rw-r--r--gcc/opts.h3
-rw-r--r--gcc/treelang/ChangeLog6
-rw-r--r--gcc/treelang/Make-lang.in4
18 files changed, 377 insertions, 120 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cee2e43..e5a5879 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 93a5016..7b08929 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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
diff --git a/gcc/common.opt b/gcc/common.opt
index 9d9cbca..ab505696 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -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
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 9cd29b4..4d71492 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -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
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 42af5fd..698ae1a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 7b6268d..9bb1bb4 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -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)
diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi
index b4ada5b..58791c7 100644
--- a/gcc/doc/options.texi
+++ b/gcc/doc/options.texi
@@ -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.
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 11b3b62..f07af3b 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -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
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index ba9bfe8..dc771f9 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -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)
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 7e5733c..4c917aa 100644
--- 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;
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 783ba55..3d2e47c 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -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).
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index dcb94d5..1a6d5be 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -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)
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 065972b..da19917 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -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
index 0000000..f3f6542
--- /dev/null
+++ b/gcc/opts-common.c
@@ -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);
+}
diff --git a/gcc/opts.c b/gcc/opts.c
index 00b9716..01ec30d 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -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
diff --git a/gcc/opts.h b/gcc/opts.h
index bfa9ccc..3af501f 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -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 *);
diff --git a/gcc/treelang/ChangeLog b/gcc/treelang/ChangeLog
index 71b444d..b4ee6d3 100644
--- a/gcc/treelang/ChangeLog
+++ b/gcc/treelang/ChangeLog
@@ -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
diff --git a/gcc/treelang/Make-lang.in b/gcc/treelang/Make-lang.in
index 2d91fd3..a0230d4 100644
--- a/gcc/treelang/Make-lang.in
+++ b/gcc/treelang/Make-lang.in
@@ -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)