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