OSDN Git Service

Add framework support for darwin.
[pf3gnuchains/gcc-fork.git] / gcc / c-opts.c
index 075112e..6d9696a 100644 (file)
@@ -1,5 +1,5 @@
 /* C/ObjC/C++ command line option handling.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
 This file is part of GCC.
@@ -32,12 +32,27 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree-inline.h"
 #include "diagnostic.h"
 #include "intl.h"
+#include "cppdefault.h"
+#include "c-incpath.h"
+#include "debug.h"             /* For debug_hooks.  */
+#include "opts.h"
+#include "options.h"
+
+#ifndef DOLLARS_IN_IDENTIFIERS
+# define DOLLARS_IN_IDENTIFIERS true
+#endif
+
+#ifndef TARGET_SYSTEM_ROOT
+# define TARGET_SYSTEM_ROOT NULL
+#endif
+
+static int saved_lineno;
 
 /* CPP's options.  */
 static cpp_options *cpp_opts;
 
 /* Input filename.  */
-static const char *in_fname;
+static const char *this_input_filename;
 
 /* Filename and stream for preprocessed output.  */
 static const char *out_fname;
@@ -49,592 +64,205 @@ static bool deps_append;
 /* If dependency switches (-MF etc.) have been given.  */
 static bool deps_seen;
 
+/* If -v seen.  */
+static bool verbose;
+
 /* Dependency output file.  */
 static const char *deps_file;
 
-/* Number of deferred options, deferred options array size.  */
-static size_t deferred_count, deferred_size;
-
-static void missing_arg PARAMS ((size_t));
-static size_t find_opt PARAMS ((const char *, int));
-static void set_Wimplicit PARAMS ((int));
-static void complain_wrong_lang PARAMS ((size_t));
-static void write_langs PARAMS ((char *, int));
-static void print_help PARAMS ((void));
-static void handle_OPT_d PARAMS ((const char *));
-static void set_std_cxx98 PARAMS ((int));
-static void set_std_c89 PARAMS ((int, int));
-static void set_std_c99 PARAMS ((int));
-static void check_deps_environment_vars PARAMS ((void));
-static void preprocess_file PARAMS ((void));
-static void handle_deferred_opts PARAMS ((void));
-static void sanitize_cpp_opts PARAMS ((void));
+/* The prefix given by -iprefix, if any.  */
+static const char *iprefix;
 
-#ifndef STDC_0_IN_SYSTEM_HEADERS
-#define STDC_0_IN_SYSTEM_HEADERS 0
-#endif
+/* The system root, if any.  Overridden by -isysroot.  */
+static const char *sysroot = TARGET_SYSTEM_ROOT;
 
-#define CL_C_ONLY      (1 << 0) /* Only C.  */
-#define CL_OBJC_ONLY   (1 << 1) /* Only ObjC.  */
-#define CL_CXX_ONLY    (1 << 2) /* Only C++.  */
-#define CL_OBJCXX_ONLY (1 << 3) /* Only ObjC++.  */
-#define CL_JOINED      (1 << 4) /* If takes joined argument.  */
-#define CL_SEPARATE    (1 << 5) /* If takes a separate argument.  */
-
-#define CL_ARG         (CL_JOINED | CL_SEPARATE)
-#define CL_C           (CL_C_ONLY | CL_OBJC_ONLY)
-#define CL_OBJC                (CL_OBJC_ONLY | CL_OBJCXX_ONLY)
-#define CL_CXX         (CL_CXX_ONLY | CL_OBJCXX_ONLY)
-#define CL_ALL         (CL_C | CL_CXX)
-
-/* This is the list of all command line options, with the leading "-"
-   removed.  It must be sorted in ASCII collating order.  All options
-   beginning with "f" or "W" are implicitly assumed to take a "no-"
-   form; this form should not be listed.  The variable "on" is true if
-   the positive form is given, otherwise it is false.  If you don't
-   want to allow a "no-" form, your handler should reject "on" being
-   false by returning zero.  See, for example, the handling of
-   -ftabstop=.
-
-   If the user gives an option to a front end that doesn't support it,
-   an error is output, mentioning which front ends the option is valid
-   for.  If you don't want this, you must accept it for all front
-   ends, and test for the front end in the option handler.  See, for
-   example, the handling of -Wno-strict-prototypes for C++.
-
-   If you request an argument with CL_JOINED, CL_SEPARATE or their
-   combination CL_ARG, it is stored in the variable "arg", which is
-   guaranteed to be non-NULL and to not be an empty string.  It points
-   to the argument either within the argv[] vector or within one of
-   that vector's strings, and so the text is permanent and copies need
-   not be made.  Be sure to add an error message in missing_arg() if
-   the default is not appropriate.  */
-
-#define COMMAND_LINE_OPTIONS                                                \
-  OPT("-help",                  CL_ALL,   OPT__help)                        \
-  OPT("-output-pch=",          CL_ALL | CL_ARG, OPT__output_pch)            \
-  OPT("C",                      CL_ALL,   OPT_C)                            \
-  OPT("CC",                     CL_ALL,   OPT_CC)                           \
-  OPT("E",                     CL_ALL,   OPT_E)                             \
-  OPT("H",                      CL_ALL,   OPT_H)                            \
-  OPT("M",                      CL_ALL,   OPT_M)                            \
-  OPT("MD",                     CL_ALL | CL_SEPARATE, OPT_MD)               \
-  OPT("MF",                     CL_ALL | CL_ARG, OPT_MF)                    \
-  OPT("MG",                     CL_ALL,   OPT_MG)                           \
-  OPT("MM",                     CL_ALL,   OPT_MM)                           \
-  OPT("MMD",                    CL_ALL | CL_SEPARATE, OPT_MMD)              \
-  OPT("MP",                     CL_ALL,   OPT_MP)                           \
-  OPT("MQ",                     CL_ALL | CL_ARG, OPT_MQ)                    \
-  OPT("MT",                     CL_ALL | CL_ARG, OPT_MT)                    \
-  OPT("P",                      CL_ALL,   OPT_P)                            \
-  OPT("Wabi",                   CL_CXX,   OPT_Wabi)                          \
-  OPT("Wall",                  CL_ALL,   OPT_Wall)                          \
-  OPT("Wbad-function-cast",    CL_C,     OPT_Wbad_function_cast)            \
-  OPT("Wcast-qual",            CL_ALL,   OPT_Wcast_qual)                    \
-  OPT("Wchar-subscripts",      CL_ALL,   OPT_Wchar_subscripts)              \
-  OPT("Wcomment",              CL_ALL,   OPT_Wcomment)                      \
-  OPT("Wcomments",              CL_ALL,   OPT_Wcomments)                    \
-  OPT("Wconversion",           CL_ALL,   OPT_Wconversion)                   \
-  OPT("Wctor-dtor-privacy",    CL_CXX,   OPT_Wctor_dtor_privacy)            \
-  OPT("Wdeprecated",           CL_CXX,   OPT_Wdeprecated)                   \
-  OPT("Wdiv-by-zero",          CL_C,     OPT_Wdiv_by_zero)                  \
-  OPT("Weffc++",               CL_CXX,   OPT_Weffcxx)                       \
-  OPT("Wendif-labels",         CL_ALL,   OPT_Wendif_labels)                 \
-  OPT("Werror",                 CL_ALL,   OPT_Werror)                       \
-  OPT("Werror-implicit-function-declaration",                               \
-                               CL_C,     OPT_Werror_implicit_function_decl) \
-  OPT("Wfloat-equal",          CL_ALL,   OPT_Wfloat_equal)                  \
-  OPT("Wformat",               CL_ALL,   OPT_Wformat)                       \
-  OPT("Wformat-extra-args",    CL_ALL,   OPT_Wformat_extra_args)            \
-  OPT("Wformat-nonliteral",    CL_ALL,   OPT_Wformat_nonliteral)            \
-  OPT("Wformat-security",      CL_ALL,   OPT_Wformat_security)              \
-  OPT("Wformat-y2k",           CL_ALL,   OPT_Wformat_y2k)                   \
-  OPT("Wformat-zero-length",   CL_C,     OPT_Wformat_zero_length)           \
-  OPT("Wformat=",              CL_ALL | CL_JOINED, OPT_Wformat_eq)          \
-  OPT("Wimplicit",             CL_ALL,   OPT_Wimplicit)                     \
-  OPT("Wimplicit-function-declaration",        CL_C, OPT_Wimplicit_function_decl)   \
-  OPT("Wimplicit-int",         CL_C,     OPT_Wimplicit_int)                 \
-  OPT("Wimport",                CL_ALL,   OPT_Wimport)                      \
-  OPT("Winvalid-pch",           CL_ALL,   OPT_Winvalid_pch)                 \
-  OPT("Wlong-long",            CL_ALL,   OPT_Wlong_long)                    \
-  OPT("Wmain",                 CL_C,     OPT_Wmain)                         \
-  OPT("Wmissing-braces",       CL_ALL,   OPT_Wmissing_braces)               \
-  OPT("Wmissing-declarations", CL_C,     OPT_Wmissing_declarations)         \
-  OPT("Wmissing-format-attribute",CL_ALL, OPT_Wmissing_format_attribute)     \
-  OPT("Wmissing-prototypes",   CL_ALL,   OPT_Wmissing_prototypes)           \
-  OPT("Wmultichar",            CL_ALL,   OPT_Wmultichar)                    \
-  OPT("Wnested-externs",       CL_C,     OPT_Wnested_externs)               \
-  OPT("Wnon-template-friend",  CL_CXX,   OPT_Wnon_template_friend)          \
-  OPT("Wnon-virtual-dtor",     CL_CXX,   OPT_Wnon_virtual_dtor)             \
-  OPT("Wnonnull",              CL_C,     OPT_Wnonnull)                      \
-  OPT("Wold-style-cast",       CL_CXX,   OPT_Wold_style_cast)               \
-  OPT("Woverloaded-virtual",   CL_CXX,   OPT_Woverloaded_virtual)           \
-  OPT("Wparentheses",          CL_ALL,   OPT_Wparentheses)                  \
-  OPT("Wpmf-conversions",      CL_CXX,   OPT_Wpmf_conversions)              \
-  OPT("Wpointer-arith",                CL_ALL,   OPT_Wpointer_arith)                \
-  OPT("Wprotocol",             CL_OBJC,  OPT_Wprotocol)                     \
-  OPT("Wredundant-decls",      CL_ALL,   OPT_Wredundant_decls)              \
-  OPT("Wreorder",              CL_CXX,   OPT_Wreorder)                      \
-  OPT("Wreturn-type",          CL_ALL,   OPT_Wreturn_type)                  \
-  OPT("Wselector",             CL_OBJC,  OPT_Wselector)                     \
-  OPT("Wsequence-point",       CL_C,     OPT_Wsequence_point)               \
-  OPT("Wsign-compare",         CL_ALL,   OPT_Wsign_compare)                 \
-  OPT("Wsign-promo",           CL_CXX,   OPT_Wsign_promo)                   \
-  OPT("Wstrict-prototypes",    CL_ALL,   OPT_Wstrict_prototypes)            \
-  OPT("Wsynth",                        CL_CXX,   OPT_Wsynth)                        \
-  OPT("Wsystem-headers",       CL_ALL,   OPT_Wsystem_headers)               \
-  OPT("Wtraditional",          CL_C,     OPT_Wtraditional)                  \
-  OPT("Wtrigraphs",            CL_ALL,   OPT_Wtrigraphs)                    \
-  OPT("Wundeclared-selector",  CL_OBJC,  OPT_Wundeclared_selector)          \
-  OPT("Wundef",                        CL_ALL,   OPT_Wundef)                        \
-  OPT("Wunknown-pragmas",      CL_ALL,   OPT_Wunknown_pragmas)              \
-  OPT("Wunused-macros",                CL_ALL,   OPT_Wunused_macros)                \
-  OPT("Wwrite-strings",                CL_ALL,   OPT_Wwrite_strings)                \
-  OPT("ansi",                  CL_ALL,   OPT_ansi)                          \
-  OPT("d",                      CL_ALL | CL_JOINED, OPT_d)                  \
-  OPT("fabi-version=",          CL_CXX | CL_JOINED, OPT_fabi_version)        \
-  OPT("faccess-control",       CL_CXX,   OPT_faccess_control)               \
-  OPT("fall-virtual",          CL_CXX,   OPT_fall_virtual)                  \
-  OPT("falt-external-templates",CL_CXX,   OPT_falt_external_templates)      \
-  OPT("fasm",                  CL_ALL,   OPT_fasm)                          \
-  OPT("fbuiltin",              CL_ALL,   OPT_fbuiltin)                      \
-  OPT("fbuiltin-",             CL_ALL | CL_JOINED, OPT_fbuiltin_)           \
-  OPT("fcheck-new",            CL_CXX,   OPT_fcheck_new)                    \
-  OPT("fcond-mismatch",                CL_ALL,   OPT_fcond_mismatch)                \
-  OPT("fconserve-space",       CL_CXX,   OPT_fconserve_space)               \
-  OPT("fconst-strings",                CL_CXX,   OPT_fconst_strings)                \
-  OPT("fconstant-string-class=", CL_OBJC | CL_JOINED,                       \
-                                         OPT_fconstant_string_class)        \
-  OPT("fdefault-inline",       CL_CXX,   OPT_fdefault_inline)               \
-  OPT("fdollars-in-identifiers",CL_ALL,   OPT_fdollars_in_identifiers)      \
-  OPT("fdump-",                        CL_ALL | CL_JOINED, OPT_fdump)               \
-  OPT("felide-constructors",   CL_CXX,   OPT_felide_constructors)           \
-  OPT("fenforce-eh-specs",     CL_CXX,   OPT_fenforce_eh_specs)             \
-  OPT("fenum-int-equiv",       CL_CXX,   OPT_fenum_int_equiv)               \
-  OPT("fexternal-templates",   CL_CXX,   OPT_fexternal_templates)           \
-  OPT("ffixed-form",           CL_C,     OPT_ffixed_form)                   \
-  OPT("ffixed-line-length-",   CL_C | CL_JOINED, OPT_ffixed_line_length)    \
-  OPT("ffor-scope",            CL_CXX,   OPT_ffor_scope)                    \
-  OPT("ffreestanding",         CL_C,     OPT_ffreestanding)                 \
-  OPT("fgnu-keywords",         CL_CXX,   OPT_fgnu_keywords)                 \
-  OPT("fgnu-runtime",          CL_OBJC,  OPT_fgnu_runtime)                  \
-  OPT("fguiding-decls",                CL_CXX,   OPT_fguiding_decls)                \
-  OPT("fhandle-exceptions",    CL_CXX,   OPT_fhandle_exceptions)            \
-  OPT("fhonor-std",            CL_CXX,   OPT_fhonor_std)                    \
-  OPT("fhosted",               CL_C,     OPT_fhosted)                       \
-  OPT("fhuge-objects",         CL_CXX,   OPT_fhuge_objects)                 \
-  OPT("fimplement-inlines",    CL_CXX,   OPT_fimplement_inlines)            \
-  OPT("fimplicit-inline-templates", CL_CXX, OPT_fimplicit_inline_templates)  \
-  OPT("fimplicit-templates",   CL_CXX,   OPT_fimplicit_templates)           \
-  OPT("flabels-ok",            CL_CXX,   OPT_flabels_ok)                    \
-  OPT("fms-extensions",                CL_ALL,   OPT_fms_extensions)                \
-  OPT("fname-mangling-version-",CL_CXX | CL_JOINED, OPT_fname_mangling)             \
-  OPT("fnew-abi",              CL_CXX,   OPT_fnew_abi)                      \
-  OPT("fnext-runtime",         CL_OBJC,  OPT_fnext_runtime)                 \
-  OPT("fnonansi-builtins",     CL_CXX,   OPT_fnonansi_builtins)             \
-  OPT("fnonnull-objects",      CL_CXX,   OPT_fnonnull_objects)              \
-  OPT("foperator-names",       CL_CXX,   OPT_foperator_names)               \
-  OPT("foptional-diags",       CL_CXX,   OPT_foptional_diags)               \
-  OPT("fpch-deps",             CL_ALL,   OPT_fpch_deps)                     \
-  OPT("fpermissive",           CL_CXX,   OPT_fpermissive)                   \
-  OPT("fpreprocessed",         CL_ALL,   OPT_fpreprocessed)                 \
-  OPT("frepo",                 CL_CXX,   OPT_frepo)                         \
-  OPT("frtti",                 CL_CXX,   OPT_frtti)                         \
-  OPT("fshort-double",         CL_ALL,   OPT_fshort_double)                 \
-  OPT("fshort-enums",          CL_ALL,   OPT_fshort_enums)                  \
-  OPT("fshort-wchar",          CL_ALL,   OPT_fshort_wchar)                  \
-  OPT("fshow-column",          CL_ALL,   OPT_fshow_column)                  \
-  OPT("fsigned-bitfields",     CL_ALL,   OPT_fsigned_bitfields)             \
-  OPT("fsigned-char",          CL_ALL,   OPT_fsigned_char)                  \
-  OPT("fsquangle",             CL_CXX,   OPT_fsquangle)                     \
-  OPT("fstats",                        CL_CXX,   OPT_fstats)                        \
-  OPT("fstrict-prototype",     CL_CXX,   OPT_fstrict_prototype)             \
-  OPT("ftabstop=",              CL_ALL | CL_JOINED, OPT_ftabstop)           \
-  OPT("ftemplate-depth-",      CL_CXX | CL_JOINED, OPT_ftemplate_depth)     \
-  OPT("fthis-is-variable",     CL_CXX,   OPT_fthis_is_variable)             \
-  OPT("funsigned-bitfields",   CL_ALL,   OPT_funsigned_bitfields)           \
-  OPT("funsigned-char",                CL_ALL,   OPT_funsigned_char)                \
-  OPT("fuse-cxa-atexit",       CL_CXX,   OPT_fuse_cxa_atexit)               \
-  OPT("fvtable-gc",            CL_CXX,   OPT_fvtable_gc)                    \
-  OPT("fvtable-thunks",                CL_CXX,   OPT_fvtable_thunks)                \
-  OPT("fweak",                 CL_CXX,   OPT_fweak)                         \
-  OPT("fxref",                 CL_CXX,   OPT_fxref)                         \
-  OPT("gen-decls",             CL_OBJC,  OPT_gen_decls)                     \
-  OPT("lang-asm",              CL_C_ONLY, OPT_lang_asm)                     \
-  OPT("lang-objc",              CL_ALL,   OPT_lang_objc)                    \
-  OPT("nostdinc",               CL_ALL,   OPT_nostdinc)                             \
-  OPT("nostdinc++",             CL_ALL,   OPT_nostdincplusplus)                     \
-  OPT("o",                     CL_ALL | CL_ARG, OPT_o)                      \
-  OPT("pedantic",              CL_ALL,   OPT_pedantic)                      \
-  OPT("pedantic-errors",       CL_ALL,   OPT_pedantic_errors)               \
-  OPT("print-objc-runtime-info", CL_OBJC, OPT_print_objc_runtime_info)      \
-  OPT("remap",                 CL_ALL,   OPT_remap)                         \
-  OPT("std=c++98",             CL_CXX,   OPT_std_cplusplus98)               \
-  OPT("std=c89",               CL_C,     OPT_std_c89)                       \
-  OPT("std=c99",               CL_C,     OPT_std_c99)                       \
-  OPT("std=c9x",               CL_C,     OPT_std_c9x)                       \
-  OPT("std=gnu++98",           CL_CXX,   OPT_std_gnuplusplus98)             \
-  OPT("std=gnu89",             CL_C,     OPT_std_gnu89)                     \
-  OPT("std=gnu99",             CL_C,     OPT_std_gnu99)                     \
-  OPT("std=gnu9x",             CL_C,     OPT_std_gnu9x)                     \
-  OPT("std=iso9899:1990",      CL_C,     OPT_std_iso9899_1990)              \
-  OPT("std=iso9899:199409",    CL_C,     OPT_std_iso9899_199409)            \
-  OPT("std=iso9899:1999",      CL_C,     OPT_std_iso9899_1999)              \
-  OPT("std=iso9899:199x",      CL_C,     OPT_std_iso9899_199x)              \
-  OPT("traditional-cpp",       CL_ALL,   OPT_traditional_cpp)               \
-  OPT("trigraphs",              CL_ALL,   OPT_trigraphs)                    \
-  OPT("undef",                 CL_ALL,   OPT_undef)                         \
-  OPT("v",                      CL_ALL,   OPT_v)                            \
-  OPT("w",                      CL_ALL,   OPT_w)
-
-#define OPT(text, flags, code) code,
-enum opt_code
-{
-  COMMAND_LINE_OPTIONS
-  N_OPTS
-};
-#undef OPT
+/* Zero disables all standard directories for headers.  */
+static bool std_inc = true;
 
-struct cl_option
-{
-  const char *opt_text;
-  unsigned char opt_len;
-  unsigned char flags;
-  ENUM_BITFIELD (opt_code) opt_code : 2 * CHAR_BIT;
-};
-
-#define OPT(text, flags, code) { text, sizeof(text) - 1, flags, code },
-#ifdef HOST_EBCDIC
-static struct cl_option cl_options[] =
-#else
-static const struct cl_option cl_options[] =
+/* Zero disables the C++-specific standard directories for headers.  */
+static bool std_cxx_inc = true;
+
+/* If the quote chain has been split by -I-.  */
+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_c89 (int, int);
+static void set_std_c99 (int);
+static void check_deps_environment_vars (void);
+static void handle_deferred_opts (void);
+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 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
 #endif
-{
-  COMMAND_LINE_OPTIONS
-};
-#undef OPT
-#undef COMMAND_LINE_OPTIONS
 
-/* Holds switches parsed by c_common_decode_option (), but whose
+/* Holds switches parsed by c_common_handle_option (), but whose
    handling is deferred to c_common_post_options ().  */
-static void defer_opt PARAMS ((enum opt_code, const char *));
+static void defer_opt (enum opt_code, const char *);
 static struct deferred_opt
 {
   enum opt_code code;
   const char *arg;
 } *deferred_opts;
 
-
-#ifdef HOST_EBCDIC
-static int opt_comp PARAMS ((const void *, const void *));
-
-/* Run-time sorting of options array.  */
-static int
-opt_comp (p1, p2)
-     const void *p1, *p2;
-{
-  return strcmp (((struct cl_option *) p1)->opt_text,
-                ((struct cl_option *) p2)->opt_text);
-}
-#endif
-
-/* Complain that switch OPT_INDEX expects an argument but none was
-   provided.  */
-static void
-missing_arg (opt_index)
-     size_t opt_index;
+/* 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
+   one.  */
+bool
+c_common_missing_argument (const char *opt, size_t code)
 {
-  const char *opt_text = cl_options[opt_index].opt_text;
-
-  switch (cl_options[opt_index].opt_code)
+  switch (code)
     {
-    case OPT__output_pch:
-    case OPT_Wformat_eq:
-    case OPT_d:
-    case OPT_fabi_version:
-    case OPT_fbuiltin_:
-    case OPT_fdump:
-    case OPT_fname_mangling:
-    case OPT_ftabstop:
-    case OPT_ftemplate_depth:
     default:
-      error ("missing argument to \"-%s\"", opt_text);
+      /* Pick up the default message.  */
+      return false;
+
+    case OPT_fconstant_string_class_:
+      error ("no class name specified with \"%s\"", opt);
+      break;
+
+    case OPT_A:
+      error ("assertion missing after \"%s\"", opt);
       break;
 
-    case OPT_fconstant_string_class:
-      error ("no class name specified with \"-%s\"", opt_text);
+    case OPT_D:
+    case OPT_U:
+      error ("macro name missing after \"%s\"", opt);
+      break;
+
+    case OPT_F:
+    case OPT_I:
+    case OPT_idirafter:
+    case OPT_isysroot:
+    case OPT_isystem:
+      error ("missing path after \"%s\"", opt);
       break;
 
     case OPT_MF:
     case OPT_MD:
     case OPT_MMD:
+    case OPT_include:
+    case OPT_imacros:
     case OPT_o:
-      error ("missing filename after \"-%s\"", opt_text);
+      error ("missing filename after \"%s\"", opt);
       break;
 
     case OPT_MQ:
     case OPT_MT:
-      error ("missing target after \"-%s\"", opt_text);
+      error ("missing makefile target after \"%s\"", opt);
       break;
     }
-}
-
-/* Perform a binary search to find which option the command-line INPUT
-   matches.  Returns its index in the option array, and N_OPTS on
-   failure.
-
-   Complications arise since some options can be suffixed with an
-   argument, and multiple complete matches can occur, e.g. -pedantic
-   and -pedantic-errors.  Also, some options are only accepted by some
-   languages.  If a switch matches for a different language and
-   doesn't match any alternatives for the true front end, the index of
-   the matched switch is returned anyway.  The caller should check for
-   this case.  */
-static size_t
-find_opt (input, lang_flag)
-     const char *input;
-     int lang_flag;
-{
-  size_t md, mn, mx;
-  size_t opt_len;
-  size_t result = N_OPTS;
-  int comp;
-
-  mn = 0;
-  mx = N_OPTS;
-
-  while (mx > mn)
-    {
-      md = (mn + mx) / 2;
-
-      opt_len = cl_options[md].opt_len;
-      comp = strncmp (input, cl_options[md].opt_text, opt_len);
-
-      if (comp < 0)
-       mx = md;
-      else if (comp > 0)
-       mn = md + 1;
-      else
-       {
-         /* The switch matches.  It it an exact match?  */
-         if (input[opt_len] == '\0')
-           return md;
-         else
-           {
-             mn = md + 1;
-
-             /* If the switch takes no arguments this is not a proper
-                match, so we continue the search (e.g. input="stdc++"
-                match was "stdc").  */
-             if (!(cl_options[md].flags & CL_JOINED))
-               continue;
-
-             /* Is this switch valid for this front end?  */
-             if (!(cl_options[md].flags & lang_flag))
-               {
-                 /* If subsequently we don't find a better match,
-                    return this and let the caller report it as a bad
-                    match.  */
-                 result = md;
-                 continue;
-               }
-
-             /* Two scenarios remain: we have the switch's argument,
-                or we match a longer option.  This can happen with
-                -iwithprefix and -withprefixbefore.  The longest
-                possible option match succeeds.
-
-                Scan forwards, and return an exact match.  Otherwise
-                return the longest valid option-accepting match (mx).
-                This loops at most twice with current options.  */
-             mx = md;
-             for (md = md + 1; md < (size_t) N_OPTS; md++)
-               {
-                 opt_len = cl_options[md].opt_len;
-                 if (strncmp (input, cl_options[md].opt_text, opt_len))
-                   break;
-                 if (input[opt_len] == '\0')
-                   return md;
-                 if (cl_options[md].flags & lang_flag
-                     && cl_options[md].flags & CL_JOINED)
-                   mx = md;
-               }
-
-             return mx;
-           }
-       }
-    }
 
-  return result;
+  return true;
 }
 
 /* Defer option CODE with argument ARG.  */
 static void
-defer_opt (code, arg)
-     enum opt_code code;
-     const char *arg;
+defer_opt (enum opt_code code, const char *arg)
 {
-  /* FIXME: this should be in c_common_init_options, which should take
-     argc and argv.  */
-  if (!deferred_opts)
-    {
-      extern int save_argc;
-      deferred_size = save_argc;
-      deferred_opts = (struct deferred_opt *)
-       xmalloc (deferred_size * sizeof (struct deferred_opt));
-    }
-
-  if (deferred_count == deferred_size)
-    abort ();
-
   deferred_opts[deferred_count].code = code;
   deferred_opts[deferred_count].arg = arg;
   deferred_count++;
 }
 
 /* Common initialization before parsing options.  */
-void
-c_common_init_options (lang)
-     enum c_language_kind lang;
-{
-#ifdef HOST_EBCDIC
-  /* For non-ASCII hosts, the cl_options array needs to be sorted at
-     runtime.  */
-  qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
-#endif
-#if ENABLE_CHECKING
- {
-  size_t i;
-
-  for (i = 1; i < N_OPTS; i++)
-    if (strcmp (cl_options[i - 1].opt_text, cl_options[i].opt_text) >= 0)
-      error ("options array incorrectly sorted: %s is before %s",
-            cl_options[i - 1].opt_text, cl_options[i].opt_text);
- }
-#endif
-
-  c_language = lang;
-  parse_in = cpp_create_reader (lang == clk_c ? CLK_GNUC89 : CLK_GNUCXX);
-  cpp_opts = cpp_get_options (parse_in);
-  if (flag_objc)
-    cpp_opts->objc = 1;
-
-  flag_const_strings = (lang == clk_cplusplus);
-  warn_pointer_arith = (lang == clk_cplusplus);
-  if (lang == clk_c)
-    warn_sign_compare = -1;
-}
-
-/* Handle one command-line option in (argc, argv).
-   Can be called multiple times, to handle multiple sets of options.
-   Returns number of strings consumed.  */
-int
-c_common_decode_option (argc, argv)
-     int argc;
-     char **argv;
+unsigned int
+c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
 {
-  static const int lang_flags[] = {CL_C_ONLY, CL_C, CL_CXX_ONLY, CL_CXX};
-  size_t opt_index;
-  const char *opt, *arg = 0;
-  char *dup = 0;
-  bool on = true;
-  int result, lang_flag;
-  const struct cl_option *option;
-  enum opt_code code;
-
-  opt = argv[0];
-
-  /* Interpret "-" or a non-switch as a file name.  */
-  if (opt[0] != '-' || opt[1] == '\0')
-    {
-      if (!in_fname)
-       in_fname = opt;
-      else if (!out_fname)
-       out_fname = opt;
-      else
-       {
-         error ("too many filenames given.  Type %s --help for usage",
-                progname);
-         return argc;
-       }
-
-      return 1;
-    }
+  static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
+  unsigned int result;
 
-  /* Drop the "no-" from negative switches.  */
-  if ((opt[1] == 'W' || opt[1] == 'f')
-      && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+  /* This is conditionalized only because that is the way the front
+     ends used to do it.  Maybe this should be unconditional?  */
+  if (c_dialect_cxx ())
     {
-      size_t len = strlen (opt) - 3;
-
-      dup = xmalloc (len + 1);
-      dup[0] = '-';
-      dup[1] = opt[1];
-      memcpy (dup + 2, opt + 5, len - 2 + 1);
-      opt = dup;
-      on = false;
+      /* By default wrap lines at 80 characters.  Is getenv
+        ("COLUMNS") preferable?  */
+      diagnostic_line_cutoff (global_dc) = 80;
+      /* By default, emit location information once for every
+        diagnostic message.  */
+      diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
     }
 
-  result = cpp_handle_option (parse_in, argc, argv);
+  parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
+                               ident_hash, &line_table);
 
-  /* Skip over '-'.  */
-  lang_flag = lang_flags[(c_language << 1) + flag_objc];
-  opt_index = find_opt (opt + 1, lang_flag);
-  if (opt_index == N_OPTS)
-    goto done;
+  cpp_opts = cpp_get_options (parse_in);
+  cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
+  cpp_opts->objc = c_dialect_objc ();
 
-  result = 1;
-  option = &cl_options[opt_index];
+  /* Reset to avoid warnings on internal definitions.  We set it just
+     before passing on command-line options to cpplib.  */
+  cpp_opts->warn_dollars = 0;
 
-  /* Sort out any argument the switch takes.  */
-  if (option->flags & CL_ARG)
-    {
-      if (option->flags & CL_JOINED)
-       {
-         /* Have arg point to the original switch.  This is because
-            some code, such as disable_builtin_function, expects its
-            argument to be persistent until the program exits.  */
-         arg = argv[0] + cl_options[opt_index].opt_len + 1;
-         if (!on)
-           arg += strlen ("no-");
-       }
+  flag_const_strings = c_dialect_cxx ();
+  flag_exceptions = c_dialect_cxx ();
+  warn_pointer_arith = c_dialect_cxx ();
 
-      /* If we don't have an argument, and CL_SEPARATE, try the next
-        argument in the vector.  */
-      if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
-       {
-         arg = argv[1];
-         result = 2;
-       }
+  deferred_opts = xmalloc (argc * sizeof (struct deferred_opt));
 
-      if (!arg || *arg == '\0')
-       {
-         missing_arg (opt_index);
-         result = argc;
-         goto done;
-       }
-    }
+  result = lang_flags[c_language];
 
-  /* Complain about the wrong language after we've swallowed any
-     necessary extra argument.  Eventually make this a hard error
-     after the call to find_opt, and return argc.  */
-  if (!(cl_options[opt_index].flags & lang_flag))
+  /* 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" ))
     {
-      complain_wrong_lang (opt_index);
-      goto done;
+      permit_fortran_options = true;
+      result |= CL_F77;
     }
+#endif
 
-  switch (code = option->opt_code)
+  return result;
+}
+
+/* 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).  */
+int
+c_common_handle_option (size_t scode, const char *arg, int value)
+{
+  const struct cl_option *option = &cl_options[scode];
+  enum opt_code code = (enum opt_code) scode;
+  int result = 1;
+
+  switch (code)
     {
-    case N_OPTS: /* Shut GCC up.  */
+    default:
+      result = permit_fortran_options;
       break;
 
-    case OPT__help:
-      print_help ();
+    case OPT__output_pch_:
+      pch_file = arg;
       break;
 
-    case OPT__output_pch:
-      pch_file = arg;
+    case OPT_A:
+      defer_opt (code, arg);
       break;
 
     case OPT_C:
@@ -646,6 +274,10 @@ c_common_decode_option (argc, argv)
       cpp_opts->discard_comments_in_macro_exp = 0;
       break;
 
+    case OPT_D:
+      defer_opt (code, arg);
+      break;
+
     case OPT_E:
       flag_preprocess_only = 1;
       break;
@@ -654,6 +286,22 @@ c_common_decode_option (argc, argv)
       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);
+      else
+       {
+         if (quote_chain_split)
+           error ("-I- specified twice");
+         quote_chain_split = true;
+         split_quote_chain ();
+       }
+      break;
+
     case OPT_M:
     case OPT_MM:
       /* When doing dependencies with -M or -MM, suppress normal
@@ -661,7 +309,7 @@ c_common_decode_option (argc, argv)
         depends on this.  Preprocessed output does occur if -MD, -MMD
         or environment var dependency generation is used.  */
       cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);
-      cpp_opts->no_output = 1;
+      flag_no_output = 1;
       cpp_opts->inhibit_warnings = 1;
       break;
 
@@ -693,310 +341,332 @@ c_common_decode_option (argc, argv)
       break;
 
     case OPT_P:
-      cpp_opts->no_line_commands = 1;
+      flag_no_line_commands = 1;
+      break;
+
+    case OPT_fworking_directory:
+      flag_working_directory = value;
+      break;
+
+    case OPT_U:
+      defer_opt (code, arg);
       break;
 
     case OPT_Wabi:
-      warn_abi = on;
+      warn_abi = value;
       break;
 
     case OPT_Wall:
-      set_Wunused (on);
-      set_Wformat (on);
-      set_Wimplicit (on);
-      warn_char_subscripts = on;
-      warn_missing_braces = on;
-      warn_parentheses = on;
-      warn_return_type = on;
-      warn_sequence_point = on;        /* Was C only.  */
-      warn_sign_compare = on;  /* Was C++ only.  */
-      warn_switch = on;
-      warn_strict_aliasing = on;
-      
+      set_Wunused (value);
+      set_Wformat (value);
+      set_Wimplicit (value);
+      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;
+
       /* Only warn about unknown pragmas that are not in system
-        headers.  */                                        
-      warn_unknown_pragmas = on;
+        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 = (on ? 2 : 0);
+       warn_uninitialized = (value ? 2 : 0);
 
-      if (c_language == clk_c)
+      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 = on * 2;
+       warn_main = value * 2;
       else
        {
          /* C++-specific warnings.  */
-         warn_ctor_dtor_privacy = on;
-         warn_nonvdtor = on;
-         warn_reorder = on;
-         warn_nontemplate_friend = on;
+         warn_nonvdtor = value;
+         warn_reorder = value;
+         warn_nontemplate_friend = value;
        }
 
-      cpp_opts->warn_trigraphs = on;
-      cpp_opts->warn_comments = on;
-      cpp_opts->warn_num_sign_change = on;
-      cpp_opts->warn_multichar = on;   /* Was C++ only.  */
+      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 = on;
+      warn_bad_function_cast = value;
       break;
 
     case OPT_Wcast_qual:
-      warn_cast_qual = on;
+      warn_cast_qual = value;
       break;
 
     case OPT_Wchar_subscripts:
-      warn_char_subscripts = on;
+      warn_char_subscripts = value;
       break;
 
     case OPT_Wcomment:
     case OPT_Wcomments:
-      cpp_opts->warn_comments = on;
+      cpp_opts->warn_comments = value;
       break;
 
     case OPT_Wconversion:
-      warn_conversion = on;
+      warn_conversion = value;
       break;
 
     case OPT_Wctor_dtor_privacy:
-      warn_ctor_dtor_privacy = on;
+      warn_ctor_dtor_privacy = value;
+      break;
+
+    case OPT_Wdeclaration_after_statement:
+      warn_declaration_after_statement = value;
       break;
 
     case OPT_Wdeprecated:
-      warn_deprecated = on;
-      cpp_opts->warn_deprecated = on;
+      warn_deprecated = value;
+      cpp_opts->warn_deprecated = value;
       break;
 
     case OPT_Wdiv_by_zero:
-      warn_div_by_zero = on;
+      warn_div_by_zero = value;
       break;
 
-    case OPT_Weffcxx:
-      warn_ecpp = on;
+    case OPT_Weffc__:
+      warn_ecpp = value;
       break;
 
     case OPT_Wendif_labels:
-      cpp_opts->warn_endif_labels = on;
+      cpp_opts->warn_endif_labels = value;
       break;
 
     case OPT_Werror:
-      cpp_opts->warnings_are_errors = on;
+      cpp_opts->warnings_are_errors = value;
       break;
 
-    case OPT_Werror_implicit_function_decl:
-      if (!on)
-       result = 0;
-      else
-       mesg_implicit_function_declaration = 2;
+    case OPT_Werror_implicit_function_declaration:
+      mesg_implicit_function_declaration = 2;
       break;
 
     case OPT_Wfloat_equal:
-      warn_float_equal = on;
+      warn_float_equal = value;
       break;
 
     case OPT_Wformat:
-      set_Wformat (on);
+      set_Wformat (value);
       break;
 
-    case OPT_Wformat_eq:
+    case OPT_Wformat_:
       set_Wformat (atoi (arg));
       break;
 
     case OPT_Wformat_extra_args:
-      warn_format_extra_args = on;
+      warn_format_extra_args = value;
       break;
 
     case OPT_Wformat_nonliteral:
-      warn_format_nonliteral = on;
+      warn_format_nonliteral = value;
       break;
 
     case OPT_Wformat_security:
-      warn_format_security = on;
+      warn_format_security = value;
       break;
 
     case OPT_Wformat_y2k:
-      warn_format_y2k = on;
+      warn_format_y2k = value;
       break;
 
     case OPT_Wformat_zero_length:
-      warn_format_zero_length = on;
+      warn_format_zero_length = value;
+      break;
+
+    case OPT_Winit_self:
+      warn_init_self = value;
       break;
 
     case OPT_Wimplicit:
-      set_Wimplicit (on);
+      set_Wimplicit (value);
       break;
 
-    case OPT_Wimplicit_function_decl:
-      mesg_implicit_function_declaration = on;
+    case OPT_Wimplicit_function_declaration:
+      mesg_implicit_function_declaration = value;
       break;
 
     case OPT_Wimplicit_int:
-      warn_implicit_int = on;
+      warn_implicit_int = value;
       break;
 
     case OPT_Wimport:
-      cpp_opts->warn_import = on;
+      /* Silently ignore for now.  */
+      break;
+
+    case OPT_Winvalid_offsetof:
+      warn_invalid_offsetof = value;
       break;
 
     case OPT_Winvalid_pch:
-      cpp_opts->warn_invalid_pch = on;
+      cpp_opts->warn_invalid_pch = value;
       break;
 
     case OPT_Wlong_long:
-      warn_long_long = on;
+      warn_long_long = value;
       break;
 
     case OPT_Wmain:
-      if (on)
+      if (value)
        warn_main = 1;
       else
        warn_main = -1;
       break;
 
     case OPT_Wmissing_braces:
-      warn_missing_braces = on;
+      warn_missing_braces = value;
       break;
 
     case OPT_Wmissing_declarations:
-      warn_missing_declarations = on;
+      warn_missing_declarations = value;
       break;
 
     case OPT_Wmissing_format_attribute:
-      warn_missing_format_attribute = on;
+      warn_missing_format_attribute = value;
       break;
 
     case OPT_Wmissing_prototypes:
-      warn_missing_prototypes = on;
+      warn_missing_prototypes = value;
       break;
 
     case OPT_Wmultichar:
-      cpp_opts->warn_multichar = on;
+      cpp_opts->warn_multichar = value;
       break;
 
     case OPT_Wnested_externs:
-      warn_nested_externs = on;
+      warn_nested_externs = value;
       break;
 
     case OPT_Wnon_template_friend:
-      warn_nontemplate_friend = on;
+      warn_nontemplate_friend = value;
       break;
 
     case OPT_Wnon_virtual_dtor:
-      warn_nonvdtor = on;
+      warn_nonvdtor = value;
       break;
 
     case OPT_Wnonnull:
-      warn_nonnull = on;
+      warn_nonnull = value;
+      break;
+
+    case OPT_Wold_style_definition:
+      warn_old_style_definition = value;
       break;
 
     case OPT_Wold_style_cast:
-      warn_old_style_cast = on;
+      warn_old_style_cast = value;
       break;
 
     case OPT_Woverloaded_virtual:
-      warn_overloaded_virtual = on;
+      warn_overloaded_virtual = value;
       break;
 
     case OPT_Wparentheses:
-      warn_parentheses = on;
+      warn_parentheses = value;
       break;
 
     case OPT_Wpmf_conversions:
-      warn_pmf2ptr = on;
+      warn_pmf2ptr = value;
       break;
 
     case OPT_Wpointer_arith:
-      warn_pointer_arith = on;
+      warn_pointer_arith = value;
       break;
 
     case OPT_Wprotocol:
-      warn_protocol = on;
+      warn_protocol = value;
       break;
 
     case OPT_Wselector:
-      warn_selector = on;
+      warn_selector = value;
       break;
 
     case OPT_Wredundant_decls:
-      warn_redundant_decls = on;
+      warn_redundant_decls = value;
       break;
 
     case OPT_Wreorder:
-      warn_reorder = on;
+      warn_reorder = value;
       break;
 
     case OPT_Wreturn_type:
-      warn_return_type = on;
+      warn_return_type = value;
       break;
 
     case OPT_Wsequence_point:
-      warn_sequence_point = on;
+      warn_sequence_point = value;
       break;
 
     case OPT_Wsign_compare:
-      warn_sign_compare = on;
+      warn_sign_compare = value;
       break;
 
     case OPT_Wsign_promo:
-      warn_sign_promo = on;
+      warn_sign_promo = value;
       break;
 
     case OPT_Wstrict_prototypes:
-      if (!on && c_language == clk_cplusplus)
-       warning ("-Wno-strict-prototypes is not supported in C++");
-      else
-       warn_strict_prototypes = on;
+      warn_strict_prototypes = value;
       break;
 
     case OPT_Wsynth:
-      warn_synth = on;
+      warn_synth = value;
       break;
 
     case OPT_Wsystem_headers:
-      cpp_opts->warn_system_headers = on;
+      cpp_opts->warn_system_headers = value;
       break;
 
     case OPT_Wtraditional:
-      warn_traditional = on;
-      cpp_opts->warn_traditional = on;
+      warn_traditional = value;
+      cpp_opts->warn_traditional = value;
       break;
 
     case OPT_Wtrigraphs:
-      cpp_opts->warn_trigraphs = on;
+      cpp_opts->warn_trigraphs = value;
       break;
 
     case OPT_Wundeclared_selector:
-      warn_undeclared_selector = on;
+      warn_undeclared_selector = value;
       break;
 
     case OPT_Wundef:
-      cpp_opts->warn_undef = on;
+      cpp_opts->warn_undef = value;
       break;
 
     case OPT_Wunknown_pragmas:
       /* Set to greater than 1, so that even unknown pragmas in
-        system headers will be warned about.  */  
-      warn_unknown_pragmas = on * 2;
+        system headers will be warned about.  */
+      warn_unknown_pragmas = value * 2;
       break;
 
     case OPT_Wunused_macros:
-      cpp_opts->warn_unused_macros = on;
+      warn_unused_macros = value;
+      break;
+
+    case OPT_Wvariadic_macros:
+      warn_variadic_macros = value;
       break;
 
     case OPT_Wwrite_strings:
-      if (c_language == clk_c)
-       flag_const_strings = on;
+      if (!c_dialect_cxx ())
+       flag_const_strings = value;
       else
-       warn_write_strings = on;
+       warn_write_strings = value;
       break;
-      
+
     case OPT_ansi:
-      if (c_language == clk_c)
+      if (!c_dialect_cxx ())
        set_std_c89 (false, true);
       else
        set_std_cxx98 (true);
@@ -1007,20 +677,22 @@ c_common_decode_option (argc, argv)
       break;
 
     case OPT_fcond_mismatch:
-      if (c_language == clk_c)
+      if (!c_dialect_cxx ())
        {
-         flag_cond_mismatch = on;
+         flag_cond_mismatch = value;
          break;
        }
       /* 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:
     case OPT_flabels_ok:
-    case OPT_fname_mangling:
+    case OPT_fname_mangling_version_:
     case OPT_fnew_abi:
     case OPT_fnonnull_objects:
     case OPT_fsquangle:
@@ -1028,244 +700,275 @@ c_common_decode_option (argc, argv)
     case OPT_fthis_is_variable:
     case OPT_fvtable_thunks:
     case OPT_fxref:
-      warning ("switch \"%s\" is no longer supported", argv[0]);
-      break;
-
-    case OPT_fabi_version:
-      flag_abi_version = read_integral_parameter (arg, argv[0], 1);
+    case OPT_fvtable_gc:
+      warning ("switch \"%s\" is no longer supported", option->opt_text);
       break;
 
     case OPT_faccess_control:
-      flag_access_control = on;
-      break;
-
-    case OPT_falt_external_templates:
-      flag_alt_external_templates = on;
-      if (on)
-       flag_external_templates = true;
-    cp_deprecated:
-      warning ("switch \"%s\" is deprecated, please see documentation for details", argv[0]);
+      flag_access_control = value;
       break;
 
     case OPT_fasm:
-      flag_no_asm = !on;
+      flag_no_asm = !value;
       break;
 
     case OPT_fbuiltin:
-      flag_no_builtin = !on;
+      flag_no_builtin = !value;
       break;
 
     case OPT_fbuiltin_:
-      if (on)
+      if (value)
        result = 0;
       else
        disable_builtin_function (arg);
       break;
 
     case OPT_fdollars_in_identifiers:
-      dollars_in_ident = on;
+      cpp_opts->dollars_in_ident = value;
       break;
 
-    case OPT_fdump:
-      if (!on || !dump_switch_p (argv[0] + strlen ("-f")))
+    case OPT_fdump_:
+      if (!dump_switch_p (arg))
        result = 0;
       break;
 
     case OPT_ffreestanding:
-      on = !on;
-      /* Fall through...  */
+      value = !value;
+      /* Fall through....  */
     case OPT_fhosted:
-      flag_hosted = on;
-      flag_no_builtin = !on;
+      flag_hosted = value;
+      flag_no_builtin = !value;
       /* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */
-      if (!on && warn_main == 2)
+      if (!value && warn_main == 2)
        warn_main = 0;
       break;
 
     case OPT_fshort_double:
-      flag_short_double = on;
+      flag_short_double = value;
       break;
 
     case OPT_fshort_enums:
-      flag_short_enums = on;
+      flag_short_enums = value;
       break;
 
     case OPT_fshort_wchar:
-      flag_short_wchar = on;
+      flag_short_wchar = value;
       break;
 
     case OPT_fsigned_bitfields:
-      flag_signed_bitfields = on;
+      flag_signed_bitfields = value;
       explicit_flag_signed_bitfields = 1;
       break;
 
     case OPT_fsigned_char:
-      flag_signed_char = on;
+      flag_signed_char = value;
       break;
 
     case OPT_funsigned_bitfields:
-      flag_signed_bitfields = !on;
+      flag_signed_bitfields = !value;
       explicit_flag_signed_bitfields = 1;
       break;
 
     case OPT_funsigned_char:
-      flag_signed_char = !on;
+      flag_signed_char = !value;
       break;
 
     case OPT_fcheck_new:
-      flag_check_new = on;
+      flag_check_new = value;
       break;
 
     case OPT_fconserve_space:
-      flag_conserve_space = on;
+      flag_conserve_space = value;
       break;
 
     case OPT_fconst_strings:
-      flag_const_strings = on;
+      flag_const_strings = value;
       break;
 
-    case OPT_fconstant_string_class:
+    case OPT_fconstant_string_class_:
       constant_string_class_name = arg;
       break;
 
     case OPT_fdefault_inline:
-      flag_default_inline = on;
+      flag_default_inline = value;
       break;
 
     case OPT_felide_constructors:
-      flag_elide_constructors = on;
+      flag_elide_constructors = value;
       break;
 
     case OPT_fenforce_eh_specs:
-      flag_enforce_eh_specs = on;
+      flag_enforce_eh_specs = value;
       break;
 
-    case OPT_fexternal_templates:
-      flag_external_templates = on;
-      goto cp_deprecated;
-
     case OPT_ffixed_form:
-    case OPT_ffixed_line_length:
+    case OPT_ffixed_line_length_:
       /* Fortran front end options ignored when preprocessing only.  */
-      if (flag_preprocess_only)
-        result = -1;
+      if (!flag_preprocess_only)
+        result = 0;
       break;
 
     case OPT_ffor_scope:
-      flag_new_for_scope = on;
+      flag_new_for_scope = value;
       break;
 
     case OPT_fgnu_keywords:
-      flag_no_gnu_keywords = !on;
+      flag_no_gnu_keywords = !value;
       break;
 
     case OPT_fgnu_runtime:
-      flag_next_runtime = !on;
+      flag_next_runtime = !value;
       break;
 
     case OPT_fhandle_exceptions:
-      warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
-      flag_exceptions = on;
+      warning ("-fhandle-exceptions has been renamed -fexceptions (and is now on by default)");
+      flag_exceptions = value;
       break;
 
     case OPT_fimplement_inlines:
-      flag_implement_inlines = on;
+      flag_implement_inlines = value;
       break;
 
     case OPT_fimplicit_inline_templates:
-      flag_implicit_inline_templates = on;
+      flag_implicit_inline_templates = value;
       break;
 
     case OPT_fimplicit_templates:
-      flag_implicit_templates = on;
+      flag_implicit_templates = value;
       break;
 
     case OPT_fms_extensions:
-      flag_ms_extensions = on;
+      flag_ms_extensions = value;
       break;
 
     case OPT_fnext_runtime:
-      flag_next_runtime = on;
+      flag_next_runtime = value;
+      break;
+
+    case OPT_fnil_receivers:
+      flag_nil_receivers = value;
       break;
 
     case OPT_fnonansi_builtins:
-      flag_no_nonansi_builtin = !on;
+      flag_no_nonansi_builtin = !value;
+      break;
+
+    case OPT_fobjc_exceptions:
+      flag_objc_exceptions = value;
       break;
 
     case OPT_foperator_names:
-      cpp_opts->operator_names = on;
+      cpp_opts->operator_names = value;
       break;
 
     case OPT_foptional_diags:
-      flag_optional_diags = on;
+      flag_optional_diags = value;
       break;
 
     case OPT_fpch_deps:
-      cpp_opts->restore_pch_deps = on;
+      cpp_opts->restore_pch_deps = value;
       break;
 
     case OPT_fpermissive:
-      flag_permissive = on;
+      flag_permissive = value;
       break;
 
     case OPT_fpreprocessed:
-      cpp_opts->preprocessed = on;
+      cpp_opts->preprocessed = value;
       break;
 
+    case OPT_freplace_objc_classes:
+      flag_replace_objc_classes = value;
+      break;
+      
     case OPT_frepo:
-      flag_use_repository = on;
-      if (on)
+      flag_use_repository = value;
+      if (value)
        flag_implicit_templates = 0;
       break;
 
     case OPT_frtti:
-      flag_rtti = on;
+      flag_rtti = value;
       break;
 
     case OPT_fshow_column:
-      cpp_opts->show_column = on;
+      cpp_opts->show_column = value;
       break;
 
     case OPT_fstats:
-      flag_detailed_statistics = on;
+      flag_detailed_statistics = value;
       break;
 
-    case OPT_ftabstop:
-      /* Don't recognize -fno-tabstop=.  */
-      if (!on)
-       return 0;
-
+    case OPT_ftabstop_:
       /* It is documented that we silently ignore silly values.  */
-       {
-         char *endptr;
-         long tabstop = strtol (arg, &endptr, 10);
-         if (*endptr == '\0' && tabstop >= 1 && tabstop <= 100)
-           cpp_opts->tabstop = tabstop;
-       }
+      if (value >= 1 && value <= 100)
+       cpp_opts->tabstop = value;
       break;
 
-    case OPT_ftemplate_depth:
-      max_tinst_depth = read_integral_parameter (arg, argv[0], 0);
+    case OPT_fexec_charset_:
+      cpp_opts->narrow_charset = arg;
       break;
 
-    case OPT_fvtable_gc:
-      flag_vtable_gc = on;
+    case OPT_fwide_exec_charset_:
+      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;
 
     case OPT_fuse_cxa_atexit:
-      flag_use_cxa_atexit = on;
+      flag_use_cxa_atexit = value;
       break;
 
     case OPT_fweak:
-      flag_weak = on;
+      flag_weak = 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);
+      break;
+
+    case OPT_imacros:
+    case OPT_include:
+      defer_opt (code, arg);
+      break;
+
+    case OPT_iprefix:
+      iprefix = arg;
+      break;
+
+    case OPT_isysroot:
+      sysroot = arg;
+      break;
+
+    case OPT_isystem:
+      add_path (xstrdup (arg), SYSTEM, 0);
+      break;
+
+    case OPT_iwithprefix:
+      add_prefixed_path (arg, SYSTEM);
+      break;
+
+    case OPT_iwithprefixbefore:
+      add_prefixed_path (arg, BRACKET);
+      break;
+
     case OPT_lang_asm:
       cpp_set_lang (parse_in, CLK_ASM);
+      cpp_opts->dollars_in_ident = false;
       break;
 
     case OPT_lang_objc:
@@ -1273,24 +976,18 @@ c_common_decode_option (argc, argv)
       break;
 
     case OPT_nostdinc:
-      /* No default include directories.  You must specify all
-        include-file directories with -I.  */
-      cpp_opts->no_standard_includes = 1;
+      std_inc = false;
       break;
 
-    case OPT_nostdincplusplus:
-      /* No default C++-specific include directories.  */
-      cpp_opts->no_standard_cplusplus_includes = 1;
+    case OPT_nostdinc__:
+      std_cxx_inc = false;
       break;
 
     case OPT_o:
       if (!out_fname)
        out_fname = arg;
       else
-       {
-         error ("output filename specified twice");
-         result = argc;
-       }
+       error ("output filename specified twice");
       break;
 
       /* We need to handle the -pedantic switches here, rather than in
@@ -1298,7 +995,7 @@ c_common_decode_option (argc, argv)
         is not overridden.  */
     case OPT_pedantic_errors:
       cpp_opts->pedantic_errors = 1;
-      /* fall through */
+      /* Fall through.  */
     case OPT_pedantic:
       cpp_opts->pedantic = 1;
       cpp_opts->warn_endif_labels = 1;
@@ -1312,9 +1009,9 @@ c_common_decode_option (argc, argv)
       cpp_opts->remap = 1;
       break;
 
-    case OPT_std_cplusplus98:
-    case OPT_std_gnuplusplus98:
-      set_std_cxx98 (code == OPT_std_cplusplus98 /* ISO */);
+    case OPT_std_c__98:
+    case OPT_std_gnu__98:
+      set_std_cxx98 (code == OPT_std_c__98 /* ISO */);
       break;
 
     case OPT_std_c89:
@@ -1356,23 +1053,27 @@ c_common_decode_option (argc, argv)
       break;
 
     case OPT_v:
-      cpp_opts->verbose = 1;
+      verbose = true;
       break;
     }
 
- done:
-  if (dup)
-    free (dup);
   return result;
 }
 
 /* Post-switch processing.  */
 bool
-c_common_post_options ()
+c_common_post_options (const char **pfilename)
 {
+  struct cpp_callbacks *cb;
+
   /* Canonicalize the input and output filenames.  */
-  if (in_fname == NULL || !strcmp (in_fname, "-"))
-    in_fname = "";
+  if (in_fnames == NULL)
+    {
+      in_fnames = xmalloc (sizeof (in_fnames[0]));
+      in_fnames[0] = "";
+    }
+  else if (strcmp (in_fnames[0], "-") == 0)
+    in_fnames[0] = "";
 
   if (out_fname == NULL || !strcmp (out_fname, "-"))
     out_fname = "";
@@ -1384,6 +1085,9 @@ c_common_post_options ()
 
   sanitize_cpp_opts ();
 
+  register_include_chains (parse_in, sysroot, iprefix,
+                          std_inc, std_cxx_inc && c_dialect_cxx (), verbose);
+
   flag_inline_trees = 1;
 
   /* Use tree inlining if possible.  Function instrumentation is only
@@ -1399,6 +1103,11 @@ c_common_post_options ()
        }
     }
 
+  /* -Wextra implies -Wsign-compare, but not if explicitly
+      overridden.  */
+  if (warn_sign_compare == -1)
+    warn_sign_compare = extra_warnings;
+
   /* Special format checking options don't work without -Wformat; warn if
      they are used.  */
   if (warn_format_y2k && !warn_format)
@@ -1414,36 +1123,66 @@ c_common_post_options ()
   if (warn_missing_format_attribute && !warn_format)
     warning ("-Wmissing-format-attribute ignored without -Wformat");
 
+  if (flag_preprocess_only)
+    {
+      /* Open the output now.  We must do so even if flag_no_output is
+        on, because there may be other output than from the actual
+        preprocessing (e.g. from -dM).  */
+      if (out_fname[0] == '\0')
+       out_stream = stdout;
+      else
+       out_stream = fopen (out_fname, "w");
+
+      if (out_stream == NULL)
+       {
+         fatal_error ("opening output file %s: %m", out_fname);
+         return false;
+       }
+
+      if (num_in_fnames > 1)
+       error ("too many filenames given.  Type %s --help for usage",
+              progname);
+
+      init_pp_output (out_stream);
+    }
+  else
+    {
+      init_c_lex ();
+
+      /* Yuk.  WTF is this?  I do know ObjC relies on it somewhere.  */
+      input_line = 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;
+
   /* If an error has occurred in cpplib, note it so we fail
      immediately.  */
   errorcount += cpp_errors (parse_in);
 
-  return flag_preprocess_only;
-}
+  *pfilename = this_input_filename
+    = cpp_read_main_file (parse_in, in_fnames[0]);
+  if (this_input_filename == NULL)
+    return true;
 
-/* Preprocess the input file to out_stream.  */
-static void
-preprocess_file ()
-{
-  /* Open the output now.  We must do so even if no_output is on,
-     because there may be other output than from the actual
-     preprocessing (e.g. from -dM).  */
-  if (out_fname[0] == '\0')
-    out_stream = stdout;
-  else
-    out_stream = fopen (out_fname, "w");
+  if (flag_working_directory
+      && flag_preprocess_only && ! flag_no_line_commands)
+    pp_dir_change (parse_in, get_src_pwd ());
 
-  if (out_stream == NULL)
-    fatal_io_error ("opening output file %s", out_fname);
-  else
-    cpp_preprocess_file (parse_in, in_fname, out_stream);
+  return flag_preprocess_only;
 }
 
 /* Front end initialization common to C, ObjC and C++.  */
-const char *
-c_common_init (filename)
-     const char *filename;
+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);
@@ -1451,31 +1190,68 @@ c_common_init (filename)
   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->bytes_big_endian = BYTES_BIG_ENDIAN;
 
-  /* Register preprocessor built-ins before calls to
-     cpp_main_file.  */
-  cpp_get_callbacks (parse_in)->register_builtins = cb_register_builtins;
+  /* This can't happen until after wchar_precision and bytes_big_endian
+     are known.  */
+  cpp_init_iconv (parse_in);
 
-  /* NULL is passed up to toplev.c and we exit quickly.  */
   if (flag_preprocess_only)
     {
-      preprocess_file ();
-      return NULL;
+      finish_options ();
+      preprocess_file (parse_in);
+      return false;
     }
 
-  /* Do this before initializing pragmas, as then cpplib's hash table
-     has been set up.  NOTE: we are using our own file name here, not
-     the one supplied.  */
-  filename = init_c_lex (in_fname);
-
+  /* Has to wait until now so that cpplib has its hash table.  */
   init_pragma ();
 
-  return filename;
+  return true;
+}
+
+/* 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)
+{
+  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();
+
+         /* Reset cpplib's macros and start a new file.  */
+         cpp_undef_all (parse_in);
+         main_input_filename = this_input_filename
+           = cpp_read_main_file (parse_in, in_fnames[file_index]);
+         if (this_input_filename == NULL)
+           break;
+       }
+      finish_options ();
+      if (file_index == 0)
+       pch_init();
+      c_parse_file ();
+
+      file_index++;
+    } while (file_index < num_in_fnames);
+  
+  finish_file ();
 }
 
 /* Common finish hook for the C, ObjC and C++ front ends.  */
 void
-c_common_finish ()
+c_common_finish (void)
 {
   FILE *deps_stream = NULL;
 
@@ -1489,7 +1265,7 @@ c_common_finish ()
        {
          deps_stream = fopen (deps_file, deps_append ? "a": "w");
          if (!deps_stream)
-           fatal_io_error ("opening dependency file %s", deps_file);
+           fatal_error ("opening dependency file %s: %m", deps_file);
        }
     }
 
@@ -1499,10 +1275,10 @@ c_common_finish ()
 
   if (deps_stream && deps_stream != out_stream
       && (ferror (deps_stream) || fclose (deps_stream)))
-    fatal_io_error ("closing dependency file %s", deps_file);
+    fatal_error ("closing dependency file %s: %m", deps_file);
 
   if (out_stream && (ferror (out_stream) || fclose (out_stream)))
-    fatal_io_error ("when writing output to %s", out_fname);
+    fatal_error ("when writing output to %s: %m", out_fname);
 }
 
 /* Either of two environment variables can specify output of
@@ -1513,7 +1289,7 @@ c_common_finish ()
    rather than overwriting it, and like Sun's compiler
    SUNPRO_DEPENDENCIES suppresses the dependency on the main file.  */
 static void
-check_deps_environment_vars ()
+check_deps_environment_vars (void)
 {
   char *spec;
 
@@ -1551,7 +1327,7 @@ check_deps_environment_vars ()
 
 /* Handle deferred command line switches.  */
 static void
-handle_deferred_opts ()
+handle_deferred_opts (void)
 {
   size_t i;
 
@@ -1559,25 +1335,15 @@ handle_deferred_opts ()
     {
       struct deferred_opt *opt = &deferred_opts[i];
 
-      switch (opt->code)
-       {
-       case OPT_MT:
-       case OPT_MQ:
-         cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ);
-         break;
-
-       default:
-         abort ();
-       }
+      if (opt->code == OPT_MT || opt->code == OPT_MQ)
+       cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ);
     }
-
-  free (deferred_opts);
 }
 
 /* These settings are appropriate for GCC, but not necessarily so for
    cpplib as a library.  */
 static void
-sanitize_cpp_opts ()
+sanitize_cpp_opts (void)
 {
   /* If we don't know what style of dependencies to output, complain
      if any other dependency switches have been given.  */
@@ -1586,16 +1352,16 @@ sanitize_cpp_opts ()
 
   /* -dM and dependencies suppress normal output; do it here so that
      the last -d[MDN] switch overrides earlier ones.  */
-  if (cpp_opts->dump_macros == dump_only)
-    cpp_opts->no_output = 1;
+  if (flag_dump_macros == 'M')
+    flag_no_output = 1;
 
   /* Disable -dD, -dN and -dI if normal output is suppressed.  Allow
      -dM since at least glibc relies on -M -dM to work.  */
-  if (cpp_opts->no_output)
+  if (flag_no_output)
     {
-      if (cpp_opts->dump_macros != dump_only)
-       cpp_opts->dump_macros = dump_none;
-      cpp_opts->dump_includes = 0;
+      if (flag_dump_macros != 'M')
+       flag_dump_macros = 0;
+      flag_dump_includes = 0;
     }
 
   cpp_opts->unsigned_char = !flag_signed_char;
@@ -1605,56 +1371,188 @@ sanitize_cpp_opts ()
      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.  */
+static void
+add_prefixed_path (const char *suffix, size_t chain)
+{
+  char *path;
+  const char *prefix;
+  size_t prefix_len, suffix_len;
+
+  suffix_len = strlen (suffix);
+  prefix     = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR;
+  prefix_len = iprefix ? strlen (iprefix) : cpp_GCC_INCLUDE_DIR_len;
+
+  path = 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);
+}
+
+/* Handle -D, -U, -A, -imacros, and the first -include.  */
+static void
+finish_options (void)
+{
+  if (!cpp_opts->preprocessed)
+    {
+      size_t i;
+
+      cpp_change_file (parse_in, LC_RENAME, _("<built-in>"));
+      cpp_init_builtins (parse_in, flag_hosted);
+      c_cpp_builtins (parse_in);
+
+      /* We're about to send user input to cpplib, so make it warn for
+        things that we previously (when we sent it internal definitions)
+        told it to not warn.
+
+        C99 permits implementation-defined characters in identifiers.
+        The documented meaning of -std= is to turn off extensions that
+        conflict with the specified standard, and since a strictly
+        conforming program cannot contain a '$', we do not condition
+        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>"));
+      for (i = 0; i < deferred_count; i++)
+       {
+         struct deferred_opt *opt = &deferred_opts[i];
+
+         if (opt->code == OPT_D)
+           cpp_define (parse_in, opt->arg);
+         else if (opt->code == OPT_U)
+           cpp_undef (parse_in, opt->arg);
+         else if (opt->code == OPT_A)
+           {
+             if (opt->arg[0] == '-')
+               cpp_unassert (parse_in, opt->arg + 1);
+             else
+               cpp_assert (parse_in, opt->arg);
+           }
+       }
+
+      /* Handle -imacros after -D and -U.  */
+      for (i = 0; i < deferred_count; i++)
+       {
+         struct deferred_opt *opt = &deferred_opts[i];
+
+         if (opt->code == OPT_imacros
+             && cpp_push_include (parse_in, opt->arg))
+           {
+             /* Disable push_command_line_include callback for now.  */
+             include_cursor = deferred_count + 1;
+             cpp_scan_nooutput (parse_in);
+           }
+       }
+    }
+
+  include_cursor = 0;
+  push_command_line_include ();
+}
+
+/* Give CPP the next file given by -include, if any.  */
+static void
+push_command_line_include (void)
+{
+  while (include_cursor < deferred_count)
+    {
+      struct deferred_opt *opt = &deferred_opts[include_cursor++];
+
+      if (! cpp_opts->preprocessed && opt->code == OPT_include
+         && cpp_push_include (parse_in, opt->arg))
+       return;
+    }
+
+  if (include_cursor == deferred_count)
+    {
+      include_cursor++;
+      /* -Wunused-macros should only warn about macros defined hereafter.  */
+      cpp_opts->warn_unused_macros = warn_unused_macros;
+      /* Restore the line map from <command line>.  */
+      if (! cpp_opts->preprocessed)
+       cpp_change_file (parse_in, LC_RENAME, main_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,
+               const struct line_map *new_map)
+{
+  if (flag_preprocess_only)
+    pp_file_change (new_map);
+  else
+    fe_file_change (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 *pfile ATTRIBUTE_UNUSED, const char *dir)
+{
+  if (! set_src_pwd (dir))
+    warning ("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
-set_std_c89 (c94, iso)
-     int c94, iso;
+set_std_c89 (int c94, int iso)
 {
   cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89);
   flag_iso = 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).  */
 static void
-set_std_c99 (iso)
-     int iso;
+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).  */
 static void
-set_std_cxx98 (iso)
-     int iso;
+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;
 }
 
 /* Handle setting implicit to ON.  */
 static void
-set_Wimplicit (on)
-     int on;
+set_Wimplicit (int on)
 {
   warn_implicit = on;
   warn_implicit_int = on;
@@ -1670,146 +1568,21 @@ set_Wimplicit (on)
 /* Args to -d specify what to dump.  Silently ignore
    unrecognized options; they may be aimed at toplev.c.  */
 static void
-handle_OPT_d (arg)
-     const char *arg;
+handle_OPT_d (const char *arg)
 {
   char c;
 
   while ((c = *arg++) != '\0')
     switch (c)
       {
-      case 'M':
-       cpp_opts->dump_macros = dump_only;
-       break;
-
-      case 'N':
-       cpp_opts->dump_macros = dump_names;
-       break;
-
-      case 'D':
-       cpp_opts->dump_macros = dump_definitions;
+      case 'M':                        /* Dump macros only.  */
+      case 'N':                        /* Dump names.  */
+      case 'D':                        /* Dump definitions.  */
+       flag_dump_macros = c;
        break;
 
       case 'I':
-       cpp_opts->dump_includes = 1;
+       flag_dump_includes = 1;
        break;
       }
 }
-
-/* Write a slash-separated list of languages in FLAGS to BUF.  */
-static void
-write_langs (buf, flags)
-     char *buf;
-     int flags;
-{
-  *buf = '\0';
-  if (flags & CL_C_ONLY)
-    strcat (buf, "C");
-  if (flags & CL_OBJC_ONLY)
-    {
-      if (*buf)
-       strcat (buf, "/");
-      strcat (buf, "ObjC");
-    }
-  if (flags & CL_CXX_ONLY)
-    {
-      if (*buf)
-       strcat (buf, "/");
-      strcat (buf, "C++");
-    }
-}
-
-/* Complain that switch OPT_INDEX does not apply to this front end.  */
-static void
-complain_wrong_lang (opt_index)
-     size_t opt_index;
-{
-  char ok_langs[60], bad_langs[60];
-  int ok_flags = cl_options[opt_index].flags;
-
-  write_langs (ok_langs, ok_flags);
-  write_langs (bad_langs, ~ok_flags);
-  warning ("\"-%s\" is valid for %s but not for %s",
-          cl_options[opt_index].opt_text, ok_langs, bad_langs);
-}
-
-/* Handle --help output.  */
-static void
-print_help ()
-{
-  /* To keep the lines from getting too long for some compilers, limit
-     to about 500 characters (6 lines) per chunk.  */
-  fputs (_("\
-Switches:\n\
-  -include <file>           Include the contents of <file> before other files\n\
-  -imacros <file>           Accept definition of macros in <file>\n\
-  -iprefix <path>           Specify <path> as a prefix for next two options\n\
-  -iwithprefix <dir>        Add <dir> to the end of the system include path\n\
-  -iwithprefixbefore <dir>  Add <dir> to the end of the main include path\n\
-  -isystem <dir>            Add <dir> to the start of the system include path\n\
-"), stdout);
-  fputs (_("\
-  -idirafter <dir>          Add <dir> to the end of the system include path\n\
-  -I <dir>                  Add <dir> to the end of the main include path\n\
-  -I-                       Fine-grained include path control; see info docs\n\
-  -nostdinc                 Do not search system include directories\n\
-                             (dirs specified with -isystem will still be used)\n\
-  -nostdinc++               Do not search system include directories for C++\n\
-  -o <file>                 Put output into <file>\n\
-"), stdout);
-  fputs (_("\
-  -trigraphs                Support ISO C trigraphs\n\
-  -std=<std name>           Specify the conformance standard; one of:\n\
-                            gnu89, gnu99, c89, c99, iso9899:1990,\n\
-                            iso9899:199409, iso9899:1999, c++98\n\
-  -w                        Inhibit warning messages\n\
-  -W[no-]trigraphs          Warn if trigraphs are encountered\n\
-  -W[no-]comment{s}         Warn if one comment starts inside another\n\
-"), stdout);
-  fputs (_("\
-  -W[no-]traditional        Warn about features not present in traditional C\n\
-  -W[no-]undef              Warn if an undefined macro is used by #if\n\
-  -W[no-]import             Warn about the use of the #import directive\n\
-"), stdout);
-  fputs (_("\
-  -W[no-]error              Treat all warnings as errors\n\
-  -W[no-]system-headers     Do not suppress warnings from system headers\n\
-  -W[no-]all                Enable most preprocessor warnings\n\
-"), stdout);
-  fputs (_("\
-  -M                        Generate make dependencies\n\
-  -MM                       As -M, but ignore system header files\n\
-  -MD                       Generate make dependencies and compile\n\
-  -MMD                      As -MD, but ignore system header files\n\
-  -MF <file>                Write dependency output to the given file\n\
-  -MG                       Treat missing header file as generated files\n\
-"), stdout);
-  fputs (_("\
-  -MP                      Generate phony targets for all headers\n\
-  -MQ <target>              Add a MAKE-quoted target\n\
-  -MT <target>              Add an unquoted target\n\
-"), stdout);
-  fputs (_("\
-  -D<macro>                 Define a <macro> with string '1' as its value\n\
-  -D<macro>=<val>           Define a <macro> with <val> as its value\n\
-  -A<question>=<answer>     Assert the <answer> to <question>\n\
-  -A-<question>=<answer>    Disable the <answer> to <question>\n\
-  -U<macro>                 Undefine <macro> \n\
-  -v                        Display the version number\n\
-"), stdout);
-  fputs (_("\
-  -H                        Print the name of header files as they are used\n\
-  -C                        Do not discard comments\n\
-  -dM                       Display a list of macro definitions active at end\n\
-  -dD                       Preserve macro definitions in output\n\
-  -dN                       As -dD except that only the names are preserved\n\
-  -dI                       Include #include directives in the output\n\
-"), stdout);
-  fputs (_("\
-  -f[no-]preprocessed       Treat the input file as already preprocessed\n\
-  -ftabstop=<number>        Distance between tab stops for column reporting\n\
-  -P                        Do not generate #line directives\n\
-  -remap                    Remap file names when including files\n\
-  --help                    Display this information\n\
-"), stdout);
-}