/* C/ObjC/C++ command line option handling.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Contributed by Neil Booth.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
#include "tree.h"
#include "c-common.h"
#include "c-pragma.h"
#include "flags.h"
#include "toplev.h"
#include "langhooks.h"
-#include "tree-inline.h"
#include "diagnostic.h"
#include "intl.h"
#include "cppdefault.h"
#include "opts.h"
#include "options.h"
#include "mkdeps.h"
-#include "target.h"
-#include "tm_p.h"
+#include "target.h" /* For gcc_targetcm. */
#include "c-tree.h" /* For c_cpp_error. */
#ifndef DOLLARS_IN_IDENTIFIERS
/* Number of deferred options scanned for -include. */
static size_t include_cursor;
-static void set_Wimplicit (int);
static void handle_OPT_d (const char *);
static void set_std_cxx98 (int);
static void set_std_cxx0x (int);
static void set_std_c89 (int, int);
static void set_std_c99 (int);
+static void set_std_c1x (int);
static void check_deps_environment_vars (void);
static void handle_deferred_opts (void);
static void sanitize_cpp_opts (void);
const char *arg;
} *deferred_opts;
+
+static const unsigned int
+c_family_lang_mask = (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX);
+
/* Complain that switch CODE expects an argument but none was
provided. OPT was the command-line option. Return FALSE to get
the default message in opts.c, TRUE if we provide a specialized
deferred_count++;
}
+/* -Werror= may set a warning option to enable a warning that is emitted
+ by the preprocessor. Set any corresponding flag in cpp_opts. */
+
+static void
+warning_as_error_callback (int option_index)
+{
+ switch (option_index)
+ {
+ default:
+ /* Ignore options not associated with the preprocessor. */
+ break;
+
+ case OPT_Wdeprecated:
+ cpp_opts->warn_deprecated = 1;
+ break;
+
+ case OPT_Wcomment:
+ case OPT_Wcomments:
+ cpp_opts->warn_comments = 1;
+ break;
+
+ case OPT_Wtrigraphs:
+ cpp_opts->warn_trigraphs = 1;
+ break;
+
+ case OPT_Wmultichar:
+ cpp_opts->warn_multichar = 1;
+ break;
+
+ case OPT_Wtraditional:
+ cpp_opts->warn_traditional = 1;
+ break;
+
+ case OPT_Wlong_long:
+ cpp_opts->warn_long_long = 1;
+ break;
+
+ case OPT_Wendif_labels:
+ cpp_opts->warn_endif_labels = 1;
+ break;
+
+ case OPT_Wvariadic_macros:
+ /* Set the local flag that is used later to update cpp_opts. */
+ warn_variadic_macros = 1;
+ break;
+
+ case OPT_Wbuiltin_macro_redefined:
+ cpp_opts->warn_builtin_macro_redefined = 1;
+ break;
+
+ case OPT_Wundef:
+ cpp_opts->warn_undef = 1;
+ break;
+
+ case OPT_Wunused_macros:
+ /* Set the local flag that is used later to update cpp_opts. */
+ warn_unused_macros = 1;
+ break;
+
+ case OPT_Wc___compat:
+ /* Add warnings in the same way as c_common_handle_option below. */
+ if (warn_enum_compare == -1)
+ warn_enum_compare = 1;
+ if (warn_jump_misses_init == -1)
+ warn_jump_misses_init = 1;
+ cpp_opts->warn_cxx_operator_names = 1;
+ break;
+
+ case OPT_Wnormalized_:
+ inform (input_location, "-Werror=normalized=: Set -Wnormalized=nfc");
+ cpp_opts->warn_normalize = normalized_C;
+ break;
+
+ case OPT_Winvalid_pch:
+ cpp_opts->warn_invalid_pch = 1;
+ break;
+
+ case OPT_Wcpp:
+ /* Handled by standard diagnostics using the option's associated
+ boolean variable. */
+ break;
+ }
+}
+
/* Common initialization before parsing options. */
unsigned int
c_common_init_options (unsigned int argc, const char **argv)
unsigned int i, result;
struct cpp_callbacks *cb;
+ /* Register callback for warnings enabled by -Werror=. */
+ register_warning_as_error_callback (warning_as_error_callback);
+
/* This is conditionalized only because that is the way the front
ends used to do it. Maybe this should be unconditional? */
if (c_dialect_cxx ())
flag_exceptions = c_dialect_cxx ();
warn_pointer_arith = c_dialect_cxx ();
warn_write_strings = c_dialect_cxx();
+ flag_warn_unused_result = true;
/* By default, C99-like requirements for complex multiply and divide. */
flag_complex_method = 2;
invalid, a negative number to prevent language-independent
processing in toplev.c (a hack necessary for the short-term). */
int
-c_common_handle_option (size_t scode, const char *arg, int value)
+c_common_handle_option (size_t scode, const char *arg, int value,
+ int kind)
{
const struct cl_option *option = &cl_options[scode];
enum opt_code code = (enum opt_code) scode;
/* Prevent resetting the language standard to a C dialect when the driver
has already determined that we're looking at assembler input. */
bool preprocessing_asm_p = (cpp_get_options (parse_in)->lang == CLK_ASM);
-
+
switch (code)
{
default:
- if (cl_options[code].flags & (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX))
+ if (cl_options[code].flags & c_family_lang_mask)
{
if ((option->flags & CL_TARGET)
&& ! targetcm.handle_c_option (scode, arg, value))
case OPT_MD:
case OPT_MMD:
cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER);
+ cpp_opts->deps.need_preprocessor_output = true;
deps_file = arg;
break;
case OPT_Wall:
warn_unused = value;
set_Wformat (value);
- set_Wimplicit (value);
+ handle_option (OPT_Wimplicit, value, NULL, c_family_lang_mask, kind);
warn_char_subscripts = value;
warn_missing_braces = value;
warn_parentheses = value;
headers. */
warn_unknown_pragmas = value;
- /* We save the value of warn_uninitialized, since if they put
- -Wuninitialized on the command line, we need to generate a
- warning about not using it without also specifying -O. */
- if (warn_uninitialized != 1)
- warn_uninitialized = (value ? 2 : 0);
+ warn_uninitialized = value;
if (!c_dialect_cxx ())
{
implies -Wenum-compare. */
if (warn_enum_compare == -1 && value)
warn_enum_compare = value;
+ /* Because C++ always warns about a goto which misses an
+ initialization, -Wc++-compat turns on -Wjump-misses-init. */
+ if (warn_jump_misses_init == -1 && value)
+ warn_jump_misses_init = value;
+ cpp_opts->warn_cxx_operator_names = value;
break;
case OPT_Wdeprecated:
global_dc->warning_as_error_requested = value;
break;
- case OPT_Werror_implicit_function_declaration:
+ case OPT_Werror_implicit_function_declaration:
/* For backward compatibility, this is the same as
-Werror=implicit-function-declaration. */
- enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
+ enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
break;
case OPT_Wformat:
break;
case OPT_Wimplicit:
- set_Wimplicit (value);
+ gcc_assert (value == 0 || value == 1);
+ if (warn_implicit_int == -1)
+ handle_option (OPT_Wimplicit_int, value, NULL,
+ c_family_lang_mask, kind);
+ if (warn_implicit_function_declaration == -1)
+ handle_option (OPT_Wimplicit_function_declaration, value, NULL,
+ c_family_lang_mask, kind);
break;
case OPT_Wimport:
break;
case OPT_ftemplate_depth_:
+ /* Kept for backwards compatibility. */
+ case OPT_ftemplate_depth_eq:
max_tinst_depth = value;
break;
break;
case OPT_std_c89:
+ case OPT_std_c90:
case OPT_std_iso9899_1990:
case OPT_std_iso9899_199409:
if (!preprocessing_asm_p)
break;
case OPT_std_gnu89:
+ case OPT_std_gnu90:
if (!preprocessing_asm_p)
set_std_c89 (false /* c94 */, false /* ISO */);
break;
set_std_c99 (false /* ISO */);
break;
+ case OPT_std_c1x:
+ if (!preprocessing_asm_p)
+ set_std_c1x (true /* ISO */);
+ break;
+
+ case OPT_std_gnu1x:
+ if (!preprocessing_asm_p)
+ set_std_c1x (false /* ISO */);
+ break;
+
case OPT_trigraphs:
cpp_opts->trigraphs = 1;
break;
if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
flag_exceptions = 1;
- /* -Wextra implies -Wtype-limits, -Wclobbered,
- -Wempty-body, -Wsign-compare,
- -Wmissing-field-initializers, -Wmissing-parameter-type
- -Wold-style-declaration, -Woverride-init and -Wignored-qualifiers
- but not if explicitly overridden. */
+ /* -Wextra implies the following flags
+ unless explicitly overridden. */
if (warn_type_limits == -1)
warn_type_limits = extra_warnings;
if (warn_clobbered == -1)
warn_override_init = extra_warnings;
if (warn_ignored_qualifiers == -1)
warn_ignored_qualifiers = extra_warnings;
- if (warn_logical_op == -1)
- warn_logical_op = extra_warnings;
/* -Wpointer-sign is disabled by default, but it is enabled if any
of -Wall or -pedantic are given. */
warn_strict_aliasing = 0;
if (warn_strict_overflow == -1)
warn_strict_overflow = 0;
+ if (warn_jump_misses_init == -1)
+ warn_jump_misses_init = 0;
/* -Woverlength-strings is off by default, but is enabled by -pedantic.
It is never enabled in C++, as the minimum limit is not normative
"-Wformat-security ignored without -Wformat");
}
+ if (warn_implicit == -1)
+ warn_implicit = 0;
+
+ if (warn_implicit_int == -1)
+ warn_implicit_int = 0;
+
/* -Wimplicit-function-declaration is enabled by default for C99. */
- if (warn_implicit_function_declaration == -1)
+ if (warn_implicit_function_declaration == -1)
warn_implicit_function_declaration = flag_isoc99;
/* If we're allowing C++0x constructs, don't warn about C++0x
i = 0;
for (;;)
{
- /* Start the main input file, if the debug writer wants it. */
- if (debug_hooks->start_end_main_source_file)
- (*debug_hooks->start_source_file) (0, this_input_filename);
finish_options ();
pch_init ();
push_file_scope ();
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 && ((pedantic
- && (c_dialect_cxx ()
- ? cxx_dialect == cxx98
- : !flag_isoc99))
- || warn_traditional);
+ /* Wlong-long is disabled by default. It is enabled by:
+ [-pedantic | -Wtraditional] -std=[gnu|c]++98 ; or
+ [-pedantic | -Wtraditional] -std=non-c99 .
+
+ Either -Wlong-long or -Wno-long-long override any other settings. */
+ if (warn_long_long == -1)
+ warn_long_long = ((pedantic || warn_traditional)
+ && (c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99));
+ cpp_opts->warn_long_long = warn_long_long;
/* Similarly with -Wno-variadic-macros. No check for c99 here, since
this also turns off warnings about GCCs extension. */
}
}
+ /* Start the main input file, if the debug writer wants it. */
+ if (debug_hooks->start_end_main_source_file
+ && !flag_preprocess_only)
+ (*debug_hooks->start_source_file) (0, this_input_filename);
+
/* Handle -imacros after -D and -U. */
for (i = 0; i < deferred_count; i++)
{
}
}
}
- else if (cpp_opts->directives_only)
- cpp_init_special_builtins (parse_in);
+ else
+ {
+ if (cpp_opts->directives_only)
+ cpp_init_special_builtins (parse_in);
+
+ /* Start the main input file, if the debug writer wants it. */
+ if (debug_hooks->start_end_main_source_file
+ && !flag_preprocess_only)
+ (*debug_hooks->start_source_file) (0, this_input_filename);
+ }
include_cursor = 0;
push_command_line_include ();
flag_no_nonansi_builtin = iso;
flag_isoc94 = c94;
flag_isoc99 = 0;
+ flag_isoc1x = 0;
}
/* Set the C 99 standard (without GNU extensions if ISO). */
flag_no_asm = iso;
flag_no_nonansi_builtin = iso;
flag_iso = iso;
+ flag_isoc1x = 0;
+ flag_isoc99 = 1;
+ flag_isoc94 = 1;
+}
+
+/* Set the C 1X standard draft (without GNU extensions if ISO). */
+static void
+set_std_c1x (int iso)
+{
+ cpp_set_lang (parse_in, iso ? CLK_STDC1X: CLK_GNUC1X);
+ flag_no_asm = iso;
+ flag_no_nonansi_builtin = iso;
+ flag_iso = iso;
+ flag_isoc1x = 1;
flag_isoc99 = 1;
flag_isoc94 = 1;
}
cxx_dialect = cxx0x;
}
-/* Handle setting implicit to ON. */
-static void
-set_Wimplicit (int on)
-{
- warn_implicit = on;
- warn_implicit_int = on;
- warn_implicit_function_declaration = on;
-}
-
/* Args to -d specify what to dump. Silently ignore
unrecognized options; they may be aimed at toplev.c. */
static void