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 67adab8..d57cf91 100644 (file)
@@ -1,12 +1,13 @@
 /* C/ObjC/C++ command line option handling.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
 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 2, or (at your option) any later
+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
@@ -15,9 +16,8 @@ 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 COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -33,11 +33,14 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "diagnostic.h"
 #include "intl.h"
 #include "cppdefault.h"
-#include "c-incpath.h"
+#include "incpath.h"
 #include "debug.h"             /* For debug_hooks.  */
 #include "opts.h"
 #include "options.h"
 #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
@@ -52,7 +55,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #endif
 
 /* CPP's options.  */
-static cpp_options *cpp_opts;
+cpp_options *cpp_opts;
 
 /* Input filename.  */
 static const char *this_input_filename;
@@ -70,9 +73,6 @@ static bool deps_seen;
 /* If -v seen.  */
 static bool verbose;
 
-/* If -lang-fortran seen.  */
-static bool lang_fortran = false;
-
 /* Dependency output file.  */
 static const char *deps_file;
 
@@ -106,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);
@@ -134,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
@@ -196,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,7 +308,9 @@ 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);
+                               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;
@@ -229,6 +323,10 @@ 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;
 
   deferred_opts = XNEWVEC (struct deferred_opt, argc);
 
@@ -244,15 +342,6 @@ c_common_init_options (unsigned int argc, const char **argv)
            result |= CL_C | CL_ObjC | CL_CXX | CL_ObjCXX;
            break;
          }
-
-#ifdef CL_Fortran
-      for (i = 1; i < argc; i++)
-       if (! strcmp (argv[i], "-lang-fortran"))
-       {
-           result |= CL_Fortran;
-           break;
-       }
-#endif
     }
 
   return result;
@@ -263,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;
@@ -272,16 +362,17 @@ 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))
-       break;
-#ifdef CL_Fortran
-      if (lang_fortran && (cl_options[code].flags & (CL_Fortran)))
-       break;
-#endif
+      if (cl_options[code].flags & c_family_lang_mask)
+       {
+         if ((option->flags & CL_TARGET)
+             && ! targetcm.handle_c_option (scode, arg, value))
+           result = 0;
+         break;
+       }
       result = 0;
       break;
 
@@ -327,7 +418,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
            error ("-I- specified twice");
          quote_chain_split = true;
          split_quote_chain ();
-         inform ("obsolete option -I- used, please use -iquote instead");
+         inform (input_location, "obsolete option -I- used, please use -iquote instead");
        }
       break;
 
@@ -339,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;
 
@@ -382,51 +473,60 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_Wall:
-      set_Wunused (value);
+      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;
       warn_return_type = value;
       warn_sequence_point = value;     /* Was C only.  */
-      if (c_dialect_cxx ())
-       warn_sign_compare = value;
       warn_switch = value;
-      warn_strict_aliasing = value;
-      warn_string_literal_comparison = value;
-      warn_always_true = value;
+      if (warn_strict_aliasing == -1)
+       set_Wstrict_aliasing (value);
+      warn_address = value;
+      if (warn_strict_overflow == -1)
+       warn_strict_overflow = value;
+      warn_array_bounds = value;
+      warn_volatile_register_var = value;
 
       /* Only warn about unknown pragmas that are not in system
         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 ())
-       /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding
-          can turn it off only if it's not explicit.  */
-       warn_main = value * 2;
+       {
+         /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding
+            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
        {
          /* C++-specific warnings.  */
+          warn_sign_compare = value;
          warn_reorder = value;
-         warn_nontemplate_friend = value;
-          if (value > 0)
-            warn_write_strings = true;
+          warn_cxx0x_compat = value;
        }
 
       cpp_opts->warn_trigraphs = value;
       cpp_opts->warn_comments = value;
       cpp_opts->warn_num_sign_change = value;
-      cpp_opts->warn_multichar = value;        /* Was C++ only.  */
 
       if (warn_pointer_sign == -1)
-       warn_pointer_sign = 1;
+       warn_pointer_sign = value;
+      break;
+
+    case OPT_Wbuiltin_macro_redefined:
+      cpp_opts->warn_builtin_macro_redefined = value;
       break;
 
     case OPT_Wcomment:
@@ -434,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;
@@ -443,12 +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:
-      mesg_implicit_function_declaration = 2;
+      /* For backward compatibility, this is the same as
+        -Werror=implicit-function-declaration.  */
+      enable_warning_as_error ("implicit-function-declaration", value, CL_C | CL_ObjC);
       break;
 
     case OPT_Wformat:
@@ -460,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:
@@ -471,13 +590,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->warn_invalid_pch = value;
       break;
 
-    case OPT_Wmain:
-      if (value)
-       warn_main = 1;
-      else
-       warn_main = -1;
-      break;
-
     case OPT_Wmissing_include_dirs:
       cpp_opts->warn_missing_include_dirs = value;
       break;
@@ -507,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;
@@ -605,6 +713,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
        disable_builtin_function (arg);
       break;
 
+    case OPT_fdirectives_only:
+      cpp_opts->directives_only = value;
+      break;
+
     case OPT_fdollars_in_identifiers:
       cpp_opts->dollars_in_ident = value;
       break;
@@ -615,9 +727,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
     case OPT_fhosted:
       flag_hosted = value;
       flag_no_builtin = !value;
-      /* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */
-      if (!value && warn_main == 2)
-       warn_main = 0;
       break;
 
     case OPT_fshort_double:
@@ -790,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;
 
@@ -813,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;
@@ -821,6 +936,18 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_gen_declaration = 1;
       break;
 
+    case OPT_femit_struct_debug_baseonly:
+      set_struct_debug_option ("base");
+      break;
+
+    case OPT_femit_struct_debug_reduced:
+      set_struct_debug_option ("dir:ord:sys,dir:gen:any,ind:base");
+      break;
+
+    case OPT_femit_struct_debug_detailed_:
+      set_struct_debug_option (arg);
+      break;
+
     case OPT_idirafter:
       add_path (xstrdup (arg), AFTER, 0, true);
       break;
@@ -863,10 +990,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->dollars_in_ident = false;
       break;
 
-    case OPT_lang_fortran:
-      lang_fortran = true;
-      break;
-
     case OPT_lang_objc:
       cpp_opts->objc = 1;
       break;
@@ -890,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;
@@ -899,6 +1020,8 @@ c_common_handle_option (size_t scode, const char *arg, int value)
        warn_pointer_sign = 1;
       if (warn_overlength_strings == -1)
        warn_overlength_strings = 1;
+      if (warn_main == -1)
+       warn_main = 2;
       break;
 
     case OPT_print_objc_runtime_info:
@@ -927,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)
@@ -934,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;
@@ -952,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;
@@ -964,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;
@@ -1010,18 +1145,26 @@ c_common_post_options (const char **pfilename)
   C_COMMON_OVERRIDE_OPTIONS;
 #endif
 
-  flag_inline_trees = 1;
-
-  /* Use tree inlining.  */
-  if (!flag_no_inline)
-    flag_no_inline = 1;
-  if (flag_inline_functions)
-    flag_inline_trees = 2;
-
-  /* If we are given more than one input file, we must use
-     unit-at-a-time mode.  */
-  if (num_in_fnames > 1)
-    flag_unit_at_a_time = 1;
+  /* 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)
+    flag_gnu89_inline = !flag_isoc99;
+  else if (!flag_gnu89_inline && !flag_isoc99)
+    error ("-fno-gnu89-inline is only supported in GNU99 or C99 mode");
 
   /* Default to ObjC sjlj exception handling if NeXT runtime.  */
   if (flag_objc_sjlj_exceptions < 0)
@@ -1029,10 +1172,10 @@ c_common_post_options (const char **pfilename)
   if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
     flag_exceptions = 1;
 
-  /* -Wextra implies -Wclobbered, -Wempty-body, -Wsign-compare, 
-     -Wmissing-field-initializers, -Wmissing-parameter-type
-     -Wold-style-declaration, and -Woverride-init, 
-     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_clobbered = extra_warnings;
   if (warn_empty_body == -1)
@@ -1047,18 +1190,54 @@ c_common_post_options (const char **pfilename)
     warn_old_style_declaration = extra_warnings;
   if (warn_override_init == -1)
     warn_override_init = extra_warnings;
+  if (warn_ignored_qualifiers == -1)
+    warn_ignored_qualifiers = extra_warnings;
 
-  /* -Wpointer_sign is disabled by default, but it is enabled if any
+  /* -Wpointer-sign is disabled by default, but it is enabled if any
      of -Wall or -pedantic are given.  */
   if (warn_pointer_sign == -1)
     warn_pointer_sign = 0;
 
+  if (warn_strict_aliasing == -1)
+    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
      in that standard.  */
   if (warn_overlength_strings == -1 || c_dialect_cxx ())
     warn_overlength_strings = 0;
 
+  /* Wmain is enabled by default in C++ but not in C.  */
+  /* Wmain is disabled by default for -ffreestanding (!flag_hosted),
+     even if -Wall was given (warn_main will be 2 if set by -Wall, 1
+     if set by -Wmain).  */
+  if (warn_main == -1)
+    warn_main = (c_dialect_cxx () && flag_hosted) ? 1 : 0;
+  else if (warn_main == 2)
+    warn_main = flag_hosted ? 1 : 0;
+
+  /* In C, -Wconversion enables -Wsign-conversion (unless disabled
+     through -Wno-sign-conversion). While in C++,
+     -Wsign-conversion needs to be requested explicitly.  */
+  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.  */
+  if (warn_packed_bitfield_compat == -1)
+    warn_packed_bitfield_compat = 1;
+
   /* Special format checking options don't work without -Wformat; warn if
      they are used.  */
   if (!warn_format)
@@ -1071,14 +1250,26 @@ c_common_post_options (const char **pfilename)
               "-Wformat-zero-length ignored without -Wformat");
       warning (OPT_Wformat_nonliteral,
               "-Wformat-nonliteral ignored without -Wformat");
+      warning (OPT_Wformat_contains_nul,
+              "-Wformat-contains-nul ignored without -Wformat");
       warning (OPT_Wformat_security,
               "-Wformat-security ignored without -Wformat");
     }
 
-  /* C99 requires special handling of complex multiplication and division;
-     -ffast-math and -fcx-limited-range are handled in process_options.  */
-  if (flag_isoc99)
-    flag_complex_method = 2;
+  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)
+    warn_implicit_function_declaration = flag_isoc99;
+
+  /* If we're allowing C++0x constructs, don't warn about C++0x
+     compatibility problems.  */
+  if (cxx_dialect == cxx0x)
+    warn_cxx0x_compat = 0;
 
   if (flag_preprocess_only)
     {
@@ -1117,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.  */
@@ -1157,6 +1344,9 @@ c_common_init (void)
   if (version_flag)
     c_common_print_pch_checksum (stderr);
 
+  /* Has to wait until now so that cpplib has its hash table.  */
+  init_pragma ();
+
   if (flag_preprocess_only)
     {
       finish_options ();
@@ -1164,9 +1354,6 @@ c_common_init (void)
       return false;
     }
 
-  /* Has to wait until now so that cpplib has its hash table.  */
-  init_pragma ();
-
   return true;
 }
 
@@ -1201,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 ();
@@ -1216,6 +1400,7 @@ c_common_parse_file (int set_yydebug)
       if (++i >= num_in_fnames)
        break;
       cpp_undef_all (parse_in);
+      cpp_clear_file_cache (parse_in);
       this_input_filename
        = cpp_read_main_file (parse_in, in_fnames[i]);
       /* If an input file is missing, abandon further compilation.
@@ -1231,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.  */
@@ -1247,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)))
@@ -1341,6 +1527,11 @@ sanitize_cpp_opts (void)
   if (flag_dump_macros == 'M')
     flag_no_output = 1;
 
+  /* By default, -fdirectives-only implies -dD.  This allows subsequent phases
+     to perform proper macro expansion.  */
+  if (cpp_opts->directives_only && !cpp_opts->preprocessed && !flag_dump_macros)
+    flag_dump_macros = 'D';
+
   /* Disable -dD, -dN and -dI if normal output is suppressed.  Allow
      -dM since at least glibc relies on -M -dM to work.  */
   /* Also, flag_no_output implies flag_no_line_commands, always.  */
@@ -1351,14 +1542,21 @@ sanitize_cpp_opts (void)
       flag_dump_includes = 0;
       flag_no_line_commands = 1;
     }
+  else if (cpp_opts->deps.missing_files)
+    error ("-MG may only be used with -M or -MM");
 
   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);
+  /* 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.  */
@@ -1371,6 +1569,14 @@ sanitize_cpp_opts (void)
      actually output the current directory?  */
   if (flag_working_directory == -1)
     flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE);
+
+  if (cpp_opts->directives_only)
+    {
+      if (warn_unused_macros)
+       error ("-fdirectives-only is incompatible with -Wunused_macros");
+      if (cpp_opts->traditional)
+       error ("-fdirectives-only is incompatible with -traditional");
+    }
 }
 
 /* Add include path with a prefix at the front of its name.  */
@@ -1402,7 +1608,7 @@ finish_options (void)
       size_t i;
 
       cb_file_change (parse_in,
-                     linemap_add (&line_table, LC_RENAME, 0,
+                     linemap_add (line_table, LC_RENAME, 0,
                                   _("<built-in>"), 0));
 
       cpp_init_builtins (parse_in, flag_hosted);
@@ -1420,7 +1626,7 @@ finish_options (void)
       cpp_opts->warn_dollars = (cpp_opts->pedantic && !cpp_opts->c99);
 
       cb_file_change (parse_in,
-                     linemap_add (&line_table, LC_RENAME, 0,
+                     linemap_add (line_table, LC_RENAME, 0,
                                   _("<command-line>"), 0));
 
       for (i = 0; i < deferred_count; i++)
@@ -1440,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++)
        {
@@ -1454,6 +1665,16 @@ finish_options (void)
            }
        }
     }
+  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 ();
@@ -1483,7 +1704,7 @@ push_command_line_include (void)
 
       /* Set this here so the client can change the option if it wishes,
         and after stacking the main file so we don't trace the main file.  */
-      line_table.trace_includes = cpp_opts->print_include_names;
+      line_table->trace_includes = cpp_opts->print_include_names;
     }
 }
 
@@ -1520,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).  */
@@ -1530,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;
 }
@@ -1542,6 +1778,7 @@ set_std_cxx98 (int iso)
   flag_no_gnu_keywords = iso;
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
+  cxx_dialect = cxx98;
 }
 
 /* Set the C++ 0x working draft "standard" (without GNU extensions if ISO).  */
@@ -1552,22 +1789,7 @@ set_std_cxx0x (int iso)
   flag_no_gnu_keywords = iso;
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
-  flag_cpp0x = 1;
-}
-
-/* Handle setting implicit to ON.  */
-static void
-set_Wimplicit (int on)
-{
-  warn_implicit = on;
-  warn_implicit_int = on;
-  if (on)
-    {
-      if (mesg_implicit_function_declaration != 2)
-       mesg_implicit_function_declaration = 1;
-    }
-  else
-    mesg_implicit_function_declaration = 0;
+  cxx_dialect = cxx0x;
 }
 
 /* Args to -d specify what to dump.  Silently ignore
@@ -1583,6 +1805,7 @@ handle_OPT_d (const char *arg)
       case 'M':                        /* Dump macros only.  */
       case 'N':                        /* Dump names.  */
       case 'D':                        /* Dump definitions.  */
+      case 'U':                        /* Dump used macros.  */
        flag_dump_macros = c;
        break;