OSDN Git Service

* c-opts.c (c_common_parse_file): If start_end_main_source_file,
[pf3gnuchains/gcc-fork.git] / gcc / c-opts.c
index a7ff6cc..d57cf91 100644 (file)
@@ -1,5 +1,5 @@
 /* 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.
 
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "mkdeps.h"
 #include "target.h"
 #include "tm_p.h"
+#include "c-tree.h"            /* For c_cpp_error.  */
 
 #ifndef DOLLARS_IN_IDENTIFIERS
 # define DOLLARS_IN_IDENTIFIERS true
@@ -105,12 +106,12 @@ static size_t deferred_count;
 /* 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);
@@ -133,6 +134,10 @@ static struct deferred_opt
   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
@@ -195,12 +200,100 @@ defer_opt (enum opt_code code, const char *arg)
   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)
 {
   static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
   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?  */
@@ -216,6 +309,8 @@ c_common_init_options (unsigned int argc, const char **argv)
 
   parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
                                ident_hash, line_table);
+  cb = cpp_get_callbacks (parse_in);
+  cb->error = c_cpp_error;
 
   cpp_opts = cpp_get_options (parse_in);
   cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
@@ -228,6 +323,7 @@ c_common_init_options (unsigned int argc, const char **argv)
   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;
@@ -256,7 +352,8 @@ c_common_init_options (unsigned int argc, const char **argv)
    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;
@@ -265,11 +362,11 @@ c_common_handle_option (size_t scode, const char *arg, int value)
   /* 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))
@@ -333,12 +430,12 @@ c_common_handle_option (size_t scode, const char *arg, int value)
         or environment var dependency generation is used.  */
       cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);
       flag_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);
+      cpp_opts->deps.need_preprocessor_output = true;
       deps_file = arg;
       break;
 
@@ -378,7 +475,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
     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;
@@ -397,11 +494,7 @@ c_common_handle_option (size_t scode, const char *arg, int 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 ())
        {
@@ -409,6 +502,12 @@ c_common_handle_option (size_t scode, const char *arg, int value)
             can turn it off only if it's not explicit.  */
          if (warn_main == -1)
            warn_main = (value ? 2 : 0);
+
+         /* In C, -Wall turns on -Wenum-compare, which we do here.
+            In C++ it is on by default, which is done in
+            c_common_post_options.  */
+          if (warn_enum_compare == -1)
+            warn_enum_compare = value;
        }
       else
        {
@@ -435,6 +534,18 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->warn_comments = value;
       break;
 
+    case OPT_Wc___compat:
+      /* Because -Wenum-compare is the default in C++, -Wc++-compat
+        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:
       cpp_opts->warn_deprecated = value;
       break;
@@ -444,14 +555,13 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_Werror:
-      cpp_opts->warnings_are_errors = value;
       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:
@@ -463,7 +573,13 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       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:
@@ -503,10 +619,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       warn_strict_null_sentinel = value;
       break;
 
-    case OPT_Wsystem_headers:
-      cpp_opts->warn_system_headers = value;
-      break;
-
     case OPT_Wtraditional:
       cpp_opts->warn_traditional = value;
       break;
@@ -787,6 +899,8 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_ftemplate_depth_:
+      /* Kept for backwards compatibility.  */
+    case OPT_ftemplate_depth_eq:
       max_tinst_depth = value;
       break;
 
@@ -810,6 +924,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_threadsafe_statics = value;
       break;
 
+    case OPT_fpretty_templates:
+      flag_pretty_templates = value;
+      break;
+
     case OPT_fzero_link:
       flag_zero_link = value;
       break;
@@ -895,8 +1013,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
         c_common_post_options, so that a subsequent -Wno-endif-labels
         is not overridden.  */
     case OPT_pedantic_errors:
-      cpp_opts->pedantic_errors = 1;
-      /* Fall through.  */
     case OPT_pedantic:
       cpp_opts->pedantic = 1;
       cpp_opts->warn_endif_labels = 1;
@@ -934,6 +1050,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_std_c89:
+    case OPT_std_c90:
     case OPT_std_iso9899_1990:
     case OPT_std_iso9899_199409:
       if (!preprocessing_asm_p)
@@ -941,6 +1058,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_std_gnu89:
+    case OPT_std_gnu90:
       if (!preprocessing_asm_p)
        set_std_c89 (false /* c94 */, false /* ISO */);
       break;
@@ -959,6 +1077,16 @@ c_common_handle_option (size_t scode, const char *arg, int value)
        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;
@@ -971,13 +1099,13 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_undef = 1;
       break;
 
-    case OPT_w:
-      cpp_opts->inhibit_warnings = 1;
-      break;
-
     case OPT_v:
       verbose = true;
       break;
+
+    case OPT_Wabi:
+      warn_psabi = value;
+      break;
     }
 
   return result;
@@ -1017,6 +1145,20 @@ c_common_post_options (const char **pfilename)
   C_COMMON_OVERRIDE_OPTIONS;
 #endif
 
+  /* Excess precision other than "fast" requires front-end
+     support.  */
+  if (c_dialect_cxx ())
+    {
+      if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD
+         && TARGET_FLT_EVAL_METHOD_NON_DEFAULT)
+       sorry ("-fexcess-precision=standard for C++");
+      flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
+    }
+  else if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT)
+    flag_excess_precision_cmdline = (flag_iso
+                                    ? EXCESS_PRECISION_STANDARD
+                                    : EXCESS_PRECISION_FAST);
+
   /* By default we use C99 inline semantics in GNU99 or C99 mode.  C99
      inline semantics are not supported in GNU89 or C89 mode.  */
   if (flag_gnu89_inline == -1)
@@ -1030,11 +1172,8 @@ c_common_post_options (const char **pfilename)
   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)
@@ -1063,6 +1202,8 @@ c_common_post_options (const char **pfilename)
     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
@@ -1085,6 +1226,12 @@ c_common_post_options (const char **pfilename)
   if (warn_sign_conversion == -1)
     warn_sign_conversion =  (c_dialect_cxx ()) ? 0 : warn_conversion;
 
+  /* In C, -Wall and -Wc++-compat enable -Wenum-compare, which we do
+     in c_common_handle_option; if it has not yet been set, it is
+     disabled by default.  In C++, it is enabled by default.  */
+  if (warn_enum_compare == -1)
+    warn_enum_compare = c_dialect_cxx () ? 1 : 0;
+
   /* -Wpacked-bitfield-compat is on by default for the C languages.  The
      warning is issued in stor-layout.c which is not part of the front-end so
      we need to selectively turn it on here.  */
@@ -1109,8 +1256,14 @@ c_common_post_options (const char **pfilename)
               "-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
@@ -1155,10 +1308,6 @@ c_common_post_options (const char **pfilename)
 
   input_location = UNKNOWN_LOCATION;
 
-  /* If an error has occurred in cpplib, note it so we fail
-     immediately.  */
-  errorcount += cpp_errors (parse_in);
-
   *pfilename = this_input_filename
     = cpp_read_main_file (parse_in, in_fnames[0]);
   /* Don't do any compilation or preprocessing if there is no input file.  */
@@ -1239,9 +1388,6 @@ c_common_parse_file (int set_yydebug)
   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 ();
@@ -1270,7 +1416,8 @@ c_common_finish (void)
 {
   FILE *deps_stream = NULL;
 
-  if (cpp_opts->deps.style != DEPS_NONE)
+  /* Don't write the deps file if there are errors.  */
+  if (cpp_opts->deps.style != DEPS_NONE && errorcount == 0)
     {
       /* If -M or -MM was seen without -MF, default output to the
         output stream.  */
@@ -1286,7 +1433,7 @@ c_common_finish (void)
 
   /* For performance, avoid tearing down cpplib's internal structures
      with cpp_destroy ().  */
-  errorcount += cpp_finish (parse_in, deps_stream);
+  cpp_finish (parse_in, deps_stream);
 
   if (deps_stream && deps_stream != out_stream
       && (ferror (deps_stream) || fclose (deps_stream)))
@@ -1401,14 +1548,15 @@ sanitize_cpp_opts (void)
   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.  */
@@ -1498,6 +1646,11 @@ finish_options (void)
            }
        }
 
+      /* 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++)
        {
@@ -1512,8 +1665,16 @@ finish_options (void)
            }
        }
     }
-  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 ();
@@ -1580,6 +1741,7 @@ set_std_c89 (int c94, int iso)
   flag_no_nonansi_builtin = iso;
   flag_isoc94 = c94;
   flag_isoc99 = 0;
+  flag_isoc1x = 0;
 }
 
 /* Set the C 99 standard (without GNU extensions if ISO).  */
@@ -1590,6 +1752,20 @@ set_std_c99 (int 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;
 }
@@ -1616,15 +1792,6 @@ set_std_cxx0x (int iso)
   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