1 | /* C/ObjC/C++ command line option handling. |
2 | Copyright (C) 2002-2023 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 3, 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 COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ |
20 | |
21 | #include "config.h" |
22 | #include "system.h" |
23 | #include "coretypes.h" |
24 | #include "tm.h" |
25 | #include "c-target.h" |
26 | #include "c-common.h" |
27 | #include "memmodel.h" |
28 | #include "tm_p.h" /* For C_COMMON_OVERRIDE_OPTIONS. */ |
29 | #include "diagnostic.h" |
30 | #include "c-pragma.h" |
31 | #include "flags.h" |
32 | #include "toplev.h" |
33 | #include "langhooks.h" |
34 | #include "tree-diagnostic.h" /* for virt_loc_aware_diagnostic_finalizer */ |
35 | #include "intl.h" |
36 | #include "cppdefault.h" |
37 | #include "incpath.h" |
38 | #include "debug.h" /* For debug_hooks. */ |
39 | #include "opts.h" |
40 | #include "plugin.h" /* For PLUGIN_INCLUDE_FILE event. */ |
41 | #include "mkdeps.h" |
42 | #include "dumpfile.h" |
43 | #include "file-prefix-map.h" /* add_*_prefix_map() */ |
44 | #include "context.h" |
45 | |
46 | #ifndef DOLLARS_IN_IDENTIFIERS |
47 | # define DOLLARS_IN_IDENTIFIERS true |
48 | #endif |
49 | |
50 | #ifndef TARGET_SYSTEM_ROOT |
51 | # define TARGET_SYSTEM_ROOT NULL |
52 | #endif |
53 | |
54 | #ifndef TARGET_OPTF |
55 | #define TARGET_OPTF(ARG) |
56 | #endif |
57 | |
58 | /* CPP's options. */ |
59 | cpp_options *cpp_opts; |
60 | |
61 | /* Input filename. */ |
62 | static const char *this_input_filename; |
63 | |
64 | /* Filename and stream for preprocessed output. */ |
65 | static const char *out_fname; |
66 | static FILE *out_stream; |
67 | |
68 | /* Append dependencies to deps_file. */ |
69 | static bool deps_append; |
70 | |
71 | /* If dependency switches (-MF etc.) have been given. */ |
72 | static bool deps_seen; |
73 | |
74 | /* If -v seen. */ |
75 | static bool verbose; |
76 | |
77 | /* Dependency output file. */ |
78 | static const char *deps_file; |
79 | |
80 | /* Structured dependency output file. */ |
81 | static const char *fdeps_file; |
82 | |
83 | /* The prefix given by -iprefix, if any. */ |
84 | static const char *iprefix; |
85 | |
86 | /* The multilib directory given by -imultilib, if any. */ |
87 | static const char *imultilib; |
88 | |
89 | /* The system root, if any. Overridden by -isysroot. */ |
90 | static const char *sysroot = TARGET_SYSTEM_ROOT; |
91 | |
92 | /* Zero disables all standard directories for headers. */ |
93 | static bool std_inc = true; |
94 | |
95 | /* Zero disables the C++-specific standard directories for headers. */ |
96 | static bool std_cxx_inc = true; |
97 | |
98 | /* If the quote chain has been split by -I-. */ |
99 | static bool quote_chain_split; |
100 | |
101 | /* Number of deferred options. */ |
102 | static size_t deferred_count; |
103 | |
104 | /* Number of deferred options scanned for -include. */ |
105 | static size_t include_cursor; |
106 | |
107 | /* Whether any standard preincluded header has been preincluded. */ |
108 | static bool done_preinclude; |
109 | |
110 | static void handle_OPT_d (const char *); |
111 | static void set_std_cxx98 (int); |
112 | static void set_std_cxx11 (int); |
113 | static void set_std_cxx14 (int); |
114 | static void set_std_cxx17 (int); |
115 | static void set_std_cxx20 (int); |
116 | static void set_std_cxx23 (int); |
117 | static void set_std_cxx26 (int); |
118 | static void set_std_c89 (int, int); |
119 | static void set_std_c99 (int); |
120 | static void set_std_c11 (int); |
121 | static void set_std_c17 (int); |
122 | static void set_std_c23 (int); |
123 | static void check_deps_environment_vars (void); |
124 | static void handle_deferred_opts (void); |
125 | static void sanitize_cpp_opts (void); |
126 | static void add_prefixed_path (const char *, incpath_kind); |
127 | static void push_command_line_include (void); |
128 | static void cb_file_change (cpp_reader *, const line_map_ordinary *); |
129 | static void cb_dir_change (cpp_reader *, const char *); |
130 | static void c_finish_options (void); |
131 | |
132 | #ifndef STDC_0_IN_SYSTEM_HEADERS |
133 | #define 0 |
134 | #endif |
135 | |
136 | /* Holds switches parsed by c_common_handle_option (), but whose |
137 | handling is deferred to c_common_post_options (). */ |
138 | static void defer_opt (enum opt_code, const char *); |
139 | static struct deferred_opt |
140 | { |
141 | enum opt_code code; |
142 | const char *arg; |
143 | } *deferred_opts; |
144 | |
145 | |
146 | extern const unsigned int |
147 | c_family_lang_mask = (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX); |
148 | |
149 | /* Defer option CODE with argument ARG. */ |
150 | static void |
151 | defer_opt (enum opt_code code, const char *arg) |
152 | { |
153 | deferred_opts[deferred_count].code = code; |
154 | deferred_opts[deferred_count].arg = arg; |
155 | deferred_count++; |
156 | } |
157 | |
158 | /* Return language mask for option parsing. */ |
159 | unsigned int |
160 | c_common_option_lang_mask (void) |
161 | { |
162 | static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX}; |
163 | |
164 | return lang_flags[c_language]; |
165 | } |
166 | |
167 | /* Diagnostic finalizer for C/C++/Objective-C/Objective-C++. */ |
168 | static void |
169 | c_diagnostic_finalizer (diagnostic_context *context, |
170 | diagnostic_info *diagnostic, |
171 | diagnostic_t) |
172 | { |
173 | char *saved_prefix = pp_take_prefix (context->printer); |
174 | pp_set_prefix (context->printer, NULL); |
175 | pp_newline (context->printer); |
176 | diagnostic_show_locus (context, richloc: diagnostic->richloc, diagnostic_kind: diagnostic->kind); |
177 | /* By default print macro expansion contexts in the diagnostic |
178 | finalizer -- for tokens resulting from macro expansion. */ |
179 | virt_loc_aware_diagnostic_finalizer (context, diagnostic); |
180 | pp_set_prefix (context->printer, saved_prefix); |
181 | pp_flush (context->printer); |
182 | } |
183 | |
184 | /* Common default settings for diagnostics. */ |
185 | void |
186 | c_common_diagnostics_set_defaults (diagnostic_context *context) |
187 | { |
188 | diagnostic_finalizer (context) = c_diagnostic_finalizer; |
189 | context->m_opt_permissive = OPT_fpermissive; |
190 | } |
191 | |
192 | /* Input charset configuration for diagnostics. */ |
193 | static const char * |
194 | c_common_input_charset_cb (const char * /*filename*/) |
195 | { |
196 | const char *cs = cpp_opts->input_charset; |
197 | return cpp_input_conversion_is_trivial (input_charset: cs) ? nullptr : cs; |
198 | } |
199 | |
200 | /* Whether options from all C-family languages should be accepted |
201 | quietly. */ |
202 | static bool accept_all_c_family_options = false; |
203 | |
204 | /* Return whether to complain about a wrong-language option. */ |
205 | bool |
206 | c_common_complain_wrong_lang_p (const struct cl_option *option) |
207 | { |
208 | if (accept_all_c_family_options |
209 | && (option->flags & c_family_lang_mask)) |
210 | return false; |
211 | |
212 | return true; |
213 | } |
214 | |
215 | /* Initialize options structure OPTS. */ |
216 | void |
217 | c_common_init_options_struct (struct gcc_options *opts) |
218 | { |
219 | opts->x_flag_exceptions = c_dialect_cxx (); |
220 | opts->x_warn_pointer_arith = c_dialect_cxx (); |
221 | opts->x_warn_write_strings = c_dialect_cxx (); |
222 | opts->x_flag_warn_unused_result = true; |
223 | |
224 | /* By default, C99-like requirements for complex multiply and divide. */ |
225 | opts->x_flag_complex_method = 2; |
226 | opts->x_flag_default_complex_method = opts->x_flag_complex_method; |
227 | } |
228 | |
229 | /* Common initialization before calling option handlers. */ |
230 | void |
231 | c_common_init_options (unsigned int decoded_options_count, |
232 | struct cl_decoded_option *decoded_options) |
233 | { |
234 | unsigned int i; |
235 | struct cpp_callbacks *cb; |
236 | |
237 | g_string_concat_db |
238 | = new (ggc_alloc <string_concat_db> ()) string_concat_db (); |
239 | |
240 | parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89, |
241 | ident_hash, line_table, ident_hash_extra); |
242 | cb = cpp_get_callbacks (parse_in); |
243 | cb->diagnostic = c_cpp_diagnostic; |
244 | |
245 | cpp_opts = cpp_get_options (parse_in); |
246 | cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS; |
247 | cpp_opts->objc = c_dialect_objc (); |
248 | cpp_opts->deps.modules = true; |
249 | |
250 | /* Reset to avoid warnings on internal definitions. We set it just |
251 | before passing on command-line options to cpplib. */ |
252 | cpp_opts->warn_dollars = 0; |
253 | |
254 | deferred_opts = XNEWVEC (struct deferred_opt, decoded_options_count); |
255 | |
256 | if (c_language == clk_c) |
257 | { |
258 | /* The default for C is gnu17. */ |
259 | set_std_c17 (false /* ISO */); |
260 | |
261 | /* If preprocessing assembly language, accept any of the C-family |
262 | front end options since the driver may pass them through. */ |
263 | for (i = 1; i < decoded_options_count; i++) |
264 | if (decoded_options[i].opt_index == OPT_lang_asm) |
265 | { |
266 | accept_all_c_family_options = true; |
267 | break; |
268 | } |
269 | } |
270 | |
271 | /* Set C++ standard to C++17 if not specified on the command line. */ |
272 | if (c_dialect_cxx ()) |
273 | set_std_cxx17 (/*ISO*/false); |
274 | |
275 | global_dc->m_source_printing.colorize_source_p = true; |
276 | } |
277 | |
278 | /* Handle switch SCODE with argument ARG. VALUE is true, unless no- |
279 | form of an -f or -W option was given. Returns false if the switch was |
280 | invalid, true if valid. Use HANDLERS in recursive handle_option calls. */ |
281 | bool |
282 | c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, |
283 | int kind, location_t loc, |
284 | const struct cl_option_handlers *handlers) |
285 | { |
286 | const struct cl_option *option = &cl_options[scode]; |
287 | enum opt_code code = (enum opt_code) scode; |
288 | bool result = true; |
289 | |
290 | /* Prevent resetting the language standard to a C dialect when the driver |
291 | has already determined that we're looking at assembler input. */ |
292 | bool preprocessing_asm_p = (cpp_get_options (parse_in)->lang == CLK_ASM); |
293 | |
294 | switch (code) |
295 | { |
296 | default: |
297 | if (cl_options[code].flags & c_family_lang_mask) |
298 | { |
299 | if ((option->flags & CL_TARGET) |
300 | && ! targetcm.handle_c_option (scode, arg, value)) |
301 | result = false; |
302 | break; |
303 | } |
304 | result = false; |
305 | break; |
306 | |
307 | case OPT__output_pch: |
308 | pch_file = arg; |
309 | break; |
310 | |
311 | case OPT_A: |
312 | defer_opt (code, arg); |
313 | break; |
314 | |
315 | case OPT_C: |
316 | cpp_opts->discard_comments = 0; |
317 | break; |
318 | |
319 | case OPT_CC: |
320 | cpp_opts->discard_comments = 0; |
321 | cpp_opts->discard_comments_in_macro_exp = 0; |
322 | break; |
323 | |
324 | case OPT_D: |
325 | defer_opt (code, arg); |
326 | break; |
327 | |
328 | case OPT_H: |
329 | cpp_opts->print_include_names = 1; |
330 | break; |
331 | |
332 | case OPT_F: |
333 | TARGET_OPTF (xstrdup (arg)); |
334 | break; |
335 | |
336 | case OPT_I: |
337 | if (strcmp (s1: arg, s2: "-" )) |
338 | add_path (xstrdup (arg), INC_BRACKET, 0, true); |
339 | else |
340 | { |
341 | if (quote_chain_split) |
342 | error ("%<-I-%> specified twice" ); |
343 | quote_chain_split = true; |
344 | split_quote_chain (); |
345 | inform (input_location, "obsolete option %<-I-%> used, " |
346 | "please use %<-iquote%> instead" ); |
347 | } |
348 | break; |
349 | |
350 | case OPT_M: |
351 | case OPT_MM: |
352 | /* When doing dependencies with -M or -MM, suppress normal |
353 | preprocessed output, but still do -dM etc. as software |
354 | depends on this. Preprocessed output does occur if -MD, -MMD |
355 | or environment var dependency generation is used. */ |
356 | cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER); |
357 | flag_no_output = 1; |
358 | break; |
359 | |
360 | case OPT_MD: |
361 | case OPT_MMD: |
362 | cpp_opts->deps.style = (code == OPT_MD ? DEPS_SYSTEM: DEPS_USER); |
363 | cpp_opts->deps.need_preprocessor_output = true; |
364 | deps_file = arg; |
365 | break; |
366 | |
367 | case OPT_fdeps_format_: |
368 | /* https://wg21.link/p1689r5 */ |
369 | if (!strcmp (s1: arg, s2: "p1689r5" )) |
370 | cpp_opts->deps.fdeps_format = FDEPS_FMT_P1689R5; |
371 | else |
372 | error ("%<-fdeps-format=%> unknown format %<%s%>" , arg); |
373 | break; |
374 | |
375 | case OPT_fdeps_file_: |
376 | deps_seen = true; |
377 | fdeps_file = arg; |
378 | break; |
379 | |
380 | case OPT_fdeps_target_: |
381 | deps_seen = true; |
382 | defer_opt (code, arg); |
383 | break; |
384 | |
385 | case OPT_MF: |
386 | deps_seen = true; |
387 | deps_file = arg; |
388 | break; |
389 | |
390 | case OPT_MG: |
391 | deps_seen = true; |
392 | cpp_opts->deps.missing_files = true; |
393 | break; |
394 | |
395 | case OPT_MP: |
396 | deps_seen = true; |
397 | cpp_opts->deps.phony_targets = true; |
398 | break; |
399 | |
400 | case OPT_Mmodules: |
401 | /* Do not set deps_seen, so the user can unconditionally turn |
402 | this on or off. */ |
403 | cpp_opts->deps.modules = true; |
404 | break; |
405 | |
406 | case OPT_Mno_modules: |
407 | /* Do not set deps_seen, so the user can unconditionally turn |
408 | this on or off. */ |
409 | cpp_opts->deps.modules = false; |
410 | break; |
411 | |
412 | case OPT_MQ: |
413 | case OPT_MT: |
414 | deps_seen = true; |
415 | defer_opt (code, arg); |
416 | break; |
417 | |
418 | case OPT_P: |
419 | flag_no_line_commands = 1; |
420 | break; |
421 | |
422 | case OPT_U: |
423 | defer_opt (code, arg); |
424 | break; |
425 | |
426 | case OPT_Wall: |
427 | /* ??? Don't add new options here. Use LangEnabledBy in c.opt. */ |
428 | |
429 | cpp_opts->warn_num_sign_change = value; |
430 | break; |
431 | |
432 | case OPT_Wunknown_pragmas: |
433 | /* Set to greater than 1, so that even unknown pragmas in |
434 | system headers will be warned about. */ |
435 | /* ??? There is no way to handle this automatically for now. */ |
436 | warn_unknown_pragmas = value * 2; |
437 | break; |
438 | |
439 | case OPT_ansi: |
440 | if (!c_dialect_cxx ()) |
441 | set_std_c89 (false, true); |
442 | else |
443 | set_std_cxx98 (true); |
444 | break; |
445 | |
446 | case OPT_d: |
447 | handle_OPT_d (arg); |
448 | break; |
449 | |
450 | case OPT_Wabi_: |
451 | warn_abi = true; |
452 | if (value == 1) |
453 | { |
454 | warning (0, "%<-Wabi=1%> is not supported, using =2" ); |
455 | value = 2; |
456 | } |
457 | warn_abi_version = value; |
458 | break; |
459 | |
460 | case OPT_fcanonical_system_headers: |
461 | cpp_opts->canonical_system_headers = value; |
462 | break; |
463 | |
464 | case OPT_fcond_mismatch: |
465 | if (!c_dialect_cxx ()) |
466 | { |
467 | flag_cond_mismatch = value; |
468 | break; |
469 | } |
470 | warning (0, "switch %qs is no longer supported" , option->opt_text); |
471 | break; |
472 | |
473 | case OPT_fbuiltin_: |
474 | if (value) |
475 | result = false; |
476 | else |
477 | disable_builtin_function (arg); |
478 | break; |
479 | |
480 | case OPT_fdirectives_only: |
481 | cpp_opts->directives_only = value; |
482 | break; |
483 | |
484 | case OPT_fdollars_in_identifiers: |
485 | cpp_opts->dollars_in_ident = value; |
486 | break; |
487 | |
488 | case OPT_fmacro_prefix_map_: |
489 | add_macro_prefix_map (arg); |
490 | break; |
491 | |
492 | case OPT_ffreestanding: |
493 | value = !value; |
494 | /* Fall through. */ |
495 | case OPT_fhosted: |
496 | flag_hosted = value; |
497 | flag_no_builtin = !value; |
498 | break; |
499 | |
500 | case OPT_fconstant_string_class_: |
501 | constant_string_class_name = arg; |
502 | break; |
503 | |
504 | case OPT_fextended_identifiers: |
505 | cpp_opts->extended_identifiers = value; |
506 | break; |
507 | |
508 | case OPT_fmax_include_depth_: |
509 | cpp_opts->max_include_depth = value; |
510 | break; |
511 | |
512 | case OPT_foperator_names: |
513 | cpp_opts->operator_names = value; |
514 | break; |
515 | |
516 | case OPT_fpch_deps: |
517 | cpp_opts->restore_pch_deps = value; |
518 | break; |
519 | |
520 | case OPT_fpch_preprocess: |
521 | flag_pch_preprocess = value; |
522 | break; |
523 | |
524 | case OPT_fpermissive: |
525 | flag_permissive = value; |
526 | global_dc->m_permissive = value; |
527 | break; |
528 | |
529 | case OPT_fpreprocessed: |
530 | cpp_opts->preprocessed = value; |
531 | break; |
532 | |
533 | case OPT_fdebug_cpp: |
534 | cpp_opts->debug = 1; |
535 | break; |
536 | |
537 | case OPT_ftrack_macro_expansion: |
538 | if (value) |
539 | value = 2; |
540 | /* Fall Through. */ |
541 | |
542 | case OPT_ftrack_macro_expansion_: |
543 | if (arg && *arg != '\0') |
544 | cpp_opts->track_macro_expansion = value; |
545 | else |
546 | cpp_opts->track_macro_expansion = 2; |
547 | break; |
548 | |
549 | case OPT_fexec_charset_: |
550 | cpp_opts->narrow_charset = arg; |
551 | break; |
552 | |
553 | case OPT_fwide_exec_charset_: |
554 | cpp_opts->wide_charset = arg; |
555 | break; |
556 | |
557 | case OPT_finput_charset_: |
558 | cpp_opts->input_charset = arg; |
559 | cpp_opts->cpp_input_charset_explicit = 1; |
560 | break; |
561 | |
562 | case OPT_ftemplate_depth_: |
563 | max_tinst_depth = value; |
564 | break; |
565 | |
566 | case OPT_fvisibility_inlines_hidden: |
567 | visibility_options.inlines_hidden = value; |
568 | break; |
569 | |
570 | case OPT_femit_struct_debug_baseonly: |
571 | set_struct_debug_option (opts: &global_options, loc, value: "base" ); |
572 | break; |
573 | |
574 | case OPT_femit_struct_debug_reduced: |
575 | set_struct_debug_option (opts: &global_options, loc, |
576 | value: "dir:ord:sys,dir:gen:any,ind:base" ); |
577 | break; |
578 | |
579 | case OPT_femit_struct_debug_detailed_: |
580 | set_struct_debug_option (opts: &global_options, loc, value: arg); |
581 | break; |
582 | |
583 | case OPT_fext_numeric_literals: |
584 | cpp_opts->ext_numeric_literals = value; |
585 | break; |
586 | |
587 | case OPT_idirafter: |
588 | add_path (xstrdup (arg), INC_AFTER, 0, true); |
589 | break; |
590 | |
591 | case OPT_imacros: |
592 | case OPT_include: |
593 | defer_opt (code, arg); |
594 | break; |
595 | |
596 | case OPT_imultilib: |
597 | imultilib = arg; |
598 | break; |
599 | |
600 | case OPT_iprefix: |
601 | iprefix = arg; |
602 | break; |
603 | |
604 | case OPT_iquote: |
605 | add_path (xstrdup (arg), INC_QUOTE, 0, true); |
606 | break; |
607 | |
608 | case OPT_isysroot: |
609 | sysroot = arg; |
610 | break; |
611 | |
612 | case OPT_isystem: |
613 | add_path (xstrdup (arg), INC_SYSTEM, 0, true); |
614 | break; |
615 | |
616 | case OPT_iwithprefix: |
617 | add_prefixed_path (arg, INC_SYSTEM); |
618 | break; |
619 | |
620 | case OPT_iwithprefixbefore: |
621 | add_prefixed_path (arg, INC_BRACKET); |
622 | break; |
623 | |
624 | case OPT_lang_asm: |
625 | cpp_set_lang (parse_in, CLK_ASM); |
626 | cpp_opts->dollars_in_ident = false; |
627 | break; |
628 | |
629 | case OPT_nostdinc: |
630 | std_inc = false; |
631 | break; |
632 | |
633 | case OPT_nostdinc__: |
634 | std_cxx_inc = false; |
635 | break; |
636 | |
637 | case OPT_o: |
638 | if (!out_fname) |
639 | out_fname = arg; |
640 | else |
641 | error ("output filename specified twice" ); |
642 | break; |
643 | |
644 | case OPT_print_objc_runtime_info: |
645 | print_struct_values = 1; |
646 | break; |
647 | |
648 | case OPT_remap: |
649 | cpp_opts->remap = 1; |
650 | break; |
651 | |
652 | case OPT_std_c__98: |
653 | case OPT_std_gnu__98: |
654 | if (!preprocessing_asm_p) |
655 | set_std_cxx98 (code == OPT_std_c__98 /* ISO */); |
656 | break; |
657 | |
658 | case OPT_std_c__11: |
659 | case OPT_std_gnu__11: |
660 | if (!preprocessing_asm_p) |
661 | set_std_cxx11 (code == OPT_std_c__11 /* ISO */); |
662 | break; |
663 | |
664 | case OPT_std_c__14: |
665 | case OPT_std_gnu__14: |
666 | if (!preprocessing_asm_p) |
667 | set_std_cxx14 (code == OPT_std_c__14 /* ISO */); |
668 | break; |
669 | |
670 | case OPT_std_c__17: |
671 | case OPT_std_gnu__17: |
672 | if (!preprocessing_asm_p) |
673 | set_std_cxx17 (code == OPT_std_c__17 /* ISO */); |
674 | break; |
675 | |
676 | case OPT_std_c__20: |
677 | case OPT_std_gnu__20: |
678 | if (!preprocessing_asm_p) |
679 | set_std_cxx20 (code == OPT_std_c__20 /* ISO */); |
680 | break; |
681 | |
682 | case OPT_std_c__23: |
683 | case OPT_std_gnu__23: |
684 | if (!preprocessing_asm_p) |
685 | set_std_cxx23 (code == OPT_std_c__23 /* ISO */); |
686 | break; |
687 | |
688 | case OPT_std_c__26: |
689 | case OPT_std_gnu__26: |
690 | if (!preprocessing_asm_p) |
691 | set_std_cxx26 (code == OPT_std_c__26 /* ISO */); |
692 | break; |
693 | |
694 | case OPT_std_c90: |
695 | case OPT_std_iso9899_199409: |
696 | if (!preprocessing_asm_p) |
697 | set_std_c89 (code == OPT_std_iso9899_199409 /* c94 */, true /* ISO */); |
698 | break; |
699 | |
700 | case OPT_std_gnu90: |
701 | if (!preprocessing_asm_p) |
702 | set_std_c89 (false /* c94 */, false /* ISO */); |
703 | break; |
704 | |
705 | case OPT_std_c99: |
706 | if (!preprocessing_asm_p) |
707 | set_std_c99 (true /* ISO */); |
708 | break; |
709 | |
710 | case OPT_std_gnu99: |
711 | if (!preprocessing_asm_p) |
712 | set_std_c99 (false /* ISO */); |
713 | break; |
714 | |
715 | case OPT_std_c11: |
716 | if (!preprocessing_asm_p) |
717 | set_std_c11 (true /* ISO */); |
718 | break; |
719 | |
720 | case OPT_std_gnu11: |
721 | if (!preprocessing_asm_p) |
722 | set_std_c11 (false /* ISO */); |
723 | break; |
724 | |
725 | case OPT_std_c17: |
726 | if (!preprocessing_asm_p) |
727 | set_std_c17 (true /* ISO */); |
728 | break; |
729 | |
730 | case OPT_std_gnu17: |
731 | if (!preprocessing_asm_p) |
732 | set_std_c17 (false /* ISO */); |
733 | break; |
734 | |
735 | case OPT_std_c23: |
736 | if (!preprocessing_asm_p) |
737 | set_std_c23 (true /* ISO */); |
738 | break; |
739 | |
740 | case OPT_std_gnu23: |
741 | if (!preprocessing_asm_p) |
742 | set_std_c23 (false /* ISO */); |
743 | break; |
744 | |
745 | case OPT_trigraphs: |
746 | cpp_opts->trigraphs = 1; |
747 | break; |
748 | |
749 | case OPT_traditional_cpp: |
750 | cpp_opts->traditional = 1; |
751 | break; |
752 | |
753 | case OPT_v: |
754 | verbose = true; |
755 | break; |
756 | } |
757 | |
758 | switch (c_language) |
759 | { |
760 | case clk_c: |
761 | C_handle_option_auto (opts: &global_options, opts_set: &global_options_set, |
762 | scode, arg, value, |
763 | lang_mask: c_family_lang_mask, kind, |
764 | loc, handlers, dc: global_dc); |
765 | break; |
766 | |
767 | case clk_objc: |
768 | ObjC_handle_option_auto (opts: &global_options, opts_set: &global_options_set, |
769 | scode, arg, value, |
770 | lang_mask: c_family_lang_mask, kind, |
771 | loc, handlers, dc: global_dc); |
772 | break; |
773 | |
774 | case clk_cxx: |
775 | CXX_handle_option_auto (opts: &global_options, opts_set: &global_options_set, |
776 | scode, arg, value, |
777 | lang_mask: c_family_lang_mask, kind, |
778 | loc, handlers, dc: global_dc); |
779 | break; |
780 | |
781 | case clk_objcxx: |
782 | ObjCXX_handle_option_auto (opts: &global_options, opts_set: &global_options_set, |
783 | scode, arg, value, |
784 | lang_mask: c_family_lang_mask, kind, |
785 | loc, handlers, dc: global_dc); |
786 | break; |
787 | |
788 | default: |
789 | gcc_unreachable (); |
790 | } |
791 | |
792 | cpp_handle_option_auto (opts: &global_options, scode, cpp_opts); |
793 | return result; |
794 | } |
795 | |
796 | /* Default implementation of TARGET_HANDLE_C_OPTION. */ |
797 | |
798 | bool |
799 | default_handle_c_option (size_t code ATTRIBUTE_UNUSED, |
800 | const char *arg ATTRIBUTE_UNUSED, |
801 | int value ATTRIBUTE_UNUSED) |
802 | { |
803 | return false; |
804 | } |
805 | |
806 | /* Post-switch processing. */ |
807 | bool |
808 | c_common_post_options (const char **pfilename) |
809 | { |
810 | /* Canonicalize the input and output filenames. */ |
811 | if (in_fnames == NULL) |
812 | { |
813 | in_fnames = XNEWVEC (const char *, 1); |
814 | in_fnames[0] = "" ; |
815 | } |
816 | else if (strcmp (s1: in_fnames[0], s2: "-" ) == 0) |
817 | { |
818 | if (pch_file) |
819 | error ("cannot use %<-%> as input filename for a precompiled header" ); |
820 | |
821 | in_fnames[0] = "" ; |
822 | } |
823 | |
824 | if (out_fname == NULL || !strcmp (s1: out_fname, s2: "-" )) |
825 | out_fname = "" ; |
826 | |
827 | if (cpp_opts->deps.style == DEPS_NONE) |
828 | check_deps_environment_vars (); |
829 | |
830 | handle_deferred_opts (); |
831 | |
832 | sanitize_cpp_opts (); |
833 | |
834 | register_include_chains (parse_in, sysroot, iprefix, imultilib, |
835 | std_inc, std_cxx_inc && c_dialect_cxx (), verbose); |
836 | |
837 | #ifdef C_COMMON_OVERRIDE_OPTIONS |
838 | /* Some machines may reject certain combinations of C |
839 | language-specific options. */ |
840 | C_COMMON_OVERRIDE_OPTIONS; |
841 | #endif |
842 | |
843 | if (flag_excess_precision == EXCESS_PRECISION_DEFAULT) |
844 | flag_excess_precision = (flag_iso ? EXCESS_PRECISION_STANDARD |
845 | : EXCESS_PRECISION_FAST); |
846 | |
847 | /* ISO C restricts floating-point expression contraction to within |
848 | source-language expressions (-ffp-contract=on, currently an alias |
849 | for -ffp-contract=off). */ |
850 | if (flag_iso |
851 | && !c_dialect_cxx () |
852 | && (OPTION_SET_P (flag_fp_contract_mode) |
853 | == (enum fp_contract_mode) 0) |
854 | && flag_unsafe_math_optimizations == 0) |
855 | flag_fp_contract_mode = FP_CONTRACT_OFF; |
856 | |
857 | /* C language modes before C99 enable -fpermissive by default, but |
858 | only if -pedantic-errors is not specified. Also treat |
859 | -fno-permissive as a subset of -pedantic-errors that does not |
860 | reject certain GNU extensions also present the defaults for later |
861 | language modes. */ |
862 | if (!c_dialect_cxx () |
863 | && !flag_isoc99 |
864 | && !global_dc->m_pedantic_errors |
865 | && !OPTION_SET_P (flag_permissive)) |
866 | { |
867 | flag_permissive = 1; |
868 | global_dc->m_permissive = 1; |
869 | } |
870 | |
871 | /* If we are compiling C, and we are outside of a standards mode, |
872 | we can permit the new values from ISO/IEC TS 18661-3 for |
873 | FLT_EVAL_METHOD. Otherwise, we must restrict the possible values to |
874 | the set specified in ISO C99/C11. */ |
875 | if (!flag_iso |
876 | && !c_dialect_cxx () |
877 | && (OPTION_SET_P (flag_permitted_flt_eval_methods) |
878 | == PERMITTED_FLT_EVAL_METHODS_DEFAULT)) |
879 | flag_permitted_flt_eval_methods = PERMITTED_FLT_EVAL_METHODS_TS_18661; |
880 | else |
881 | flag_permitted_flt_eval_methods = PERMITTED_FLT_EVAL_METHODS_C11; |
882 | |
883 | /* C23 Annex F does not permit certain built-in functions to raise |
884 | "inexact". */ |
885 | if (flag_isoc23) |
886 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, |
887 | flag_fp_int_builtin_inexact, 0); |
888 | |
889 | /* By default we use C99 inline semantics in GNU99 or C99 mode. C99 |
890 | inline semantics are not supported in GNU89 or C89 mode. */ |
891 | if (flag_gnu89_inline == -1) |
892 | flag_gnu89_inline = !flag_isoc99; |
893 | else if (!flag_gnu89_inline && !flag_isoc99) |
894 | error ("%<-fno-gnu89-inline%> is only supported in GNU99 or C99 mode" ); |
895 | |
896 | /* Default to ObjC sjlj exception handling if NeXT runtime < v2. */ |
897 | if (flag_objc_sjlj_exceptions < 0) |
898 | flag_objc_sjlj_exceptions = (flag_next_runtime && flag_objc_abi < 2); |
899 | if (flag_objc_exceptions && !flag_objc_sjlj_exceptions) |
900 | flag_exceptions = 1; |
901 | |
902 | /* If -ffreestanding, -fno-hosted or -fno-builtin then disable |
903 | pattern recognition. */ |
904 | if (flag_no_builtin) |
905 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, |
906 | flag_tree_loop_distribute_patterns, 0); |
907 | |
908 | /* -Woverlength-strings is off by default, but is enabled by -Wpedantic. |
909 | It is never enabled in C++, as the minimum limit is not normative |
910 | in that standard. */ |
911 | if (c_dialect_cxx ()) |
912 | warn_overlength_strings = 0; |
913 | |
914 | /* Wmain is enabled by default in C++ but not in C. */ |
915 | /* Wmain is disabled by default for -ffreestanding (!flag_hosted), |
916 | even if -Wall or -Wpedantic was given (warn_main will be 2 if set |
917 | by -Wall, 1 if set by -Wmain). */ |
918 | if (warn_main == -1) |
919 | warn_main = (c_dialect_cxx () && flag_hosted) ? 1 : 0; |
920 | else if (warn_main == 2) |
921 | warn_main = flag_hosted ? 1 : 0; |
922 | |
923 | /* In C, -Wall and -Wc++-compat enable -Wenum-compare; if it has not |
924 | yet been set, it is disabled by default. In C++, it is enabled |
925 | by default. */ |
926 | if (warn_enum_compare == -1) |
927 | warn_enum_compare = c_dialect_cxx () ? 1 : 0; |
928 | |
929 | /* -Wpacked-bitfield-compat is on by default for the C languages. The |
930 | warning is issued in stor-layout.cc which is not part of the front-end so |
931 | we need to selectively turn it on here. */ |
932 | if (warn_packed_bitfield_compat == -1) |
933 | warn_packed_bitfield_compat = 1; |
934 | |
935 | /* Special format checking options don't work without -Wformat; warn if |
936 | they are used. */ |
937 | if (!warn_format) |
938 | { |
939 | warning (OPT_Wformat_y2k, |
940 | "%<-Wformat-y2k%> ignored without %<-Wformat%>" ); |
941 | warning (OPT_Wformat_extra_args, |
942 | "%<-Wformat-extra-args%> ignored without %<-Wformat%>" ); |
943 | warning (OPT_Wformat_zero_length, |
944 | "%<-Wformat-zero-length%> ignored without %<-Wformat%>" ); |
945 | warning (OPT_Wformat_nonliteral, |
946 | "%<-Wformat-nonliteral%> ignored without %<-Wformat%>" ); |
947 | warning (OPT_Wformat_contains_nul, |
948 | "%<-Wformat-contains-nul%> ignored without %<-Wformat%>" ); |
949 | warning (OPT_Wformat_security, |
950 | "%<-Wformat-security%> ignored without %<-Wformat%>" ); |
951 | } |
952 | |
953 | /* -Wimplicit-function-declaration is enabled by default for C99. */ |
954 | if (warn_implicit_function_declaration == -1) |
955 | warn_implicit_function_declaration = flag_isoc99; |
956 | |
957 | /* -Wimplicit-int is enabled by default for C99. */ |
958 | if (warn_implicit_int == -1) |
959 | warn_implicit_int = flag_isoc99; |
960 | |
961 | /* -Wold-style-definition is enabled by default for C23. */ |
962 | if (warn_old_style_definition == -1) |
963 | warn_old_style_definition = flag_isoc23; |
964 | |
965 | /* -Wshift-overflow is enabled by default in C99 and C++11 modes. */ |
966 | if (warn_shift_overflow == -1) |
967 | warn_shift_overflow = cxx_dialect >= cxx11 || flag_isoc99; |
968 | |
969 | /* -Wshift-negative-value is enabled by -Wextra in C99 and C++11 to C++17 |
970 | modes. */ |
971 | if (warn_shift_negative_value == -1) |
972 | warn_shift_negative_value = (extra_warnings |
973 | && (cxx_dialect >= cxx11 || flag_isoc99) |
974 | && cxx_dialect < cxx20); |
975 | |
976 | /* -Wregister is enabled by default in C++17. */ |
977 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, warn_register, |
978 | cxx_dialect >= cxx17); |
979 | |
980 | /* -Wcomma-subscript is enabled by default in C++20. */ |
981 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, |
982 | warn_comma_subscript, |
983 | cxx_dialect >= cxx23 |
984 | || (cxx_dialect == cxx20 && warn_deprecated)); |
985 | |
986 | /* -Wvolatile is enabled by default in C++20. */ |
987 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, warn_volatile, |
988 | cxx_dialect >= cxx20 && warn_deprecated); |
989 | |
990 | /* -Wdeprecated-enum-enum-conversion is enabled by default in C++20. */ |
991 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, |
992 | warn_deprecated_enum_enum_conv, |
993 | cxx_dialect >= cxx20 && warn_deprecated); |
994 | |
995 | /* -Wdeprecated-enum-float-conversion is enabled by default in C++20. */ |
996 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, |
997 | warn_deprecated_enum_float_conv, |
998 | cxx_dialect >= cxx20 && warn_deprecated); |
999 | |
1000 | /* Declone C++ 'structors if -Os. */ |
1001 | if (flag_declone_ctor_dtor == -1) |
1002 | flag_declone_ctor_dtor = optimize_size; |
1003 | |
1004 | if (flag_abi_compat_version == 1) |
1005 | { |
1006 | warning (0, "%<-fabi-compat-version=1%> is not supported, using =2" ); |
1007 | flag_abi_compat_version = 2; |
1008 | } |
1009 | |
1010 | /* Change flag_abi_version to be the actual current ABI level, for the |
1011 | benefit of c_cpp_builtins, and to make comparison simpler. */ |
1012 | const int latest_abi_version = 19; |
1013 | /* Generate compatibility aliases for ABI v13 (8.2) by default. */ |
1014 | const int abi_compat_default = 13; |
1015 | |
1016 | #define clamp(X) if (X == 0 || X > latest_abi_version) X = latest_abi_version |
1017 | clamp (flag_abi_version); |
1018 | clamp (warn_abi_version); |
1019 | clamp (flag_abi_compat_version); |
1020 | #undef clamp |
1021 | |
1022 | /* Default -Wabi= or -fabi-compat-version= from each other. */ |
1023 | if (warn_abi_version == -1 && flag_abi_compat_version != -1) |
1024 | warn_abi_version = flag_abi_compat_version; |
1025 | else if (flag_abi_compat_version == -1 && warn_abi_version != -1) |
1026 | flag_abi_compat_version = warn_abi_version; |
1027 | else if (warn_abi_version == -1 && flag_abi_compat_version == -1) |
1028 | { |
1029 | warn_abi_version = latest_abi_version; |
1030 | if (flag_abi_version == latest_abi_version) |
1031 | { |
1032 | auto_diagnostic_group d; |
1033 | if (warning (OPT_Wabi, "%<-Wabi%> won%'t warn about anything" )) |
1034 | { |
1035 | inform (input_location, "%<-Wabi%> warns about differences " |
1036 | "from the most up-to-date ABI, which is also used " |
1037 | "by default" ); |
1038 | inform (input_location, "use e.g. %<-Wabi=11%> to warn about " |
1039 | "changes from GCC 7" ); |
1040 | } |
1041 | flag_abi_compat_version = abi_compat_default; |
1042 | } |
1043 | else |
1044 | flag_abi_compat_version = latest_abi_version; |
1045 | } |
1046 | |
1047 | /* By default, enable the new inheriting constructor semantics along with ABI |
1048 | 11. New and old should coexist fine, but it is a change in what |
1049 | artificial symbols are generated. */ |
1050 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, |
1051 | flag_new_inheriting_ctors, |
1052 | abi_version_at_least (11)); |
1053 | |
1054 | /* For GCC 7, only enable DR150 resolution by default if -std=c++17. */ |
1055 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, flag_new_ttp, |
1056 | cxx_dialect >= cxx17); |
1057 | |
1058 | /* C++11 guarantees forward progress. */ |
1059 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, flag_finite_loops, |
1060 | optimize >= 2 && cxx_dialect >= cxx11); |
1061 | |
1062 | /* It's OK to discard calls to pure/const functions that might throw. */ |
1063 | SET_OPTION_IF_UNSET (&global_options, &global_options_set, |
1064 | flag_delete_dead_exceptions, true); |
1065 | |
1066 | if (cxx_dialect >= cxx11) |
1067 | { |
1068 | /* If we're allowing C++0x constructs, don't warn about C++98 |
1069 | identifiers which are keywords in C++0x. */ |
1070 | warn_cxx11_compat = 0; |
1071 | cpp_opts->cpp_warn_cxx11_compat = 0; |
1072 | |
1073 | if (warn_narrowing == -1) |
1074 | warn_narrowing = 1; |
1075 | |
1076 | /* Unless -f{,no-}ext-numeric-literals has been used explicitly, |
1077 | for -std=c++{11,14,17,20,23,26} default to |
1078 | -fno-ext-numeric-literals. */ |
1079 | if (flag_iso && !OPTION_SET_P (flag_ext_numeric_literals)) |
1080 | cpp_opts->ext_numeric_literals = 0; |
1081 | } |
1082 | else if (warn_narrowing == -1) |
1083 | warn_narrowing = 0; |
1084 | |
1085 | if (cxx_dialect >= cxx20) |
1086 | { |
1087 | /* Don't warn about C++20 compatibility changes in C++20 or later. */ |
1088 | warn_cxx20_compat = 0; |
1089 | cpp_opts->cpp_warn_cxx20_compat = 0; |
1090 | } |
1091 | |
1092 | /* C++17 has stricter evaluation order requirements; let's use some of them |
1093 | for earlier C++ as well, so chaining works as expected. */ |
1094 | if (c_dialect_cxx () |
1095 | && flag_strong_eval_order == -1) |
1096 | flag_strong_eval_order = (cxx_dialect >= cxx17 ? 2 : 1); |
1097 | |
1098 | if (flag_implicit_constexpr && cxx_dialect < cxx14) |
1099 | flag_implicit_constexpr = false; |
1100 | |
1101 | /* Global sized deallocation is new in C++14. */ |
1102 | if (flag_sized_deallocation == -1) |
1103 | flag_sized_deallocation = (cxx_dialect >= cxx14); |
1104 | |
1105 | /* Pedwarn about invalid constexpr functions before C++23. */ |
1106 | if (warn_invalid_constexpr == -1) |
1107 | warn_invalid_constexpr = (cxx_dialect < cxx23); |
1108 | |
1109 | /* char8_t support is implicitly enabled in C++20 and C23. */ |
1110 | if (flag_char8_t == -1) |
1111 | flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc23; |
1112 | cpp_opts->unsigned_utf8char = flag_char8_t ? 1 : cpp_opts->unsigned_char; |
1113 | |
1114 | if (flag_extern_tls_init) |
1115 | { |
1116 | if (!TARGET_SUPPORTS_ALIASES || !SUPPORTS_WEAK) |
1117 | { |
1118 | /* Lazy TLS initialization for a variable in another TU requires |
1119 | alias and weak reference support. */ |
1120 | if (flag_extern_tls_init > 0) |
1121 | sorry ("external TLS initialization functions not supported " |
1122 | "on this target" ); |
1123 | |
1124 | flag_extern_tls_init = 0; |
1125 | } |
1126 | else |
1127 | flag_extern_tls_init = 1; |
1128 | } |
1129 | |
1130 | /* Enable by default only for C++ and C++ with ObjC extensions. */ |
1131 | if (warn_return_type == -1 && c_dialect_cxx ()) |
1132 | warn_return_type = 1; |
1133 | |
1134 | /* C++20 is the final version of concepts. We still use -fconcepts |
1135 | to know when concepts are enabled. Note that -fconcepts-ts can |
1136 | be used to include additional features, although modified to |
1137 | work with the standard. */ |
1138 | if (cxx_dialect >= cxx20 || flag_concepts_ts) |
1139 | flag_concepts = 1; |
1140 | |
1141 | if (num_in_fnames > 1) |
1142 | error ("too many filenames given; type %<%s %s%> for usage" , |
1143 | progname, "--help" ); |
1144 | |
1145 | if (flag_preprocess_only) |
1146 | { |
1147 | /* Open the output now. We must do so even if flag_no_output is |
1148 | on, because there may be other output than from the actual |
1149 | preprocessing (e.g. from -dM). */ |
1150 | if (out_fname[0] == '\0') |
1151 | out_stream = stdout; |
1152 | else |
1153 | out_stream = fopen (filename: out_fname, modes: "w" ); |
1154 | |
1155 | if (out_stream == NULL) |
1156 | fatal_error (input_location, "opening output file %s: %m" , out_fname); |
1157 | |
1158 | init_pp_output (out_stream); |
1159 | } |
1160 | else |
1161 | { |
1162 | init_c_lex (); |
1163 | |
1164 | /* When writing a PCH file, avoid reading some other PCH file, |
1165 | because the default address space slot then can't be used |
1166 | for the output PCH file. */ |
1167 | if (pch_file) |
1168 | { |
1169 | c_common_no_more_pch (); |
1170 | /* Only -g0 and -gdwarf* are supported with PCH, for other |
1171 | debug formats we warn here and refuse to load any PCH files. */ |
1172 | if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG) |
1173 | warning (OPT_Wdeprecated, |
1174 | "the %qs debug info cannot be used with " |
1175 | "pre-compiled headers" , |
1176 | debug_set_names (write_symbols & ~DWARF2_DEBUG)); |
1177 | } |
1178 | else if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG) |
1179 | c_common_no_more_pch (); |
1180 | |
1181 | /* Yuk. WTF is this? I do know ObjC relies on it somewhere. */ |
1182 | input_location = UNKNOWN_LOCATION; |
1183 | } |
1184 | |
1185 | struct cpp_callbacks *cb = cpp_get_callbacks (parse_in); |
1186 | cb->file_change = cb_file_change; |
1187 | cb->dir_change = cb_dir_change; |
1188 | if (lang_hooks.preprocess_options) |
1189 | lang_hooks.preprocess_options (parse_in); |
1190 | cpp_post_options (parse_in); |
1191 | init_global_opts_from_cpp (opts: &global_options, cpp_opts: cpp_get_options (parse_in)); |
1192 | /* For C++23 and explicit -finput-charset=UTF-8, turn on -Winvalid-utf8 |
1193 | by default and make it a pedwarn unless -Wno-invalid-utf8. */ |
1194 | if (cxx_dialect >= cxx23 |
1195 | && cpp_opts->cpp_input_charset_explicit |
1196 | && strcmp (s1: cpp_opts->input_charset, s2: "UTF-8" ) == 0 |
1197 | && (cpp_opts->cpp_warn_invalid_utf8 |
1198 | || !global_options_set.x_warn_invalid_utf8)) |
1199 | { |
1200 | global_options.x_warn_invalid_utf8 = 1; |
1201 | cpp_opts->cpp_warn_invalid_utf8 = cpp_opts->cpp_pedantic ? 2 : 1; |
1202 | } |
1203 | |
1204 | /* Let diagnostics infrastructure know how to convert input files the same |
1205 | way libcpp will do it, namely using the configured input charset and |
1206 | skipping a UTF-8 BOM if present. */ |
1207 | diagnostic_initialize_input_context (context: global_dc, |
1208 | ccb: c_common_input_charset_cb, should_skip_bom: true); |
1209 | input_location = UNKNOWN_LOCATION; |
1210 | |
1211 | *pfilename = this_input_filename |
1212 | = cpp_read_main_file (parse_in, in_fnames[0], |
1213 | /* We'll inject preamble pieces if this is |
1214 | not preprocessed. */ |
1215 | injecting: !cpp_opts->preprocessed); |
1216 | |
1217 | /* Don't do any compilation or preprocessing if there is no input file. */ |
1218 | if (this_input_filename == NULL) |
1219 | { |
1220 | errorcount++; |
1221 | return false; |
1222 | } |
1223 | |
1224 | if (flag_working_directory |
1225 | && flag_preprocess_only && !flag_no_line_commands) |
1226 | pp_dir_change (parse_in, get_src_pwd ()); |
1227 | |
1228 | /* Disable LTO output when outputting a precompiled header. */ |
1229 | if (pch_file && flag_lto) |
1230 | { |
1231 | flag_lto = 0; |
1232 | flag_generate_lto = 0; |
1233 | } |
1234 | |
1235 | return flag_preprocess_only; |
1236 | } |
1237 | |
1238 | /* Front end initialization common to C, ObjC and C++. */ |
1239 | bool |
1240 | c_common_init (void) |
1241 | { |
1242 | /* Set up preprocessor arithmetic. Must be done after call to |
1243 | c_common_nodes_and_builtins for type nodes to be good. */ |
1244 | cpp_opts->precision = TYPE_PRECISION (intmax_type_node); |
1245 | cpp_opts->char_precision = TYPE_PRECISION (char_type_node); |
1246 | cpp_opts->int_precision = TYPE_PRECISION (integer_type_node); |
1247 | cpp_opts->wchar_precision = TYPE_PRECISION (wchar_type_node); |
1248 | cpp_opts->unsigned_wchar = TYPE_UNSIGNED (wchar_type_node); |
1249 | cpp_opts->bytes_big_endian = BYTES_BIG_ENDIAN; |
1250 | |
1251 | /* This can't happen until after wchar_precision and bytes_big_endian |
1252 | are known. */ |
1253 | cpp_init_iconv (parse_in); |
1254 | |
1255 | if (version_flag) |
1256 | { |
1257 | int i; |
1258 | fputs (s: "Compiler executable checksum: " , stderr); |
1259 | for (i = 0; i < 16; i++) |
1260 | fprintf (stderr, format: "%02x" , executable_checksum[i]); |
1261 | putc (c: '\n', stderr); |
1262 | } |
1263 | |
1264 | /* Has to wait until now so that cpplib has its hash table. */ |
1265 | init_pragma (); |
1266 | |
1267 | if (flag_preprocess_only) |
1268 | { |
1269 | c_finish_options (); |
1270 | c_init_preprocess (); |
1271 | preprocess_file (parse_in); |
1272 | return false; |
1273 | } |
1274 | |
1275 | return true; |
1276 | } |
1277 | |
1278 | /* Initialize the integrated preprocessor after debug output has been |
1279 | initialized; loop over each input file. */ |
1280 | void |
1281 | c_common_parse_file (void) |
1282 | { |
1283 | auto dumps = g->get_dumps (); |
1284 | for (unsigned int i = 0;;) |
1285 | { |
1286 | c_finish_options (); |
1287 | /* Open the dump file to use for the original dump output |
1288 | here, to be used during parsing for the current file. */ |
1289 | dumps->dump_start (phase: TDI_original, flag_ptr: &dump_flags); |
1290 | pch_init (); |
1291 | push_file_scope (); |
1292 | c_parse_file (); |
1293 | pop_file_scope (); |
1294 | /* And end the main input file, if the debug writer wants it */ |
1295 | if (debug_hooks->start_end_main_source_file) |
1296 | (*debug_hooks->end_source_file) (0); |
1297 | if (++i >= num_in_fnames) |
1298 | break; |
1299 | cpp_undef_all (parse_in); |
1300 | cpp_clear_file_cache (parse_in); |
1301 | this_input_filename |
1302 | = cpp_read_main_file (parse_in, in_fnames[i]); |
1303 | /* If an input file is missing, abandon further compilation. |
1304 | cpplib has issued a diagnostic. */ |
1305 | if (!this_input_filename) |
1306 | break; |
1307 | dumps->dump_finish (phase: TDI_original); |
1308 | } |
1309 | |
1310 | c_parse_final_cleanups (); |
1311 | dumps->dump_finish (phase: TDI_original); |
1312 | } |
1313 | |
1314 | /* Common finish hook for the C, ObjC and C++ front ends. */ |
1315 | void |
1316 | c_common_finish (void) |
1317 | { |
1318 | FILE *deps_stream = NULL; |
1319 | FILE *fdeps_stream = NULL; |
1320 | |
1321 | /* Note that we write the dependencies even if there are errors. This is |
1322 | useful for handling outdated generated headers that now trigger errors |
1323 | (for example, with #error) which would be resolved by re-generating |
1324 | them. In a sense, this complements -MG. */ |
1325 | if (cpp_opts->deps.style != DEPS_NONE) |
1326 | { |
1327 | /* If -M or -MM was seen without -MF, default output to the |
1328 | output stream. */ |
1329 | if (!deps_file) |
1330 | deps_stream = out_stream; |
1331 | else if (deps_file[0] == '-' && deps_file[1] == '\0') |
1332 | deps_stream = stdout; |
1333 | else |
1334 | { |
1335 | deps_stream = fopen (filename: deps_file, modes: deps_append ? "a" : "w" ); |
1336 | if (!deps_stream) |
1337 | fatal_error (input_location, "opening dependency file %s: %m" , |
1338 | deps_file); |
1339 | } |
1340 | } |
1341 | |
1342 | /* When we call cpp_finish (), it may generate some diagnostics using |
1343 | locations it remembered from the preprocessing phase, e.g. for |
1344 | -Wunused-macros. So inform c_cpp_diagnostic () not to override those |
1345 | locations with input_location, which would be incorrect now. */ |
1346 | override_libcpp_locations = false; |
1347 | |
1348 | if (cpp_opts->deps.fdeps_format != FDEPS_FMT_NONE) |
1349 | { |
1350 | if (!fdeps_file) |
1351 | fdeps_stream = out_stream; |
1352 | else if (fdeps_file[0] == '-' && fdeps_file[1] == '\0') |
1353 | fdeps_stream = stdout; |
1354 | else |
1355 | { |
1356 | fdeps_stream = fopen (filename: fdeps_file, modes: "w" ); |
1357 | if (!fdeps_stream) |
1358 | fatal_error (input_location, "opening dependency file %s: %m" , |
1359 | fdeps_file); |
1360 | } |
1361 | if (fdeps_stream == deps_stream && fdeps_stream != stdout) |
1362 | fatal_error (input_location, "%<-MF%> and %<-fdeps-file=%> cannot share an output file %s: %m" , |
1363 | fdeps_file); |
1364 | } |
1365 | |
1366 | /* For performance, avoid tearing down cpplib's internal structures |
1367 | with cpp_destroy (). */ |
1368 | cpp_finish (parse_in, deps_stream, fdeps_stream); |
1369 | |
1370 | if (deps_stream && deps_stream != out_stream && deps_stream != stdout |
1371 | && (ferror (stream: deps_stream) || fclose (stream: deps_stream))) |
1372 | fatal_error (input_location, "closing dependency file %s: %m" , deps_file); |
1373 | |
1374 | if (out_stream && (ferror (stream: out_stream) || fclose (stream: out_stream))) |
1375 | fatal_error (input_location, "when writing output to %s: %m" , out_fname); |
1376 | } |
1377 | |
1378 | /* Either of two environment variables can specify output of |
1379 | dependencies. Their value is either "OUTPUT_FILE" or "OUTPUT_FILE |
1380 | DEPS_TARGET", where OUTPUT_FILE is the file to write deps info to |
1381 | and DEPS_TARGET is the target to mention in the deps. They also |
1382 | result in dependency information being appended to the output file |
1383 | rather than overwriting it, and like Sun's compiler |
1384 | SUNPRO_DEPENDENCIES suppresses the dependency on the main file. */ |
1385 | static void |
1386 | check_deps_environment_vars (void) |
1387 | { |
1388 | char *spec; |
1389 | |
1390 | spec = getenv (name: "DEPENDENCIES_OUTPUT" ); |
1391 | if (spec) |
1392 | cpp_opts->deps.style = DEPS_USER; |
1393 | else |
1394 | { |
1395 | spec = getenv (name: "SUNPRO_DEPENDENCIES" ); |
1396 | if (spec) |
1397 | { |
1398 | cpp_opts->deps.style = DEPS_SYSTEM; |
1399 | cpp_opts->deps.ignore_main_file = true; |
1400 | } |
1401 | } |
1402 | |
1403 | if (spec) |
1404 | { |
1405 | /* Find the space before the DEPS_TARGET, if there is one. */ |
1406 | char *s = strchr (s: spec, c: ' '); |
1407 | if (s) |
1408 | { |
1409 | /* Let the caller perform MAKE quoting. */ |
1410 | defer_opt (code: OPT_MT, arg: s + 1); |
1411 | *s = '\0'; |
1412 | } |
1413 | |
1414 | /* Command line -MF overrides environment variables and default. */ |
1415 | if (!deps_file) |
1416 | deps_file = spec; |
1417 | |
1418 | deps_append = 1; |
1419 | deps_seen = true; |
1420 | } |
1421 | } |
1422 | |
1423 | /* Handle deferred command line switches. */ |
1424 | static void |
1425 | handle_deferred_opts (void) |
1426 | { |
1427 | /* Avoid allocating the deps buffer if we don't need it. |
1428 | (This flag may be true without there having been -MT or -MQ |
1429 | options, but we'll still need the deps buffer.) */ |
1430 | if (!deps_seen) |
1431 | return; |
1432 | |
1433 | if (mkdeps *deps = cpp_get_deps (parse_in)) |
1434 | for (unsigned i = 0; i < deferred_count; i++) |
1435 | { |
1436 | struct deferred_opt *opt = &deferred_opts[i]; |
1437 | |
1438 | if (opt->code == OPT_MT || opt->code == OPT_MQ) |
1439 | deps_add_target (deps, opt->arg, opt->code == OPT_MQ); |
1440 | else if (opt->code == OPT_fdeps_target_) |
1441 | fdeps_add_target (deps, opt->arg, true); |
1442 | } |
1443 | } |
1444 | |
1445 | /* These settings are appropriate for GCC, but not necessarily so for |
1446 | cpplib as a library. */ |
1447 | static void |
1448 | sanitize_cpp_opts (void) |
1449 | { |
1450 | /* If we don't know what style of dependencies to output, complain |
1451 | if any other dependency switches have been given. */ |
1452 | if (deps_seen && cpp_opts->deps.style == DEPS_NONE) |
1453 | error ("to generate dependencies you must specify either %<-M%> " |
1454 | "or %<-MM%>" ); |
1455 | |
1456 | /* -dM and dependencies suppress normal output; do it here so that |
1457 | the last -d[MDN] switch overrides earlier ones. */ |
1458 | if (flag_dump_macros == 'M') |
1459 | flag_no_output = 1; |
1460 | |
1461 | /* By default, -fdirectives-only implies -dD. This allows subsequent phases |
1462 | to perform proper macro expansion. */ |
1463 | if (cpp_opts->directives_only && !cpp_opts->preprocessed && !flag_dump_macros) |
1464 | flag_dump_macros = 'D'; |
1465 | |
1466 | /* Disable -dD, -dN and -dI if normal output is suppressed. Allow |
1467 | -dM since at least glibc relies on -M -dM to work. */ |
1468 | /* Also, flag_no_output implies flag_no_line_commands, always. */ |
1469 | if (flag_no_output) |
1470 | { |
1471 | if (flag_dump_macros != 'M') |
1472 | flag_dump_macros = 0; |
1473 | flag_dump_includes = 0; |
1474 | flag_no_line_commands = 1; |
1475 | } |
1476 | else if (cpp_opts->deps.missing_files) |
1477 | error ("%<-MG%> may only be used with %<-M%> or %<-MM%>" ); |
1478 | |
1479 | cpp_opts->unsigned_char = !flag_signed_char; |
1480 | cpp_opts->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS; |
1481 | |
1482 | /* Wlong-long is disabled by default. It is enabled by: |
1483 | [-Wpedantic | -Wtraditional] -std=[gnu|c]++98 ; or |
1484 | [-Wpedantic | -Wtraditional] -std=non-c99 |
1485 | |
1486 | Either -Wlong-long or -Wno-long-long override any other settings. |
1487 | ??? These conditions should be handled in c.opt. */ |
1488 | if (warn_long_long == -1) |
1489 | { |
1490 | warn_long_long = ((pedantic || warn_traditional) |
1491 | && (c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99)); |
1492 | cpp_opts->cpp_warn_long_long = warn_long_long; |
1493 | } |
1494 | |
1495 | /* If we're generating preprocessor output, emit current directory |
1496 | if explicitly requested or if debugging information is enabled. |
1497 | ??? Maybe we should only do it for debugging formats that |
1498 | actually output the current directory? */ |
1499 | if (flag_working_directory == -1) |
1500 | flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE); |
1501 | |
1502 | if (warn_implicit_fallthrough < 5) |
1503 | cpp_opts->cpp_warn_implicit_fallthrough = warn_implicit_fallthrough; |
1504 | else |
1505 | cpp_opts->cpp_warn_implicit_fallthrough = 0; |
1506 | |
1507 | if (cpp_opts->directives_only) |
1508 | { |
1509 | if (cpp_warn_unused_macros) |
1510 | error ("%<-fdirectives-only%> is incompatible " |
1511 | "with %<-Wunused-macros%>" ); |
1512 | if (cpp_opts->traditional) |
1513 | error ("%<-fdirectives-only%> is incompatible with %<-traditional%>" ); |
1514 | } |
1515 | } |
1516 | |
1517 | /* Add include path with a prefix at the front of its name. */ |
1518 | static void |
1519 | add_prefixed_path (const char *suffix, incpath_kind chain) |
1520 | { |
1521 | char *path; |
1522 | const char *prefix; |
1523 | size_t prefix_len, suffix_len; |
1524 | |
1525 | suffix_len = strlen (s: suffix); |
1526 | prefix = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR; |
1527 | prefix_len = iprefix ? strlen (s: iprefix) : cpp_GCC_INCLUDE_DIR_len; |
1528 | |
1529 | path = (char *) xmalloc (prefix_len + suffix_len + 1); |
1530 | memcpy (dest: path, src: prefix, n: prefix_len); |
1531 | memcpy (dest: path + prefix_len, src: suffix, n: suffix_len); |
1532 | path[prefix_len + suffix_len] = '\0'; |
1533 | |
1534 | add_path (path, chain, 0, false); |
1535 | } |
1536 | |
1537 | /* Handle -D, -U, -A, -imacros, and the first -include. */ |
1538 | static void |
1539 | c_finish_options (void) |
1540 | { |
1541 | if (!cpp_opts->preprocessed) |
1542 | { |
1543 | const line_map_ordinary *bltin_map |
1544 | = linemap_check_ordinary (map: linemap_add (line_table, LC_RENAME, sysp: 0, |
1545 | to_file: special_fname_builtin (), to_line: 0)); |
1546 | cb_file_change (parse_in, bltin_map); |
1547 | linemap_line_start (set: line_table, to_line: 0, max_column_hint: 1); |
1548 | |
1549 | /* Make sure all of the builtins about to be declared have |
1550 | BUILTINS_LOCATION has their location_t. */ |
1551 | cpp_force_token_locations (parse_in, BUILTINS_LOCATION); |
1552 | |
1553 | cpp_init_builtins (parse_in, flag_hosted); |
1554 | c_cpp_builtins (parse_in); |
1555 | |
1556 | /* We're about to send user input to cpplib, so make it warn for |
1557 | things that we previously (when we sent it internal definitions) |
1558 | told it to not warn. |
1559 | |
1560 | C99 permits implementation-defined characters in identifiers. |
1561 | The documented meaning of -std= is to turn off extensions that |
1562 | conflict with the specified standard, and since a strictly |
1563 | conforming program cannot contain a '$', we do not condition |
1564 | their acceptance on the -std= setting. */ |
1565 | cpp_opts->warn_dollars = (cpp_opts->cpp_pedantic && !cpp_opts->c99); |
1566 | |
1567 | const line_map_ordinary *cmd_map |
1568 | = linemap_check_ordinary (map: linemap_add (line_table, LC_RENAME, sysp: 0, |
1569 | _("<command-line>" ), to_line: 0)); |
1570 | cb_file_change (parse_in, cmd_map); |
1571 | linemap_line_start (set: line_table, to_line: 0, max_column_hint: 1); |
1572 | |
1573 | /* All command line defines must have the same location. */ |
1574 | cpp_force_token_locations (parse_in, line_table->highest_line); |
1575 | for (size_t i = 0; i < deferred_count; i++) |
1576 | { |
1577 | struct deferred_opt *opt = &deferred_opts[i]; |
1578 | |
1579 | if (opt->code == OPT_D) |
1580 | cpp_define (parse_in, opt->arg); |
1581 | else if (opt->code == OPT_U) |
1582 | cpp_undef (parse_in, opt->arg); |
1583 | else if (opt->code == OPT_A) |
1584 | { |
1585 | if (opt->arg[0] == '-') |
1586 | cpp_unassert (parse_in, opt->arg + 1); |
1587 | else |
1588 | cpp_assert (parse_in, opt->arg); |
1589 | } |
1590 | } |
1591 | |
1592 | cpp_stop_forcing_token_locations (parse_in); |
1593 | } |
1594 | else if (cpp_opts->directives_only) |
1595 | cpp_init_special_builtins (parse_in); |
1596 | |
1597 | /* Start the main input file, if the debug writer wants it. */ |
1598 | if (debug_hooks->start_end_main_source_file |
1599 | && !flag_preprocess_only) |
1600 | (*debug_hooks->start_source_file) (0, this_input_filename); |
1601 | |
1602 | if (!cpp_opts->preprocessed) |
1603 | /* Handle -imacros after -D and -U. */ |
1604 | for (size_t i = 0; i < deferred_count; i++) |
1605 | { |
1606 | struct deferred_opt *opt = &deferred_opts[i]; |
1607 | |
1608 | if (opt->code == OPT_imacros |
1609 | && cpp_push_include (parse_in, opt->arg)) |
1610 | { |
1611 | /* Disable push_command_line_include callback for now. */ |
1612 | include_cursor = deferred_count + 1; |
1613 | cpp_scan_nooutput (parse_in); |
1614 | } |
1615 | } |
1616 | |
1617 | include_cursor = 0; |
1618 | push_command_line_include (); |
1619 | } |
1620 | |
1621 | /* Give CPP the next file given by -include, if any. */ |
1622 | static void |
1623 | push_command_line_include (void) |
1624 | { |
1625 | /* This can happen if disabled by -imacros for example. |
1626 | Punt so that we don't set "<command-line>" as the filename for |
1627 | the header. */ |
1628 | if (include_cursor > deferred_count) |
1629 | return; |
1630 | |
1631 | if (!done_preinclude) |
1632 | { |
1633 | done_preinclude = true; |
1634 | if (flag_hosted && std_inc && !cpp_opts->preprocessed) |
1635 | { |
1636 | const char *preinc = targetcm.c_preinclude (); |
1637 | if (preinc && cpp_push_default_include (parse_in, preinc)) |
1638 | return; |
1639 | } |
1640 | } |
1641 | |
1642 | pch_cpp_save_state (); |
1643 | |
1644 | while (include_cursor < deferred_count) |
1645 | { |
1646 | struct deferred_opt *opt = &deferred_opts[include_cursor++]; |
1647 | |
1648 | if (!cpp_opts->preprocessed && opt->code == OPT_include |
1649 | && cpp_push_include (parse_in, opt->arg)) |
1650 | return; |
1651 | } |
1652 | |
1653 | if (include_cursor == deferred_count) |
1654 | { |
1655 | include_cursor++; |
1656 | /* -Wunused-macros should only warn about macros defined hereafter. */ |
1657 | cpp_opts->warn_unused_macros = cpp_warn_unused_macros; |
1658 | /* Restore the line map back to the main file. */ |
1659 | if (!cpp_opts->preprocessed) |
1660 | { |
1661 | cpp_change_file (parse_in, LC_RENAME, this_input_filename); |
1662 | if (lang_hooks.preprocess_main_file) |
1663 | /* We're starting the main file. Inform the FE of that. */ |
1664 | lang_hooks.preprocess_main_file |
1665 | (parse_in, line_table, LINEMAPS_LAST_ORDINARY_MAP (set: line_table)); |
1666 | } |
1667 | |
1668 | /* Set this here so the client can change the option if it wishes, |
1669 | and after stacking the main file so we don't trace the main file. */ |
1670 | line_table->trace_includes = cpp_opts->print_include_names; |
1671 | } |
1672 | } |
1673 | |
1674 | /* File change callback. Has to handle -include files. */ |
1675 | static void |
1676 | cb_file_change (cpp_reader *reader, const line_map_ordinary *new_map) |
1677 | { |
1678 | if (flag_preprocess_only) |
1679 | pp_file_change (new_map); |
1680 | else |
1681 | fe_file_change (new_map); |
1682 | |
1683 | if (new_map && cpp_opts->preprocessed |
1684 | && lang_hooks.preprocess_main_file && MAIN_FILE_P (ord_map: new_map) |
1685 | && ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map: new_map)) |
1686 | /* We're starting the main file. Inform the FE of that. */ |
1687 | lang_hooks.preprocess_main_file (reader, line_table, new_map); |
1688 | |
1689 | if (new_map |
1690 | && (new_map->reason == LC_ENTER || new_map->reason == LC_RENAME)) |
1691 | { |
1692 | /* Signal to plugins that a file is included. This could happen |
1693 | several times with the same file path, e.g. because of |
1694 | several '#include' or '#line' directives... */ |
1695 | invoke_plugin_callbacks |
1696 | (event: PLUGIN_INCLUDE_FILE, |
1697 | gcc_data: const_cast<char*> (ORDINARY_MAP_FILE_NAME (ord_map: new_map))); |
1698 | } |
1699 | |
1700 | if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (ord_map: new_map))) |
1701 | { |
1702 | pch_cpp_save_state (); |
1703 | push_command_line_include (); |
1704 | } |
1705 | } |
1706 | |
1707 | void |
1708 | cb_dir_change (cpp_reader * ARG_UNUSED (pfile), const char *dir) |
1709 | { |
1710 | if (!set_src_pwd (dir)) |
1711 | warning (0, "too late for # directive to set debug directory" ); |
1712 | } |
1713 | |
1714 | /* Set the C 89 standard (with 1994 amendments if C94, without GNU |
1715 | extensions if ISO). There is no concept of gnu94. */ |
1716 | static void |
1717 | set_std_c89 (int c94, int iso) |
1718 | { |
1719 | cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89); |
1720 | flag_iso = iso; |
1721 | flag_no_asm = iso; |
1722 | flag_no_gnu_keywords = iso; |
1723 | flag_no_nonansi_builtin = iso; |
1724 | flag_isoc94 = c94; |
1725 | flag_isoc99 = 0; |
1726 | flag_isoc11 = 0; |
1727 | flag_isoc23 = 0; |
1728 | lang_hooks.name = "GNU C89" ; |
1729 | } |
1730 | |
1731 | /* Set the C 99 standard (without GNU extensions if ISO). */ |
1732 | static void |
1733 | set_std_c99 (int iso) |
1734 | { |
1735 | cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99); |
1736 | flag_no_asm = iso; |
1737 | flag_no_nonansi_builtin = iso; |
1738 | flag_iso = iso; |
1739 | flag_isoc23 = 0; |
1740 | flag_isoc11 = 0; |
1741 | flag_isoc99 = 1; |
1742 | flag_isoc94 = 1; |
1743 | lang_hooks.name = "GNU C99" ; |
1744 | } |
1745 | |
1746 | /* Set the C 11 standard (without GNU extensions if ISO). */ |
1747 | static void |
1748 | set_std_c11 (int iso) |
1749 | { |
1750 | cpp_set_lang (parse_in, iso ? CLK_STDC11: CLK_GNUC11); |
1751 | flag_no_asm = iso; |
1752 | flag_no_nonansi_builtin = iso; |
1753 | flag_iso = iso; |
1754 | flag_isoc23 = 0; |
1755 | flag_isoc11 = 1; |
1756 | flag_isoc99 = 1; |
1757 | flag_isoc94 = 1; |
1758 | lang_hooks.name = "GNU C11" ; |
1759 | } |
1760 | |
1761 | /* Set the C 17 standard (without GNU extensions if ISO). */ |
1762 | static void |
1763 | set_std_c17 (int iso) |
1764 | { |
1765 | cpp_set_lang (parse_in, iso ? CLK_STDC17: CLK_GNUC17); |
1766 | flag_no_asm = iso; |
1767 | flag_no_nonansi_builtin = iso; |
1768 | flag_iso = iso; |
1769 | flag_isoc23 = 0; |
1770 | flag_isoc11 = 1; |
1771 | flag_isoc99 = 1; |
1772 | flag_isoc94 = 1; |
1773 | lang_hooks.name = "GNU C17" ; |
1774 | } |
1775 | |
1776 | /* Set the C 2X standard (without GNU extensions if ISO). */ |
1777 | static void |
1778 | set_std_c23 (int iso) |
1779 | { |
1780 | cpp_set_lang (parse_in, iso ? CLK_STDC23: CLK_GNUC23); |
1781 | flag_no_asm = iso; |
1782 | flag_no_nonansi_builtin = iso; |
1783 | flag_iso = iso; |
1784 | flag_isoc23 = 1; |
1785 | flag_isoc11 = 1; |
1786 | flag_isoc99 = 1; |
1787 | flag_isoc94 = 1; |
1788 | lang_hooks.name = "GNU C23" ; |
1789 | } |
1790 | |
1791 | |
1792 | /* Set the C++ 98 standard (without GNU extensions if ISO). */ |
1793 | static void |
1794 | set_std_cxx98 (int iso) |
1795 | { |
1796 | cpp_set_lang (parse_in, iso ? CLK_CXX98: CLK_GNUCXX); |
1797 | flag_no_gnu_keywords = iso; |
1798 | flag_no_nonansi_builtin = iso; |
1799 | flag_iso = iso; |
1800 | flag_isoc94 = 0; |
1801 | flag_isoc99 = 0; |
1802 | cxx_dialect = cxx98; |
1803 | lang_hooks.name = "GNU C++98" ; |
1804 | } |
1805 | |
1806 | /* Set the C++ 2011 standard (without GNU extensions if ISO). */ |
1807 | static void |
1808 | set_std_cxx11 (int iso) |
1809 | { |
1810 | cpp_set_lang (parse_in, iso ? CLK_CXX11: CLK_GNUCXX11); |
1811 | flag_no_gnu_keywords = iso; |
1812 | flag_no_nonansi_builtin = iso; |
1813 | flag_iso = iso; |
1814 | /* C++11 includes the C99 standard library. */ |
1815 | flag_isoc94 = 1; |
1816 | flag_isoc99 = 1; |
1817 | cxx_dialect = cxx11; |
1818 | lang_hooks.name = "GNU C++11" ; |
1819 | } |
1820 | |
1821 | /* Set the C++ 2014 standard (without GNU extensions if ISO). */ |
1822 | static void |
1823 | set_std_cxx14 (int iso) |
1824 | { |
1825 | cpp_set_lang (parse_in, iso ? CLK_CXX14: CLK_GNUCXX14); |
1826 | flag_no_gnu_keywords = iso; |
1827 | flag_no_nonansi_builtin = iso; |
1828 | flag_iso = iso; |
1829 | /* C++14 includes the C99 standard library. */ |
1830 | flag_isoc94 = 1; |
1831 | flag_isoc99 = 1; |
1832 | cxx_dialect = cxx14; |
1833 | lang_hooks.name = "GNU C++14" ; |
1834 | } |
1835 | |
1836 | /* Set the C++ 2017 standard (without GNU extensions if ISO). */ |
1837 | static void |
1838 | set_std_cxx17 (int iso) |
1839 | { |
1840 | cpp_set_lang (parse_in, iso ? CLK_CXX17: CLK_GNUCXX17); |
1841 | flag_no_gnu_keywords = iso; |
1842 | flag_no_nonansi_builtin = iso; |
1843 | flag_iso = iso; |
1844 | /* C++17 includes the C11 standard library. */ |
1845 | flag_isoc94 = 1; |
1846 | flag_isoc99 = 1; |
1847 | flag_isoc11 = 1; |
1848 | cxx_dialect = cxx17; |
1849 | lang_hooks.name = "GNU C++17" ; |
1850 | } |
1851 | |
1852 | /* Set the C++ 2020 standard (without GNU extensions if ISO). */ |
1853 | static void |
1854 | set_std_cxx20 (int iso) |
1855 | { |
1856 | cpp_set_lang (parse_in, iso ? CLK_CXX20: CLK_GNUCXX20); |
1857 | flag_no_gnu_keywords = iso; |
1858 | flag_no_nonansi_builtin = iso; |
1859 | flag_iso = iso; |
1860 | /* C++20 includes the C11 standard library. */ |
1861 | flag_isoc94 = 1; |
1862 | flag_isoc99 = 1; |
1863 | flag_isoc11 = 1; |
1864 | /* C++20 includes coroutines. */ |
1865 | flag_coroutines = true; |
1866 | cxx_dialect = cxx20; |
1867 | lang_hooks.name = "GNU C++20" ; |
1868 | } |
1869 | |
1870 | /* Set the C++ 2023 standard (without GNU extensions if ISO). */ |
1871 | static void |
1872 | set_std_cxx23 (int iso) |
1873 | { |
1874 | cpp_set_lang (parse_in, iso ? CLK_CXX23: CLK_GNUCXX23); |
1875 | flag_no_gnu_keywords = iso; |
1876 | flag_no_nonansi_builtin = iso; |
1877 | flag_iso = iso; |
1878 | /* C++23 includes the C11 standard library. */ |
1879 | flag_isoc94 = 1; |
1880 | flag_isoc99 = 1; |
1881 | flag_isoc11 = 1; |
1882 | /* C++23 includes coroutines. */ |
1883 | flag_coroutines = true; |
1884 | cxx_dialect = cxx23; |
1885 | lang_hooks.name = "GNU C++23" ; |
1886 | } |
1887 | |
1888 | /* Set the C++ 2026 standard (without GNU extensions if ISO). */ |
1889 | static void |
1890 | set_std_cxx26 (int iso) |
1891 | { |
1892 | cpp_set_lang (parse_in, iso ? CLK_CXX26: CLK_GNUCXX26); |
1893 | flag_no_gnu_keywords = iso; |
1894 | flag_no_nonansi_builtin = iso; |
1895 | flag_iso = iso; |
1896 | /* C++26 includes the C11 standard library. */ |
1897 | flag_isoc94 = 1; |
1898 | flag_isoc99 = 1; |
1899 | flag_isoc11 = 1; |
1900 | /* C++26 includes coroutines. */ |
1901 | flag_coroutines = true; |
1902 | cxx_dialect = cxx26; |
1903 | lang_hooks.name = "GNU C++26" ; |
1904 | } |
1905 | |
1906 | /* Args to -d specify what to dump. Silently ignore |
1907 | unrecognized options; they may be aimed at toplev.cc. */ |
1908 | static void |
1909 | handle_OPT_d (const char *arg) |
1910 | { |
1911 | char c; |
1912 | |
1913 | while ((c = *arg++) != '\0') |
1914 | switch (c) |
1915 | { |
1916 | case 'M': /* Dump macros only. */ |
1917 | case 'N': /* Dump names. */ |
1918 | case 'D': /* Dump definitions. */ |
1919 | case 'U': /* Dump used macros. */ |
1920 | flag_dump_macros = c; |
1921 | break; |
1922 | |
1923 | case 'I': |
1924 | flag_dump_includes = 1; |
1925 | break; |
1926 | } |
1927 | } |
1928 | |