diff options
Diffstat (limited to 'contrib/gcc/c-opts.c')
-rw-r--r-- | contrib/gcc/c-opts.c | 1799 |
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); +} |