OSDN Git Service

2007-02-15 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / c-opts.c
index e1922cb..76ad827 100644 (file)
@@ -1,5 +1,6 @@
 /* C/ObjC/C++ command line option handling.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
 This file is part of GCC.
@@ -16,8 +17,8 @@ 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.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -37,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "debug.h"             /* For debug_hooks.  */
 #include "opts.h"
 #include "options.h"
+#include "mkdeps.h"
 
 #ifndef DOLLARS_IN_IDENTIFIERS
 # define DOLLARS_IN_IDENTIFIERS true
@@ -46,7 +48,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 # define TARGET_SYSTEM_ROOT NULL
 #endif
 
-static int saved_lineno;
+#ifndef TARGET_OPTF
+#define TARGET_OPTF(ARG)
+#endif
 
 /* CPP's options.  */
 static cpp_options *cpp_opts;
@@ -67,12 +71,18 @@ 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;
 
 /* 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;
 
@@ -88,18 +98,19 @@ static bool quote_chain_split;
 /* If -Wunused-macros.  */
 static bool warn_unused_macros;
 
+/* If -Wvariadic-macros.  */
+static bool warn_variadic_macros = true;
+
 /* Number of deferred options.  */
 static size_t deferred_count;
 
 /* Number of deferred options scanned for -include.  */
 static size_t include_cursor;
 
-/* Permit Fotran front-end options.  */
-static bool permit_fortran_options;
-
 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);
@@ -108,7 +119,8 @@ static void sanitize_cpp_opts (void);
 static void add_prefixed_path (const char *, size_t);
 static void push_command_line_include (void);
 static void cb_file_change (cpp_reader *, const struct line_map *);
-static void finish_options (const char *);
+static void cb_dir_change (cpp_reader *, const char *);
+static void finish_options (void);
 
 #ifndef STDC_0_IN_SYSTEM_HEADERS
 #define STDC_0_IN_SYSTEM_HEADERS 0
@@ -137,23 +149,25 @@ c_common_missing_argument (const char *opt, size_t code)
       return false;
 
     case OPT_fconstant_string_class_:
-      error ("no class name specified with \"%s\"", opt);
+      error ("no class name specified with %qs", opt);
       break;
 
     case OPT_A:
-      error ("assertion missing after \"%s\"", opt);
+      error ("assertion missing after %qs", opt);
       break;
 
     case OPT_D:
     case OPT_U:
-      error ("macro name missing after \"%s\"", opt);
+      error ("macro name missing after %qs", opt);
       break;
 
+    case OPT_F:
     case OPT_I:
     case OPT_idirafter:
     case OPT_isysroot:
     case OPT_isystem:
-      error ("missing path after \"%s\"", opt);
+    case OPT_iquote:
+      error ("missing path after %qs", opt);
       break;
 
     case OPT_MF:
@@ -162,12 +176,12 @@ c_common_missing_argument (const char *opt, size_t code)
     case OPT_include:
     case OPT_imacros:
     case OPT_o:
-      error ("missing filename after \"%s\"", opt);
+      error ("missing filename after %qs", opt);
       break;
 
     case OPT_MQ:
     case OPT_MT:
-      error ("missing makefile target after \"%s\"", opt);
+      error ("missing makefile target after %qs", opt);
       break;
     }
 
@@ -185,10 +199,10 @@ defer_opt (enum opt_code code, const char *arg)
 
 /* Common initialization before parsing options.  */
 unsigned int
-c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
+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 result;
+  unsigned int i, result;
 
   /* This is conditionalized only because that is the way the front
      ends used to do it.  Maybe this should be unconditional?  */
@@ -203,7 +217,7 @@ c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
     }
 
   parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
-                               ident_hash);
+                               ident_hash, &line_table);
 
   cpp_opts = cpp_get_options (parse_in);
   cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
@@ -213,29 +227,39 @@ c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
      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();
 
-  deferred_opts = xmalloc (argc * sizeof (struct deferred_opt));
+  deferred_opts = XNEWVEC (struct deferred_opt, argc);
 
   result = lang_flags[c_language];
 
-  /* If potentially preprocessing Fortran we have to accept its front
-     end options since the driver passes most of them through.  */
-#ifdef CL_F77
-  if (c_language == clk_c && argc > 2
-      && !strcmp (argv[2], "-traditional-cpp" ))
+  if (c_language == clk_c)
     {
-      permit_fortran_options = true;
-      result |= CL_F77;
-    }
+      /* If preprocessing assembly language, accept any of the C-family
+        front end options since the driver may pass them through.  */
+      for (i = 1; i < argc; i++)
+       if (! strcmp (argv[i], "-lang-asm"))
+         {
+           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;
 }
 
-/* Handle switch SCODE with argument ARG.  ON is true, unless no-
+/* Handle switch SCODE with argument ARG.  VALUE is true, unless no-
    form of an -f or -W option was given.  Returns 0 if the switch was
    invalid, a negative number to prevent language-independent
    processing in toplev.c (a hack necessary for the short-term).  */
@@ -246,10 +270,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:
-      result = permit_fortran_options;
+      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
+      result = 0;
       break;
 
     case OPT__output_pch_:
@@ -281,15 +315,20 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->print_include_names = 1;
       break;
 
+    case OPT_F:
+      TARGET_OPTF (xstrdup (arg));
+      break;
+
     case OPT_I:
       if (strcmp (arg, "-"))
-       add_path (xstrdup (arg), BRACKET, 0);
+       add_path (xstrdup (arg), BRACKET, 0, true);
       else
        {
          if (quote_chain_split)
            error ("-I- specified twice");
          quote_chain_split = true;
          split_quote_chain ();
+         inform ("obsolete option -I- used, please use -iquote instead");
        }
       break;
 
@@ -335,12 +374,12 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_no_line_commands = 1;
       break;
 
-    case OPT_U:
-      defer_opt (code, arg);
+    case OPT_fworking_directory:
+      flag_working_directory = value;
       break;
 
-    case OPT_Wabi:
-      warn_abi = value;
+    case OPT_U:
+      defer_opt (code, arg);
       break;
 
     case OPT_Wall:
@@ -356,6 +395,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
        warn_sign_compare = value;
       warn_switch = value;
       warn_strict_aliasing = value;
+      warn_strict_overflow = value;
+      warn_string_literal_comparison = value;
+      warn_always_true = value;
+      warn_array_bounds = value;
 
       /* Only warn about unknown pragmas that are not in system
         headers.  */
@@ -374,27 +417,20 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       else
        {
          /* C++-specific warnings.  */
-         warn_nonvdtor = value;
          warn_reorder = value;
          warn_nontemplate_friend = value;
+          warn_cxx0x_compat = value;
+          if (value > 0)
+            warn_write_strings = true;
        }
 
       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.  */
-      break;
-
-    case OPT_Wbad_function_cast:
-      warn_bad_function_cast = value;
-      break;
 
-    case OPT_Wcast_qual:
-      warn_cast_qual = value;
-      break;
-
-    case OPT_Wchar_subscripts:
-      warn_char_subscripts = value;
+      if (warn_pointer_sign == -1)
+       warn_pointer_sign = 1;
       break;
 
     case OPT_Wcomment:
@@ -402,45 +438,23 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->warn_comments = value;
       break;
 
-    case OPT_Wconversion:
-      warn_conversion = value;
-      break;
-
-    case OPT_Wctor_dtor_privacy:
-      warn_ctor_dtor_privacy = value;
-      break;
-
-    case OPT_Wdeclaration_after_statement:
-      warn_declaration_after_statement = value;
-      break;
-
     case OPT_Wdeprecated:
-      warn_deprecated = value;
       cpp_opts->warn_deprecated = value;
       break;
 
-    case OPT_Wdiv_by_zero:
-      warn_div_by_zero = value;
-      break;
-
-    case OPT_Weffc__:
-      warn_ecpp = value;
-      break;
-
     case OPT_Wendif_labels:
       cpp_opts->warn_endif_labels = 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;
-      break;
-
-    case OPT_Wfloat_equal:
-      warn_float_equal = value;
+    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:
@@ -451,54 +465,18 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       set_Wformat (atoi (arg));
       break;
 
-    case OPT_Wformat_extra_args:
-      warn_format_extra_args = value;
-      break;
-
-    case OPT_Wformat_nonliteral:
-      warn_format_nonliteral = value;
-      break;
-
-    case OPT_Wformat_security:
-      warn_format_security = value;
-      break;
-
-    case OPT_Wformat_y2k:
-      warn_format_y2k = value;
-      break;
-
-    case OPT_Wformat_zero_length:
-      warn_format_zero_length = value;
-      break;
-
     case OPT_Wimplicit:
       set_Wimplicit (value);
       break;
 
-    case OPT_Wimplicit_function_declaration:
-      mesg_implicit_function_declaration = value;
-      break;
-
-    case OPT_Wimplicit_int:
-      warn_implicit_int = value;
-      break;
-
     case OPT_Wimport:
       /* Silently ignore for now.  */
       break;
 
-    case OPT_Winvalid_offsetof:
-      warn_invalid_offsetof = value;
-      break;
-
     case OPT_Winvalid_pch:
       cpp_opts->warn_invalid_pch = value;
       break;
 
-    case OPT_Wlong_long:
-      warn_long_long = value;
-      break;
-
     case OPT_Wmain:
       if (value)
        warn_main = 1;
@@ -506,100 +484,33 @@ c_common_handle_option (size_t scode, const char *arg, int value)
        warn_main = -1;
       break;
 
-    case OPT_Wmissing_braces:
-      warn_missing_braces = value;
-      break;
-
-    case OPT_Wmissing_declarations:
-      warn_missing_declarations = value;
-      break;
-
-    case OPT_Wmissing_format_attribute:
-      warn_missing_format_attribute = value;
-      break;
-
-    case OPT_Wmissing_prototypes:
-      warn_missing_prototypes = value;
+    case OPT_Wmissing_include_dirs:
+      cpp_opts->warn_missing_include_dirs = value;
       break;
 
     case OPT_Wmultichar:
       cpp_opts->warn_multichar = value;
       break;
 
-    case OPT_Wnested_externs:
-      warn_nested_externs = value;
-      break;
-
-    case OPT_Wnon_template_friend:
-      warn_nontemplate_friend = value;
-      break;
-
-    case OPT_Wnon_virtual_dtor:
-      warn_nonvdtor = value;
-      break;
-
-    case OPT_Wnonnull:
-      warn_nonnull = value;
-      break;
-
-    case OPT_Wold_style_cast:
-      warn_old_style_cast = value;
-      break;
-
-    case OPT_Woverloaded_virtual:
-      warn_overloaded_virtual = value;
-      break;
-
-    case OPT_Wparentheses:
-      warn_parentheses = value;
-      break;
-
-    case OPT_Wpmf_conversions:
-      warn_pmf2ptr = value;
-      break;
-
-    case OPT_Wpointer_arith:
-      warn_pointer_arith = value;
-      break;
-
-    case OPT_Wprotocol:
-      warn_protocol = value;
-      break;
-
-    case OPT_Wselector:
-      warn_selector = value;
-      break;
-
-    case OPT_Wredundant_decls:
-      warn_redundant_decls = value;
-      break;
-
-    case OPT_Wreorder:
-      warn_reorder = value;
+    case OPT_Wnormalized_:
+      if (!value || (arg && strcasecmp (arg, "none") == 0))
+       cpp_opts->warn_normalize = normalized_none;
+      else if (!arg || strcasecmp (arg, "nfkc") == 0)
+       cpp_opts->warn_normalize = normalized_KC;
+      else if (strcasecmp (arg, "id") == 0)
+       cpp_opts->warn_normalize = normalized_identifier_C;
+      else if (strcasecmp (arg, "nfc") == 0)
+       cpp_opts->warn_normalize = normalized_C;
+      else
+       error ("argument %qs to %<-Wnormalized%> not recognized", arg);
       break;
 
     case OPT_Wreturn_type:
       warn_return_type = value;
       break;
 
-    case OPT_Wsequence_point:
-      warn_sequence_point = value;
-      break;
-
-    case OPT_Wsign_compare:
-      warn_sign_compare = value;
-      break;
-
-    case OPT_Wsign_promo:
-      warn_sign_promo = value;
-      break;
-
-    case OPT_Wstrict_prototypes:
-      warn_strict_prototypes = value;
-      break;
-
-    case OPT_Wsynth:
-      warn_synth = value;
+    case OPT_Wstrict_null_sentinel:
+      warn_strict_null_sentinel = value;
       break;
 
     case OPT_Wsystem_headers:
@@ -607,7 +518,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_Wtraditional:
-      warn_traditional = value;
       cpp_opts->warn_traditional = value;
       break;
 
@@ -615,10 +525,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->warn_trigraphs = value;
       break;
 
-    case OPT_Wundeclared_selector:
-      warn_undeclared_selector = value;
-      break;
-
     case OPT_Wundef:
       cpp_opts->warn_undef = value;
       break;
@@ -633,11 +539,18 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       warn_unused_macros = value;
       break;
 
+    case OPT_Wvariadic_macros:
+      warn_variadic_macros = 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:
@@ -660,7 +573,9 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       /* Fall through.  */
 
     case OPT_fall_virtual:
+    case OPT_falt_external_templates:
     case OPT_fenum_int_equiv:
+    case OPT_fexternal_templates:
     case OPT_fguiding_decls:
     case OPT_fhonor_std:
     case OPT_fhuge_objects:
@@ -674,26 +589,13 @@ c_common_handle_option (size_t scode, const char *arg, int value)
     case OPT_fvtable_thunks:
     case OPT_fxref:
     case OPT_fvtable_gc:
-      warning ("switch \"%s\" is no longer supported", option->opt_text);
-      break;
-
-    case OPT_fabi_version_:
-      flag_abi_version = value;
+      warning (0, "switch %qs is no longer supported", option->opt_text);
       break;
 
     case OPT_faccess_control:
       flag_access_control = value;
       break;
 
-    case OPT_falt_external_templates:
-      flag_alt_external_templates = value;
-      if (value)
-       flag_external_templates = true;
-    cp_deprecated:
-      warning ("switch \"%s\" is deprecated, please see documentation "
-              "for details", option->opt_text);
-      break;
-
     case OPT_fasm:
       flag_no_asm = !value;
       break;
@@ -713,11 +615,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->dollars_in_ident = value;
       break;
 
-    case OPT_fdump_:
-      if (!dump_switch_p (arg))
-       result = 0;
-      break;
-
     case OPT_ffreestanding:
       value = !value;
       /* Fall through....  */
@@ -743,7 +640,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
 
     case OPT_fsigned_bitfields:
       flag_signed_bitfields = value;
-      explicit_flag_signed_bitfields = 1;
       break;
 
     case OPT_fsigned_char:
@@ -752,7 +648,6 @@ c_common_handle_option (size_t scode, const char *arg, int value)
 
     case OPT_funsigned_bitfields:
       flag_signed_bitfields = !value;
-      explicit_flag_signed_bitfields = 1;
       break;
 
     case OPT_funsigned_char:
@@ -767,10 +662,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;
@@ -787,15 +678,8 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_enforce_eh_specs = value;
       break;
 
-    case OPT_fexternal_templates:
-      flag_external_templates = value;
-      goto cp_deprecated;
-
-    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:
@@ -811,7 +695,7 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_fhandle_exceptions:
-      warning ("-fhandle-exceptions has been renamed -fexceptions (and is now on by default)");
+      warning (0, "-fhandle-exceptions has been renamed -fexceptions (and is now on by default)");
       flag_exceptions = value;
       break;
 
@@ -827,6 +711,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;
@@ -835,6 +723,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       flag_next_runtime = value;
       break;
 
+    case OPT_fnil_receivers:
+      flag_nil_receivers = value;
+      break;
+
     case OPT_fnonansi_builtins:
       flag_no_nonansi_builtin = !value;
       break;
@@ -851,6 +743,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->restore_pch_deps = value;
       break;
 
+    case OPT_fpch_preprocess:
+      flag_pch_preprocess = value;
+      break;
+
     case OPT_fpermissive:
       flag_permissive = value;
       break;
@@ -859,6 +755,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->preprocessed = value;
       break;
 
+    case OPT_freplace_objc_classes:
+      flag_replace_objc_classes = value;
+      break;
+
     case OPT_frepo:
       flag_use_repository = value;
       if (value)
@@ -891,6 +791,10 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       cpp_opts->wide_charset = arg;
       break;
 
+    case OPT_finput_charset_:
+      cpp_opts->input_charset = arg;
+      break;
+
     case OPT_ftemplate_depth_:
       max_tinst_depth = value;
       break;
@@ -899,16 +803,32 @@ c_common_handle_option (size_t scode, const char *arg, int value)
       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;
+
     case OPT_fweak:
       flag_weak = value;
       break;
 
+    case OPT_fthreadsafe_statics:
+      flag_threadsafe_statics = value;
+      break;
+
+    case OPT_fzero_link:
+      flag_zero_link = value;
+      break;
+
     case OPT_gen_decls:
       flag_gen_declaration = 1;
       break;
 
     case OPT_idirafter:
-      add_path (xstrdup (arg), AFTER, 0);
+      add_path (xstrdup (arg), AFTER, 0, true);
       break;
 
     case OPT_imacros:
@@ -916,16 +836,24 @@ 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;
 
+    case OPT_iquote:
+      add_path (xstrdup (arg), QUOTE, 0, true);
+      break;
+
     case OPT_isysroot:
       sysroot = arg;
       break;
 
     case OPT_isystem:
-      add_path (xstrdup (arg), SYSTEM, 0);
+      add_path (xstrdup (arg), SYSTEM, 0, true);
       break;
 
     case OPT_iwithprefix:
@@ -941,6 +869,10 @@ 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;
@@ -969,41 +901,61 @@ c_common_handle_option (size_t scode, const char *arg, int value)
     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;
       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:
@@ -1034,10 +986,12 @@ c_common_handle_option (size_t scode, const char *arg, int value)
 bool
 c_common_post_options (const char **pfilename)
 {
+  struct cpp_callbacks *cb;
+
   /* Canonicalize the input and output filenames.  */
   if (in_fnames == NULL)
     {
-      in_fnames = xmalloc (sizeof (in_fnames[0]));
+      in_fnames = XNEWVEC (const char *, 1);
       in_fnames[0] = "";
     }
   else if (strcmp (in_fnames[0], "-") == 0)
@@ -1053,43 +1007,93 @@ 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;
+#ifdef C_COMMON_OVERRIDE_OPTIONS
+  /* Some machines may reject certain combinations of C
+     language-specific options.  */
+  C_COMMON_OVERRIDE_OPTIONS;
+#endif
 
-  /* Use tree inlining if possible.  Function instrumentation is only
-     done in the RTL level, so we disable tree inlining.  */
-  if (! flag_instrument_function_entry_exit)
-    {
-      if (!flag_no_inline)
-       flag_no_inline = 1;
-      if (flag_inline_functions)
-       {
-         flag_inline_trees = 2;
-         flag_inline_functions = 0;
-       }
-    }
+  flag_inline_trees = 1;
 
-  /* -Wextra implies -Wsign-compare, but not if explicitly
-      overridden.  */
+  /* 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;
+
+  /* Default to ObjC sjlj exception handling if NeXT runtime.  */
+  if (flag_objc_sjlj_exceptions < 0)
+    flag_objc_sjlj_exceptions = flag_next_runtime;
+  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.  */
+  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;
+
+  /* -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;
+
+  /* -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;
 
   /* Special format checking options don't work without -Wformat; warn if
      they are used.  */
-  if (warn_format_y2k && !warn_format)
-    warning ("-Wformat-y2k ignored without -Wformat");
-  if (warn_format_extra_args && !warn_format)
-    warning ("-Wformat-extra-args ignored without -Wformat");
-  if (warn_format_zero_length && !warn_format)
-    warning ("-Wformat-zero-length ignored without -Wformat");
-  if (warn_format_nonliteral && !warn_format)
-    warning ("-Wformat-nonliteral ignored without -Wformat");
-  if (warn_format_security && !warn_format)
-    warning ("-Wformat-security ignored without -Wformat");
-  if (warn_missing_format_attribute && !warn_format)
-    warning ("-Wmissing-format-attribute ignored without -Wformat");
+  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_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;
+
+  /* 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 we're allowing C++0x constructs, don't warn about C++0x
+     compatibility problems.  */
+  if (flag_cpp0x)
+    warn_cxx0x_compat = 0;
 
   if (flag_preprocess_only)
     {
@@ -1118,21 +1122,33 @@ c_common_post_options (const char **pfilename)
       init_c_lex ();
 
       /* Yuk.  WTF is this?  I do know ObjC relies on it somewhere.  */
-      input_line = 0;
+      input_location = UNKNOWN_LOCATION;
     }
 
-  cpp_get_callbacks (parse_in)->file_change = cb_file_change;
-
-  /* NOTE: we use in_fname here, not the one supplied.  */
-  *pfilename = cpp_read_main_file (parse_in, in_fnames[0]);
+  cb = cpp_get_callbacks (parse_in);
+  cb->file_change = cb_file_change;
+  cb->dir_change = cb_dir_change;
+  cpp_post_options (parse_in);
 
-  saved_lineno = input_line;
-  input_line = 0;
+  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.  */
+  if (this_input_filename == NULL)
+    {
+      errorcount++;
+      return false;
+    }
+
+  if (flag_working_directory
+      && flag_preprocess_only && !flag_no_line_commands)
+    pp_dir_change (parse_in, get_src_pwd ());
+
   return flag_preprocess_only;
 }
 
@@ -1140,24 +1156,25 @@ c_common_post_options (const char **pfilename)
 bool
 c_common_init (void)
 {
-  input_line = saved_lineno;
-
   /* Set up preprocessor arithmetic.  Must be done after call to
      c_common_nodes_and_builtins for type nodes to be good.  */
   cpp_opts->precision = TYPE_PRECISION (intmax_type_node);
   cpp_opts->char_precision = TYPE_PRECISION (char_type_node);
   cpp_opts->int_precision = TYPE_PRECISION (integer_type_node);
   cpp_opts->wchar_precision = TYPE_PRECISION (wchar_type_node);
-  cpp_opts->unsigned_wchar = TREE_UNSIGNED (wchar_type_node);
+  cpp_opts->unsigned_wchar = TYPE_UNSIGNED (wchar_type_node);
   cpp_opts->bytes_big_endian = BYTES_BIG_ENDIAN;
 
   /* This can't happen until after wchar_precision and bytes_big_endian
      are known.  */
   cpp_init_iconv (parse_in);
 
+  if (version_flag)
+    c_common_print_pch_checksum (stderr);
+
   if (flag_preprocess_only)
     {
-      finish_options (in_fnames[0]);
+      finish_options ();
       preprocess_file (parse_in);
       return false;
     }
@@ -1171,40 +1188,56 @@ c_common_init (void)
 /* Initialize the integrated preprocessor after debug output has been
    initialized; loop over each input file.  */
 void
-c_common_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
+c_common_parse_file (int set_yydebug)
 {
-  unsigned file_index;
-  
-#if YYDEBUG != 0
-  yydebug = set_yydebug;
-#else
-  warning ("YYDEBUG not defined");
-#endif
-
-  file_index = 0;
-  
-  do
-    {
-      if (file_index > 0)
-       {
-         /* Reset the state of the parser.  */
-         c_reset_state();
+  unsigned int i;
 
-         /* Reset cpplib's macros and start a new file.  */
-         cpp_undef_all (parse_in);
-         cpp_stack_file (parse_in, in_fnames[file_index]);
-       }
+  if (set_yydebug)
+    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 ();
+    }
 
-      finish_options(in_fnames[file_index]);
-      if (file_index == 0)
-       pch_init();
+  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 ();
       c_parse_file ();
-
-      file_index++;
-    } while (file_index < num_in_fnames);
-  
-  free_parser_stacks ();
-  finish_file ();
+      finish_file ();
+      pop_file_scope ();
+      /* And end the main input file, if the debug writer wants it  */
+      if (debug_hooks->start_end_main_source_file)
+       (*debug_hooks->end_source_file) (0);
+      if (++i >= num_in_fnames)
+       break;
+      cpp_undef_all (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.  */
+      if (!this_input_filename)
+       break;
+    }
 }
 
 /* Common finish hook for the C, ObjC and C++ front ends.  */
@@ -1280,6 +1313,7 @@ check_deps_environment_vars (void)
        deps_file = spec;
 
       deps_append = 1;
+      deps_seen = true;
     }
 }
 
@@ -1288,13 +1322,22 @@ static void
 handle_deferred_opts (void)
 {
   size_t i;
+  struct deps *deps;
+
+  /* Avoid allocating the deps buffer if we don't need it.
+     (This flag may be true without there having been -MT or -MQ
+     options, but we'll still need the deps buffer.)  */
+  if (!deps_seen)
+    return;
+
+  deps = cpp_get_deps (parse_in);
 
   for (i = 0; i < deferred_count; i++)
     {
       struct deferred_opt *opt = &deferred_opts[i];
 
       if (opt->code == OPT_MT || opt->code == OPT_MQ)
-       cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ);
+       deps_add_target (deps, opt->arg, opt->code == OPT_MQ);
     }
 }
 
@@ -1315,11 +1358,13 @@ sanitize_cpp_opts (void)
 
   /* 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.  */
   if (flag_no_output)
     {
       if (flag_dump_macros != 'M')
        flag_dump_macros = 0;
       flag_dump_includes = 0;
+      flag_no_line_commands = 1;
     }
 
   cpp_opts->unsigned_char = !flag_signed_char;
@@ -1329,6 +1374,18 @@ sanitize_cpp_opts (void)
      and/or -Wtraditional, whatever the ordering.  */
   cpp_opts->warn_long_long
     = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
+
+  /* Similarly with -Wno-variadic-macros.  No check for c99 here, since
+     this also turns off warnings about GCCs extension.  */
+  cpp_opts->warn_variadic_macros
+    = warn_variadic_macros && (pedantic || warn_traditional);
+
+  /* If we're generating preprocessor output, emit current directory
+     if explicitly requested or if debugging information is enabled.
+     ??? Maybe we should only do it for debugging formats that
+     actually output the current directory?  */
+  if (flag_working_directory == -1)
+    flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE);
 }
 
 /* Add include path with a prefix at the front of its name.  */
@@ -1343,25 +1400,26 @@ add_prefixed_path (const char *suffix, size_t chain)
   prefix     = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR;
   prefix_len = iprefix ? strlen (iprefix) : cpp_GCC_INCLUDE_DIR_len;
 
-  path = xmalloc (prefix_len + suffix_len + 1);
+  path = (char *) xmalloc (prefix_len + suffix_len + 1);
   memcpy (path, prefix, prefix_len);
   memcpy (path + prefix_len, suffix, suffix_len);
   path[prefix_len + suffix_len] = '\0';
 
-  add_path (path, chain, 0);
+  add_path (path, chain, 0, false);
 }
 
-/* Handle -D, -U, -A, -imacros, and the first -include.  
-   TIF is the input file to which we will return after processing all
-   the includes.  */
+/* Handle -D, -U, -A, -imacros, and the first -include.  */
 static void
-finish_options (const char *tif)
+finish_options (void)
 {
   if (!cpp_opts->preprocessed)
     {
       size_t i;
 
-      cpp_change_file (parse_in, LC_RENAME, _("<built-in>"));
+      cb_file_change (parse_in,
+                     linemap_add (&line_table, LC_RENAME, 0,
+                                  _("<built-in>"), 0));
+
       cpp_init_builtins (parse_in, flag_hosted);
       c_cpp_builtins (parse_in);
 
@@ -1376,7 +1434,10 @@ finish_options (const char *tif)
         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];
@@ -1401,12 +1462,15 @@ finish_options (const char *tif)
 
          if (opt->code == OPT_imacros
              && cpp_push_include (parse_in, opt->arg))
-           cpp_scan_nooutput (parse_in);
+           {
+             /* Disable push_command_line_include callback for now.  */
+             include_cursor = deferred_count + 1;
+             cpp_scan_nooutput (parse_in);
+           }
        }
     }
 
   include_cursor = 0;
-  this_input_filename = tif;
   push_command_line_include ();
 }
 
@@ -1414,30 +1478,33 @@ finish_options (const char *tif)
 static void
 push_command_line_include (void)
 {
-  if (cpp_opts->preprocessed)
-    return;
-
   while (include_cursor < deferred_count)
     {
       struct deferred_opt *opt = &deferred_opts[include_cursor++];
 
-      if (opt->code == OPT_include && cpp_push_include (parse_in, opt->arg))
+      if (!cpp_opts->preprocessed && opt->code == OPT_include
+         && cpp_push_include (parse_in, opt->arg))
        return;
     }
 
   if (include_cursor == deferred_count)
     {
-      /* Restore the line map from <command line>.  */
-      cpp_change_file (parse_in, LC_RENAME, this_input_filename);
+      include_cursor++;
       /* -Wunused-macros should only warn about macros defined hereafter.  */
       cpp_opts->warn_unused_macros = warn_unused_macros;
-      include_cursor++;
+      /* Restore the line map from <command line>.  */
+      if (!cpp_opts->preprocessed)
+       cpp_change_file (parse_in, LC_RENAME, this_input_filename);
+
+      /* 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;
     }
 }
 
 /* File change callback.  Has to handle -include files.  */
 static void
-cb_file_change (cpp_reader *pfile ATTRIBUTE_UNUSED,
+cb_file_change (cpp_reader * ARG_UNUSED (pfile),
                const struct line_map *new_map)
 {
   if (flag_preprocess_only)
@@ -1445,10 +1512,17 @@ cb_file_change (cpp_reader *pfile ATTRIBUTE_UNUSED,
   else
     fe_file_change (new_map);
 
-  if (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map))
+  if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map)))
     push_command_line_include ();
 }
 
+void
+cb_dir_change (cpp_reader * ARG_UNUSED (pfile), const char *dir)
+{
+  if (!set_src_pwd (dir))
+    warning (0, "too late for # directive to set debug directory");
+}
+
 /* Set the C 89 standard (with 1994 amendments if C94, without GNU
    extensions if ISO).  There is no concept of gnu94.  */
 static void
@@ -1459,10 +1533,8 @@ set_std_c89 (int c94, int iso)
   flag_no_asm = iso;
   flag_no_gnu_keywords = iso;
   flag_no_nonansi_builtin = iso;
-  flag_noniso_default_format_attributes = !iso;
   flag_isoc94 = c94;
   flag_isoc99 = 0;
-  flag_writable_strings = 0;
 }
 
 /* Set the C 99 standard (without GNU extensions if ISO).  */
@@ -1472,11 +1544,9 @@ set_std_c99 (int iso)
   cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99);
   flag_no_asm = iso;
   flag_no_nonansi_builtin = iso;
-  flag_noniso_default_format_attributes = !iso;
   flag_iso = iso;
   flag_isoc99 = 1;
   flag_isoc94 = 1;
-  flag_writable_strings = 0;
 }
 
 /* Set the C++ 98 standard (without GNU extensions if ISO).  */
@@ -1486,23 +1556,27 @@ set_std_cxx98 (int iso)
   cpp_set_lang (parse_in, iso ? CLK_CXX98: CLK_GNUCXX);
   flag_no_gnu_keywords = iso;
   flag_no_nonansi_builtin = iso;
-  flag_noniso_default_format_attributes = !iso;
   flag_iso = iso;
 }
 
+/* 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;
+  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;
+  warn_implicit_function_declaration = on;
 }
 
 /* Args to -d specify what to dump.  Silently ignore