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