aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-opts.c')
-rw-r--r--gcc/c-opts.c247
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). */