diff options
Diffstat (limited to 'gcc/c-opts.c')
-rw-r--r-- | gcc/c-opts.c | 247 |
1 files changed, 196 insertions, 51 deletions
diff --git a/gcc/c-opts.c b/gcc/c-opts.c index 4f6bb5d..189cb1b 100644 --- a/gcc/c-opts.c +++ b/gcc/c-opts.c @@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "diagnostic.h" #include "intl.h" +/* CPP's options. */ static cpp_options *cpp_opts; /* Input filename. */ @@ -43,6 +44,15 @@ static FILE *out_stream; /* Append dependencies to deps_file. */ static bool deps_append; +/* If dependency switches (-MF etc.) have been given. */ +static bool deps_seen; + +/* Dependency output file. */ +static const char *deps_file; + +/* Number of deferred options, deferred options array size. */ +static size_t deferred_count, deferred_size; + static void missing_arg PARAMS ((size_t)); static size_t find_opt PARAMS ((const char *, int)); static void set_Wimplicit PARAMS ((int)); @@ -55,6 +65,8 @@ static void set_std_c89 PARAMS ((int, int)); static void set_std_c99 PARAMS ((int)); static void check_deps_environment_vars PARAMS ((void)); static void preprocess_file PARAMS ((void)); +static void handle_deferred_opts PARAMS ((void)); +static void sanitize_cpp_opts PARAMS ((void)); #ifndef STDC_0_IN_SYSTEM_HEADERS #define STDC_0_IN_SYSTEM_HEADERS 0 @@ -102,6 +114,15 @@ static void preprocess_file PARAMS ((void)); OPT("CC", CL_ALL, OPT_CC) \ OPT("E", CL_ALL, OPT_E) \ OPT("H", CL_ALL, OPT_H) \ + OPT("M", CL_ALL, OPT_M) \ + OPT("MD", CL_ALL | CL_SEPARATE, OPT_MD) \ + OPT("MF", CL_ALL | CL_ARG, OPT_MF) \ + OPT("MG", CL_ALL, OPT_MG) \ + OPT("MM", CL_ALL, OPT_MM) \ + OPT("MMD", CL_ALL | CL_SEPARATE, OPT_MMD) \ + OPT("MP", CL_ALL, OPT_MP) \ + OPT("MQ", CL_ALL | CL_ARG, OPT_MQ) \ + OPT("MT", CL_ALL | CL_ARG, OPT_MT) \ OPT("P", CL_ALL, OPT_P) \ OPT("Wall", CL_ALL, OPT_Wall) \ OPT("Wbad-function-cast", CL_C, OPT_Wbad_function_cast) \ @@ -284,6 +305,16 @@ static const struct cl_option cl_options[] = #undef OPT #undef COMMAND_LINE_OPTIONS +/* Holds switches parsed by c_common_decode_option (), but whose + handling is deffered to c_common_post_options (). */ +static void defer_opt PARAMS ((enum opt_code, const char *)); +static struct deferred_opt +{ + enum opt_code code; + const char *arg; +} *deferred_opts; + + #ifdef HOST_EBCDIC static int opt_comp PARAMS ((const void *, const void *)); @@ -303,6 +334,8 @@ static void missing_arg (opt_index) size_t opt_index; { + const char *opt_text = cl_options[opt_index].opt_text; + switch (opt_index) { case OPT_Wformat_eq: @@ -313,15 +346,23 @@ missing_arg (opt_index) case OPT_ftabstop: case OPT_ftemplate_depth: default: - error ("missing argument to \"-%s\"", cl_options[opt_index].opt_text); + error ("missing argument to \"-%s\"", opt_text); break; case OPT_fconstant_string_class: - error ("no class name specified with -fconstant-string-class="); + error ("no class name specified with \"-%s\"", opt_text); break; + case OPT_MF: + case OPT_MD: + case OPT_MMD: case OPT_o: - error ("missing filename after \"-%s\"", cl_options[opt_index].opt_text); + error ("missing filename after \"-%s\"", opt_text); + break; + + case OPT_MQ: + case OPT_MT: + error ("missing target after \"-%s\"", opt_text); break; } } @@ -420,6 +461,30 @@ find_opt (input, lang_flag) return N_OPTS; } +/* Defer option CODE with argument ARG. */ +static void +defer_opt (code, arg) + enum opt_code code; + const char *arg; +{ + /* FIXME: this should be in c_common_init_options, which should take + argc and argv. */ + if (!deferred_opts) + { + extern int save_argc; + deferred_size = save_argc; + deferred_opts = (struct deferred_opt *) + xmalloc (deferred_size * sizeof (struct deferred_opt)); + } + + if (deferred_count == deferred_size) + abort (); + + deferred_opts[deferred_count].code = code; + deferred_opts[deferred_count].arg = arg; + deferred_count++; +} + /* Common initialization before parsing options. */ void c_common_init_options (lang) @@ -432,10 +497,8 @@ c_common_init_options (lang) #endif c_language = lang; - parse_in = cpp_create_reader (lang == clk_c - ? CLK_GNUC89 : CLK_GNUCXX); + parse_in = cpp_create_reader (lang == clk_c ? CLK_GNUC89 : CLK_GNUCXX); cpp_opts = cpp_get_options (parse_in); - if (flag_objc) cpp_opts->objc = 1; @@ -563,6 +626,44 @@ c_common_decode_option (argc, argv) cpp_opts->print_include_names = 1; break; + case OPT_M: + case OPT_MM: + /* When doing dependencies with -M or -MM, suppress normal + preprocessed output, but still do -dM etc. as software + depends on this. Preprocessed output does occur if -MD, -MMD + or environment var dependency generation is used. */ + cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER); + cpp_opts->no_output = 1; + cpp_opts->inhibit_warnings = 1; + break; + + case OPT_MD: + case OPT_MMD: + cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER); + deps_file = arg; + break; + + case OPT_MF: + deps_seen = true; + deps_file = arg; + break; + + case OPT_MG: + deps_seen = true; + cpp_opts->deps.missing_files = true; + break; + + case OPT_MP: + deps_seen = true; + cpp_opts->deps.phony_targets = true; + break; + + case OPT_MQ: + case OPT_MT: + deps_seen = true; + defer_opt (code, arg); + break; + case OPT_P: cpp_opts->no_line_commands = 1; break; @@ -1219,26 +1320,12 @@ c_common_post_options () if (out_fname == NULL || !strcmp (out_fname, "-")) out_fname = ""; - if (cpp_opts->print_deps == 0) + if (cpp_opts->deps.style != DEPS_NONE) check_deps_environment_vars (); - /* If we're not outputting dependencies, complain if other -M - options have been given. */ - if (!cpp_opts->print_deps - && (cpp_opts->print_deps_missing_files - || cpp_opts->deps_file - || cpp_opts->deps_phony_targets)) - error ("you must additionally specify either -M or -MM"); + handle_deferred_opts (); - cpp_post_options (parse_in); - - cpp_opts->unsigned_char = !flag_signed_char; - cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS; - - /* We want -Wno-long-long to override -pedantic -std=non-c99 - and/or -Wtraditional, whatever the ordering. */ - cpp_opts->warn_long_long - = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional); + sanitize_cpp_opts (); flag_inline_trees = 1; @@ -1339,17 +1426,17 @@ c_common_finish () { FILE *deps_stream = NULL; - if (cpp_opts->print_deps) + if (cpp_opts->deps.style != DEPS_NONE) { /* If -M or -MM was seen without -MF, default output to the output stream. */ - if (!cpp_opts->deps_file) + if (!deps_file) deps_stream = out_stream; else { - deps_stream = fopen (cpp_opts->deps_file, deps_append ? "a": "w"); + deps_stream = fopen (deps_file, deps_append ? "a": "w"); if (!deps_stream) - fatal_io_error ("opening dependency file %s", cpp_opts->deps_file); + fatal_io_error ("opening dependency file %s", deps_file); } } @@ -1359,29 +1446,12 @@ c_common_finish () if (deps_stream && deps_stream != out_stream && (ferror (deps_stream) || fclose (deps_stream))) - fatal_io_error ("closing dependency file %s", cpp_opts->deps_file); + fatal_io_error ("closing dependency file %s", deps_file); if (out_stream && (ferror (out_stream) || fclose (out_stream))) fatal_io_error ("when writing output to %s", out_fname); } -/* Set the C 89 standard (with 1994 amendments if C94, without GNU - extensions if ISO). There is no concept of gnu94. */ -static void -set_std_c89 (c94, iso) - int c94, iso; -{ - cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89); - flag_iso = iso; - flag_no_asm = iso; - flag_no_gnu_keywords = iso; - flag_no_nonansi_builtin = iso; - flag_noniso_default_format_attributes = !iso; - flag_isoc94 = c94; - flag_isoc99 = 0; - flag_writable_strings = 0; -} - /* Either of two environment variables can specify output of dependencies. Their value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", where OUTPUT_FILE is the file to write deps info to @@ -1395,12 +1465,12 @@ check_deps_environment_vars () GET_ENVIRONMENT (spec, "DEPENDENCIES_OUTPUT"); if (spec) - cpp_opts->print_deps = 1; + cpp_opts->deps.style = DEPS_USER; else { GET_ENVIRONMENT (spec, "SUNPRO_DEPENDENCIES"); if (spec) - cpp_opts->print_deps = 2; + cpp_opts->deps.style = DEPS_SYSTEM; } if (spec) @@ -1410,16 +1480,91 @@ check_deps_environment_vars () if (s) { /* Let the caller perform MAKE quoting. */ - cpp_add_dependency_target (parse_in, s + 1, 0); + defer_opt (OPT_MT, s + 1); *s = '\0'; } /* Command line -MF overrides environment variables and default. */ - if (!cpp_opts->deps_file) - cpp_opts->deps_file = spec; + if (!deps_file) + deps_file = spec; + + deps_append = 1; + } +} + +/* Handle deferred command line switches. */ +static void +handle_deferred_opts () +{ + size_t i; - cpp_opts->print_deps_append = 1; + for (i = 0; i < deferred_count; i++) + { + struct deferred_opt *opt = &deferred_opts[i]; + + switch (opt->code) + { + case OPT_MT: + case OPT_MQ: + cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ); + break; + + default: + abort (); + } + } + + free (deferred_opts); +} + +/* These settings are appropriate for GCC, but not necessarily so for + cpplib as a library. */ +static void +sanitize_cpp_opts () +{ + /* If we don't know what style of dependencies to output, complain + if any other dependency switches have been given. */ + if (deps_seen && cpp_opts->deps.style == DEPS_NONE) + error ("to generate dependencies you must specify either -M or -MM"); + + /* -dM and dependencies suppress normal output; do it here so that + the last -d[MDN] switch overrides earlier ones. */ + if (cpp_opts->dump_macros == dump_only) + cpp_opts->no_output = 1; + + /* Disable -dD, -dN and -dI if normal output is suppressed. Allow + -dM since at least glibc relies on -M -dM to work. */ + if (cpp_opts->no_output) + { + if (cpp_opts->dump_macros != dump_only) + cpp_opts->dump_macros = dump_none; + cpp_opts->dump_includes = 0; } + + cpp_opts->unsigned_char = !flag_signed_char; + cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS; + + /* We want -Wno-long-long to override -pedantic -std=non-c99 + and/or -Wtraditional, whatever the ordering. */ + cpp_opts->warn_long_long + = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional); +} + +/* Set the C 89 standard (with 1994 amendments if C94, without GNU + extensions if ISO). There is no concept of gnu94. */ +static void +set_std_c89 (c94, iso) + int c94, iso; +{ + cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89); + flag_iso = iso; + flag_no_asm = iso; + flag_no_gnu_keywords = iso; + flag_no_nonansi_builtin = iso; + flag_noniso_default_format_attributes = !iso; + flag_isoc94 = c94; + flag_isoc99 = 0; + flag_writable_strings = 0; } /* Set the C 99 standard (without GNU extensions if ISO). */ |