diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2ca38e4db51..9ffa3c450fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2010-11-19 Joseph Myers + + * doc/options.texi (Var): Document effects of Defer. + (Defer): Document. + * opt-functions.awk (var_type, var_set): Handle deferred options. + * opts-common.c (set_option): Handle CLVC_DEFER. + * common.opt (fcall-saved-, fcall-used-, fdump-, ffixed-, + fplugin=, fplugin-arg-, fstack-limit, fstack-limit-register=, + fstack-limit-symbol=): Mark as deferred. + * opts.c: Don't include rtl.h, ggc.h, output.h, tree-pass.h or + plugin.h. + (print_filtered_help): Don't report state of CLVC_DEFER options. + (common_handle_option): Move code for OPT_fcall_used_, + OPT_fcall_saved_, OPT_fdump_, OPT_ffixed_, OPT_fplugin_, + OPT_fplugin_arg_, OPT_fstack_limit, OPT_fstack_limit_register_ and + OPT_fstack_limit_symbol_ to opts-global.c. + (option_enabled, get_option_state): Handle CLVC_DEFER. + * opts.h: Include vec.h. + (enum cl_var_type): Add CLVC_DEFER. + (cl_deferred_option): Define type and vectors. + (handle_common_deferred_options): Declare. + * opts-global.c: New. + * toplev.c (toplev_main): Call handle_common_deferred_options + * Makefile.in (OPTS_H): Include $(VEC_H). + (OBJS-common): Include opts-global.o. + (opts.o): Update dependencies. + (opts-global.o): Add dependencies. + 2010-11-19 Nicola Pero * c-parser.c (c_parser_objc_protocol_definition): Pass attributes diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 7e560998537..2904da37bac 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -932,7 +932,7 @@ PREDICT_H = predict.h predict.def CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \ $(srcdir)/../libcpp/include/cpplib.h INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h -OPTS_H = $(INPUT_H) opts.h +OPTS_H = $(INPUT_H) $(VEC_H) opts.h DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \ $(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h \ $(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal128Local.h @@ -1295,6 +1295,7 @@ OBJS-common = \ optabs.o \ options.o \ opts-common.o \ + opts-global.o \ opts.o \ params.o \ passes.o \ @@ -2809,10 +2810,13 @@ fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ version.h $(INPUT_H) intl.h $(DIAGNOSTIC_H) diagnostic.def opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(EXPR_H) $(RTL_H) \ - output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ - $(FLAGS_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) debug.h \ - $(PLUGIN_H) $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h + coretypes.h $(TREE_H) $(TM_H) langhooks.h $(EXPR_H) \ + $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ + $(FLAGS_H) $(PARAMS_H) $(DBGCNT_H) debug.h \ + $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h +opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(DIAGNOSTIC_CORE_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TM_H) $(RTL_H) \ + output.h $(PLUGIN_H) $(TREE_PASS_H) opts-common.o : opts-common.c $(OPTS_H) $(FLAGS_H) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H) targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ diff --git a/gcc/common.opt b/gcc/common.opt index 0a6e38c4bbd..a3dd291d095 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -710,11 +710,11 @@ Common Report Var(flag_btr_bb_exclusive) Optimization Restrict target load migration not to re-use registers in any basic block fcall-saved- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fcall-saved- Mark as being preserved across functions fcall-used- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fcall-used- Mark as being corrupted by function calls ; Nonzero for -fcaller-saves: allocate values in regs that need to @@ -815,7 +815,7 @@ Common Var(flag_diagnostics_show_option) Init(1) Amend appropriate diagnostic messages with the command line option that controls them fdump- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fdump- Dump various compiler internals to a file fdump-final-insns @@ -893,7 +893,7 @@ Common Report Var(flag_finite_math_only) Optimization Assume no NaNs or infinities are generated ffixed- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -ffixed- Mark as being unavailable to the compiler ffloat-store @@ -1306,11 +1306,11 @@ Common Report Var(flag_pie,1) Generate position-independent code for executables if possible (small mode) fplugin= -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer Specify a plugin to load fplugin-arg- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fplugin-arg--[=] Specify argument = for plugin fpredictive-commoning @@ -1573,14 +1573,14 @@ Common Alias(fstack-check=, specific, no) Insert stack checking code into the program. Same as -fstack-check=specific fstack-limit -Common +Common Var(common_deferred_options) Defer fstack-limit-register= -Common RejectNegative Joined +Common RejectNegative Joined Var(common_deferred_options) Defer -fstack-limit-register= Trap if the stack goes past fstack-limit-symbol= -Common RejectNegative Joined +Common RejectNegative Joined Var(common_deferred_options) Defer -fstack-limit-symbol= Trap if the stack goes past symbol fstack-protector diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi index 3b844bb9eb6..0538393d2e7 100644 --- a/gcc/doc/options.texi +++ b/gcc/doc/options.texi @@ -200,6 +200,12 @@ option is used and 0 when the ``no-'' form is used. 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. +@item +If the option has the @code{Defer} property, @var{var} is a pointer to +a @code{VEC(cl_deferred_option,heap)} that stores the option for later +processing. (@var{var} is declared with type @code{void *} and needs +to be cast to @code{VEC(cl_deferred_option,heap)} before use.) + @item Otherwise, if the option takes an argument, @var{var} is a pointer to the argument string. The pointer will be null if the argument is optional @@ -255,6 +261,10 @@ The main purpose of this property is to support synonymous options. The first option should use @samp{Mask(@var{name})} and the others should use @samp{Mask(@var{name}) MaskExists}. +@item Defer +The option should be stored in a vector, specified with @code{Var}, +for later processing. + @item Alias(@var{opt}) @itemx Alias(@var{opt}, @var{arg}) @itemx Alias(@var{opt}, @var{posarg}, @var{negarg}) diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk index c85df5cd3de..99bbb314475 100644 --- a/gcc/opt-functions.awk +++ b/gcc/opt-functions.awk @@ -148,7 +148,9 @@ function static_var(name, flags) # Return the type of variable that should be associated with the given flags. function var_type(flags) { - if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) + if (flag_set_p("Defer", flags)) + return "void *" + else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) return "int " else if (flag_set_p("UInteger", flags)) return "int " @@ -177,6 +179,8 @@ function var_type_struct(flags) # "var_cond" and "var_value" fields of its cl_options[] entry. function var_set(flags) { + if (flag_set_p("Defer", flags)) + return "CLVC_DEFER, 0" s = nth_arg(1, opt_args("Var", flags)) if (s != "") return "CLVC_EQUAL, " s diff --git a/gcc/opts-common.c b/gcc/opts-common.c index cc20410544c..79d3f052bac 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -958,6 +958,22 @@ set_option (struct gcc_options *opts, struct gcc_options *opts_set, if (set_flag_var) *(const char **) set_flag_var = ""; break; + + case CLVC_DEFER: + { + VEC(cl_deferred_option,heap) *vec + = (VEC(cl_deferred_option,heap) *) *(void **) flag_var; + cl_deferred_option *p; + + p = VEC_safe_push (cl_deferred_option, heap, vec, NULL); + p->opt_index = opt_index; + p->arg = arg; + p->value = value; + *(void **) flag_var = vec; + if (set_flag_var) + *(void **) set_flag_var = vec; + } + break; } if ((diagnostic_t) kind != DK_UNSPECIFIED diff --git a/gcc/opts-global.c b/gcc/opts-global.c new file mode 100644 index 00000000000..e4e62dbc36f --- /dev/null +++ b/gcc/opts-global.c @@ -0,0 +1,105 @@ +/* Command line option handling. Code involving global state that + should not be shared with the driver. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + 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 3, 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 COPYING3. If not see +. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "opts.h" +#include "flags.h" +#include "ggc.h" +#include "tm.h" /* Required by rtl.h. */ +#include "rtl.h" +#include "output.h" +#include "plugin.h" +#include "tree-pass.h" + +void +handle_common_deferred_options (void) +{ + unsigned int i; + cl_deferred_option *opt; + VEC(cl_deferred_option,heap) *vec + = (VEC(cl_deferred_option,heap) *) common_deferred_options; + + FOR_EACH_VEC_ELT (cl_deferred_option, vec, i, opt) + { + switch (opt->opt_index) + { + case OPT_fcall_used_: + fix_register (opt->arg, 0, 1); + break; + + case OPT_fcall_saved_: + fix_register (opt->arg, 0, 0); + break; + + case OPT_fdump_: + if (!dump_switch_p (opt->arg)) + error ("unrecognized command line option %<-fdump-%s%>", opt->arg); + break; + + case OPT_ffixed_: + /* Deferred. */ + fix_register (opt->arg, 1, 1); + break; + + case OPT_fplugin_: +#ifdef ENABLE_PLUGIN + add_new_plugin (opt->arg); +#else + error ("plugin support is disabled; configure with --enable-plugin"); +#endif + break; + + case OPT_fplugin_arg_: +#ifdef ENABLE_PLUGIN + parse_plugin_arg_opt (opt->arg); +#else + error ("plugin support is disabled; configure with --enable-plugin"); +#endif + break; + + case OPT_fstack_limit: + /* The real switch is -fno-stack-limit. */ + gcc_assert (!opt->value); + stack_limit_rtx = NULL_RTX; + break; + + case OPT_fstack_limit_register_: + { + int reg = decode_reg_name (opt->arg); + if (reg < 0) + error ("unrecognized register name %qs", opt->arg); + else + stack_limit_rtx = gen_rtx_REG (Pmode, reg); + } + break; + + case OPT_fstack_limit_symbol_: + stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg)); + break; + + default: + gcc_unreachable (); + } + } +} diff --git a/gcc/opts.c b/gcc/opts.c index 6c2fca3dc29..ad3d6fcc1c6 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -25,10 +25,7 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" #include "expr.h" -#include "ggc.h" -#include "output.h" #include "langhooks.h" #include "opts.h" #include "options.h" @@ -39,10 +36,8 @@ along with GCC; see the file COPYING3. If not see #include "opts-diagnostic.h" #include "insn-attr.h" /* For INSN_SCHEDULING. */ #include "target.h" -#include "tree-pass.h" #include "dbgcnt.h" #include "debug.h" -#include "plugin.h" #include "except.h" #include "lto-streamer.h" @@ -1443,7 +1438,8 @@ print_filtered_help (unsigned int include_flags, else strcpy (new_help, "\t"); - if (flag_var != NULL) + if (flag_var != NULL + && option->var_type != CLVC_DEFER) { if (option->flags & CL_JOINED) { @@ -1842,11 +1838,8 @@ common_handle_option (struct gcc_options *opts, break; case OPT_fcall_used_: - fix_register (arg, 0, 1); - break; - case OPT_fcall_saved_: - fix_register (arg, 0, 0); + /* Deferred. */ break; case OPT_fcompare_debug_second: @@ -1880,8 +1873,7 @@ common_handle_option (struct gcc_options *opts, break; case OPT_fdump_: - if (!dump_switch_p (arg)) - return false; + /* Deferred. */ break; case OPT_ffp_contract_: @@ -1914,7 +1906,7 @@ common_handle_option (struct gcc_options *opts, break; case OPT_ffixed_: - fix_register (arg, 1, 1); + /* Deferred. */ break; case OPT_finline_limit_: @@ -1949,19 +1941,8 @@ common_handle_option (struct gcc_options *opts, break; case OPT_fplugin_: -#ifdef ENABLE_PLUGIN - add_new_plugin (arg); -#else - error ("plugin support is disabled; configure with --enable-plugin"); -#endif - break; - case OPT_fplugin_arg_: -#ifdef ENABLE_PLUGIN - parse_plugin_arg_opt (arg); -#else - error ("plugin support is disabled; configure with --enable-plugin"); -#endif + /* Deferred. */ break; case OPT_fprofile_dir_: @@ -2087,21 +2068,12 @@ common_handle_option (struct gcc_options *opts, /* The real switch is -fno-stack-limit. */ if (value) return false; - stack_limit_rtx = NULL_RTX; + /* Deferred. */ break; case OPT_fstack_limit_register_: - { - int reg = decode_reg_name (arg); - if (reg < 0) - error ("unrecognized register name \"%s\"", arg); - else - stack_limit_rtx = gen_rtx_REG (Pmode, reg); - } - break; - case OPT_fstack_limit_symbol_: - stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg)); + /* Deferred. */ break; case OPT_ftree_vectorizer_verbose_: @@ -2383,6 +2355,7 @@ option_enabled (int opt_idx, void *opts) return (*(int *) flag_var & option->var_value) != 0; case CLVC_STRING: + case CLVC_DEFER: break; } return -1; @@ -2421,6 +2394,9 @@ get_option_state (struct gcc_options *opts, int option, state->data = ""; state->size = strlen ((const char *) state->data) + 1; break; + + case CLVC_DEFER: + return false; } return true; } diff --git a/gcc/opts.h b/gcc/opts.h index 00422b6ea38..9bbbced721a 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_OPTS_H #include "input.h" +#include "vec.h" /* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR. */ enum cl_var_type { @@ -39,7 +40,11 @@ enum cl_var_type { /* The switch takes a string argument and FLAG_VAR points to that argument. */ - CLVC_STRING + CLVC_STRING, + + /* The switch should be stored in the VEC pointed to by FLAG_VAR for + later processing. */ + CLVC_DEFER }; struct cl_option @@ -158,6 +163,20 @@ struct cl_decoded_option int errors; }; +/* Structure describing an option deferred for handling after the main + option handlers. */ + +typedef struct +{ + /* Elements from struct cl_decoded_option used for deferred + options. */ + size_t opt_index; + const char *arg; + int value; +} cl_deferred_option; +DEF_VEC_O(cl_deferred_option); +DEF_VEC_ALLOC_O(cl_deferred_option,heap); + /* Structure describing a single option-handling callback. */ struct cl_option_handler_func @@ -264,4 +283,5 @@ extern void control_warning_option (unsigned int opt_index, int kind, struct gcc_options *opts_set, diagnostic_context *dc); extern void print_ignored_options (void); +extern void handle_common_deferred_options (void); #endif diff --git a/gcc/toplev.c b/gcc/toplev.c index 7c91b06bb7c..c77db524789 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2359,6 +2359,8 @@ toplev_main (int argc, char **argv) save_decoded_options, save_decoded_options_count, UNKNOWN_LOCATION, global_dc); + handle_common_deferred_options (); + init_local_tick (); initialize_plugins ();