c-opts.c (deps_seen, [...]): New.
[platform/upstream/gcc.git] / gcc / c-opts.c
1 /* C/ObjC/C++ command line option handling.
2    Copyright (C) 2002 Free Software Foundation, Inc.
3    Contributed by Neil Booth.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "tree.h"
25 #include "c-common.h"
26 #include "c-pragma.h"
27 #include "flags.h"
28 #include "toplev.h"
29 #include "langhooks.h"
30 #include "tree-inline.h"
31 #include "diagnostic.h"
32 #include "intl.h"
33
34 /* CPP's options.  */
35 static cpp_options *cpp_opts;
36
37 /* Input filename.  */
38 static const char *in_fname;
39
40 /* Filename and stream for preprocessed output.  */
41 static const char *out_fname;
42 static FILE *out_stream;
43
44 /* Append dependencies to deps_file.  */
45 static bool deps_append;
46
47 /* If dependency switches (-MF etc.) have been given.  */
48 static bool deps_seen;
49
50 /* Dependency output file.  */
51 static const char *deps_file;
52
53 /* Number of deferred options, deferred options array size.  */
54 static size_t deferred_count, deferred_size;
55
56 static void missing_arg PARAMS ((size_t));
57 static size_t find_opt PARAMS ((const char *, int));
58 static void set_Wimplicit PARAMS ((int));
59 static void complain_wrong_lang PARAMS ((size_t));
60 static void write_langs PARAMS ((char *, int));
61 static void print_help PARAMS ((void));
62 static void handle_OPT_d PARAMS ((const char *));
63 static void set_std_cxx98 PARAMS ((int));
64 static void set_std_c89 PARAMS ((int, int));
65 static void set_std_c99 PARAMS ((int));
66 static void check_deps_environment_vars PARAMS ((void));
67 static void preprocess_file PARAMS ((void));
68 static void handle_deferred_opts PARAMS ((void));
69 static void sanitize_cpp_opts PARAMS ((void));
70
71 #ifndef STDC_0_IN_SYSTEM_HEADERS
72 #define STDC_0_IN_SYSTEM_HEADERS 0
73 #endif
74
75 #define CL_C_ONLY       (1 << 0) /* Only C.  */
76 #define CL_OBJC_ONLY    (1 << 1) /* Only ObjC.  */
77 #define CL_CXX_ONLY     (1 << 2) /* Only C++.  */
78 #define CL_OBJCXX_ONLY  (1 << 3) /* Only ObjC++.  */
79 #define CL_JOINED       (1 << 4) /* If takes joined argument.  */
80 #define CL_SEPARATE     (1 << 5) /* If takes a separate argument.  */
81
82 #define CL_ARG          (CL_JOINED | CL_SEPARATE)
83 #define CL_C            (CL_C_ONLY | CL_OBJC_ONLY)
84 #define CL_OBJC         (CL_OBJC_ONLY | CL_OBJCXX_ONLY)
85 #define CL_CXX          (CL_CXX_ONLY | CL_OBJCXX_ONLY)
86 #define CL_ALL          (CL_C | CL_CXX)
87
88 /* This is the list of all command line options, with the leading "-"
89    removed.  It must be sorted in ASCII collating order.  All options
90    beginning with "f" or "W" are implicitly assumed to take a "no-"
91    form; this form should not be listed.  The variable "on" is true if
92    the positive form is given, otherwise it is false.  If you don't
93    want to allow a "no-" form, your handler should reject "on" being
94    false by returning zero.  See, for example, the handling of
95    -ftabstop=.
96
97    If the user gives an option to a front end that doesn't support it,
98    an error is output, mentioning which front ends the option is valid
99    for.  If you don't want this, you must accept it for all front
100    ends, and test for the front end in the option handler.  See, for
101    example, the handling of -Wno-strict-prototypes for C++.
102
103    If you request an argument with CL_JOINED, CL_SEPARATE or their
104    combination CL_ARG, it is stored in the variable "arg", which is
105    guaranteed to be non-NULL and to not be an empty string.  It points
106    to the argument either within the argv[] vector or within one of
107    that vector's strings, and so the text is permanent and copies need
108    not be made.  Be sure to add an error message in missing_arg() if
109    the default is not appropriate.  */
110
111 #define COMMAND_LINE_OPTIONS                                                 \
112   OPT("-help",                  CL_ALL,   OPT__help)                         \
113   OPT("C",                      CL_ALL,   OPT_C)                             \
114   OPT("CC",                     CL_ALL,   OPT_CC)                            \
115   OPT("E",                      CL_ALL,   OPT_E)                             \
116   OPT("H",                      CL_ALL,   OPT_H)                             \
117   OPT("M",                      CL_ALL,   OPT_M)                             \
118   OPT("MD",                     CL_ALL | CL_SEPARATE, OPT_MD)                \
119   OPT("MF",                     CL_ALL | CL_ARG, OPT_MF)                     \
120   OPT("MG",                     CL_ALL,   OPT_MG)                            \
121   OPT("MM",                     CL_ALL,   OPT_MM)                            \
122   OPT("MMD",                    CL_ALL | CL_SEPARATE, OPT_MMD)               \
123   OPT("MP",                     CL_ALL,   OPT_MP)                            \
124   OPT("MQ",                     CL_ALL | CL_ARG, OPT_MQ)                     \
125   OPT("MT",                     CL_ALL | CL_ARG, OPT_MT)                     \
126   OPT("P",                      CL_ALL,   OPT_P)                             \
127   OPT("Wall",                   CL_ALL,   OPT_Wall)                          \
128   OPT("Wbad-function-cast",     CL_C,     OPT_Wbad_function_cast)            \
129   OPT("Wcast-qual",             CL_ALL,   OPT_Wcast_qual)                    \
130   OPT("Wchar-subscripts",       CL_ALL,   OPT_Wchar_subscripts)              \
131   OPT("Wcomment",               CL_ALL,   OPT_Wcomment)                      \
132   OPT("Wcomments",              CL_ALL,   OPT_Wcomments)                     \
133   OPT("Wconversion",            CL_ALL,   OPT_Wconversion)                   \
134   OPT("Wctor-dtor-privacy",     CL_CXX,   OPT_Wctor_dtor_privacy)            \
135   OPT("Wdeprecated",            CL_CXX,   OPT_Wdeprecated)                   \
136   OPT("Wdiv-by-zero",           CL_C,     OPT_Wdiv_by_zero)                  \
137   OPT("Weffc++",                CL_CXX,   OPT_Weffcxx)                       \
138   OPT("Wendif-labels",          CL_ALL,   OPT_Wendif_labels)                 \
139   OPT("Werror",                 CL_ALL,   OPT_Werror)                        \
140   OPT("Werror-implicit-function-declaration",                                \
141                                 CL_C,     OPT_Werror_implicit_function_decl) \
142   OPT("Wfloat-equal",           CL_ALL,   OPT_Wfloat_equal)                  \
143   OPT("Wformat",                CL_ALL,   OPT_Wformat)                       \
144   OPT("Wformat-extra-args",     CL_ALL,   OPT_Wformat_extra_args)            \
145   OPT("Wformat-nonliteral",     CL_ALL,   OPT_Wformat_nonliteral)            \
146   OPT("Wformat-security",       CL_ALL,   OPT_Wformat_security)              \
147   OPT("Wformat-y2k",            CL_ALL,   OPT_Wformat_y2k)                   \
148   OPT("Wformat-zero-length",    CL_C,     OPT_Wformat_zero_length)           \
149   OPT("Wformat=",               CL_ALL | CL_JOINED, OPT_Wformat_eq)          \
150   OPT("Wimplicit",              CL_CXX,   OPT_Wimplicit)                     \
151   OPT("Wimplicit-function-declaration", CL_C, OPT_Wimplicit_function_decl)   \
152   OPT("Wimplicit-int",          CL_C,     OPT_Wimplicit_int)                 \
153   OPT("Wimport",                CL_ALL,   OPT_Wimport)                       \
154   OPT("Wlong-long",             CL_ALL,   OPT_Wlong_long)                    \
155   OPT("Wmain",                  CL_C,     OPT_Wmain)                         \
156   OPT("Wmissing-braces",        CL_ALL,   OPT_Wmissing_braces)               \
157   OPT("Wmissing-declarations",  CL_C,     OPT_Wmissing_declarations)         \
158   OPT("Wmissing-format-attribute",CL_ALL, OPT_Wmissing_format_attribute)     \
159   OPT("Wmissing-prototypes",    CL_ALL,   OPT_Wmissing_prototypes)           \
160   OPT("Wmultichar",             CL_ALL,   OPT_Wmultichar)                    \
161   OPT("Wnested-externs",        CL_C,     OPT_Wnested_externs)               \
162   OPT("Wnon-template-friend",   CL_CXX,   OPT_Wnon_template_friend)          \
163   OPT("Wnon-virtual-dtor",      CL_CXX,   OPT_Wnon_virtual_dtor)             \
164   OPT("Wnonnull",               CL_C,     OPT_Wnonnull)                      \
165   OPT("Wold-style-cast",        CL_CXX,   OPT_Wold_style_cast)               \
166   OPT("Woverloaded-virtual",    CL_CXX,   OPT_Woverloaded_virtual)           \
167   OPT("Wparentheses",           CL_ALL,   OPT_Wparentheses)                  \
168   OPT("Wpmf-conversions",       CL_CXX,   OPT_Wpmf_conversions)              \
169   OPT("Wpointer-arith",         CL_ALL,   OPT_Wpointer_arith)                \
170   OPT("Wprotocol",              CL_OBJC,  OPT_Wprotocol)                     \
171   OPT("Wredundant-decls",       CL_ALL,   OPT_Wredundant_decls)              \
172   OPT("Wreorder",               CL_CXX,   OPT_Wreorder)                      \
173   OPT("Wreturn-type",           CL_ALL,   OPT_Wreturn_type)                  \
174   OPT("Wselector",              CL_OBJC,  OPT_Wselector)                     \
175   OPT("Wsequence-point",        CL_C,     OPT_Wsequence_point)               \
176   OPT("Wsign-compare",          CL_ALL,   OPT_Wsign_compare)                 \
177   OPT("Wsign-promo",            CL_CXX,   OPT_Wsign_promo)                   \
178   OPT("Wstrict-prototypes",     CL_ALL,   OPT_Wstrict_prototypes)            \
179   OPT("Wsynth",                 CL_CXX,   OPT_Wsynth)                        \
180   OPT("Wsystem-headers",        CL_ALL,   OPT_Wsystem_headers)               \
181   OPT("Wtraditional",           CL_C,     OPT_Wtraditional)                  \
182   OPT("Wtrigraphs",             CL_ALL,   OPT_Wtrigraphs)                    \
183   OPT("Wundef",                 CL_ALL,   OPT_Wundef)                        \
184   OPT("Wunknown-pragmas",       CL_ALL,   OPT_Wunknown_pragmas)              \
185   OPT("Wunused-macros",         CL_ALL,   OPT_Wunused_macros)                \
186   OPT("Wwrite-strings",         CL_ALL,   OPT_Wwrite_strings)                \
187   OPT("ansi",                   CL_ALL,   OPT_ansi)                          \
188   OPT("d",                      CL_ALL | CL_JOINED, OPT_d)                   \
189   OPT("faccess-control",        CL_CXX,   OPT_faccess_control)               \
190   OPT("fall-virtual",           CL_CXX,   OPT_fall_virtual)                  \
191   OPT("falt-external-templates",CL_CXX,   OPT_falt_external_templates)       \
192   OPT("fasm",                   CL_ALL,   OPT_fasm)                          \
193   OPT("fbuiltin",               CL_ALL,   OPT_fbuiltin)                      \
194   OPT("fbuiltin-",              CL_ALL | CL_JOINED, OPT_fbuiltin_)           \
195   OPT("fcheck-new",             CL_CXX,   OPT_fcheck_new)                    \
196   OPT("fcond-mismatch",         CL_ALL,   OPT_fcond_mismatch)                \
197   OPT("fconserve-space",        CL_CXX,   OPT_fconserve_space)               \
198   OPT("fconst-strings",         CL_CXX,   OPT_fconst_strings)                \
199   OPT("fconstant-string-class=", CL_OBJC | CL_JOINED,                        \
200                                           OPT_fconstant_string_class)        \
201   OPT("fdefault-inline",        CL_CXX,   OPT_fdefault_inline)               \
202   OPT("fdollars-in-identifiers",CL_ALL,   OPT_fdollars_in_identifiers)       \
203   OPT("fdump-",                 CL_ALL | CL_JOINED, OPT_fdump)               \
204   OPT("felide-constructors",    CL_CXX,   OPT_felide_constructors)           \
205   OPT("fenforce-eh-specs",      CL_CXX,   OPT_fenforce_eh_specs)             \
206   OPT("fenum-int-equiv",        CL_CXX,   OPT_fenum_int_equiv)               \
207   OPT("fexternal-templates",    CL_CXX,   OPT_fexternal_templates)           \
208   OPT("ffor-scope",             CL_CXX,   OPT_ffor_scope)                    \
209   OPT("ffreestanding",          CL_C,     OPT_ffreestanding)                 \
210   OPT("fgnu-keywords",          CL_CXX,   OPT_fgnu_keywords)                 \
211   OPT("fgnu-runtime",           CL_OBJC,  OPT_fgnu_runtime)                  \
212   OPT("fguiding-decls",         CL_CXX,   OPT_fguiding_decls)                \
213   OPT("fhandle-exceptions",     CL_CXX,   OPT_fhandle_exceptions)            \
214   OPT("fhonor-std",             CL_CXX,   OPT_fhonor_std)                    \
215   OPT("fhosted",                CL_C,     OPT_fhosted)                       \
216   OPT("fhuge-objects",          CL_CXX,   OPT_fhuge_objects)                 \
217   OPT("fimplement-inlines",     CL_CXX,   OPT_fimplement_inlines)            \
218   OPT("fimplicit-inline-templates", CL_CXX, OPT_fimplicit_inline_templates)  \
219   OPT("fimplicit-templates",    CL_CXX,   OPT_fimplicit_templates)           \
220   OPT("flabels-ok",             CL_CXX,   OPT_flabels_ok)                    \
221   OPT("fms-extensions",         CL_ALL,   OPT_fms_extensions)                \
222   OPT("fname-mangling-version-",CL_CXX | CL_JOINED, OPT_fname_mangling)      \
223   OPT("fnew-abi",               CL_CXX,   OPT_fnew_abi)                      \
224   OPT("fnext-runtime",          CL_OBJC,  OPT_fnext_runtime)                 \
225   OPT("fnonansi-builtins",      CL_CXX,   OPT_fnonansi_builtins)             \
226   OPT("fnonnull-objects",       CL_CXX,   OPT_fnonnull_objects)              \
227   OPT("foperator-names",        CL_CXX,   OPT_foperator_names)               \
228   OPT("foptional-diags",        CL_CXX,   OPT_foptional_diags)               \
229   OPT("fpermissive",            CL_CXX,   OPT_fpermissive)                   \
230   OPT("fpreprocessed",          CL_ALL,   OPT_fpreprocessed)                 \
231   OPT("frepo",                  CL_CXX,   OPT_frepo)                         \
232   OPT("frtti",                  CL_CXX,   OPT_frtti)                         \
233   OPT("fshort-double",          CL_ALL,   OPT_fshort_double)                 \
234   OPT("fshort-enums",           CL_ALL,   OPT_fshort_enums)                  \
235   OPT("fshort-wchar",           CL_ALL,   OPT_fshort_wchar)                  \
236   OPT("fshow-column",           CL_ALL,   OPT_fshow_column)                  \
237   OPT("fsigned-bitfields",      CL_ALL,   OPT_fsigned_bitfields)             \
238   OPT("fsigned-char",           CL_ALL,   OPT_fsigned_char)                  \
239   OPT("fsquangle",              CL_CXX,   OPT_fsquangle)                     \
240   OPT("fstats",                 CL_CXX,   OPT_fstats)                        \
241   OPT("fstrict-prototype",      CL_CXX,   OPT_fstrict_prototype)             \
242   OPT("ftabstop=",              CL_ALL | CL_JOINED, OPT_ftabstop)            \
243   OPT("ftemplate-depth-",       CL_CXX | CL_JOINED, OPT_ftemplate_depth)     \
244   OPT("fthis-is-variable",      CL_CXX,   OPT_fthis_is_variable)             \
245   OPT("funsigned-bitfields",    CL_ALL,   OPT_funsigned_bitfields)           \
246   OPT("funsigned-char",         CL_ALL,   OPT_funsigned_char)                \
247   OPT("fuse-cxa-atexit",        CL_CXX,   OPT_fuse_cxa_atexit)               \
248   OPT("fvtable-gc",             CL_CXX,   OPT_fvtable_gc)                    \
249   OPT("fvtable-thunks",         CL_CXX,   OPT_fvtable_thunks)                \
250   OPT("fweak",                  CL_CXX,   OPT_fweak)                         \
251   OPT("fxref",                  CL_CXX,   OPT_fxref)                         \
252   OPT("gen-decls",              CL_OBJC,  OPT_gen_decls)                     \
253   OPT("lang-asm",               CL_C_ONLY, OPT_lang_asm)                     \
254   OPT("lang-objc",              CL_ALL,   OPT_lang_objc)                     \
255   OPT("nostdinc",               CL_ALL,   OPT_nostdinc)                      \
256   OPT("nostdinc++",             CL_ALL,   OPT_nostdincplusplus)              \
257   OPT("o",                      CL_ALL | CL_ARG, OPT_o)                      \
258   OPT("pedantic",               CL_ALL,   OPT_pedantic)                      \
259   OPT("pedantic-errors",        CL_ALL,   OPT_pedantic_errors)               \
260   OPT("print-objc-runtime-info", CL_OBJC, OPT_print_objc_runtime_info)       \
261   OPT("remap",                  CL_ALL,   OPT_remap)                         \
262   OPT("std=c++98",              CL_CXX,   OPT_std_cplusplus98)               \
263   OPT("std=c89",                CL_C,     OPT_std_c89)                       \
264   OPT("std=c99",                CL_C,     OPT_std_c99)                       \
265   OPT("std=c9x",                CL_C,     OPT_std_c9x)                       \
266   OPT("std=gnu++98",            CL_CXX,   OPT_std_gnuplusplus98)             \
267   OPT("std=gnu89",              CL_C,     OPT_std_gnu89)                     \
268   OPT("std=gnu99",              CL_C,     OPT_std_gnu99)                     \
269   OPT("std=gnu9x",              CL_C,     OPT_std_gnu9x)                     \
270   OPT("std=iso9899:1990",       CL_C,     OPT_std_iso9899_1990)              \
271   OPT("std=iso9899:199409",     CL_C,     OPT_std_iso9899_199409)            \
272   OPT("std=iso9899:1999",       CL_C,     OPT_std_iso9899_1999)              \
273   OPT("std=iso9899:199x",       CL_C,     OPT_std_iso9899_199x)              \
274   OPT("traditional-cpp",        CL_ALL,   OPT_traditional_cpp)               \
275   OPT("trigraphs",              CL_ALL,   OPT_trigraphs)                     \
276   OPT("undef",                  CL_ALL,   OPT_undef)                         \
277   OPT("v",                      CL_ALL,   OPT_v)                             \
278   OPT("w",                      CL_ALL,   OPT_w)
279
280 #define OPT(text, flags, code) code,
281 enum opt_code
282 {
283   COMMAND_LINE_OPTIONS
284   N_OPTS
285 };
286 #undef OPT
287
288 struct cl_option
289 {
290   const char *opt_text;
291   unsigned char opt_len;
292   unsigned char flags;
293   ENUM_BITFIELD (opt_code) opt_code : 2 * CHAR_BIT;
294 };
295
296 #define OPT(text, flags, code) { text, sizeof(text) - 1, flags, code },
297 #ifdef HOST_EBCDIC
298 static struct cl_option cl_options[] =
299 #else
300 static const struct cl_option cl_options[] =
301 #endif
302 {
303   COMMAND_LINE_OPTIONS
304 };
305 #undef OPT
306 #undef COMMAND_LINE_OPTIONS
307
308 /* Holds switches parsed by c_common_decode_option (), but whose
309    handling is deffered to c_common_post_options ().  */
310 static void defer_opt PARAMS ((enum opt_code, const char *));
311 static struct deferred_opt
312 {
313   enum opt_code code;
314   const char *arg;
315 } *deferred_opts;
316
317
318 #ifdef HOST_EBCDIC
319 static int opt_comp PARAMS ((const void *, const void *));
320
321 /* Run-time sorting of options array.  */
322 static int
323 opt_comp (p1, p2)
324      const void *p1, *p2;
325 {
326   return strcmp (((struct cl_option *) p1)->opt_text,
327                  ((struct cl_option *) p2)->opt_text);
328 }
329 #endif
330
331 /* Complain that switch OPT_INDEX expects an argument but none was
332    provided.  */
333 static void
334 missing_arg (opt_index)
335      size_t opt_index;
336 {
337   const char *opt_text = cl_options[opt_index].opt_text;
338
339   switch (opt_index)
340     {
341     case OPT_Wformat_eq:
342     case OPT_d:
343     case OPT_fbuiltin_:
344     case OPT_fdump:
345     case OPT_fname_mangling:
346     case OPT_ftabstop:
347     case OPT_ftemplate_depth:
348     default:
349       error ("missing argument to \"-%s\"", opt_text);
350       break;
351
352     case OPT_fconstant_string_class:
353       error ("no class name specified with \"-%s\"", opt_text);
354       break;
355
356     case OPT_MF:
357     case OPT_MD:
358     case OPT_MMD:
359     case OPT_o:
360       error ("missing filename after \"-%s\"", opt_text);
361       break;
362
363     case OPT_MQ:
364     case OPT_MT:
365       error ("missing target after \"-%s\"", opt_text);
366       break;
367     }
368 }
369
370 /* Perform a binary search to find which option the command-line INPUT
371    matches.  Returns its index in the option array, and N_OPTS on
372    failure.
373
374    Complications arise since some options can be suffixed with an
375    argument, and multiple complete matches can occur, e.g. -pedantic
376    and -pedantic-errors.  Also, some options are only accepted by some
377    languages.  */
378 static size_t
379 find_opt (input, lang_flag)
380      const char *input;
381      int lang_flag;
382 {
383   size_t md, mn, mx;
384   size_t opt_len;
385   size_t wrong_lang = N_OPTS;
386   int comp;
387
388   mn = 0;
389   mx = N_OPTS;
390
391   while (mx > mn)
392     {
393       md = (mn + mx) / 2;
394
395       opt_len = cl_options[md].opt_len;
396       comp = memcmp (input, cl_options[md].opt_text, opt_len);
397
398       if (comp < 0)
399         mx = md;
400       else if (comp > 0)
401         mn = md + 1;
402       else
403         {
404           /* The switch matches.  It it an exact match?  */
405           if (input[opt_len] == '\0')
406             {
407             exact_match:
408               if (cl_options[md].flags & lang_flag)
409                 return md;
410               wrong_lang = md;
411               break;
412             }
413           else
414             {
415               mn = md + 1;
416
417               /* If the switch takes no arguments this is not a proper
418                  match, so we continue the search (e.g. input="stdc++"
419                  match was "stdc").  */
420               if (!(cl_options[md].flags & CL_JOINED))
421                 continue;
422
423               /* Is this switch valid for this front end?  */
424               if (!(cl_options[md].flags & lang_flag))
425                 {
426                   /* If subsequently we don't find a good match,
427                      report this as a bad match.  */
428                   wrong_lang = md;
429                   continue;
430                 }
431
432               /* Two scenarios remain: we have the switch's argument,
433                  or we match a longer option.  This can happen with
434                  -iwithprefix and -withprefixbefore.  The longest
435                  possible option match succeeds.
436
437                  Scan forwards, and return an exact match.  Otherwise
438                  return the longest valid option-accepting match (mx).
439                  This loops at most twice with current options.  */
440               mx = md;
441               for (md = md + 1; md < (size_t) N_OPTS; md++)
442                 {
443                   opt_len = cl_options[md].opt_len;
444                   if (memcmp (input, cl_options[md].opt_text, opt_len))
445                     break;
446                   if (input[opt_len] == '\0')
447                     goto exact_match;
448                   if (cl_options[md].flags & lang_flag
449                       && cl_options[md].flags & CL_JOINED)
450                     mx = md;
451                 }
452
453               return mx;
454             }
455         }
456     }
457
458   if (wrong_lang != N_OPTS)
459     complain_wrong_lang (wrong_lang);
460
461   return N_OPTS;
462 }
463
464 /* Defer option CODE with argument ARG.  */
465 static void
466 defer_opt (code, arg)
467      enum opt_code code;
468      const char *arg;
469 {
470   /* FIXME: this should be in c_common_init_options, which should take
471      argc and argv.  */
472   if (!deferred_opts)
473     {
474       extern int save_argc;
475       deferred_size = save_argc;
476       deferred_opts = (struct deferred_opt *)
477         xmalloc (deferred_size * sizeof (struct deferred_opt));
478     }
479
480   if (deferred_count == deferred_size)
481     abort ();
482
483   deferred_opts[deferred_count].code = code;
484   deferred_opts[deferred_count].arg = arg;
485   deferred_count++;
486 }
487
488 /* Common initialization before parsing options.  */
489 void
490 c_common_init_options (lang)
491      enum c_language_kind lang;
492 {
493 #ifdef HOST_EBCDIC
494   /* For non-ASCII hosts, the cl_options array needs to be sorted at
495      runtime.  */
496   qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
497 #endif
498
499   c_language = lang;
500   parse_in = cpp_create_reader (lang == clk_c ? CLK_GNUC89 : CLK_GNUCXX);
501   cpp_opts = cpp_get_options (parse_in);
502   if (flag_objc)
503     cpp_opts->objc = 1;
504
505   flag_const_strings = (lang == clk_cplusplus);
506   warn_pointer_arith = (lang == clk_cplusplus);
507   if (lang == clk_c)
508     warn_sign_compare = -1;
509
510   /* Mark as "unspecified" (see c_common_post_options).  */
511   flag_bounds_check = -1;
512 }
513
514 /* Handle one command-line option in (argc, argv).
515    Can be called multiple times, to handle multiple sets of options.
516    Returns number of strings consumed.  */
517 int
518 c_common_decode_option (argc, argv)
519      int argc;
520      char **argv;
521 {
522   static int lang_flags[] = {CL_C_ONLY, CL_C, CL_CXX_ONLY, CL_CXX};
523   size_t opt_index;
524   const char *opt, *arg = 0;
525   char *dup = 0;
526   bool on = true;
527   int result;
528   const struct cl_option *option;
529   enum opt_code code;
530
531   opt = argv[0];
532
533   /* Interpret "-" or a non-switch as a file name.  */
534   if (opt[0] != '-' || opt[1] == '\0')
535     {
536       if (!in_fname)
537         in_fname = opt;
538       else if (!out_fname)
539         out_fname = opt;
540       else
541         {
542           error ("too many filenames given.  Type %s --help for usage",
543                  progname);
544           return argc;
545         }
546
547       return 1;
548     }
549
550   /* Drop the "no-" from negative switches.  */
551   if ((opt[1] == 'W' || opt[1] == 'f')
552       && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
553     {
554       size_t len = strlen (opt) - 3;
555
556       dup = xmalloc (len + 1);
557       dup[0] = '-';
558       dup[1] = opt[1];
559       memcpy (dup + 2, opt + 5, len - 2 + 1);
560       opt = dup;
561       on = false;
562     }
563
564   result = cpp_handle_option (parse_in, argc, argv);
565
566   /* Skip over '-'.  */
567   opt_index = find_opt (opt + 1, lang_flags[(c_language << 1) + flag_objc]);
568   if (opt_index == N_OPTS)
569     goto done;
570
571   result = 1;
572   option = &cl_options[opt_index];
573
574   /* Sort out any argument the switch takes.  */
575   if (option->flags & CL_ARG)
576     {
577       if (option->flags & CL_JOINED)
578         {
579           /* Have arg point to the original switch.  This is because
580              some code, such as disable_builtin_function, expects its
581              argument to be persistent until the program exits.  */
582           arg = argv[0] + cl_options[opt_index].opt_len + 1;
583           if (!on)
584             arg += strlen ("no-");
585         }
586
587       /* If we don't have an argument, and CL_SEPARATE, try the next
588          argument in the vector.  */
589       if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
590         {
591           arg = argv[1];
592           result = 2;
593         }
594
595       if (!arg || *arg == '\0')
596         {
597           missing_arg (opt_index);
598           result = argc;
599           goto done;
600         }
601     }
602
603   switch (code = option->opt_code)
604     {
605     case N_OPTS: /* Shut GCC up.  */
606       break;
607
608     case OPT__help:
609       print_help ();
610       break;
611
612     case OPT_C:
613       cpp_opts->discard_comments = 0;
614       break;
615
616     case OPT_CC:
617       cpp_opts->discard_comments = 0;
618       cpp_opts->discard_comments_in_macro_exp = 0;
619       break;
620
621     case OPT_E:
622       flag_preprocess_only = 1;
623       break;
624
625     case OPT_H:
626       cpp_opts->print_include_names = 1;
627       break;
628
629     case OPT_M:
630     case OPT_MM:
631       /* When doing dependencies with -M or -MM, suppress normal
632          preprocessed output, but still do -dM etc. as software
633          depends on this.  Preprocessed output does occur if -MD, -MMD
634          or environment var dependency generation is used.  */
635       cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);
636       cpp_opts->no_output = 1;
637       cpp_opts->inhibit_warnings = 1;
638       break;
639
640     case OPT_MD:
641     case OPT_MMD:
642       cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER);
643       deps_file = arg;
644       break;
645
646     case OPT_MF:
647       deps_seen = true;
648       deps_file = arg;
649       break;
650
651     case OPT_MG:
652       deps_seen = true;
653       cpp_opts->deps.missing_files = true;
654       break;
655
656     case OPT_MP:
657       deps_seen = true;
658       cpp_opts->deps.phony_targets = true;
659       break;
660
661     case OPT_MQ:
662     case OPT_MT:
663       deps_seen = true;
664       defer_opt (code, arg);
665       break;
666
667     case OPT_P:
668       cpp_opts->no_line_commands = 1;
669       break;
670
671     case OPT_Wall:
672       set_Wunused (on);
673       set_Wformat (on);
674       set_Wimplicit (on);
675       warn_char_subscripts = on;
676       warn_missing_braces = on;
677       warn_parentheses = on;
678       warn_return_type = on;
679       warn_sequence_point = on; /* Was C only.  */
680       warn_sign_compare = on;   /* Was C++ only.  */
681       warn_switch = on;
682
683       /* Only warn about unknown pragmas that are not in system
684          headers.  */                                        
685       warn_unknown_pragmas = on;
686
687       /* We save the value of warn_uninitialized, since if they put
688          -Wuninitialized on the command line, we need to generate a
689          warning about not using it without also specifying -O.  */
690       if (warn_uninitialized != 1)
691         warn_uninitialized = (on ? 2 : 0);
692
693       if (c_language == clk_c)
694         /* We set this to 2 here, but 1 in -Wmain, so -ffreestanding
695            can turn it off only if it's not explicit.  */
696         warn_main = on * 2;
697       else
698         {
699           /* C++-specific warnings.  */
700           warn_ctor_dtor_privacy = on;
701           warn_nonvdtor = on;
702           warn_reorder = on;
703           warn_nontemplate_friend = on;
704         }
705
706       cpp_opts->warn_trigraphs = on;
707       cpp_opts->warn_comments = on;
708       cpp_opts->warn_num_sign_change = on;
709       cpp_opts->warn_multichar = on;    /* Was C++ only.  */
710       break;
711
712     case OPT_Wbad_function_cast:
713       warn_bad_function_cast = on;
714       break;
715
716     case OPT_Wcast_qual:
717       warn_cast_qual = on;
718       break;
719
720     case OPT_Wchar_subscripts:
721       warn_char_subscripts = on;
722       break;
723
724     case OPT_Wcomment:
725     case OPT_Wcomments:
726       cpp_opts->warn_comments = on;
727       break;
728
729     case OPT_Wconversion:
730       warn_conversion = on;
731       break;
732
733     case OPT_Wctor_dtor_privacy:
734       warn_ctor_dtor_privacy = on;
735       break;
736
737     case OPT_Wdeprecated:
738       warn_deprecated = on;
739       break;
740
741     case OPT_Wdiv_by_zero:
742       warn_div_by_zero = on;
743       break;
744
745     case OPT_Weffcxx:
746       warn_ecpp = on;
747       break;
748
749     case OPT_Wendif_labels:
750       cpp_opts->warn_endif_labels = on;
751       break;
752
753     case OPT_Werror:
754       cpp_opts->warnings_are_errors = on;
755       break;
756
757     case OPT_Werror_implicit_function_decl:
758       if (!on)
759         result = 0;
760       else
761         mesg_implicit_function_declaration = 2;
762       break;
763
764     case OPT_Wfloat_equal:
765       warn_float_equal = on;
766       break;
767
768     case OPT_Wformat:
769       set_Wformat (on);
770       break;
771
772     case OPT_Wformat_eq:
773       set_Wformat (atoi (arg));
774       break;
775
776     case OPT_Wformat_extra_args:
777       warn_format_extra_args = on;
778       break;
779
780     case OPT_Wformat_nonliteral:
781       warn_format_nonliteral = on;
782       break;
783
784     case OPT_Wformat_security:
785       warn_format_security = on;
786       break;
787
788     case OPT_Wformat_y2k:
789       warn_format_y2k = on;
790       break;
791
792     case OPT_Wformat_zero_length:
793       warn_format_zero_length = on;
794       break;
795
796     case OPT_Wimplicit:
797       set_Wimplicit (on);
798       break;
799
800     case OPT_Wimplicit_function_decl:
801       mesg_implicit_function_declaration = on;
802       break;
803
804     case OPT_Wimplicit_int:
805       warn_implicit_int = on;
806       break;
807
808     case OPT_Wimport:
809       cpp_opts->warn_import = on;
810       break;
811
812     case OPT_Wlong_long:
813       warn_long_long = on;
814       break;
815
816     case OPT_Wmain:
817       if (on)
818         warn_main = 1;
819       else
820         warn_main = -1;
821       break;
822
823     case OPT_Wmissing_braces:
824       warn_missing_braces = on;
825       break;
826
827     case OPT_Wmissing_declarations:
828       warn_missing_declarations = on;
829       break;
830
831     case OPT_Wmissing_format_attribute:
832       warn_missing_format_attribute = on;
833       break;
834
835     case OPT_Wmissing_prototypes:
836       warn_missing_prototypes = on;
837       break;
838
839     case OPT_Wmultichar:
840       cpp_opts->warn_multichar = on;
841       break;
842
843     case OPT_Wnested_externs:
844       warn_nested_externs = on;
845       break;
846
847     case OPT_Wnon_template_friend:
848       warn_nontemplate_friend = on;
849       break;
850
851     case OPT_Wnon_virtual_dtor:
852       warn_nonvdtor = on;
853       break;
854
855     case OPT_Wnonnull:
856       warn_nonnull = on;
857       break;
858
859     case OPT_Wold_style_cast:
860       warn_old_style_cast = on;
861       break;
862
863     case OPT_Woverloaded_virtual:
864       warn_overloaded_virtual = on;
865       break;
866
867     case OPT_Wparentheses:
868       warn_parentheses = on;
869       break;
870
871     case OPT_Wpmf_conversions:
872       warn_pmf2ptr = on;
873       break;
874
875     case OPT_Wpointer_arith:
876       warn_pointer_arith = on;
877       break;
878
879     case OPT_Wprotocol:
880       warn_protocol = on;
881       break;
882
883     case OPT_Wselector:
884       warn_selector = on;
885       break;
886
887     case OPT_Wredundant_decls:
888       warn_redundant_decls = on;
889       break;
890
891     case OPT_Wreorder:
892       warn_reorder = on;
893       break;
894
895     case OPT_Wreturn_type:
896       warn_return_type = on;
897       break;
898
899     case OPT_Wsequence_point:
900       warn_sequence_point = on;
901       break;
902
903     case OPT_Wsign_compare:
904       warn_sign_compare = on;
905       break;
906
907     case OPT_Wsign_promo:
908       warn_sign_promo = on;
909       break;
910
911     case OPT_Wstrict_prototypes:
912       if (!on && c_language == clk_cplusplus)
913         warning ("-Wno-strict-prototypes is not supported in C++");
914       else
915         warn_strict_prototypes = on;
916       break;
917
918     case OPT_Wsynth:
919       warn_synth = on;
920       break;
921
922     case OPT_Wsystem_headers:
923       cpp_opts->warn_system_headers = on;
924       break;
925
926     case OPT_Wtraditional:
927       warn_traditional = on;
928       cpp_opts->warn_traditional = on;
929       break;
930
931     case OPT_Wtrigraphs:
932       cpp_opts->warn_trigraphs = on;
933       break;
934
935     case OPT_Wundef:
936       cpp_opts->warn_undef = on;
937       break;
938
939     case OPT_Wunknown_pragmas:
940       /* Set to greater than 1, so that even unknown pragmas in
941          system headers will be warned about.  */  
942       warn_unknown_pragmas = on * 2;
943       break;
944
945     case OPT_Wunused_macros:
946       cpp_opts->warn_unused_macros = on;
947       break;
948
949     case OPT_Wwrite_strings:
950       if (c_language == clk_c)
951         flag_const_strings = on;
952       else
953         warn_write_strings = on;
954       break;
955       
956     case OPT_ansi:
957       if (c_language == clk_c)
958         set_std_c89 (false, true);
959       else
960         set_std_cxx98 (true);
961       break;
962
963     case OPT_d:
964       handle_OPT_d (arg);
965       break;
966
967     case OPT_fcond_mismatch:
968       if (c_language == clk_c)
969         {
970           flag_cond_mismatch = on;
971           break;
972         }
973       /* Fall through.  */
974
975     case OPT_fall_virtual:
976     case OPT_fenum_int_equiv:
977     case OPT_fguiding_decls:
978     case OPT_fhonor_std:
979     case OPT_fhuge_objects:
980     case OPT_flabels_ok:
981     case OPT_fname_mangling:
982     case OPT_fnew_abi:
983     case OPT_fnonnull_objects:
984     case OPT_fsquangle:
985     case OPT_fstrict_prototype:
986     case OPT_fthis_is_variable:
987     case OPT_fvtable_thunks:
988     case OPT_fxref:
989       warning ("switch \"%s\" is no longer supported", argv[0]);
990       break;
991
992     case OPT_faccess_control:
993       flag_access_control = on;
994       break;
995
996     case OPT_falt_external_templates:
997       flag_alt_external_templates = on;
998       if (on)
999         flag_external_templates = true;
1000     cp_deprecated:
1001       warning ("switch \"%s\" is deprecated, please see documentation for details", argv[0]);
1002       break;
1003
1004     case OPT_fasm:
1005       flag_no_asm = !on;
1006       break;
1007
1008     case OPT_fbuiltin:
1009       flag_no_builtin = !on;
1010       break;
1011
1012     case OPT_fbuiltin_:
1013       if (on)
1014         result = 0;
1015       else
1016         disable_builtin_function (arg);
1017       break;
1018
1019     case OPT_fdollars_in_identifiers:
1020       dollars_in_ident = on;
1021       break;
1022
1023     case OPT_fdump:
1024       if (!on || !dump_switch_p (argv[0] + strlen ("-f")))
1025         result = 0;
1026       break;
1027
1028     case OPT_ffreestanding:
1029       on = !on;
1030       /* Fall through...  */
1031     case OPT_fhosted:
1032       flag_hosted = on;
1033       flag_no_builtin = !on;
1034       /* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */
1035       if (!on && warn_main == 2)
1036         warn_main = 0;
1037       break;
1038
1039     case OPT_fshort_double:
1040       flag_short_double = on;
1041       break;
1042
1043     case OPT_fshort_enums:
1044       flag_short_enums = on;
1045       break;
1046
1047     case OPT_fshort_wchar:
1048       flag_short_wchar = on;
1049       break;
1050
1051     case OPT_fsigned_bitfields:
1052       flag_signed_bitfields = on;
1053       explicit_flag_signed_bitfields = 1;
1054       break;
1055
1056     case OPT_fsigned_char:
1057       flag_signed_char = on;
1058       break;
1059
1060     case OPT_funsigned_bitfields:
1061       flag_signed_bitfields = !on;
1062       explicit_flag_signed_bitfields = 1;
1063       break;
1064
1065     case OPT_funsigned_char:
1066       flag_signed_char = !on;
1067       break;
1068
1069     case OPT_fcheck_new:
1070       flag_check_new = on;
1071       break;
1072
1073     case OPT_fconserve_space:
1074       flag_conserve_space = on;
1075       break;
1076
1077     case OPT_fconst_strings:
1078       flag_const_strings = on;
1079       break;
1080
1081     case OPT_fconstant_string_class:
1082       constant_string_class_name = arg;
1083       break;
1084
1085     case OPT_fdefault_inline:
1086       flag_default_inline = on;
1087       break;
1088
1089     case OPT_felide_constructors:
1090       flag_elide_constructors = on;
1091       break;
1092
1093     case OPT_fenforce_eh_specs:
1094       flag_enforce_eh_specs = on;
1095       break;
1096
1097     case OPT_fexternal_templates:
1098       flag_external_templates = on;
1099       goto cp_deprecated;
1100
1101     case OPT_ffor_scope:
1102       flag_new_for_scope = on;
1103       break;
1104
1105     case OPT_fgnu_keywords:
1106       flag_no_gnu_keywords = !on;
1107       break;
1108
1109     case OPT_fgnu_runtime:
1110       flag_next_runtime = !on;
1111       break;
1112
1113     case OPT_fhandle_exceptions:
1114       warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
1115       flag_exceptions = on;
1116       break;
1117
1118     case OPT_fimplement_inlines:
1119       flag_implement_inlines = on;
1120       break;
1121
1122     case OPT_fimplicit_inline_templates:
1123       flag_implicit_inline_templates = on;
1124       break;
1125
1126     case OPT_fimplicit_templates:
1127       flag_implicit_templates = on;
1128       break;
1129
1130     case OPT_fms_extensions:
1131       flag_ms_extensions = on;
1132       break;
1133
1134     case OPT_fnext_runtime:
1135       flag_next_runtime = on;
1136       break;
1137
1138     case OPT_fnonansi_builtins:
1139       flag_no_nonansi_builtin = !on;
1140       break;
1141
1142     case OPT_foperator_names:
1143       cpp_opts->operator_names = on;
1144       break;
1145
1146     case OPT_foptional_diags:
1147       flag_optional_diags = on;
1148       break;
1149
1150     case OPT_fpermissive:
1151       flag_permissive = on;
1152       break;
1153
1154     case OPT_fpreprocessed:
1155       cpp_opts->preprocessed = on;
1156       break;
1157
1158     case OPT_frepo:
1159       flag_use_repository = on;
1160       if (on)
1161         flag_implicit_templates = 0;
1162       break;
1163
1164     case OPT_frtti:
1165       flag_rtti = on;
1166       break;
1167
1168     case OPT_fshow_column:
1169       cpp_opts->show_column = on;
1170       break;
1171
1172     case OPT_fstats:
1173       flag_detailed_statistics = on;
1174       break;
1175
1176     case OPT_ftabstop:
1177       /* Don't recognise -fno-tabstop=.  */
1178       if (!on)
1179         return 0;
1180
1181       /* It is documented that we silently ignore silly values.  */
1182         {
1183           char *endptr;
1184           long tabstop = strtol (arg, &endptr, 10);
1185           if (*endptr == '\0' && tabstop >= 1 && tabstop <= 100)
1186             cpp_opts->tabstop = tabstop;
1187         }
1188       break;
1189
1190     case OPT_ftemplate_depth:
1191       max_tinst_depth = read_integral_parameter (arg, argv[0], 0);
1192       break;
1193
1194     case OPT_fvtable_gc:
1195       flag_vtable_gc = on;
1196       break;
1197
1198     case OPT_fuse_cxa_atexit:
1199       flag_use_cxa_atexit = on;
1200       break;
1201
1202     case OPT_fweak:
1203       flag_weak = on;
1204       break;
1205
1206     case OPT_gen_decls:
1207       flag_gen_declaration = 1;
1208       break;
1209
1210     case OPT_lang_asm:
1211       cpp_set_lang (parse_in, CLK_ASM);
1212       break;
1213
1214     case OPT_lang_objc:
1215       cpp_opts->objc = 1;
1216       break;
1217
1218     case OPT_nostdinc:
1219       /* No default include directories.  You must specify all
1220          include-file directories with -I.  */
1221       cpp_opts->no_standard_includes = 1;
1222       break;
1223
1224     case OPT_nostdincplusplus:
1225       /* No default C++-specific include directories.  */
1226       cpp_opts->no_standard_cplusplus_includes = 1;
1227       break;
1228
1229     case OPT_o:
1230       if (!out_fname)
1231         out_fname = arg;
1232       else
1233         {
1234           error ("output filename specified twice");
1235           result = argc;
1236         }
1237       break;
1238
1239       /* We need to handle the -pedantic switches here, rather than in
1240          c_common_post_options, so that a subsequent -Wno-endif-labels
1241          is not overridden.  */
1242     case OPT_pedantic_errors:
1243       cpp_opts->pedantic_errors = 1;
1244       /* fall through */
1245     case OPT_pedantic:
1246       cpp_opts->pedantic = 1;
1247       cpp_opts->warn_endif_labels = 1;
1248       break;
1249
1250     case OPT_print_objc_runtime_info:
1251       print_struct_values = 1;
1252       break;
1253
1254     case OPT_remap:
1255       cpp_opts->remap = 1;
1256       break;
1257
1258     case OPT_std_cplusplus98:
1259     case OPT_std_gnuplusplus98:
1260       set_std_cxx98 (code == OPT_std_cplusplus98 /* ISO */);
1261       break;
1262
1263     case OPT_std_c89:
1264     case OPT_std_iso9899_1990:
1265     case OPT_std_iso9899_199409:
1266       set_std_c89 (code == OPT_std_iso9899_199409 /* c94 */, true /* ISO */);
1267       break;
1268
1269     case OPT_std_gnu89:
1270       set_std_c89 (false /* c94 */, false /* ISO */);
1271       break;
1272
1273     case OPT_std_c99:
1274     case OPT_std_c9x:
1275     case OPT_std_iso9899_1999:
1276     case OPT_std_iso9899_199x:
1277       set_std_c99 (true /* ISO */);
1278       break;
1279
1280     case OPT_std_gnu99:
1281     case OPT_std_gnu9x:
1282       set_std_c99 (false /* ISO */);
1283       break;
1284
1285     case OPT_trigraphs:
1286       cpp_opts->trigraphs = 1;
1287       break;
1288
1289     case OPT_traditional_cpp:
1290       cpp_opts->traditional = 1;
1291       break;
1292
1293     case OPT_undef:
1294       flag_undef = 1;
1295       break;
1296
1297     case OPT_w:
1298       cpp_opts->inhibit_warnings = 1;
1299       break;
1300
1301     case OPT_v:
1302       cpp_opts->verbose = 1;
1303       break;
1304     }
1305
1306  done:
1307   if (dup)
1308     free (dup);
1309   return result;
1310 }
1311
1312 /* Post-switch processing.  */
1313 bool
1314 c_common_post_options ()
1315 {
1316   /* Canonicalize the input and output filenames.  */
1317   if (in_fname == NULL || !strcmp (in_fname, "-"))
1318     in_fname = "";
1319
1320   if (out_fname == NULL || !strcmp (out_fname, "-"))
1321     out_fname = "";
1322
1323   if (cpp_opts->deps.style != DEPS_NONE)
1324     check_deps_environment_vars ();
1325
1326   handle_deferred_opts ();
1327
1328   sanitize_cpp_opts ();
1329
1330   flag_inline_trees = 1;
1331
1332   /* Use tree inlining if possible.  Function instrumentation is only
1333      done in the RTL level, so we disable tree inlining.  */
1334   if (! flag_instrument_function_entry_exit)
1335     {
1336       if (!flag_no_inline)
1337         flag_no_inline = 1;
1338       if (flag_inline_functions)
1339         {
1340           flag_inline_trees = 2;
1341           flag_inline_functions = 0;
1342         }
1343     }
1344
1345   /* If still "unspecified", make it match -fbounded-pointers.  */
1346   if (flag_bounds_check == -1)
1347     flag_bounds_check = flag_bounded_pointers;
1348
1349   /* Special format checking options don't work without -Wformat; warn if
1350      they are used.  */
1351   if (warn_format_y2k && !warn_format)
1352     warning ("-Wformat-y2k ignored without -Wformat");
1353   if (warn_format_extra_args && !warn_format)
1354     warning ("-Wformat-extra-args ignored without -Wformat");
1355   if (warn_format_zero_length && !warn_format)
1356     warning ("-Wformat-zero-length ignored without -Wformat");
1357   if (warn_format_nonliteral && !warn_format)
1358     warning ("-Wformat-nonliteral ignored without -Wformat");
1359   if (warn_format_security && !warn_format)
1360     warning ("-Wformat-security ignored without -Wformat");
1361   if (warn_missing_format_attribute && !warn_format)
1362     warning ("-Wmissing-format-attribute ignored without -Wformat");
1363
1364   /* If an error has occurred in cpplib, note it so we fail
1365      immediately.  */
1366   errorcount += cpp_errors (parse_in);
1367
1368   return flag_preprocess_only;
1369 }
1370
1371 /* Preprocess the input file to out_stream.  */
1372 static void
1373 preprocess_file ()
1374 {
1375   /* Open the output now.  We must do so even if no_output is on,
1376      because there may be other output than from the actual
1377      preprocessing (e.g. from -dM).  */
1378   if (out_fname[0] == '\0')
1379     out_stream = stdout;
1380   else
1381     out_stream = fopen (out_fname, "w");
1382
1383   if (out_stream == NULL)
1384     fatal_io_error ("opening output file %s", out_fname);
1385   else
1386     cpp_preprocess_file (parse_in, in_fname, out_stream);
1387 }
1388
1389 /* Front end initialization common to C, ObjC and C++.  */
1390 const char *
1391 c_common_init (filename)
1392      const char *filename;
1393 {
1394   /* Set up preprocessor arithmetic.  Must be done after call to
1395      c_common_nodes_and_builtins for type nodes to be good.  */
1396   cpp_opts->precision = TYPE_PRECISION (intmax_type_node);
1397   cpp_opts->char_precision = TYPE_PRECISION (char_type_node);
1398   cpp_opts->int_precision = TYPE_PRECISION (integer_type_node);
1399   cpp_opts->wchar_precision = TYPE_PRECISION (wchar_type_node);
1400   cpp_opts->unsigned_wchar = TREE_UNSIGNED (wchar_type_node);
1401
1402   /* Register preprocessor built-ins before calls to
1403      cpp_main_file.  */
1404   cpp_get_callbacks (parse_in)->register_builtins = cb_register_builtins;
1405
1406   /* NULL is passed up to toplev.c and we exit quickly.  */
1407   if (flag_preprocess_only)
1408     {
1409       preprocess_file ();
1410       return NULL;
1411     }
1412
1413   /* Do this before initializing pragmas, as then cpplib's hash table
1414      has been set up.  NOTE: we are using our own file name here, not
1415      the one supplied.  */
1416   filename = init_c_lex (in_fname);
1417
1418   init_pragma ();
1419
1420   return filename;
1421 }
1422
1423 /* Common finish hook for the C, ObjC and C++ front ends.  */
1424 void
1425 c_common_finish ()
1426 {
1427   FILE *deps_stream = NULL;
1428
1429   if (cpp_opts->deps.style != DEPS_NONE)
1430     {
1431       /* If -M or -MM was seen without -MF, default output to the
1432          output stream.  */
1433       if (!deps_file)
1434         deps_stream = out_stream;
1435       else
1436         {
1437           deps_stream = fopen (deps_file, deps_append ? "a": "w");
1438           if (!deps_stream)
1439             fatal_io_error ("opening dependency file %s", deps_file);
1440         }
1441     }
1442
1443   /* For performance, avoid tearing down cpplib's internal structures
1444      with cpp_destroy ().  */
1445   errorcount += cpp_finish (parse_in, deps_stream);
1446
1447   if (deps_stream && deps_stream != out_stream
1448       && (ferror (deps_stream) || fclose (deps_stream)))
1449     fatal_io_error ("closing dependency file %s", deps_file);
1450
1451   if (out_stream && (ferror (out_stream) || fclose (out_stream)))
1452     fatal_io_error ("when writing output to %s", out_fname);
1453 }
1454
1455 /* Either of two environment variables can specify output of
1456    dependencies.  Their value is either "OUTPUT_FILE" or "OUTPUT_FILE
1457    DEPS_TARGET", where OUTPUT_FILE is the file to write deps info to
1458    and DEPS_TARGET is the target to mention in the deps.  They also
1459    result in dependency information being appended to the output file
1460    rather than overwriting it.  */
1461 static void
1462 check_deps_environment_vars ()
1463 {
1464   char *spec;
1465
1466   GET_ENVIRONMENT (spec, "DEPENDENCIES_OUTPUT");
1467   if (spec)
1468     cpp_opts->deps.style = DEPS_USER;
1469   else
1470     {
1471       GET_ENVIRONMENT (spec, "SUNPRO_DEPENDENCIES");
1472       if (spec)
1473         cpp_opts->deps.style = DEPS_SYSTEM;
1474     }
1475
1476   if (spec)
1477     {
1478       /* Find the space before the DEPS_TARGET, if there is one.  */
1479       char *s = strchr (spec, ' ');
1480       if (s)
1481         {
1482           /* Let the caller perform MAKE quoting.  */
1483           defer_opt (OPT_MT, s + 1);
1484           *s = '\0';
1485         }
1486
1487       /* Command line -MF overrides environment variables and default.  */
1488       if (!deps_file)
1489         deps_file = spec;
1490
1491       deps_append = 1;
1492     }
1493 }
1494
1495 /* Handle deferred command line switches.  */
1496 static void
1497 handle_deferred_opts ()
1498 {
1499   size_t i;
1500
1501   for (i = 0; i < deferred_count; i++)
1502     {
1503       struct deferred_opt *opt = &deferred_opts[i];
1504
1505       switch (opt->code)
1506         {
1507         case OPT_MT:
1508         case OPT_MQ:
1509           cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ);
1510           break;
1511
1512         default:
1513           abort ();
1514         }
1515     }
1516
1517   free (deferred_opts);
1518 }
1519
1520 /* These settings are appropriate for GCC, but not necessarily so for
1521    cpplib as a library.  */
1522 static void
1523 sanitize_cpp_opts ()
1524 {
1525   /* If we don't know what style of dependencies to output, complain
1526      if any other dependency switches have been given.  */
1527   if (deps_seen && cpp_opts->deps.style == DEPS_NONE)
1528     error ("to generate dependencies you must specify either -M or -MM");
1529
1530   /* -dM and dependencies suppress normal output; do it here so that
1531      the last -d[MDN] switch overrides earlier ones.  */
1532   if (cpp_opts->dump_macros == dump_only)
1533     cpp_opts->no_output = 1;
1534
1535   /* Disable -dD, -dN and -dI if normal output is suppressed.  Allow
1536      -dM since at least glibc relies on -M -dM to work.  */
1537   if (cpp_opts->no_output)
1538     {
1539       if (cpp_opts->dump_macros != dump_only)
1540         cpp_opts->dump_macros = dump_none;
1541       cpp_opts->dump_includes = 0;
1542     }
1543
1544   cpp_opts->unsigned_char = !flag_signed_char;
1545   cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
1546
1547   /* We want -Wno-long-long to override -pedantic -std=non-c99
1548      and/or -Wtraditional, whatever the ordering.  */
1549   cpp_opts->warn_long_long
1550     = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
1551 }
1552
1553 /* Set the C 89 standard (with 1994 amendments if C94, without GNU
1554    extensions if ISO).  There is no concept of gnu94.  */
1555 static void
1556 set_std_c89 (c94, iso)
1557      int c94, iso;
1558 {
1559   cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89);
1560   flag_iso = iso;
1561   flag_no_asm = iso;
1562   flag_no_gnu_keywords = iso;
1563   flag_no_nonansi_builtin = iso;
1564   flag_noniso_default_format_attributes = !iso;
1565   flag_isoc94 = c94;
1566   flag_isoc99 = 0;
1567   flag_writable_strings = 0;
1568 }
1569
1570 /* Set the C 99 standard (without GNU extensions if ISO).  */
1571 static void
1572 set_std_c99 (iso)
1573      int iso;
1574 {
1575   cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99);
1576   flag_no_asm = iso;
1577   flag_no_nonansi_builtin = iso;
1578   flag_noniso_default_format_attributes = !iso;
1579   flag_iso = iso;
1580   flag_isoc99 = 1;
1581   flag_isoc94 = 1;
1582   flag_writable_strings = 0;
1583 }
1584
1585 /* Set the C++ 98 standard (without GNU extensions if ISO).  */
1586 static void
1587 set_std_cxx98 (iso)
1588      int iso;
1589 {
1590   cpp_set_lang (parse_in, iso ? CLK_CXX98: CLK_GNUCXX);
1591   flag_no_gnu_keywords = iso;
1592   flag_no_nonansi_builtin = iso;
1593   flag_noniso_default_format_attributes = !iso;
1594   flag_iso = iso;
1595 }
1596
1597 /* Handle setting implicit to ON.  */
1598 static void
1599 set_Wimplicit (on)
1600      int on;
1601 {
1602   warn_implicit = on;
1603   warn_implicit_int = on;
1604   if (on)
1605     {
1606       if (mesg_implicit_function_declaration != 2)
1607         mesg_implicit_function_declaration = 1;
1608     }
1609   else
1610     mesg_implicit_function_declaration = 0;
1611 }
1612
1613 /* Args to -d specify what to dump.  Silently ignore
1614    unrecognised options; they may be aimed at toplev.c.  */
1615 static void
1616 handle_OPT_d (arg)
1617      const char *arg;
1618 {
1619   char c;
1620
1621   while ((c = *arg++) != '\0')
1622     switch (c)
1623       {
1624       case 'M':
1625         cpp_opts->dump_macros = dump_only;
1626         break;
1627
1628       case 'N':
1629         cpp_opts->dump_macros = dump_names;
1630         break;
1631
1632       case 'D':
1633         cpp_opts->dump_macros = dump_definitions;
1634         break;
1635
1636       case 'I':
1637         cpp_opts->dump_includes = 1;
1638         break;
1639       }
1640 }
1641
1642 /* Write a slash-separated list of languages in FLAGS to BUF.  */
1643 static void
1644 write_langs (buf, flags)
1645      char *buf;
1646      int flags;
1647 {
1648   *buf = '\0';
1649   if (flags & CL_C_ONLY)
1650     strcat (buf, "C");
1651   if (flags & CL_OBJC_ONLY)
1652     {
1653       if (*buf)
1654         strcat (buf, "/");
1655       strcat (buf, "ObjC");
1656     }
1657   if (flags & CL_CXX_ONLY)
1658     {
1659       if (*buf)
1660         strcat (buf, "/");
1661       strcat (buf, "C++");
1662     }
1663 }
1664
1665 /* Complain that switch OPT_INDEX does not apply to this front end.  */
1666 static void
1667 complain_wrong_lang (opt_index)
1668      size_t opt_index;
1669 {
1670   char ok_langs[60], bad_langs[60];
1671   int ok_flags = cl_options[opt_index].flags;
1672
1673   write_langs (ok_langs, ok_flags);
1674   write_langs (bad_langs, ~ok_flags);
1675   warning ("\"-%s\" is valid for %s but not for %s",
1676            cl_options[opt_index].opt_text, ok_langs, bad_langs);
1677 }
1678
1679 /* Handle --help output.  */
1680 static void
1681 print_help ()
1682 {
1683   /* To keep the lines from getting too long for some compilers, limit
1684      to about 500 characters (6 lines) per chunk.  */
1685   fputs (_("\
1686 Switches:\n\
1687   -include <file>           Include the contents of <file> before other files\n\
1688   -imacros <file>           Accept definition of macros in <file>\n\
1689   -iprefix <path>           Specify <path> as a prefix for next two options\n\
1690   -iwithprefix <dir>        Add <dir> to the end of the system include path\n\
1691   -iwithprefixbefore <dir>  Add <dir> to the end of the main include path\n\
1692   -isystem <dir>            Add <dir> to the start of the system include path\n\
1693 "), stdout);
1694   fputs (_("\
1695   -idirafter <dir>          Add <dir> to the end of the system include path\n\
1696   -I <dir>                  Add <dir> to the end of the main include path\n\
1697   -I-                       Fine-grained include path control; see info docs\n\
1698   -nostdinc                 Do not search system include directories\n\
1699                              (dirs specified with -isystem will still be used)\n\
1700   -nostdinc++               Do not search system include directories for C++\n\
1701   -o <file>                 Put output into <file>\n\
1702 "), stdout);
1703   fputs (_("\
1704   -trigraphs                Support ISO C trigraphs\n\
1705   -std=<std name>           Specify the conformance standard; one of:\n\
1706                             gnu89, gnu99, c89, c99, iso9899:1990,\n\
1707                             iso9899:199409, iso9899:1999, c++98\n\
1708   -w                        Inhibit warning messages\n\
1709   -W[no-]trigraphs          Warn if trigraphs are encountered\n\
1710   -W[no-]comment{s}         Warn if one comment starts inside another\n\
1711 "), stdout);
1712   fputs (_("\
1713   -W[no-]traditional        Warn about features not present in traditional C\n\
1714   -W[no-]undef              Warn if an undefined macro is used by #if\n\
1715   -W[no-]import             Warn about the use of the #import directive\n\
1716 "), stdout);
1717   fputs (_("\
1718   -W[no-]error              Treat all warnings as errors\n\
1719   -W[no-]system-headers     Do not suppress warnings from system headers\n\
1720   -W[no-]all                Enable most preprocessor warnings\n\
1721 "), stdout);
1722   fputs (_("\
1723   -M                        Generate make dependencies\n\
1724   -MM                       As -M, but ignore system header files\n\
1725   -MD                       Generate make dependencies and compile\n\
1726   -MMD                      As -MD, but ignore system header files\n\
1727   -MF <file>                Write dependency output to the given file\n\
1728   -MG                       Treat missing header file as generated files\n\
1729 "), stdout);
1730   fputs (_("\
1731   -MP                       Generate phony targets for all headers\n\
1732   -MQ <target>              Add a MAKE-quoted target\n\
1733   -MT <target>              Add an unquoted target\n\
1734 "), stdout);
1735   fputs (_("\
1736   -D<macro>                 Define a <macro> with string '1' as its value\n\
1737   -D<macro>=<val>           Define a <macro> with <val> as its value\n\
1738   -A<question>=<answer>     Assert the <answer> to <question>\n\
1739   -A-<question>=<answer>    Disable the <answer> to <question>\n\
1740   -U<macro>                 Undefine <macro> \n\
1741   -v                        Display the version number\n\
1742 "), stdout);
1743   fputs (_("\
1744   -H                        Print the name of header files as they are used\n\
1745   -C                        Do not discard comments\n\
1746   -dM                       Display a list of macro definitions active at end\n\
1747   -dD                       Preserve macro definitions in output\n\
1748   -dN                       As -dD except that only the names are preserved\n\
1749   -dI                       Include #include directives in the output\n\
1750 "), stdout);
1751   fputs (_("\
1752   -f[no-]preprocessed       Treat the input file as already preprocessed\n\
1753   -ftabstop=<number>        Distance between tab stops for column reporting\n\
1754   -P                        Do not generate #line directives\n\
1755   -remap                    Remap file names when including files\n\
1756   --help                    Display this information\n\
1757 "), stdout);
1758 }