OSDN Git Service

PR middle-end/40500
[pf3gnuchains/gcc-fork.git] / gcc / c-opts.c
index ebf23e5..e026fd9 100644 (file)
@@ -1,12 +1,13 @@
 /* C/ObjC/C++ command line option handling.
-   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   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, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, 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, 59 Temple Place - Suite 330, 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, 59 Temple Place - Suite 330, Boston, MA
 #endif
 
 /* CPP's options.  */
-static cpp_options *cpp_opts;
+cpp_options *cpp_opts;
 
 /* Input filename.  */
 static const char *this_input_filename;
@@ -76,6 +79,9 @@ static const char *deps_file;
 /* The prefix given by -iprefix, if any.  */
 static const char *iprefix;
 
+/* The multilib directory given by -imultilib, if any.  */
+static const char *imultilib;
+
 /* The system root, if any.  Overridden by -isysroot.  */
 static const char *sysroot = TARGET_SYSTEM_ROOT;
 
@@ -103,6 +109,7 @@ 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 check_deps_environment_vars (void);
@@ -195,6 +202,7 @@ 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;
 
   /* This is conditionalized only because that is the way the front
      ends used to do it.  Maybe this should be unconditional?  */
@@ -209,7 +217,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;
@@ -219,9 +229,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);
 
@@ -253,11 +267,20 @@ c_common_handle_option (size_t scode, const char *arg, int value)
   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;
+       {
+         if ((option->flags & CL_TARGET)
+             && ! targetcm.handle_c_option (scode, arg, value))
+           result = 0;
+         break;
+       }
       result = 0;
       break;
 
@@ -303,7 +326,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;
 
@@ -315,12 +338,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;
 
@@ -358,7 +381,7 @@ 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);
       warn_char_subscripts = value;
@@ -366,37 +389,52 @@ c_common_handle_option (size_t scode, const char *arg, int 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;
+      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:
@@ -404,12 +442,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:
@@ -417,12 +463,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;
+    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); 
       break;
 
     case OPT_Wformat:
@@ -445,13 +492,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;
@@ -481,10 +521,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;
@@ -512,10 +548,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:
@@ -576,6 +615,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;
@@ -586,9 +629,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:
@@ -627,10 +667,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;
@@ -647,11 +683,8 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_enforce_eh_specs = value;
       break;
 
-    case OPT_ffixed_form:
-    case OPT_ffixed_line_length_:
-      /* Fortran front end options ignored when preprocessing only.  */
-      if (!flag_preprocess_only)
-        result = 0;
+    case OPT_fextended_identifiers:
+      cpp_opts->extended_identifiers = value;
       break;
 
     case OPT_ffor_scope:
@@ -683,6 +716,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;
@@ -699,14 +736,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_no_nonansi_builtin = !value;
       break;
 
-    case OPT_fobjc_exceptions:
-      flag_objc_exceptions = value;
-      break;
-
-    case OPT_fobjc_sjlj_exceptions:
-      flag_objc_sjlj_exceptions = value;
-      break;
-
     case OPT_foperator_names:
       cpp_opts->operator_names = value;
       break;
@@ -734,7 +763,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)
@@ -778,7 +807,11 @@ c_common_handle_option (size_t scode, const char *arg, int value)
     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;
@@ -791,6 +824,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;
@@ -799,6 +836,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;
@@ -808,6 +857,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       defer_opt (code, arg);
       break;
 
+    case OPT_imultilib:
+      imultilib = arg;
+      break;
+
     case OPT_iprefix:
       iprefix = arg;
       break;
@@ -860,46 +913,66 @@ 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:
       print_struct_values = 1;
       break;
 
+    case OPT_print_pch_checksum:
+      c_common_print_pch_checksum (stdout);
+      exit_after_options = true;
+      break;
+
     case OPT_remap:
       cpp_opts->remap = 1;
       break;
 
     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_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 */);
+      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_trigraphs:
@@ -914,13 +987,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;
@@ -951,21 +1024,35 @@ c_common_post_options (const char **pfilename)
 
   sanitize_cpp_opts ();
 
-  register_include_chains (parse_in, sysroot, iprefix,
+  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)
@@ -973,32 +1060,98 @@ 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.  */
-  if (warn_format_y2k && !warn_format)
-    warning (0, "-Wformat-y2k ignored without -Wformat");
-  if (warn_format_extra_args && !warn_format)
-    warning (0, "-Wformat-extra-args ignored without -Wformat");
-  if (warn_format_zero_length && !warn_format)
-    warning (0, "-Wformat-zero-length ignored without -Wformat");
-  if (warn_format_nonliteral && !warn_format)
-    warning (0, "-Wformat-nonliteral ignored without -Wformat");
-  if (warn_format_security && !warn_format)
-    warning (0, "-Wformat-security ignored without -Wformat");
-  if (warn_missing_format_attribute && !warn_format)
-    warning (0, "-Wmissing-format-attribute 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_format)
+    {
+      warning (OPT_Wformat_y2k,
+              "-Wformat-y2k ignored without -Wformat");
+      warning (OPT_Wformat_extra_args,
+              "-Wformat-extra-args ignored without -Wformat");
+      warning (OPT_Wformat_zero_length,
+              "-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");
+    }
+
+  /* -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)
     {
@@ -1037,10 +1190,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.  */
@@ -1074,6 +1223,12 @@ c_common_init (void)
      are known.  */
   cpp_init_iconv (parse_in);
 
+  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 ();
@@ -1081,9 +1236,6 @@ c_common_init (void)
       return false;
     }
 
-  /* Has to wait until now so that cpplib has its hash table.  */
-  init_pragma ();
-
   return true;
 }
 
@@ -1094,14 +1246,26 @@ 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 (;;)
@@ -1121,10 +1285,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;
     }
@@ -1136,7 +1301,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.  */
@@ -1152,7 +1318,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)))
@@ -1246,6 +1412,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.  */
@@ -1256,14 +1427,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.  */
@@ -1276,6 +1454,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.  */
@@ -1307,7 +1493,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);
@@ -1324,7 +1510,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];
@@ -1356,6 +1545,8 @@ finish_options (void)
            }
        }
     }
+  else if (cpp_opts->directives_only)
+    cpp_init_special_builtins (parse_in);
 
   include_cursor = 0;
   push_command_line_include ();
@@ -1385,7 +1576,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;
     }
 }
 
@@ -1444,6 +1635,18 @@ 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).  */
+static void
+set_std_cxx0x (int iso)
+{
+  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;
 }
 
 /* Handle setting implicit to ON.  */
@@ -1452,13 +1655,7 @@ 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;
+  warn_implicit_function_declaration = on;
 }
 
 /* Args to -d specify what to dump.  Silently ignore
@@ -1474,6 +1671,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;