X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-opts.c;h=b1dcc044f27dbab27278bfea01be9fa958c2316e;hb=f8156b5757829d11898f68d490c57290e388093f;hp=7d4c0e5f61bf58e3cf41baaaf413c74459ffb59d;hpb=2847dda94565f068630d772649ce30ed79a92c6d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-opts.c b/gcc/c-opts.c index 7d4c0e5f61b..b1dcc044f27 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, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Neil Booth. This file is part of GCC. @@ -16,8 +16,8 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ #include "config.h" #include "system.h" @@ -35,6 +35,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "cppdefault.h" #include "c-incpath.h" #include "debug.h" /* For debug_hooks. */ +#include "opts.h" +#include "options.h" +#include "mkdeps.h" #ifndef DOLLARS_IN_IDENTIFIERS # define DOLLARS_IN_IDENTIFIERS true @@ -44,17 +47,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA # define TARGET_SYSTEM_ROOT NULL #endif -#ifndef TARGET_EBCDIC -# define TARGET_EBCDIC 0 +#ifndef TARGET_OPTF +#define TARGET_OPTF(ARG) #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; @@ -90,355 +91,75 @@ static bool quote_chain_split; /* If -Wunused-macros. */ static bool warn_unused_macros; -/* Number of deferred options, deferred options array size. */ -static size_t deferred_count, deferred_size; +/* If -Wvariadic-macros. */ +static bool warn_variadic_macros = true; + +/* Number of deferred options. */ +static size_t deferred_count; /* Number of deferred options scanned for -include. */ static size_t include_cursor; -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 handle_deferred_opts PARAMS ((void)); -static void sanitize_cpp_opts PARAMS ((void)); -static void add_prefixed_path PARAMS ((const char *, size_t)); -static void push_command_line_include PARAMS ((void)); -static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *)); -static void finish_options PARAMS ((void)); +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 -#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("A", CL_ALL | CL_ARG, OPT_A) \ - OPT("C", CL_ALL, OPT_C) \ - OPT("CC", CL_ALL, OPT_CC) \ - OPT("D", CL_ALL | CL_ARG, OPT_D) \ - OPT("E", CL_ALL, OPT_E) \ - OPT("H", CL_ALL, OPT_H) \ - OPT("I", CL_ALL | CL_ARG, OPT_I) \ - 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("U", CL_ALL | CL_ARG, OPT_U) \ - 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-offsetof", CL_CXX, OPT_Winvalid_offsetof) \ - 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_C, 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_C, 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("idirafter", CL_ALL | CL_ARG, OPT_idirafter) \ - OPT("imacros", CL_ALL | CL_ARG, OPT_imacros) \ - OPT("include", CL_ALL | CL_ARG, OPT_include) \ - OPT("iprefix", CL_ALL | CL_ARG, OPT_iprefix) \ - OPT("isysroot", CL_ALL | CL_ARG, OPT_isysroot) \ - OPT("isystem", CL_ALL | CL_ARG, OPT_isystem) \ - OPT("iwithprefix", CL_ALL | CL_ARG, OPT_iwithprefix) \ - OPT("iwithprefixbefore", CL_ALL | CL_ARG, OPT_iwithprefixbefore) \ - 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 +/* 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: - case OPT_iprefix: - case OPT_iwithprefix: - case OPT_iwithprefixbefore: default: - error ("missing argument to \"-%s\"", opt_text); - break; + /* Pick up the default message. */ + return false; - case OPT_fconstant_string_class: - error ("no class name specified with \"-%s\"", opt_text); + case OPT_fconstant_string_class_: + error ("no class name specified with %qs", opt); break; case OPT_A: - error ("assertion missing after \"-%s\"", opt_text); + error ("assertion missing after %qs", opt); break; case OPT_D: case OPT_U: - error ("macro name missing after \"-%s\"", opt_text); + error ("macro name missing after %qs", opt); break; + case OPT_F: case OPT_I: case OPT_idirafter: case OPT_isysroot: case OPT_isystem: - error ("missing path after \"-%s\"", opt_text); + case OPT_iquote: + error ("missing path after %qs", opt); break; case OPT_MF: @@ -447,269 +168,100 @@ missing_arg (opt_index) case OPT_include: case OPT_imacros: case OPT_o: - error ("missing filename after \"-%s\"", opt_text); + error ("missing filename after %qs", opt); break; case OPT_MQ: case OPT_MT: - error ("missing target after \"-%s\"", opt_text); + error ("missing makefile target after %qs", 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; +unsigned int +c_common_init_options (unsigned int argc, const char **argv) { -#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; + static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX}; + unsigned int i, result; - 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 + /* 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 ()) + { + /* 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; + } + + parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89, + ident_hash, &line_table); - c_language = lang; - parse_in = cpp_create_reader (lang == clk_c ? CLK_GNUC89 : CLK_GNUCXX, - ident_hash); cpp_opts = cpp_get_options (parse_in); cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS; - if (flag_objc) - cpp_opts->objc = 1; + cpp_opts->objc = c_dialect_objc (); - flag_const_strings = (lang == clk_cplusplus); - warn_pointer_arith = (lang == clk_cplusplus); -} + /* Reset to avoid warnings on internal definitions. We set it just + before passing on command-line options to cpplib. */ + cpp_opts->warn_dollars = 0; -/* 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 = 0, lang_flag; - const struct cl_option *option; - enum opt_code code; + flag_const_strings = c_dialect_cxx (); + flag_exceptions = c_dialect_cxx (); + warn_pointer_arith = c_dialect_cxx (); - opt = argv[0]; + deferred_opts = XNEWVEC (struct deferred_opt, argc); - /* 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; - } + result = lang_flags[c_language]; - /* Drop the "no-" from negative switches. */ - if ((opt[1] == 'W' || opt[1] == 'f') - && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') + if (c_language == clk_c) { - 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; + /* If preprocessing assembly language, accept any of the C-family + front end options since the driver may pass them through. */ + for (i = 1; i < argc; i++) + if (! strcmp (argv[i], "-lang-asm")) + { + result |= CL_C | CL_ObjC | CL_CXX | CL_ObjCXX; + break; + } } - /* 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; - } - } + return result; +} - /* 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); - goto done; - } +/* 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 = option->opt_code) + switch (code) { - case N_OPTS: /* Shut GCC up. */ - break; - - case OPT__help: - print_help (); + default: + if (cl_options[code].flags & (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX)) + break; + result = 0; break; - case OPT__output_pch: + case OPT__output_pch_: pch_file = arg; break; @@ -738,15 +290,20 @@ c_common_decode_option (argc, argv) cpp_opts->print_include_names = 1; break; + case OPT_F: + TARGET_OPTF (xstrdup (arg)); + break; + case OPT_I: if (strcmp (arg, "-")) - add_path (xstrdup (arg), BRACKET, 0); + add_path (xstrdup (arg), BRACKET, 0, true); else { if (quote_chain_split) error ("-I- specified twice"); quote_chain_split = true; split_quote_chain (); + inform ("obsolete option -I- used, please use -iquote instead"); } break; @@ -792,315 +349,177 @@ c_common_decode_option (argc, argv) flag_no_line_commands = 1; break; - case OPT_U: - defer_opt (code, arg); + case OPT_fworking_directory: + flag_working_directory = value; break; - case OPT_Wabi: - warn_abi = on; + case OPT_U: + defer_opt (code, arg); 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; - + 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_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. */ - 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; + 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_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; + cpp_opts->warn_comments = value; break; case OPT_Wdeprecated: - warn_deprecated = on; - cpp_opts->warn_deprecated = on; + cpp_opts->warn_deprecated = value; break; case OPT_Wdiv_by_zero: - warn_div_by_zero = on; - break; - - case OPT_Weffcxx: - warn_ecpp = on; + warn_div_by_zero = 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; - break; - - case OPT_Werror_implicit_function_decl: - if (!on) - result = 0; - else - mesg_implicit_function_declaration = 2; + cpp_opts->warnings_are_errors = value; + global_dc->warning_as_error_requested = value; break; - case OPT_Wfloat_equal: - warn_float_equal = on; + case OPT_Werror_implicit_function_declaration: + mesg_implicit_function_declaration = 2; 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; - 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; + set_Wimplicit (value); break; case OPT_Wimport: - cpp_opts->warn_import = on; - break; - - case OPT_Winvalid_offsetof: - warn_invalid_offsetof = on; + /* Silently ignore for now. */ break; case OPT_Winvalid_pch: - cpp_opts->warn_invalid_pch = on; - break; - - case OPT_Wlong_long: - warn_long_long = on; + cpp_opts->warn_invalid_pch = 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; - 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; + case OPT_Wmissing_include_dirs: + cpp_opts->warn_missing_include_dirs = value; 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; + cpp_opts->warn_multichar = value; + break; + + case OPT_Wnormalized_: + if (!value || (arg && strcasecmp (arg, "none") == 0)) + cpp_opts->warn_normalize = normalized_none; + else if (!arg || strcasecmp (arg, "nfkc") == 0) + cpp_opts->warn_normalize = normalized_KC; + else if (strcasecmp (arg, "id") == 0) + cpp_opts->warn_normalize = normalized_identifier_C; + else if (strcasecmp (arg, "nfc") == 0) + cpp_opts->warn_normalize = normalized_C; + else + error ("argument %qs to %<-Wnormalized%> not recognized", arg); break; case OPT_Wreturn_type: - warn_return_type = on; + warn_return_type = value; 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; + case OPT_Wstrict_null_sentinel: + warn_strict_null_sentinel = 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; + cpp_opts->warn_traditional = value; break; case OPT_Wtrigraphs: - cpp_opts->warn_trigraphs = on; - break; - - case OPT_Wundeclared_selector: - warn_undeclared_selector = on; + cpp_opts->warn_trigraphs = 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: - warn_unused_macros = on; + warn_unused_macros = value; + break; + + case OPT_Wvariadic_macros: + warn_variadic_macros = value; break; case OPT_Wwrite_strings: - if (c_language == clk_c) - flag_const_strings = on; + if (!c_dialect_cxx ()) + flag_const_strings = value; else - warn_write_strings = on; + warn_write_strings = value; break; - + case OPT_ansi: - if (c_language == clk_c) + if (!c_dialect_cxx ()) set_std_c89 (false, true); else set_std_cxx98 (true); @@ -1111,20 +530,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: @@ -1132,236 +553,238 @@ c_common_decode_option (argc, argv) case OPT_fthis_is_variable: case OPT_fvtable_thunks: case OPT_fxref: - warning ("switch \"%s\" is no longer supported", argv[0]); - break; - - case OPT_fabi_version: - flag_abi_version = read_integral_parameter (arg, argv[0], 1); + case OPT_fvtable_gc: + warning (0, "switch %qs is no longer supported", option->opt_text); break; case OPT_faccess_control: - flag_access_control = on; - break; - - case OPT_falt_external_templates: - flag_alt_external_templates = on; - if (on) - flag_external_templates = true; - cp_deprecated: - warning ("switch \"%s\" is deprecated, please see documentation for details", argv[0]); + flag_access_control = value; break; case OPT_fasm: - flag_no_asm = !on; + flag_no_asm = !value; break; case OPT_fbuiltin: - flag_no_builtin = !on; + flag_no_builtin = !value; break; case OPT_fbuiltin_: - if (on) + if (value) result = 0; else disable_builtin_function (arg); break; case OPT_fdollars_in_identifiers: - cpp_opts->dollars_in_ident = on; - break; - - case OPT_fdump: - if (!on || !dump_switch_p (argv[0] + strlen ("-f"))) - result = 0; + cpp_opts->dollars_in_ident = value; 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; - explicit_flag_signed_bitfields = 1; + flag_signed_bitfields = value; break; case OPT_fsigned_char: - flag_signed_char = on; + flag_signed_char = value; break; case OPT_funsigned_bitfields: - flag_signed_bitfields = !on; - explicit_flag_signed_bitfields = 1; + flag_signed_bitfields = !value; 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 (0, "-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_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_fpch_preprocess: + flag_pch_preprocess = 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_fvisibility_inlines_hidden: + visibility_options.inlines_hidden = value; break; case OPT_fweak: - flag_weak = on; + flag_weak = value; + break; + + case OPT_fthreadsafe_statics: + flag_threadsafe_statics = value; + break; + + case OPT_fzero_link: + flag_zero_link = value; break; case OPT_gen_decls: @@ -1369,7 +792,7 @@ c_common_decode_option (argc, argv) break; case OPT_idirafter: - add_path (xstrdup (arg), AFTER, 0); + add_path (xstrdup (arg), AFTER, 0, true); break; case OPT_imacros: @@ -1381,12 +804,16 @@ c_common_decode_option (argc, argv) iprefix = arg; break; + case OPT_iquote: + add_path (xstrdup (arg), QUOTE, 0, true); + break; + case OPT_isysroot: sysroot = arg; break; case OPT_isystem: - add_path (xstrdup (arg), SYSTEM, 0); + add_path (xstrdup (arg), SYSTEM, 0, true); break; case OPT_iwithprefix: @@ -1410,7 +837,7 @@ c_common_decode_option (argc, argv) std_inc = false; break; - case OPT_nostdincplusplus: + case OPT_nostdinc__: std_cxx_inc = false; break; @@ -1418,10 +845,7 @@ c_common_decode_option (argc, argv) 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 @@ -1429,7 +853,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; @@ -1439,13 +863,18 @@ c_common_decode_option (argc, argv) print_struct_values = 1; break; + case OPT_print_pch_checksum: + c_common_print_pch_checksum (stdout); + exit_after_options = true; + break; + case OPT_remap: cpp_opts->remap = 1; break; - case OPT_std_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: @@ -1491,20 +920,23 @@ c_common_decode_option (argc, argv) break; } - done: - if (dup) - free (dup); return result; } /* Post-switch processing. */ bool -c_common_post_options (pfilename) - const char **pfilename; +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 = XNEWVEC (const char *, 1); + in_fnames[0] = ""; + } + else if (strcmp (in_fnames[0], "-") == 0) + in_fnames[0] = ""; if (out_fname == NULL || !strcmp (out_fname, "-")) out_fname = ""; @@ -1517,43 +949,56 @@ c_common_post_options (pfilename) sanitize_cpp_opts (); register_include_chains (parse_in, sysroot, iprefix, - std_inc, std_cxx_inc && c_language == clk_cplusplus, - verbose); + std_inc, std_cxx_inc && c_dialect_cxx (), verbose); 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; - } - } - - /* -Wextra implies -Wsign-compare, but not if explicitly - overridden. */ + /* Use tree inlining. */ + if (!flag_no_inline) + flag_no_inline = 1; + if (flag_inline_functions) + flag_inline_trees = 2; + + /* If we are given more than one input file, we must use + unit-at-a-time mode. */ + if (num_in_fnames > 1) + flag_unit_at_a_time = 1; + + /* Default to ObjC sjlj exception handling if NeXT runtime. */ + if (flag_objc_sjlj_exceptions < 0) + flag_objc_sjlj_exceptions = flag_next_runtime; + if (flag_objc_exceptions && !flag_objc_sjlj_exceptions) + flag_exceptions = 1; + + /* -Wextra implies -Wsign-compare and -Wmissing-field-initializers, + but not if explicitly overridden. */ if (warn_sign_compare == -1) warn_sign_compare = extra_warnings; + if (warn_missing_field_initializers == -1) + warn_missing_field_initializers = extra_warnings; /* Special format checking options don't work without -Wformat; warn if they are used. */ - if (warn_format_y2k && !warn_format) - warning ("-Wformat-y2k ignored without -Wformat"); - if (warn_format_extra_args && !warn_format) - warning ("-Wformat-extra-args ignored without -Wformat"); - if (warn_format_zero_length && !warn_format) - warning ("-Wformat-zero-length ignored without -Wformat"); - if (warn_format_nonliteral && !warn_format) - warning ("-Wformat-nonliteral ignored without -Wformat"); - if (warn_format_security && !warn_format) - warning ("-Wformat-security ignored without -Wformat"); - if (warn_missing_format_attribute && !warn_format) - warning ("-Wmissing-format-attribute ignored without -Wformat"); + if (!warn_format) + { + warning (OPT_Wformat_y2k, + "-Wformat-y2k ignored without -Wformat"); + warning (OPT_Wformat_extra_args, + "-Wformat-extra-args ignored without -Wformat"); + warning (OPT_Wformat_zero_length, + "-Wformat-zero-length ignored without -Wformat"); + warning (OPT_Wformat_nonliteral, + "-Wformat-nonliteral ignored without -Wformat"); + warning (OPT_Wformat_security, + "-Wformat-security ignored without -Wformat"); + warning (OPT_Wmissing_format_attribute, + "-Wmissing-format-attribute ignored without -Wformat"); + } + + /* C99 requires special handling of complex multiplication and division; + -ffast-math and -fcx-limited-range are handled in process_options. */ + if (flag_isoc99) + flag_complex_method = 2; if (flag_preprocess_only) { @@ -1571,6 +1016,10 @@ c_common_post_options (pfilename) return false; } + if (num_in_fnames > 1) + error ("too many filenames given. Type %s --help for usage", + progname); + init_pp_output (out_stream); } else @@ -1578,38 +1027,55 @@ c_common_post_options (pfilename) init_c_lex (); /* Yuk. WTF is this? I do know ObjC relies on it somewhere. */ - input_line = 0; + input_location = UNKNOWN_LOCATION; } - cpp_get_callbacks (parse_in)->file_change = cb_file_change; + cb = cpp_get_callbacks (parse_in); + cb->file_change = cb_file_change; + cb->dir_change = cb_dir_change; + cpp_post_options (parse_in); - /* NOTE: we use in_fname here, not the one supplied. */ - *pfilename = cpp_read_main_file (parse_in, in_fname); - - saved_lineno = input_line; - input_line = 0; + input_location = UNKNOWN_LOCATION; /* If an error has occurred in cpplib, note it so we fail immediately. */ errorcount += cpp_errors (parse_in); + *pfilename = this_input_filename + = cpp_read_main_file (parse_in, in_fnames[0]); + /* Don't do any compilation or preprocessing if there is no input file. */ + if (this_input_filename == NULL) + { + errorcount++; + return false; + } + + if (flag_working_directory + && flag_preprocess_only && !flag_no_line_commands) + pp_dir_change (parse_in, get_src_pwd ()); + return flag_preprocess_only; } /* Front end initialization common to C, ObjC and C++. */ bool -c_common_init () +c_common_init (void) { - input_line = saved_lineno; - /* Set up preprocessor arithmetic. Must be done after call to c_common_nodes_and_builtins for type nodes to be good. */ cpp_opts->precision = TYPE_PRECISION (intmax_type_node); cpp_opts->char_precision = TYPE_PRECISION (char_type_node); cpp_opts->int_precision = TYPE_PRECISION (integer_type_node); cpp_opts->wchar_precision = TYPE_PRECISION (wchar_type_node); - cpp_opts->unsigned_wchar = TREE_UNSIGNED (wchar_type_node); - cpp_opts->EBCDIC = TARGET_EBCDIC; + cpp_opts->unsigned_wchar = TYPE_UNSIGNED (wchar_type_node); + cpp_opts->bytes_big_endian = BYTES_BIG_ENDIAN; + + /* This can't happen until after wchar_precision and bytes_big_endian + are known. */ + cpp_init_iconv (parse_in); + + if (version_flag) + c_common_print_pch_checksum (stderr); if (flag_preprocess_only) { @@ -1624,30 +1090,52 @@ c_common_init () return true; } -/* A thin wrapper around the real parser that initializes the - integrated preprocessor after debug output has been initialized. - Also, make sure the start_source_file debug hook gets called for - the primary source file. */ +/* Initialize the integrated preprocessor after debug output has been + initialized; loop over each input file. */ void -c_common_parse_file (set_yydebug) - int set_yydebug ATTRIBUTE_UNUSED; +c_common_parse_file (int set_yydebug) { + unsigned int i; + + /* Enable parser debugging, if requested and we can. If requested + and we can't, notify the user. */ #if YYDEBUG != 0 yydebug = set_yydebug; #else - warning ("YYDEBUG not defined"); + if (set_yydebug) + warning (0, "YYDEBUG was not defined at build time, -dy ignored"); #endif - (*debug_hooks->start_source_file) (input_line, input_filename); - finish_options(); - pch_init(); - yyparse (); - free_parser_stacks (); + i = 0; + for (;;) + { + /* Start the main input file, if the debug writer wants it. */ + if (debug_hooks->start_end_main_source_file) + (*debug_hooks->start_source_file) (0, this_input_filename); + finish_options (); + pch_init (); + push_file_scope (); + c_parse_file (); + finish_file (); + pop_file_scope (); + /* And end the main input file, if the debug writer wants it */ + if (debug_hooks->start_end_main_source_file) + (*debug_hooks->end_source_file) (0); + if (++i >= num_in_fnames) + break; + cpp_undef_all (parse_in); + this_input_filename + = cpp_read_main_file (parse_in, in_fnames[i]); + /* If an input file is missing, abandon further compilation. + cpplib has issued a diagnostic. */ + if (!this_input_filename) + break; + } } /* Common finish hook for the C, ObjC and C++ front ends. */ void -c_common_finish () +c_common_finish (void) { FILE *deps_stream = NULL; @@ -1685,7 +1173,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; @@ -1718,28 +1206,38 @@ check_deps_environment_vars () deps_file = spec; deps_append = 1; + deps_seen = true; } } /* Handle deferred command line switches. */ static void -handle_deferred_opts () +handle_deferred_opts (void) { size_t i; + struct deps *deps; + + /* Avoid allocating the deps buffer if we don't need it. + (This flag may be true without there having been -MT or -MQ + options, but we'll still need the deps buffer.) */ + if (!deps_seen) + return; + + deps = cpp_get_deps (parse_in); for (i = 0; i < deferred_count; i++) { struct deferred_opt *opt = &deferred_opts[i]; if (opt->code == OPT_MT || opt->code == OPT_MQ) - cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ); + deps_add_target (deps, opt->arg, opt->code == OPT_MQ); } } /* 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. */ @@ -1753,11 +1251,13 @@ sanitize_cpp_opts () /* Disable -dD, -dN and -dI if normal output is suppressed. Allow -dM since at least glibc relies on -M -dM to work. */ + /* Also, flag_no_output implies flag_no_line_commands, always. */ if (flag_no_output) { if (flag_dump_macros != 'M') flag_dump_macros = 0; flag_dump_includes = 0; + flag_no_line_commands = 1; } cpp_opts->unsigned_char = !flag_signed_char; @@ -1767,13 +1267,23 @@ sanitize_cpp_opts () and/or -Wtraditional, whatever the ordering. */ cpp_opts->warn_long_long = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional); + + /* Similarly with -Wno-variadic-macros. No check for c99 here, since + this also turns off warnings about GCCs extension. */ + cpp_opts->warn_variadic_macros + = warn_variadic_macros && (pedantic || warn_traditional); + + /* If we're generating preprocessor output, emit current directory + if explicitly requested or if debugging information is enabled. + ??? Maybe we should only do it for debugging formats that + actually output the current directory? */ + if (flag_working_directory == -1) + flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE); } /* Add include path with a prefix at the front of its name. */ static void -add_prefixed_path (suffix, chain) - const char *suffix; - size_t chain; +add_prefixed_path (const char *suffix, size_t chain) { char *path; const char *prefix; @@ -1783,25 +1293,40 @@ add_prefixed_path (suffix, chain) prefix = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR; prefix_len = iprefix ? strlen (iprefix) : cpp_GCC_INCLUDE_DIR_len; - path = xmalloc (prefix_len + suffix_len + 1); + path = (char *) xmalloc (prefix_len + suffix_len + 1); memcpy (path, prefix, prefix_len); memcpy (path + prefix_len, suffix, suffix_len); path[prefix_len + suffix_len] = '\0'; - add_path (path, chain, 0); + add_path (path, chain, 0, false); } /* Handle -D, -U, -A, -imacros, and the first -include. */ static void -finish_options () +finish_options (void) { if (!cpp_opts->preprocessed) { size_t i; - cpp_change_file (parse_in, LC_RENAME, _("")); + cb_file_change (parse_in, + linemap_add (&line_table, LC_RENAME, 0, + _(""), 0)); + 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++) { @@ -1827,101 +1352,106 @@ finish_options () if (opt->code == OPT_imacros && cpp_push_include (parse_in, opt->arg)) - cpp_scan_nooutput (parse_in); + { + /* Disable push_command_line_include callback for now. */ + include_cursor = deferred_count + 1; + cpp_scan_nooutput (parse_in); + } } } + include_cursor = 0; push_command_line_include (); } /* Give CPP the next file given by -include, if any. */ static void -push_command_line_include () +push_command_line_include (void) { - if (cpp_opts->preprocessed) - return; - while (include_cursor < deferred_count) { struct deferred_opt *opt = &deferred_opts[include_cursor++]; - - if (opt->code == OPT_include && cpp_push_include (parse_in, opt->arg)) + + if (!cpp_opts->preprocessed && opt->code == OPT_include + && cpp_push_include (parse_in, opt->arg)) return; } if (include_cursor == deferred_count) { - /* Restore the line map from . */ - cpp_change_file (parse_in, LC_RENAME, main_input_filename); + include_cursor++; /* -Wunused-macros should only warn about macros defined hereafter. */ cpp_opts->warn_unused_macros = warn_unused_macros; - include_cursor++; + /* Restore the line map from . */ + if (!cpp_opts->preprocessed) + cpp_change_file (parse_in, LC_RENAME, this_input_filename); + + /* Set this here so the client can change the option if it wishes, + and after stacking the main file so we don't trace the main file. */ + line_table.trace_includes = cpp_opts->print_include_names; } } /* File change callback. Has to handle -include files. */ static void -cb_file_change (pfile, new_map) - cpp_reader *pfile ATTRIBUTE_UNUSED; - const struct line_map *new_map; +cb_file_change (cpp_reader * ARG_UNUSED (pfile), + const struct line_map *new_map) { if (flag_preprocess_only) pp_file_change (new_map); else fe_file_change (new_map); - if (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map)) + if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map))) push_command_line_include (); } +void +cb_dir_change (cpp_reader * ARG_UNUSED (pfile), const char *dir) +{ + if (!set_src_pwd (dir)) + warning (0, "too late for # directive to set debug directory"); +} + /* Set the C 89 standard (with 1994 amendments if C94, without GNU extensions if ISO). There is no concept of gnu94. */ static void -set_std_c89 (c94, iso) - int c94, iso; +set_std_c89 (int c94, int iso) { cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89); flag_iso = iso; flag_no_asm = iso; flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; - flag_noniso_default_format_attributes = !iso; flag_isoc94 = c94; flag_isoc99 = 0; - flag_writable_strings = 0; } /* Set the C 99 standard (without GNU extensions if ISO). */ static void -set_std_c99 (iso) - int iso; +set_std_c99 (int iso) { cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99); flag_no_asm = iso; flag_no_nonansi_builtin = iso; - flag_noniso_default_format_attributes = !iso; flag_iso = iso; flag_isoc99 = 1; flag_isoc94 = 1; - flag_writable_strings = 0; } /* Set the C++ 98 standard (without GNU extensions if ISO). */ static void -set_std_cxx98 (iso) - int iso; +set_std_cxx98 (int iso) { cpp_set_lang (parse_in, iso ? CLK_CXX98: CLK_GNUCXX); flag_no_gnu_keywords = iso; flag_no_nonansi_builtin = iso; - flag_noniso_default_format_attributes = !iso; flag_iso = iso; } /* Handle setting implicit to ON. */ static void -set_Wimplicit (on) - int on; +set_Wimplicit (int on) { warn_implicit = on; warn_implicit_int = on; @@ -1937,8 +1467,7 @@ 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; @@ -1956,122 +1485,3 @@ handle_OPT_d (arg) 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\ - -isysroot Set to be the system root directory\n\ - -P Do not generate #line directives\n\ - -remap Remap file names when including files\n\ - --help Display this information\n\ -"), stdout); -}