summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/c-opts.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/c-opts.c')
-rw-r--r--contrib/gcc/c-opts.c1799
1 files changed, 1799 insertions, 0 deletions
diff --git a/contrib/gcc/c-opts.c b/contrib/gcc/c-opts.c
new file mode 100644
index 0000000..77a468a
--- /dev/null
+++ b/contrib/gcc/c-opts.c
@@ -0,0 +1,1799 @@
+/* C/ObjC/C++ command line option handling.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Neil Booth.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "tree.h"
+#include "c-common.h"
+#include "c-pragma.h"
+#include "flags.h"
+#include "toplev.h"
+#include "langhooks.h"
+#include "tree-inline.h"
+#include "diagnostic.h"
+#include "intl.h"
+
+/* CPP's options. */
+static cpp_options *cpp_opts;
+
+/* Input filename. */
+static const char *in_fname;
+
+/* Filename and stream for preprocessed output. */
+static const char *out_fname;
+static FILE *out_stream;
+
+/* Append dependencies to deps_file. */
+static bool deps_append;
+
+/* If dependency switches (-MF etc.) have been given. */
+static bool deps_seen;
+
+/* 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, int));
+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));
+
+#ifndef STDC_0_IN_SYSTEM_HEADERS
+#define STDC_0_IN_SYSTEM_HEADERS 0
+#endif
+
+#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("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("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("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
+
+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[] =
+#endif
+{
+ COMMAND_LINE_OPTIONS
+};
+#undef OPT
+#undef COMMAND_LINE_OPTIONS
+
+/* Holds switches parsed by c_common_decode_option (), but whose
+ handling is deffered to c_common_post_options (). */
+static void defer_opt PARAMS ((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;
+{
+ const char *opt_text = cl_options[opt_index].opt_text;
+
+ switch (cl_options[opt_index].opt_code)
+ {
+ 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);
+ break;
+
+ case OPT_fconstant_string_class:
+ error ("no class name specified with \"-%s\"", opt_text);
+ break;
+
+ case OPT_MF:
+ case OPT_MD:
+ case OPT_MMD:
+ case OPT_o:
+ error ("missing filename after \"-%s\"", opt_text);
+ break;
+
+ case OPT_MQ:
+ case OPT_MT:
+ error ("missing target after \"-%s\"", opt_text);
+ 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;
+}
+
+/* Defer option CODE with argument ARG. */
+static void
+defer_opt (code, arg)
+ 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;
+{
+ 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;
+ }
+
+ /* Drop the "no-" from negative switches. */
+ if ((opt[1] == 'W' || opt[1] == 'f')
+ && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+ {
+ 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;
+ }
+
+ result = cpp_handle_option (parse_in, argc, argv);
+
+ /* 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;
+
+ result = 1;
+ option = &cl_options[opt_index];
+
+ /* 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-");
+ }
+
+ /* 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;
+ }
+
+ if (!arg || *arg == '\0')
+ {
+ missing_arg (opt_index);
+ result = argc;
+ goto done;
+ }
+ }
+
+ /* 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))
+ {
+ complain_wrong_lang (opt_index, on);
+ goto done;
+ }
+
+ switch (code = option->opt_code)
+ {
+ case N_OPTS: /* Shut GCC up. */
+ break;
+
+ case OPT__help:
+ print_help ();
+ break;
+
+ case OPT_C:
+ cpp_opts->discard_comments = 0;
+ break;
+
+ case OPT_CC:
+ cpp_opts->discard_comments = 0;
+ cpp_opts->discard_comments_in_macro_exp = 0;
+ break;
+
+ case OPT_E:
+ flag_preprocess_only = 1;
+ break;
+
+ case OPT_H:
+ cpp_opts->print_include_names = 1;
+ break;
+
+ case OPT_M:
+ case OPT_MM:
+ /* When doing dependencies with -M or -MM, suppress normal
+ preprocessed output, but still do -dM etc. as software
+ 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;
+ cpp_opts->inhibit_warnings = 1;
+ break;
+
+ case OPT_MD:
+ case OPT_MMD:
+ cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER);
+ deps_file = arg;
+ break;
+
+ case OPT_MF:
+ deps_seen = true;
+ deps_file = arg;
+ break;
+
+ case OPT_MG:
+ deps_seen = true;
+ cpp_opts->deps.missing_files = true;
+ break;
+
+ case OPT_MP:
+ deps_seen = true;
+ cpp_opts->deps.phony_targets = true;
+ break;
+
+ case OPT_MQ:
+ case OPT_MT:
+ deps_seen = true;
+ defer_opt (code, arg);
+ break;
+
+ case OPT_P:
+ cpp_opts->no_line_commands = 1;
+ break;
+
+ case OPT_Wabi:
+ warn_abi = on;
+ 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. */
+ if (c_language == clk_cplusplus)
+ warn_sign_compare = on;
+ warn_switch = on;
+ warn_strict_aliasing = on;
+
+ /* Only warn about unknown pragmas that are not in system
+ headers. */
+ warn_unknown_pragmas = on;
+
+ /* 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);
+
+ if (c_language == clk_c)
+ /* 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;
+ else
+ {
+ /* C++-specific warnings. */
+ warn_ctor_dtor_privacy = on;
+ warn_nonvdtor = on;
+ warn_reorder = on;
+ warn_nontemplate_friend = on;
+ }
+
+ 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. */
+ break;
+
+ case OPT_Wbad_function_cast:
+ warn_bad_function_cast = on;
+ break;
+
+ case OPT_Wcast_qual:
+ warn_cast_qual = on;
+ break;
+
+ case OPT_Wchar_subscripts:
+ warn_char_subscripts = on;
+ break;
+
+ case OPT_Wcomment:
+ case OPT_Wcomments:
+ cpp_opts->warn_comments = on;
+ break;
+
+ case OPT_Wconversion:
+ warn_conversion = on;
+ break;
+
+ case OPT_Wctor_dtor_privacy:
+ warn_ctor_dtor_privacy = on;
+ break;
+
+ case OPT_Wdeprecated:
+ warn_deprecated = on;
+ break;
+
+ case OPT_Wdiv_by_zero:
+ warn_div_by_zero = on;
+ break;
+
+ case OPT_Weffcxx:
+ warn_ecpp = on;
+ break;
+
+ case OPT_Wendif_labels:
+ cpp_opts->warn_endif_labels = on;
+ break;
+
+ case OPT_Werror:
+ cpp_opts->warnings_are_errors = on;
+ break;
+
+ case OPT_Werror_implicit_function_decl:
+ if (!on)
+ result = 0;
+ else
+ mesg_implicit_function_declaration = 2;
+ break;
+
+ case OPT_Wfloat_equal:
+ warn_float_equal = on;
+ break;
+
+ case OPT_Wformat:
+ set_Wformat (on);
+ break;
+
+ case OPT_Wformat_eq:
+ set_Wformat (atoi (arg));
+ break;
+
+ case OPT_Wformat_extra_args:
+ warn_format_extra_args = on;
+ break;
+
+ case OPT_Wformat_nonliteral:
+ warn_format_nonliteral = on;
+ break;
+
+ case OPT_Wformat_security:
+ warn_format_security = on;
+ break;
+
+ case OPT_Wformat_y2k:
+ warn_format_y2k = on;
+ break;
+
+ case OPT_Wformat_zero_length:
+ warn_format_zero_length = on;
+ break;
+
+ case OPT_Wimplicit:
+ set_Wimplicit (on);
+ break;
+
+ case OPT_Wimplicit_function_decl:
+ mesg_implicit_function_declaration = on;
+ break;
+
+ case OPT_Wimplicit_int:
+ warn_implicit_int = on;
+ break;
+
+ case OPT_Wimport:
+ cpp_opts->warn_import = on;
+ break;
+
+ case OPT_Wlong_long:
+ warn_long_long = on;
+ break;
+
+ case OPT_Wmain:
+ if (on)
+ warn_main = 1;
+ else
+ warn_main = -1;
+ break;
+
+ case OPT_Wmissing_braces:
+ warn_missing_braces = on;
+ break;
+
+ case OPT_Wmissing_declarations:
+ warn_missing_declarations = on;
+ break;
+
+ case OPT_Wmissing_format_attribute:
+ warn_missing_format_attribute = on;
+ break;
+
+ case OPT_Wmissing_prototypes:
+ warn_missing_prototypes = on;
+ break;
+
+ case OPT_Wmultichar:
+ cpp_opts->warn_multichar = on;
+ break;
+
+ case OPT_Wnested_externs:
+ warn_nested_externs = on;
+ break;
+
+ case OPT_Wnon_template_friend:
+ warn_nontemplate_friend = on;
+ break;
+
+ case OPT_Wnon_virtual_dtor:
+ warn_nonvdtor = on;
+ break;
+
+ case OPT_Wnonnull:
+ warn_nonnull = on;
+ break;
+
+ case OPT_Wold_style_cast:
+ warn_old_style_cast = on;
+ break;
+
+ case OPT_Woverloaded_virtual:
+ warn_overloaded_virtual = on;
+ break;
+
+ case OPT_Wparentheses:
+ warn_parentheses = on;
+ break;
+
+ case OPT_Wpmf_conversions:
+ warn_pmf2ptr = on;
+ break;
+
+ case OPT_Wpointer_arith:
+ warn_pointer_arith = on;
+ break;
+
+ case OPT_Wprotocol:
+ warn_protocol = on;
+ break;
+
+ case OPT_Wselector:
+ warn_selector = on;
+ break;
+
+ case OPT_Wredundant_decls:
+ warn_redundant_decls = on;
+ break;
+
+ case OPT_Wreorder:
+ warn_reorder = on;
+ break;
+
+ case OPT_Wreturn_type:
+ warn_return_type = on;
+ break;
+
+ case OPT_Wsequence_point:
+ warn_sequence_point = on;
+ break;
+
+ case OPT_Wsign_compare:
+ warn_sign_compare = on;
+ break;
+
+ case OPT_Wsign_promo:
+ warn_sign_promo = on;
+ 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;
+ break;
+
+ case OPT_Wsynth:
+ warn_synth = on;
+ break;
+
+ case OPT_Wsystem_headers:
+ cpp_opts->warn_system_headers = on;
+ break;
+
+ case OPT_Wtraditional:
+ warn_traditional = on;
+ cpp_opts->warn_traditional = on;
+ break;
+
+ case OPT_Wtrigraphs:
+ cpp_opts->warn_trigraphs = on;
+ break;
+
+ case OPT_Wundeclared_selector:
+ warn_undeclared_selector = on;
+ break;
+
+ case OPT_Wundef:
+ cpp_opts->warn_undef = on;
+ 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;
+ break;
+
+ case OPT_Wunused_macros:
+ cpp_opts->warn_unused_macros = on;
+ break;
+
+ case OPT_Wwrite_strings:
+ if (c_language == clk_c)
+ flag_const_strings = on;
+ else
+ warn_write_strings = on;
+ break;
+
+ case OPT_ansi:
+ if (c_language == clk_c)
+ set_std_c89 (false, true);
+ else
+ set_std_cxx98 (true);
+ break;
+
+ case OPT_d:
+ handle_OPT_d (arg);
+ break;
+
+ case OPT_fcond_mismatch:
+ if (c_language == clk_c)
+ {
+ flag_cond_mismatch = on;
+ break;
+ }
+ /* Fall through. */
+
+ case OPT_fall_virtual:
+ case OPT_fenum_int_equiv:
+ case OPT_fguiding_decls:
+ case OPT_fhonor_std:
+ case OPT_fhuge_objects:
+ case OPT_flabels_ok:
+ case OPT_fname_mangling:
+ case OPT_fnew_abi:
+ case OPT_fnonnull_objects:
+ case OPT_fsquangle:
+ case OPT_fstrict_prototype:
+ 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);
+ 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]);
+ break;
+
+ case OPT_fasm:
+ flag_no_asm = !on;
+ break;
+
+ case OPT_fbuiltin:
+ flag_no_builtin = !on;
+ break;
+
+ case OPT_fbuiltin_:
+ if (on)
+ result = 0;
+ else
+ disable_builtin_function (arg);
+ break;
+
+ case OPT_fdollars_in_identifiers:
+ dollars_in_ident = on;
+ break;
+
+ case OPT_fdump:
+ if (!on || !dump_switch_p (argv[0] + strlen ("-f")))
+ result = 0;
+ break;
+
+ case OPT_ffreestanding:
+ on = !on;
+ /* Fall through... */
+ case OPT_fhosted:
+ flag_hosted = on;
+ flag_no_builtin = !on;
+ /* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */
+ if (!on && warn_main == 2)
+ warn_main = 0;
+ break;
+
+ case OPT_fshort_double:
+ flag_short_double = on;
+ break;
+
+ case OPT_fshort_enums:
+ flag_short_enums = on;
+ break;
+
+ case OPT_fshort_wchar:
+ flag_short_wchar = on;
+ break;
+
+ case OPT_fsigned_bitfields:
+ flag_signed_bitfields = on;
+ explicit_flag_signed_bitfields = 1;
+ break;
+
+ case OPT_fsigned_char:
+ flag_signed_char = on;
+ break;
+
+ case OPT_funsigned_bitfields:
+ flag_signed_bitfields = !on;
+ explicit_flag_signed_bitfields = 1;
+ break;
+
+ case OPT_funsigned_char:
+ flag_signed_char = !on;
+ break;
+
+ case OPT_fcheck_new:
+ flag_check_new = on;
+ break;
+
+ case OPT_fconserve_space:
+ flag_conserve_space = on;
+ break;
+
+ case OPT_fconst_strings:
+ flag_const_strings = on;
+ break;
+
+ case OPT_fconstant_string_class:
+ constant_string_class_name = arg;
+ break;
+
+ case OPT_fdefault_inline:
+ flag_default_inline = on;
+ break;
+
+ case OPT_felide_constructors:
+ flag_elide_constructors = on;
+ break;
+
+ case OPT_fenforce_eh_specs:
+ flag_enforce_eh_specs = on;
+ break;
+
+ case OPT_fexternal_templates:
+ flag_external_templates = on;
+ 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 = -1;
+ break;
+
+ case OPT_ffor_scope:
+ flag_new_for_scope = on;
+ break;
+
+ case OPT_fgnu_keywords:
+ flag_no_gnu_keywords = !on;
+ break;
+
+ case OPT_fgnu_runtime:
+ flag_next_runtime = !on;
+ break;
+
+ case OPT_fhandle_exceptions:
+ warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
+ flag_exceptions = on;
+ break;
+
+ case OPT_fimplement_inlines:
+ flag_implement_inlines = on;
+ break;
+
+ case OPT_fimplicit_inline_templates:
+ flag_implicit_inline_templates = on;
+ break;
+
+ case OPT_fimplicit_templates:
+ flag_implicit_templates = on;
+ break;
+
+ case OPT_fms_extensions:
+ flag_ms_extensions = on;
+ break;
+
+ case OPT_fnext_runtime:
+ flag_next_runtime = on;
+ break;
+
+ case OPT_fnonansi_builtins:
+ flag_no_nonansi_builtin = !on;
+ break;
+
+ case OPT_foperator_names:
+ cpp_opts->operator_names = on;
+ break;
+
+ case OPT_foptional_diags:
+ flag_optional_diags = on;
+ break;
+
+ case OPT_fpermissive:
+ flag_permissive = on;
+ break;
+
+ case OPT_fpreprocessed:
+ cpp_opts->preprocessed = on;
+ break;
+
+ case OPT_frepo:
+ flag_use_repository = on;
+ if (on)
+ flag_implicit_templates = 0;
+ break;
+
+ case OPT_frtti:
+ flag_rtti = on;
+ break;
+
+ case OPT_fshow_column:
+ cpp_opts->show_column = on;
+ break;
+
+ case OPT_fstats:
+ flag_detailed_statistics = on;
+ break;
+
+ case OPT_ftabstop:
+ /* Don't recognize -fno-tabstop=. */
+ if (!on)
+ return 0;
+
+ /* 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;
+ }
+ break;
+
+ case OPT_ftemplate_depth:
+ max_tinst_depth = read_integral_parameter (arg, argv[0], 0);
+ break;
+
+ case OPT_fvtable_gc:
+ flag_vtable_gc = on;
+ break;
+
+ case OPT_fuse_cxa_atexit:
+ flag_use_cxa_atexit = on;
+ break;
+
+ case OPT_fweak:
+ flag_weak = on;
+ break;
+
+ case OPT_gen_decls:
+ flag_gen_declaration = 1;
+ break;
+
+ case OPT_lang_asm:
+ cpp_set_lang (parse_in, CLK_ASM);
+ break;
+
+ case OPT_lang_objc:
+ cpp_opts->objc = 1;
+ break;
+
+ case OPT_nostdinc:
+ /* No default include directories. You must specify all
+ include-file directories with -I. */
+ cpp_opts->no_standard_includes = 1;
+ break;
+
+ case OPT_nostdincplusplus:
+ /* No default C++-specific include directories. */
+ cpp_opts->no_standard_cplusplus_includes = 1;
+ break;
+
+ case OPT_o:
+ if (!out_fname)
+ out_fname = arg;
+ else
+ {
+ error ("output filename specified twice");
+ result = argc;
+ }
+ break;
+
+ /* We need to handle the -pedantic switches here, rather than in
+ c_common_post_options, so that a subsequent -Wno-endif-labels
+ is not overridden. */
+ case OPT_pedantic_errors:
+ cpp_opts->pedantic_errors = 1;
+ /* fall through */
+ case OPT_pedantic:
+ cpp_opts->pedantic = 1;
+ cpp_opts->warn_endif_labels = 1;
+ break;
+
+ case OPT_print_objc_runtime_info:
+ print_struct_values = 1;
+ break;
+
+ case OPT_remap:
+ cpp_opts->remap = 1;
+ break;
+
+ case OPT_std_cplusplus98:
+ case OPT_std_gnuplusplus98:
+ set_std_cxx98 (code == OPT_std_cplusplus98 /* 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 */);
+ break;
+
+ case OPT_std_gnu89:
+ 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 */);
+ break;
+
+ case OPT_std_gnu99:
+ case OPT_std_gnu9x:
+ set_std_c99 (false /* ISO */);
+ break;
+
+ case OPT_trigraphs:
+ cpp_opts->trigraphs = 1;
+ break;
+
+ case OPT_traditional_cpp:
+ cpp_opts->traditional = 1;
+ break;
+
+ case OPT_undef:
+ flag_undef = 1;
+ break;
+
+ case OPT_w:
+ cpp_opts->inhibit_warnings = 1;
+ break;
+
+ case OPT_v:
+ cpp_opts->verbose = 1;
+ break;
+ }
+
+ done:
+ if (dup)
+ free (dup);
+ return result;
+}
+
+/* Post-switch processing. */
+bool
+c_common_post_options ()
+{
+ /* Canonicalize the input and output filenames. */
+ if (in_fname == NULL || !strcmp (in_fname, "-"))
+ in_fname = "";
+
+ if (out_fname == NULL || !strcmp (out_fname, "-"))
+ out_fname = "";
+
+ if (cpp_opts->deps.style == DEPS_NONE)
+ check_deps_environment_vars ();
+
+ handle_deferred_opts ();
+
+ sanitize_cpp_opts ();
+
+ flag_inline_trees = 1;
+
+ /* 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;
+ }
+ }
+
+ /* 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 an error has occurred in cpplib, note it so we fail
+ immediately. */
+ errorcount += cpp_errors (parse_in);
+
+ return flag_preprocess_only;
+}
+
+/* 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 (out_stream == NULL)
+ fatal_io_error ("opening output file %s", out_fname);
+ else
+ cpp_preprocess_file (parse_in, in_fname, out_stream);
+}
+
+/* Front end initialization common to C, ObjC and C++. */
+const char *
+c_common_init (filename)
+ const char *filename;
+{
+ /* 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);
+
+ /* Register preprocessor built-ins before calls to
+ cpp_main_file. */
+ cpp_get_callbacks (parse_in)->register_builtins = cb_register_builtins;
+
+ /* NULL is passed up to toplev.c and we exit quickly. */
+ if (flag_preprocess_only)
+ {
+ preprocess_file ();
+ return NULL;
+ }
+
+ /* 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);
+
+ init_pragma ();
+
+ return filename;
+}
+
+/* Common finish hook for the C, ObjC and C++ front ends. */
+void
+c_common_finish ()
+{
+ FILE *deps_stream = NULL;
+
+ if (cpp_opts->deps.style != DEPS_NONE)
+ {
+ /* If -M or -MM was seen without -MF, default output to the
+ output stream. */
+ if (!deps_file)
+ deps_stream = out_stream;
+ else
+ {
+ deps_stream = fopen (deps_file, deps_append ? "a": "w");
+ if (!deps_stream)
+ fatal_io_error ("opening dependency file %s", deps_file);
+ }
+ }
+
+ /* For performance, avoid tearing down cpplib's internal structures
+ with cpp_destroy (). */
+ errorcount += cpp_finish (parse_in, deps_stream);
+
+ if (deps_stream && deps_stream != out_stream
+ && (ferror (deps_stream) || fclose (deps_stream)))
+ fatal_io_error ("closing dependency file %s", deps_file);
+
+ if (out_stream && (ferror (out_stream) || fclose (out_stream)))
+ fatal_io_error ("when writing output to %s", out_fname);
+}
+
+/* Either of two environment variables can specify output of
+ dependencies. Their value is either "OUTPUT_FILE" or "OUTPUT_FILE
+ DEPS_TARGET", where OUTPUT_FILE is the file to write deps info to
+ and DEPS_TARGET is the target to mention in the deps. They also
+ result in dependency information being appended to the output file
+ rather than overwriting it, and like Sun's compiler
+ SUNPRO_DEPENDENCIES suppresses the dependency on the main file. */
+static void
+check_deps_environment_vars ()
+{
+ char *spec;
+
+ GET_ENVIRONMENT (spec, "DEPENDENCIES_OUTPUT");
+ if (spec)
+ cpp_opts->deps.style = DEPS_USER;
+ else
+ {
+ GET_ENVIRONMENT (spec, "SUNPRO_DEPENDENCIES");
+ if (spec)
+ {
+ cpp_opts->deps.style = DEPS_SYSTEM;
+ cpp_opts->deps.ignore_main_file = true;
+ }
+ }
+
+ if (spec)
+ {
+ /* Find the space before the DEPS_TARGET, if there is one. */
+ char *s = strchr (spec, ' ');
+ if (s)
+ {
+ /* Let the caller perform MAKE quoting. */
+ defer_opt (OPT_MT, s + 1);
+ *s = '\0';
+ }
+
+ /* Command line -MF overrides environment variables and default. */
+ if (!deps_file)
+ deps_file = spec;
+
+ deps_append = 1;
+ }
+}
+
+/* Handle deferred command line switches. */
+static void
+handle_deferred_opts ()
+{
+ size_t i;
+
+ for (i = 0; i < deferred_count; i++)
+ {
+ 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 ();
+ }
+ }
+
+ free (deferred_opts);
+}
+
+/* These settings are appropriate for GCC, but not necessarily so for
+ cpplib as a library. */
+static void
+sanitize_cpp_opts ()
+{
+ /* If we don't know what style of dependencies to output, complain
+ if any other dependency switches have been given. */
+ if (deps_seen && cpp_opts->deps.style == DEPS_NONE)
+ error ("to generate dependencies you must specify either -M or -MM");
+
+ /* -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;
+
+ /* 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 (cpp_opts->dump_macros != dump_only)
+ cpp_opts->dump_macros = dump_none;
+ cpp_opts->dump_includes = 0;
+ }
+
+ cpp_opts->unsigned_char = !flag_signed_char;
+ cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
+
+ /* We want -Wno-long-long to override -pedantic -std=non-c99
+ and/or -Wtraditional, whatever the ordering. */
+ cpp_opts->warn_long_long
+ = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
+}
+
+/* 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;
+{
+ 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;
+{
+ 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;
+{
+ 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;
+{
+ 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;
+}
+
+/* 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;
+{
+ 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;
+ break;
+
+ case 'I':
+ cpp_opts->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, on)
+ size_t opt_index;
+ int on;
+{
+ 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 ("\"-%c%s%s\" is valid for %s but not for %s",
+ cl_options[opt_index].opt_text[0], on ? "" : "no-",
+ cl_options[opt_index].opt_text + 1, 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);
+}
OpenPOWER on IntegriCloud