Makefile.in (toplev.o): Add value-prof.h dependency.
[platform/upstream/gcc.git] / gcc / opts.c
1 /* Command line option handling.
2    Copyright (C) 2002, 2003 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 "intl.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "tree.h"
28 #include "rtl.h"
29 #include "ggc.h"
30 #include "output.h"
31 #include "langhooks.h"
32 #include "opts.h"
33 #include "options.h"
34 #include "flags.h"
35 #include "toplev.h"
36 #include "params.h"
37 #include "diagnostic.h"
38 #include "tm_p.h"               /* For OPTIMIZATION_OPTIONS.  */
39 #include "insn-attr.h"          /* For INSN_SCHEDULING.  */
40
41 /* Value of the -G xx switch, and whether it was passed or not.  */
42 unsigned HOST_WIDE_INT g_switch_value;
43 bool g_switch_set;
44
45 /* True if we should exit after parsing options.  */
46 bool exit_after_options;
47
48 /* If -version.  */
49 bool version_flag;
50
51 /* Print various extra warnings.  -W/-Wextra.  */
52 bool extra_warnings;
53
54 /* Don't print warning messages.  -w.  */
55 bool inhibit_warnings;
56
57 /* Treat warnings as errors.  -Werror.  */
58 bool warnings_are_errors;
59
60 /* Warn if a function returns an aggregate, since there are often
61    incompatible calling conventions for doing this.  */
62 bool warn_aggregate_return;
63
64 /* Nonzero means warn about pointer casts that increase the required
65    alignment of the target type (and might therefore lead to a crash
66    due to a misaligned access).  */
67 bool warn_cast_align;
68
69 /* Nonzero means warn about uses of __attribute__((deprecated))
70    declarations.  */
71 bool warn_deprecated_decl = true;
72
73 /* Warn when an optimization pass is disabled.  */
74 bool warn_disabled_optimization;
75
76 /* Nonzero means warn if inline function is too large.  */
77 bool warn_inline;
78
79 /* True to warn about any objects definitions whose size is larger
80    than N bytes.  Also want about function definitions whose returned
81    values are larger than N bytes, where N is `larger_than_size'.  */
82 bool warn_larger_than;
83 HOST_WIDE_INT larger_than_size;
84
85 /* Warn about functions which might be candidates for attribute noreturn.  */
86 bool warn_missing_noreturn;
87
88 /* True to warn about code which is never reached.  */
89 bool warn_notreached;
90
91 /* Warn if packed attribute on struct is unnecessary and inefficient.  */
92 bool warn_packed;
93
94 /* Warn when gcc pads a structure to an alignment boundary.  */
95 bool warn_padded;
96
97 /* True means warn about all declarations which shadow others.  */
98 bool warn_shadow;
99
100 /* Nonzero means warn about constructs which might not be
101    strict-aliasing safe.  */
102 bool warn_strict_aliasing;
103
104 /* True to warn if a switch on an enum, that does not have a default
105    case, fails to have a case for every enum value.  */
106 bool warn_switch;
107
108 /* Warn if a switch does not have a default case.  */
109 bool warn_switch_default;
110
111 /* Warn if a switch on an enum fails to have a case for every enum
112    value (regardless of the presence or otherwise of a default case).  */
113 bool warn_switch_enum;
114
115 /* Don't suppress warnings from system headers.  -Wsystem-headers.  */
116 bool warn_system_headers;
117
118 /* True to warn about variables used before they are initialized.  */
119 int warn_uninitialized;
120
121 /* True to warn about unused variables, functions et.al.  */
122 bool warn_unused_function;
123 bool warn_unused_label;
124 bool warn_unused_parameter;
125 bool warn_unused_variable;
126 bool warn_unused_value;
127
128 /* Hack for cooperation between set_Wunused and set_Wextra.  */
129 static bool maybe_warn_unused_parameter;
130
131 /* Type(s) of debugging information we are producing (if any).  See
132    flags.h for the definitions of the different possible types of
133    debugging information.  */
134 enum debug_info_type write_symbols = NO_DEBUG;
135
136 /* Level of debugging information we are producing.  See flags.h for
137    the definitions of the different possible levels.  */
138 enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
139
140 /* Nonzero means use GNU-only extensions in the generated symbolic
141    debugging information.  Currently, this only has an effect when
142    write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
143 bool use_gnu_debug_info_extensions;
144
145 /* Columns of --help display.  */
146 static unsigned int columns = 80;
147
148 /* What to print when a switch has no documentation.  */
149 static const char undocumented_msg[] = N_("This switch lacks documentation");
150
151 /* Input file names.  */
152 const char **in_fnames;
153 unsigned num_in_fnames;
154
155 static size_t find_opt (const char *, int);
156 static int common_handle_option (size_t scode, const char *arg, int value);
157 static void handle_param (const char *);
158 static void set_Wextra (int);
159 static unsigned int handle_option (const char **argv, unsigned int lang_mask);
160 static char *write_langs (unsigned int lang_mask);
161 static void complain_wrong_lang (const char *, const struct cl_option *,
162                                  unsigned int lang_mask);
163 static void handle_options (unsigned int, const char **, unsigned int);
164 static void wrap_help (const char *help, const char *item, unsigned int);
165 static void print_help (void);
166 static void print_param_help (void);
167 static void print_filtered_help (unsigned int flag);
168 static unsigned int print_switch (const char *text, unsigned int indent);
169 static void set_debug_level (enum debug_info_type type, int extended,
170                              const char *arg);
171
172 /* Perform a binary search to find which option the command-line INPUT
173    matches.  Returns its index in the option array, and N_OPTS
174    (cl_options_count) on failure.
175
176    This routine is quite subtle.  A normal binary search is not good
177    enough because some options can be suffixed with an argument, and
178    multiple sub-matches can occur, e.g. input of "-pedantic" matching
179    the initial substring of "-pedantic-errors".
180
181    A more complicated example is -gstabs.  It should match "-g" with
182    an argument of "stabs".  Suppose, however, that the number and list
183    of switches are such that the binary search tests "-gen-decls"
184    before having tested "-g".  This doesn't match, and as "-gen-decls"
185    is less than "-gstabs", it will become the lower bound of the
186    binary search range, and "-g" will never be seen.  To resolve this
187    issue, opts.sh makes "-gen-decls" point, via the back_chain member,
188    to "-g" so that failed searches that end between "-gen-decls" and
189    the lexicographically subsequent switch know to go back and see if
190    "-g" causes a match (which it does in this example).
191
192    This search is done in such a way that the longest match for the
193    front end in question wins.  If there is no match for the current
194    front end, the longest match for a different front end is returned
195    (or N_OPTS if none) and the caller emits an error message.  */
196 static size_t
197 find_opt (const char *input, int lang_mask)
198 {
199   size_t mn, mx, md, opt_len;
200   size_t match_wrong_lang;
201   int comp;
202
203   mn = 0;
204   mx = cl_options_count;
205
206   /* Find mn such this lexicographical inequality holds:
207      cl_options[mn] <= input < cl_options[mn + 1].  */
208   while (mx - mn > 1)
209     {
210       md = (mn + mx) / 2;
211       opt_len = cl_options[md].opt_len;
212       comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
213
214       if (comp < 0)
215         mx = md;
216       else
217         mn = md;
218     }
219
220   /* This is the switch that is the best match but for a different
221      front end, or cl_options_count if there is no match at all.  */
222   match_wrong_lang = cl_options_count;
223
224   /* Backtrace the chain of possible matches, returning the longest
225      one, if any, that fits best.  With current GCC switches, this
226      loop executes at most twice.  */
227   do
228     {
229       const struct cl_option *opt = &cl_options[mn];
230
231       /* Is this switch a prefix of the input?  */
232       if (!strncmp (input, opt->opt_text + 1, opt->opt_len))
233         {
234           /* If language is OK, and the match is exact or the switch
235              takes a joined argument, return it.  */
236           if ((opt->flags & lang_mask)
237               && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
238             return mn;
239
240           /* If we haven't remembered a prior match, remember this
241              one.  Any prior match is necessarily better.  */
242           if (match_wrong_lang == cl_options_count)
243             match_wrong_lang = mn;
244         }
245
246       /* Try the next possibility.  This is cl_options_count if there
247          are no more.  */
248       mn = opt->back_chain;
249     }
250   while (mn != cl_options_count);
251
252   /* Return the best wrong match, or cl_options_count if none.  */
253   return match_wrong_lang;
254 }
255
256 /* If ARG is a non-negative integer made up solely of digits, return its
257    value, otherwise return -1.  */
258 static int
259 integral_argument (const char *arg)
260 {
261   const char *p = arg;
262
263   while (*p && ISDIGIT (*p))
264     p++;
265
266   if (*p == '\0')
267     return atoi (arg);
268
269   return -1;
270 }
271
272 /* Return a malloced slash-separated list of languages in MASK.  */
273 static char *
274 write_langs (unsigned int mask)
275 {
276   unsigned int n = 0, len = 0;
277   const char *lang_name;
278   char *result;
279
280   for (n = 0; (lang_name = lang_names[n]) != 0; n++)
281     if (mask & (1U << n))
282       len += strlen (lang_name) + 1;
283
284   result = xmalloc (len);
285   len = 0;
286   for (n = 0; (lang_name = lang_names[n]) != 0; n++)
287     if (mask & (1U << n))
288       {
289         if (len)
290           result[len++] = '/';
291         strcpy (result + len, lang_name);
292         len += strlen (lang_name);
293       }
294
295   result[len] = 0;
296
297   return result;
298 }
299
300 /* Complain that switch OPT_INDEX does not apply to this front end.  */
301 static void
302 complain_wrong_lang (const char *text, const struct cl_option *option,
303                      unsigned int lang_mask)
304 {
305   char *ok_langs, *bad_lang;
306
307   ok_langs = write_langs (option->flags);
308   bad_lang = write_langs (lang_mask);
309
310   /* Eventually this should become a hard error IMO.  */
311   warning ("command line option \"%s\" is valid for %s but not for %s",
312            text, ok_langs, bad_lang);
313
314   free (ok_langs);
315   free (bad_lang);
316 }
317
318 /* Handle the switch beginning at ARGV for the language indicated by
319    LANG_MASK.  Returns the number of switches consumed.  */
320 static unsigned int
321 handle_option (const char **argv, unsigned int lang_mask)
322 {
323   size_t opt_index;
324   const char *opt, *arg = 0;
325   char *dup = 0;
326   int value = 1;
327   unsigned int result = 0;
328   const struct cl_option *option;
329
330   opt = argv[0];
331
332   /* Drop the "no-" from negative switches.  */
333   if ((opt[1] == 'W' || opt[1] == 'f')
334       && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
335     {
336       size_t len = strlen (opt) - 3;
337
338       dup = xmalloc (len + 1);
339       dup[0] = '-';
340       dup[1] = opt[1];
341       memcpy (dup + 2, opt + 5, len - 2 + 1);
342       opt = dup;
343       value = 0;
344     }
345
346   opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
347   if (opt_index == cl_options_count)
348     goto done;
349
350   option = &cl_options[opt_index];
351
352   /* Reject negative form of switches that don't take negatives as
353      unrecognized.  */
354   if (!value && (option->flags & CL_REJECT_NEGATIVE))
355     goto done;
356
357   /* We've recognized this switch.  */
358   result = 1;
359
360   /* Sort out any argument the switch takes.  */
361   if (option->flags & CL_JOINED)
362     {
363       /* Have arg point to the original switch.  This is because
364          some code, such as disable_builtin_function, expects its
365          argument to be persistent until the program exits.  */
366       arg = argv[0] + cl_options[opt_index].opt_len + 1;
367       if (!value)
368         arg += strlen ("no-");
369
370       if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
371         {
372           if (option->flags & CL_SEPARATE)
373             {
374               arg = argv[1];
375               result = 2;
376             }
377           else
378             /* Missing argument.  */
379             arg = NULL;
380         }
381     }
382   else if (option->flags & CL_SEPARATE)
383     {
384       arg = argv[1];
385       result = 2;
386     }
387
388   /* Now we've swallowed any potential argument, complain if this
389      is a switch for a different front end.  */
390   if (!(option->flags & (lang_mask | CL_COMMON)))
391     {
392       complain_wrong_lang (argv[0], option, lang_mask);
393       goto done;
394     }
395
396   if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
397     {
398       if (!(*lang_hooks.missing_argument) (opt, opt_index))
399         error ("missing argument to \"%s\"", opt);
400       goto done;
401     }
402
403   /* If the switch takes an integer, convert it.  */
404   if (arg && (option->flags & CL_UINTEGER))
405     {
406       value = integral_argument (arg);
407       if (value == -1)
408         {
409           error ("argument to \"%s\" should be a non-negative integer",
410                  option->opt_text);
411           goto done;
412         }
413     }
414
415   if (option->flags & lang_mask)
416     if ((*lang_hooks.handle_option) (opt_index, arg, value) == 0)
417       result = 0;
418
419   if (result && (option->flags & CL_COMMON))
420     if (common_handle_option (opt_index, arg, value) == 0)
421       result = 0;
422
423  done:
424   if (dup)
425     free (dup);
426   return result;
427 }
428
429 /* Decode and handle the vector of command line options.  LANG_MASK
430    contains has a single bit set representing the current
431    language.  */
432 static void
433 handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
434 {
435   unsigned int n, i;
436
437   for (i = 1; i < argc; i += n)
438     {
439       const char *opt = argv[i];
440
441       /* Interpret "-" or a non-switch as a file name.  */
442       if (opt[0] != '-' || opt[1] == '\0')
443         {
444           main_input_filename = opt;
445           add_input_filename (opt);
446           n = 1;
447           continue;
448         }
449
450       n = handle_option (argv + i, lang_mask);
451
452       if (!n)
453         {
454           n = 1;
455           error ("unrecognized command line option \"%s\"", opt);
456         }
457     }
458 }
459
460 /* Handle FILENAME from the command line.  */
461 void
462 add_input_filename (const char *filename)
463 {
464   num_in_fnames++;
465   in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0]));
466   in_fnames[num_in_fnames - 1] = filename;
467 }
468
469 /* Parse command line options and set default flag values.  Do minimal
470    options processing.  */
471 void
472 decode_options (unsigned int argc, const char **argv)
473 {
474   unsigned int i, lang_mask;
475
476   /* Perform language-specific options initialization.  */
477   lang_mask = (*lang_hooks.init_options) (argc, argv);
478
479   lang_hooks.initialize_diagnostics (global_dc);
480
481   /* Scan to see what optimization level has been specified.  That will
482      determine the default value of many flags.  */
483   for (i = 1; i < argc; i++)
484     {
485       if (!strcmp (argv[i], "-O"))
486         {
487           optimize = 1;
488           optimize_size = 0;
489         }
490       else if (argv[i][0] == '-' && argv[i][1] == 'O')
491         {
492           /* Handle -Os, -O2, -O3, -O69, ...  */
493           const char *p = &argv[i][2];
494
495           if ((p[0] == 's') && (p[1] == 0))
496             {
497               optimize_size = 1;
498
499               /* Optimizing for size forces optimize to be 2.  */
500               optimize = 2;
501             }
502           else
503             {
504               const int optimize_val = read_integral_parameter (p, p - 2, -1);
505               if (optimize_val != -1)
506                 {
507                   optimize = optimize_val;
508                   optimize_size = 0;
509                 }
510             }
511         }
512     }
513
514   if (!optimize)
515     {
516       flag_merge_constants = 0;
517     }
518
519   if (optimize >= 1)
520     {
521       flag_defer_pop = 1;
522       flag_thread_jumps = 1;
523 #ifdef DELAY_SLOTS
524       flag_delayed_branch = 1;
525 #endif
526 #ifdef CAN_DEBUG_WITHOUT_FP
527       flag_omit_frame_pointer = 1;
528 #endif
529       flag_guess_branch_prob = 1;
530       flag_cprop_registers = 1;
531       flag_loop_optimize = 1;
532       flag_crossjumping = 1;
533       flag_if_conversion = 1;
534       flag_if_conversion2 = 1;
535     }
536
537   if (optimize >= 2)
538     {
539       flag_optimize_sibling_calls = 1;
540       flag_cse_follow_jumps = 1;
541       flag_cse_skip_blocks = 1;
542       flag_gcse = 1;
543       flag_expensive_optimizations = 1;
544       flag_strength_reduce = 1;
545       flag_rerun_cse_after_loop = 1;
546       flag_rerun_loop_opt = 1;
547       flag_caller_saves = 1;
548       flag_force_mem = 1;
549       flag_peephole2 = 1;
550 #ifdef INSN_SCHEDULING
551       flag_schedule_insns = 1;
552       flag_schedule_insns_after_reload = 1;
553 #endif
554       flag_regmove = 1;
555       flag_strict_aliasing = 1;
556       flag_delete_null_pointer_checks = 1;
557       flag_reorder_blocks = 1;
558       flag_reorder_functions = 1;
559       flag_unit_at_a_time = 1;
560     }
561
562   if (optimize >= 3)
563     {
564       flag_inline_functions = 1;
565       flag_rename_registers = 1;
566       flag_unswitch_loops = 1;
567       flag_web = 1;
568     }
569
570   if (optimize < 2 || optimize_size)
571     {
572       align_loops = 1;
573       align_jumps = 1;
574       align_labels = 1;
575       align_functions = 1;
576
577       /* Don't reorder blocks when optimizing for size because extra
578          jump insns may be created; also barrier may create extra padding.
579
580          More correctly we should have a block reordering mode that tried
581          to minimize the combined size of all the jumps.  This would more
582          or less automatically remove extra jumps, but would also try to
583          use more short jumps instead of long jumps.  */
584       flag_reorder_blocks = 0;
585     }
586
587   /* Initialize whether `char' is signed.  */
588   flag_signed_char = DEFAULT_SIGNED_CHAR;
589 #ifdef DEFAULT_SHORT_ENUMS
590   /* Initialize how much space enums occupy, by default.  */
591   flag_short_enums = DEFAULT_SHORT_ENUMS;
592 #endif
593
594   /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
595      modify it.  */
596   target_flags = 0;
597   set_target_switch ("");
598
599   /* Unwind tables are always present in an ABI-conformant IA-64
600      object file, so the default should be ON.  */
601 #ifdef IA64_UNWIND_INFO
602   flag_unwind_tables = IA64_UNWIND_INFO;
603 #endif
604
605 #ifdef OPTIMIZATION_OPTIONS
606   /* Allow default optimizations to be specified on a per-machine basis.  */
607   OPTIMIZATION_OPTIONS (optimize, optimize_size);
608 #endif
609
610   handle_options (argc, argv, lang_mask);
611
612   if (flag_pie)
613     flag_pic = flag_pie;
614   if (flag_pic && !flag_pie)
615     flag_shlib = 1;
616
617   if (flag_no_inline == 2)
618     flag_no_inline = 0;
619   else
620     flag_really_no_inline = flag_no_inline;
621
622   /* Set flag_no_inline before the post_options () hook.  The C front
623      ends use it to determine tree inlining defaults.  FIXME: such
624      code should be lang-independent when all front ends use tree
625      inlining, in which case it, and this condition, should be moved
626      to the top of process_options() instead.  */
627   if (optimize == 0)
628     {
629       /* Inlining does not work if not optimizing,
630          so force it not to be done.  */
631       flag_no_inline = 1;
632       warn_inline = 0;
633
634       /* The c_decode_option function and decode_option hook set
635          this to `2' if -Wall is used, so we can avoid giving out
636          lots of errors for people who don't realize what -Wall does.  */
637       if (warn_uninitialized == 1)
638         warning ("-Wuninitialized is not supported without -O");
639     }
640
641   if (flag_really_no_inline == 2)
642     flag_really_no_inline = flag_no_inline;
643 }
644
645 /* Handle target- and language-independent options.  Return zero to
646    generate an "unknown option" message.  */
647 static int
648 common_handle_option (size_t scode, const char *arg,
649                       int value ATTRIBUTE_UNUSED)
650 {
651   enum opt_code code = (enum opt_code) scode;
652
653   switch (code)
654     {
655     default:
656       abort ();
657
658     case OPT__help:
659       print_help ();
660       exit_after_options = true;
661       break;
662
663     case OPT__param:
664       handle_param (arg);
665       break;
666
667     case OPT__target_help:
668       display_target_options ();
669       exit_after_options = true;
670       break;
671
672     case OPT__version:
673       print_version (stderr, "");
674       exit_after_options = true;
675       break;
676
677     case OPT_G:
678       g_switch_value = value;
679       g_switch_set = true;
680       break;
681
682     case OPT_O:
683     case OPT_Os:
684       /* Currently handled in a prescan.  */
685       break;
686
687     case OPT_W:
688       /* For backward compatibility, -W is the same as -Wextra.  */
689       set_Wextra (value);
690       break;
691
692     case OPT_Waggregate_return:
693       warn_aggregate_return = value;
694       break;
695
696     case OPT_Wcast_align:
697       warn_cast_align = value;
698       break;
699
700     case OPT_Wdeprecated_declarations:
701       warn_deprecated_decl = value;
702       break;
703
704     case OPT_Wdisabled_optimization:
705       warn_disabled_optimization = value;
706       break;
707
708     case OPT_Werror:
709       warnings_are_errors = value;
710       break;
711
712     case OPT_Wextra:
713       set_Wextra (value);
714       break;
715
716     case OPT_Winline:
717       warn_inline = value;
718       break;
719
720     case OPT_Wlarger_than_:
721       larger_than_size = value;
722       warn_larger_than = value != -1;
723       break;
724
725     case OPT_Wmissing_noreturn:
726       warn_missing_noreturn = value;
727       break;
728
729     case OPT_Wpacked:
730       warn_packed = value;
731       break;
732
733     case OPT_Wpadded:
734       warn_padded = value;
735       break;
736
737     case OPT_Wshadow:
738       warn_shadow = value;
739       break;
740
741     case OPT_Wstrict_aliasing:
742       warn_strict_aliasing = value;
743       break;
744
745     case OPT_Wswitch:
746       warn_switch = value;
747       break;
748
749     case OPT_Wswitch_default:
750       warn_switch_default = value;
751       break;
752
753     case OPT_Wswitch_enum:
754       warn_switch_enum = value;
755       break;
756
757     case OPT_Wsystem_headers:
758       warn_system_headers = value;
759       break;
760
761     case OPT_Wuninitialized:
762       warn_uninitialized = value;
763       break;
764
765     case OPT_Wunreachable_code:
766       warn_notreached = value;
767       break;
768
769     case OPT_Wunused:
770       set_Wunused (value);
771       break;
772
773     case OPT_Wunused_function:
774       warn_unused_function = value;
775       break;
776
777     case OPT_Wunused_label:
778       warn_unused_label = value;
779       break;
780
781     case OPT_Wunused_parameter:
782       warn_unused_parameter = value;
783       break;
784
785     case OPT_Wunused_value:
786       warn_unused_value = value;
787       break;
788
789     case OPT_Wunused_variable:
790       warn_unused_variable = value;
791       break;
792
793     case OPT_aux_info:
794     case OPT_aux_info_:
795       aux_info_file_name = arg;
796       flag_gen_aux_info = 1;
797       break;
798
799     case OPT_auxbase:
800       aux_base_name = arg;
801       break;
802
803     case OPT_auxbase_strip:
804       {
805         char *tmp = xstrdup (arg);
806         strip_off_ending (tmp, strlen (tmp));
807         if (tmp[0])
808           aux_base_name = tmp;
809       }
810       break;
811
812     case OPT_d:
813       decode_d_option (arg);
814       break;
815
816     case OPT_dumpbase:
817       dump_base_name = arg;
818       break;
819
820     case OPT_fPIC:
821       flag_pic = value + value;
822       break;
823
824     case OPT_fPIE:
825       flag_pie = value + value;
826       break;
827
828     case OPT_falign_functions:
829       align_functions = !value;
830       break;
831
832     case OPT_falign_functions_:
833       align_functions = value;
834       break;
835
836     case OPT_falign_jumps:
837       align_jumps = !value;
838       break;
839
840     case OPT_falign_jumps_:
841       align_jumps = value;
842       break;
843
844     case OPT_falign_labels:
845       align_labels = !value;
846       break;
847
848     case OPT_falign_labels_:
849       align_labels = value;
850       break;
851
852     case OPT_falign_loops:
853       align_loops = !value;
854       break;
855
856     case OPT_falign_loops_:
857       align_loops = value;
858       break;
859
860     case OPT_fargument_alias:
861       flag_argument_noalias = !value;
862       break;
863
864     case OPT_fargument_noalias:
865       flag_argument_noalias = value;
866       break;
867
868     case OPT_fargument_noalias_global:
869       flag_argument_noalias = value + value;
870       break;
871
872     case OPT_fasynchronous_unwind_tables:
873       flag_asynchronous_unwind_tables = value;
874       break;
875
876     case OPT_fbounds_check:
877       flag_bounds_check = value;
878       break;
879
880     case OPT_fbranch_count_reg:
881       flag_branch_on_count_reg = value;
882       break;
883
884     case OPT_fbranch_probabilities:
885       flag_branch_probabilities = value;
886       break;
887
888     case OPT_fbranch_target_load_optimize:
889       flag_branch_target_load_optimize = value;
890       break;
891
892     case OPT_fbranch_target_load_optimize2:
893       flag_branch_target_load_optimize2 = value;
894       break;
895
896     case OPT_fcall_used_:
897       fix_register (arg, 0, 1);
898       break;
899
900     case OPT_fcall_saved_:
901       fix_register (arg, 0, 0);
902       break;
903
904     case OPT_fcaller_saves:
905       flag_caller_saves = value;
906       break;
907
908     case OPT_fcommon:
909       flag_no_common = !value;
910       break;
911
912     case OPT_fcprop_registers:
913       flag_cprop_registers = value;
914       break;
915
916     case OPT_fcrossjumping:
917       flag_crossjumping = value;
918       break;
919
920     case OPT_fcse_follow_jumps:
921       flag_cse_follow_jumps = value;
922       break;
923
924     case OPT_fcse_skip_blocks:
925       flag_cse_skip_blocks = value;
926       break;
927
928     case OPT_fdata_sections:
929       flag_data_sections = value;
930       break;
931
932     case OPT_fdefer_pop:
933       flag_defer_pop = value;
934       break;
935
936     case OPT_fdelayed_branch:
937       flag_delayed_branch = value;
938       break;
939
940     case OPT_fdelete_null_pointer_checks:
941       flag_delete_null_pointer_checks = value;
942       break;
943
944     case OPT_fdiagnostics_show_location_:
945       if (!strcmp (arg, "once"))
946         diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
947       else if (!strcmp (arg, "every-line"))
948         diagnostic_prefixing_rule (global_dc)
949           = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
950       else
951         return 0;
952       break;
953
954     case OPT_fdump_unnumbered:
955       flag_dump_unnumbered = value;
956       break;
957
958     case OPT_feliminate_dwarf2_dups:
959       flag_eliminate_dwarf2_dups = value;
960       break;
961
962     case OPT_feliminate_unused_debug_types:
963       flag_eliminate_unused_debug_types = value;
964       break;
965
966     case OPT_feliminate_unused_debug_symbols:
967       flag_debug_only_used_symbols = value;
968       break;
969
970     case OPT_fexceptions:
971       flag_exceptions = value;
972       break;
973
974     case OPT_fexpensive_optimizations:
975       flag_expensive_optimizations = value;
976       break;
977
978     case OPT_ffast_math:
979       set_fast_math_flags (value);
980       break;
981
982     case OPT_ffinite_math_only:
983       flag_finite_math_only = value;
984       break;
985
986     case OPT_ffixed_:
987       fix_register (arg, 1, 1);
988       break;
989
990     case OPT_ffunction_cse:
991       flag_no_function_cse = !value;
992       break;
993
994     case OPT_ffloat_store:
995       flag_float_store = value;
996       break;
997
998     case OPT_fforce_addr:
999       flag_force_addr = value;
1000       break;
1001
1002     case OPT_fforce_mem:
1003       flag_force_mem = value;
1004       break;
1005
1006     case OPT_ffunction_sections:
1007       flag_function_sections = value;
1008       break;
1009
1010     case OPT_fgcse:
1011       flag_gcse = value;
1012       break;
1013
1014     case OPT_fgcse_lm:
1015       flag_gcse_lm = value;
1016       break;
1017
1018     case OPT_fgcse_sm:
1019       flag_gcse_sm = value;
1020       break;
1021
1022     case OPT_fgcse_las:
1023       flag_gcse_las = value;
1024       break;
1025
1026     case OPT_fgnu_linker:
1027       flag_gnu_linker = value;
1028       break;
1029
1030     case OPT_fguess_branch_probability:
1031       flag_guess_branch_prob = value;
1032       break;
1033
1034     case OPT_fident:
1035       flag_no_ident = !value;
1036       break;
1037
1038     case OPT_fif_conversion:
1039       flag_if_conversion = value;
1040       break;
1041
1042     case OPT_fif_conversion2:
1043       flag_if_conversion2 = value;
1044       break;
1045
1046     case OPT_finhibit_size_directive:
1047       flag_inhibit_size_directive = value;
1048       break;
1049
1050     case OPT_finline:
1051       flag_no_inline = !value;
1052       break;
1053
1054     case OPT_finline_functions:
1055       flag_inline_functions = value;
1056       break;
1057
1058     case OPT_finline_limit_:
1059     case OPT_finline_limit_eq:
1060       set_param_value ("max-inline-insns", value);
1061       set_param_value ("max-inline-insns-single", value / 2);
1062       set_param_value ("max-inline-insns-auto", value / 2);
1063       set_param_value ("max-inline-insns-rtl", value);
1064       if (value / 4 < MIN_INLINE_INSNS)
1065         {
1066           if (value / 4 > 10)
1067             set_param_value ("min-inline-insns", value / 4);
1068           else
1069             set_param_value ("min-inline-insns", 10);
1070         }
1071       break;
1072
1073     case OPT_finstrument_functions:
1074       flag_instrument_function_entry_exit = value;
1075       break;
1076
1077     case OPT_fkeep_inline_functions:
1078       flag_keep_inline_functions =value;
1079       break;
1080
1081     case OPT_fkeep_static_consts:
1082       flag_keep_static_consts = value;
1083       break;
1084
1085     case OPT_fleading_underscore:
1086       flag_leading_underscore = value;
1087       break;
1088
1089     case OPT_floop_optimize:
1090       flag_loop_optimize = value;
1091       break;
1092
1093     case OPT_fmath_errno:
1094       flag_errno_math = value;
1095       break;
1096
1097     case OPT_fmem_report:
1098       mem_report = value;
1099       break;
1100
1101     case OPT_fmerge_all_constants:
1102       flag_merge_constants = value + value;
1103       break;
1104
1105     case OPT_fmerge_constants:
1106       flag_merge_constants = value;
1107       break;
1108
1109     case OPT_fmessage_length_:
1110       pp_set_line_maximum_length (global_dc->printer, value);
1111       break;
1112
1113     case OPT_fmove_all_movables:
1114       flag_move_all_movables = value;
1115       break;
1116
1117     case OPT_fnew_ra:
1118       flag_new_regalloc = value;
1119       break;
1120
1121     case OPT_fnon_call_exceptions:
1122       flag_non_call_exceptions = value;
1123       break;
1124
1125     case OPT_fold_unroll_all_loops:
1126       flag_old_unroll_all_loops = value;
1127       break;
1128
1129     case OPT_fold_unroll_loops:
1130       flag_old_unroll_loops = value;
1131       break;
1132
1133     case OPT_fomit_frame_pointer:
1134       flag_omit_frame_pointer = value;
1135       break;
1136
1137     case OPT_foptimize_register_move:
1138       flag_regmove = value;
1139       break;
1140
1141     case OPT_foptimize_sibling_calls:
1142       flag_optimize_sibling_calls = value;
1143       break;
1144
1145     case OPT_fpack_struct:
1146       flag_pack_struct = value;
1147       break;
1148
1149     case OPT_fpeel_loops:
1150       flag_peel_loops = value;
1151       break;
1152
1153     case OPT_fpcc_struct_return:
1154       flag_pcc_struct_return = value;
1155       break;
1156
1157     case OPT_fpeephole:
1158       flag_no_peephole = !value;
1159       break;
1160
1161     case OPT_fpeephole2:
1162       flag_peephole2 = value;
1163       break;
1164
1165     case OPT_fpic:
1166       flag_pic = value;
1167       break;
1168
1169     case OPT_fpie:
1170       flag_pie = value;
1171       break;
1172
1173     case OPT_fprefetch_loop_arrays:
1174       flag_prefetch_loop_arrays = value;
1175       break;
1176
1177     case OPT_fprofile:
1178       profile_flag = value;
1179       break;
1180
1181     case OPT_fprofile_arcs:
1182       profile_arc_flag = value;
1183       break;
1184
1185     case OPT_fprofile_values:
1186       flag_profile_values = value;
1187       break;
1188
1189     case OPT_fvpt:
1190       flag_value_profile_transformations = value;
1191       break;
1192
1193     case OPT_frandom_seed:
1194       /* The real switch is -fno-random-seed.  */
1195       if (value)
1196         return 0;
1197       flag_random_seed = NULL;
1198       break;
1199
1200     case OPT_frandom_seed_:
1201       flag_random_seed = arg;
1202       break;
1203
1204     case OPT_freduce_all_givs:
1205       flag_reduce_all_givs = value;
1206       break;
1207
1208     case OPT_freg_struct_return:
1209       flag_pcc_struct_return = !value;
1210       break;
1211
1212     case OPT_fregmove:
1213       flag_regmove = value;
1214       break;
1215
1216     case OPT_frename_registers:
1217       flag_rename_registers = value;
1218       break;
1219
1220     case OPT_freorder_blocks:
1221       flag_reorder_blocks = value;
1222       break;
1223
1224     case OPT_freorder_functions:
1225       flag_reorder_functions = value;
1226       break;
1227
1228     case OPT_frerun_cse_after_loop:
1229       flag_rerun_cse_after_loop = value;
1230       break;
1231
1232     case OPT_frerun_loop_opt:
1233       flag_rerun_loop_opt = value;
1234       break;
1235
1236     case OPT_frounding_math:
1237       flag_rounding_math = value;
1238       break;
1239
1240     case OPT_fsched_interblock:
1241       flag_schedule_interblock = value;
1242       break;
1243
1244     case OPT_fsched_spec:
1245       flag_schedule_speculative = value;
1246       break;
1247
1248     case OPT_fsched_spec_load:
1249       flag_schedule_speculative_load = value;
1250       break;
1251
1252     case OPT_fsched_spec_load_dangerous:
1253       flag_schedule_speculative_load_dangerous = value;
1254       break;
1255
1256     case OPT_fsched_verbose_:
1257 #ifdef INSN_SCHEDULING
1258       fix_sched_param ("verbose", arg);
1259       break;
1260 #else
1261       return 0;
1262 #endif
1263
1264     case OPT_fsched2_use_superblocks:
1265       flag_sched2_use_superblocks = value;
1266       break;
1267
1268     case OPT_fsched2_use_traces:
1269       flag_sched2_use_traces = value;
1270       break;
1271
1272     case OPT_fschedule_insns:
1273       flag_schedule_insns = value;
1274       break;
1275
1276     case OPT_fschedule_insns2:
1277       flag_schedule_insns_after_reload = value;
1278       break;
1279
1280     case OPT_fsched_stalled_insns:
1281       flag_sched_stalled_insns = value;
1282       break;
1283
1284     case OPT_fsched_stalled_insns_:
1285       flag_sched_stalled_insns = value;
1286       if (flag_sched_stalled_insns == 0)
1287         flag_sched_stalled_insns = -1;
1288       break;
1289
1290     case OPT_fsched_stalled_insns_dep:
1291       flag_sched_stalled_insns_dep = 1;
1292       break;
1293
1294     case OPT_fsched_stalled_insns_dep_:
1295       flag_sched_stalled_insns_dep = value;
1296       break;
1297
1298     case OPT_fshared_data:
1299       flag_shared_data = value;
1300       break;
1301
1302     case OPT_fsignaling_nans:
1303       flag_signaling_nans = value;
1304       break;
1305
1306     case OPT_fsingle_precision_constant:
1307       flag_single_precision_constant = value;
1308       break;
1309
1310     case OPT_fssa:
1311       flag_ssa = value;
1312       break;
1313
1314     case OPT_fssa_ccp:
1315       flag_ssa_ccp = value;
1316       break;
1317
1318     case OPT_fssa_dce:
1319       flag_ssa_dce = value;
1320       break;
1321
1322     case OPT_fstack_check:
1323       flag_stack_check = value;
1324       break;
1325
1326     case OPT_fstack_limit:
1327       /* The real switch is -fno-stack-limit.  */
1328       if (value)
1329         return 0;
1330       stack_limit_rtx = NULL_RTX;
1331       break;
1332
1333     case OPT_fstack_limit_register_:
1334       {
1335         int reg = decode_reg_name (arg);
1336         if (reg < 0)
1337           error ("unrecognized register name \"%s\"", arg);
1338         else
1339           stack_limit_rtx = gen_rtx_REG (Pmode, reg);
1340       }
1341       break;
1342
1343     case OPT_fstack_limit_symbol_:
1344       stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg));
1345       break;
1346
1347     case OPT_fstrength_reduce:
1348       flag_strength_reduce = value;
1349       break;
1350
1351     case OPT_fstrict_aliasing:
1352       flag_strict_aliasing = value;
1353       break;
1354
1355     case OPT_fsyntax_only:
1356       flag_syntax_only = value;
1357       break;
1358
1359     case OPT_ftest_coverage:
1360       flag_test_coverage = value;
1361       break;
1362
1363     case OPT_fthread_jumps:
1364       flag_thread_jumps = value;
1365       break;
1366
1367     case OPT_ftime_report:
1368       time_report = value;
1369       break;
1370
1371     case OPT_ftls_model_:
1372       if (!strcmp (arg, "global-dynamic"))
1373         flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
1374       else if (!strcmp (arg, "local-dynamic"))
1375         flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
1376       else if (!strcmp (arg, "initial-exec"))
1377         flag_tls_default = TLS_MODEL_INITIAL_EXEC;
1378       else if (!strcmp (arg, "local-exec"))
1379         flag_tls_default = TLS_MODEL_LOCAL_EXEC;
1380       else
1381         warning ("unknown tls-model \"%s\"", arg);
1382       break;
1383
1384     case OPT_ftracer:
1385       flag_tracer = value;
1386       break;
1387
1388     case OPT_ftrapping_math:
1389       flag_trapping_math = value;
1390       break;
1391
1392     case OPT_ftrapv:
1393       flag_trapv = value;
1394       break;
1395
1396     case OPT_funit_at_a_time:
1397       flag_unit_at_a_time = value;
1398       break;
1399
1400     case OPT_funroll_all_loops:
1401       flag_unroll_all_loops = value;
1402       break;
1403
1404     case OPT_funroll_loops:
1405       flag_unroll_loops = value;
1406       break;
1407
1408     case OPT_funsafe_math_optimizations:
1409       flag_unsafe_math_optimizations = value;
1410       break;
1411
1412     case OPT_funswitch_loops:
1413       flag_unswitch_loops = value;
1414       break;
1415
1416     case OPT_funwind_tables:
1417       flag_unwind_tables = value;
1418       break;
1419
1420     case OPT_fverbose_asm:
1421       flag_verbose_asm = value;
1422       break;
1423
1424     case OPT_fweb:
1425       flag_web = value;
1426       break;
1427       
1428     case OPT_fwrapv:
1429       flag_wrapv = value;
1430       break;
1431
1432     case OPT_fwritable_strings:
1433       flag_writable_strings = value;
1434       break;
1435
1436     case OPT_fzero_initialized_in_bss:
1437       flag_zero_initialized_in_bss = value;
1438       break;
1439
1440     case OPT_g:
1441       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
1442       break;
1443
1444     case OPT_gcoff:
1445       set_debug_level (SDB_DEBUG, false, arg);
1446       break;
1447
1448     case OPT_gdwarf:
1449       if (*arg)
1450         {
1451           error ("use -gdwarf -gN for DWARF v1 level N, "
1452                  "and -gdwarf-2 for DWARF v2" );
1453           break;
1454         }
1455
1456       /* Fall through.  */
1457     case OPT_gdwarf_:
1458       set_debug_level (DWARF_DEBUG, code == OPT_gdwarf_, arg);
1459       break;
1460
1461     case OPT_gdwarf_2:
1462       set_debug_level (DWARF2_DEBUG, false, arg);
1463       break;
1464
1465     case OPT_ggdb:
1466       set_debug_level (NO_DEBUG, 2, arg);
1467       break;
1468
1469     case OPT_gstabs:
1470     case OPT_gstabs_:
1471       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg);
1472       break;
1473
1474     case OPT_gvms:
1475       set_debug_level (VMS_DEBUG, false, arg);
1476       break;
1477
1478     case OPT_gxcoff:
1479     case OPT_gxcoff_:
1480       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg);
1481       break;
1482
1483     case OPT_m:
1484       set_target_switch (arg);
1485       break;
1486
1487     case OPT_o:
1488       asm_file_name = arg;
1489       break;
1490
1491     case OPT_p:
1492       profile_flag = 1;
1493       break;
1494
1495     case OPT_pedantic:
1496       pedantic = 1;
1497       break;
1498
1499     case OPT_pedantic_errors:
1500       flag_pedantic_errors = pedantic = 1;
1501       break;
1502
1503     case OPT_quiet:
1504       quiet_flag = 1;
1505       break;
1506
1507     case OPT_version:
1508       version_flag = 1;
1509       break;
1510
1511     case OPT_w:
1512       inhibit_warnings = true;
1513       break;      
1514     }
1515
1516   return 1;
1517 }
1518
1519 /* Handle --param NAME=VALUE.  */
1520 static void
1521 handle_param (const char *carg)
1522 {
1523   char *equal, *arg;
1524   int value;
1525
1526   arg = xstrdup (carg);
1527   equal = strchr (arg, '=');
1528   if (!equal)
1529     error ("%s: --param arguments should be of the form NAME=VALUE", arg);
1530   else
1531     {
1532       value = integral_argument (equal + 1);
1533       if (value == -1)
1534         error ("invalid --param value `%s'", equal + 1);
1535       else
1536         {
1537           *equal = '\0';
1538           set_param_value (arg, value);
1539         }
1540     }
1541
1542   free (arg);
1543 }
1544
1545 /* Handle -W and -Wextra.  */
1546 static void
1547 set_Wextra (int setting)
1548 {
1549   extra_warnings = setting;
1550   warn_unused_value = setting;
1551   warn_unused_parameter = (setting && maybe_warn_unused_parameter);
1552
1553   /* We save the value of warn_uninitialized, since if they put
1554      -Wuninitialized on the command line, we need to generate a
1555      warning about not using it without also specifying -O.  */
1556   if (setting == 0)
1557     warn_uninitialized = 0;
1558   else if (warn_uninitialized != 1)
1559     warn_uninitialized = 2;
1560 }
1561
1562 /* Initialize unused warning flags.  */
1563 void
1564 set_Wunused (int setting)
1565 {
1566   warn_unused_function = setting;
1567   warn_unused_label = setting;
1568   /* Unused function parameter warnings are reported when either
1569      ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.
1570      Thus, if -Wextra has already been seen, set warn_unused_parameter;
1571      otherwise set maybe_warn_extra_parameter, which will be picked up
1572      by set_Wextra.  */
1573   maybe_warn_unused_parameter = setting;
1574   warn_unused_parameter = (setting && extra_warnings);
1575   warn_unused_variable = setting;
1576   warn_unused_value = setting;
1577 }
1578
1579 /* The following routines are useful in setting all the flags that
1580    -ffast-math and -fno-fast-math imply.  */
1581 void
1582 set_fast_math_flags (int set)
1583 {
1584   flag_trapping_math = !set;
1585   flag_unsafe_math_optimizations = set;
1586   flag_finite_math_only = set;
1587   flag_errno_math = !set;
1588   if (set)
1589     {
1590       flag_signaling_nans = 0;
1591       flag_rounding_math = 0;
1592     }
1593 }
1594
1595 /* Return true iff flags are set as if -ffast-math.  */
1596 bool
1597 fast_math_flags_set_p (void)
1598 {
1599   return (!flag_trapping_math
1600           && flag_unsafe_math_optimizations
1601           && flag_finite_math_only
1602           && !flag_errno_math);
1603 }
1604
1605 /* Handle a debug output -g switch.  EXTENDED is true or false to support
1606    extended output (2 is special and means "-ggdb" was given).  */
1607 static void
1608 set_debug_level (enum debug_info_type type, int extended, const char *arg)
1609 {
1610   static bool type_explicit;
1611
1612   use_gnu_debug_info_extensions = extended;
1613
1614   if (type == NO_DEBUG)
1615     {
1616       if (write_symbols == NO_DEBUG)
1617         {
1618           write_symbols = PREFERRED_DEBUGGING_TYPE;
1619
1620           if (extended == 2)
1621             {
1622 #ifdef DWARF2_DEBUGGING_INFO
1623               write_symbols = DWARF2_DEBUG;
1624 #elif defined DBX_DEBUGGING_INFO
1625               write_symbols = DBX_DEBUG;
1626 #endif
1627             }
1628
1629           if (write_symbols == NO_DEBUG)
1630             warning ("target system does not support debug output");
1631         }
1632     }
1633   else
1634     {
1635       /* Does it conflict with an already selected type?  */
1636       if (type_explicit && write_symbols != NO_DEBUG && type != write_symbols)
1637         error ("debug format \"%s\" conflicts with prior selection",
1638                debug_type_names[type]);
1639       write_symbols = type;
1640       type_explicit = true;
1641     }
1642
1643   /* A debug flag without a level defaults to level 2.  */
1644   if (*arg == '\0')
1645     {
1646       if (!debug_info_level)
1647         debug_info_level = 2;
1648     }
1649   else
1650     {
1651       debug_info_level = integral_argument (arg);
1652       if (debug_info_level == (unsigned int) -1)
1653         error ("unrecognised debug output level \"%s\"", arg);
1654       else if (debug_info_level > 3)
1655         error ("debug output level %s is too high", arg);
1656     }
1657 }
1658
1659 /* Output --help text.  */
1660 static void
1661 print_help (void)
1662 {
1663   size_t i;
1664   const char *p;
1665
1666   GET_ENVIRONMENT (p, "COLUMNS");
1667   if (p)
1668     {
1669       int value = atoi (p);
1670       if (value > 0)
1671         columns = value;
1672     }
1673
1674   puts (_("The following options are language-independent:\n"));
1675
1676   print_filtered_help (CL_COMMON);
1677   print_param_help ();
1678
1679   for (i = 0; lang_names[i]; i++)
1680     {
1681       printf (_("The %s front end recognizes the following options:\n\n"),
1682               lang_names[i]);
1683       print_filtered_help (1U << i);
1684     }
1685
1686   display_target_options ();
1687 }
1688
1689 /* Print the help for --param.  */
1690 static void
1691 print_param_help (void)
1692 {
1693   size_t i;
1694
1695   puts (_("The --param option recognizes the following as parameters:\n"));
1696
1697   for (i = 0; i < LAST_PARAM; i++)
1698     {
1699       const char *help = compiler_params[i].help;
1700       const char *param = compiler_params[i].option;
1701
1702       if (help == NULL || *help == '\0')
1703         help = undocumented_msg;
1704
1705       /* Get the translation.  */
1706       help = _(help);
1707
1708       wrap_help (help, param, strlen (param));
1709     }
1710
1711   putchar ('\n');
1712 }
1713
1714 /* Print help for a specific front-end, etc.  */
1715 static void
1716 print_filtered_help (unsigned int flag)
1717 {
1718   unsigned int i, len, filter, indent = 0;
1719   bool duplicates = false;
1720   const char *help, *opt, *tab;
1721   static char *printed;
1722
1723   if (flag == CL_COMMON)
1724     {
1725       filter = flag;
1726       if (!printed)
1727         printed = xmalloc (cl_options_count);
1728       memset (printed, 0, cl_options_count);
1729     }
1730   else
1731     {
1732       /* Don't print COMMON options twice.  */
1733       filter = flag | CL_COMMON;
1734
1735       for (i = 0; i < cl_options_count; i++)
1736         {
1737           if ((cl_options[i].flags & filter) != flag)
1738             continue;
1739
1740           /* Skip help for internal switches.  */
1741           if (cl_options[i].flags & CL_UNDOCUMENTED)
1742             continue;
1743
1744           /* Skip switches that have already been printed, mark them to be
1745              listed later.  */
1746           if (printed[i])
1747             {
1748               duplicates = true;
1749               indent = print_switch (cl_options[i].opt_text, indent);
1750             }
1751         }
1752
1753       if (duplicates)
1754         {
1755           putchar ('\n');
1756           putchar ('\n');
1757         }
1758     }
1759
1760   for (i = 0; i < cl_options_count; i++)
1761     {
1762       if ((cl_options[i].flags & filter) != flag)
1763         continue;
1764
1765       /* Skip help for internal switches.  */
1766       if (cl_options[i].flags & CL_UNDOCUMENTED)
1767         continue;
1768
1769       /* Skip switches that have already been printed.  */
1770       if (printed[i])
1771         continue;
1772
1773       printed[i] = true;
1774
1775       help = cl_options[i].help;
1776       if (!help)
1777         help = undocumented_msg;
1778
1779       /* Get the translation.  */
1780       help = _(help);
1781
1782       tab = strchr (help, '\t');
1783       if (tab)
1784         {
1785           len = tab - help;
1786           opt = help;
1787           help = tab + 1;
1788         }
1789       else
1790         {
1791           opt = cl_options[i].opt_text;
1792           len = strlen (opt);
1793         }
1794
1795       wrap_help (help, opt, len);
1796     }
1797
1798   putchar ('\n');
1799 }
1800
1801 /* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
1802    word-wrapped HELP in a second column.  */
1803 static unsigned int
1804 print_switch (const char *text, unsigned int indent)
1805 {
1806   unsigned int len = strlen (text) + 1; /* trailing comma */
1807
1808   if (indent)
1809     {
1810       putchar (',');
1811       if (indent + len > columns)
1812         {
1813           putchar ('\n');
1814           putchar (' ');
1815           indent = 1;
1816         }
1817     }
1818   else
1819     putchar (' ');
1820
1821   putchar (' ');
1822   fputs (text, stdout);
1823
1824   return indent + len + 1;
1825 }
1826
1827 /* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
1828    word-wrapped HELP in a second column.  */
1829 static void
1830 wrap_help (const char *help, const char *item, unsigned int item_width)
1831 {
1832   unsigned int col_width = 27;
1833   unsigned int remaining, room, len;
1834
1835   remaining = strlen (help);
1836
1837   do
1838     {
1839       room = columns - 3 - MAX (col_width, item_width);
1840       if (room > columns)
1841         room = 0;
1842       len = remaining;
1843
1844       if (room < len)
1845         {
1846           unsigned int i;
1847
1848           for (i = 0; help[i]; i++)
1849             {
1850               if (i >= room && len != remaining)
1851                 break;
1852               if (help[i] == ' ')
1853                 len = i;
1854               else if ((help[i] == '-' || help[i] == '/')
1855                        && help[i + 1] != ' '
1856                        && ISALPHA (help[i - 1]))
1857                 len = i + 1;
1858             }
1859         }
1860
1861       printf( "  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1862       item_width = 0;
1863       while (help[len] == ' ')
1864         len++;
1865       help += len;
1866       remaining -= len;
1867     }
1868   while (remaining);
1869 }