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 f508e4e..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,11 +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?  */
@@ -215,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;
@@ -225,9 +320,13 @@ c_common_init_options (unsigned int argc, const char **argv)
      before passing on command-line options to cpplib.  */
   cpp_opts->warn_dollars = 0;
 
-  flag_const_strings = 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;
 
   deferred_opts = XNEWVEC (struct deferred_opt, argc);
 
@@ -243,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;
@@ -262,21 +352,27 @@ 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;
   int result = 1;
 
+  /* 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;
 
@@ -322,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;
 
@@ -334,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;
 
@@ -377,47 +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_nonvdtor = value;
+          warn_sign_compare = value;
          warn_reorder = value;
-         warn_nontemplate_friend = value;
+          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 = value;
+      break;
+
+    case OPT_Wbuiltin_macro_redefined:
+      cpp_opts->warn_builtin_macro_redefined = value;
       break;
 
     case OPT_Wcomment:
@@ -425,12 +534,20 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->warn_comments = value;
       break;
 
-    case OPT_Wdeprecated:
-      cpp_opts->warn_deprecated = value;
+    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_Wdiv_by_zero:
-      warn_div_by_zero = value;
+    case OPT_Wdeprecated:
+      cpp_opts->warn_deprecated = value;
       break;
 
     case OPT_Wendif_labels:
@@ -438,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:
@@ -455,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:
@@ -466,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;
@@ -502,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;
@@ -533,10 +646,13 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_Wwrite_strings:
-      if (!c_dialect_cxx ())
-       flag_const_strings = value;
-      else
-       warn_write_strings = value;
+      warn_write_strings = value;
+      break;
+
+    case OPT_Weffc__:
+      warn_ecpp = value;
+      if (value)
+        warn_nonvdtor = true;
       break;
 
     case OPT_ansi:
@@ -597,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;
@@ -607,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:
@@ -648,10 +765,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_conserve_space = value;
       break;
 
-    case OPT_fconst_strings:
-      flag_const_strings = value;
-      break;
-
     case OPT_fconstant_string_class_:
       constant_string_class_name = arg;
       break;
@@ -701,6 +814,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_implicit_templates = value;
       break;
 
+    case OPT_flax_vector_conversions:
+      flag_lax_vector_conversions = value;
+      break;
+
     case OPT_fms_extensions:
       flag_ms_extensions = value;
       break;
@@ -744,7 +861,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
     case OPT_freplace_objc_classes:
       flag_replace_objc_classes = value;
       break;
-      
+
     case OPT_frepo:
       flag_use_repository = value;
       if (value)
@@ -782,13 +899,19 @@ 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;
 
     case OPT_fuse_cxa_atexit:
       flag_use_cxa_atexit = value;
       break;
-      
+
+    case OPT_fuse_cxa_get_exception_ptr:
+      flag_use_cxa_get_exception_ptr = value;
+      break;
+
     case OPT_fvisibility_inlines_hidden:
       visibility_options.inlines_hidden = value;
       break;
@@ -801,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;
@@ -809,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;
@@ -851,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;
@@ -878,11 +1013,15 @@ 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;
+      if (warn_pointer_sign == -1)
+       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:
@@ -900,29 +1039,52 @@ c_common_handle_option (size_t scode, const char *arg, int value)
 
     case OPT_std_c__98:
     case OPT_std_gnu__98:
-      set_std_cxx98 (code == OPT_std_c__98 /* ISO */);
+      if (!preprocessing_asm_p)
+       set_std_cxx98 (code == OPT_std_c__98 /* ISO */);
+      break;
+
+    case OPT_std_c__0x:
+    case OPT_std_gnu__0x:
+      if (!preprocessing_asm_p)
+       set_std_cxx0x (code == OPT_std_c__0x /* ISO */);
       break;
 
     case OPT_std_c89:
+    case OPT_std_c90:
     case OPT_std_iso9899_1990:
     case OPT_std_iso9899_199409:
-      set_std_c89 (code == OPT_std_iso9899_199409 /* c94 */, true /* ISO */);
+      if (!preprocessing_asm_p)
+       set_std_c89 (code == OPT_std_iso9899_199409 /* c94 */, true /* ISO */);
       break;
 
     case OPT_std_gnu89:
-      set_std_c89 (false /* c94 */, false /* ISO */);
+    case OPT_std_gnu90:
+      if (!preprocessing_asm_p)
+       set_std_c89 (false /* c94 */, false /* ISO */);
       break;
 
     case OPT_std_c99:
     case OPT_std_c9x:
     case OPT_std_iso9899_1999:
     case OPT_std_iso9899_199x:
-      set_std_c99 (true /* ISO */);
+      if (!preprocessing_asm_p)
+       set_std_c99 (true /* ISO */);
       break;
 
     case OPT_std_gnu99:
     case OPT_std_gnu9x:
-      set_std_c99 (false /* ISO */);
+      if (!preprocessing_asm_p)
+       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:
@@ -937,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;
@@ -977,18 +1139,32 @@ c_common_post_options (const char **pfilename)
   register_include_chains (parse_in, sysroot, iprefix, imultilib,
                           std_inc, std_cxx_inc && c_dialect_cxx (), verbose);
 
-  flag_inline_trees = 1;
-
-  /* Use tree inlining.  */
-  if (!flag_no_inline)
-    flag_no_inline = 1;
-  if (flag_inline_functions)
-    flag_inline_trees = 2;
+#ifdef C_COMMON_OVERRIDE_OPTIONS
+  /* Some machines may reject certain combinations of C
+     language-specific options.  */
+  C_COMMON_OVERRIDE_OPTIONS;
+#endif
 
-  /* 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)
@@ -996,12 +1172,71 @@ c_common_post_options (const char **pfilename)
   if (flag_objc_exceptions && !flag_objc_sjlj_exceptions)
     flag_exceptions = 1;
 
-  /* -Wextra implies -Wsign-compare and -Wmissing-field-initializers,
-     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)
+    warn_empty_body = extra_warnings;
   if (warn_sign_compare == -1)
     warn_sign_compare = extra_warnings;
   if (warn_missing_field_initializers == -1)
     warn_missing_field_initializers = extra_warnings;
+  if (warn_missing_parameter_type == -1)
+    warn_missing_parameter_type = extra_warnings;
+  if (warn_old_style_declaration == -1)
+    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
+     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.  */
@@ -1015,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)
     {
@@ -1061,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.  */
@@ -1101,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 ();
@@ -1108,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;
 }
 
@@ -1121,21 +1364,30 @@ c_common_parse_file (int set_yydebug)
 {
   unsigned int i;
 
-  /* Enable parser debugging, if requested and we can.  If requested
-     and we can't, notify the user.  */
-#if YYDEBUG != 0
-  yydebug = set_yydebug;
-#else
   if (set_yydebug)
-    warning (0, "YYDEBUG was not defined at build time, -dy ignored");
-#endif
+    switch (c_language)
+      {
+      case clk_c:
+       warning(0, "The C parser does not support -dy, option ignored");
+       break;
+      case clk_objc:
+       warning(0,
+               "The Objective-C parser does not support -dy, option ignored");
+       break;
+      case clk_cxx:
+       warning(0, "The C++ parser does not support -dy, option ignored");
+       break;
+      case clk_objcxx:
+       warning(0,
+           "The Objective-C++ parser does not support -dy, option ignored");
+       break;
+      default:
+       gcc_unreachable ();
+    }
 
   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 ();
@@ -1148,10 +1400,11 @@ 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.
-         cpplib has issued a diagnostic.  */
+        cpplib has issued a diagnostic.  */
       if (!this_input_filename)
        break;
     }
@@ -1163,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.  */
@@ -1179,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)))
@@ -1273,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.  */
@@ -1283,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.  */
@@ -1303,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.  */
@@ -1334,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);
@@ -1351,7 +1625,10 @@ finish_options (void)
         their acceptance on the -std= setting.  */
       cpp_opts->warn_dollars = (cpp_opts->pedantic && !cpp_opts->c99);
 
-      cpp_change_file (parse_in, LC_RENAME, _("<command line>"));
+      cb_file_change (parse_in,
+                     linemap_add (line_table, LC_RENAME, 0,
+                                  _("<command-line>"), 0));
+
       for (i = 0; i < deferred_count; i++)
        {
          struct deferred_opt *opt = &deferred_opts[i];
@@ -1369,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++)
        {
@@ -1383,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 ();
@@ -1412,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;
     }
 }
 
@@ -1449,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).  */
@@ -1459,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;
 }
@@ -1471,21 +1778,18 @@ set_std_cxx98 (int iso)
   flag_no_gnu_keywords = iso;
   flag_no_nonansi_builtin = iso;
   flag_iso = iso;
+  cxx_dialect = cxx98;
 }
 
-/* Handle setting implicit to ON.  */
+/* Set the C++ 0x working draft "standard" (without GNU extensions if ISO).  */
 static void
-set_Wimplicit (int on)
+set_std_cxx0x (int iso)
 {
-  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;
+  cpp_set_lang (parse_in, iso ? CLK_CXX0X: CLK_GNUCXX0X);
+  flag_no_gnu_keywords = iso;
+  flag_no_nonansi_builtin = iso;
+  flag_iso = iso;
+  cxx_dialect = cxx0x;
 }
 
 /* Args to -d specify what to dump.  Silently ignore
@@ -1501,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;