opts.c revision 259268
1/* Command line option handling.
2   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3   Free Software Foundation, Inc.
4   Contributed by Neil Booth.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING.  If not, write to the Free
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA.  */
22
23/* $FreeBSD: stable/10/contrib/gcc/opts.c 259268 2013-12-12 18:15:32Z pfg $ */
24
25#include "config.h"
26#include "system.h"
27#include "intl.h"
28#include "coretypes.h"
29#include "tm.h"
30#include "tree.h"
31#include "rtl.h"
32#include "ggc.h"
33#include "output.h"
34#include "langhooks.h"
35#include "opts.h"
36#include "options.h"
37#include "flags.h"
38#include "toplev.h"
39#include "params.h"
40#include "diagnostic.h"
41#include "tm_p.h"		/* For OPTIMIZATION_OPTIONS.  */
42#include "insn-attr.h"		/* For INSN_SCHEDULING.  */
43#include "target.h"
44#include "tree-pass.h"
45
46/* Value of the -G xx switch, and whether it was passed or not.  */
47unsigned HOST_WIDE_INT g_switch_value;
48bool g_switch_set;
49
50/* True if we should exit after parsing options.  */
51bool exit_after_options;
52
53/* Print various extra warnings.  -W/-Wextra.  */
54bool extra_warnings;
55
56/* True to warn about any objects definitions whose size is larger
57   than N bytes.  Also want about function definitions whose returned
58   values are larger than N bytes, where N is `larger_than_size'.  */
59bool warn_larger_than;
60HOST_WIDE_INT larger_than_size;
61
62/* Nonzero means warn about constructs which might not be
63   strict-aliasing safe.  */
64int warn_strict_aliasing;
65
66/* Nonzero means warn about optimizations which rely on undefined
67   signed overflow.  */
68int warn_strict_overflow;
69
70/* Hack for cooperation between set_Wunused and set_Wextra.  */
71static bool maybe_warn_unused_parameter;
72
73/* Type(s) of debugging information we are producing (if any).  See
74   flags.h for the definitions of the different possible types of
75   debugging information.  */
76enum debug_info_type write_symbols = NO_DEBUG;
77
78/* Level of debugging information we are producing.  See flags.h for
79   the definitions of the different possible levels.  */
80enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
81
82/* A major contribution to object and executable size is debug
83   information size.  A major contribution to debug information size
84   is struct descriptions replicated in several object files. The
85   following flags attempt to reduce this information.  The basic
86   idea is to not emit struct debugging information in the current
87   compilation unit when that information will be generated by
88   another compilation unit.
89
90   Debug information for a struct defined in the current source
91   file should be generated in the object file.  Likewise the
92   debug information for a struct defined in a header should be
93   generated in the object file of the corresponding source file.
94   Both of these case are handled when the base name of the file of
95   the struct definition matches the base name of the source file
96   of thet current compilation unit.  This matching emits minimal
97   struct debugging information.
98
99   The base file name matching rule above will fail to emit debug
100   information for structs defined in system headers.  So a second
101   category of files includes system headers in addition to files
102   with matching bases.
103
104   The remaining types of files are library headers and application
105   headers.  We cannot currently distinguish these two types.  */
106
107enum debug_struct_file
108{
109  DINFO_STRUCT_FILE_NONE,   /* Debug no structs. */
110  DINFO_STRUCT_FILE_BASE,   /* Debug structs defined in files with the
111                               same base name as the compilation unit. */
112  DINFO_STRUCT_FILE_SYS,    /* Also debug structs defined in system
113                               header files.  */
114  DINFO_STRUCT_FILE_ANY     /* Debug structs defined in all files. */
115};
116
117/* Generic structs (e.g. templates not explicitly specialized)
118   may not have a compilation unit associated with them, and so
119   may need to be treated differently from ordinary structs.
120
121   Structs only handled by reference (indirectly), will also usually
122   not need as much debugging information.  */
123
124static enum debug_struct_file debug_struct_ordinary[DINFO_USAGE_NUM_ENUMS]
125  = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY };
126static enum debug_struct_file debug_struct_generic[DINFO_USAGE_NUM_ENUMS]
127  = { DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY, DINFO_STRUCT_FILE_ANY };
128
129/* Parse the -femit-struct-debug-detailed option value
130   and set the flag variables. */
131
132#define MATCH( prefix, string ) \
133  ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
134   ? ((string += sizeof prefix - 1), 1) : 0)
135
136void
137set_struct_debug_option (const char *spec)
138{
139  /* various labels for comparison */
140  static char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
141  static char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
142  static char none_lbl[] = "none", any_lbl[] = "any";
143  static char base_lbl[] = "base", sys_lbl[] = "sys";
144
145  enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
146  /* Default is to apply to as much as possible. */
147  enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
148  int ord = 1, gen = 1;
149
150  /* What usage? */
151  if (MATCH (dfn_lbl, spec))
152    usage = DINFO_USAGE_DFN;
153  else if (MATCH (dir_lbl, spec))
154    usage = DINFO_USAGE_DIR_USE;
155  else if (MATCH (ind_lbl, spec))
156    usage = DINFO_USAGE_IND_USE;
157
158  /* Generics or not? */
159  if (MATCH (ord_lbl, spec))
160    gen = 0;
161  else if (MATCH (gen_lbl, spec))
162    ord = 0;
163
164  /* What allowable environment? */
165  if (MATCH (none_lbl, spec))
166    files = DINFO_STRUCT_FILE_NONE;
167  else if (MATCH (any_lbl, spec))
168    files = DINFO_STRUCT_FILE_ANY;
169  else if (MATCH (sys_lbl, spec))
170    files = DINFO_STRUCT_FILE_SYS;
171  else if (MATCH (base_lbl, spec))
172    files = DINFO_STRUCT_FILE_BASE;
173  else
174    error ("argument %qs to %<-femit-struct-debug-detailed%> not recognized",
175           spec);
176
177  /* Effect the specification. */
178  if (usage == DINFO_USAGE_NUM_ENUMS)
179    {
180      if (ord)
181        {
182          debug_struct_ordinary[DINFO_USAGE_DFN] = files;
183          debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
184          debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
185        }
186      if (gen)
187        {
188          debug_struct_generic[DINFO_USAGE_DFN] = files;
189          debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
190          debug_struct_generic[DINFO_USAGE_IND_USE] = files;
191        }
192    }
193  else
194    {
195      if (ord)
196        debug_struct_ordinary[usage] = files;
197      if (gen)
198        debug_struct_generic[usage] = files;
199    }
200
201  if (*spec == ',')
202    set_struct_debug_option (spec+1);
203  else
204    {
205      /* No more -femit-struct-debug-detailed specifications.
206         Do final checks. */
207      if (*spec != '\0')
208	error ("argument %qs to %<-femit-struct-debug-detailed%> unknown",
209               spec);
210      if (debug_struct_ordinary[DINFO_USAGE_DIR_USE]
211		< debug_struct_ordinary[DINFO_USAGE_IND_USE]
212	  || debug_struct_generic[DINFO_USAGE_DIR_USE]
213		< debug_struct_generic[DINFO_USAGE_IND_USE])
214	error ("%<-femit-struct-debug-detailed=dir:...%> must allow at least"
215               " as much as %<-femit-struct-debug-detailed=ind:...%>");
216    }
217}
218
219/* Find the base name of a path, stripping off both directories and
220   a single final extension. */
221static int
222base_of_path (const char *path, const char **base_out)
223{
224  const char *base = path;
225  const char *dot = 0;
226  const char *p = path;
227  char c = *p;
228  while (c)
229    {
230      if (IS_DIR_SEPARATOR(c))
231        {
232          base = p + 1;
233          dot = 0;
234        }
235      else if (c == '.')
236        dot = p;
237      c = *++p;
238    }
239  if (!dot)
240    dot = p;
241  *base_out = base;
242  return dot - base;
243}
244
245/* Match the base name of a file to the base name of a compilation unit. */
246
247static const char *main_input_basename;
248static int main_input_baselength;
249
250static int
251matches_main_base (const char *path)
252{
253  /* Cache the last query. */
254  static const char *last_path = NULL;
255  static int last_match = 0;
256  if (path != last_path)
257    {
258      const char *base;
259      int length = base_of_path (path, &base);
260      last_path = path;
261      last_match = (length == main_input_baselength
262                    && memcmp (base, main_input_basename, length) == 0);
263    }
264  return last_match;
265}
266
267#ifdef DEBUG_DEBUG_STRUCT
268
269static int
270dump_struct_debug (tree type, enum debug_info_usage usage,
271		   enum debug_struct_file criterion, int generic,
272		   int matches, int result)
273{
274  /* Find the type name. */
275  tree type_decl = TYPE_STUB_DECL (type);
276  tree t = type_decl;
277  const char *name = 0;
278  if (TREE_CODE (t) == TYPE_DECL)
279    t = DECL_NAME (t);
280  if (t)
281    name = IDENTIFIER_POINTER (t);
282
283  fprintf (stderr, "	struct %d %s %s %s %s %d %p %s\n",
284	   criterion,
285           DECL_IN_SYSTEM_HEADER (type_decl) ? "sys" : "usr",
286           matches ? "bas" : "hdr",
287           generic ? "gen" : "ord",
288           usage == DINFO_USAGE_DFN ? ";" :
289             usage == DINFO_USAGE_DIR_USE ? "." : "*",
290           result,
291           (void*) type_decl, name);
292  return result;
293}
294#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
295  dump_struct_debug (type, usage, criterion, generic, matches, result)
296
297#else
298
299#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
300  (result)
301
302#endif
303
304
305bool
306should_emit_struct_debug (tree type, enum debug_info_usage usage)
307{
308  enum debug_struct_file criterion;
309  tree type_decl;
310  bool generic = lang_hooks.types.generic_p (type);
311
312  if (generic)
313    criterion = debug_struct_generic[usage];
314  else
315    criterion = debug_struct_ordinary[usage];
316
317  if (criterion == DINFO_STRUCT_FILE_NONE)
318    return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
319  if (criterion == DINFO_STRUCT_FILE_ANY)
320    return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
321
322  type_decl = TYPE_STUB_DECL (type);
323
324  if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl))
325    return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);
326
327  if (matches_main_base (DECL_SOURCE_FILE (type_decl)))
328    return DUMP_GSTRUCT (type, usage, criterion, generic, true, true);
329  return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
330}
331
332/* Nonzero means use GNU-only extensions in the generated symbolic
333   debugging information.  Currently, this only has an effect when
334   write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
335bool use_gnu_debug_info_extensions;
336
337/* The default visibility for all symbols (unless overridden) */
338enum symbol_visibility default_visibility = VISIBILITY_DEFAULT;
339
340/* Disable unit-at-a-time for frontends that might be still broken in this
341   respect.  */
342
343bool no_unit_at_a_time_default;
344
345/* Global visibility options.  */
346struct visibility_flags visibility_options;
347
348/* Columns of --help display.  */
349static unsigned int columns = 80;
350
351/* What to print when a switch has no documentation.  */
352static const char undocumented_msg[] = N_("This switch lacks documentation");
353
354/* Used for bookkeeping on whether user set these flags so
355   -fprofile-use/-fprofile-generate does not use them.  */
356static bool profile_arc_flag_set, flag_profile_values_set;
357static bool flag_unroll_loops_set, flag_tracer_set;
358static bool flag_value_profile_transformations_set;
359static bool flag_peel_loops_set, flag_branch_probabilities_set;
360
361/* Input file names.  */
362const char **in_fnames;
363unsigned num_in_fnames;
364
365static int common_handle_option (size_t scode, const char *arg, int value,
366				 unsigned int lang_mask);
367static void handle_param (const char *);
368static void set_Wextra (int);
369static unsigned int handle_option (const char **argv, unsigned int lang_mask);
370static char *write_langs (unsigned int lang_mask);
371static void complain_wrong_lang (const char *, const struct cl_option *,
372				 unsigned int lang_mask);
373static void handle_options (unsigned int, const char **, unsigned int);
374static void wrap_help (const char *help, const char *item, unsigned int);
375static void print_target_help (void);
376static void print_help (void);
377static void print_param_help (void);
378static void print_filtered_help (unsigned int);
379static unsigned int print_switch (const char *text, unsigned int indent);
380static void set_debug_level (enum debug_info_type type, int extended,
381			     const char *arg);
382
383/* If ARG is a non-negative integer made up solely of digits, return its
384   value, otherwise return -1.  */
385static int
386integral_argument (const char *arg)
387{
388  const char *p = arg;
389
390  while (*p && ISDIGIT (*p))
391    p++;
392
393  if (*p == '\0')
394    return atoi (arg);
395
396  return -1;
397}
398
399/* Return a malloced slash-separated list of languages in MASK.  */
400static char *
401write_langs (unsigned int mask)
402{
403  unsigned int n = 0, len = 0;
404  const char *lang_name;
405  char *result;
406
407  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
408    if (mask & (1U << n))
409      len += strlen (lang_name) + 1;
410
411  result = XNEWVEC (char, len);
412  len = 0;
413  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
414    if (mask & (1U << n))
415      {
416	if (len)
417	  result[len++] = '/';
418	strcpy (result + len, lang_name);
419	len += strlen (lang_name);
420      }
421
422  result[len] = 0;
423
424  return result;
425}
426
427/* Complain that switch OPT_INDEX does not apply to this front end.  */
428static void
429complain_wrong_lang (const char *text, const struct cl_option *option,
430		     unsigned int lang_mask)
431{
432  char *ok_langs, *bad_lang;
433
434  ok_langs = write_langs (option->flags);
435  bad_lang = write_langs (lang_mask);
436
437  /* Eventually this should become a hard error IMO.  */
438  warning (0, "command line option \"%s\" is valid for %s but not for %s",
439	   text, ok_langs, bad_lang);
440
441  free (ok_langs);
442  free (bad_lang);
443}
444
445/* Handle the switch beginning at ARGV for the language indicated by
446   LANG_MASK.  Returns the number of switches consumed.  */
447static unsigned int
448handle_option (const char **argv, unsigned int lang_mask)
449{
450  size_t opt_index;
451  const char *opt, *arg = 0;
452  char *dup = 0;
453  int value = 1;
454  unsigned int result = 0;
455  const struct cl_option *option;
456
457  opt = argv[0];
458
459  opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
460  if (opt_index == cl_options_count
461      && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
462      && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
463    {
464      /* Drop the "no-" from negative switches.  */
465      size_t len = strlen (opt) - 3;
466
467      dup = XNEWVEC (char, len + 1);
468      dup[0] = '-';
469      dup[1] = opt[1];
470      memcpy (dup + 2, opt + 5, len - 2 + 1);
471      opt = dup;
472      value = 0;
473      opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
474    }
475
476  if (opt_index == cl_options_count)
477    goto done;
478
479  option = &cl_options[opt_index];
480
481  /* Reject negative form of switches that don't take negatives as
482     unrecognized.  */
483  if (!value && (option->flags & CL_REJECT_NEGATIVE))
484    goto done;
485
486  /* We've recognized this switch.  */
487  result = 1;
488
489  /* Check to see if the option is disabled for this configuration.  */
490  if (option->flags & CL_DISABLED)
491    {
492      error ("command line option %qs"
493	     " is not supported by this configuration", opt);
494      goto done;
495    }
496
497  /* Sort out any argument the switch takes.  */
498  if (option->flags & CL_JOINED)
499    {
500      /* Have arg point to the original switch.  This is because
501	 some code, such as disable_builtin_function, expects its
502	 argument to be persistent until the program exits.  */
503      arg = argv[0] + cl_options[opt_index].opt_len + 1;
504      if (!value)
505	arg += strlen ("no-");
506
507      if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
508	{
509	  if (option->flags & CL_SEPARATE)
510	    {
511	      arg = argv[1];
512	      result = 2;
513	    }
514	  else
515	    /* Missing argument.  */
516	    arg = NULL;
517	}
518    }
519  else if (option->flags & CL_SEPARATE)
520    {
521      arg = argv[1];
522      result = 2;
523    }
524
525  /* Now we've swallowed any potential argument, complain if this
526     is a switch for a different front end.  */
527  if (!(option->flags & (lang_mask | CL_COMMON | CL_TARGET)))
528    {
529      complain_wrong_lang (argv[0], option, lang_mask);
530      goto done;
531    }
532
533  if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
534    {
535      if (!lang_hooks.missing_argument (opt, opt_index))
536	error ("missing argument to \"%s\"", opt);
537      goto done;
538    }
539
540  /* If the switch takes an integer, convert it.  */
541  if (arg && (option->flags & CL_UINTEGER))
542    {
543      value = integral_argument (arg);
544      if (value == -1)
545	{
546	  error ("argument to \"%s\" should be a non-negative integer",
547		 option->opt_text);
548	  goto done;
549	}
550    }
551
552  if (option->flag_var)
553    switch (option->var_type)
554      {
555      case CLVC_BOOLEAN:
556	*(int *) option->flag_var = value;
557	break;
558
559      case CLVC_EQUAL:
560	*(int *) option->flag_var = (value
561				     ? option->var_value
562				     : !option->var_value);
563	break;
564
565      case CLVC_BIT_CLEAR:
566      case CLVC_BIT_SET:
567	if ((value != 0) == (option->var_type == CLVC_BIT_SET))
568	  *(int *) option->flag_var |= option->var_value;
569	else
570	  *(int *) option->flag_var &= ~option->var_value;
571	if (option->flag_var == &target_flags)
572	  target_flags_explicit |= option->var_value;
573	break;
574
575      case CLVC_STRING:
576	*(const char **) option->flag_var = arg;
577	break;
578      }
579
580  if (option->flags & lang_mask)
581    if (lang_hooks.handle_option (opt_index, arg, value) == 0)
582      result = 0;
583
584  if (result && (option->flags & CL_COMMON))
585    if (common_handle_option (opt_index, arg, value, lang_mask) == 0)
586      result = 0;
587
588  if (result && (option->flags & CL_TARGET))
589    if (!targetm.handle_option (opt_index, arg, value))
590      result = 0;
591
592 done:
593  if (dup)
594    free (dup);
595  return result;
596}
597
598/* Handle FILENAME from the command line.  */
599static void
600add_input_filename (const char *filename)
601{
602  num_in_fnames++;
603  in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0]));
604  in_fnames[num_in_fnames - 1] = filename;
605}
606
607/* Decode and handle the vector of command line options.  LANG_MASK
608   contains has a single bit set representing the current
609   language.  */
610static void
611handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
612{
613  unsigned int n, i;
614
615  for (i = 1; i < argc; i += n)
616    {
617      const char *opt = argv[i];
618
619      /* Interpret "-" or a non-switch as a file name.  */
620      if (opt[0] != '-' || opt[1] == '\0')
621	{
622	  if (main_input_filename == NULL)
623	    {
624	    main_input_filename = opt;
625	      main_input_baselength
626		= base_of_path (main_input_filename, &main_input_basename);
627	    }
628	  add_input_filename (opt);
629	  n = 1;
630	  continue;
631	}
632
633      n = handle_option (argv + i, lang_mask);
634
635      if (!n)
636	{
637	  n = 1;
638	  error ("unrecognized command line option \"%s\"", opt);
639	}
640    }
641}
642
643/* Parse command line options and set default flag values.  Do minimal
644   options processing.  */
645void
646decode_options (unsigned int argc, const char **argv)
647{
648  unsigned int i, lang_mask;
649
650  /* Perform language-specific options initialization.  */
651  lang_mask = lang_hooks.init_options (argc, argv);
652
653  lang_hooks.initialize_diagnostics (global_dc);
654
655  /* Scan to see what optimization level has been specified.  That will
656     determine the default value of many flags.  */
657  for (i = 1; i < argc; i++)
658    {
659      if (!strcmp (argv[i], "-O"))
660	{
661	  optimize = 1;
662	  optimize_size = 0;
663	}
664      else if (argv[i][0] == '-' && argv[i][1] == 'O')
665	{
666	  /* Handle -Os, -O2, -O3, -O69, ...  */
667	  const char *p = &argv[i][2];
668
669	  if ((p[0] == 's') && (p[1] == 0))
670	    {
671	      optimize_size = 1;
672
673	      /* Optimizing for size forces optimize to be 2.  */
674	      optimize = 2;
675	    }
676	  else
677	    {
678	      const int optimize_val = read_integral_parameter (p, p - 2, -1);
679	      if (optimize_val != -1)
680		{
681		  optimize = optimize_val;
682		  optimize_size = 0;
683		}
684	    }
685	}
686    }
687
688  if (!optimize)
689    {
690      flag_merge_constants = 0;
691    }
692
693  if (optimize >= 1)
694    {
695      flag_defer_pop = 1;
696#ifdef DELAY_SLOTS
697      flag_delayed_branch = 1;
698#endif
699#ifdef CAN_DEBUG_WITHOUT_FP
700      flag_omit_frame_pointer = 1;
701#endif
702      flag_guess_branch_prob = 1;
703      flag_cprop_registers = 1;
704      flag_if_conversion = 1;
705      flag_if_conversion2 = 1;
706      flag_ipa_pure_const = 1;
707      flag_ipa_reference = 1;
708      flag_tree_ccp = 1;
709      flag_tree_dce = 1;
710      flag_tree_dom = 1;
711      flag_tree_dse = 1;
712      flag_tree_ter = 1;
713      flag_tree_live_range_split = 1;
714      flag_tree_sra = 1;
715      flag_tree_copyrename = 1;
716      flag_tree_fre = 1;
717      flag_tree_copy_prop = 1;
718      flag_tree_sink = 1;
719      flag_tree_salias = 1;
720      if (!no_unit_at_a_time_default)
721        flag_unit_at_a_time = 1;
722
723      if (!optimize_size)
724	{
725	  /* Loop header copying usually increases size of the code.  This used
726	     not to be true, since quite often it is possible to verify that
727	     the condition is satisfied in the first iteration and therefore
728	     to eliminate it.  Jump threading handles these cases now.  */
729	  flag_tree_ch = 1;
730	}
731    }
732
733  if (optimize >= 2)
734    {
735      flag_thread_jumps = 1;
736      flag_crossjumping = 1;
737      flag_optimize_sibling_calls = 1;
738      flag_cse_follow_jumps = 1;
739      flag_cse_skip_blocks = 1;
740      flag_gcse = 1;
741      flag_expensive_optimizations = 1;
742      flag_ipa_type_escape = 1;
743      flag_rerun_cse_after_loop = 1;
744      flag_caller_saves = 1;
745      flag_peephole2 = 1;
746#ifdef INSN_SCHEDULING
747      flag_schedule_insns = 1;
748      flag_schedule_insns_after_reload = 1;
749#endif
750      flag_regmove = 1;
751      flag_strict_aliasing = 1;
752      flag_strict_overflow = 1;
753      flag_delete_null_pointer_checks = 1;
754      flag_reorder_blocks = 1;
755      flag_reorder_functions = 1;
756      flag_tree_store_ccp = 1;
757      flag_tree_store_copy_prop = 1;
758      /* XXX: some issues with ports have been traced to -ftree-vrp.
759         So remove it from -O2 and above.  Note that jdk1{5,6} are affected
760         and they build with w/-O3 - so we cannot just move it to -O3. */
761      /* flag_tree_vrp = 1; // See GCC tree-optimization/33099 */
762
763      if (!optimize_size)
764	{
765          /* PRE tends to generate bigger code.  */
766          flag_tree_pre = 1;
767	}
768    }
769
770  if (optimize >= 3)
771    {
772      flag_inline_functions = 1;
773      flag_unswitch_loops = 1;
774      flag_gcse_after_reload = 1;
775    }
776
777  if (optimize_size)
778    {
779      align_loops = 1;
780      align_jumps = 1;
781      align_labels = 1;
782      align_functions = 1;
783
784      /* Don't reorder blocks when optimizing for size because extra
785	 jump insns may be created; also barrier may create extra padding.
786
787	 More correctly we should have a block reordering mode that tried
788	 to minimize the combined size of all the jumps.  This would more
789	 or less automatically remove extra jumps, but would also try to
790	 use more short jumps instead of long jumps.  */
791      flag_reorder_blocks = 0;
792      flag_reorder_blocks_and_partition = 0;
793    }
794
795  if (optimize_size)
796    {
797      /* Inlining of very small functions usually reduces total size.  */
798      set_param_value ("max-inline-insns-single", 5);
799      set_param_value ("max-inline-insns-auto", 5);
800      flag_inline_functions = 1;
801
802      /* We want to crossjump as much as possible.  */
803      set_param_value ("min-crossjump-insns", 1);
804    }
805
806  /* Initialize whether `char' is signed.  */
807  flag_signed_char = DEFAULT_SIGNED_CHAR;
808  /* Set this to a special "uninitialized" value.  The actual default is set
809     after target options have been processed.  */
810  flag_short_enums = 2;
811
812  /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
813     modify it.  */
814  target_flags = targetm.default_target_flags;
815
816  /* Some tagets have ABI-specified unwind tables.  */
817  flag_unwind_tables = targetm.unwind_tables_default;
818
819#ifdef OPTIMIZATION_OPTIONS
820  /* Allow default optimizations to be specified on a per-machine basis.  */
821  OPTIMIZATION_OPTIONS (optimize, optimize_size);
822#endif
823
824  handle_options (argc, argv, lang_mask);
825
826  if (flag_pie)
827    flag_pic = flag_pie;
828  if (flag_pic && !flag_pie)
829    flag_shlib = 1;
830
831  if (flag_no_inline == 2)
832    flag_no_inline = 0;
833  else
834    flag_really_no_inline = flag_no_inline;
835
836  /* Set flag_no_inline before the post_options () hook.  The C front
837     ends use it to determine tree inlining defaults.  FIXME: such
838     code should be lang-independent when all front ends use tree
839     inlining, in which case it, and this condition, should be moved
840     to the top of process_options() instead.  */
841  if (optimize == 0)
842    {
843      /* Inlining does not work if not optimizing,
844	 so force it not to be done.  */
845      flag_no_inline = 1;
846      warn_inline = 0;
847
848      /* The c_decode_option function and decode_option hook set
849	 this to `2' if -Wall is used, so we can avoid giving out
850	 lots of errors for people who don't realize what -Wall does.  */
851      if (warn_uninitialized == 1)
852	warning (OPT_Wuninitialized,
853		 "-Wuninitialized is not supported without -O");
854    }
855
856  if (flag_really_no_inline == 2)
857    flag_really_no_inline = flag_no_inline;
858
859  /* The optimization to partition hot and cold basic blocks into separate
860     sections of the .o and executable files does not work (currently)
861     with exception handling.  This is because there is no support for
862     generating unwind info.  If flag_exceptions is turned on we need to
863     turn off the partitioning optimization.  */
864
865  if (flag_exceptions && flag_reorder_blocks_and_partition)
866    {
867      inform
868	    ("-freorder-blocks-and-partition does not work with exceptions");
869      flag_reorder_blocks_and_partition = 0;
870      flag_reorder_blocks = 1;
871    }
872
873  /* If user requested unwind info, then turn off the partitioning
874     optimization.  */
875
876  if (flag_unwind_tables && ! targetm.unwind_tables_default
877      && flag_reorder_blocks_and_partition)
878    {
879      inform ("-freorder-blocks-and-partition does not support unwind info");
880      flag_reorder_blocks_and_partition = 0;
881      flag_reorder_blocks = 1;
882    }
883
884  /* If the target requested unwind info, then turn off the partitioning
885     optimization with a different message.  Likewise, if the target does not
886     support named sections.  */
887
888  if (flag_reorder_blocks_and_partition
889      && (!targetm.have_named_sections
890	  || (flag_unwind_tables && targetm.unwind_tables_default)))
891    {
892      inform
893       ("-freorder-blocks-and-partition does not work on this architecture");
894      flag_reorder_blocks_and_partition = 0;
895      flag_reorder_blocks = 1;
896    }
897}
898
899/* Handle target- and language-independent options.  Return zero to
900   generate an "unknown option" message.  Only options that need
901   extra handling need to be listed here; if you simply want
902   VALUE assigned to a variable, it happens automatically.  */
903
904static int
905common_handle_option (size_t scode, const char *arg, int value,
906		      unsigned int lang_mask)
907{
908  enum opt_code code = (enum opt_code) scode;
909
910  switch (code)
911    {
912    case OPT__help:
913      print_help ();
914      exit_after_options = true;
915      break;
916
917    case OPT__param:
918      handle_param (arg);
919      break;
920
921    case OPT__target_help:
922      print_target_help ();
923      exit_after_options = true;
924      break;
925
926    case OPT__version:
927      print_version (stderr, "");
928      exit_after_options = true;
929      break;
930
931    case OPT_G:
932      g_switch_value = value;
933      g_switch_set = true;
934      break;
935
936    case OPT_O:
937    case OPT_Os:
938      /* Currently handled in a prescan.  */
939      break;
940
941    case OPT_W:
942      /* For backward compatibility, -W is the same as -Wextra.  */
943      set_Wextra (value);
944      break;
945
946    case OPT_Werror_:
947      {
948	char *new_option;
949	int option_index;
950	new_option = XNEWVEC (char, strlen (arg) + 2);
951	new_option[0] = 'W';
952	strcpy (new_option+1, arg);
953	option_index = find_opt (new_option, lang_mask);
954	if (option_index == N_OPTS)
955	  {
956	    error ("-Werror=%s: No option -%s", arg, new_option);
957	  }
958	else
959	  {
960	    int kind = value ? DK_ERROR : DK_WARNING;
961	    diagnostic_classify_diagnostic (global_dc, option_index, kind);
962
963	    /* -Werror=foo implies -Wfoo.  */
964	    if (cl_options[option_index].var_type == CLVC_BOOLEAN
965		&& cl_options[option_index].flag_var
966		&& kind == DK_ERROR)
967	      *(int *) cl_options[option_index].flag_var = 1;
968	    free (new_option);
969	  }
970      }
971      break;
972
973    case OPT_Wextra:
974      set_Wextra (value);
975      break;
976
977    case OPT_Wlarger_than_:
978      larger_than_size = value;
979      warn_larger_than = value != -1;
980      break;
981
982    case OPT_Wstrict_aliasing:
983    case OPT_Wstrict_aliasing_:
984      warn_strict_aliasing = value;
985      break;
986
987    case OPT_Wstrict_overflow:
988      warn_strict_overflow = (value
989			      ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
990			      : 0);
991      break;
992
993    case OPT_Wstrict_overflow_:
994      warn_strict_overflow = value;
995      break;
996
997    case OPT_Wunused:
998      set_Wunused (value);
999      break;
1000
1001    case OPT_aux_info:
1002    case OPT_aux_info_:
1003      aux_info_file_name = arg;
1004      flag_gen_aux_info = 1;
1005      break;
1006
1007    case OPT_auxbase:
1008      aux_base_name = arg;
1009      break;
1010
1011    case OPT_auxbase_strip:
1012      {
1013	char *tmp = xstrdup (arg);
1014	strip_off_ending (tmp, strlen (tmp));
1015	if (tmp[0])
1016	  aux_base_name = tmp;
1017      }
1018      break;
1019
1020    case OPT_d:
1021      decode_d_option (arg);
1022      break;
1023
1024    case OPT_dumpbase:
1025      dump_base_name = arg;
1026      break;
1027
1028    case OPT_falign_functions_:
1029      align_functions = value;
1030      break;
1031
1032    case OPT_falign_jumps_:
1033      align_jumps = value;
1034      break;
1035
1036    case OPT_falign_labels_:
1037      align_labels = value;
1038      break;
1039
1040    case OPT_falign_loops_:
1041      align_loops = value;
1042      break;
1043
1044    case OPT_fbranch_probabilities:
1045      flag_branch_probabilities_set = true;
1046      break;
1047
1048    case OPT_fcall_used_:
1049      fix_register (arg, 0, 1);
1050      break;
1051
1052    case OPT_fcall_saved_:
1053      fix_register (arg, 0, 0);
1054      break;
1055
1056    case OPT_fdiagnostics_show_location_:
1057      if (!strcmp (arg, "once"))
1058	diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
1059      else if (!strcmp (arg, "every-line"))
1060	diagnostic_prefixing_rule (global_dc)
1061	  = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
1062      else
1063	return 0;
1064      break;
1065
1066    case OPT_fdiagnostics_show_option:
1067      global_dc->show_option_requested = true;
1068      break;
1069
1070    case OPT_fdump_:
1071      if (!dump_switch_p (arg))
1072	return 0;
1073      break;
1074
1075    case OPT_ffast_math:
1076      set_fast_math_flags (value);
1077      break;
1078
1079    case OPT_ffixed_:
1080      fix_register (arg, 1, 1);
1081      break;
1082
1083    case OPT_finline_limit_:
1084    case OPT_finline_limit_eq:
1085      set_param_value ("max-inline-insns-single", value / 2);
1086      set_param_value ("max-inline-insns-auto", value / 2);
1087      break;
1088
1089    case OPT_fmessage_length_:
1090      pp_set_line_maximum_length (global_dc->printer, value);
1091      break;
1092
1093    case OPT_fpack_struct_:
1094      if (value <= 0 || (value & (value - 1)) || value > 16)
1095	error("structure alignment must be a small power of two, not %d", value);
1096      else
1097	{
1098	  initial_max_fld_align = value;
1099	  maximum_field_alignment = value * BITS_PER_UNIT;
1100	}
1101      break;
1102
1103    case OPT_fpeel_loops:
1104      flag_peel_loops_set = true;
1105      break;
1106
1107    case OPT_fprofile_arcs:
1108      profile_arc_flag_set = true;
1109      break;
1110
1111    case OPT_fprofile_use:
1112      if (!flag_branch_probabilities_set)
1113        flag_branch_probabilities = value;
1114      if (!flag_profile_values_set)
1115        flag_profile_values = value;
1116      if (!flag_unroll_loops_set)
1117        flag_unroll_loops = value;
1118      if (!flag_peel_loops_set)
1119        flag_peel_loops = value;
1120      if (!flag_tracer_set)
1121        flag_tracer = value;
1122      if (!flag_value_profile_transformations_set)
1123        flag_value_profile_transformations = value;
1124      break;
1125
1126    case OPT_fprofile_generate:
1127      if (!profile_arc_flag_set)
1128        profile_arc_flag = value;
1129      if (!flag_profile_values_set)
1130        flag_profile_values = value;
1131      if (!flag_value_profile_transformations_set)
1132        flag_value_profile_transformations = value;
1133      break;
1134
1135    case OPT_fprofile_values:
1136      flag_profile_values_set = true;
1137      break;
1138
1139    case OPT_fvisibility_:
1140      {
1141        if (!strcmp(arg, "default"))
1142          default_visibility = VISIBILITY_DEFAULT;
1143        else if (!strcmp(arg, "internal"))
1144          default_visibility = VISIBILITY_INTERNAL;
1145        else if (!strcmp(arg, "hidden"))
1146          default_visibility = VISIBILITY_HIDDEN;
1147        else if (!strcmp(arg, "protected"))
1148          default_visibility = VISIBILITY_PROTECTED;
1149        else
1150          error ("unrecognized visibility value \"%s\"", arg);
1151      }
1152      break;
1153
1154    case OPT_fvpt:
1155      flag_value_profile_transformations_set = true;
1156      break;
1157
1158    case OPT_frandom_seed:
1159      /* The real switch is -fno-random-seed.  */
1160      if (value)
1161	return 0;
1162      flag_random_seed = NULL;
1163      break;
1164
1165    case OPT_frandom_seed_:
1166      flag_random_seed = arg;
1167      break;
1168
1169    case OPT_fsched_verbose_:
1170#ifdef INSN_SCHEDULING
1171      fix_sched_param ("verbose", arg);
1172      break;
1173#else
1174      return 0;
1175#endif
1176
1177    case OPT_fsched_stalled_insns_:
1178      flag_sched_stalled_insns = value;
1179      if (flag_sched_stalled_insns == 0)
1180	flag_sched_stalled_insns = -1;
1181      break;
1182
1183    case OPT_fsched_stalled_insns_dep_:
1184      flag_sched_stalled_insns_dep = value;
1185      break;
1186
1187    case OPT_fstack_limit:
1188      /* The real switch is -fno-stack-limit.  */
1189      if (value)
1190	return 0;
1191      stack_limit_rtx = NULL_RTX;
1192      break;
1193
1194    case OPT_fstack_limit_register_:
1195      {
1196	int reg = decode_reg_name (arg);
1197	if (reg < 0)
1198	  error ("unrecognized register name \"%s\"", arg);
1199	else
1200	  stack_limit_rtx = gen_rtx_REG (Pmode, reg);
1201      }
1202      break;
1203
1204    case OPT_fstack_limit_symbol_:
1205      stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg));
1206      break;
1207
1208    case OPT_ftree_vectorizer_verbose_:
1209      vect_set_verbosity_level (arg);
1210      break;
1211
1212    case OPT_ftls_model_:
1213      if (!strcmp (arg, "global-dynamic"))
1214	flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
1215      else if (!strcmp (arg, "local-dynamic"))
1216	flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
1217      else if (!strcmp (arg, "initial-exec"))
1218	flag_tls_default = TLS_MODEL_INITIAL_EXEC;
1219      else if (!strcmp (arg, "local-exec"))
1220	flag_tls_default = TLS_MODEL_LOCAL_EXEC;
1221      else
1222	warning (0, "unknown tls-model \"%s\"", arg);
1223      break;
1224
1225    case OPT_ftracer:
1226      flag_tracer_set = true;
1227      break;
1228
1229    case OPT_funroll_loops:
1230      flag_unroll_loops_set = true;
1231      break;
1232
1233    case OPT_g:
1234      set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
1235      break;
1236
1237    case OPT_gcoff:
1238      set_debug_level (SDB_DEBUG, false, arg);
1239      break;
1240
1241    case OPT_gdwarf_2:
1242      set_debug_level (DWARF2_DEBUG, false, arg);
1243      break;
1244
1245    case OPT_ggdb:
1246      set_debug_level (NO_DEBUG, 2, arg);
1247      break;
1248
1249    case OPT_gstabs:
1250    case OPT_gstabs_:
1251      set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg);
1252      break;
1253
1254    case OPT_gvms:
1255      set_debug_level (VMS_DEBUG, false, arg);
1256      break;
1257
1258    case OPT_gxcoff:
1259    case OPT_gxcoff_:
1260      set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg);
1261      break;
1262
1263    case OPT_o:
1264      asm_file_name = arg;
1265      break;
1266
1267    case OPT_pedantic_errors:
1268      flag_pedantic_errors = pedantic = 1;
1269      break;
1270
1271    case OPT_fforce_mem:
1272      warning (0, "-f[no-]force-mem is nop and option will be removed in 4.3");
1273      break;
1274
1275    case OPT_floop_optimize:
1276    case OPT_frerun_loop_opt:
1277    case OPT_fstrength_reduce:
1278      /* These are no-ops, preserved for backward compatibility.  */
1279      break;
1280
1281    default:
1282      /* If the flag was handled in a standard way, assume the lack of
1283	 processing here is intentional.  */
1284      gcc_assert (cl_options[scode].flag_var);
1285      break;
1286    }
1287
1288  return 1;
1289}
1290
1291/* Handle --param NAME=VALUE.  */
1292static void
1293handle_param (const char *carg)
1294{
1295  char *equal, *arg;
1296  int value;
1297
1298  arg = xstrdup (carg);
1299  equal = strchr (arg, '=');
1300  if (!equal)
1301    error ("%s: --param arguments should be of the form NAME=VALUE", arg);
1302  else
1303    {
1304      value = integral_argument (equal + 1);
1305      if (value == -1)
1306	error ("invalid --param value %qs", equal + 1);
1307      else
1308	{
1309	  *equal = '\0';
1310	  set_param_value (arg, value);
1311	}
1312    }
1313
1314  free (arg);
1315}
1316
1317/* Handle -W and -Wextra.  */
1318static void
1319set_Wextra (int setting)
1320{
1321  extra_warnings = setting;
1322  warn_unused_value = setting;
1323  warn_unused_parameter = (setting && maybe_warn_unused_parameter);
1324
1325  /* We save the value of warn_uninitialized, since if they put
1326     -Wuninitialized on the command line, we need to generate a
1327     warning about not using it without also specifying -O.  */
1328  if (setting == 0)
1329    warn_uninitialized = 0;
1330  else if (warn_uninitialized != 1)
1331    warn_uninitialized = 2;
1332}
1333
1334/* Initialize unused warning flags.  */
1335void
1336set_Wunused (int setting)
1337{
1338  warn_unused_function = setting;
1339  warn_unused_label = setting;
1340  /* Unused function parameter warnings are reported when either
1341     ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.
1342     Thus, if -Wextra has already been seen, set warn_unused_parameter;
1343     otherwise set maybe_warn_extra_parameter, which will be picked up
1344     by set_Wextra.  */
1345  maybe_warn_unused_parameter = setting;
1346  warn_unused_parameter = (setting && extra_warnings);
1347  warn_unused_variable = setting;
1348  warn_unused_value = setting;
1349}
1350
1351/* The following routines are useful in setting all the flags that
1352   -ffast-math and -fno-fast-math imply.  */
1353void
1354set_fast_math_flags (int set)
1355{
1356  flag_trapping_math = !set;
1357  flag_unsafe_math_optimizations = set;
1358  flag_finite_math_only = set;
1359  flag_errno_math = !set;
1360  if (set)
1361    {
1362      flag_signaling_nans = 0;
1363      flag_rounding_math = 0;
1364      flag_cx_limited_range = 1;
1365    }
1366}
1367
1368/* Return true iff flags are set as if -ffast-math.  */
1369bool
1370fast_math_flags_set_p (void)
1371{
1372  return (!flag_trapping_math
1373	  && flag_unsafe_math_optimizations
1374	  && flag_finite_math_only
1375	  && !flag_errno_math);
1376}
1377
1378/* Handle a debug output -g switch.  EXTENDED is true or false to support
1379   extended output (2 is special and means "-ggdb" was given).  */
1380static void
1381set_debug_level (enum debug_info_type type, int extended, const char *arg)
1382{
1383  static bool type_explicit;
1384
1385  use_gnu_debug_info_extensions = extended;
1386
1387  if (type == NO_DEBUG)
1388    {
1389      if (write_symbols == NO_DEBUG)
1390	{
1391	  write_symbols = PREFERRED_DEBUGGING_TYPE;
1392
1393	  if (extended == 2)
1394	    {
1395#ifdef DWARF2_DEBUGGING_INFO
1396	      write_symbols = DWARF2_DEBUG;
1397#elif defined DBX_DEBUGGING_INFO
1398	      write_symbols = DBX_DEBUG;
1399#endif
1400	    }
1401
1402	  if (write_symbols == NO_DEBUG)
1403	    warning (0, "target system does not support debug output");
1404	}
1405    }
1406  else
1407    {
1408      /* Does it conflict with an already selected type?  */
1409      if (type_explicit && write_symbols != NO_DEBUG && type != write_symbols)
1410	error ("debug format \"%s\" conflicts with prior selection",
1411	       debug_type_names[type]);
1412      write_symbols = type;
1413      type_explicit = true;
1414    }
1415
1416  /* A debug flag without a level defaults to level 2.  */
1417  if (*arg == '\0')
1418    {
1419      if (!debug_info_level)
1420	debug_info_level = 2;
1421    }
1422  else
1423    {
1424      debug_info_level = integral_argument (arg);
1425      if (debug_info_level == (unsigned int) -1)
1426	error ("unrecognised debug output level \"%s\"", arg);
1427      else if (debug_info_level > 3)
1428	error ("debug output level %s is too high", arg);
1429    }
1430}
1431
1432/* Display help for target options.  */
1433static void
1434print_target_help (void)
1435{
1436  unsigned int i;
1437  static bool displayed = false;
1438
1439  /* Avoid double printing for --help --target-help.  */
1440  if (displayed)
1441    return;
1442
1443  displayed = true;
1444  for (i = 0; i < cl_options_count; i++)
1445    if ((cl_options[i].flags & (CL_TARGET | CL_UNDOCUMENTED)) == CL_TARGET)
1446      {
1447	printf (_("\nTarget specific options:\n"));
1448	print_filtered_help (CL_TARGET);
1449	break;
1450      }
1451}
1452
1453/* Output --help text.  */
1454static void
1455print_help (void)
1456{
1457  size_t i;
1458  const char *p;
1459
1460  GET_ENVIRONMENT (p, "COLUMNS");
1461  if (p)
1462    {
1463      int value = atoi (p);
1464      if (value > 0)
1465	columns = value;
1466    }
1467
1468  puts (_("The following options are language-independent:\n"));
1469
1470  print_filtered_help (CL_COMMON);
1471  print_param_help ();
1472
1473  for (i = 0; lang_names[i]; i++)
1474    {
1475      printf (_("The %s front end recognizes the following options:\n\n"),
1476	      lang_names[i]);
1477      print_filtered_help (1U << i);
1478    }
1479  print_target_help ();
1480}
1481
1482/* Print the help for --param.  */
1483static void
1484print_param_help (void)
1485{
1486  size_t i;
1487
1488  puts (_("The --param option recognizes the following as parameters:\n"));
1489
1490  for (i = 0; i < LAST_PARAM; i++)
1491    {
1492      const char *help = compiler_params[i].help;
1493      const char *param = compiler_params[i].option;
1494
1495      if (help == NULL || *help == '\0')
1496	help = undocumented_msg;
1497
1498      /* Get the translation.  */
1499      help = _(help);
1500
1501      wrap_help (help, param, strlen (param));
1502    }
1503
1504  putchar ('\n');
1505}
1506
1507/* Print help for a specific front-end, etc.  */
1508static void
1509print_filtered_help (unsigned int flag)
1510{
1511  unsigned int i, len, filter, indent = 0;
1512  bool duplicates = false;
1513  const char *help, *opt, *tab;
1514  static char *printed;
1515
1516  if (flag == CL_COMMON || flag == CL_TARGET)
1517    {
1518      filter = flag;
1519      if (!printed)
1520	printed = xmalloc (cl_options_count);
1521      memset (printed, 0, cl_options_count);
1522    }
1523  else
1524    {
1525      /* Don't print COMMON options twice.  */
1526      filter = flag | CL_COMMON;
1527
1528      for (i = 0; i < cl_options_count; i++)
1529	{
1530	  if ((cl_options[i].flags & filter) != flag)
1531	    continue;
1532
1533	  /* Skip help for internal switches.  */
1534	  if (cl_options[i].flags & CL_UNDOCUMENTED)
1535	    continue;
1536
1537	  /* Skip switches that have already been printed, mark them to be
1538	     listed later.  */
1539	  if (printed[i])
1540	    {
1541	      duplicates = true;
1542	      indent = print_switch (cl_options[i].opt_text, indent);
1543	    }
1544	}
1545
1546      if (duplicates)
1547	{
1548	  putchar ('\n');
1549	  putchar ('\n');
1550	}
1551    }
1552
1553  for (i = 0; i < cl_options_count; i++)
1554    {
1555      if ((cl_options[i].flags & filter) != flag)
1556	continue;
1557
1558      /* Skip help for internal switches.  */
1559      if (cl_options[i].flags & CL_UNDOCUMENTED)
1560	continue;
1561
1562      /* Skip switches that have already been printed.  */
1563      if (printed[i])
1564	continue;
1565
1566      printed[i] = true;
1567
1568      help = cl_options[i].help;
1569      if (!help)
1570	help = undocumented_msg;
1571
1572      /* Get the translation.  */
1573      help = _(help);
1574
1575      tab = strchr (help, '\t');
1576      if (tab)
1577	{
1578	  len = tab - help;
1579	  opt = help;
1580	  help = tab + 1;
1581	}
1582      else
1583	{
1584	  opt = cl_options[i].opt_text;
1585	  len = strlen (opt);
1586	}
1587
1588      wrap_help (help, opt, len);
1589    }
1590
1591  putchar ('\n');
1592}
1593
1594/* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
1595   word-wrapped HELP in a second column.  */
1596static unsigned int
1597print_switch (const char *text, unsigned int indent)
1598{
1599  unsigned int len = strlen (text) + 1; /* trailing comma */
1600
1601  if (indent)
1602    {
1603      putchar (',');
1604      if (indent + len > columns)
1605	{
1606	  putchar ('\n');
1607	  putchar (' ');
1608	  indent = 1;
1609	}
1610    }
1611  else
1612    putchar (' ');
1613
1614  putchar (' ');
1615  fputs (text, stdout);
1616
1617  return indent + len + 1;
1618}
1619
1620/* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
1621   word-wrapped HELP in a second column.  */
1622static void
1623wrap_help (const char *help, const char *item, unsigned int item_width)
1624{
1625  unsigned int col_width = 27;
1626  unsigned int remaining, room, len;
1627
1628  remaining = strlen (help);
1629
1630  do
1631    {
1632      room = columns - 3 - MAX (col_width, item_width);
1633      if (room > columns)
1634	room = 0;
1635      len = remaining;
1636
1637      if (room < len)
1638	{
1639	  unsigned int i;
1640
1641	  for (i = 0; help[i]; i++)
1642	    {
1643	      if (i >= room && len != remaining)
1644		break;
1645	      if (help[i] == ' ')
1646		len = i;
1647	      else if ((help[i] == '-' || help[i] == '/')
1648		       && help[i + 1] != ' '
1649		       && i > 0 && ISALPHA (help[i - 1]))
1650		len = i + 1;
1651	    }
1652	}
1653
1654      printf( "  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1655      item_width = 0;
1656      while (help[len] == ' ')
1657	len++;
1658      help += len;
1659      remaining -= len;
1660    }
1661  while (remaining);
1662}
1663
1664/* Return 1 if OPTION is enabled, 0 if it is disabled, or -1 if it isn't
1665   a simple on-off switch.  */
1666
1667int
1668option_enabled (int opt_idx)
1669{
1670  const struct cl_option *option = &(cl_options[opt_idx]);
1671  if (option->flag_var)
1672    switch (option->var_type)
1673      {
1674      case CLVC_BOOLEAN:
1675	return *(int *) option->flag_var != 0;
1676
1677      case CLVC_EQUAL:
1678	return *(int *) option->flag_var == option->var_value;
1679
1680      case CLVC_BIT_CLEAR:
1681	return (*(int *) option->flag_var & option->var_value) == 0;
1682
1683      case CLVC_BIT_SET:
1684	return (*(int *) option->flag_var & option->var_value) != 0;
1685
1686      case CLVC_STRING:
1687	break;
1688      }
1689  return -1;
1690}
1691
1692/* Fill STATE with the current state of option OPTION.  Return true if
1693   there is some state to store.  */
1694
1695bool
1696get_option_state (int option, struct cl_option_state *state)
1697{
1698  if (cl_options[option].flag_var == 0)
1699    return false;
1700
1701  switch (cl_options[option].var_type)
1702    {
1703    case CLVC_BOOLEAN:
1704    case CLVC_EQUAL:
1705      state->data = cl_options[option].flag_var;
1706      state->size = sizeof (int);
1707      break;
1708
1709    case CLVC_BIT_CLEAR:
1710    case CLVC_BIT_SET:
1711      state->ch = option_enabled (option);
1712      state->data = &state->ch;
1713      state->size = 1;
1714      break;
1715
1716    case CLVC_STRING:
1717      state->data = *(const char **) cl_options[option].flag_var;
1718      if (state->data == 0)
1719	state->data = "";
1720      state->size = strlen (state->data) + 1;
1721      break;
1722    }
1723  return true;
1724}
1725